[glib/application] remote commandline now works...



commit fdce77282b97a566828a768c5bd5c2f8a4509d59
Author: Ryan Lortie <desrt desrt ca>
Date:   Thu Aug 5 23:45:22 2010 -0400

    remote commandline now works...

 gio/Makefile.am                                    |    2 +-
 gio/gapplication.c                                 |   37 ++--
 gio/gapplication.h                                 |   87 ++++---
 gio/gapplicationcommandline.c                      |  301 ++++++++++++++++++++
 gio/gapplicationcommandline.h                      |  114 ++++++++
 ...cation.c => gapplicationcommandlineimpl-dbus.c} |   16 +-
 gio/gapplicationimpl-dbus-interface.c              |   47 +++-
 gio/gapplicationimpl-dbus-private.h                |    1 +
 gio/gapplicationimpl-dbus.c                        |  104 +++++++-
 gio/gapplicationinvocation.c                       |  301 --------------------
 gio/gapplicationinvocation.h                       |  114 --------
 gio/giotypes.h                                     |    2 +-
 12 files changed, 628 insertions(+), 498 deletions(-)
---
diff --git a/gio/Makefile.am b/gio/Makefile.am
index 32064be..46c6c8a 100644
--- a/gio/Makefile.am
+++ b/gio/Makefile.am
@@ -262,7 +262,7 @@ libgio_2_0_la_SOURCES =		\
 	gappinfo.c 		\
 	gapplicationimpl-dbus-interface.h \
 	gapplicationimpl-dbus-interface.c \
-	gapplicationinvocation.c\
+	gapplicationcommandline.c\
 	gapplication.c		\
 	gapplication.h		\
 	gasynchelper.c 		\
diff --git a/gio/gapplication.c b/gio/gapplication.c
index cd5ed1f..e9a97d5 100644
--- a/gio/gapplication.c
+++ b/gio/gapplication.c
@@ -41,7 +41,7 @@
 #include "gdbusintrospection.h"
 #include "gdbusmethodinvocation.h"
 #include "gioenumtypes.h"
-#include "gapplicationinvocation.h"
+#include "gapplicationcommandline.h"
 
 /**
  * SECTION: gapplication
@@ -205,6 +205,9 @@ static int      g_application_impl_cmdline  (GApplicationImpl  *impl,
 
 static void     g_application_impl_flush    (GApplicationImpl  *impl);
 
+void g_application_command_line_setup_remote (GApplicationCommandLine *,
+                                              gpointer);
+
 #ifdef G_OS_UNIX
 #include "gapplicationimpl-dbus.c"
 #else
@@ -844,28 +847,28 @@ g_application_add_platform_data (GApplication    *application,
 {
 }
 
-static GApplicationInvocation *
-g_application_create_invocation (GApplication *application,
-                                 GVariant     *arguments,
-                                 GVariant     *platform_data)
+static GApplicationCommandLine *
+g_application_create_command_line (GApplication *application,
+                                   GVariant     *arguments,
+                                   GVariant     *platform_data)
 {
-  return g_object_new (G_TYPE_APPLICATION_INVOCATION,
+  return g_object_new (G_TYPE_APPLICATION_COMMAND_LINE,
                        "arguments", arguments,
                        "platform-data", platform_data,
                        NULL);
 }
 
 static int
-g_application_emit_cmdline (GApplication           *application,
-                            GApplicationInvocation *invocation)
+g_application_emit_cmdline (GApplication            *application,
+                            GApplicationCommandLine *command_line)
 {
   return G_APPLICATION_GET_CLASS (application)
-    ->cmdline (application, invocation);
+    ->cmdline (application, command_line);
 }
 
 int
-g_application_real_cmdline (GApplication           *application,
-                            GApplicationInvocation *invocation)
+g_application_real_cmdline (GApplication            *application,
+                            GApplicationCommandLine *command_line)
 {
   g_warning ("G_APPLICATION_FLAGS_REMOTE_CMDLINE specified but the "
              "cmdline() virtual function has not been implemented");
@@ -919,7 +922,7 @@ g_application_class_init (GApplicationClass *klass)
 
   klass->process_cmdline = g_application_process_cmdline;
   klass->add_platform_data = g_application_add_platform_data;
-  klass->create_invocation = g_application_create_invocation;
+  klass->create_command_line = g_application_create_command_line;
   klass->emit_cmdline = g_application_emit_cmdline;
   klass->cmdline = g_application_real_cmdline;
   klass->run_mainloop = g_application_real_run_mainloop;
@@ -1049,14 +1052,14 @@ g_application_cmdline_with_arguments (GApplication *application,
         }
       else
         {
-          GApplicationInvocation *invocation;
+          GApplicationCommandLine *command_line;
 
-          invocation = G_APPLICATION_GET_CLASS (application)
-            ->create_invocation (application, arguments, NULL);
+          command_line = G_APPLICATION_GET_CLASS (application)
+            ->create_command_line (application, arguments, NULL);
 
-          exit_status = class->emit_cmdline (application, invocation);
+          exit_status = class->emit_cmdline (application, command_line);
 
-          g_object_unref (invocation);
+          g_object_unref (command_line);
 
           if (exit_status == 0)
             class->run_mainloop (application);
diff --git a/gio/gapplication.h b/gio/gapplication.h
index 19c6ad5..de1648d 100644
--- a/gio/gapplication.h
+++ b/gio/gapplication.h
@@ -39,6 +39,21 @@ G_BEGIN_DECLS
 #define G_IS_APPLICATION_CLASS(klass)   (G_TYPE_CHECK_CLASS_TYPE ((klass), G_TYPE_APPLICATION))
 #define G_APPLICATION_GET_CLASS(obj)    (G_TYPE_INSTANCE_GET_CLASS ((obj), G_TYPE_APPLICATION, GApplicationClass))
 
+#define G_APPLICATION_MAIN(app_type, appid, flags) \
+  int main (int argc, char **argv) {                    \
+    GApplication *app;                                  \
+    gint status;                                        \
+    g_type_init ();                                     \
+    g_set_prgname (argv[0]);                            \
+    app = g_object_new (app_type,                       \
+                        "application-id", appid,        \
+                        "flags", flags,                 \
+                        NULL);                          \
+    status = g_application_cmdline (app, argc, argv);   \
+    g_object_unref (app);                               \
+    return status;                                      \
+  }
+
 typedef struct _GApplicationPrivate     GApplicationPrivate;
 typedef struct _GApplicationClass       GApplicationClass;
 
@@ -77,49 +92,49 @@ struct _GApplicationClass
 
   /*< public >*/
   /* signals */
-  void                     (* startup)            (GApplication            *application);
+  void                      (* startup)             (GApplication             *application);
 
-  void                     (* open)               (GApplication            *application,
-                                                   GFile                  **files,
-                                                   gint                     n_files,
-                                                   const gchar             *hint);
+  void                      (* open)                (GApplication             *application,
+                                                     GFile                   **files,
+                                                     gint                      n_files,
+                                                     const gchar              *hint);
 
-  void                     (* activate)           (GApplication            *application);
+  void                      (* activate)            (GApplication             *application);
 
-  int                      (* cmdline)            (GApplication            *application,
-                                                   GApplicationInvocation  *invocation);
+  int                       (* cmdline)             (GApplication             *application,
+                                                     GApplicationCommandLine  *command_line);
 
-  gboolean                 (* action)             (GApplication            *application,
-                                                   const gchar             *action_name,
-                                                   GVariant                *parameters);
+  gboolean                  (* action)              (GApplication             *application,
+                                                     const gchar              *action_name,
+                                                     GVariant                 *parameters);
 
 
   /* vfuncs */
-  void                     (* add_platform_data)  (GApplication            *application,
-                                                   GVariantBuilder         *builder);
-  gboolean                 (* process_cmdline)    (GApplication            *application,
-                                                   GVariant               **arguments,
-                                                   gint                    *exit_status);
-
-  GApplicationInvocation * (* create_invocation)  (GApplication            *application,
-                                                   GVariant                *arguments,
-                                                   GVariant                *platform_data);
-
-  int                      (* emit_cmdline)       (GApplication            *application,
-                                                   GApplicationInvocation  *invocation);
-  void                     (* emit_open)          (GApplication            *application,
-                                                   GFile                  **files,
-                                                   gint                     n_files,
-                                                   const gchar             *hint,
-                                                   GVariant                *platform_data);
-  void                     (* emit_activate)      (GApplication            *application,
-                                                   GVariant                *platform_data);
-  void                     (* emit_action)        (GApplication            *application,
-                                                   const gchar             *action_name,
-                                                   GVariant                *platform_data);
-
-  void                     (* quit_mainloop)      (GApplication            *application);
-  void                     (* run_mainloop)       (GApplication            *application);
+  void                      (* add_platform_data)   (GApplication             *application,
+                                                     GVariantBuilder          *builder);
+  gboolean                  (* process_cmdline)     (GApplication             *application,
+                                                     GVariant                **arguments,
+                                                     gint                     *exit_status);
+
+  GApplicationCommandLine * (* create_command_line) (GApplication             *application,
+                                                     GVariant                 *arguments,
+                                                     GVariant                 *platform_data);
+
+  int                       (* emit_cmdline)        (GApplication             *application,
+                                                     GApplicationCommandLine  *command_line);
+  void                      (* emit_open)           (GApplication             *application,
+                                                     GFile                   **files,
+                                                     gint                      n_files,
+                                                     const gchar              *hint,
+                                                     GVariant                 *platform_data);
+  void                      (* emit_activate)       (GApplication             *application,
+                                                     GVariant                 *platform_data);
+  void                      (* emit_action)         (GApplication             *application,
+                                                     const gchar              *action_name,
+                                                     GVariant                 *platform_data);
+
+  void                      (* quit_mainloop)       (GApplication             *application);
+  void                      (* run_mainloop)        (GApplication             *application);
 
   /*< private >*/
   gpointer padding[12];
diff --git a/gio/gapplicationcommandline.c b/gio/gapplicationcommandline.c
new file mode 100644
index 0000000..47c0a82
--- /dev/null
+++ b/gio/gapplicationcommandline.c
@@ -0,0 +1,301 @@
+#include "gapplicationcommandline.h"
+
+#include <string.h>
+#include <stdio.h>
+
+G_DEFINE_TYPE (GApplicationCommandLine, g_application_command_line, G_TYPE_OBJECT)
+
+enum
+{
+  PROP_NONE,
+  PROP_ARGUMENTS,
+  PROP_PLATFORM_DATA,
+  PROP_IS_REMOTE
+};
+
+typedef struct _RemoteImpl RemoteImpl;
+
+static void     remote_impl_init                (RemoteImpl    *remote_impl,
+                                                 gpointer       remote_handle);
+static void     remote_impl_stdout_write        (RemoteImpl    *remote_impl,
+                                                 gconstpointer  buf,
+                                                 gsize          length);
+static void     remote_impl_stderr_write        (RemoteImpl    *remote_impl,
+                                                 gconstpointer  buf,
+                                                 gsize          length);
+static void     remote_impl_exit                (RemoteImpl    *remote_impl,
+                                                 int            status);
+
+
+#include "gapplicationcommandlineimpl-dbus.c"
+
+struct _GApplicationCommandLinePrivate
+{
+  GVariant *platform_data;
+  GVariant *arguments;
+  GVariant *cwd;
+  gint exit_status;
+
+  RemoteImpl remote_impl;
+};
+
+#define IS_REMOTE(command_line) ((command_line)->priv->platform_data != NULL)
+
+void
+g_application_command_line_get_argc_argv (GApplicationCommandLine *command_line,
+                                        int *argc, char ***argv)
+{
+  gsize len;
+
+  g_return_if_fail (G_IS_APPLICATION_COMMAND_LINE (command_line));
+  g_return_if_fail (argc != NULL && argv != NULL);
+
+  *argv = g_variant_dup_bytestring_array (command_line->priv->arguments, &len);
+  *argc = len;
+}
+
+GVariant *
+g_application_command_line_get_arguments (GApplicationCommandLine *command_line)
+{
+  return g_variant_ref (command_line->priv->arguments);
+}
+
+const gchar *
+g_application_command_line_get_cwd (GApplicationCommandLine *command_line)
+{
+  if (command_line->priv->cwd)
+    return g_variant_get_bytestring (command_line->priv->cwd);
+  else
+    return NULL;
+}
+
+GVariant *
+g_application_command_line_get_cwd_variant (GApplicationCommandLine *command_line)
+{
+  if (command_line->priv->cwd)
+    return g_variant_ref (command_line->priv->cwd);
+  else
+    return NULL;
+}
+
+gboolean
+g_application_command_line_get_is_remote (GApplicationCommandLine *command_line)
+{
+  return IS_REMOTE (command_line);
+}
+
+void
+g_application_command_line_stdout_write (GApplicationCommandLine *command_line,
+                                       gconstpointer           buf,
+                                       gssize                  length)
+{
+  if (length < 0)
+    length = strlen (buf);
+
+  if (IS_REMOTE (command_line))
+    remote_impl_stdout_write (&command_line->priv->remote_impl, buf, length);
+  else
+    fwrite (buf, length, 1, stdout);
+}
+
+void
+g_application_command_line_stderr_write (GApplicationCommandLine *command_line,
+                                       gconstpointer           buf,
+                                       gssize                  length)
+{
+  if (length < 0)
+    length = strlen (buf);
+
+  if (IS_REMOTE (command_line))
+    remote_impl_stderr_write (&command_line->priv->remote_impl, buf, length);
+  else
+    fwrite (buf, length, 1, stderr);
+}
+
+void
+g_application_command_line_stdout_print (GApplicationCommandLine *command_line,
+                                       const gchar            *format,
+                                       ...)
+{
+  gchar *message;
+  va_list ap;
+
+  g_return_if_fail (G_IS_APPLICATION_COMMAND_LINE (command_line));
+  g_return_if_fail (format != NULL);
+
+  va_start (ap, format);
+  message = g_strdup_vprintf (format, ap);
+  va_end (ap);
+
+  g_application_command_line_stdout_write (command_line, message, -1);
+}
+
+void
+g_application_command_line_stderr_print (GApplicationCommandLine *command_line,
+                                       const gchar            *format,
+                                       ...)
+{
+  gchar *message;
+  va_list ap;
+
+  g_return_if_fail (G_IS_APPLICATION_COMMAND_LINE (command_line));
+  g_return_if_fail (format != NULL);
+
+  va_start (ap, format);
+  message = g_strdup_vprintf (format, ap);
+  va_end (ap);
+
+  g_application_command_line_stderr_write (command_line, message, -1);
+}
+
+void
+g_application_command_line_set_exit_status (GApplicationCommandLine *command_line,
+                                          int                     exit_status)
+{
+  g_return_if_fail (G_IS_APPLICATION_COMMAND_LINE (command_line));
+
+  command_line->priv->exit_status = exit_status;
+}
+
+static void
+grok_platform_data (GApplicationCommandLine *command_line)
+{
+  GVariantIter iter;
+  const gchar *key;
+  GVariant *value;
+
+  g_variant_iter_init (&iter, command_line->priv->platform_data);
+
+  while (g_variant_iter_loop (&iter, "{&sv}", &key, &value))
+    if (strcmp (key, "cwd") == 0)
+      {
+        if (!command_line->priv->cwd)
+          command_line->priv->cwd = g_variant_ref (value);
+      }
+}
+
+static void
+g_application_command_line_get_property (GObject *object, guint prop_id,
+                                       GValue *value, GParamSpec *pspec)
+{
+  GApplicationCommandLine *command_line = G_APPLICATION_COMMAND_LINE (object);
+
+  switch (prop_id)
+    {
+    case PROP_ARGUMENTS:
+      g_value_set_variant (value, command_line->priv->arguments);
+      break;
+
+    case PROP_PLATFORM_DATA:
+      g_value_set_variant (value, command_line->priv->platform_data);
+      break;
+
+    case PROP_IS_REMOTE:
+      g_value_set_boolean (value, IS_REMOTE (command_line));
+      break;
+
+    default:
+      g_assert_not_reached ();
+    }
+}
+
+static void
+g_application_command_line_set_property (GObject *object, guint prop_id,
+                                       const GValue *value, GParamSpec *pspec)
+{
+  GApplicationCommandLine *command_line = G_APPLICATION_COMMAND_LINE (object);
+
+  switch (prop_id)
+    {
+    case PROP_ARGUMENTS:
+      g_assert (command_line->priv->arguments == NULL);
+      command_line->priv->arguments = g_value_dup_variant (value);
+      break;
+
+    case PROP_PLATFORM_DATA:
+      g_assert (command_line->priv->platform_data == NULL);
+      command_line->priv->platform_data = g_value_dup_variant (value);
+      if (command_line->priv->platform_data != NULL)
+        grok_platform_data (command_line);
+      break;
+
+    default:
+      g_assert_not_reached ();
+    }
+}
+
+static void
+g_application_command_line_finalize (GObject *object)
+{
+  GApplicationCommandLine *command_line = G_APPLICATION_COMMAND_LINE (object);
+
+  if (IS_REMOTE (command_line))
+    remote_impl_exit (&command_line->priv->remote_impl,
+                      command_line->priv->exit_status);
+
+  if (command_line->priv->platform_data)
+    g_variant_unref (command_line->priv->platform_data);
+  if (command_line->priv->arguments)
+    g_variant_unref (command_line->priv->arguments);
+  if (command_line->priv->cwd)
+    g_variant_unref (command_line->priv->cwd);
+
+  G_OBJECT_CLASS (g_application_command_line_parent_class)
+    ->finalize (object);
+}
+
+static void
+g_application_command_line_init (GApplicationCommandLine *command_line)
+{
+  command_line->priv =
+    G_TYPE_INSTANCE_GET_PRIVATE (command_line,
+                                 G_TYPE_APPLICATION_COMMAND_LINE,
+                                 GApplicationCommandLinePrivate);
+}
+
+static void
+g_application_command_line_class_init (GApplicationCommandLineClass *class)
+{
+  GObjectClass *object_class = G_OBJECT_CLASS (class);
+
+  object_class->get_property = g_application_command_line_get_property;
+  object_class->set_property = g_application_command_line_set_property;
+  object_class->finalize = g_application_command_line_finalize;
+
+  g_object_class_install_property (object_class, PROP_ARGUMENTS,
+    g_param_spec_variant ("arguments", "commandline arguments",
+                          "the commandline that caused this command_line",
+                          G_VARIANT_TYPE_BYTESTRING_ARRAY, NULL,
+                          G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY |
+                          G_PARAM_STATIC_STRINGS));
+
+  g_object_class_install_property (object_class, PROP_PLATFORM_DATA,
+    g_param_spec_variant ("platform-data", "platform data",
+                          "platform-specific data for the command_line",
+                          G_VARIANT_TYPE ("a{sv}"), NULL,
+                          G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY |
+                          G_PARAM_STATIC_STRINGS));
+
+  g_object_class_install_property (object_class, PROP_IS_REMOTE,
+    g_param_spec_boolean ("is-remote", "is remote",
+                          "TRUE if this is a remote command_line", FALSE,
+                          G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
+
+  g_type_class_add_private (class, sizeof (GApplicationCommandLinePrivate));
+}
+
+GVariant *
+g_application_command_line_get_platform_data (GApplicationCommandLine *command_line)
+{
+  g_return_val_if_fail (G_IS_APPLICATION_COMMAND_LINE (command_line), NULL);
+  g_return_val_if_fail (IS_REMOTE (command_line), NULL);
+
+  return g_variant_ref (command_line->priv->platform_data);
+}
+
+void
+g_application_command_line_setup_remote (GApplicationCommandLine *command_line,
+                                       gpointer                remote_handle)
+{
+  remote_impl_init (&command_line->priv->remote_impl, remote_handle);
+}
diff --git a/gio/gapplicationcommandline.h b/gio/gapplicationcommandline.h
new file mode 100644
index 0000000..39f6e9e
--- /dev/null
+++ b/gio/gapplicationcommandline.h
@@ -0,0 +1,114 @@
+/* GIO - GLib Input, Output and Streaming Library
+ *
+ * Copyright © 2010 Codethink Limited
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published
+ * by the Free Software Foundation; either version 2 of the licence or (at
+ * your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General
+ * Public License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Authors: Ryan Lortie <desrt desrt ca>
+ */
+
+#if !defined (__GIO_GIO_H_INSIDE__) && !defined (GIO_COMPILATION)
+#error "Only <gio/gio.h> can be included directly."
+#endif
+
+#ifndef __G_APPLICATION_COMMAND_LINE_H__
+#define __G_APPLICATION_COMMAND_LINE_H__
+
+#include <gio/giotypes.h>
+
+G_BEGIN_DECLS
+
+#define G_TYPE_APPLICATION_COMMAND_LINE                       (g_application_command_line_get_type ())
+#define G_APPLICATION_COMMAND_LINE(inst)                      (G_TYPE_CHECK_INSTANCE_CAST ((inst),                     \
+                                                             G_TYPE_APPLICATION_COMMAND_LINE,                          \
+                                                             GApplicationCommandLine))
+#define G_APPLICATION_COMMAND_LINE_CLASS(class)               (G_TYPE_CHECK_CLASS_CAST ((class),                       \
+                                                             G_TYPE_APPLICATION_COMMAND_LINE,                          \
+                                                             GApplicationCommandLineClass))
+#define G_IS_APPLICATION_COMMAND_LINE(inst)                   (G_TYPE_CHECK_INSTANCE_TYPE ((inst),                     \
+                                                             G_TYPE_APPLICATION_COMMAND_LINE))
+#define G_IS_APPLICATION_COMMAND_LINE_CLASS(class)            (G_TYPE_CHECK_CLASS_TYPE ((class),                       \
+                                                             G_TYPE_APPLICATION_COMMAND_LINE))
+#define G_APPLICATION_COMMAND_LINE_GET_CLASS(inst)            (G_TYPE_INSTANCE_GET_CLASS ((inst),                      \
+                                                             G_TYPE_APPLICATION_COMMAND_LINE,                          \
+                                                             GApplicationCommandLineClass))
+
+typedef struct _GApplicationCommandLinePrivate               GApplicationCommandLinePrivate;
+typedef struct _GApplicationCommandLineClass                 GApplicationCommandLineClass;
+
+/**
+ * GApplicationCommandLine:
+ *
+ * The <structname>GApplicationCommandLine</structname> structure contains private
+ * data and should only be accessed using the provided API
+ *
+ * Since: 2.26
+ */
+struct _GApplicationCommandLine
+{
+  /*< private >*/
+  GObject parent_instance;
+
+  GApplicationCommandLinePrivate *priv;
+};
+
+/**
+ * GApplicationCommandLineClass:
+ *
+ * The <structname>GApplicationCommandLineClass</structname> structure contains
+ * private data only
+ *
+ * Since: 2.26
+ */
+struct _GApplicationCommandLineClass
+{
+  /*< private >*/
+  GObjectClass parent_class;
+  gpointer padding[12];
+};
+
+GType                   g_application_command_line_get_type               (void) G_GNUC_CONST;
+
+void                    g_application_command_line_get_argc_argv          (GApplicationCommandLine *command_line,
+                                                                         int *argc, char ***argv);
+GVariant *              g_application_command_line_get_arguments          (GApplicationCommandLine *command_line);
+
+const gchar *           g_application_command_line_get_cwd                (GApplicationCommandLine *command_line);
+GVariant *              g_application_command_line_get_cwd_variant        (GApplicationCommandLine *command_line);
+
+gboolean                g_application_command_line_get_is_remote          (GApplicationCommandLine *command_line);
+
+void                    g_application_command_line_stdout_write           (GApplicationCommandLine *command_line,
+                                                                         gconstpointer           buf,
+                                                                         gssize                  length);
+void                    g_application_command_line_stderr_write           (GApplicationCommandLine *command_line,
+                                                                         gconstpointer           buf,
+                                                                         gssize                  length);
+void                    g_application_command_line_stdout_print           (GApplicationCommandLine *command_line,
+                                                                         const gchar            *format,
+                                                                         ...);
+void                    g_application_command_line_stderr_print           (GApplicationCommandLine *command_line,
+                                                                         const gchar            *format,
+                                                                         ...);
+
+void                    g_application_command_line_set_exit_status        (GApplicationCommandLine *command_line,
+                                                                         int                     exit_status);
+
+GVariant *              g_application_command_line_get_platform_data      (GApplicationCommandLine *command_line);
+
+G_END_DECLS
+
+#endif /* __G_APPLICATION_COMMAND_LINE_H__ */
diff --git a/gio/gdbusapplicationinvocation.c b/gio/gapplicationcommandlineimpl-dbus.c
similarity index 59%
rename from gio/gdbusapplicationinvocation.c
rename to gio/gapplicationcommandlineimpl-dbus.c
index 6cb1ebb..fbaae3e 100644
--- a/gio/gdbusapplicationinvocation.c
+++ b/gio/gapplicationcommandlineimpl-dbus.c
@@ -1,20 +1,15 @@
 #include "gdbusconnection.h"
+#include "gdbusmethodinvocation.h"
 
 struct _RemoteImpl {
-  GDBusConnection *session;
-  gchar *remote_name;
+  GDBusMethodInvocation *invocation;
 };
 
 void
 remote_impl_init (RemoteImpl *remote_impl,
                   gpointer    remote_handle)
 {
-  /* won't block, won't fail */
-  g_assert (remote_impl->session == NULL);
-  remote_impl->session = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, NULL);
-  g_assert (remote_impl->session != NULL);
-
-  remote_impl->remote_name = g_strdup (remote_handle);
+  remote_impl->invocation = g_object_ref (remote_handle);
 }
 
 void
@@ -36,6 +31,7 @@ void
 remote_impl_exit (RemoteImpl *remote_impl,
                   int         status)
 {
-  g_object_unref (remote_impl->session);
-  g_free (remote_impl->remote_name);
+  g_dbus_method_invocation_return_value (remote_impl->invocation,
+                                         g_variant_new ("(i)", status));
+  g_object_unref (remote_impl->invocation);
 }
diff --git a/gio/gapplicationimpl-dbus-interface.c b/gio/gapplicationimpl-dbus-interface.c
index e395830..fded1e6 100644
--- a/gio/gapplicationimpl-dbus-interface.c
+++ b/gio/gapplicationimpl-dbus-interface.c
@@ -21,19 +21,19 @@
 
 #include "gapplicationimpl-dbus-private.h"
 
-static GDBusArgInfo platform_data_arg = { -1, (gchar *) "platform_data", (gchar *) "a{sv}" };
+static const GDBusArgInfo platform_data_arg = { -1, (gchar *) "platform_data", (gchar *) "a{sv}" };
 
-static GDBusArgInfo open_uris_arg = { -1, (gchar *) "uris", (gchar *) "as" };
-static GDBusArgInfo open_hint_arg = { -1, (gchar *) "hint", (gchar *) "s" };
+static const GDBusArgInfo open_uris_arg = { -1, (gchar *) "uris", (gchar *) "as" };
+static const GDBusArgInfo open_hint_arg = { -1, (gchar *) "hint", (gchar *) "s" };
 
-static GDBusArgInfo invoke_action_name_arg = { -1, (gchar *) "name", (gchar *) "s" };
-static GDBusArgInfo invoke_action_args_arg = { -1, (gchar *) "args", (gchar *) "v" };
+static const GDBusArgInfo invoke_action_name_arg = { -1, (gchar *) "name", (gchar *) "s" };
+static const GDBusArgInfo invoke_action_args_arg = { -1, (gchar *) "args", (gchar *) "v" };
 
-static GDBusArgInfo cmdline_path_arg = { -1, (gchar *) "path", (gchar *) "o" };
-static GDBusArgInfo cmdline_arguments_arg = { -1, (gchar *) "arguments", (gchar *) "aay" };
-static GDBusArgInfo cmdline_exit_status_arg = { -1, (gchar *) "exit_status", (gchar *) "i" };
+static const GDBusArgInfo cmdline_path_arg = { -1, (gchar *) "path", (gchar *) "o" };
+static const GDBusArgInfo cmdline_arguments_arg = { -1, (gchar *) "arguments", (gchar *) "aay" };
+static const GDBusArgInfo cmdline_exit_status_arg = { -1, (gchar *) "exit_status", (gchar *) "i" };
 
-static GDBusArgInfo list_actions_actions_arg = { -1, (gchar *) "actions", (gchar *) "a{s(sgb)}" };
+static const GDBusArgInfo list_actions_actions_arg = { -1, (gchar *) "actions", (gchar *) "a{s(sgb)}" };
 
 static const GDBusArgInfo *activate_in[] = { &platform_data_arg, NULL };
 static const GDBusArgInfo *activate_out[] = { NULL };
@@ -80,11 +80,36 @@ static const GDBusMethodInfo cmdline_method = {
   (GDBusArgInfo **) cmdline_out
 };
 
-static const GDBusMethodInfo *methods[] = {
+static const GDBusMethodInfo *application_methods[] = {
   &activate_method, &open_method, &list_actions_method, &invoke_action_method, &cmdline_method, NULL
 };
 
 const GDBusInterfaceInfo org_gtk_Application = {
   -1, (gchar *) "org.gtk.Application",
-  (GDBusMethodInfo **) methods
+  (GDBusMethodInfo **) application_methods
+};
+
+static const GDBusArgInfo message_arg = { -1, (gchar *) "message", (gchar *) "ay" };
+static const GDBusArgInfo *print_in[] = { &message_arg, NULL };
+static const GDBusArgInfo *print_out[] = { NULL };
+
+static const GDBusMethodInfo stdout_method = {
+  -1, (gchar *) "Stdout",
+  (GDBusArgInfo **) print_in,
+  (GDBusArgInfo **) print_out
+};
+
+static const GDBusMethodInfo stderr_method = {
+  -1, (gchar *) "Stderr",
+  (GDBusArgInfo **) print_in,
+  (GDBusArgInfo **) print_out
+};
+
+static const GDBusMethodInfo *cmdline_methods[] = {
+  &stdout_method, &stderr_method, NULL
+};
+
+const GDBusInterfaceInfo org_gtk_private_Cmdline = {
+  -1, (gchar *) "org.gtk.private.Cmdline",
+  (GDBusMethodInfo **) cmdline_methods
 };
diff --git a/gio/gapplicationimpl-dbus-private.h b/gio/gapplicationimpl-dbus-private.h
index 0181df7..7bc25d2 100644
--- a/gio/gapplicationimpl-dbus-private.h
+++ b/gio/gapplicationimpl-dbus-private.h
@@ -25,5 +25,6 @@
 #include "gdbusintrospection.h"
 
 G_GNUC_INTERNAL extern const GDBusInterfaceInfo org_gtk_Application;
+G_GNUC_INTERNAL extern const GDBusInterfaceInfo org_gtk_private_Cmdline;
 
 #endif
diff --git a/gio/gapplicationimpl-dbus.c b/gio/gapplicationimpl-dbus.c
index e6e5c52..4a77a2c 100644
--- a/gio/gapplicationimpl-dbus.c
+++ b/gio/gapplicationimpl-dbus.c
@@ -22,6 +22,8 @@
 #include "gapplicationimpl-dbus-private.h"
 #include "gfile.h"
 
+#include <stdio.h>
+
 struct _GApplicationImpl
 {
   GDBusConnection *session_bus;
@@ -29,6 +31,8 @@ struct _GApplicationImpl
   gchar           *object_path;
   guint            object_id;
   gpointer         app;
+
+  GMainLoop       *cmdline_mainloop;
 };
 
 static void
@@ -97,23 +101,27 @@ g_application_impl_method_call (GDBusConnection       *connection,
 
   else if (strcmp (method_name, "Cmdline") == 0)
     {
+      GApplicationCommandLine *command_line;
       GVariant *arguments, *platform_data;
-      //GApplicationInvocation *invocation;
       const gchar *remote_path;
+      int exit_status;
 
       g_variant_get (parameters, "(&o aay@a{sv})",
                      &remote_path, &arguments, &platform_data);
 
-      //invocation = g_application_create_invocation (application,
-      //                                              arguments,
-      //                                              platform_data);
+      command_line = G_APPLICATION_GET_CLASS (impl->app)
+        ->create_command_line (impl->app, arguments, platform_data);
       g_variant_unref (platform_data);
       g_variant_unref (arguments);
 
-      /* XXX hook up the stuff... */
+      g_application_command_line_setup_remote (command_line,
+                                               g_object_ref (invocation));
+
+      exit_status = G_APPLICATION_GET_CLASS (impl->app)
+        ->emit_cmdline (impl->app, command_line);
 
-      //g_application_emit_invocation (invocation);
-      //g_object_unref (invocation);
+      g_application_command_line_set_exit_status (command_line, exit_status);
+      g_object_unref (command_line);
     }
 
   else
@@ -293,13 +301,95 @@ g_application_impl_action (GApplicationImpl *impl,
                            GVariant         *parameters,
                            GVariant         *platform_data)
 {
+  g_dbus_connection_call (impl->session_bus,
+                          impl->bus_name,
+                          impl->object_path,
+                          "org.gtk.Application",
+                          "InvokeAction",
+                          g_variant_new ("sv a{sv}", action_name,
+                                         parameters, platform_data),
+                          NULL, 0, -1, NULL, NULL, NULL);
+}
+
+static void
+g_application_impl_cmdline_method_call (GDBusConnection       *connection,
+                                        const gchar           *sender,
+                                        const gchar           *object_path,
+                                        const gchar           *interface_name,
+                                        const gchar           *method_name,
+                                        GVariant              *parameters,
+                                        GDBusMethodInvocation *invocation,
+                                        gpointer               user_data)
+{
+  FILE *fp;
+
+  if (strcmp (method_name, "Stdout") == 0)
+    fp = stdout;
+
+  else if (strcmp (method_name, "Stderr") == 0)
+    fp = stderr;
+
+  else
+    g_assert_not_reached ();
+
+  fwrite (g_variant_get_data (parameters), 1,
+          g_variant_get_size (parameters), fp);
+}
+
+static void
+g_application_impl_cmdline_done (GObject      *source,
+                                 GAsyncResult *result,
+                                 gpointer      user_data)
+{
+  GApplicationImpl *impl = user_data;
+
+  g_main_loop_quit (impl->cmdline_mainloop);
 }
 
+
 static int
 g_application_impl_cmdline (GApplicationImpl *impl,
                             GVariant         *arguments,
                             GVariant         *platform_data)
 {
+  const static GDBusInterfaceVTable vtable = {
+    g_application_impl_cmdline_method_call
+  };
+  const gchar *object_path = "/org/gtk/Application/Cmdline";
+  GMainContext *context;
+  guint object_id;
+
+  g_assert (impl->cmdline_mainloop == NULL);
+
+  context = g_main_context_new ();
+  impl->cmdline_mainloop = g_main_loop_new (context, FALSE);
+  g_main_context_push_thread_default (context);
+
+  object_id = g_dbus_connection_register_object (impl->session_bus,
+                                                 object_path,
+                                                 (GDBusInterfaceInfo *)
+                                                   &org_gtk_private_Cmdline,
+                                                 &vtable, impl, NULL, NULL);
+  /* In theory we should try other paths... */
+  g_assert (object_id != 0);
+
+  g_dbus_connection_call (impl->session_bus,
+                          impl->bus_name,
+                          impl->object_path,
+                          "org.gtk.Application",
+                          "Cmdline",
+                          g_variant_new ("(o aay@a{sv})", object_path,
+                                         arguments, platform_data),
+                          NULL, 0, -1, NULL,
+                          g_application_impl_cmdline_done, impl);
+
+  g_main_loop_run (impl->cmdline_mainloop);
+
+  g_main_context_pop_thread_default (context);
+  g_main_loop_unref (impl->cmdline_mainloop);
+  g_main_context_unref (context);
+  impl->cmdline_mainloop = NULL;
+
   return 1;
 }
 
diff --git a/gio/giotypes.h b/gio/giotypes.h
index 482aa71..64b730b 100644
--- a/gio/giotypes.h
+++ b/gio/giotypes.h
@@ -48,7 +48,7 @@ typedef struct _GZlibCompressor               GZlibCompressor;
 typedef struct _GZlibDecompressor             GZlibDecompressor;
 
 typedef struct _GApplication                  GApplication;
-typedef struct _GApplicationInvocation        GApplicationInvocation;
+typedef struct _GApplicationCommandLine       GApplicationCommandLine;
 typedef struct _GSettingsBackend              GSettingsBackend;
 typedef struct _GSettings                     GSettings;
 typedef struct _GPermission                   GPermission;



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