summaryrefslogtreecommitdiffstats
path: root/app
diff options
context:
space:
mode:
Diffstat (limited to 'app')
-rw-r--r--app/actions/data-commands.c20
-rw-r--r--app/app.c24
-rw-r--r--app/config/Makefile.am4
-rw-r--r--app/config/Makefile.in18
-rw-r--r--app/config/config-types.h2
-rw-r--r--app/config/gimpcoreconfig.c43
-rw-r--r--app/config/gimpcoreconfig.h3
-rw-r--r--app/config/gimpearlyrc.c (renamed from app/config/gimplangrc.c)172
-rw-r--r--app/config/gimpearlyrc.h71
-rw-r--r--app/config/gimplangrc.h60
-rw-r--r--app/config/gimprc-blurbs.h3
-rw-r--r--app/core/core-enums.c29
-rw-r--r--app/core/core-enums.h11
-rw-r--r--app/core/gimp-utils.c45
-rw-r--r--app/core/gimp-utils.h6
-rw-r--r--app/core/gimpimage-new.c11
-rw-r--r--app/core/gimppalette-load.c4
-rw-r--r--app/core/gimppattern.c23
-rw-r--r--app/dialogs/preferences-dialog.c15
-rw-r--r--app/dialogs/quit-dialog.c2
-rw-r--r--app/display/gimpdisplayshell-title.c72
-rw-r--r--app/display/gimpimagewindow.c3
-rw-r--r--app/gegl/gimp-babl.c3
-rw-r--r--app/gui/gui.c19
-rw-r--r--app/gui/splash.c17
-rw-r--r--app/main.c128
-rw-r--r--app/pdb/plug-in-compat-cmds.c22
-rw-r--r--app/widgets/gimpaction-history.c1
-rw-r--r--app/widgets/gimpdashboard.c7
-rw-r--r--app/widgets/gimpdeviceinfo.c18
30 files changed, 652 insertions, 204 deletions
diff --git a/app/actions/data-commands.c b/app/actions/data-commands.c
index 9d71bda..d93a6b1 100644
--- a/app/actions/data-commands.c
+++ b/app/actions/data-commands.c
@@ -117,11 +117,15 @@ data_new_cmd_callback (GimpAction *action,
if (data)
{
+ GtkWidget *edit_button;
+
gimp_context_set_by_type (context,
gimp_data_factory_view_get_children_type (view),
GIMP_OBJECT (data));
- gtk_button_clicked (GTK_BUTTON (gimp_data_factory_view_get_edit_button (view)));
+ edit_button = gimp_data_factory_view_get_edit_button (view);
+ if (edit_button && gtk_widget_get_visible (edit_button))
+ gtk_button_clicked (GTK_BUTTON (gimp_data_factory_view_get_edit_button (view)));
}
}
}
@@ -149,11 +153,15 @@ data_duplicate_cmd_callback (GimpAction *action,
if (new_data)
{
+ GtkWidget *edit_button;
+
gimp_context_set_by_type (context,
gimp_data_factory_view_get_children_type (view),
GIMP_OBJECT (new_data));
- gtk_button_clicked (GTK_BUTTON (gimp_data_factory_view_get_edit_button (view)));
+ edit_button = gimp_data_factory_view_get_edit_button (view);
+ if (edit_button && gtk_widget_get_visible (edit_button))
+ gtk_button_clicked (GTK_BUTTON (gimp_data_factory_view_get_edit_button (view)));
}
}
}
@@ -288,6 +296,7 @@ data_edit_cmd_callback (GimpAction *action,
GdkScreen *screen = gtk_widget_get_screen (GTK_WIDGET (view));
gint monitor = gimp_widget_get_monitor (GTK_WIDGET (view));
GtkWidget *dockable;
+ GtkWidget *editor = NULL;
dockable =
gimp_window_strategy_show_dockable_dialog (GIMP_WINDOW_STRATEGY (gimp_get_window_strategy (context->gimp)),
@@ -298,7 +307,10 @@ data_edit_cmd_callback (GimpAction *action,
g_variant_get_string (value,
NULL));
- gimp_data_editor_set_data (GIMP_DATA_EDITOR (gtk_bin_get_child (GTK_BIN (dockable))),
- data);
+ if (dockable)
+ editor = gtk_bin_get_child (GTK_BIN (dockable));
+
+ if (editor && GIMP_IS_DATA_EDITOR (editor))
+ gimp_data_editor_set_data (GIMP_DATA_EDITOR (editor), data);
}
}
diff --git a/app/app.c b/app/app.c
index 3bb210b..05b0a88 100644
--- a/app/app.c
+++ b/app/app.c
@@ -48,7 +48,6 @@
#include "core/core-types.h"
-#include "config/gimplangrc.h"
#include "config/gimprc.h"
#include "gegl/gimp-gegl.h"
@@ -68,7 +67,6 @@
#include "app.h"
#include "errors.h"
-#include "language.h"
#include "sanity.h"
#include "gimp-debug.h"
@@ -189,8 +187,6 @@ app_run (const gchar *full_prog_name,
GFile *default_folder = NULL;
GFile *gimpdir;
const gchar *abort_message;
- GimpLangRc *temprc;
- gchar *language = NULL;
GError *font_error = NULL;
if (filenames && filenames[0] && ! filenames[1] &&
@@ -213,26 +209,6 @@ app_run (const gchar *full_prog_name,
filenames = NULL;
}
- /* Language needs to be determined first, before any GimpContext is
- * instantiated (which happens when the Gimp object is created)
- * because its properties need to be properly localized in the
- * settings language (if different from system language). Otherwise we
- * end up with pieces of GUI always using the system language (cf. bug
- * 787457). Therefore we do a first pass on "gimprc" file for the sole
- * purpose of getting the settings language, so that we can initialize
- * it before anything else.
- */
- temprc = gimp_lang_rc_new (alternate_system_gimprc,
- alternate_gimprc,
- be_verbose);
- language = gimp_lang_rc_get_language (temprc);
- g_object_unref (temprc);
-
- /* change the locale if a language if specified */
- language_init (language);
- if (language)
- g_free (language);
-
/* Create an instance of the "Gimp" object which is the root of the
* core object system
*/
diff --git a/app/config/Makefile.am b/app/config/Makefile.am
index 04ac126..0a1266c 100644
--- a/app/config/Makefile.am
+++ b/app/config/Makefile.am
@@ -46,12 +46,12 @@ libappconfig_a_sources = \
gimpdisplayconfig.h \
gimpdisplayoptions.c \
gimpdisplayoptions.h \
+ gimpearlyrc.c \
+ gimpearlyrc.h \
gimpgeglconfig.c \
gimpgeglconfig.h \
gimpguiconfig.c \
gimpguiconfig.h \
- gimplangrc.c \
- gimplangrc.h \
gimppluginconfig.c \
gimppluginconfig.h \
gimprc.c \
diff --git a/app/config/Makefile.in b/app/config/Makefile.in
index ab37152..8caafdc 100644
--- a/app/config/Makefile.in
+++ b/app/config/Makefile.in
@@ -120,8 +120,8 @@ am__objects_1 = config-enums.$(OBJEXT)
am__objects_2 = gimpconfig-dump.$(OBJEXT) gimpconfig-file.$(OBJEXT) \
gimpconfig-utils.$(OBJEXT) gimpcoreconfig.$(OBJEXT) \
gimpdialogconfig.$(OBJEXT) gimpdisplayconfig.$(OBJEXT) \
- gimpdisplayoptions.$(OBJEXT) gimpgeglconfig.$(OBJEXT) \
- gimpguiconfig.$(OBJEXT) gimplangrc.$(OBJEXT) \
+ gimpdisplayoptions.$(OBJEXT) gimpearlyrc.$(OBJEXT) \
+ gimpgeglconfig.$(OBJEXT) gimpguiconfig.$(OBJEXT) \
gimppluginconfig.$(OBJEXT) gimprc.$(OBJEXT) \
gimprc-deserialize.$(OBJEXT) gimprc-serialize.$(OBJEXT) \
gimprc-unknown.$(OBJEXT) gimpxmlparser.$(OBJEXT)
@@ -157,9 +157,9 @@ am__depfiles_remade = ./$(DEPDIR)/config-enums.Po \
./$(DEPDIR)/gimpconfig-utils.Po ./$(DEPDIR)/gimpcoreconfig.Po \
./$(DEPDIR)/gimpdialogconfig.Po \
./$(DEPDIR)/gimpdisplayconfig.Po \
- ./$(DEPDIR)/gimpdisplayoptions.Po \
+ ./$(DEPDIR)/gimpdisplayoptions.Po ./$(DEPDIR)/gimpearlyrc.Po \
./$(DEPDIR)/gimpgeglconfig.Po ./$(DEPDIR)/gimpguiconfig.Po \
- ./$(DEPDIR)/gimplangrc.Po ./$(DEPDIR)/gimppluginconfig.Po \
+ ./$(DEPDIR)/gimppluginconfig.Po \
./$(DEPDIR)/gimprc-deserialize.Po \
./$(DEPDIR)/gimprc-serialize.Po ./$(DEPDIR)/gimprc-unknown.Po \
./$(DEPDIR)/gimprc.Po ./$(DEPDIR)/gimpxmlparser.Po \
@@ -876,12 +876,12 @@ libappconfig_a_sources = \
gimpdisplayconfig.h \
gimpdisplayoptions.c \
gimpdisplayoptions.h \
+ gimpearlyrc.c \
+ gimpearlyrc.h \
gimpgeglconfig.c \
gimpgeglconfig.h \
gimpguiconfig.c \
gimpguiconfig.h \
- gimplangrc.c \
- gimplangrc.h \
gimppluginconfig.c \
gimppluginconfig.h \
gimprc.c \
@@ -1020,9 +1020,9 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gimpdialogconfig.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gimpdisplayconfig.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gimpdisplayoptions.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gimpearlyrc.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gimpgeglconfig.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gimpguiconfig.Po@am__quote@ # am--include-marker
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gimplangrc.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gimppluginconfig.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gimprc-deserialize.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gimprc-serialize.Po@am__quote@ # am--include-marker
@@ -1365,9 +1365,9 @@ distclean: distclean-am
-rm -f ./$(DEPDIR)/gimpdialogconfig.Po
-rm -f ./$(DEPDIR)/gimpdisplayconfig.Po
-rm -f ./$(DEPDIR)/gimpdisplayoptions.Po
+ -rm -f ./$(DEPDIR)/gimpearlyrc.Po
-rm -f ./$(DEPDIR)/gimpgeglconfig.Po
-rm -f ./$(DEPDIR)/gimpguiconfig.Po
- -rm -f ./$(DEPDIR)/gimplangrc.Po
-rm -f ./$(DEPDIR)/gimppluginconfig.Po
-rm -f ./$(DEPDIR)/gimprc-deserialize.Po
-rm -f ./$(DEPDIR)/gimprc-serialize.Po
@@ -1428,9 +1428,9 @@ maintainer-clean: maintainer-clean-am
-rm -f ./$(DEPDIR)/gimpdialogconfig.Po
-rm -f ./$(DEPDIR)/gimpdisplayconfig.Po
-rm -f ./$(DEPDIR)/gimpdisplayoptions.Po
+ -rm -f ./$(DEPDIR)/gimpearlyrc.Po
-rm -f ./$(DEPDIR)/gimpgeglconfig.Po
-rm -f ./$(DEPDIR)/gimpguiconfig.Po
- -rm -f ./$(DEPDIR)/gimplangrc.Po
-rm -f ./$(DEPDIR)/gimppluginconfig.Po
-rm -f ./$(DEPDIR)/gimprc-deserialize.Po
-rm -f ./$(DEPDIR)/gimprc-serialize.Po
diff --git a/app/config/config-types.h b/app/config/config-types.h
index 40b0802..1fe5594 100644
--- a/app/config/config-types.h
+++ b/app/config/config-types.h
@@ -36,7 +36,7 @@ typedef struct _GimpCoreConfig GimpCoreConfig;
typedef struct _GimpDisplayConfig GimpDisplayConfig;
typedef struct _GimpGuiConfig GimpGuiConfig;
typedef struct _GimpDialogConfig GimpDialogConfig;
-typedef struct _GimpLangRc GimpLangRc;
+typedef struct _GimpEarlyRc GimpEarlyRc;
typedef struct _GimpPluginConfig GimpPluginConfig;
typedef struct _GimpRc GimpRc;
diff --git a/app/config/gimpcoreconfig.c b/app/config/gimpcoreconfig.c
index 823e808..3e033c2 100644
--- a/app/config/gimpcoreconfig.c
+++ b/app/config/gimpcoreconfig.c
@@ -133,6 +133,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,
@@ -815,6 +818,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_WINTAB,
+ GIMP_PARAM_STATIC_STRINGS |
+ GIMP_CONFIG_PARAM_RESTART);
+#endif
+
/* only for backward compatibility: */
GIMP_CONFIG_PROP_BOOLEAN (object_class, PROP_INSTALL_COLORMAP,
"install-colormap",
@@ -1152,6 +1166,30 @@ 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:
+ {
+ GimpWin32PointerInputAPI api = g_value_get_enum (value);
+ gboolean have_wintab = gimp_win32_have_wintab ();
+ gboolean have_windows_ink = gimp_win32_have_windows_ink ();
+ gboolean api_is_wintab = (api == GIMP_WIN32_POINTER_INPUT_API_WINTAB);
+ gboolean api_is_windows_ink = (api == GIMP_WIN32_POINTER_INPUT_API_WINDOWS_INK);
+
+ if (api_is_wintab && !have_wintab && have_windows_ink)
+ {
+ core_config->win32_pointer_input_api = GIMP_WIN32_POINTER_INPUT_API_WINDOWS_INK;
+ }
+ else if (api_is_windows_ink && !have_windows_ink && have_wintab)
+ {
+ core_config->win32_pointer_input_api = GIMP_WIN32_POINTER_INPUT_API_WINTAB;
+ }
+ else
+ {
+ core_config->win32_pointer_input_api = api;
+ }
+ }
+ break;
+#endif
case PROP_INSTALL_COLORMAP:
case PROP_MIN_COLORS:
@@ -1378,6 +1416,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 f413ae4..22d2f3f 100644
--- a/app/config/gimpcoreconfig.h
+++ b/app/config/gimpcoreconfig.h
@@ -102,6 +102,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/gimplangrc.c b/app/config/gimpearlyrc.c
index 34e26f4..f9e83d5 100644
--- a/app/config/gimplangrc.c
+++ b/app/config/gimpearlyrc.c
@@ -1,7 +1,9 @@
/* GIMP - The GNU Image Manipulation Program
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
*
- * GimpLangRc: pre-parsing of gimprc returning the language.
+ * GimpEarlyRc: pre-parsing of gimprc suitable for use during early
+ * initialization, when the gimp singleton is not constructed yet.
+ *
* Copyright (C) 2017 Jehan <jehan@gimp.org>
*
* This program is free software: you can redistribute it and/or modify
@@ -27,7 +29,10 @@
#include "config-types.h"
-#include "gimplangrc.h"
+#include "core/core-types.h"
+#include "core/gimp-utils.h"
+
+#include "gimpearlyrc.h"
enum
{
@@ -35,39 +40,42 @@ enum
PROP_VERBOSE,
PROP_SYSTEM_GIMPRC,
PROP_USER_GIMPRC,
- PROP_LANGUAGE
+ PROP_LANGUAGE,
+#ifdef G_OS_WIN32
+ PROP_WIN32_POINTER_INPUT_API,
+#endif
};
-static void gimp_lang_rc_constructed (GObject *object);
-static void gimp_lang_rc_finalize (GObject *object);
-static void gimp_lang_rc_set_property (GObject *object,
- guint property_id,
- const GValue *value,
- GParamSpec *pspec);
-static void gimp_lang_rc_get_property (GObject *object,
- guint property_id,
- GValue *value,
- GParamSpec *pspec);
+static void gimp_early_rc_constructed (GObject *object);
+static void gimp_early_rc_finalize (GObject *object);
+static void gimp_early_rc_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec);
+static void gimp_early_rc_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec);
/* Just use GimpConfig interface's default implementation which will
- * fill the PROP_LANGUAGE property. */
-G_DEFINE_TYPE_WITH_CODE (GimpLangRc, gimp_lang_rc, G_TYPE_OBJECT,
+ * fill the properties. */
+G_DEFINE_TYPE_WITH_CODE (GimpEarlyRc, gimp_early_rc, G_TYPE_OBJECT,
G_IMPLEMENT_INTERFACE (GIMP_TYPE_CONFIG, NULL))
-#define parent_class gimp_lang_rc_parent_class
+#define parent_class gimp_early_rc_parent_class
static void
-gimp_lang_rc_class_init (GimpLangRcClass *klass)
+gimp_early_rc_class_init (GimpEarlyRcClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
- object_class->constructed = gimp_lang_rc_constructed;
- object_class->finalize = gimp_lang_rc_finalize;
- object_class->set_property = gimp_lang_rc_set_property;
- object_class->get_property = gimp_lang_rc_get_property;
+ object_class->constructed = gimp_early_rc_constructed;
+ object_class->finalize = gimp_early_rc_finalize;
+ object_class->set_property = gimp_early_rc_set_property;
+ object_class->get_property = gimp_early_rc_get_property;
g_object_class_install_property (object_class, PROP_VERBOSE,
g_param_spec_boolean ("verbose",
@@ -94,21 +102,29 @@ gimp_lang_rc_class_init (GimpLangRcClass *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_WINTAB,
+ GIMP_PARAM_STATIC_STRINGS |
+ GIMP_CONFIG_PARAM_RESTART);
+#endif
}
static void
-gimp_lang_rc_init (GimpLangRc *rc)
+gimp_early_rc_init (GimpEarlyRc *rc)
{
}
static void
-gimp_lang_rc_constructed (GObject *object)
+gimp_early_rc_constructed (GObject *object)
{
- GimpLangRc *rc = GIMP_LANG_RC (object);
- GError *error = NULL;
+ GimpEarlyRc *rc = GIMP_EARLY_RC (object);
+ GError *error = NULL;
if (rc->verbose)
- g_print ("Parsing '%s' for configured language.\n",
+ g_print ("Parsing '%s' for configuration data required during early initialization.\n",
gimp_file_get_utf8_name (rc->system_gimprc));
if (! gimp_config_deserialize_gfile (GIMP_CONFIG (rc),
@@ -121,7 +137,7 @@ gimp_lang_rc_constructed (GObject *object)
}
if (rc->verbose)
- g_print ("Parsing '%s' for configured language.\n",
+ g_print ("Parsing '%s' for configuration data required during early initialization.\n",
gimp_file_get_utf8_name (rc->user_gimprc));
if (! gimp_config_deserialize_gfile (GIMP_CONFIG (rc),
@@ -143,9 +159,9 @@ gimp_lang_rc_constructed (GObject *object)
}
static void
-gimp_lang_rc_finalize (GObject *object)
+gimp_early_rc_finalize (GObject *object)
{
- GimpLangRc *rc = GIMP_LANG_RC (object);
+ GimpEarlyRc *rc = GIMP_EARLY_RC (object);
g_clear_object (&rc->system_gimprc);
g_clear_object (&rc->user_gimprc);
@@ -156,12 +172,12 @@ gimp_lang_rc_finalize (GObject *object)
}
static void
-gimp_lang_rc_set_property (GObject *object,
- guint property_id,
- const GValue *value,
- GParamSpec *pspec)
+gimp_early_rc_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec)
{
- GimpLangRc *rc = GIMP_LANG_RC (object);
+ GimpEarlyRc *rc = GIMP_EARLY_RC (object);
switch (property_id)
{
@@ -195,6 +211,31 @@ gimp_lang_rc_set_property (GObject *object,
rc->language = g_value_dup_string (value);
break;
+#ifdef G_OS_WIN32
+ case PROP_WIN32_POINTER_INPUT_API:
+ {
+ GimpWin32PointerInputAPI api = g_value_get_enum (value);
+ gboolean have_wintab = gimp_win32_have_wintab ();
+ gboolean have_windows_ink = gimp_win32_have_windows_ink ();
+ gboolean api_is_wintab = (api == GIMP_WIN32_POINTER_INPUT_API_WINTAB);
+ gboolean api_is_windows_ink = (api == GIMP_WIN32_POINTER_INPUT_API_WINDOWS_INK);
+
+ if (api_is_wintab && !have_wintab && have_windows_ink)
+ {
+ rc->win32_pointer_input_api = GIMP_WIN32_POINTER_INPUT_API_WINDOWS_INK;
+ }
+ else if (api_is_windows_ink && !have_windows_ink && have_wintab)
+ {
+ rc->win32_pointer_input_api = GIMP_WIN32_POINTER_INPUT_API_WINTAB;
+ }
+ else
+ {
+ rc->win32_pointer_input_api = api;
+ }
+ }
+ break;
+#endif
+
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
break;
@@ -202,12 +243,12 @@ gimp_lang_rc_set_property (GObject *object,
}
static void
-gimp_lang_rc_get_property (GObject *object,
- guint property_id,
- GValue *value,
- GParamSpec *pspec)
+gimp_early_rc_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec)
{
- GimpLangRc *rc = GIMP_LANG_RC (object);
+ GimpEarlyRc *rc = GIMP_EARLY_RC (object);
switch (property_id)
{
@@ -224,6 +265,12 @@ gimp_lang_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;
@@ -231,31 +278,31 @@ gimp_lang_rc_get_property (GObject *object,
}
/**
- * gimp_lang_rc_new:
+ * gimp_early_rc_new:
* @system_gimprc: the name of the system-wide gimprc file or %NULL to
* use the standard location
* @user_gimprc: the name of the user gimprc file or %NULL to use the
* standard location
- * @verbose: enable console messages about loading the language
+ * @verbose: enable console messages about loading the preferences
*
- * Creates a new GimpLangRc object which only looks for the configure
- * language.
+ * Creates a new GimpEarlyRc object which looks for some configuration
+ * data required in the early initialization steps
*
- * Returns: the new #GimpLangRc.
+ * Returns: the new #GimpEarlyRc.
*/
-GimpLangRc *
-gimp_lang_rc_new (GFile *system_gimprc,
- GFile *user_gimprc,
- gboolean verbose)
+GimpEarlyRc *
+gimp_early_rc_new (GFile *system_gimprc,
+ GFile *user_gimprc,
+ gboolean verbose)
{
- GimpLangRc *rc;
+ GimpEarlyRc *rc;
g_return_val_if_fail (system_gimprc == NULL || G_IS_FILE (system_gimprc),
NULL);
g_return_val_if_fail (user_gimprc == NULL || G_IS_FILE (user_gimprc),
NULL);
- rc = g_object_new (GIMP_TYPE_LANG_RC,
+ rc = g_object_new (GIMP_TYPE_EARLY_RC,
"verbose", verbose,
"system-gimprc", system_gimprc,
"user-gimprc", user_gimprc,
@@ -265,8 +312,8 @@ gimp_lang_rc_new (GFile *system_gimprc,
}
/**
- * gimp_lang_rc_get_language:
- * @lang_rc: a #GimpLangRc object.
+ * gimp_early_rc_get_language:
+ * @rc: a #GimpEarlyRc object.
*
* This function looks up the language set in `gimprc`.
*
@@ -274,7 +321,26 @@ gimp_lang_rc_new (GFile *system_gimprc,
* %NULL if the key couldn't be found.
**/
gchar *
-gimp_lang_rc_get_language (GimpLangRc *rc)
+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
new file mode 100644
index 0000000..b10835d
--- /dev/null
+++ b/app/config/gimpearlyrc.h
@@ -0,0 +1,71 @@
+/* GIMP - The GNU Image Manipulation Program
+ * Copyright (C) 1995 Spencer Kimball and Peter Mattis
+ *
+ * GimpEarlyRc: pre-parsing of gimprc suitable for use during early
+ * initialization, when the gimp singleton is not constructed yet
+ *
+ * Copyright (C) 2017 Jehan <jehan@gimp.org>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+#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))
+#define GIMP_EARLY_RC_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GIMP_TYPE_EARLY_RC, GimpEarlyRcClass))
+#define GIMP_IS_EARLY_RC(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GIMP_TYPE_EARLY_RC))
+#define GIMP_IS_EARLY_RC_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GIMP_TYPE_EARLY_RC))
+
+
+typedef struct _GimpEarlyRcClass GimpEarlyRcClass;
+
+struct _GimpEarlyRc
+{
+ GObject parent_instance;
+
+ GFile *user_gimprc;
+ GFile *system_gimprc;
+ gboolean verbose;
+
+ gchar *language;
+
+#ifdef G_OS_WIN32
+ GimpWin32PointerInputAPI win32_pointer_input_api;
+#endif
+};
+
+struct _GimpEarlyRcClass
+{
+ GObjectClass parent_class;
+};
+
+
+GType gimp_early_rc_get_type (void) G_GNUC_CONST;
+
+GimpEarlyRc * gimp_early_rc_new (GFile *system_gimprc,
+ GFile *user_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/gimplangrc.h b/app/config/gimplangrc.h
deleted file mode 100644
index 62412fd..0000000
--- a/app/config/gimplangrc.h
+++ /dev/null
@@ -1,60 +0,0 @@
-/* GIMP - The GNU Image Manipulation Program
- * Copyright (C) 1995 Spencer Kimball and Peter Mattis
- *
- * GimpLangRc: pre-parsing of gimprc returning the language.
- * Copyright (C) 2017 Jehan <jehan@gimp.org>
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <https://www.gnu.org/licenses/>.
- */
-
-#ifndef __GIMP_LANG_RC_H__
-#define __GIMP_LANG_RC_H__
-
-
-#define GIMP_TYPE_LANG_RC (gimp_lang_rc_get_type ())
-#define GIMP_LANG_RC(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GIMP_TYPE_LANG_RC, GimpLangRc))
-#define GIMP_LANG_RC_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GIMP_TYPE_LANG_RC, GimpLangRcClass))
-#define GIMP_IS_LANG_RC(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GIMP_TYPE_LANG_RC))
-#define GIMP_IS_LANG_RC_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GIMP_TYPE_LANG_RC))
-
-
-typedef struct _GimpLangRcClass GimpLangRcClass;
-
-struct _GimpLangRc
-{
- GObject parent_instance;
-
- GFile *user_gimprc;
- GFile *system_gimprc;
- gboolean verbose;
-
- gchar *language;
-};
-
-struct _GimpLangRcClass
-{
- GObjectClass parent_class;
-};
-
-
-GType gimp_lang_rc_get_type (void) G_GNUC_CONST;
-
-GimpLangRc * gimp_lang_rc_new (GFile *system_gimprc,
- GFile *user_gimprc,
- gboolean verbose);
-gchar * gimp_lang_rc_get_language (GimpLangRc *rc);
-
-
-#endif /* GIMP_LANG_RC_H__ */
-
diff --git a/app/config/gimprc-blurbs.h b/app/config/gimprc-blurbs.h
index 51b771a..3d5f5d0 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 f8ecb14..31969dd 100644
--- a/app/core/core-enums.c
+++ b/app/core/core-enums.c
@@ -926,6 +926,35 @@ gimp_paste_type_get_type (void)
}
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)
{
static const GEnumValue values[] =
diff --git a/app/core/core-enums.h b/app/core/core-enums.h
index 8826145..7a80238 100644
--- a/app/core/core-enums.h
+++ b/app/core/core-enums.h
@@ -414,6 +414,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 d3df098..cac4000 100644
--- a/app/core/gimp-utils.c
+++ b/app/core/gimp-utils.c
@@ -1049,6 +1049,51 @@ gimp_idle_run_async_full (gint priority,
return g_object_ref (data->async);
}
+#if defined(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)
+{
+ wchar_t buf[100];
+ DWORD ret;
+
+ memset (buf, 0, sizeof (buf));
+ ret = GetEnvironmentVariableW (L"GDK_WIN32_FEATURES", buf, sizeof (buf) - 1);
+ if (ret > 0 && ret < 100)
+ return wcsstr (buf, L"winpointer") != NULL;
+
+ return FALSE;
+}
+
+#endif
+
/* debug stuff */
diff --git a/app/core/gimp-utils.h b/app/core/gimp-utils.h
index 8373de7..e9810bf 100644
--- a/app/core/gimp-utils.h
+++ b/app/core/gimp-utils.h
@@ -112,5 +112,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/core/gimpimage-new.c b/app/core/gimpimage-new.c
index 4d0fa7b..c307d63 100644
--- a/app/core/gimpimage-new.c
+++ b/app/core/gimpimage-new.c
@@ -61,9 +61,20 @@ gimp_image_new_get_last_template (Gimp *gimp,
if (image)
{
+ const gchar *comment;
+
+ comment = gimp_template_get_comment (gimp->config->default_image);
+
gimp_config_sync (G_OBJECT (gimp->config->default_image),
G_OBJECT (template), 0);
gimp_template_set_from_image (template, image);
+
+ /* Do not pass around the comment from the current active comment. Only
+ * pass comments stored in actual templates. This can be even considered
+ * as data leak otherwise (creating 2 images in a row and not realizing
+ * the second will have the metadata comment from the first). See #11384.
+ */
+ g_object_set (template, "comment", comment, NULL);
}
else
{
diff --git a/app/core/gimppalette-load.c b/app/core/gimppalette-load.c
index 7605b92..817c055 100644
--- a/app/core/gimppalette-load.c
+++ b/app/core/gimppalette-load.c
@@ -1095,7 +1095,7 @@ gimp_palette_load_ase (GimpContext *context,
/* Convert 4 bytes to a 32bit float value */
tmp = GINT32_FROM_BE (tmp);
- pixels[j] = *(gfloat *) &tmp;
+ memcpy (&pixels[j], &tmp, 4);
}
if (! valid_color)
@@ -1206,7 +1206,7 @@ gimp_palette_load_css (GimpContext *context,
g_return_val_if_fail (G_IS_INPUT_STREAM (input), NULL);
g_return_val_if_fail (error == NULL || *error == NULL, NULL);
- regex = g_regex_new (".*color.*:(?P<param>.*);", G_REGEX_CASELESS, 0, error);
+ regex = g_regex_new (".*color.*:(?P<param>.*)", G_REGEX_CASELESS, 0, error);
if (! regex)
return NULL;
diff --git a/app/core/gimppattern.c b/app/core/gimppattern.c
index 22d2d78..12b15b6 100644
--- a/app/core/gimppattern.c
+++ b/app/core/gimppattern.c
@@ -143,13 +143,14 @@ gimp_pattern_get_new_preview (GimpViewable *viewable,
gint width,
gint height)
{
- GimpPattern *pattern = GIMP_PATTERN (viewable);
+ GimpPattern *pattern = GIMP_PATTERN (viewable);
GimpTempBuf *temp_buf;
GeglBuffer *src_buffer;
gint true_width;
gint true_height;
gint copy_width;
gint copy_height;
+ gboolean has_temp_buf = FALSE;
true_width = gimp_temp_buf_get_width (pattern->mask);
true_height = gimp_temp_buf_get_height (pattern->mask);
@@ -174,13 +175,21 @@ gimp_pattern_get_new_preview (GimpViewable *viewable,
temp_buf = gimp_temp_buf_new (copy_width, copy_height,
gimp_temp_buf_get_format (pattern->mask));
- gegl_buffer_get (src_buffer,
- GEGL_RECTANGLE (0, 0, copy_width, copy_height),
- scale, gimp_temp_buf_get_format (temp_buf),
- gimp_temp_buf_get_data (temp_buf),
- GEGL_AUTO_ROWSTRIDE, GEGL_ABYSS_CLAMP);
+ if (temp_buf)
+ {
+ gegl_buffer_get (src_buffer,
+ GEGL_RECTANGLE (0, 0, copy_width, copy_height),
+ scale, gimp_temp_buf_get_format (temp_buf),
+ gimp_temp_buf_get_data (temp_buf),
+ GEGL_AUTO_ROWSTRIDE, GEGL_ABYSS_CLAMP);
+
+ has_temp_buf = TRUE;
+ }
}
- else
+
+ /* If scaled image pattern could not be loaded,
+ * use the default pattern */
+ if (! has_temp_buf)
{
GeglBuffer *dest_buffer;
diff --git a/app/dialogs/preferences-dialog.c b/app/dialogs/preferences-dialog.c
index cde1576..67e21b5 100644
--- a/app/dialogs/preferences-dialog.c
+++ b/app/dialogs/preferences-dialog.c
@@ -35,6 +35,7 @@
#include "core/gimp.h"
#include "core/gimptemplate.h"
+#include "core/gimp-utils.h"
#include "plug-in/gimppluginmanager.h"
@@ -74,7 +75,6 @@
#include "gimp-intl.h"
-
#define RESPONSE_RESET 1
@@ -3146,6 +3146,19 @@ prefs_dialog_new (Gimp *gimp,
vbox2 = prefs_frame_new (_("Extended Input Devices"),
GTK_CONTAINER (vbox), FALSE);
+#ifdef G_OS_WIN32
+ if (gimp_win32_have_windows_ink ())
+ {
+ GtkWidget *combo;
+
+ table = prefs_table_new (1, GTK_CONTAINER (vbox2));
+
+ combo = prefs_enum_combo_box_add (object, "win32-pointer-input-api", 0, 0,
+ _("Pointer Input API:"),
+ GTK_TABLE (table), 0, NULL);
+ }
+#endif
+
prefs_check_button_add (object, "devices-share-tool",
_("S_hare tool and tool options between input devices"),
GTK_BOX (vbox2));
diff --git a/app/dialogs/quit-dialog.c b/app/dialogs/quit-dialog.c
index 11737f9..435ea49 100644
--- a/app/dialogs/quit-dialog.c
+++ b/app/dialogs/quit-dialog.c
@@ -273,7 +273,7 @@ quit_close_all_dialog_new (Gimp *gimp,
closure = g_cclosure_new (G_CALLBACK (quit_close_all_dialog_container_changed),
private, NULL);
- g_object_watch_closure (G_OBJECT (private->dialog), closure);
+ g_signal_connect_swapped (private->dialog, "destroy", G_CALLBACK (g_closure_invalidate), closure);
g_signal_connect_closure (private->images, "add", closure, FALSE);
g_signal_connect_closure (private->images, "remove", closure, FALSE);
diff --git a/app/display/gimpdisplayshell-title.c b/app/display/gimpdisplayshell-title.c
index ff356ce..ba14485 100644
--- a/app/display/gimpdisplayshell-title.c
+++ b/app/display/gimpdisplayshell-title.c
@@ -59,6 +59,11 @@ static gint gimp_display_shell_format_title (GimpDisplayShell *display,
gint title_len,
const gchar *format);
+static gint print_unichar (gunichar c,
+ gchar *title,
+ gint title_len,
+ gint index);
+
/* public functions */
@@ -170,6 +175,21 @@ print (gchar *buf,
}
static gint
+print_unichar (gunichar c,
+ gchar *title,
+ gint title_len,
+ gint index)
+{
+ gchar letter[8];
+ gint len;
+
+ len = g_unichar_to_utf8 (c, letter);
+ letter[len] = '\0';
+
+ return print (title, title_len, index, "%s", letter);
+}
+
+static gint
gimp_display_shell_format_title (GimpDisplayShell *shell,
gchar *title,
gint title_len,
@@ -179,6 +199,7 @@ gimp_display_shell_format_title (GimpDisplayShell *shell,
GimpDrawable *drawable;
gint num, denom;
gint i = 0;
+ gunichar c;
g_return_val_if_fail (GIMP_IS_DISPLAY_SHELL (shell), 0);
@@ -194,13 +215,17 @@ gimp_display_shell_format_title (GimpDisplayShell *shell,
gimp_zoom_model_get_fraction (shell->zoom, &num, &denom);
- while (i < title_len && *format)
+ c = g_utf8_get_char (format);
+ while (i < title_len && c)
{
- switch (*format)
+ switch (c)
{
case '%':
- format++;
- switch (*format)
+ format = g_utf8_next_char (format);
+ c = g_utf8_get_char (format);
+
+ switch (c)
+
{
case 0:
/* format string ends within %-sequence, print literal '%' */
@@ -262,27 +287,31 @@ gimp_display_shell_format_title (GimpDisplayShell *shell,
break;
case 'D': /* dirty flag */
- if (format[1] == 0)
+ format = g_utf8_next_char (format);
+ c = g_utf8_get_char (format);
+
+ if (c == 0)
{
/* format string ends within %D-sequence, print literal '%D' */
i += print (title, title_len, i, "%%D");
break;
}
if (gimp_image_is_dirty (image))
- title[i++] = format[1];
- format++;
+ i += print_unichar (c, title, title_len, i);
break;
case 'C': /* clean flag */
- if (format[1] == 0)
+ format = g_utf8_next_char (format);
+ c = g_utf8_get_char (format);
+
+ if (c == 0)
{
/* format string ends within %C-sequence, print literal '%C' */
i += print (title, title_len, i, "%%C");
break;
}
if (! gimp_image_is_dirty (image))
- title[i++] = format[1];
- format++;
+ i += print_unichar (c, title, title_len, i);
break;
case 'B': /* dirty flag (long) */
@@ -296,27 +325,31 @@ gimp_display_shell_format_title (GimpDisplayShell *shell,
break;
case 'N': /* not-exported flag */
- if (format[1] == 0)
+ format = g_utf8_next_char (format);
+ c = g_utf8_get_char (format);
+
+ if (c == 0)
{
/* format string ends within %E-sequence, print literal '%E' */
i += print (title, title_len, i, "%%N");
break;
}
if (gimp_image_is_export_dirty (image))
- title[i++] = format[1];
- format++;
+ i += print_unichar (c, title, title_len, i);
break;
case 'E': /* exported flag */
- if (format[1] == 0)
+ format = g_utf8_next_char (format);
+ c = g_utf8_get_char (format);
+
+ if (c == 0)
{
/* format string ends within %E-sequence, print literal '%E' */
i += print (title, title_len, i, "%%E");
break;
}
if (! gimp_image_is_export_dirty (image))
- title[i++] = format[1];
- format++;
+ i += print_unichar (c, title, title_len, i);
break;
case 'm': /* memory used by image */
@@ -545,17 +578,18 @@ gimp_display_shell_format_title (GimpDisplayShell *shell,
default:
/* format string contains unknown %-sequence, print it literally */
- i += print (title, title_len, i, "%%%c", *format);
+ i += print_unichar (c, title, title_len, i);
break;
}
break;
default:
- title[i++] = *format;
+ i += print_unichar (c, title, title_len, i);
break;
}
- format++;
+ format = g_utf8_next_char (format);
+ c = g_utf8_get_char (format);
}
title[MIN (i, title_len - 1)] = '\0';
diff --git a/app/display/gimpimagewindow.c b/app/display/gimpimagewindow.c
index fd5c501..5de1fac 100644
--- a/app/display/gimpimagewindow.c
+++ b/app/display/gimpimagewindow.c
@@ -1105,9 +1105,6 @@ gimp_image_window_set_aux_info (GimpSessionManaged *session_managed,
else if (StartupInfo.wShowWindow == SW_SHOWMINIMIZED ||
StartupInfo.wShowWindow == SW_SHOWMINNOACTIVE ||
StartupInfo.wShowWindow == SW_MINIMIZE)
- /* XXX Iconification does not seem to work. I see the
- * window being iconified and immediately re-raised.
- * I leave this piece of code for later improvement. */
gtk_window_iconify (GTK_WINDOW (session_managed));
else
/* Another show property not relevant to min/max.
diff --git a/app/gegl/gimp-babl.c b/app/gegl/gimp-babl.c
index b2dc20a..19673e9 100644
--- a/app/gegl/gimp-babl.c
+++ b/app/gegl/gimp-babl.c
@@ -36,6 +36,8 @@
void
gimp_babl_init (void)
{
+// in newer version of babl these format names are pre-registered
+#if (BABL_MINOR_VERSION == 1 && BABL_MICRO_VERSION <= 108)
babl_format_new ("name", "R u8",
babl_model ("RGBA"),
babl_type ("u8"),
@@ -251,6 +253,7 @@ gimp_babl_init (void)
babl_type ("double"),
babl_component ("A"),
NULL);
+#endif
}
void
diff --git a/app/gui/gui.c b/app/gui/gui.c
index e5928eb..ef548f5 100644
--- a/app/gui/gui.c
+++ b/app/gui/gui.c
@@ -83,6 +83,12 @@
#include "splash.h"
#include "themes.h"
+#ifdef G_OS_WIN32
+#include <windef.h>
+#include <winbase.h>
+#include <windows.h>
+#endif
+
#ifdef GDK_WINDOWING_QUARTZ
#import <AppKit/AppKit.h>
#include <gtkosxapplication.h>
@@ -599,6 +605,11 @@ gui_restore_after_callback (Gimp *gimp,
{
GimpGuiConfig *gui_config = GIMP_GUI_CONFIG (gimp->config);
GimpDisplay *display;
+#ifdef G_OS_WIN32
+ STARTUPINFO StartupInfo;
+
+ GetStartupInfo (&StartupInfo);
+#endif
if (gimp->be_verbose)
g_print ("INIT: %s\n", G_STRFUNC);
@@ -740,6 +751,14 @@ gui_restore_after_callback (Gimp *gimp,
}
#endif /* GDK_WINDOWING_QUARTZ */
+#ifdef G_OS_WIN32
+ /* Prevents window from reappearing on start-up if the user
+ * requested it to be minimized via window hints
+ */
+ if (StartupInfo.wShowWindow != SW_SHOWMINIMIZED &&
+ StartupInfo.wShowWindow != SW_SHOWMINNOACTIVE &&
+ StartupInfo.wShowWindow != SW_MINIMIZE)
+#endif
/* move keyboard focus to the display */
gtk_window_present (GTK_WINDOW (toplevel));
}
diff --git a/app/gui/splash.c b/app/gui/splash.c
index aec664e..23c0505 100644
--- a/app/gui/splash.c
+++ b/app/gui/splash.c
@@ -35,6 +35,11 @@
#include "gimp-intl.h"
+#ifdef G_OS_WIN32
+#include <windef.h>
+#include <winbase.h>
+#include <windows.h>
+#endif
#define MEASURE_UPPER "1235678901234567890"
#define MEASURE_LOWER "12356789012345678901234567890"
@@ -118,6 +123,11 @@ splash_create (gboolean be_verbose,
PangoRectangle ink;
gint max_width;
gint max_height;
+#ifdef G_OS_WIN32
+ STARTUPINFO StartupInfo;
+
+ GetStartupInfo (&StartupInfo);
+#endif
g_return_if_fail (splash == NULL);
g_return_if_fail (GDK_IS_SCREEN (screen));
@@ -219,6 +229,13 @@ splash_create (gboolean be_verbose,
gtk_widget_show (splash->window);
+#ifdef G_OS_WIN32
+ if (StartupInfo.wShowWindow == SW_SHOWMINIMIZED ||
+ StartupInfo.wShowWindow == SW_SHOWMINNOACTIVE ||
+ StartupInfo.wShowWindow == SW_MINIMIZE)
+ gtk_window_iconify (GTK_WINDOW (splash->window));
+#endif
+
if (FALSE)
splash->timer = g_timer_new ();
}
diff --git a/app/main.c b/app/main.c
index ba38758..9527219 100644
--- a/app/main.c
+++ b/app/main.c
@@ -44,7 +44,7 @@
#endif /* __APPLE__ */
#ifndef GIMP_CONSOLE_COMPILATION
-#include <gdk/gdk.h>
+#include <gtk/gtk.h>
#else
#include <gdk-pixbuf/gdk-pixbuf.h>
#endif
@@ -55,10 +55,12 @@
#include "pdb/pdb-types.h"
+#include "config/gimpearlyrc.h"
#include "config/gimpconfig-dump.h"
#include "core/gimp.h"
#include "core/gimpbacktrace.h"
+#include "core/gimp-utils.h"
#include "pdb/gimppdb.h"
#include "pdb/gimpprocedure.h"
@@ -66,6 +68,7 @@
#include "about.h"
#include "app.h"
+#include "language.h"
#include "sanity.h"
#include "signals.h"
#include "unique.h"
@@ -325,6 +328,7 @@ gimp_macos_setenv (const char * progname)
* instead of system one
*/
static gboolean show_playground = TRUE;
+ gboolean need_pythonpath = FALSE;
gchar *path;
gchar *tmp;
@@ -332,6 +336,7 @@ gimp_macos_setenv (const char * progname)
gchar *res_dir;
size_t path_len;
struct stat sb;
+ gchar *pythonpath_format;
app_dir = g_path_get_dirname (resolved_path);
tmp = g_strdup_printf ("%s/../Resources", app_dir);
@@ -347,6 +352,15 @@ gimp_macos_setenv (const char * progname)
return;
}
+ /* Detect we were built in MacPorts for MacOS and setup PYTHONPATH */
+ tmp = g_strdup_printf ("%s/Library/Frameworks/Python.framework", res_dir);
+ if (tmp && !stat (tmp, &sb) && S_ISDIR (sb.st_mode))
+ {
+ g_print ("GIMP was built with MacPorts\n");
+ need_pythonpath = TRUE;
+ }
+ g_free (tmp);
+
path_len = strlen (g_getenv ("PATH") ? g_getenv ("PATH") : "") + strlen (app_dir) + 2;
path = g_try_malloc (path_len);
if (path == NULL)
@@ -379,12 +393,23 @@ gimp_macos_setenv (const char * progname)
tmp = g_strdup_printf ("%s/etc/fonts", res_dir);
g_setenv ("FONTCONFIG_PATH", tmp, TRUE);
g_free (tmp);
- tmp = g_strdup_printf ("%s", res_dir);
- g_setenv ("PYTHONHOME", tmp, TRUE);
- g_free (tmp);
- tmp = g_strdup_printf ("%s/lib/python2.7:%s/lib/gimp/2.0/python", res_dir, res_dir);
- g_setenv ("PYTHONPATH", tmp, TRUE);
- g_free (tmp);
+ if (need_pythonpath)
+ {
+ g_unsetenv ("PYTHONHOME");
+ pythonpath_format = "%s/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages:%s/lib/gimp/2.0/python";
+ tmp = g_strdup_printf (pythonpath_format, res_dir, res_dir);
+ g_setenv ("PYTHONPATH", tmp, TRUE);
+ g_free (tmp);
+ }
+ else
+ {
+ tmp = g_strdup_printf ("%s", res_dir);
+ g_setenv ("PYTHONHOME", tmp, TRUE);
+ g_free (tmp);
+ tmp = g_strdup_printf ("%s/lib/python2.7:%s/lib/gimp/2.0/python", res_dir, res_dir);
+ g_setenv ("PYTHONPATH", tmp, TRUE);
+ g_free (tmp);
+ }
tmp = g_strdup_printf ("%s/lib/gio/modules", res_dir);
g_setenv ("GIO_MODULE_DIR", tmp, TRUE);
g_free (tmp);
@@ -404,6 +429,84 @@ gimp_macos_setenv (const char * progname)
}
#endif
+/* gimp_early_configuration () is executed as soon as we can read
+ * the "gimprc" files, but before any library initialization takes
+ * place
+ */
+static void
+gimp_early_configuration (void)
+{
+ GFile *system_gimprc_file = NULL;
+ GFile *user_gimprc_file = NULL;
+ GimpEarlyRc *earlyrc;
+ gchar *language;
+
+ if (system_gimprc)
+ system_gimprc_file = g_file_new_for_commandline_arg (system_gimprc);
+
+ if (user_gimprc)
+ user_gimprc_file = g_file_new_for_commandline_arg (user_gimprc);
+
+ /* GimpEarlyRc is reponsible for reading "gimprc" files for the
+ * sole purpose of getting some configuration data that is needed
+ * in the early initialization phase
+ */
+ earlyrc = gimp_early_rc_new (system_gimprc_file,
+ user_gimprc_file,
+ be_verbose);
+
+ /* Language needs to be determined first, before any GimpContext is
+ * instantiated (which happens when the Gimp object is created)
+ * because its properties need to be properly localized in the
+ * settings language (if different from system language). Otherwise we
+ * end up with pieces of GUI always using the system language (cf. bug
+ * 787457)
+ */
+ language = gimp_early_rc_get_language (earlyrc);
+
+ /* change the locale if a language if specified */
+ language_init (language);
+ if (language)
+ g_free (language);
+
+#if defined (G_OS_WIN32) && !defined (GIMP_CONSOLE_COMPILATION)
+ if (gimp_win32_have_windows_ink ())
+ {
+ 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);
+
+ if (system_gimprc_file)
+ g_object_unref (system_gimprc_file);
+
+ if (user_gimprc_file)
+ g_object_unref (user_gimprc_file);
+}
+
+static gboolean
+gimp_options_group_parse_hook (GOptionContext *context,
+ GOptionGroup *group,
+ gpointer data,
+ GError **error)
+{
+ /* early initialization from data stored in "gimprc" files */
+ gimp_early_configuration ();
+
+ return TRUE;
+}
+
int
main (int argc,
char **argv)
@@ -414,6 +517,7 @@ main (int argc,
gchar *basename;
GFile *system_gimprc_file = NULL;
GFile *user_gimprc_file = NULL;
+ GOptionGroup *gimp_group = NULL;
gchar *backtrace_file = NULL;
gint i;
@@ -598,6 +702,16 @@ main (int argc,
context = g_option_context_new (_("[FILE|URI...]"));
g_option_context_set_summary (context, GIMP_NAME);
+ /* The GIMP option group is just an empty option group, created for the sole
+ * purpose of running a post-parse hook before any other of dependant libraries
+ * are run. This makes it possible to apply options from configuration data
+ * obtained from "gimprc" files, before other libraries have a chance to run
+ * some of their intialization code.
+ */
+ gimp_group = g_option_group_new ("gimp", "", "", NULL, NULL);
+ g_option_group_set_parse_hooks (gimp_group, NULL, gimp_options_group_parse_hook);
+ g_option_context_add_group (context, gimp_group);
+
g_option_context_add_main_entries (context, main_entries, GETTEXT_PACKAGE);
app_libs_init (context, no_interface);
diff --git a/app/pdb/plug-in-compat-cmds.c b/app/pdb/plug-in-compat-cmds.c
index 6e02cdd..fe61802 100644
--- a/app/pdb/plug-in-compat-cmds.c
+++ b/app/pdb/plug-in-compat-cmds.c
@@ -3397,11 +3397,15 @@ plug_in_plasma_invoker (GimpProcedure *procedure,
GIMP_PDB_ITEM_CONTENT, error) &&
gimp_pdb_item_is_not_group (GIMP_ITEM (drawable), error))
{
- GeglNode *node;
- gint x, y, width, height;
+ GimpImage *image = gimp_item_get_image (GIMP_ITEM (drawable));
+ GeglNode *node;
+ gint x, y, width, height;
gimp_item_mask_intersect (GIMP_ITEM (drawable), &x, &y, &width, &height);
+ if (! gimp_channel_is_empty (gimp_image_get_mask (image)))
+ x = y = 0;
+
node = gegl_node_new_child (NULL,
"operation", "gegl:plasma",
"seed", seed,
@@ -6373,8 +6377,8 @@ register_plug_in_compat_procs (GimpPDB *pdb)
gimp_procedure_add_argument (procedure,
g_param_spec_double ("radius",
"radius",
- "Radius of gaussian blur (in pixels",
- 0.0, 500.0, 0.0,
+ "Radius of gaussian blur (in pixels)",
+ 0.0, 1500.0, 0.0,
GIMP_PARAM_READWRITE));
gimp_procedure_add_argument (procedure,
g_param_spec_boolean ("horizontal",
@@ -6475,8 +6479,8 @@ register_plug_in_compat_procs (GimpPDB *pdb)
gimp_procedure_add_argument (procedure,
g_param_spec_double ("radius",
"radius",
- "Radius of gaussian blur (in pixels",
- 0.0, 500.0, 0.0,
+ "Radius of gaussian blur (in pixels)",
+ 0.0, 1500.0, 0.0,
GIMP_PARAM_READWRITE));
gimp_procedure_add_argument (procedure,
g_param_spec_boolean ("horizontal",
@@ -9021,13 +9025,13 @@ register_plug_in_compat_procs (GimpPDB *pdb)
g_param_spec_double ("spread-amount-x",
"spread amount x",
"Horizontal spread amount",
- 0, 200, 0,
+ 0, 512, 0,
GIMP_PARAM_READWRITE));
gimp_procedure_add_argument (procedure,
g_param_spec_double ("spread-amount-y",
"spread amount y",
"Vertical spread amount",
- 0, 200, 0,
+ 0, 512, 0,
GIMP_PARAM_READWRITE));
gimp_pdb_register_procedure (pdb, procedure);
g_object_unref (procedure);
@@ -9483,7 +9487,7 @@ register_plug_in_compat_procs (GimpPDB *pdb)
g_param_spec_double ("wavelength",
"wavelength",
"The Wavelength of the Waves",
- 0.1, 50, 0.1,
+ 0.1, 100, 0.1,
GIMP_PARAM_READWRITE));
gimp_procedure_add_argument (procedure,
g_param_spec_boolean ("type",
diff --git a/app/widgets/gimpaction-history.c b/app/widgets/gimpaction-history.c
index 37cdc03..57ac1bf 100644
--- a/app/widgets/gimpaction-history.c
+++ b/app/widgets/gimpaction-history.c
@@ -319,6 +319,7 @@ gimp_action_history_is_blacklisted_action (const gchar *action_name)
return (g_str_has_suffix (action_name, "-set") ||
g_str_has_suffix (action_name, "-accel") ||
+ g_str_has_suffix (action_name, "-internal") ||
g_str_has_prefix (action_name, "context-") ||
g_str_has_prefix (action_name, "filters-recent-") ||
g_strcmp0 (action_name, "dialogs-action-search") == 0);
diff --git a/app/widgets/gimpdashboard.c b/app/widgets/gimpdashboard.c
index 8e8273b..5b55b37 100644
--- a/app/widgets/gimpdashboard.c
+++ b/app/widgets/gimpdashboard.c
@@ -2420,6 +2420,13 @@ gimp_dashboard_sample_cpu_active_time (GimpDashboard *dashboard,
#ifdef HAVE_MEMORY_GROUP
#ifdef PLATFORM_OSX
+ #if MAC_OS_X_VERSION_MAX_ALLOWED < 1080
+ #define MACH_TASK_BASIC_INFO_COUNT TASK_BASIC_INFO_COUNT
+ #define mach_task_basic_info_data_t task_basic_info_data_t
+
+ #define MACH_TASK_BASIC_INFO TASK_BASIC_INFO
+ #define mach_task_basic_info task_basic_info
+ #endif
static void
gimp_dashboard_sample_memory_used (GimpDashboard *dashboard,
Variable variable)
diff --git a/app/widgets/gimpdeviceinfo.c b/app/widgets/gimpdeviceinfo.c
index 594dd90..053af61 100644
--- a/app/widgets/gimpdeviceinfo.c
+++ b/app/widgets/gimpdeviceinfo.c
@@ -80,7 +80,6 @@ G_DEFINE_TYPE (GimpDeviceInfo, gimp_device_info, GIMP_TYPE_TOOL_PRESET)
#define parent_class gimp_device_info_parent_class
-
static void
gimp_device_info_class_init (GimpDeviceInfoClass *klass)
{
@@ -535,8 +534,23 @@ gimp_device_info_set_device (GimpDeviceInfo *info,
* Also we had no clear report on macOS or BSD (AFAIK) of broken
* tablets with any of the version of the code. So let's keep
* these similar to Linux for now.
+ *
+ * Update: it's not needed for Windows Ink, only Wintab.
*/
- return FALSE;
+ {
+ Gimp *gimp = NULL;
+
+ g_object_get (info, "gimp", &gimp, NULL);
+ if (gimp)
+ {
+ GimpWin32PointerInputAPI api = GIMP_WIN32_POINTER_INPUT_API_WINTAB;
+
+ g_object_get (gimp->config, "win32-pointer-input-api", &api, NULL);
+
+ if (api == GIMP_WIN32_POINTER_INPUT_API_WINTAB)
+ return FALSE;
+ }
+ }
#endif /* G_OS_WIN32 */
}
else if (! device && ! info->device)