[gimp] app: Add in gimpconsoleapp and gimpcoreapp interface



commit 1ee1224d05f691d1e99aac3c67c6080f83482ff6
Author: Lukas Oberhuber <lukaso gmail com>
Date:   Mon Feb 7 10:02:19 2022 +0000

    app: Add in gimpconsoleapp and gimpcoreapp interface
    
    GimpApp is a GtkApplication
    GimpCoreApp is an interface for common functions
    GimpConsoleApp is a GApplication (to avoid linking in Gtk)

 app/Makefile.am         |   6 +-
 app/app.c               | 140 +++++++++++++++++-----------
 app/gimpapp.c           | 191 --------------------------------------
 app/gimpconsoleapp.c    |  65 +++++++++++++
 app/gimpconsoleapp.h    |  30 ++++++
 app/gimpcoreapp.c       | 239 ++++++++++++++++++++++++++++++++++++++++++++++++
 app/gimpcoreapp.h       |  83 +++++++++++++++++
 app/gui/Makefile.am     |   2 +
 app/gui/gimpapp.c       |  79 ++++++++++++++++
 app/{ => gui}/gimpapp.h |  28 ++----
 app/gui/gui.c           |   4 +-
 app/gui/gui.h           |   3 +-
 app/gui/meson.build     |   1 +
 app/gui/splash.c        |   6 +-
 app/gui/splash.h        |   5 +-
 app/meson.build         |   3 +-
 16 files changed, 611 insertions(+), 274 deletions(-)
---
diff --git a/app/Makefile.am b/app/Makefile.am
index 07bae5532e..8fea0e4569 100644
--- a/app/Makefile.am
+++ b/app/Makefile.am
@@ -57,8 +57,10 @@ libapp_sources = \
        app.h                   \
        errors.c                \
        errors.h                \
-       gimpapp.c               \
-       gimpapp.h               \
+       gimpcoreapp.c           \
+       gimpcoreapp.h           \
+       gimpconsoleapp.c        \
+       gimpconsoleapp.h        \
        language.c              \
        language.h              \
        sanity.c                \
diff --git a/app/app.c b/app/app.c
index 8d6ac3f2fc..515618f900 100644
--- a/app/app.c
+++ b/app/app.c
@@ -67,7 +67,10 @@
 
 #include "app.h"
 #include "errors.h"
-#include "gimpapp.h"
+#ifndef GIMP_CONSOLE_COMPILATION
+#include "gui/gimpapp.h"
+#endif
+#include "gimpconsoleapp.h"
 #include "language.h"
 #include "sanity.h"
 #include "gimp-debug.h"
@@ -85,7 +88,7 @@ static void       app_restore_after_callback (Gimp               *gimp,
                                               GimpInitStatusFunc  status_callback);
 static gboolean   app_exit_after_callback    (Gimp               *gimp,
                                               gboolean            kill_it,
-                                              GimpApp           **app);
+                                              GApplication      **app);
 
 #if 0
 /*  left here as documentation how to do compat enums  */
@@ -164,18 +167,25 @@ app_exit (gint status)
 }
 
 static void
-app_activate_callback (GApplication *gapp,
-                       gpointer      user_data)
+app_activate_callback (GimpCoreApp *app,
+                       gpointer     user_data)
 {
-  GimpApp            *app                = GIMP_APP (gapp);
   Gimp               *gimp               = NULL;
   GimpInitStatusFunc  update_status_func = NULL;
+  const gchar       **filenames;
+  const gchar        *current_language;
+  gchar              *prev_language      = NULL;
+  GError             *font_error         = NULL;
+
+  g_return_if_fail (GIMP_IS_CORE_APP (app));
 
-  gimp = gimp_app_get_gimp (app);
+  gimp = gimp_core_app_get_gimp (app);
+
+  gimp_core_app_set_exit_status (app, EXIT_SUCCESS);
 
 #ifndef GIMP_CONSOLE_COMPILATION
   if (! gimp->no_interface)
-    update_status_func = gui_init (gimp, gimp_app_get_no_splash (app), gapp, NULL);
+    update_status_func = gui_init (gimp, gimp_app_get_no_splash (GIMP_APP (app)), GIMP_APP (app), NULL);
 #endif
 
   if (! update_status_func)
@@ -186,8 +196,19 @@ app_activate_callback (GApplication *gapp,
    */
   gimp_initialize (gimp, update_status_func);
 
+  g_object_get (gimp->edit_config,
+                "prev-language", &prev_language,
+                NULL);
+  /* Language was already initialized. I call this again only to get the
+   * actual language information.
+   */
+  current_language = language_init (NULL);
+  gimp->query_all = (prev_language == NULL ||
+                     g_strcmp0 (prev_language, current_language) != 0);
+  g_free (prev_language);
+
   /*  Load all data files */
-  gimp_restore (gimp, update_status_func, NULL);
+  gimp_restore (gimp, update_status_func, &font_error);
 
   /*  enable autosave late so we don't autosave when the
    *  monitor resolution is set in gui_init()
@@ -199,11 +220,12 @@ app_activate_callback (GApplication *gapp,
    */
   gimp_update_auto_check (gimp->edit_config, gimp);
 
-  /* Set this after gimp_update_auto_check(). This will be used for the
-   * next run.
-   */
+  /* Setting properties to be used for the next run.  */
   g_object_set (gimp->edit_config,
+                /* Set this after gimp_update_auto_check(). */
                 "config-version", GIMP_VERSION,
+                /* Set this after gimp_restore(). */
+                "prev-language",  current_language,
                 NULL);
 
 #ifndef GIMP_CONSOLE_COMPILATION
@@ -232,7 +254,7 @@ app_activate_callback (GApplication *gapp,
                                               gimp_get_user_context (gimp),
                                               NULL,
                                               file,
-                                              gimp_app_get_as_new (app),
+                                              gimp_core_app_get_as_new (app),
                                               initial_monitor,
                                               &status, &error);
               if (image)
@@ -263,10 +285,9 @@ app_activate_callback (GApplication *gapp,
     }
 #endif
 
-  //XXX
-#if 0
   /*  Load the images given on the command-line. */
-  if (filenames)
+  filenames = gimp_core_app_get_filenames (app);
+  if (filenames != NULL)
     {
       gint i;
 
@@ -277,25 +298,48 @@ app_activate_callback (GApplication *gapp,
               GFile *file = g_file_new_for_commandline_arg (filenames[i]);
 
               file_open_from_command_line (gimp, file,
-                                           gimp_app_get_as_new (app),
+                                           gimp_core_app_get_as_new (app),
                                            initial_monitor);
 
               g_object_unref (file);
             }
         }
     }
-#endif
 
   /* The software is now fully loaded and ready to be used and get
    * external input.
    */
   gimp->initialized = TRUE;
 
+  if (font_error)
+    {
+      gimp_message_literal (gimp, NULL,
+                            GIMP_MESSAGE_INFO,
+                            font_error->message);
+      g_error_free (font_error);
+    }
+
   if (app)
     {
-      gimp_batch_run (gimp,
-                      gimp_app_get_batch_interpreter (app),
-                      gimp_app_get_batch_commands (app));
+      gint batch_retval;
+
+      batch_retval = gimp_batch_run (gimp,
+                      gimp_core_app_get_batch_interpreter (app),
+                      gimp_core_app_get_batch_commands (app));
+
+      if (gimp_core_app_get_quit (app))
+        {
+          /*  Only if we are in batch mode, we want to exit with the
+           *  return value of the batch command.
+           */
+            gimp_core_app_set_exit_status (app, batch_retval);
+
+          /* Return value, needed for the signal call; let's just ignore the
+          * result. */
+          gboolean cb_retval;
+
+          g_signal_emit_by_name (gimp, "exit", TRUE, &cb_retval);
+        }
     }
 }
 
@@ -324,12 +368,12 @@ app_run (const gchar         *full_prog_name,
          GimpPDBCompatMode    pdb_compat_mode,
          const gchar         *backtrace_file)
 {
-  Gimp               *gimp               = NULL;
-  GApplication       *app                = NULL;
-  GFile              *default_folder     = NULL;
-  GFile              *gimpdir            = NULL;
-  const gchar        *abort_message      = NULL;
-  gint                retval             = EXIT_SUCCESS;
+  Gimp               *gimp           = NULL;
+  GApplication       *app            = NULL;
+  GFile              *default_folder = NULL;
+  GFile              *gimpdir        = NULL;
+  const gchar        *abort_message  = NULL;
+  gint                retval         = EXIT_SUCCESS;
 
   if (filenames && filenames[0] && ! filenames[1] &&
       g_file_test (filenames[0], G_FILE_TEST_IS_DIR))
@@ -371,7 +415,11 @@ app_run (const gchar         *full_prog_name,
 
   g_clear_object (&default_folder);
 
-  app = gimp_app_new (gimp, no_splash, as_new, batch_interpreter, batch_commands);
+#ifndef GIMP_CONSOLE_COMPILATION
+  app = gimp_app_new (gimp, no_splash, quit, as_new, filenames, batch_interpreter, batch_commands);
+#else
+  app = gimp_console_app_new (gimp, quit, as_new, filenames, batch_interpreter, batch_commands);
+#endif
 
   gimp_cpu_accel_set_use (use_cpu_accel);
 
@@ -433,30 +481,15 @@ app_run (const gchar         *full_prog_name,
 
   g_signal_connect_after (gimp, "exit",
                           G_CALLBACK (app_exit_after_callback),
-                          &run_loop);
-
-#ifndef GIMP_CONSOLE_COMPILATION
-  if (run_loop && ! no_interface)
-    {
-      /* Before opening images from command line, check for salvaged images
-       * and query interactively to know if we should recover or discard
-       * them.
-       */
-      GList *recovered_files;
-      GList *iter;
+                          &app);
 
-      recovered_files = errors_recovered ();
-      if (recovered_files &&
-          gui_recover (g_list_length (recovered_files)))
-        {
-          for (iter = recovered_files; iter; iter = iter->next)
-            {
-              GFile             *file;
-              GimpImage         *image;
-              GError            *error = NULL;
-              GimpPDBStatusType  status;
+  g_signal_connect (app, "activate",
+                    G_CALLBACK (app_activate_callback),
+                    NULL);
+  retval = g_application_run (app, 0, NULL);
 
-  g_application_run (app, 0, NULL);
+  if (! retval)
+    retval = gimp_core_app_get_exit_status (GIMP_CORE_APP (app));
 
   if (gimp->be_verbose)
     g_print ("EXIT: %s\n", G_STRFUNC);
@@ -505,9 +538,9 @@ app_restore_after_callback (Gimp               *gimp,
 }
 
 static gboolean
-app_exit_after_callback (Gimp       *gimp,
-                         gboolean    kill_it,
-                         GimpApp   **app)
+app_exit_after_callback (Gimp          *gimp,
+                         gboolean       kill_it,
+                         GApplication **app)
 {
   if (gimp->be_verbose)
     g_print ("EXIT: %s\n", G_STRFUNC);
@@ -524,7 +557,6 @@ app_exit_after_callback (Gimp       *gimp,
 #ifdef GIMP_UNSTABLE
 
   g_application_quit (G_APPLICATION (*app));
-  *app = NULL;
 
 #else
 
@@ -532,7 +564,7 @@ app_exit_after_callback (Gimp       *gimp,
 
   gegl_exit ();
 
-  exit (EXIT_SUCCESS);
+  exit (gimp_core_app_get_exit_status (GIMP_CORE_APP (*app)));
 
 #endif
 
diff --git a/app/gimpconsoleapp.c b/app/gimpconsoleapp.c
new file mode 100644
index 0000000000..f9325991f1
--- /dev/null
+++ b/app/gimpconsoleapp.c
@@ -0,0 +1,65 @@
+/* GIMP - The GNU Image Manipulation Program
+ * Copyright (C) 1995-1997 Peter Mattis and Spencer Kimball
+ *
+ * gimpapp.c
+ * Copyright (C) 2021 Niels De Graef <nielsdegraef gmail com>
+ *
+ * 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
+ * Library 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, see
+ * <https://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+
+#include "gimpconsoleapp.h"
+
+#include "libgimpbase/gimpbase.h"
+
+struct _GimpConsoleApp
+{
+  GApplication parent_instance;
+};
+
+G_DEFINE_TYPE_WITH_CODE (GimpConsoleApp, gimp_console_app, G_TYPE_APPLICATION,
+                         G_IMPLEMENT_INTERFACE (GIMP_TYPE_CORE_APP,
+                                                gimp_console_app_class_init))
+
+
+static void
+gimp_console_app_class_init (GimpConsoleAppClass *klass)
+{
+  GObjectClass *gobj_class = G_OBJECT_CLASS (klass);
+
+  gobj_class->finalize     = gimp_core_app_finalize;
+}
+
+static void
+gimp_console_app_init (GimpConsoleApp *self)
+{
+}
+
+/*  public functions  */
+
+GApplication *
+gimp_console_app_new (Gimp        *gimp,
+                      gboolean     quit,
+                      gboolean     as_new,
+                      const char **filenames,
+                      const char  *batch_interpreter,
+                      const char **batch_commands)
+{
+  GimpConsoleApp *app;
+
+  app = g_object_new (GIMP_TYPE_CONSOLE_APP, NULL);
+
+  gimp_core_app_set_values (GIMP_CORE_APP (app), gimp,
+                            quit, as_new, filenames,
+                            batch_interpreter, batch_commands);
+
+  return G_APPLICATION (app);
+}
diff --git a/app/gimpconsoleapp.h b/app/gimpconsoleapp.h
new file mode 100644
index 0000000000..acb717f1e8
--- /dev/null
+++ b/app/gimpconsoleapp.h
@@ -0,0 +1,30 @@
+
+/* GIMP - The GNU Image Manipulation Program
+ * Copyright (C) 1995-1997 Peter Mattis and Spencer Kimball
+ *
+ * gimpapp.h
+ * Copyright (C) 2021 Niels De Graef <nielsdegraef gmail com>
+ *
+ * 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
+ * Library 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, see
+ * <https://www.gnu.org/licenses/>.
+ */
+
+#pragma once
+
+#include "gimpcoreapp.h"
+
+#define GIMP_TYPE_CONSOLE_APP (gimp_console_app_get_type ())
+G_DECLARE_FINAL_TYPE (GimpConsoleApp, gimp_console_app, GIMP, CONSOLE_APP, GApplication)
+
+GApplication  *    gimp_console_app_new                   (Gimp         *gimp,
+                                                           gboolean      quit,
+                                                           gboolean      as_new,
+                                                           const char  **filenames,
+                                                           const char   *batch_interpreter,
+                                                           const char  **batch_commands);
diff --git a/app/gimpcoreapp.c b/app/gimpcoreapp.c
new file mode 100644
index 0000000000..140b8fc49c
--- /dev/null
+++ b/app/gimpcoreapp.c
@@ -0,0 +1,239 @@
+/* GIMP - The GNU Image Manipulation Program
+ * Copyright (C) 1995-1997 Peter Mattis and Spencer Kimball
+ *
+ * gimpapp.c
+ * Copyright (C) 2022 Lukas Oberhuber <lukaso gmail com>
+ *
+ * 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
+ * Library 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, see
+ * <https://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+
+#include "gimpcoreapp.h"
+
+#include "libgimpbase/gimpbase.h"
+
+#define GIMP_CORE_APP_GET_PRIVATE(obj) (gimp_core_app_get_private ((GimpCoreApp *) (obj)))
+
+enum
+{
+  PROP_0,
+  PROP_GIMP,
+  N_PROPS
+};
+
+typedef struct _GimpCoreAppPrivate GimpCoreAppPrivate;
+
+struct _GimpCoreAppPrivate
+{
+  Gimp          *gimp;
+  gboolean       quit;
+  gboolean       as_new;
+  const gchar  **filenames;
+  const gchar   *batch_interpreter;
+  const gchar  **batch_commands;
+  gint           exit_status;
+};
+
+/*  local function prototypes  */
+
+static GimpCoreAppPrivate *
+              gimp_core_app_get_private      (GimpCoreApp        *app);
+static void   gimp_core_app_private_finalize (GimpCoreAppPrivate *private);
+
+G_DEFINE_INTERFACE (GimpCoreApp, gimp_core_app, G_TYPE_OBJECT)
+
+static void
+gimp_core_app_default_init (GimpCoreAppInterface *iface)
+{
+  /* add properties and signals to the interface here */
+  g_object_interface_install_property (iface,
+                                       g_param_spec_object ("gimp",
+                                                            "GIMP",
+                                                            "GIMP root object",
+                                                            GIMP_TYPE_GIMP,
+                                                            GIMP_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
+
+  iface->get_gimp              = gimp_core_app_get_gimp;
+  iface->get_quit              = gimp_core_app_get_quit;
+  iface->get_as_new            = gimp_core_app_get_as_new;
+  iface->get_filenames         = gimp_core_app_get_filenames;
+  iface->get_batch_interpreter = gimp_core_app_get_batch_interpreter;
+  iface->get_batch_commands    = gimp_core_app_get_batch_commands;
+  iface->set_exit_status       = gimp_core_app_set_exit_status;
+  iface->get_exit_status       = gimp_core_app_get_exit_status;
+  iface->set_values            = gimp_core_app_set_values;
+}
+
+void
+gimp_core_app_finalize (GObject *object)
+{
+  GimpCoreAppPrivate *private = gimp_core_app_get_private ((GimpCoreApp *) object);
+
+  gimp_core_app_private_finalize (private);
+}
+
+Gimp *
+gimp_core_app_get_gimp (GimpCoreApp *self)
+{
+  GimpCoreAppPrivate *private;
+
+  g_return_val_if_fail (GIMP_IS_CORE_APP (self), NULL);
+
+  private = GIMP_CORE_APP_GET_PRIVATE (self);
+
+  return private->gimp;
+}
+
+gboolean
+gimp_core_app_get_quit (GimpCoreApp *self)
+{
+  GimpCoreAppPrivate *private;
+
+  g_return_val_if_fail (GIMP_IS_CORE_APP (self), FALSE);
+
+  private = GIMP_CORE_APP_GET_PRIVATE (self);
+
+  return private->quit;
+}
+
+gboolean
+gimp_core_app_get_as_new (GimpCoreApp *self)
+{
+  GimpCoreAppPrivate *private;
+
+  g_return_val_if_fail (GIMP_IS_CORE_APP (self), FALSE);
+
+  private = GIMP_CORE_APP_GET_PRIVATE (self);
+
+  return private->as_new;
+}
+
+const char **
+gimp_core_app_get_filenames (GimpCoreApp *self)
+{
+  GimpCoreAppPrivate *private;
+
+  g_return_val_if_fail (GIMP_IS_CORE_APP (self), NULL);
+
+  private = GIMP_CORE_APP_GET_PRIVATE (self);
+
+  return private->filenames;
+}
+
+const char *
+gimp_core_app_get_batch_interpreter (GimpCoreApp *self)
+{
+  GimpCoreAppPrivate *private;
+
+  g_return_val_if_fail (GIMP_IS_CORE_APP (self), NULL);
+
+  private = GIMP_CORE_APP_GET_PRIVATE (self);
+
+  return private->batch_interpreter;
+}
+
+const char **
+gimp_core_app_get_batch_commands (GimpCoreApp *self)
+{
+  GimpCoreAppPrivate *private;
+
+  g_return_val_if_fail (GIMP_IS_CORE_APP (self), NULL);
+
+  private = GIMP_CORE_APP_GET_PRIVATE (self);
+
+  return private->batch_commands;
+}
+
+void
+gimp_core_app_set_exit_status (GimpCoreApp *self, gint exit_status)
+{
+  GimpCoreAppPrivate *private;
+
+  g_return_if_fail (GIMP_IS_CORE_APP (self));
+
+  private = GIMP_CORE_APP_GET_PRIVATE (self);
+
+  private->exit_status = exit_status;
+}
+
+gint
+gimp_core_app_get_exit_status (GimpCoreApp *self)
+{
+  GimpCoreAppPrivate *private;
+
+  g_return_val_if_fail (GIMP_IS_CORE_APP (self), EXIT_FAILURE);
+
+  private = GIMP_CORE_APP_GET_PRIVATE (self);
+
+  return private->exit_status;
+}
+
+void
+gimp_core_app_set_values(GimpCoreApp  *self,
+                         Gimp         *gimp,
+                         gboolean      quit,
+                         gboolean      as_new,
+                         const gchar **filenames,
+                         const gchar  *batch_interpreter,
+                         const gchar **batch_commands)
+{
+  GimpCoreAppPrivate *private;
+
+  g_return_if_fail (GIMP_IS_CORE_APP (self));
+
+  private = GIMP_CORE_APP_GET_PRIVATE (self);
+
+  private->gimp              = gimp;
+  private->quit              = quit;
+  private->as_new            = as_new;
+  private->filenames         = filenames;
+  private->batch_interpreter = batch_interpreter;
+  private->batch_commands    = batch_commands;
+}
+
+/*  Private functions  */
+
+static void
+gimp_core_app_private_finalize (GimpCoreAppPrivate *private)
+{
+  g_slice_free (GimpCoreAppPrivate, private);
+
+  g_clear_object (&private->gimp);
+}
+
+static GimpCoreAppPrivate *
+gimp_core_app_get_private (GimpCoreApp *app)
+{
+  GimpCoreAppPrivate *private;
+
+  static GQuark private_key = 0;
+
+  g_return_val_if_fail (GIMP_IS_CORE_APP (app), NULL);
+
+  if (! private_key)
+    private_key = g_quark_from_static_string ("gimp-core-app-private");
+
+  private = g_object_get_qdata ((GObject *) app, private_key);
+
+  if (! private)
+    {
+      private = g_slice_new0 (GimpCoreAppPrivate);
+
+      g_object_set_qdata_full ((GObject *) app, private_key, private,
+                               (GDestroyNotify) gimp_core_app_private_finalize);
+
+      /* g_signal_connect (view, "destroy",
+                        G_CALLBACK (gimp_core_app_private_dispose),
+                        private); */
+    }
+
+  return private;
+}
diff --git a/app/gimpcoreapp.h b/app/gimpcoreapp.h
new file mode 100644
index 0000000000..5967adbdf6
--- /dev/null
+++ b/app/gimpcoreapp.h
@@ -0,0 +1,83 @@
+
+/* GIMP - The GNU Image Manipulation Program
+ * Copyright (C) 1995-1997 Peter Mattis and Spencer Kimball
+ *
+ * gimpcoreapp.h
+ * Copyright (C) 2022 Lukas Oberhuber <lukaso gmail com>
+ *
+ * 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
+ * Library 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, see
+ * <https://www.gnu.org/licenses/>.
+ */
+
+#pragma once
+
+#include <gio/gio.h>
+
+#include "core/core-types.h"
+#include "core/gimp.h"
+
+G_BEGIN_DECLS
+
+#define GIMP_TYPE_CORE_APP gimp_core_app_get_type()
+G_DECLARE_INTERFACE (GimpCoreApp, gimp_core_app, GIMP, CORE_APP, GObject)
+
+struct _GimpCoreAppInterface
+{
+  GTypeInterface parent_iface;
+
+  Gimp *        (*get_gimp)              (GimpCoreApp  *self);
+  gboolean      (*get_quit)              (GimpCoreApp  *self);
+  gboolean      (*get_as_new)            (GimpCoreApp  *self);
+  const char ** (*get_filenames)         (GimpCoreApp *self);
+  const char *  (*get_batch_interpreter) (GimpCoreApp *self);
+  const char ** (*get_batch_commands)    (GimpCoreApp *self);
+  void          (*set_exit_status)       (GimpCoreApp *self,
+                                          gint         exit_status);
+  gint          (*get_exit_status)       (GimpCoreApp *self);
+  void          (*set_values)            (GimpCoreApp *self,
+                                          Gimp        *gimp,
+                                          gboolean     quit,
+                                          gboolean     as_new,
+                                          const char **filenames,
+                                          const char  *batch_interpreter,
+                                          const char **batch_commands);
+
+  /* Padding to allow adding up to 12 new virtual functions without
+   * breaking ABI. */
+  gpointer padding[12];
+};
+
+void               gimp_core_app_finalize              (GObject     *object);
+
+Gimp *             gimp_core_app_get_gimp              (GimpCoreApp *self);
+
+gboolean           gimp_core_app_get_quit              (GimpCoreApp *self);
+
+gboolean           gimp_core_app_get_as_new            (GimpCoreApp *self);
+
+const char **      gimp_core_app_get_filenames         (GimpCoreApp *self);
+
+const char *       gimp_core_app_get_batch_interpreter (GimpCoreApp *self);
+
+const char **      gimp_core_app_get_batch_commands    (GimpCoreApp *self);
+
+void               gimp_core_app_set_exit_status       (GimpCoreApp *self,
+                                                        gint         exit_status);
+
+gboolean           gimp_core_app_get_exit_status       (GimpCoreApp *self);
+
+void               gimp_core_app_set_values            (GimpCoreApp *self,
+                                                        Gimp        *gimp,
+                                                        gboolean     quit,
+                                                        gboolean     as_new,
+                                                        const char **filenames,
+                                                        const char  *batch_interpreter,
+                                                        const char **batch_commands);
+
+G_END_DECLS
diff --git a/app/gui/Makefile.am b/app/gui/Makefile.am
index c43208d2aa..131c5d3fa6 100644
--- a/app/gui/Makefile.am
+++ b/app/gui/Makefile.am
@@ -31,6 +31,8 @@ AM_LDFLAGS = \
 noinst_LIBRARIES = libappgui.a
 
 libappgui_a_sources = \
+       gimpapp.c               \
+       gimpapp.h               \
        gimpdbusservice.c       \
        gimpdbusservice.h       \
        gimpuiconfigurer.c      \
diff --git a/app/gui/gimpapp.c b/app/gui/gimpapp.c
new file mode 100644
index 0000000000..98b9afa541
--- /dev/null
+++ b/app/gui/gimpapp.c
@@ -0,0 +1,79 @@
+/* GIMP - The GNU Image Manipulation Program
+ * Copyright (C) 1995-1997 Peter Mattis and Spencer Kimball
+ *
+ * gimpapp.c
+ * Copyright (C) 2021 Niels De Graef <nielsdegraef gmail com>
+ *
+ * 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
+ * Library 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, see
+ * <https://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+
+#include "gimpapp.h"
+
+#include "libgimpbase/gimpbase.h"
+
+struct _GimpApp
+{
+  GtkApplication parent_instance;
+
+  gboolean       no_splash;
+};
+
+G_DEFINE_TYPE_WITH_CODE (GimpApp, gimp_app, GTK_TYPE_APPLICATION,
+                         G_IMPLEMENT_INTERFACE (GIMP_TYPE_CORE_APP,
+                                                gimp_app_class_init))
+
+
+static void
+gimp_app_class_init (GimpAppClass *klass)
+{
+  GObjectClass *gobj_class = G_OBJECT_CLASS (klass);
+
+  gobj_class->finalize     = gimp_core_app_finalize;
+}
+
+static void
+gimp_app_init (GimpApp *self)
+{
+}
+
+/*  public functions  */
+
+GApplication *
+gimp_app_new (Gimp        *gimp,
+              gboolean     no_splash,
+              gboolean     quit,
+              gboolean     as_new,
+              const char **filenames,
+              const char  *batch_interpreter,
+              const char **batch_commands)
+{
+  GimpApp *app;
+
+  app = g_object_new (GIMP_TYPE_APP, NULL);
+
+  /* We shouldn't have to pass these externally, so I didn't bother making
+   * GObject properties for them. In the end, they should just be parsed by
+   * the GApplication code */
+  app->no_splash         = no_splash;
+
+  gimp_core_app_set_values(GIMP_CORE_APP(app), gimp, quit, as_new, filenames,
+                           batch_interpreter, batch_commands);
+
+  return G_APPLICATION (app);
+}
+
+gboolean
+gimp_app_get_no_splash (GimpApp *self)
+{
+  g_return_val_if_fail (GIMP_IS_APP (self), FALSE);
+  return GIMP_APP (self)->no_splash;
+}
diff --git a/app/gimpapp.h b/app/gui/gimpapp.h
similarity index 50%
rename from app/gimpapp.h
rename to app/gui/gimpapp.h
index 1a8a1c3989..bf4cb18068 100644
--- a/app/gimpapp.h
+++ b/app/gui/gimpapp.h
@@ -1,3 +1,4 @@
+
 /* GIMP - The GNU Image Manipulation Program
  * Copyright (C) 1995-1997 Peter Mattis and Spencer Kimball
  *
@@ -17,30 +18,21 @@
 #ifndef __GIMP_APP_H__
 #define __GIMP_APP_H__
 
-#include <gio/gio.h>
 #include <gtk/gtk.h>
 
-#include "core/core-types.h"
-#include "core/gimp.h"
+#include "gimpcoreapp.h"
 
 #define GIMP_TYPE_APP (gimp_app_get_type ())
 G_DECLARE_FINAL_TYPE (GimpApp, gimp_app, GIMP, APP, GtkApplication)
 
+GApplication * gimp_app_new                   (Gimp        *gimp,
+                                               gboolean     no_splash,
+                                               gboolean     quit,
+                                               gboolean     as_new,
+                                               const char **filenames,
+                                               const char  *batch_interpreter,
+                                               const char **batch_commands);
 
-GApplication  *    gimp_app_new                   (Gimp        *gimp,
-                                                   gboolean     no_splash,
-                                                   gboolean     as_new,
-                                                   const char  *batch_interpreter,
-                                                   const char **batch_commands);
-
-Gimp *             gimp_app_get_gimp              (GimpApp    *self);
-
-gboolean           gimp_app_get_no_splash         (GimpApp    *self);
-
-gboolean           gimp_app_get_as_new            (GimpApp    *self);
-
-const char *       gimp_app_get_batch_interpreter (GimpApp    *self);
-
-const char **      gimp_app_get_batch_commands    (GimpApp    *self);
+gboolean       gimp_app_get_no_splash         (GimpApp     *self);
 
 #endif /* __GIMP_APP_H__ */
diff --git a/app/gui/gui.c b/app/gui/gui.c
index 3dcafd4d60..bf4b099fac 100644
--- a/app/gui/gui.c
+++ b/app/gui/gui.c
@@ -225,7 +225,7 @@ gui_abort (const gchar *abort_message)
 GimpInitStatusFunc
 gui_init (Gimp         *gimp,
           gboolean      no_splash,
-          GApplication *app,
+          GimpApp      *app,
           const gchar  *test_base_dir)
 {
   GimpInitStatusFunc  status_callback = NULL;
@@ -233,7 +233,7 @@ gui_init (Gimp         *gimp,
 
   g_return_val_if_fail (GIMP_IS_GIMP (gimp), NULL);
   g_return_val_if_fail (the_gui_gimp == NULL, NULL);
-  g_return_val_if_fail (G_IS_APPLICATION (app) || app == NULL, NULL);
+  g_return_val_if_fail (GIMP_IS_APP (app) || app == NULL, NULL);
 
   abort_message = gui_sanity_check ();
   if (abort_message)
diff --git a/app/gui/gui.h b/app/gui/gui.h
index af88b08613..e64f5fa1d9 100644
--- a/app/gui/gui.h
+++ b/app/gui/gui.h
@@ -18,13 +18,14 @@
 #ifndef __GUI_H__
 #define __GUI_H__
 
+#include "gimpapp.h"
 
 void               gui_libs_init (GOptionContext *context);
 void               gui_abort     (const gchar    *abort_message);
 
 GimpInitStatusFunc gui_init      (Gimp           *gimp,
                                   gboolean        no_splash,
-                                  GApplication   *app,
+                                  GimpApp        *app,
                                   const gchar    *test_base_dir);
 
 gboolean           gui_recover   (gint            n_recoveries);
diff --git a/app/gui/meson.build b/app/gui/meson.build
index 2883a1f350..e271bb3d02 100644
--- a/app/gui/meson.build
+++ b/app/gui/meson.build
@@ -7,6 +7,7 @@ gimpdbusservice_gen = gnome.gdbus_codegen(
 )
 
 libappgui_sources = [
+  'gimpapp.c',
   'gimpdbusservice.c',
   'gimpuiconfigurer.c',
   'gui-message.c',
diff --git a/app/gui/splash.c b/app/gui/splash.c
index 3ce1bc3d6c..390dfdc88e 100644
--- a/app/gui/splash.c
+++ b/app/gui/splash.c
@@ -112,7 +112,7 @@ void
 splash_create (Gimp         *gimp,
                gboolean      be_verbose,
                GdkMonitor   *monitor,
-               GApplication *app)
+               GimpApp      *app)
 {
   GtkWidget          *frame;
   GtkWidget          *vbox;
@@ -124,7 +124,7 @@ splash_create (Gimp         *gimp,
 
   g_return_if_fail (splash == NULL);
   g_return_if_fail (GDK_IS_MONITOR (monitor));
-  g_return_if_fail (G_IS_APPLICATION (app) || app == NULL);
+  g_return_if_fail (GIMP_IS_APP (app) || app == NULL);
 
   gdk_monitor_get_workarea (monitor, &workarea);
 
@@ -171,7 +171,7 @@ splash_create (Gimp         *gimp,
                   "role",            "gimp-startup",
                   "window-position", GTK_WIN_POS_CENTER,
                   "resizable",       FALSE,
-                  "application",     app,
+                  "application",     GTK_APPLICATION (app),
                   NULL);
 
   /* Don't remove this call, it's necessary to remove decorations on Windows
diff --git a/app/gui/splash.h b/app/gui/splash.h
index c6fb9fdfb3..51e8af63de 100644
--- a/app/gui/splash.h
+++ b/app/gui/splash.h
@@ -18,11 +18,12 @@
 #ifndef __SPLASH_H__
 #define __SPLASH_H__
 
+#include "gimpapp.h"
 
 void   splash_create    (Gimp         *gimp,
                          gboolean      be_verbose,
-                         GdkMonitor   *mointor,
-                         GApplication *app);
+                         GdkMonitor   *monitor,
+                         GimpApp      *app);
 void   splash_destroy   (void);
 
 void   splash_update    (const gchar *label1,
diff --git a/app/meson.build b/app/meson.build
index 9783b164e5..8219b29874 100644
--- a/app/meson.build
+++ b/app/meson.build
@@ -32,7 +32,8 @@ app_debug_files = files(
 libapp_sources = [
   'app.c',
   'errors.c',
-  'gimpapp.c',
+  'gimpcoreapp.c',
+  'gimpconsoleapp.c',
   'gimp-debug.c',
   'gimp-log.c',
   'gimp-update.c',


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