[gimp/blend-tool-fun: 86/163] app: batch commands won't run on existing instance.



commit e4f78c0fc5c96b32f8f35ea532173aa43620f412
Author: Jehan <jehan girinstud io>
Date:   Sat Jul 11 14:56:13 2015 +0200

    app: batch commands won't run on existing instance.

 app/gui/dbus-service.xml  |    6 ++
 app/gui/gimpdbusservice.c |  147 +++++++++++++++++++++++++++++++++++++++------
 app/main.c                |    3 +
 app/unique.c              |   82 ++++++++++++++++++++++++-
 app/unique.h              |    3 +
 5 files changed, 219 insertions(+), 22 deletions(-)
---
diff --git a/app/gui/dbus-service.xml b/app/gui/dbus-service.xml
index 9324ad6..5badd9b 100644
--- a/app/gui/dbus-service.xml
+++ b/app/gui/dbus-service.xml
@@ -14,6 +14,12 @@
       <arg type="b" name="success" direction="out" />
     </method>
 
+    <method name="BatchRun">
+      <arg type="s" name="interpreter" direction="in" />
+      <arg type="s" name="command" direction="in" />
+      <arg type="b" name="success" direction="out" />
+    </method>
+
     <method name="Activate" />
 
     <signal name="Opened">
diff --git a/app/gui/gimpdbusservice.c b/app/gui/gimpdbusservice.c
index c9598c0..4bcdd5c 100644
--- a/app/gui/gimpdbusservice.c
+++ b/app/gui/gimpdbusservice.c
@@ -34,6 +34,12 @@
 #include "display/gimpdisplay.h"
 #include "display/gimpdisplayshell.h"
 
+/* Dirty hack since we are not supposed to include batch.h
+ * from an app/ subdir. DBus is a special case. */
+#define GIMP_APP_GLUE_COMPILATION
+#include "batch.h"
+#undef  GIMP_APP_GLUE_COMPILATION
+
 #include "gimpdbusservice.h"
 
 
@@ -41,8 +47,10 @@ typedef struct
 {
   GFile    *file;
   gboolean  as_new;
-} OpenData;
 
+  gchar    *interpreter;
+  gchar    *command;
+} IdleData;
 
 static void       gimp_dbus_service_ui_iface_init  (GimpDBusServiceUIIface *iface);
 
@@ -59,6 +67,11 @@ static gboolean   gimp_dbus_service_open_as_new    (GimpDBusServiceUI     *servi
                                                     GDBusMethodInvocation *invocation,
                                                     const gchar           *uri);
 
+static gboolean   gimp_dbus_service_batch_run      (GimpDBusServiceUI     *service,
+                                                    GDBusMethodInvocation *invocation,
+                                                    const gchar           *batch_interpreter,
+                                                    const gchar           *batch_command);
+
 static void       gimp_dbus_service_gimp_opened    (Gimp                  *gimp,
                                                    GFile                 *file,
                                                    GimpDBusService       *service);
@@ -66,12 +79,18 @@ static void       gimp_dbus_service_gimp_opened    (Gimp                  *gimp,
 static gboolean   gimp_dbus_service_queue_open     (GimpDBusService       *service,
                                                     const gchar           *uri,
                                                     gboolean               as_new);
+static gboolean   gimp_dbus_service_queue_batch    (GimpDBusService       *service,
+                                                    const gchar           *interpreter,
+                                                    const gchar           *command);
 
-static gboolean   gimp_dbus_service_open_idle      (GimpDBusService       *service);
-static OpenData * gimp_dbus_service_open_data_new  (GimpDBusService       *service,
+static gboolean   gimp_dbus_service_process_idle   (GimpDBusService       *service);
+static IdleData * gimp_dbus_service_open_data_new  (GimpDBusService       *service,
                                                     const gchar           *uri,
                                                     gboolean               as_new);
-static void       gimp_dbus_service_open_data_free (OpenData              *data);
+static IdleData * gimp_dbus_service_batch_data_new (GimpDBusService       *service,
+                                                    const gchar           *interpreter,
+                                                    const gchar           *command);
+static void       gimp_dbus_service_idle_data_free (IdleData              *data);
 
 
 G_DEFINE_TYPE_WITH_CODE (GimpDBusService, gimp_dbus_service,
@@ -103,6 +122,7 @@ gimp_dbus_service_ui_iface_init (GimpDBusServiceUIIface *iface)
   iface->handle_activate    = gimp_dbus_service_activate;
   iface->handle_open        = gimp_dbus_service_open;
   iface->handle_open_as_new = gimp_dbus_service_open_as_new;
+  iface->handle_batch_run   = gimp_dbus_service_batch_run;
 }
 
 GObject *
@@ -136,7 +156,7 @@ gimp_dbus_service_dispose (GObject *object)
 
   while (! g_queue_is_empty (service->queue))
     {
-      gimp_dbus_service_open_data_free (g_queue_pop_head (service->queue));
+      gimp_dbus_service_idle_data_free (g_queue_pop_head (service->queue));
     }
 
   G_OBJECT_CLASS (parent_class)->dispose (object);
@@ -210,6 +230,23 @@ gimp_dbus_service_open_as_new (GimpDBusServiceUI     *service,
   return TRUE;
 }
 
+gboolean
+gimp_dbus_service_batch_run (GimpDBusServiceUI     *service,
+                             GDBusMethodInvocation *invocation,
+                             const gchar           *batch_interpreter,
+                             const gchar           *batch_command)
+{
+  gboolean success;
+
+  success = gimp_dbus_service_queue_batch (GIMP_DBUS_SERVICE (service),
+                                           batch_interpreter,
+                                           batch_command);
+
+  gimp_dbus_service_ui_complete_batch_run (service, invocation, success);
+
+  return TRUE;
+}
+
 static void
 gimp_dbus_service_gimp_opened (Gimp            *gimp,
                               GFile           *file,
@@ -240,7 +277,41 @@ gimp_dbus_service_queue_open (GimpDBusService *service,
 
       g_source_set_priority (service->source, G_PRIORITY_LOW);
       g_source_set_callback (service->source,
-                             (GSourceFunc) gimp_dbus_service_open_idle, service,
+                             (GSourceFunc) gimp_dbus_service_process_idle,
+                             service,
+                             NULL);
+      g_source_attach (service->source, NULL);
+      g_source_unref (service->source);
+    }
+
+  /*  The call always succeeds as it is handled in one way or another.
+   *  Even presenting an error message is considered success ;-)
+   */
+  return TRUE;
+}
+
+/*
+ * Adds a request to run a batch command to the end of the queue and
+ * starts an idle source if it is not already running.
+ */
+static gboolean
+gimp_dbus_service_queue_batch (GimpDBusService *service,
+                               const gchar     *interpreter,
+                               const gchar     *command)
+{
+  g_queue_push_tail (service->queue,
+                     gimp_dbus_service_batch_data_new (service,
+                                                       interpreter,
+                                                       command));
+
+  if (! service->source)
+    {
+      service->source = g_idle_source_new ();
+
+      g_source_set_priority (service->source, G_PRIORITY_LOW);
+      g_source_set_callback (service->source,
+                             (GSourceFunc) gimp_dbus_service_process_idle,
+                             service,
                              NULL);
       g_source_attach (service->source, NULL);
       g_source_unref (service->source);
@@ -258,9 +329,9 @@ gimp_dbus_service_queue_open (GimpDBusService *service,
  * removed.
  */
 static gboolean
-gimp_dbus_service_open_idle (GimpDBusService *service)
+gimp_dbus_service_process_idle (GimpDBusService *service)
 {
-  OpenData *data;
+  IdleData *data;
 
   if (! service->gimp->restored)
     return TRUE;
@@ -269,11 +340,20 @@ gimp_dbus_service_open_idle (GimpDBusService *service)
 
   if (data)
     {
-      file_open_from_command_line (service->gimp, data->file, data->as_new,
-                                   NULL, /* FIXME monitor */
-                                   0 /* FIXME monitor */);
 
-      gimp_dbus_service_open_data_free (data);
+      if (data->file)
+        file_open_from_command_line (service->gimp, data->file, data->as_new,
+                                     NULL, /* FIXME monitor */
+                                     0 /* FIXME monitor */);
+      if (data->command)
+        {
+          const gchar *commands[2] = {data->command, 0};
+
+          batch_run (service->gimp, data->interpreter,
+                     commands);
+        }
+
+      gimp_dbus_service_idle_data_free (data);
 
       return TRUE;
     }
@@ -283,22 +363,51 @@ gimp_dbus_service_open_idle (GimpDBusService *service)
   return FALSE;
 }
 
-static OpenData *
+static IdleData *
 gimp_dbus_service_open_data_new (GimpDBusService *service,
                                  const gchar     *uri,
                                  gboolean         as_new)
 {
-  OpenData *data = g_slice_new (OpenData);
+  IdleData *data    = g_slice_new (IdleData);
+
+  data->file        = g_file_new_for_uri (uri);
+  data->as_new      = as_new;
+  data->interpreter = NULL;
+  data->command     = NULL;
+
+  return data;
+}
+
+static IdleData *
+gimp_dbus_service_batch_data_new (GimpDBusService *service,
+                                  const gchar     *interpreter,
+                                  const gchar     *command)
+{
+  IdleData *data = g_slice_new (IdleData);
+
+  data->file     = NULL;
+  data->as_new   = FALSE;
 
-  data->file   = g_file_new_for_uri (uri);
-  data->as_new = as_new;
+  data->command  = g_strdup (command);
+
+  if (g_strcmp0 (interpreter, "") == 0)
+    data->interpreter = NULL;
+  else
+    data->interpreter = g_strdup (interpreter);
 
   return data;
 }
 
 static void
-gimp_dbus_service_open_data_free (OpenData *data)
+gimp_dbus_service_idle_data_free (IdleData *data)
 {
-  g_object_unref (data->file);
-  g_slice_free (OpenData, data);
+  if (data->file)
+    g_object_unref (data->file);
+
+  if (data->command)
+    g_free (data->command);
+  if (data->interpreter)
+    g_free (data->interpreter);
+
+  g_slice_free (IdleData, data);
 }
diff --git a/app/main.c b/app/main.c
index 4c61ef0..2b348cc 100644
--- a/app/main.c
+++ b/app/main.c
@@ -483,6 +483,9 @@ main (int    argc,
        g_print ("%s\n",
                 _("Another GIMP instance is already running."));
 
+      if (batch_commands)
+        gimp_unique_batch_run (batch_interpreter, batch_commands);
+
       gdk_notify_startup_complete ();
 
       return EXIT_SUCCESS;
diff --git a/app/unique.c b/app/unique.c
index 55e63e1..cea778d 100644
--- a/app/unique.c
+++ b/app/unique.c
@@ -25,6 +25,11 @@
 
 #include "core/core-types.h"
 
+#ifndef GIMP_CONSOLE_COMPILATION
+/*  for the DBus service names  */
+#include "gui/gimpdbusservice.h"
+#endif
+
 #include "unique.h"
 
 
@@ -34,6 +39,8 @@ static gboolean  gimp_unique_dbus_open  (const gchar **filenames,
 static gboolean  gimp_unique_win32_open (const gchar **filenames,
                                         gboolean      as_new);
 #endif
+static gboolean  gimp_unique_dbus_batch_run (const gchar  *batch_interpreter,
+                                             const gchar **batch_commands);
 
 gboolean
 gimp_unique_open (const gchar **filenames,
@@ -46,15 +53,25 @@ gimp_unique_open (const gchar **filenames,
 #endif
 }
 
+gboolean
+gimp_unique_batch_run (const gchar  *batch_interpreter,
+                       const gchar **batch_commands)
+{
+#ifdef G_OS_WIN32
+  g_printerr ("Batch commands cannot be run in existing instance in Win32.\n");
+  return FALSE;
+#else
+  return gimp_unique_dbus_batch_run (batch_interpreter,
+                                     batch_commands);
+#endif
+}
+
 static gboolean
 gimp_unique_dbus_open (const gchar **filenames,
                       gboolean      as_new)
 {
 #ifndef GIMP_CONSOLE_COMPILATION
 
-/*  for the DBus service names  */
-#include "gui/gimpdbusservice.h"
-
   GDBusConnection *connection;
   GError          *error = NULL;
 
@@ -211,3 +228,62 @@ gimp_unique_win32_open (const gchar **filenames,
 }
 
 #endif  /* G_OS_WIN32 */
+
+static gboolean
+gimp_unique_dbus_batch_run (const gchar  *batch_interpreter,
+                            const gchar **batch_commands)
+{
+#ifndef GIMP_CONSOLE_COMPILATION
+
+  GDBusConnection *connection;
+  GError          *error = NULL;
+
+  connection = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, &error);
+
+  if (connection)
+    {
+      const gchar *method = "BatchRun";
+      gboolean     success = TRUE;
+      gint         i;
+
+      for (i = 0; batch_commands[i] && success; i++)
+        {
+          GVariant    *result;
+          const gchar *interpreter;
+
+          /* NULL is not a valid string GVariant. */
+          interpreter = batch_interpreter ? batch_interpreter : "";
+
+          result = g_dbus_connection_call_sync (connection,
+                                                GIMP_DBUS_SERVICE_NAME,
+                                                GIMP_DBUS_SERVICE_PATH,
+                                                GIMP_DBUS_INTERFACE_NAME,
+                                                method,
+                                                g_variant_new ("(ss)",
+                                                               interpreter,
+                                                               batch_commands[i]),
+                                                NULL,
+                                                G_DBUS_CALL_FLAGS_NO_AUTO_START,
+                                                -1,
+                                                NULL, NULL);
+
+
+          if (result)
+            g_variant_unref (result);
+          else
+            success = FALSE;
+        }
+
+      g_object_unref (connection);
+
+      return success;
+    }
+  else
+    {
+      g_printerr ("%s\n", error->message);
+      g_clear_error (&error);
+    }
+#endif
+
+  return FALSE;
+}
diff --git a/app/unique.h b/app/unique.h
index 68f05ca..d775fe6 100644
--- a/app/unique.h
+++ b/app/unique.h
@@ -22,5 +22,8 @@
 gboolean gimp_unique_open (const gchar **filenames,
                           gboolean      as_new);
 
+gboolean gimp_unique_batch_run (const gchar  *batch_interpreter,
+                                const gchar **batch_commands);
+
 
 #endif /* __UNIQUE_H__ */


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