[gimp] Add a config enum for the pointer input API to use on Windows



commit 012df8514adca82f081e8a11e40b4142c23ed33d
Author: Luca Bacci <luca bacci982 gmail com>
Date:   Tue Jun 29 16:11:03 2021 +0200

    Add a config enum for the pointer input API to use on Windows

 app/app.c                        | 32 +++++++++++++++++++++++
 app/config/gimpcoreconfig.c      | 24 ++++++++++++++++++
 app/config/gimpcoreconfig.h      |  3 +++
 app/config/gimpearlyrc.c         | 44 +++++++++++++++++++++++++++++++-
 app/config/gimpearlyrc.h         |  9 +++++++
 app/config/gimprc-blurbs.h       |  3 +++
 app/core/core-enums.c            | 29 +++++++++++++++++++++
 app/core/core-enums.h            | 11 ++++++++
 app/core/gimp-utils.c            | 38 +++++++++++++++++++++++++++
 app/core/gimp-utils.h            |  6 +++++
 app/dialogs/preferences-dialog.c | 55 ++++++++++++++++++++++++++++++++++++++++
 11 files changed, 253 insertions(+), 1 deletion(-)
---
diff --git a/app/app.c b/app/app.c
index 931dc8d833..a1cc35e689 100644
--- a/app/app.c
+++ b/app/app.c
@@ -34,6 +34,10 @@
 #include <gio/gio.h>
 #include <gegl.h>
 
+#ifndef GIMP_CONSOLE_COMPILATION
+#include <gtk/gtk.h>
+#endif
+
 #include <gdk-pixbuf/gdk-pixbuf.h>
 
 #ifdef G_OS_WIN32
@@ -240,6 +244,34 @@ app_run (const gchar         *full_prog_name,
   if (language)
     g_free (language);
 
+#if defined (G_OS_WIN32) && !defined (GIMP_CONSOLE_COMPILATION)
+
+#if GTK_MAJOR_VERSION > 3
+#warning For GTK4 and above use the proper backend-specific API instead of the GDK_WIN32_TABLET_INPUT_API 
environment variable
+#endif
+
+  /* Support for Windows Ink was introduced in GTK3 3.24.30
+   */
+  if (gtk_get_major_version () == 3 &&
+      (gtk_get_minor_version () > 24 ||
+      (gtk_get_minor_version () == 24 &&
+       gtk_get_micro_version () >= 30)))
+    {
+      GimpWin32PointerInputAPI api = gimp_early_rc_get_win32_pointer_input_api (earlyrc);;
+
+      switch (api)
+        {
+        case GIMP_WIN32_POINTER_INPUT_API_WINTAB:
+          g_setenv ("GDK_WIN32_TABLET_INPUT_API", "wintab", TRUE);
+          break;
+        case GIMP_WIN32_POINTER_INPUT_API_WINDOWS_INK:
+          g_setenv ("GDK_WIN32_TABLET_INPUT_API", "winpointer", TRUE);
+          break;
+        }
+    }
+
+#endif
+
   g_object_unref (earlyrc);
 
   /*  Create an instance of the "Gimp" object which is the root of the
diff --git a/app/config/gimpcoreconfig.c b/app/config/gimpcoreconfig.c
index e7ac85e050..159dea084f 100644
--- a/app/config/gimpcoreconfig.c
+++ b/app/config/gimpcoreconfig.c
@@ -134,6 +134,9 @@ enum
   PROP_LAST_RELEASE_COMMENT,
   PROP_LAST_REVISION,
   PROP_LAST_KNOWN_RELEASE,
+#ifdef G_OS_WIN32
+  PROP_WIN32_POINTER_INPUT_API,
+#endif
 
   /* ignored, only for backward compatibility: */
   PROP_INSTALL_COLORMAP,
@@ -823,6 +826,17 @@ gimp_core_config_class_init (GimpCoreConfigClass *klass)
 #endif
                          GIMP_PARAM_STATIC_STRINGS);
 
+#ifdef G_OS_WIN32
+  GIMP_CONFIG_PROP_ENUM (object_class, PROP_WIN32_POINTER_INPUT_API,
+                         "win32-pointer-input-api",
+                         "Pointer Input API",
+                         WIN32_POINTER_INPUT_API_BLURB,
+                         GIMP_TYPE_WIN32_POINTER_INPUT_API,
+                         GIMP_WIN32_POINTER_INPUT_API_WINDOWS_INK,
+                         GIMP_PARAM_STATIC_STRINGS |
+                         GIMP_CONFIG_PARAM_RESTART);
+#endif
+
   /*  only for backward compatibility:  */
   GIMP_CONFIG_PROP_BOOLEAN (object_class, PROP_INSTALL_COLORMAP,
                             "install-colormap",
@@ -1166,6 +1180,11 @@ gimp_core_config_set_property (GObject      *object,
     case PROP_DEBUG_POLICY:
       core_config->debug_policy = g_value_get_enum (value);
       break;
+#ifdef G_OS_WIN32
+    case PROP_WIN32_POINTER_INPUT_API:
+      core_config->win32_pointer_input_api = g_value_get_enum (value);
+      break;
+#endif
 
     case PROP_INSTALL_COLORMAP:
     case PROP_MIN_COLORS:
@@ -1395,6 +1414,11 @@ gimp_core_config_get_property (GObject    *object,
     case PROP_DEBUG_POLICY:
       g_value_set_enum (value, core_config->debug_policy);
       break;
+#ifdef G_OS_WIN32
+    case PROP_WIN32_POINTER_INPUT_API:
+      g_value_set_enum (value, core_config->win32_pointer_input_api);
+      break;
+#endif
 
     case PROP_INSTALL_COLORMAP:
     case PROP_MIN_COLORS:
diff --git a/app/config/gimpcoreconfig.h b/app/config/gimpcoreconfig.h
index 06d79770db..3b9bd49226 100644
--- a/app/config/gimpcoreconfig.h
+++ b/app/config/gimpcoreconfig.h
@@ -103,6 +103,9 @@ struct _GimpCoreConfig
   gboolean                export_metadata_xmp;
   gboolean                export_metadata_iptc;
   GimpDebugPolicy         debug_policy;
+#ifdef G_OS_WIN32
+  GimpWin32PointerInputAPI win32_pointer_input_api;
+#endif
 
   gboolean                check_updates;
   gint64                  check_update_timestamp;
diff --git a/app/config/gimpearlyrc.c b/app/config/gimpearlyrc.c
index f70340722a..b6a42b1f35 100644
--- a/app/config/gimpearlyrc.c
+++ b/app/config/gimpearlyrc.c
@@ -37,7 +37,10 @@ enum
   PROP_VERBOSE,
   PROP_SYSTEM_GIMPRC,
   PROP_USER_GIMPRC,
-  PROP_LANGUAGE
+  PROP_LANGUAGE,
+#ifdef G_OS_WIN32
+  PROP_WIN32_POINTER_INPUT_API,
+#endif
 };
 
 
@@ -96,6 +99,14 @@ gimp_early_rc_class_init (GimpEarlyRcClass *klass)
                            "language", NULL, NULL, NULL,
                            GIMP_PARAM_STATIC_STRINGS);
 
+#ifdef G_OS_WIN32
+  GIMP_CONFIG_PROP_ENUM (object_class, PROP_WIN32_POINTER_INPUT_API,
+                         "win32-pointer-input-api", NULL, NULL,
+                         GIMP_TYPE_WIN32_POINTER_INPUT_API,
+                         GIMP_WIN32_POINTER_INPUT_API_WINDOWS_INK,
+                         GIMP_PARAM_STATIC_STRINGS |
+                         GIMP_CONFIG_PARAM_RESTART);
+#endif
 }
 
 static void
@@ -197,6 +208,12 @@ gimp_early_rc_set_property (GObject      *object,
       rc->language = g_value_dup_string (value);
       break;
 
+#ifdef G_OS_WIN32
+    case PROP_WIN32_POINTER_INPUT_API:
+      rc->win32_pointer_input_api = g_value_get_enum (value);
+      break;
+#endif
+
    default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
       break;
@@ -226,6 +243,12 @@ gimp_early_rc_get_property (GObject    *object,
       g_value_set_string (value, rc->language);
       break;
 
+#ifdef G_OS_WIN32
+    case PROP_WIN32_POINTER_INPUT_API:
+      g_value_set_enum (value, rc->win32_pointer_input_api);
+      break;
+#endif
+
    default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
       break;
@@ -280,3 +303,22 @@ gimp_early_rc_get_language (GimpEarlyRc *rc)
 {
   return rc->language ? g_strdup (rc->language) : NULL;
 }
+
+#ifdef G_OS_WIN32
+
+/**
+ * gimp_early_rc_get_win32_pointer_input_api:
+ * @rc: a #GimpEarlyRc object.
+ *
+ * This function looks up the win32-specific pointer input API
+ * set in `gimprc`.
+ *
+ * Returns: the selected win32-specific pointer input API
+ **/
+GimpWin32PointerInputAPI
+gimp_early_rc_get_win32_pointer_input_api (GimpEarlyRc *rc)
+{
+  return rc->win32_pointer_input_api;
+}
+
+#endif
diff --git a/app/config/gimpearlyrc.h b/app/config/gimpearlyrc.h
index 0abbb91659..b10835dac6 100644
--- a/app/config/gimpearlyrc.h
+++ b/app/config/gimpearlyrc.h
@@ -23,6 +23,7 @@
 #ifndef __GIMP_EARLY_RC_H__
 #define __GIMP_EARLY_RC_H__
 
+#include "core/core-enums.h"
 
 #define GIMP_TYPE_EARLY_RC            (gimp_early_rc_get_type ())
 #define GIMP_EARLY_RC(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), GIMP_TYPE_EARLY_RC, GimpEarlyRc))
@@ -42,6 +43,10 @@ struct _GimpEarlyRc
   gboolean       verbose;
 
   gchar         *language;
+
+#ifdef G_OS_WIN32
+  GimpWin32PointerInputAPI win32_pointer_input_api;
+#endif
 };
 
 struct _GimpEarlyRcClass
@@ -57,6 +62,10 @@ GimpEarlyRc  * gimp_early_rc_new          (GFile      *system_gimprc,
                                            gboolean    verbose);
 gchar        * gimp_early_rc_get_language (GimpEarlyRc *rc);
 
+#ifdef G_OS_WIN32
+GimpWin32PointerInputAPI gimp_early_rc_get_win32_pointer_input_api (GimpEarlyRc *rc);
+#endif
+
 
 #endif /* GIMP_EARLY_RC_H__ */
 
diff --git a/app/config/gimprc-blurbs.h b/app/config/gimprc-blurbs.h
index daa5b0fe9f..df04e20af4 100644
--- a/app/config/gimprc-blurbs.h
+++ b/app/config/gimprc-blurbs.h
@@ -247,6 +247,9 @@ _("Export IPTC metadata by default.")
 #define GENERATE_BACKTRACE_BLURB \
 _("Try generating debug data for bug reporting when appropriate.")
 
+#define WIN32_POINTER_INPUT_API_BLURB \
+_("Sets the preferred pen and touch input API.")
+
 #define INITIAL_ZOOM_TO_FIT_BLURB \
 _("When enabled, this will ensure that the full image is visible after a " \
   "file is opened, otherwise it will be displayed with a scale of 1:1.")
diff --git a/app/core/core-enums.c b/app/core/core-enums.c
index 1875023b6d..9b459c9320 100644
--- a/app/core/core-enums.c
+++ b/app/core/core-enums.c
@@ -989,6 +989,35 @@ gimp_paste_type_get_type (void)
   return type;
 }
 
+GType
+gimp_win32_pointer_input_api_get_type (void)
+{
+  static const GEnumValue values[] =
+  {
+    { GIMP_WIN32_POINTER_INPUT_API_WINTAB, "GIMP_WIN32_POINTER_INPUT_API_WINTAB", "wintab" },
+    { GIMP_WIN32_POINTER_INPUT_API_WINDOWS_INK, "GIMP_WIN32_POINTER_INPUT_API_WINDOWS_INK", "windows-ink" },
+    { 0, NULL, NULL }
+  };
+
+  static const GimpEnumDesc descs[] =
+  {
+    { GIMP_WIN32_POINTER_INPUT_API_WINTAB, NC_("win32-pointer-input-api", "Wintab"), NULL },
+    { GIMP_WIN32_POINTER_INPUT_API_WINDOWS_INK, NC_("win32-pointer-input-api", "Windows Ink"), NULL },
+    { 0, NULL, NULL }
+  };
+
+  static GType type = 0;
+
+  if (G_UNLIKELY (! type))
+    {
+      type = g_enum_register_static ("GimpWin32PointerInputAPI", values);
+      gimp_type_set_translation_context (type, "win32-pointer-input-api");
+      gimp_enum_set_value_descriptions (type, descs);
+    }
+
+  return type;
+}
+
 GType
 gimp_thumbnail_size_get_type (void)
 {
diff --git a/app/core/core-enums.h b/app/core/core-enums.h
index 9fef881eae..ead4a09fc8 100644
--- a/app/core/core-enums.h
+++ b/app/core/core-enums.h
@@ -447,6 +447,17 @@ typedef enum  /*< pdb-skip >*/
 } GimpPasteType;
 
 
+#define GIMP_TYPE_WIN32_POINTER_INPUT_API (gimp_win32_pointer_input_api_get_type ())
+
+GType gimp_win32_pointer_input_api_get_type (void) G_GNUC_CONST;
+
+typedef enum  /*< pdb-skip >*/
+{
+  GIMP_WIN32_POINTER_INPUT_API_WINTAB,      /*< desc="Wintab"      >*/
+  GIMP_WIN32_POINTER_INPUT_API_WINDOWS_INK  /*< desc="Windows Ink" >*/
+} GimpWin32PointerInputAPI;
+
+
 #define GIMP_TYPE_THUMBNAIL_SIZE (gimp_thumbnail_size_get_type ())
 
 GType gimp_thumbnail_size_get_type (void) G_GNUC_CONST;
diff --git a/app/core/gimp-utils.c b/app/core/gimp-utils.c
index d36ce0af91..14afd88677 100644
--- a/app/core/gimp-utils.c
+++ b/app/core/gimp-utils.c
@@ -1137,6 +1137,44 @@ gimp_idle_run_async_full (gint             priority,
   return g_object_ref (data->async);
 }
 
+#ifdef G_OS_WIN32
+
+gboolean
+gimp_win32_have_wintab (void)
+{
+  gunichar2 wchars_buffer[MAX_PATH + 1];
+  UINT      wchars_count = 0;
+
+  memset (wchars_buffer, 0, sizeof (wchars_buffer));
+  wchars_count = GetSystemDirectoryW (wchars_buffer, MAX_PATH);
+  if (wchars_count > 0 && wchars_count < MAX_PATH)
+    {
+      char *system32_directory = g_utf16_to_utf8 (wchars_buffer, -1, NULL, NULL, NULL);
+
+      if (system32_directory)
+        {
+          GFile    *file   = g_file_new_build_filename (system32_directory, "Wintab32.dll", NULL);
+          gboolean  exists = g_file_query_exists (file, NULL);
+
+          g_object_unref (file);
+          g_free (system32_directory);
+
+          return exists;
+        }
+    }
+
+  return FALSE;
+}
+
+gboolean
+gimp_win32_have_windows_ink (void)
+{
+  /* Check for Windows 8 or later */
+  return g_win32_check_windows_version (6, 2, 0, G_WIN32_OS_ANY);
+}
+
+#endif
+
 
 /*  debug stuff  */
 
diff --git a/app/core/gimp-utils.h b/app/core/gimp-utils.h
index ca60d99017..371c42b920 100644
--- a/app/core/gimp-utils.h
+++ b/app/core/gimp-utils.h
@@ -118,5 +118,11 @@ GimpImage  * gimp_create_image_from_buffer         (Gimp              *gimp,
                                                     GeglBuffer        *buffer,
                                                     const gchar       *image_name);
 
+#ifdef G_OS_WIN32
+
+gboolean     gimp_win32_have_wintab                (void);
+gboolean     gimp_win32_have_windows_ink           (void);
+
+#endif
 
 #endif /* __APP_GIMP_UTILS_H__ */
diff --git a/app/dialogs/preferences-dialog.c b/app/dialogs/preferences-dialog.c
index d93c7102a5..1d77e072c9 100644
--- a/app/dialogs/preferences-dialog.c
+++ b/app/dialogs/preferences-dialog.c
@@ -34,6 +34,7 @@
 
 #include "core/gimp.h"
 #include "core/gimptemplate.h"
+#include "core/gimp-utils.h"
 
 #include "plug-in/gimppluginmanager.h"
 
@@ -757,6 +758,37 @@ prefs_devices_clear_callback (GtkWidget *widget,
     }
 }
 
+#ifdef G_OS_WIN32
+
+static gboolean
+prefs_devices_api_sensitivity_func (gint      value,
+                                    gpointer  data)
+{
+  static gboolean have_wintab      = TRUE;
+  static gboolean have_windows_ink = TRUE;
+  static gboolean inited           = FALSE;
+
+  if (!inited)
+    {
+      have_wintab      = gimp_win32_have_wintab ();
+      have_windows_ink = gimp_win32_have_windows_ink ();
+
+      inited = TRUE;
+    }
+
+  switch (value)
+    {
+    case GIMP_WIN32_POINTER_INPUT_API_WINTAB:
+      return have_wintab;
+    case GIMP_WIN32_POINTER_INPUT_API_WINDOWS_INK:
+      return have_windows_ink;
+    default:
+      return TRUE;
+    }
+}
+
+#endif
+
 static void
 prefs_search_clear_callback (GtkWidget *widget,
                              Gimp      *gimp)
@@ -3131,6 +3163,29 @@ prefs_dialog_new (Gimp       *gimp,
   vbox2 = prefs_frame_new (_("Extended Input Devices"),
                            GTK_CONTAINER (vbox), FALSE);
 
+#ifdef G_OS_WIN32
+
+  if ((gtk_get_major_version () == 3 &&
+       gtk_get_minor_version () > 24) ||
+      (gtk_get_major_version () == 3 &&
+       gtk_get_minor_version () == 24 &&
+       gtk_get_micro_version () >= 30))
+    {
+      GtkWidget *combo;
+
+      grid = prefs_grid_new (GTK_CONTAINER (vbox2));
+
+      combo = prefs_enum_combo_box_add (object, "win32-pointer-input-api", 0, 0,
+                                        _("Pointer Input API:"),
+                                        GTK_GRID (grid), 0, NULL);
+
+      gimp_int_combo_box_set_sensitivity (GIMP_INT_COMBO_BOX (combo),
+                                          prefs_devices_api_sensitivity_func,
+                                          NULL, NULL);
+    }
+
+#endif
+
   prefs_check_button_add (object, "devices-share-tool",
                           _("S_hare tool and tool options between input devices"),
                           GTK_BOX (vbox2));


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