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

This commit is contained in:
Luca Bacci 2021-06-29 16:11:03 +02:00
parent f6fc9d4245
commit 012df8514a
No known key found for this signature in database
GPG Key ID: 8E3C8D989C98883D
11 changed files with 253 additions and 1 deletions

View File

@ -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

View File

@ -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:

View File

@ -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;

View File

@ -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

View File

@ -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__ */

View File

@ -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.")

View File

@ -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)
{

View File

@ -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;

View File

@ -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 */

View File

@ -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__ */

View File

@ -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));