From db0da4c882437f3b76a34308edeaa2c41d8c2833 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Wed, 8 May 2024 10:16:52 +0200 Subject: Merging upstream version 2.10.38. Signed-off-by: Daniel Baumann --- app/actions/data-commands.c | 20 +- app/app.c | 24 --- app/config/Makefile.am | 4 +- app/config/Makefile.in | 18 +- app/config/config-types.h | 2 +- app/config/gimpcoreconfig.c | 43 +++++ app/config/gimpcoreconfig.h | 3 + app/config/gimpearlyrc.c | 346 +++++++++++++++++++++++++++++++++++ app/config/gimpearlyrc.h | 71 +++++++ app/config/gimplangrc.c | 280 ---------------------------- app/config/gimplangrc.h | 60 ------ app/config/gimprc-blurbs.h | 3 + app/core/core-enums.c | 29 +++ app/core/core-enums.h | 11 ++ app/core/gimp-utils.c | 45 +++++ app/core/gimp-utils.h | 6 + app/core/gimpimage-new.c | 11 ++ app/core/gimppalette-load.c | 4 +- app/core/gimppattern.c | 23 ++- app/dialogs/preferences-dialog.c | 15 +- app/dialogs/quit-dialog.c | 2 +- app/display/gimpdisplayshell-title.c | 72 ++++++-- app/display/gimpimagewindow.c | 3 - app/gegl/gimp-babl.c | 3 + app/gui/gui.c | 19 ++ app/gui/splash.c | 17 ++ app/main.c | 128 ++++++++++++- app/pdb/plug-in-compat-cmds.c | 22 ++- app/widgets/gimpaction-history.c | 1 + app/widgets/gimpdashboard.c | 7 + app/widgets/gimpdeviceinfo.c | 18 +- 31 files changed, 879 insertions(+), 431 deletions(-) create mode 100644 app/config/gimpearlyrc.c create mode 100644 app/config/gimpearlyrc.h delete mode 100644 app/config/gimplangrc.c delete mode 100644 app/config/gimplangrc.h (limited to 'app') 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/gimpearlyrc.c b/app/config/gimpearlyrc.c new file mode 100644 index 0000000..f9e83d5 --- /dev/null +++ b/app/config/gimpearlyrc.c @@ -0,0 +1,346 @@ +/* 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 + * + * 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 . + */ + +#include "config.h" + +#include + +#include "libgimpbase/gimpbase.h" +#include "libgimpconfig/gimpconfig.h" + +#include "config-types.h" + +#include "core/core-types.h" +#include "core/gimp-utils.h" + +#include "gimpearlyrc.h" + +enum +{ + PROP_0, + PROP_VERBOSE, + PROP_SYSTEM_GIMPRC, + PROP_USER_GIMPRC, + PROP_LANGUAGE, +#ifdef G_OS_WIN32 + PROP_WIN32_POINTER_INPUT_API, +#endif +}; + + +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 properties. */ +G_DEFINE_TYPE_WITH_CODE (GimpEarlyRc, gimp_early_rc, G_TYPE_OBJECT, + G_IMPLEMENT_INTERFACE (GIMP_TYPE_CONFIG, NULL)) + +#define parent_class gimp_early_rc_parent_class + + +static void +gimp_early_rc_class_init (GimpEarlyRcClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + 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", + NULL, NULL, + FALSE, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT_ONLY)); + + g_object_class_install_property (object_class, PROP_SYSTEM_GIMPRC, + g_param_spec_object ("system-gimprc", + NULL, NULL, + G_TYPE_FILE, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT_ONLY)); + + g_object_class_install_property (object_class, PROP_USER_GIMPRC, + g_param_spec_object ("user-gimprc", + NULL, NULL, + G_TYPE_FILE, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT_ONLY)); + + GIMP_CONFIG_PROP_STRING (object_class, PROP_LANGUAGE, + "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_early_rc_init (GimpEarlyRc *rc) +{ +} + +static void +gimp_early_rc_constructed (GObject *object) +{ + GimpEarlyRc *rc = GIMP_EARLY_RC (object); + GError *error = NULL; + + if (rc->verbose) + 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), + rc->system_gimprc, NULL, &error)) + { + if (error->code != GIMP_CONFIG_ERROR_OPEN_ENOENT) + g_message ("%s", error->message); + + g_clear_error (&error); + } + + if (rc->verbose) + 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), + rc->user_gimprc, NULL, &error)) + { + if (error->code != GIMP_CONFIG_ERROR_OPEN_ENOENT) + g_message ("%s", error->message); + + g_clear_error (&error); + } + + if (rc->verbose) + { + if (rc->language) + g_print ("Language property found: %s.\n", rc->language); + else + g_print ("No language property found.\n"); + } +} + +static void +gimp_early_rc_finalize (GObject *object) +{ + GimpEarlyRc *rc = GIMP_EARLY_RC (object); + + g_clear_object (&rc->system_gimprc); + g_clear_object (&rc->user_gimprc); + + g_clear_pointer (&rc->language, g_free); + + G_OBJECT_CLASS (parent_class)->finalize (object); +} + +static void +gimp_early_rc_set_property (GObject *object, + guint property_id, + const GValue *value, + GParamSpec *pspec) +{ + GimpEarlyRc *rc = GIMP_EARLY_RC (object); + + switch (property_id) + { + case PROP_VERBOSE: + rc->verbose = g_value_get_boolean (value); + break; + + case PROP_SYSTEM_GIMPRC: + if (rc->system_gimprc) + g_object_unref (rc->system_gimprc); + + if (g_value_get_object (value)) + rc->system_gimprc = g_value_dup_object (value); + else + rc->system_gimprc = gimp_sysconf_directory_file ("gimprc", NULL); + break; + + case PROP_USER_GIMPRC: + if (rc->user_gimprc) + g_object_unref (rc->user_gimprc); + + if (g_value_get_object (value)) + rc->user_gimprc = g_value_dup_object (value); + else + rc->user_gimprc = gimp_directory_file ("gimprc", NULL); + break; + + case PROP_LANGUAGE: + if (rc->language) + g_free (rc->language); + 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; + } +} + +static void +gimp_early_rc_get_property (GObject *object, + guint property_id, + GValue *value, + GParamSpec *pspec) +{ + GimpEarlyRc *rc = GIMP_EARLY_RC (object); + + switch (property_id) + { + case PROP_VERBOSE: + g_value_set_boolean (value, rc->verbose); + break; + case PROP_SYSTEM_GIMPRC: + g_value_set_object (value, rc->system_gimprc); + break; + case PROP_USER_GIMPRC: + g_value_set_object (value, rc->user_gimprc); + break; + case PROP_LANGUAGE: + 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; + } +} + +/** + * 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 preferences + * + * Creates a new GimpEarlyRc object which looks for some configuration + * data required in the early initialization steps + * + * Returns: the new #GimpEarlyRc. + */ +GimpEarlyRc * +gimp_early_rc_new (GFile *system_gimprc, + GFile *user_gimprc, + gboolean verbose) +{ + 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_EARLY_RC, + "verbose", verbose, + "system-gimprc", system_gimprc, + "user-gimprc", user_gimprc, + NULL); + + return rc; +} + +/** + * gimp_early_rc_get_language: + * @rc: a #GimpEarlyRc object. + * + * This function looks up the language set in `gimprc`. + * + * Return value: a newly allocated string representing the language or + * %NULL if the key couldn't be found. + **/ +gchar * +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 + * + * 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 . + */ + +#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.c b/app/config/gimplangrc.c deleted file mode 100644 index 34e26f4..0000000 --- a/app/config/gimplangrc.c +++ /dev/null @@ -1,280 +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 - * - * 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 . - */ - -#include "config.h" - -#include - -#include "libgimpbase/gimpbase.h" -#include "libgimpconfig/gimpconfig.h" - -#include "config-types.h" - -#include "gimplangrc.h" - -enum -{ - PROP_0, - PROP_VERBOSE, - PROP_SYSTEM_GIMPRC, - PROP_USER_GIMPRC, - PROP_LANGUAGE -}; - - -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); - - -/* 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, - G_IMPLEMENT_INTERFACE (GIMP_TYPE_CONFIG, NULL)) - -#define parent_class gimp_lang_rc_parent_class - - -static void -gimp_lang_rc_class_init (GimpLangRcClass *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; - - g_object_class_install_property (object_class, PROP_VERBOSE, - g_param_spec_boolean ("verbose", - NULL, NULL, - FALSE, - G_PARAM_READWRITE | - G_PARAM_CONSTRUCT_ONLY)); - - g_object_class_install_property (object_class, PROP_SYSTEM_GIMPRC, - g_param_spec_object ("system-gimprc", - NULL, NULL, - G_TYPE_FILE, - G_PARAM_READWRITE | - G_PARAM_CONSTRUCT_ONLY)); - - g_object_class_install_property (object_class, PROP_USER_GIMPRC, - g_param_spec_object ("user-gimprc", - NULL, NULL, - G_TYPE_FILE, - G_PARAM_READWRITE | - G_PARAM_CONSTRUCT_ONLY)); - - GIMP_CONFIG_PROP_STRING (object_class, PROP_LANGUAGE, - "language", NULL, NULL, NULL, - GIMP_PARAM_STATIC_STRINGS); - -} - -static void -gimp_lang_rc_init (GimpLangRc *rc) -{ -} - -static void -gimp_lang_rc_constructed (GObject *object) -{ - GimpLangRc *rc = GIMP_LANG_RC (object); - GError *error = NULL; - - if (rc->verbose) - g_print ("Parsing '%s' for configured language.\n", - gimp_file_get_utf8_name (rc->system_gimprc)); - - if (! gimp_config_deserialize_gfile (GIMP_CONFIG (rc), - rc->system_gimprc, NULL, &error)) - { - if (error->code != GIMP_CONFIG_ERROR_OPEN_ENOENT) - g_message ("%s", error->message); - - g_clear_error (&error); - } - - if (rc->verbose) - g_print ("Parsing '%s' for configured language.\n", - gimp_file_get_utf8_name (rc->user_gimprc)); - - if (! gimp_config_deserialize_gfile (GIMP_CONFIG (rc), - rc->user_gimprc, NULL, &error)) - { - if (error->code != GIMP_CONFIG_ERROR_OPEN_ENOENT) - g_message ("%s", error->message); - - g_clear_error (&error); - } - - if (rc->verbose) - { - if (rc->language) - g_print ("Language property found: %s.\n", rc->language); - else - g_print ("No language property found.\n"); - } -} - -static void -gimp_lang_rc_finalize (GObject *object) -{ - GimpLangRc *rc = GIMP_LANG_RC (object); - - g_clear_object (&rc->system_gimprc); - g_clear_object (&rc->user_gimprc); - - g_clear_pointer (&rc->language, g_free); - - G_OBJECT_CLASS (parent_class)->finalize (object); -} - -static void -gimp_lang_rc_set_property (GObject *object, - guint property_id, - const GValue *value, - GParamSpec *pspec) -{ - GimpLangRc *rc = GIMP_LANG_RC (object); - - switch (property_id) - { - case PROP_VERBOSE: - rc->verbose = g_value_get_boolean (value); - break; - - case PROP_SYSTEM_GIMPRC: - if (rc->system_gimprc) - g_object_unref (rc->system_gimprc); - - if (g_value_get_object (value)) - rc->system_gimprc = g_value_dup_object (value); - else - rc->system_gimprc = gimp_sysconf_directory_file ("gimprc", NULL); - break; - - case PROP_USER_GIMPRC: - if (rc->user_gimprc) - g_object_unref (rc->user_gimprc); - - if (g_value_get_object (value)) - rc->user_gimprc = g_value_dup_object (value); - else - rc->user_gimprc = gimp_directory_file ("gimprc", NULL); - break; - - case PROP_LANGUAGE: - if (rc->language) - g_free (rc->language); - rc->language = g_value_dup_string (value); - break; - - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); - break; - } -} - -static void -gimp_lang_rc_get_property (GObject *object, - guint property_id, - GValue *value, - GParamSpec *pspec) -{ - GimpLangRc *rc = GIMP_LANG_RC (object); - - switch (property_id) - { - case PROP_VERBOSE: - g_value_set_boolean (value, rc->verbose); - break; - case PROP_SYSTEM_GIMPRC: - g_value_set_object (value, rc->system_gimprc); - break; - case PROP_USER_GIMPRC: - g_value_set_object (value, rc->user_gimprc); - break; - case PROP_LANGUAGE: - g_value_set_string (value, rc->language); - break; - - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); - break; - } -} - -/** - * gimp_lang_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 - * - * Creates a new GimpLangRc object which only looks for the configure - * language. - * - * Returns: the new #GimpLangRc. - */ -GimpLangRc * -gimp_lang_rc_new (GFile *system_gimprc, - GFile *user_gimprc, - gboolean verbose) -{ - GimpLangRc *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, - "verbose", verbose, - "system-gimprc", system_gimprc, - "user-gimprc", user_gimprc, - NULL); - - return rc; -} - -/** - * gimp_lang_rc_get_language: - * @lang_rc: a #GimpLangRc object. - * - * This function looks up the language set in `gimprc`. - * - * Return value: a newly allocated string representing the language or - * %NULL if the key couldn't be found. - **/ -gchar * -gimp_lang_rc_get_language (GimpLangRc *rc) -{ - return rc->language ? g_strdup (rc->language) : NULL; -} 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 - * - * 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 . - */ - -#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 @@ -925,6 +925,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 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.*);", G_REGEX_CASELESS, 0, error); + regex = g_regex_new (".*color.*:(?P.*)", 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 */ @@ -169,6 +174,21 @@ print (gchar *buf, return printed; } +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, @@ -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 +#include +#include +#endif + #ifdef GDK_WINDOWING_QUARTZ #import #include @@ -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 +#include +#include +#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 +#include #else #include #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) -- cgit v1.2.3