[gimp] Bug 774971 - Display errors outputted by GEGL.



commit b7dd2622d1ba206ba086e8cf08f6f1808fe5c32b
Author: Jehan <jehan girinstud io>
Date:   Wed Jun 7 15:27:33 2017 +0200

    Bug 774971 - Display errors outputted by GEGL.
    
    Add a log handler so that GIMP can display errors outputted by GEGL.
    Since third party code may run in threads and we have no control on
    these, we have to be sure GTK+ code is run in a thread-safe way, hence
    the usage of gdk_threads_add_idle_full(). This was the case here for
    GEGL, and handling GEGL logs the same way as other GIMP logs would
    result in crashes.

 app/errors.c          |   46 +++++++++++++++++++++++++++++++++-------
 app/gui/gui-message.c |   55 ++++++++++++++++++++++++++++++++++++++++++++++++-
 2 files changed, 92 insertions(+), 9 deletions(-)
---
diff --git a/app/errors.c b/app/errors.c
index 406de17..e1520f0 100644
--- a/app/errors.c
+++ b/app/errors.c
@@ -56,14 +56,18 @@ static G_GNUC_NORETURN void  gimp_eek (const gchar *reason,
                                        const gchar *message,
                                        gboolean     use_handler);
 
-static void   gimp_message_log_func (const gchar        *log_domain,
-                                     GLogLevelFlags      flags,
-                                     const gchar        *message,
-                                     gpointer            data);
-static void   gimp_error_log_func   (const gchar        *domain,
-                                     GLogLevelFlags      flags,
-                                     const gchar        *message,
-                                     gpointer            data) G_GNUC_NORETURN;
+static void   gimp_third_party_message_log_func (const gchar        *log_domain,
+                                                 GLogLevelFlags      flags,
+                                                 const gchar        *message,
+                                                 gpointer            data);
+static void   gimp_message_log_func             (const gchar        *log_domain,
+                                                 GLogLevelFlags      flags,
+                                                 const gchar        *message,
+                                                 gpointer            data);
+static void   gimp_error_log_func               (const gchar        *domain,
+                                                 GLogLevelFlags      flags,
+                                                 const gchar        *message,
+                                                 gpointer            data) G_GNUC_NORETURN;
 
 
 
@@ -128,6 +132,9 @@ errors_init (Gimp               *gimp,
                        G_LOG_LEVEL_MESSAGE,
                        gimp_message_log_func, gimp);
 
+  g_log_set_handler ("GEGL",
+                     G_LOG_LEVEL_MESSAGE,
+                     gimp_third_party_message_log_func, gimp);
   g_log_set_handler (NULL,
                      G_LOG_LEVEL_ERROR | G_LOG_FLAG_FATAL,
                      gimp_error_log_func, gimp);
@@ -155,6 +162,29 @@ gimp_terminate (const gchar *message)
 /*  private functions  */
 
 static void
+gimp_third_party_message_log_func (const gchar    *log_domain,
+                                   GLogLevelFlags  flags,
+                                   const gchar    *message,
+                                   gpointer        data)
+{
+  Gimp *gimp = data;
+
+  if (gimp)
+    {
+      /* Whereas all GIMP messages are processed under the same domain,
+       * we need to keep the log domain information for third party
+       * messages.
+       */
+      gimp_show_message (gimp, NULL, GIMP_MESSAGE_WARNING,
+                         log_domain, message);
+    }
+  else
+    {
+      g_printerr ("%s: %s\n\n", log_domain, message);
+    }
+}
+
+static void
 gimp_message_log_func (const gchar    *log_domain,
                        GLogLevelFlags  flags,
                        const gchar    *message,
diff --git a/app/gui/gui-message.c b/app/gui/gui-message.c
index 368ce90..8f83d78 100644
--- a/app/gui/gui-message.c
+++ b/app/gui/gui-message.c
@@ -22,6 +22,7 @@
 #include <gegl.h>
 #include <gtk/gtk.h>
 
+#include "about.h"
 #include "libgimpbase/gimpbase.h"
 #include "libgimpwidgets/gimpwidgets.h"
 
@@ -48,6 +49,16 @@
 #include "gimp-intl.h"
 
 
+typedef struct
+{
+  Gimp                *gimp;
+  gchar               *domain;
+  gchar               *message;
+  GObject             *handler;
+  GimpMessageSeverity  severity;
+} GimpLogMessageData;
+
+static gboolean  gui_message_idle          (gpointer             user_data);
 static gboolean  gui_message_error_console (Gimp                *gimp,
                                             GimpMessageSeverity  severity,
                                             const gchar         *domain,
@@ -61,7 +72,6 @@ static void      gui_message_console       (GimpMessageSeverity  severity,
                                             const gchar         *domain,
                                             const gchar         *message);
 
-
 void
 gui_message (Gimp                *gimp,
              GObject             *handler,
@@ -79,6 +89,26 @@ gui_message (Gimp                *gimp,
       /*  fallthru  */
 
     case GIMP_MESSAGE_BOX:
+      if (g_strcmp0 (GIMP_ACRONYM, domain) != 0)
+        {
+          /* Handle non-GIMP messages in a multi-thread safe way,
+           * because we can't know for sure whether the log message may
+           * not have been called from a thread other than the main one.
+           */
+          GimpLogMessageData *data;
+
+          data = g_new0 (GimpLogMessageData, 1);
+          data->gimp     = gimp;
+          data->domain   = g_strdup (domain);
+          data->message  = g_strdup (message);
+          data->handler  = handler? g_object_ref (handler) : NULL;
+          data->severity = severity;
+
+          gdk_threads_add_idle_full (G_PRIORITY_DEFAULT_IDLE,
+                                     gui_message_idle,
+                                     data, g_free);
+          return;
+        }
       if (gui_message_error_dialog (gimp, handler, severity, domain, message))
         return;
 
@@ -92,6 +122,29 @@ gui_message (Gimp                *gimp,
 }
 
 static gboolean
+gui_message_idle (gpointer user_data)
+{
+  GimpLogMessageData *data = (GimpLogMessageData *) user_data;
+
+  if (! gui_message_error_dialog (data->gimp,
+                                  data->handler,
+                                  data->severity,
+                                  data->domain,
+                                  data->message))
+    {
+      gui_message_console (data->severity,
+                           data->domain,
+                           data->message);
+    }
+  g_free (data->domain);
+  g_free (data->message);
+  if (data->handler)
+    g_object_unref (data->handler);
+
+  return FALSE;
+}
+
+static gboolean
 gui_message_error_console (Gimp                *gimp,
                            GimpMessageSeverity  severity,
                            const gchar         *domain,


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