summaryrefslogtreecommitdiffstats
path: root/app/config
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--app/config/Makefile.am165
-rw-r--r--app/config/Makefile.in1505
-rw-r--r--app/config/config-enums.c397
-rw-r--r--app/config/config-enums.h173
-rw-r--r--app/config/config-types.h59
-rw-r--r--app/config/gimpconfig-dump.c644
-rw-r--r--app/config/gimpconfig-dump.h37
-rw-r--r--app/config/gimpconfig-file.c241
-rw-r--r--app/config/gimpconfig-file.h36
-rw-r--r--app/config/gimpconfig-utils.c223
-rw-r--r--app/config/gimpconfig-utils.h36
-rw-r--r--app/config/gimpcoreconfig.c1415
-rw-r--r--app/config/gimpcoreconfig.h123
-rw-r--r--app/config/gimpdialogconfig.c991
-rw-r--r--app/config/gimpdialogconfig.h123
-rw-r--r--app/config/gimpdisplayconfig.c623
-rw-r--r--app/config/gimpdisplayconfig.h81
-rw-r--r--app/config/gimpdisplayoptions.c597
-rw-r--r--app/config/gimpdisplayoptions.h78
-rw-r--r--app/config/gimpgeglconfig.c273
-rw-r--r--app/config/gimpgeglconfig.h55
-rw-r--r--app/config/gimpguiconfig.c1017
-rw-r--r--app/config/gimpguiconfig.h110
-rw-r--r--app/config/gimplangrc.c280
-rw-r--r--app/config/gimplangrc.h60
-rw-r--r--app/config/gimppluginconfig.c217
-rw-r--r--app/config/gimppluginconfig.h56
-rw-r--r--app/config/gimprc-blurbs.h747
-rw-r--r--app/config/gimprc-deserialize.c174
-rw-r--r--app/config/gimprc-deserialize.h31
-rw-r--r--app/config/gimprc-serialize.c120
-rw-r--r--app/config/gimprc-serialize.h30
-rw-r--r--app/config/gimprc-unknown.c214
-rw-r--r--app/config/gimprc-unknown.h40
-rw-r--r--app/config/gimprc.c593
-rw-r--r--app/config/gimprc.h77
-rw-r--r--app/config/gimpxmlparser.c404
-rw-r--r--app/config/gimpxmlparser.h46
-rw-r--r--app/config/test-config.c278
39 files changed, 12369 insertions, 0 deletions
diff --git a/app/config/Makefile.am b/app/config/Makefile.am
new file mode 100644
index 0000000..04ac126
--- /dev/null
+++ b/app/config/Makefile.am
@@ -0,0 +1,165 @@
+## Process this file with automake to produce Makefile.in
+
+libgimpbase = $(top_builddir)/libgimpbase/libgimpbase-$(GIMP_API_VERSION).la
+libgimpconfig = $(top_builddir)/libgimpconfig/libgimpconfig-$(GIMP_API_VERSION).la
+libgimpcolor = $(top_builddir)/libgimpcolor/libgimpcolor-$(GIMP_API_VERSION).la
+libgimpmath = $(top_builddir)/libgimpmath/libgimpmath-$(GIMP_API_VERSION).la
+libgimpmodule = $(top_builddir)/libgimpmodule/libgimpmodule-$(GIMP_API_VERSION).la
+libgimpthumb = $(top_builddir)/libgimpthumb/libgimpthumb-$(GIMP_API_VERSION).la
+
+if OS_WIN32
+else
+libm = -lm
+endif
+
+AM_CPPFLAGS = \
+ -DG_LOG_DOMAIN=\"Gimp-Config\" \
+ -DGIMP_APP_VERSION_STRING=\"$(GIMP_APP_VERSION)\" \
+ -I$(top_builddir) \
+ -I$(top_srcdir) \
+ -I$(top_builddir)/app \
+ -I$(top_srcdir)/app \
+ $(GIO_UNIX_CFLAGS) \
+ $(GIO_WINDOWS_CFLAGS) \
+ $(GEGL_CFLAGS) \
+ $(CAIRO_CFLAGS) \
+ $(GDK_PIXBUF_CFLAGS) \
+ $(MYPAINT_BRUSHES_CFLAGS) \
+ -I$(includedir)
+
+noinst_LIBRARIES = libappconfig.a
+
+libappconfig_a_sources = \
+ config-enums.h \
+ config-types.h \
+ gimpconfig-dump.c \
+ gimpconfig-dump.h \
+ gimpconfig-file.c \
+ gimpconfig-file.h \
+ gimpconfig-utils.c \
+ gimpconfig-utils.h \
+ gimpcoreconfig.c \
+ gimpcoreconfig.h \
+ gimpdialogconfig.c \
+ gimpdialogconfig.h \
+ gimpdisplayconfig.c \
+ gimpdisplayconfig.h \
+ gimpdisplayoptions.c \
+ gimpdisplayoptions.h \
+ gimpgeglconfig.c \
+ gimpgeglconfig.h \
+ gimpguiconfig.c \
+ gimpguiconfig.h \
+ gimplangrc.c \
+ gimplangrc.h \
+ gimppluginconfig.c \
+ gimppluginconfig.h \
+ gimprc.c \
+ gimprc.h \
+ gimprc-blurbs.h \
+ gimprc-deserialize.c \
+ gimprc-deserialize.h \
+ gimprc-serialize.c \
+ gimprc-serialize.h \
+ gimprc-unknown.c \
+ gimprc-unknown.h \
+ gimpxmlparser.c \
+ gimpxmlparser.h
+
+libappconfig_a_built_sources = \
+ config-enums.c
+
+libappconfig_a_SOURCES = \
+ $(libappconfig_a_built_sources) \
+ $(libappconfig_a_sources)
+
+EXTRA_PROGRAMS = test-config
+
+#
+# unit tests for the GimpConfig system
+#
+
+TESTS = test-config
+
+test_config_DEPENDENCIES = $(gimpconfig_libs)
+
+# We need this due to circular dependencies
+test_config_LDFLAGS = \
+ -Wl,-u,$(SYMPREFIX)gimp_vectors_undo_get_type \
+ -Wl,-u,$(SYMPREFIX)gimp_vectors_mod_undo_get_type \
+ -Wl,-u,$(SYMPREFIX)gimp_param_spec_duplicate \
+ -Wl,-u,$(SYMPREFIX)xcf_init \
+ -Wl,-u,$(SYMPREFIX)internal_procs_init \
+ -Wl,-u,$(SYMPREFIX)gimp_plug_in_manager_restore \
+ -Wl,-u,$(SYMPREFIX)gimp_pdb_compat_param_spec \
+ -Wl,-u,$(SYMPREFIX)gimp_layer_mode_is_legacy \
+ -Wl,-u,$(SYMPREFIX)gimp_async_set_new \
+ -Wl,-u,$(SYMPREFIX)gimp_uncancelable_waitable_new
+
+test_config_LDADD = \
+ ../xcf/libappxcf.a \
+ ../pdb/libappinternal-procs.a \
+ ../pdb/libapppdb.a \
+ ../plug-in/libappplug-in.a \
+ ../vectors/libappvectors.a \
+ ../core/libappcore.a \
+ ../file/libappfile.a \
+ ../file-data/libappfile-data.a \
+ ../text/libapptext.a \
+ ../paint/libapppaint.a \
+ ../gegl/libappgegl.a \
+ ../operations/libappoperations.a \
+ ../operations/layer-modes/libapplayermodes.a \
+ ../operations/layer-modes-legacy/libapplayermodeslegacy.a \
+ libappconfig.a \
+ ../gimp-debug.o \
+ ../gimp-log.o \
+ $(libgimpmodule) \
+ $(libgimpcolor) \
+ $(libgimpthumb) \
+ $(libgimpmath) \
+ $(libgimpconfig) \
+ $(libgimpbase) \
+ $(PANGOCAIRO_LIBS) \
+ $(HARFBUZZ_LIBS) \
+ $(GDK_PIXBUF_LIBS) \
+ $(GEGL_LIBS) \
+ $(GIO_LIBS) \
+ $(GEXIV2_LIBS) \
+ $(Z_LIBS) \
+ $(JSON_C_LIBS) \
+ $(LIBMYPAINT_LIBS) \
+ $(libm)
+
+CLEANFILES = $(EXTRA_PROGRAMS) foorc
+
+#
+# rules to generate built sources
+#
+# setup autogeneration dependencies
+gen_sources = xgen-cec
+CLEANFILES += $(gen_sources)
+
+xgen-cec: $(srcdir)/config-enums.h $(GIMP_MKENUMS) Makefile.am
+ $(AM_V_GEN) $(GIMP_MKENUMS) \
+ --fhead "#include \"config.h\"\n#include <gio/gio.h>\n#include \"libgimpbase/gimpbase.h\"\n#include \"config-enums.h\"\n#include\"gimp-intl.h\"" \
+ --fprod "\n/* enumerations from \"@basename@\" */" \
+ --vhead "GType\n@enum_name@_get_type (void)\n{\n static const G@Type@Value values[] =\n {" \
+ --vprod " { @VALUENAME@, \"@VALUENAME@\", \"@valuenick@\" }," \
+ --vtail " { 0, NULL, NULL }\n };\n" \
+ --dhead " static const Gimp@Type@Desc descs[] =\n {" \
+ --dprod " { @VALUENAME@, @valuedesc@, @valuehelp@ },@if ('@valueabbrev@' ne 'NULL')@\n /* Translators: this is an abbreviated version of @valueudesc@.\n Keep it short. */\n { @VALUENAME@, @valueabbrev@, NULL },@endif@" \
+ --dtail " { 0, NULL, NULL }\n };\n\n static GType type = 0;\n\n if (G_UNLIKELY (! type))\n {\n type = g_@type@_register_static (\"@EnumName@\", values);\n gimp_type_set_translation_context (type, \"@enumnick@\");\n gimp_@type@_set_value_descriptions (type, descs);\n }\n\n return type;\n}\n" \
+ $< > $@
+
+# copy the generated enum file back to the source directory only if it's
+# changed; otherwise, only update its timestamp, so that the recipe isn't
+# executed again on the next build, however, allow this to (harmlessly) fail,
+# to support building from a read-only source tree.
+$(srcdir)/config-enums.c: xgen-cec
+ $(AM_V_GEN) if ! cmp -s $< $@; then \
+ cp $< $@; \
+ else \
+ touch $@ 2> /dev/null \
+ || true; \
+ fi
diff --git a/app/config/Makefile.in b/app/config/Makefile.in
new file mode 100644
index 0000000..ab37152
--- /dev/null
+++ b/app/config/Makefile.in
@@ -0,0 +1,1505 @@
+# Makefile.in generated by automake 1.16.3 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994-2020 Free Software Foundation, Inc.
+
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+VPATH = @srcdir@
+am__is_gnu_make = { \
+ if test -z '$(MAKELEVEL)'; then \
+ false; \
+ elif test -n '$(MAKE_HOST)'; then \
+ true; \
+ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
+ true; \
+ else \
+ false; \
+ fi; \
+}
+am__make_running_with_option = \
+ case $${target_option-} in \
+ ?) ;; \
+ *) echo "am__make_running_with_option: internal error: invalid" \
+ "target option '$${target_option-}' specified" >&2; \
+ exit 1;; \
+ esac; \
+ has_opt=no; \
+ sane_makeflags=$$MAKEFLAGS; \
+ if $(am__is_gnu_make); then \
+ sane_makeflags=$$MFLAGS; \
+ else \
+ case $$MAKEFLAGS in \
+ *\\[\ \ ]*) \
+ bs=\\; \
+ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
+ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \
+ esac; \
+ fi; \
+ skip_next=no; \
+ strip_trailopt () \
+ { \
+ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
+ }; \
+ for flg in $$sane_makeflags; do \
+ test $$skip_next = yes && { skip_next=no; continue; }; \
+ case $$flg in \
+ *=*|--*) continue;; \
+ -*I) strip_trailopt 'I'; skip_next=yes;; \
+ -*I?*) strip_trailopt 'I';; \
+ -*O) strip_trailopt 'O'; skip_next=yes;; \
+ -*O?*) strip_trailopt 'O';; \
+ -*l) strip_trailopt 'l'; skip_next=yes;; \
+ -*l?*) strip_trailopt 'l';; \
+ -[dEDm]) skip_next=yes;; \
+ -[JT]) skip_next=yes;; \
+ esac; \
+ case $$flg in \
+ *$$target_option*) has_opt=yes; break;; \
+ esac; \
+ done; \
+ test $$has_opt = yes
+am__make_dryrun = (target_option=n; $(am__make_running_with_option))
+am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+EXTRA_PROGRAMS = test-config$(EXEEXT)
+TESTS = test-config$(EXEEXT)
+subdir = app/config
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \
+ $(top_srcdir)/m4macros/alsa.m4 \
+ $(top_srcdir)/m4macros/ax_compare_version.m4 \
+ $(top_srcdir)/m4macros/ax_cxx_compile_stdcxx.m4 \
+ $(top_srcdir)/m4macros/ax_gcc_func_attribute.m4 \
+ $(top_srcdir)/m4macros/ax_prog_cc_for_build.m4 \
+ $(top_srcdir)/m4macros/ax_prog_perl_version.m4 \
+ $(top_srcdir)/m4macros/detectcflags.m4 \
+ $(top_srcdir)/m4macros/pythondev.m4 $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+LIBRARIES = $(noinst_LIBRARIES)
+ARFLAGS = cru
+AM_V_AR = $(am__v_AR_@AM_V@)
+am__v_AR_ = $(am__v_AR_@AM_DEFAULT_V@)
+am__v_AR_0 = @echo " AR " $@;
+am__v_AR_1 =
+libappconfig_a_AR = $(AR) $(ARFLAGS)
+libappconfig_a_LIBADD =
+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) \
+ gimppluginconfig.$(OBJEXT) gimprc.$(OBJEXT) \
+ gimprc-deserialize.$(OBJEXT) gimprc-serialize.$(OBJEXT) \
+ gimprc-unknown.$(OBJEXT) gimpxmlparser.$(OBJEXT)
+am_libappconfig_a_OBJECTS = $(am__objects_1) $(am__objects_2)
+libappconfig_a_OBJECTS = $(am_libappconfig_a_OBJECTS)
+test_config_SOURCES = test-config.c
+test_config_OBJECTS = test-config.$(OBJEXT)
+am__DEPENDENCIES_1 =
+AM_V_lt = $(am__v_lt_@AM_V@)
+am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
+am__v_lt_0 = --silent
+am__v_lt_1 =
+test_config_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(test_config_LDFLAGS) $(LDFLAGS) -o $@
+AM_V_P = $(am__v_P_@AM_V@)
+am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
+am__v_P_0 = false
+am__v_P_1 = :
+AM_V_GEN = $(am__v_GEN_@AM_V@)
+am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
+am__v_GEN_0 = @echo " GEN " $@;
+am__v_GEN_1 =
+AM_V_at = $(am__v_at_@AM_V@)
+am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
+am__v_at_0 = @
+am__v_at_1 =
+DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)
+depcomp = $(SHELL) $(top_srcdir)/depcomp
+am__maybe_remake_depfiles = depfiles
+am__depfiles_remade = ./$(DEPDIR)/config-enums.Po \
+ ./$(DEPDIR)/gimpconfig-dump.Po ./$(DEPDIR)/gimpconfig-file.Po \
+ ./$(DEPDIR)/gimpconfig-utils.Po ./$(DEPDIR)/gimpcoreconfig.Po \
+ ./$(DEPDIR)/gimpdialogconfig.Po \
+ ./$(DEPDIR)/gimpdisplayconfig.Po \
+ ./$(DEPDIR)/gimpdisplayoptions.Po \
+ ./$(DEPDIR)/gimpgeglconfig.Po ./$(DEPDIR)/gimpguiconfig.Po \
+ ./$(DEPDIR)/gimplangrc.Po ./$(DEPDIR)/gimppluginconfig.Po \
+ ./$(DEPDIR)/gimprc-deserialize.Po \
+ ./$(DEPDIR)/gimprc-serialize.Po ./$(DEPDIR)/gimprc-unknown.Po \
+ ./$(DEPDIR)/gimprc.Po ./$(DEPDIR)/gimpxmlparser.Po \
+ ./$(DEPDIR)/test-config.Po
+am__mv = mv -f
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \
+ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
+ $(AM_CFLAGS) $(CFLAGS)
+AM_V_CC = $(am__v_CC_@AM_V@)
+am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@)
+am__v_CC_0 = @echo " CC " $@;
+am__v_CC_1 =
+CCLD = $(CC)
+LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(AM_LDFLAGS) $(LDFLAGS) -o $@
+AM_V_CCLD = $(am__v_CCLD_@AM_V@)
+am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@)
+am__v_CCLD_0 = @echo " CCLD " $@;
+am__v_CCLD_1 =
+SOURCES = $(libappconfig_a_SOURCES) test-config.c
+DIST_SOURCES = $(libappconfig_a_SOURCES) test-config.c
+am__can_run_installinfo = \
+ case $$AM_UPDATE_INFO_DIR in \
+ n|no|NO) false;; \
+ *) (install-info --version) >/dev/null 2>&1;; \
+ esac
+am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
+# Read a list of newline-separated strings from the standard input,
+# and print each of them once, without duplicates. Input order is
+# *not* preserved.
+am__uniquify_input = $(AWK) '\
+ BEGIN { nonempty = 0; } \
+ { items[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in items) print i; }; } \
+'
+# Make sure the list of sources is unique. This is necessary because,
+# e.g., the same source file might be shared among _SOURCES variables
+# for different programs/libraries.
+am__define_uniq_tagged_files = \
+ list='$(am__tagged_files)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | $(am__uniquify_input)`
+ETAGS = etags
+CTAGS = ctags
+am__tty_colors_dummy = \
+ mgn= red= grn= lgn= blu= brg= std=; \
+ am__color_tests=no
+am__tty_colors = { \
+ $(am__tty_colors_dummy); \
+ if test "X$(AM_COLOR_TESTS)" = Xno; then \
+ am__color_tests=no; \
+ elif test "X$(AM_COLOR_TESTS)" = Xalways; then \
+ am__color_tests=yes; \
+ elif test "X$$TERM" != Xdumb && { test -t 1; } 2>/dev/null; then \
+ am__color_tests=yes; \
+ fi; \
+ if test $$am__color_tests = yes; then \
+ red=''; \
+ grn=''; \
+ lgn=''; \
+ blu=''; \
+ mgn=''; \
+ brg=''; \
+ std=''; \
+ fi; \
+}
+am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
+am__vpath_adj = case $$p in \
+ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
+ *) f=$$p;; \
+ esac;
+am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
+am__install_max = 40
+am__nobase_strip_setup = \
+ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
+am__nobase_strip = \
+ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
+am__nobase_list = $(am__nobase_strip_setup); \
+ for p in $$list; do echo "$$p $$p"; done | \
+ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
+ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
+ if (++n[$$2] == $(am__install_max)) \
+ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
+ END { for (dir in files) print dir, files[dir] }'
+am__base_list = \
+ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
+ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
+am__uninstall_files_from_dir = { \
+ test -z "$$files" \
+ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
+ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \
+ $(am__cd) "$$dir" && rm -f $$files; }; \
+ }
+am__recheck_rx = ^[ ]*:recheck:[ ]*
+am__global_test_result_rx = ^[ ]*:global-test-result:[ ]*
+am__copy_in_global_log_rx = ^[ ]*:copy-in-global-log:[ ]*
+# A command that, given a newline-separated list of test names on the
+# standard input, print the name of the tests that are to be re-run
+# upon "make recheck".
+am__list_recheck_tests = $(AWK) '{ \
+ recheck = 1; \
+ while ((rc = (getline line < ($$0 ".trs"))) != 0) \
+ { \
+ if (rc < 0) \
+ { \
+ if ((getline line2 < ($$0 ".log")) < 0) \
+ recheck = 0; \
+ break; \
+ } \
+ else if (line ~ /$(am__recheck_rx)[nN][Oo]/) \
+ { \
+ recheck = 0; \
+ break; \
+ } \
+ else if (line ~ /$(am__recheck_rx)[yY][eE][sS]/) \
+ { \
+ break; \
+ } \
+ }; \
+ if (recheck) \
+ print $$0; \
+ close ($$0 ".trs"); \
+ close ($$0 ".log"); \
+}'
+# A command that, given a newline-separated list of test names on the
+# standard input, create the global log from their .trs and .log files.
+am__create_global_log = $(AWK) ' \
+function fatal(msg) \
+{ \
+ print "fatal: making $@: " msg | "cat >&2"; \
+ exit 1; \
+} \
+function rst_section(header) \
+{ \
+ print header; \
+ len = length(header); \
+ for (i = 1; i <= len; i = i + 1) \
+ printf "="; \
+ printf "\n\n"; \
+} \
+{ \
+ copy_in_global_log = 1; \
+ global_test_result = "RUN"; \
+ while ((rc = (getline line < ($$0 ".trs"))) != 0) \
+ { \
+ if (rc < 0) \
+ fatal("failed to read from " $$0 ".trs"); \
+ if (line ~ /$(am__global_test_result_rx)/) \
+ { \
+ sub("$(am__global_test_result_rx)", "", line); \
+ sub("[ ]*$$", "", line); \
+ global_test_result = line; \
+ } \
+ else if (line ~ /$(am__copy_in_global_log_rx)[nN][oO]/) \
+ copy_in_global_log = 0; \
+ }; \
+ if (copy_in_global_log) \
+ { \
+ rst_section(global_test_result ": " $$0); \
+ while ((rc = (getline line < ($$0 ".log"))) != 0) \
+ { \
+ if (rc < 0) \
+ fatal("failed to read from " $$0 ".log"); \
+ print line; \
+ }; \
+ printf "\n"; \
+ }; \
+ close ($$0 ".trs"); \
+ close ($$0 ".log"); \
+}'
+# Restructured Text title.
+am__rst_title = { sed 's/.*/ & /;h;s/./=/g;p;x;s/ *$$//;p;g' && echo; }
+# Solaris 10 'make', and several other traditional 'make' implementations,
+# pass "-e" to $(SHELL), and POSIX 2008 even requires this. Work around it
+# by disabling -e (using the XSI extension "set +e") if it's set.
+am__sh_e_setup = case $$- in *e*) set +e;; esac
+# Default flags passed to test drivers.
+am__common_driver_flags = \
+ --color-tests "$$am__color_tests" \
+ --enable-hard-errors "$$am__enable_hard_errors" \
+ --expect-failure "$$am__expect_failure"
+# To be inserted before the command running the test. Creates the
+# directory for the log if needed. Stores in $dir the directory
+# containing $f, in $tst the test, in $log the log. Executes the
+# developer- defined test setup AM_TESTS_ENVIRONMENT (if any), and
+# passes TESTS_ENVIRONMENT. Set up options for the wrapper that
+# will run the test scripts (or their associated LOG_COMPILER, if
+# thy have one).
+am__check_pre = \
+$(am__sh_e_setup); \
+$(am__vpath_adj_setup) $(am__vpath_adj) \
+$(am__tty_colors); \
+srcdir=$(srcdir); export srcdir; \
+case "$@" in \
+ */*) am__odir=`echo "./$@" | sed 's|/[^/]*$$||'`;; \
+ *) am__odir=.;; \
+esac; \
+test "x$$am__odir" = x"." || test -d "$$am__odir" \
+ || $(MKDIR_P) "$$am__odir" || exit $$?; \
+if test -f "./$$f"; then dir=./; \
+elif test -f "$$f"; then dir=; \
+else dir="$(srcdir)/"; fi; \
+tst=$$dir$$f; log='$@'; \
+if test -n '$(DISABLE_HARD_ERRORS)'; then \
+ am__enable_hard_errors=no; \
+else \
+ am__enable_hard_errors=yes; \
+fi; \
+case " $(XFAIL_TESTS) " in \
+ *[\ \ ]$$f[\ \ ]* | *[\ \ ]$$dir$$f[\ \ ]*) \
+ am__expect_failure=yes;; \
+ *) \
+ am__expect_failure=no;; \
+esac; \
+$(AM_TESTS_ENVIRONMENT) $(TESTS_ENVIRONMENT)
+# A shell command to get the names of the tests scripts with any registered
+# extension removed (i.e., equivalently, the names of the test logs, with
+# the '.log' extension removed). The result is saved in the shell variable
+# '$bases'. This honors runtime overriding of TESTS and TEST_LOGS. Sadly,
+# we cannot use something simpler, involving e.g., "$(TEST_LOGS:.log=)",
+# since that might cause problem with VPATH rewrites for suffix-less tests.
+# See also 'test-harness-vpath-rewrite.sh' and 'test-trs-basic.sh'.
+am__set_TESTS_bases = \
+ bases='$(TEST_LOGS)'; \
+ bases=`for i in $$bases; do echo $$i; done | sed 's/\.log$$//'`; \
+ bases=`echo $$bases`
+AM_TESTSUITE_SUMMARY_HEADER = ' for $(PACKAGE_STRING)'
+RECHECK_LOGS = $(TEST_LOGS)
+AM_RECURSIVE_TARGETS = check recheck
+TEST_SUITE_LOG = test-suite.log
+TEST_EXTENSIONS = @EXEEXT@ .test
+LOG_DRIVER = $(SHELL) $(top_srcdir)/test-driver
+LOG_COMPILE = $(LOG_COMPILER) $(AM_LOG_FLAGS) $(LOG_FLAGS)
+am__set_b = \
+ case '$@' in \
+ */*) \
+ case '$*' in \
+ */*) b='$*';; \
+ *) b=`echo '$@' | sed 's/\.log$$//'`; \
+ esac;; \
+ *) \
+ b='$*';; \
+ esac
+am__test_logs1 = $(TESTS:=.log)
+am__test_logs2 = $(am__test_logs1:@EXEEXT@.log=.log)
+TEST_LOGS = $(am__test_logs2:.test.log=.log)
+TEST_LOG_DRIVER = $(SHELL) $(top_srcdir)/test-driver
+TEST_LOG_COMPILE = $(TEST_LOG_COMPILER) $(AM_TEST_LOG_FLAGS) \
+ $(TEST_LOG_FLAGS)
+am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp \
+ $(top_srcdir)/test-driver
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+AA_LIBS = @AA_LIBS@
+ACLOCAL = @ACLOCAL@
+ALLOCA = @ALLOCA@
+ALL_LINGUAS = @ALL_LINGUAS@
+ALSA_CFLAGS = @ALSA_CFLAGS@
+ALSA_LIBS = @ALSA_LIBS@
+ALTIVEC_EXTRA_CFLAGS = @ALTIVEC_EXTRA_CFLAGS@
+AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+APPSTREAM_UTIL = @APPSTREAM_UTIL@
+AR = @AR@
+AS = @AS@
+ATK_CFLAGS = @ATK_CFLAGS@
+ATK_LIBS = @ATK_LIBS@
+ATK_REQUIRED_VERSION = @ATK_REQUIRED_VERSION@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+BABL_CFLAGS = @BABL_CFLAGS@
+BABL_LIBS = @BABL_LIBS@
+BABL_REQUIRED_VERSION = @BABL_REQUIRED_VERSION@
+BUG_REPORT_URL = @BUG_REPORT_URL@
+BUILD_EXEEXT = @BUILD_EXEEXT@
+BUILD_OBJEXT = @BUILD_OBJEXT@
+BZIP2_LIBS = @BZIP2_LIBS@
+CAIRO_CFLAGS = @CAIRO_CFLAGS@
+CAIRO_LIBS = @CAIRO_LIBS@
+CAIRO_PDF_CFLAGS = @CAIRO_PDF_CFLAGS@
+CAIRO_PDF_LIBS = @CAIRO_PDF_LIBS@
+CAIRO_PDF_REQUIRED_VERSION = @CAIRO_PDF_REQUIRED_VERSION@
+CAIRO_REQUIRED_VERSION = @CAIRO_REQUIRED_VERSION@
+CATALOGS = @CATALOGS@
+CATOBJEXT = @CATOBJEXT@
+CC = @CC@
+CCAS = @CCAS@
+CCASDEPMODE = @CCASDEPMODE@
+CCASFLAGS = @CCASFLAGS@
+CCDEPMODE = @CCDEPMODE@
+CC_FOR_BUILD = @CC_FOR_BUILD@
+CC_VERSION = @CC_VERSION@
+CFLAGS = @CFLAGS@
+CFLAGS_FOR_BUILD = @CFLAGS_FOR_BUILD@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CPPFLAGS_FOR_BUILD = @CPPFLAGS_FOR_BUILD@
+CPP_FOR_BUILD = @CPP_FOR_BUILD@
+CXX = @CXX@
+CXXCPP = @CXXCPP@
+CXXDEPMODE = @CXXDEPMODE@
+CXXFLAGS = @CXXFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DATADIRNAME = @DATADIRNAME@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DESKTOP_DATADIR = @DESKTOP_DATADIR@
+DESKTOP_FILE_VALIDATE = @DESKTOP_FILE_VALIDATE@
+DLLTOOL = @DLLTOOL@
+DOC_SHOOTER = @DOC_SHOOTER@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+FGREP = @FGREP@
+FILE_AA = @FILE_AA@
+FILE_EXR = @FILE_EXR@
+FILE_HEIF = @FILE_HEIF@
+FILE_JP2_LOAD = @FILE_JP2_LOAD@
+FILE_JPEGXL = @FILE_JPEGXL@
+FILE_MNG = @FILE_MNG@
+FILE_PDF_SAVE = @FILE_PDF_SAVE@
+FILE_PS = @FILE_PS@
+FILE_WMF = @FILE_WMF@
+FILE_XMC = @FILE_XMC@
+FILE_XPM = @FILE_XPM@
+FONTCONFIG_CFLAGS = @FONTCONFIG_CFLAGS@
+FONTCONFIG_LIBS = @FONTCONFIG_LIBS@
+FONTCONFIG_REQUIRED_VERSION = @FONTCONFIG_REQUIRED_VERSION@
+FREETYPE2_REQUIRED_VERSION = @FREETYPE2_REQUIRED_VERSION@
+FREETYPE_CFLAGS = @FREETYPE_CFLAGS@
+FREETYPE_LIBS = @FREETYPE_LIBS@
+GDBUS_CODEGEN = @GDBUS_CODEGEN@
+GDK_PIXBUF_CFLAGS = @GDK_PIXBUF_CFLAGS@
+GDK_PIXBUF_CSOURCE = @GDK_PIXBUF_CSOURCE@
+GDK_PIXBUF_LIBS = @GDK_PIXBUF_LIBS@
+GDK_PIXBUF_REQUIRED_VERSION = @GDK_PIXBUF_REQUIRED_VERSION@
+GEGL = @GEGL@
+GEGL_CFLAGS = @GEGL_CFLAGS@
+GEGL_LIBS = @GEGL_LIBS@
+GEGL_MAJOR_MINOR_VERSION = @GEGL_MAJOR_MINOR_VERSION@
+GEGL_REQUIRED_VERSION = @GEGL_REQUIRED_VERSION@
+GETTEXT_PACKAGE = @GETTEXT_PACKAGE@
+GEXIV2_CFLAGS = @GEXIV2_CFLAGS@
+GEXIV2_LIBS = @GEXIV2_LIBS@
+GEXIV2_REQUIRED_VERSION = @GEXIV2_REQUIRED_VERSION@
+GIMP_API_VERSION = @GIMP_API_VERSION@
+GIMP_APP_VERSION = @GIMP_APP_VERSION@
+GIMP_BINARY_AGE = @GIMP_BINARY_AGE@
+GIMP_COMMAND = @GIMP_COMMAND@
+GIMP_DATA_VERSION = @GIMP_DATA_VERSION@
+GIMP_FULL_NAME = @GIMP_FULL_NAME@
+GIMP_INTERFACE_AGE = @GIMP_INTERFACE_AGE@
+GIMP_MAJOR_VERSION = @GIMP_MAJOR_VERSION@
+GIMP_MICRO_VERSION = @GIMP_MICRO_VERSION@
+GIMP_MINOR_VERSION = @GIMP_MINOR_VERSION@
+GIMP_MKENUMS = @GIMP_MKENUMS@
+GIMP_MODULES = @GIMP_MODULES@
+GIMP_PACKAGE_REVISION = @GIMP_PACKAGE_REVISION@
+GIMP_PKGCONFIG_VERSION = @GIMP_PKGCONFIG_VERSION@
+GIMP_PLUGINS = @GIMP_PLUGINS@
+GIMP_PLUGIN_VERSION = @GIMP_PLUGIN_VERSION@
+GIMP_REAL_VERSION = @GIMP_REAL_VERSION@
+GIMP_RELEASE = @GIMP_RELEASE@
+GIMP_SYSCONF_VERSION = @GIMP_SYSCONF_VERSION@
+GIMP_TOOL_VERSION = @GIMP_TOOL_VERSION@
+GIMP_UNSTABLE = @GIMP_UNSTABLE@
+GIMP_USER_VERSION = @GIMP_USER_VERSION@
+GIMP_VERSION = @GIMP_VERSION@
+GIO_CFLAGS = @GIO_CFLAGS@
+GIO_LIBS = @GIO_LIBS@
+GIO_UNIX_CFLAGS = @GIO_UNIX_CFLAGS@
+GIO_UNIX_LIBS = @GIO_UNIX_LIBS@
+GIO_WINDOWS_CFLAGS = @GIO_WINDOWS_CFLAGS@
+GIO_WINDOWS_LIBS = @GIO_WINDOWS_LIBS@
+GLIB_CFLAGS = @GLIB_CFLAGS@
+GLIB_COMPILE_RESOURCES = @GLIB_COMPILE_RESOURCES@
+GLIB_GENMARSHAL = @GLIB_GENMARSHAL@
+GLIB_LIBS = @GLIB_LIBS@
+GLIB_MKENUMS = @GLIB_MKENUMS@
+GLIB_REQUIRED_VERSION = @GLIB_REQUIRED_VERSION@
+GMODULE_NO_EXPORT_CFLAGS = @GMODULE_NO_EXPORT_CFLAGS@
+GMODULE_NO_EXPORT_LIBS = @GMODULE_NO_EXPORT_LIBS@
+GMOFILES = @GMOFILES@
+GMSGFMT = @GMSGFMT@
+GOBJECT_QUERY = @GOBJECT_QUERY@
+GREP = @GREP@
+GS_LIBS = @GS_LIBS@
+GTKDOC_CHECK = @GTKDOC_CHECK@
+GTKDOC_CHECK_PATH = @GTKDOC_CHECK_PATH@
+GTKDOC_DEPS_CFLAGS = @GTKDOC_DEPS_CFLAGS@
+GTKDOC_DEPS_LIBS = @GTKDOC_DEPS_LIBS@
+GTKDOC_MKPDF = @GTKDOC_MKPDF@
+GTKDOC_REBASE = @GTKDOC_REBASE@
+GTK_CFLAGS = @GTK_CFLAGS@
+GTK_LIBS = @GTK_LIBS@
+GTK_MAC_INTEGRATION_CFLAGS = @GTK_MAC_INTEGRATION_CFLAGS@
+GTK_MAC_INTEGRATION_LIBS = @GTK_MAC_INTEGRATION_LIBS@
+GTK_REQUIRED_VERSION = @GTK_REQUIRED_VERSION@
+GTK_UPDATE_ICON_CACHE = @GTK_UPDATE_ICON_CACHE@
+GUDEV_CFLAGS = @GUDEV_CFLAGS@
+GUDEV_LIBS = @GUDEV_LIBS@
+HARFBUZZ_CFLAGS = @HARFBUZZ_CFLAGS@
+HARFBUZZ_LIBS = @HARFBUZZ_LIBS@
+HARFBUZZ_REQUIRED_VERSION = @HARFBUZZ_REQUIRED_VERSION@
+HAVE_CXX14 = @HAVE_CXX14@
+HAVE_FINITE = @HAVE_FINITE@
+HAVE_ISFINITE = @HAVE_ISFINITE@
+HAVE_VFORK = @HAVE_VFORK@
+HOST_GLIB_COMPILE_RESOURCES = @HOST_GLIB_COMPILE_RESOURCES@
+HTML_DIR = @HTML_DIR@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+INSTOBJEXT = @INSTOBJEXT@
+INTLLIBS = @INTLLIBS@
+INTLTOOL_EXTRACT = @INTLTOOL_EXTRACT@
+INTLTOOL_MERGE = @INTLTOOL_MERGE@
+INTLTOOL_PERL = @INTLTOOL_PERL@
+INTLTOOL_REQUIRED_VERSION = @INTLTOOL_REQUIRED_VERSION@
+INTLTOOL_UPDATE = @INTLTOOL_UPDATE@
+INTLTOOL_V_MERGE = @INTLTOOL_V_MERGE@
+INTLTOOL_V_MERGE_OPTIONS = @INTLTOOL_V_MERGE_OPTIONS@
+INTLTOOL__v_MERGE_ = @INTLTOOL__v_MERGE_@
+INTLTOOL__v_MERGE_0 = @INTLTOOL__v_MERGE_0@
+INTL_MACOSX_LIBS = @INTL_MACOSX_LIBS@
+ISO_CODES_LOCALEDIR = @ISO_CODES_LOCALEDIR@
+ISO_CODES_LOCATION = @ISO_CODES_LOCATION@
+JPEG_LIBS = @JPEG_LIBS@
+JSON_GLIB_CFLAGS = @JSON_GLIB_CFLAGS@
+JSON_GLIB_LIBS = @JSON_GLIB_LIBS@
+JXL_CFLAGS = @JXL_CFLAGS@
+JXL_LIBS = @JXL_LIBS@
+JXL_THREADS_CFLAGS = @JXL_THREADS_CFLAGS@
+JXL_THREADS_LIBS = @JXL_THREADS_LIBS@
+LCMS_CFLAGS = @LCMS_CFLAGS@
+LCMS_LIBS = @LCMS_LIBS@
+LCMS_REQUIRED_VERSION = @LCMS_REQUIRED_VERSION@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LDFLAGS_FOR_BUILD = @LDFLAGS_FOR_BUILD@
+LIBBACKTRACE_LIBS = @LIBBACKTRACE_LIBS@
+LIBHEIF_CFLAGS = @LIBHEIF_CFLAGS@
+LIBHEIF_LIBS = @LIBHEIF_LIBS@
+LIBHEIF_REQUIRED_VERSION = @LIBHEIF_REQUIRED_VERSION@
+LIBJXL_REQUIRED_VERSION = @LIBJXL_REQUIRED_VERSION@
+LIBLZMA_REQUIRED_VERSION = @LIBLZMA_REQUIRED_VERSION@
+LIBMYPAINT_CFLAGS = @LIBMYPAINT_CFLAGS@
+LIBMYPAINT_LIBS = @LIBMYPAINT_LIBS@
+LIBMYPAINT_REQUIRED_VERSION = @LIBMYPAINT_REQUIRED_VERSION@
+LIBOBJS = @LIBOBJS@
+LIBPNG_REQUIRED_VERSION = @LIBPNG_REQUIRED_VERSION@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LIBUNWIND_CFLAGS = @LIBUNWIND_CFLAGS@
+LIBUNWIND_LIBS = @LIBUNWIND_LIBS@
+LIBUNWIND_REQUIRED_VERSION = @LIBUNWIND_REQUIRED_VERSION@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+LT_CURRENT_MINUS_AGE = @LT_CURRENT_MINUS_AGE@
+LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@
+LT_VERSION_INFO = @LT_VERSION_INFO@
+LZMA_CFLAGS = @LZMA_CFLAGS@
+LZMA_LIBS = @LZMA_LIBS@
+MAIL = @MAIL@
+MAINT = @MAINT@
+MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
+MIME_INFO_CFLAGS = @MIME_INFO_CFLAGS@
+MIME_INFO_LIBS = @MIME_INFO_LIBS@
+MIME_TYPES = @MIME_TYPES@
+MKDIR_P = @MKDIR_P@
+MKINSTALLDIRS = @MKINSTALLDIRS@
+MMX_EXTRA_CFLAGS = @MMX_EXTRA_CFLAGS@
+MNG_CFLAGS = @MNG_CFLAGS@
+MNG_LIBS = @MNG_LIBS@
+MSGFMT = @MSGFMT@
+MSGFMT_OPTS = @MSGFMT_OPTS@
+MSGMERGE = @MSGMERGE@
+MYPAINT_BRUSHES_CFLAGS = @MYPAINT_BRUSHES_CFLAGS@
+MYPAINT_BRUSHES_LIBS = @MYPAINT_BRUSHES_LIBS@
+NATIVE_GLIB_CFLAGS = @NATIVE_GLIB_CFLAGS@
+NATIVE_GLIB_LIBS = @NATIVE_GLIB_LIBS@
+NM = @NM@
+NMEDIT = @NMEDIT@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OPENEXR_CFLAGS = @OPENEXR_CFLAGS@
+OPENEXR_LIBS = @OPENEXR_LIBS@
+OPENEXR_REQUIRED_VERSION = @OPENEXR_REQUIRED_VERSION@
+OPENJPEG_CFLAGS = @OPENJPEG_CFLAGS@
+OPENJPEG_LIBS = @OPENJPEG_LIBS@
+OPENJPEG_REQUIRED_VERSION = @OPENJPEG_REQUIRED_VERSION@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PANGOCAIRO_CFLAGS = @PANGOCAIRO_CFLAGS@
+PANGOCAIRO_LIBS = @PANGOCAIRO_LIBS@
+PANGOCAIRO_REQUIRED_VERSION = @PANGOCAIRO_REQUIRED_VERSION@
+PATHSEP = @PATHSEP@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PERL = @PERL@
+PERL_REQUIRED_VERSION = @PERL_REQUIRED_VERSION@
+PERL_VERSION = @PERL_VERSION@
+PKG_CONFIG = @PKG_CONFIG@
+PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
+PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
+PNG_CFLAGS = @PNG_CFLAGS@
+PNG_LIBS = @PNG_LIBS@
+POFILES = @POFILES@
+POPPLER_CFLAGS = @POPPLER_CFLAGS@
+POPPLER_DATA_CFLAGS = @POPPLER_DATA_CFLAGS@
+POPPLER_DATA_LIBS = @POPPLER_DATA_LIBS@
+POPPLER_DATA_REQUIRED_VERSION = @POPPLER_DATA_REQUIRED_VERSION@
+POPPLER_LIBS = @POPPLER_LIBS@
+POPPLER_REQUIRED_VERSION = @POPPLER_REQUIRED_VERSION@
+POSUB = @POSUB@
+PO_IN_DATADIR_FALSE = @PO_IN_DATADIR_FALSE@
+PO_IN_DATADIR_TRUE = @PO_IN_DATADIR_TRUE@
+PYBIN_PATH = @PYBIN_PATH@
+PYCAIRO_CFLAGS = @PYCAIRO_CFLAGS@
+PYCAIRO_LIBS = @PYCAIRO_LIBS@
+PYGIMP_EXTRA_CFLAGS = @PYGIMP_EXTRA_CFLAGS@
+PYGTK_CFLAGS = @PYGTK_CFLAGS@
+PYGTK_CODEGEN = @PYGTK_CODEGEN@
+PYGTK_DEFSDIR = @PYGTK_DEFSDIR@
+PYGTK_LIBS = @PYGTK_LIBS@
+PYLINK_LIBS = @PYLINK_LIBS@
+PYTHON = @PYTHON@
+PYTHON2_REQUIRED_VERSION = @PYTHON2_REQUIRED_VERSION@
+PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
+PYTHON_INCLUDES = @PYTHON_INCLUDES@
+PYTHON_PLATFORM = @PYTHON_PLATFORM@
+PYTHON_PREFIX = @PYTHON_PREFIX@
+PYTHON_VERSION = @PYTHON_VERSION@
+RANLIB = @RANLIB@
+RSVG_REQUIRED_VERSION = @RSVG_REQUIRED_VERSION@
+RT_LIBS = @RT_LIBS@
+SCREENSHOT_LIBS = @SCREENSHOT_LIBS@
+SED = @SED@
+SENDMAIL = @SENDMAIL@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+SOCKET_LIBS = @SOCKET_LIBS@
+SSE2_EXTRA_CFLAGS = @SSE2_EXTRA_CFLAGS@
+SSE4_1_EXTRA_CFLAGS = @SSE4_1_EXTRA_CFLAGS@
+SSE_EXTRA_CFLAGS = @SSE_EXTRA_CFLAGS@
+STRIP = @STRIP@
+SVG_CFLAGS = @SVG_CFLAGS@
+SVG_LIBS = @SVG_LIBS@
+SYMPREFIX = @SYMPREFIX@
+TIFF_LIBS = @TIFF_LIBS@
+USE_NLS = @USE_NLS@
+VERSION = @VERSION@
+WEBKIT_CFLAGS = @WEBKIT_CFLAGS@
+WEBKIT_LIBS = @WEBKIT_LIBS@
+WEBKIT_REQUIRED_VERSION = @WEBKIT_REQUIRED_VERSION@
+WEBPDEMUX_CFLAGS = @WEBPDEMUX_CFLAGS@
+WEBPDEMUX_LIBS = @WEBPDEMUX_LIBS@
+WEBPMUX_CFLAGS = @WEBPMUX_CFLAGS@
+WEBPMUX_LIBS = @WEBPMUX_LIBS@
+WEBP_CFLAGS = @WEBP_CFLAGS@
+WEBP_LIBS = @WEBP_LIBS@
+WEBP_REQUIRED_VERSION = @WEBP_REQUIRED_VERSION@
+WEB_PAGE = @WEB_PAGE@
+WIN32_LARGE_ADDRESS_AWARE = @WIN32_LARGE_ADDRESS_AWARE@
+WINDRES = @WINDRES@
+WMF_CFLAGS = @WMF_CFLAGS@
+WMF_CONFIG = @WMF_CONFIG@
+WMF_LIBS = @WMF_LIBS@
+WMF_REQUIRED_VERSION = @WMF_REQUIRED_VERSION@
+XDG_EMAIL = @XDG_EMAIL@
+XFIXES_CFLAGS = @XFIXES_CFLAGS@
+XFIXES_LIBS = @XFIXES_LIBS@
+XGETTEXT = @XGETTEXT@
+XGETTEXT_REQUIRED_VERSION = @XGETTEXT_REQUIRED_VERSION@
+XMC_CFLAGS = @XMC_CFLAGS@
+XMC_LIBS = @XMC_LIBS@
+XMKMF = @XMKMF@
+XMLLINT = @XMLLINT@
+XMU_LIBS = @XMU_LIBS@
+XPM_LIBS = @XPM_LIBS@
+XSLTPROC = @XSLTPROC@
+XVFB_RUN = @XVFB_RUN@
+X_CFLAGS = @X_CFLAGS@
+X_EXTRA_LIBS = @X_EXTRA_LIBS@
+X_LIBS = @X_LIBS@
+X_PRE_LIBS = @X_PRE_LIBS@
+Z_LIBS = @Z_LIBS@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_CC_FOR_BUILD = @ac_ct_CC_FOR_BUILD@
+ac_ct_CXX = @ac_ct_CXX@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+gimpdatadir = @gimpdatadir@
+gimpdir = @gimpdir@
+gimplocaledir = @gimplocaledir@
+gimpplugindir = @gimpplugindir@
+gimpsysconfdir = @gimpsysconfdir@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+intltool__v_merge_options_ = @intltool__v_merge_options_@
+intltool__v_merge_options_0 = @intltool__v_merge_options_0@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+manpage_gimpdir = @manpage_gimpdir@
+mkdir_p = @mkdir_p@
+ms_librarian = @ms_librarian@
+mypaint_brushes_dir = @mypaint_brushes_dir@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+pkgpyexecdir = @pkgpyexecdir@
+pkgpythondir = @pkgpythondir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+pyexecdir = @pyexecdir@
+pythondir = @pythondir@
+runstatedir = @runstatedir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+libgimpbase = $(top_builddir)/libgimpbase/libgimpbase-$(GIMP_API_VERSION).la
+libgimpconfig = $(top_builddir)/libgimpconfig/libgimpconfig-$(GIMP_API_VERSION).la
+libgimpcolor = $(top_builddir)/libgimpcolor/libgimpcolor-$(GIMP_API_VERSION).la
+libgimpmath = $(top_builddir)/libgimpmath/libgimpmath-$(GIMP_API_VERSION).la
+libgimpmodule = $(top_builddir)/libgimpmodule/libgimpmodule-$(GIMP_API_VERSION).la
+libgimpthumb = $(top_builddir)/libgimpthumb/libgimpthumb-$(GIMP_API_VERSION).la
+@OS_WIN32_FALSE@libm = -lm
+AM_CPPFLAGS = \
+ -DG_LOG_DOMAIN=\"Gimp-Config\" \
+ -DGIMP_APP_VERSION_STRING=\"$(GIMP_APP_VERSION)\" \
+ -I$(top_builddir) \
+ -I$(top_srcdir) \
+ -I$(top_builddir)/app \
+ -I$(top_srcdir)/app \
+ $(GIO_UNIX_CFLAGS) \
+ $(GIO_WINDOWS_CFLAGS) \
+ $(GEGL_CFLAGS) \
+ $(CAIRO_CFLAGS) \
+ $(GDK_PIXBUF_CFLAGS) \
+ $(MYPAINT_BRUSHES_CFLAGS) \
+ -I$(includedir)
+
+noinst_LIBRARIES = libappconfig.a
+libappconfig_a_sources = \
+ config-enums.h \
+ config-types.h \
+ gimpconfig-dump.c \
+ gimpconfig-dump.h \
+ gimpconfig-file.c \
+ gimpconfig-file.h \
+ gimpconfig-utils.c \
+ gimpconfig-utils.h \
+ gimpcoreconfig.c \
+ gimpcoreconfig.h \
+ gimpdialogconfig.c \
+ gimpdialogconfig.h \
+ gimpdisplayconfig.c \
+ gimpdisplayconfig.h \
+ gimpdisplayoptions.c \
+ gimpdisplayoptions.h \
+ gimpgeglconfig.c \
+ gimpgeglconfig.h \
+ gimpguiconfig.c \
+ gimpguiconfig.h \
+ gimplangrc.c \
+ gimplangrc.h \
+ gimppluginconfig.c \
+ gimppluginconfig.h \
+ gimprc.c \
+ gimprc.h \
+ gimprc-blurbs.h \
+ gimprc-deserialize.c \
+ gimprc-deserialize.h \
+ gimprc-serialize.c \
+ gimprc-serialize.h \
+ gimprc-unknown.c \
+ gimprc-unknown.h \
+ gimpxmlparser.c \
+ gimpxmlparser.h
+
+libappconfig_a_built_sources = \
+ config-enums.c
+
+libappconfig_a_SOURCES = \
+ $(libappconfig_a_built_sources) \
+ $(libappconfig_a_sources)
+
+test_config_DEPENDENCIES = $(gimpconfig_libs)
+
+# We need this due to circular dependencies
+test_config_LDFLAGS = \
+ -Wl,-u,$(SYMPREFIX)gimp_vectors_undo_get_type \
+ -Wl,-u,$(SYMPREFIX)gimp_vectors_mod_undo_get_type \
+ -Wl,-u,$(SYMPREFIX)gimp_param_spec_duplicate \
+ -Wl,-u,$(SYMPREFIX)xcf_init \
+ -Wl,-u,$(SYMPREFIX)internal_procs_init \
+ -Wl,-u,$(SYMPREFIX)gimp_plug_in_manager_restore \
+ -Wl,-u,$(SYMPREFIX)gimp_pdb_compat_param_spec \
+ -Wl,-u,$(SYMPREFIX)gimp_layer_mode_is_legacy \
+ -Wl,-u,$(SYMPREFIX)gimp_async_set_new \
+ -Wl,-u,$(SYMPREFIX)gimp_uncancelable_waitable_new
+
+test_config_LDADD = \
+ ../xcf/libappxcf.a \
+ ../pdb/libappinternal-procs.a \
+ ../pdb/libapppdb.a \
+ ../plug-in/libappplug-in.a \
+ ../vectors/libappvectors.a \
+ ../core/libappcore.a \
+ ../file/libappfile.a \
+ ../file-data/libappfile-data.a \
+ ../text/libapptext.a \
+ ../paint/libapppaint.a \
+ ../gegl/libappgegl.a \
+ ../operations/libappoperations.a \
+ ../operations/layer-modes/libapplayermodes.a \
+ ../operations/layer-modes-legacy/libapplayermodeslegacy.a \
+ libappconfig.a \
+ ../gimp-debug.o \
+ ../gimp-log.o \
+ $(libgimpmodule) \
+ $(libgimpcolor) \
+ $(libgimpthumb) \
+ $(libgimpmath) \
+ $(libgimpconfig) \
+ $(libgimpbase) \
+ $(PANGOCAIRO_LIBS) \
+ $(HARFBUZZ_LIBS) \
+ $(GDK_PIXBUF_LIBS) \
+ $(GEGL_LIBS) \
+ $(GIO_LIBS) \
+ $(GEXIV2_LIBS) \
+ $(Z_LIBS) \
+ $(JSON_C_LIBS) \
+ $(LIBMYPAINT_LIBS) \
+ $(libm)
+
+CLEANFILES = $(EXTRA_PROGRAMS) foorc $(gen_sources)
+
+#
+# rules to generate built sources
+#
+# setup autogeneration dependencies
+gen_sources = xgen-cec
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .lo .log .o .obj .test .test$(EXEEXT) .trs
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+ && { if test -f $@; then exit 0; else break; fi; }; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu app/config/Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --gnu app/config/Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+
+clean-noinstLIBRARIES:
+ -test -z "$(noinst_LIBRARIES)" || rm -f $(noinst_LIBRARIES)
+
+libappconfig.a: $(libappconfig_a_OBJECTS) $(libappconfig_a_DEPENDENCIES) $(EXTRA_libappconfig_a_DEPENDENCIES)
+ $(AM_V_at)-rm -f libappconfig.a
+ $(AM_V_AR)$(libappconfig_a_AR) libappconfig.a $(libappconfig_a_OBJECTS) $(libappconfig_a_LIBADD)
+ $(AM_V_at)$(RANLIB) libappconfig.a
+
+test-config$(EXEEXT): $(test_config_OBJECTS) $(test_config_DEPENDENCIES) $(EXTRA_test_config_DEPENDENCIES)
+ @rm -f test-config$(EXEEXT)
+ $(AM_V_CCLD)$(test_config_LINK) $(test_config_OBJECTS) $(test_config_LDADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/config-enums.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gimpconfig-dump.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gimpconfig-file.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gimpconfig-utils.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gimpcoreconfig.Po@am__quote@ # am--include-marker
+@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)/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
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gimprc-unknown.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gimprc.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gimpxmlparser.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-config.Po@am__quote@ # am--include-marker
+
+$(am__depfiles_remade):
+ @$(MKDIR_P) $(@D)
+ @echo '# dummy' >$@-t && $(am__mv) $@-t $@
+
+am--depfiles: $(am__depfiles_remade)
+
+.c.o:
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $<
+
+.c.obj:
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
+
+.c.lo:
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $<
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+
+ID: $(am__tagged_files)
+ $(am__define_uniq_tagged_files); mkid -fID $$unique
+tags: tags-am
+TAGS: tags
+
+tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+ set x; \
+ here=`pwd`; \
+ $(am__define_uniq_tagged_files); \
+ shift; \
+ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
+ test -n "$$unique" || unique=$$empty_fix; \
+ if test $$# -gt 0; then \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ "$$@" $$unique; \
+ else \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$unique; \
+ fi; \
+ fi
+ctags: ctags-am
+
+CTAGS: ctags
+ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+ $(am__define_uniq_tagged_files); \
+ test -z "$(CTAGS_ARGS)$$unique" \
+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+ $$unique
+
+GTAGS:
+ here=`$(am__cd) $(top_builddir) && pwd` \
+ && $(am__cd) $(top_srcdir) \
+ && gtags -i $(GTAGS_ARGS) "$$here"
+cscopelist: cscopelist-am
+
+cscopelist-am: $(am__tagged_files)
+ list='$(am__tagged_files)'; \
+ case "$(srcdir)" in \
+ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
+ *) sdir=$(subdir)/$(srcdir) ;; \
+ esac; \
+ for i in $$list; do \
+ if test -f "$$i"; then \
+ echo "$(subdir)/$$i"; \
+ else \
+ echo "$$sdir/$$i"; \
+ fi; \
+ done >> $(top_builddir)/cscope.files
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+# Recover from deleted '.trs' file; this should ensure that
+# "rm -f foo.log; make foo.trs" re-run 'foo.test', and re-create
+# both 'foo.log' and 'foo.trs'. Break the recipe in two subshells
+# to avoid problems with "make -n".
+.log.trs:
+ rm -f $< $@
+ $(MAKE) $(AM_MAKEFLAGS) $<
+
+# Leading 'am--fnord' is there to ensure the list of targets does not
+# expand to empty, as could happen e.g. with make check TESTS=''.
+am--fnord $(TEST_LOGS) $(TEST_LOGS:.log=.trs): $(am__force_recheck)
+am--force-recheck:
+ @:
+
+$(TEST_SUITE_LOG): $(TEST_LOGS)
+ @$(am__set_TESTS_bases); \
+ am__f_ok () { test -f "$$1" && test -r "$$1"; }; \
+ redo_bases=`for i in $$bases; do \
+ am__f_ok $$i.trs && am__f_ok $$i.log || echo $$i; \
+ done`; \
+ if test -n "$$redo_bases"; then \
+ redo_logs=`for i in $$redo_bases; do echo $$i.log; done`; \
+ redo_results=`for i in $$redo_bases; do echo $$i.trs; done`; \
+ if $(am__make_dryrun); then :; else \
+ rm -f $$redo_logs && rm -f $$redo_results || exit 1; \
+ fi; \
+ fi; \
+ if test -n "$$am__remaking_logs"; then \
+ echo "fatal: making $(TEST_SUITE_LOG): possible infinite" \
+ "recursion detected" >&2; \
+ elif test -n "$$redo_logs"; then \
+ am__remaking_logs=yes $(MAKE) $(AM_MAKEFLAGS) $$redo_logs; \
+ fi; \
+ if $(am__make_dryrun); then :; else \
+ st=0; \
+ errmsg="fatal: making $(TEST_SUITE_LOG): failed to create"; \
+ for i in $$redo_bases; do \
+ test -f $$i.trs && test -r $$i.trs \
+ || { echo "$$errmsg $$i.trs" >&2; st=1; }; \
+ test -f $$i.log && test -r $$i.log \
+ || { echo "$$errmsg $$i.log" >&2; st=1; }; \
+ done; \
+ test $$st -eq 0 || exit 1; \
+ fi
+ @$(am__sh_e_setup); $(am__tty_colors); $(am__set_TESTS_bases); \
+ ws='[ ]'; \
+ results=`for b in $$bases; do echo $$b.trs; done`; \
+ test -n "$$results" || results=/dev/null; \
+ all=` grep "^$$ws*:test-result:" $$results | wc -l`; \
+ pass=` grep "^$$ws*:test-result:$$ws*PASS" $$results | wc -l`; \
+ fail=` grep "^$$ws*:test-result:$$ws*FAIL" $$results | wc -l`; \
+ skip=` grep "^$$ws*:test-result:$$ws*SKIP" $$results | wc -l`; \
+ xfail=`grep "^$$ws*:test-result:$$ws*XFAIL" $$results | wc -l`; \
+ xpass=`grep "^$$ws*:test-result:$$ws*XPASS" $$results | wc -l`; \
+ error=`grep "^$$ws*:test-result:$$ws*ERROR" $$results | wc -l`; \
+ if test `expr $$fail + $$xpass + $$error` -eq 0; then \
+ success=true; \
+ else \
+ success=false; \
+ fi; \
+ br='==================='; br=$$br$$br$$br$$br; \
+ result_count () \
+ { \
+ if test x"$$1" = x"--maybe-color"; then \
+ maybe_colorize=yes; \
+ elif test x"$$1" = x"--no-color"; then \
+ maybe_colorize=no; \
+ else \
+ echo "$@: invalid 'result_count' usage" >&2; exit 4; \
+ fi; \
+ shift; \
+ desc=$$1 count=$$2; \
+ if test $$maybe_colorize = yes && test $$count -gt 0; then \
+ color_start=$$3 color_end=$$std; \
+ else \
+ color_start= color_end=; \
+ fi; \
+ echo "$${color_start}# $$desc $$count$${color_end}"; \
+ }; \
+ create_testsuite_report () \
+ { \
+ result_count $$1 "TOTAL:" $$all "$$brg"; \
+ result_count $$1 "PASS: " $$pass "$$grn"; \
+ result_count $$1 "SKIP: " $$skip "$$blu"; \
+ result_count $$1 "XFAIL:" $$xfail "$$lgn"; \
+ result_count $$1 "FAIL: " $$fail "$$red"; \
+ result_count $$1 "XPASS:" $$xpass "$$red"; \
+ result_count $$1 "ERROR:" $$error "$$mgn"; \
+ }; \
+ { \
+ echo "$(PACKAGE_STRING): $(subdir)/$(TEST_SUITE_LOG)" | \
+ $(am__rst_title); \
+ create_testsuite_report --no-color; \
+ echo; \
+ echo ".. contents:: :depth: 2"; \
+ echo; \
+ for b in $$bases; do echo $$b; done \
+ | $(am__create_global_log); \
+ } >$(TEST_SUITE_LOG).tmp || exit 1; \
+ mv $(TEST_SUITE_LOG).tmp $(TEST_SUITE_LOG); \
+ if $$success; then \
+ col="$$grn"; \
+ else \
+ col="$$red"; \
+ test x"$$VERBOSE" = x || cat $(TEST_SUITE_LOG); \
+ fi; \
+ echo "$${col}$$br$${std}"; \
+ echo "$${col}Testsuite summary"$(AM_TESTSUITE_SUMMARY_HEADER)"$${std}"; \
+ echo "$${col}$$br$${std}"; \
+ create_testsuite_report --maybe-color; \
+ echo "$$col$$br$$std"; \
+ if $$success; then :; else \
+ echo "$${col}See $(subdir)/$(TEST_SUITE_LOG)$${std}"; \
+ if test -n "$(PACKAGE_BUGREPORT)"; then \
+ echo "$${col}Please report to $(PACKAGE_BUGREPORT)$${std}"; \
+ fi; \
+ echo "$$col$$br$$std"; \
+ fi; \
+ $$success || exit 1
+
+check-TESTS:
+ @list='$(RECHECK_LOGS)'; test -z "$$list" || rm -f $$list
+ @list='$(RECHECK_LOGS:.log=.trs)'; test -z "$$list" || rm -f $$list
+ @test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG)
+ @set +e; $(am__set_TESTS_bases); \
+ log_list=`for i in $$bases; do echo $$i.log; done`; \
+ trs_list=`for i in $$bases; do echo $$i.trs; done`; \
+ log_list=`echo $$log_list`; trs_list=`echo $$trs_list`; \
+ $(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) TEST_LOGS="$$log_list"; \
+ exit $$?;
+recheck: all
+ @test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG)
+ @set +e; $(am__set_TESTS_bases); \
+ bases=`for i in $$bases; do echo $$i; done \
+ | $(am__list_recheck_tests)` || exit 1; \
+ log_list=`for i in $$bases; do echo $$i.log; done`; \
+ log_list=`echo $$log_list`; \
+ $(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) \
+ am__force_recheck=am--force-recheck \
+ TEST_LOGS="$$log_list"; \
+ exit $$?
+test-config.log: test-config$(EXEEXT)
+ @p='test-config$(EXEEXT)'; \
+ b='test-config'; \
+ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+ --log-file $$b.log --trs-file $$b.trs \
+ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+ "$$tst" $(AM_TESTS_FD_REDIRECT)
+.test.log:
+ @p='$<'; \
+ $(am__set_b); \
+ $(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \
+ --log-file $$b.log --trs-file $$b.trs \
+ $(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \
+ "$$tst" $(AM_TESTS_FD_REDIRECT)
+@am__EXEEXT_TRUE@.test$(EXEEXT).log:
+@am__EXEEXT_TRUE@ @p='$<'; \
+@am__EXEEXT_TRUE@ $(am__set_b); \
+@am__EXEEXT_TRUE@ $(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \
+@am__EXEEXT_TRUE@ --log-file $$b.log --trs-file $$b.trs \
+@am__EXEEXT_TRUE@ $(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \
+@am__EXEEXT_TRUE@ "$$tst" $(AM_TESTS_FD_REDIRECT)
+
+distdir: $(BUILT_SOURCES)
+ $(MAKE) $(AM_MAKEFLAGS) distdir-am
+
+distdir-am: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ list='$(DISTFILES)'; \
+ dist_files=`for file in $$list; do echo $$file; done | \
+ sed -e "s|^$$srcdirstrip/||;t" \
+ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+ case $$dist_files in \
+ */*) $(MKDIR_P) `echo "$$dist_files" | \
+ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+ sort -u` ;; \
+ esac; \
+ for file in $$dist_files; do \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test -d "$(distdir)/$$file"; then \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+ else \
+ test -f "$(distdir)/$$file" \
+ || cp -p $$d/$$file "$(distdir)/$$file" \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+ $(MAKE) $(AM_MAKEFLAGS) check-TESTS
+check: check-am
+all-am: Makefile $(LIBRARIES)
+installdirs:
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+ if test -z '$(STRIP)'; then \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ install; \
+ else \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+ fi
+mostlyclean-generic:
+ -test -z "$(TEST_LOGS)" || rm -f $(TEST_LOGS)
+ -test -z "$(TEST_LOGS:.log=.trs)" || rm -f $(TEST_LOGS:.log=.trs)
+ -test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG)
+
+clean-generic:
+ -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+ -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-generic clean-libtool clean-noinstLIBRARIES \
+ mostlyclean-am
+
+distclean: distclean-am
+ -rm -f ./$(DEPDIR)/config-enums.Po
+ -rm -f ./$(DEPDIR)/gimpconfig-dump.Po
+ -rm -f ./$(DEPDIR)/gimpconfig-file.Po
+ -rm -f ./$(DEPDIR)/gimpconfig-utils.Po
+ -rm -f ./$(DEPDIR)/gimpcoreconfig.Po
+ -rm -f ./$(DEPDIR)/gimpdialogconfig.Po
+ -rm -f ./$(DEPDIR)/gimpdisplayconfig.Po
+ -rm -f ./$(DEPDIR)/gimpdisplayoptions.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
+ -rm -f ./$(DEPDIR)/gimprc-unknown.Po
+ -rm -f ./$(DEPDIR)/gimprc.Po
+ -rm -f ./$(DEPDIR)/gimpxmlparser.Po
+ -rm -f ./$(DEPDIR)/test-config.Po
+ -rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+ distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+html-am:
+
+info: info-am
+
+info-am:
+
+install-data-am:
+
+install-dvi: install-dvi-am
+
+install-dvi-am:
+
+install-exec-am:
+
+install-html: install-html-am
+
+install-html-am:
+
+install-info: install-info-am
+
+install-info-am:
+
+install-man:
+
+install-pdf: install-pdf-am
+
+install-pdf-am:
+
+install-ps: install-ps-am
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+ -rm -f ./$(DEPDIR)/config-enums.Po
+ -rm -f ./$(DEPDIR)/gimpconfig-dump.Po
+ -rm -f ./$(DEPDIR)/gimpconfig-file.Po
+ -rm -f ./$(DEPDIR)/gimpconfig-utils.Po
+ -rm -f ./$(DEPDIR)/gimpcoreconfig.Po
+ -rm -f ./$(DEPDIR)/gimpdialogconfig.Po
+ -rm -f ./$(DEPDIR)/gimpdisplayconfig.Po
+ -rm -f ./$(DEPDIR)/gimpdisplayoptions.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
+ -rm -f ./$(DEPDIR)/gimprc-unknown.Po
+ -rm -f ./$(DEPDIR)/gimprc.Po
+ -rm -f ./$(DEPDIR)/gimpxmlparser.Po
+ -rm -f ./$(DEPDIR)/test-config.Po
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
+ mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am:
+
+.MAKE: check-am install-am install-strip
+
+.PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-TESTS \
+ check-am clean clean-generic clean-libtool \
+ clean-noinstLIBRARIES cscopelist-am ctags ctags-am distclean \
+ distclean-compile distclean-generic distclean-libtool \
+ distclean-tags distdir dvi dvi-am html html-am info info-am \
+ install install-am install-data install-data-am install-dvi \
+ install-dvi-am install-exec install-exec-am install-html \
+ install-html-am install-info install-info-am install-man \
+ install-pdf install-pdf-am install-ps install-ps-am \
+ install-strip installcheck installcheck-am installdirs \
+ maintainer-clean maintainer-clean-generic mostlyclean \
+ mostlyclean-compile mostlyclean-generic mostlyclean-libtool \
+ pdf pdf-am ps ps-am recheck tags tags-am uninstall \
+ uninstall-am
+
+.PRECIOUS: Makefile
+
+
+xgen-cec: $(srcdir)/config-enums.h $(GIMP_MKENUMS) Makefile.am
+ $(AM_V_GEN) $(GIMP_MKENUMS) \
+ --fhead "#include \"config.h\"\n#include <gio/gio.h>\n#include \"libgimpbase/gimpbase.h\"\n#include \"config-enums.h\"\n#include\"gimp-intl.h\"" \
+ --fprod "\n/* enumerations from \"@basename@\" */" \
+ --vhead "GType\n@enum_name@_get_type (void)\n{\n static const G@Type@Value values[] =\n {" \
+ --vprod " { @VALUENAME@, \"@VALUENAME@\", \"@valuenick@\" }," \
+ --vtail " { 0, NULL, NULL }\n };\n" \
+ --dhead " static const Gimp@Type@Desc descs[] =\n {" \
+ --dprod " { @VALUENAME@, @valuedesc@, @valuehelp@ },@if ('@valueabbrev@' ne 'NULL')@\n /* Translators: this is an abbreviated version of @valueudesc@.\n Keep it short. */\n { @VALUENAME@, @valueabbrev@, NULL },@endif@" \
+ --dtail " { 0, NULL, NULL }\n };\n\n static GType type = 0;\n\n if (G_UNLIKELY (! type))\n {\n type = g_@type@_register_static (\"@EnumName@\", values);\n gimp_type_set_translation_context (type, \"@enumnick@\");\n gimp_@type@_set_value_descriptions (type, descs);\n }\n\n return type;\n}\n" \
+ $< > $@
+
+# copy the generated enum file back to the source directory only if it's
+# changed; otherwise, only update its timestamp, so that the recipe isn't
+# executed again on the next build, however, allow this to (harmlessly) fail,
+# to support building from a read-only source tree.
+$(srcdir)/config-enums.c: xgen-cec
+ $(AM_V_GEN) if ! cmp -s $< $@; then \
+ cp $< $@; \
+ else \
+ touch $@ 2> /dev/null \
+ || true; \
+ fi
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/app/config/config-enums.c b/app/config/config-enums.c
new file mode 100644
index 0000000..aefdfb2
--- /dev/null
+++ b/app/config/config-enums.c
@@ -0,0 +1,397 @@
+
+/* Generated data (by gimp-mkenums) */
+
+#include "config.h"
+#include <gio/gio.h>
+#include "libgimpbase/gimpbase.h"
+#include "config-enums.h"
+#include"gimp-intl.h"
+
+/* enumerations from "config-enums.h" */
+GType
+gimp_canvas_padding_mode_get_type (void)
+{
+ static const GEnumValue values[] =
+ {
+ { GIMP_CANVAS_PADDING_MODE_DEFAULT, "GIMP_CANVAS_PADDING_MODE_DEFAULT", "default" },
+ { GIMP_CANVAS_PADDING_MODE_LIGHT_CHECK, "GIMP_CANVAS_PADDING_MODE_LIGHT_CHECK", "light-check" },
+ { GIMP_CANVAS_PADDING_MODE_DARK_CHECK, "GIMP_CANVAS_PADDING_MODE_DARK_CHECK", "dark-check" },
+ { GIMP_CANVAS_PADDING_MODE_CUSTOM, "GIMP_CANVAS_PADDING_MODE_CUSTOM", "custom" },
+ { 0, NULL, NULL }
+ };
+
+ static const GimpEnumDesc descs[] =
+ {
+ { GIMP_CANVAS_PADDING_MODE_DEFAULT, NC_("canvas-padding-mode", "From theme"), NULL },
+ { GIMP_CANVAS_PADDING_MODE_LIGHT_CHECK, NC_("canvas-padding-mode", "Light check color"), NULL },
+ { GIMP_CANVAS_PADDING_MODE_DARK_CHECK, NC_("canvas-padding-mode", "Dark check color"), NULL },
+ { GIMP_CANVAS_PADDING_MODE_CUSTOM, NC_("canvas-padding-mode", "Custom color"), NULL },
+ { 0, NULL, NULL }
+ };
+
+ static GType type = 0;
+
+ if (G_UNLIKELY (! type))
+ {
+ type = g_enum_register_static ("GimpCanvasPaddingMode", values);
+ gimp_type_set_translation_context (type, "canvas-padding-mode");
+ gimp_enum_set_value_descriptions (type, descs);
+ }
+
+ return type;
+}
+
+GType
+gimp_cursor_format_get_type (void)
+{
+ static const GEnumValue values[] =
+ {
+ { GIMP_CURSOR_FORMAT_BITMAP, "GIMP_CURSOR_FORMAT_BITMAP", "bitmap" },
+ { GIMP_CURSOR_FORMAT_PIXBUF, "GIMP_CURSOR_FORMAT_PIXBUF", "pixbuf" },
+ { 0, NULL, NULL }
+ };
+
+ static const GimpEnumDesc descs[] =
+ {
+ { GIMP_CURSOR_FORMAT_BITMAP, NC_("cursor-format", "Black & white"), NULL },
+ { GIMP_CURSOR_FORMAT_PIXBUF, NC_("cursor-format", "Fancy"), NULL },
+ { 0, NULL, NULL }
+ };
+
+ static GType type = 0;
+
+ if (G_UNLIKELY (! type))
+ {
+ type = g_enum_register_static ("GimpCursorFormat", values);
+ gimp_type_set_translation_context (type, "cursor-format");
+ gimp_enum_set_value_descriptions (type, descs);
+ }
+
+ return type;
+}
+
+GType
+gimp_cursor_mode_get_type (void)
+{
+ static const GEnumValue values[] =
+ {
+ { GIMP_CURSOR_MODE_TOOL_ICON, "GIMP_CURSOR_MODE_TOOL_ICON", "tool-icon" },
+ { GIMP_CURSOR_MODE_TOOL_CROSSHAIR, "GIMP_CURSOR_MODE_TOOL_CROSSHAIR", "tool-crosshair" },
+ { GIMP_CURSOR_MODE_CROSSHAIR, "GIMP_CURSOR_MODE_CROSSHAIR", "crosshair" },
+ { 0, NULL, NULL }
+ };
+
+ static const GimpEnumDesc descs[] =
+ {
+ { GIMP_CURSOR_MODE_TOOL_ICON, NC_("cursor-mode", "Tool icon"), NULL },
+ { GIMP_CURSOR_MODE_TOOL_CROSSHAIR, NC_("cursor-mode", "Tool icon with crosshair"), NULL },
+ { GIMP_CURSOR_MODE_CROSSHAIR, NC_("cursor-mode", "Crosshair only"), NULL },
+ { 0, NULL, NULL }
+ };
+
+ static GType type = 0;
+
+ if (G_UNLIKELY (! type))
+ {
+ type = g_enum_register_static ("GimpCursorMode", values);
+ gimp_type_set_translation_context (type, "cursor-mode");
+ gimp_enum_set_value_descriptions (type, descs);
+ }
+
+ return type;
+}
+
+GType
+gimp_export_file_type_get_type (void)
+{
+ static const GEnumValue values[] =
+ {
+ { GIMP_EXPORT_FILE_PNG, "GIMP_EXPORT_FILE_PNG", "png" },
+ { GIMP_EXPORT_FILE_JPG, "GIMP_EXPORT_FILE_JPG", "jpg" },
+ { GIMP_EXPORT_FILE_ORA, "GIMP_EXPORT_FILE_ORA", "ora" },
+ { GIMP_EXPORT_FILE_PSD, "GIMP_EXPORT_FILE_PSD", "psd" },
+ { GIMP_EXPORT_FILE_PDF, "GIMP_EXPORT_FILE_PDF", "pdf" },
+ { GIMP_EXPORT_FILE_TIF, "GIMP_EXPORT_FILE_TIF", "tif" },
+ { GIMP_EXPORT_FILE_BMP, "GIMP_EXPORT_FILE_BMP", "bmp" },
+ { GIMP_EXPORT_FILE_WEBP, "GIMP_EXPORT_FILE_WEBP", "webp" },
+ { 0, NULL, NULL }
+ };
+
+ static const GimpEnumDesc descs[] =
+ {
+ { GIMP_EXPORT_FILE_PNG, NC_("export-file-type", "PNG Image"), NULL },
+ { GIMP_EXPORT_FILE_JPG, NC_("export-file-type", "JPEG Image"), NULL },
+ { GIMP_EXPORT_FILE_ORA, NC_("export-file-type", "OpenRaster Image"), NULL },
+ { GIMP_EXPORT_FILE_PSD, NC_("export-file-type", "Photoshop Image"), NULL },
+ { GIMP_EXPORT_FILE_PDF, NC_("export-file-type", "Portable Document Format"), NULL },
+ { GIMP_EXPORT_FILE_TIF, NC_("export-file-type", "TIFF Image"), NULL },
+ { GIMP_EXPORT_FILE_BMP, NC_("export-file-type", "Windows BMP Image"), NULL },
+ { GIMP_EXPORT_FILE_WEBP, NC_("export-file-type", "WebP Image"), NULL },
+ { 0, NULL, NULL }
+ };
+
+ static GType type = 0;
+
+ if (G_UNLIKELY (! type))
+ {
+ type = g_enum_register_static ("GimpExportFileType", values);
+ gimp_type_set_translation_context (type, "export-file-type");
+ gimp_enum_set_value_descriptions (type, descs);
+ }
+
+ return type;
+}
+
+GType
+gimp_handedness_get_type (void)
+{
+ static const GEnumValue values[] =
+ {
+ { GIMP_HANDEDNESS_LEFT, "GIMP_HANDEDNESS_LEFT", "left" },
+ { GIMP_HANDEDNESS_RIGHT, "GIMP_HANDEDNESS_RIGHT", "right" },
+ { 0, NULL, NULL }
+ };
+
+ static const GimpEnumDesc descs[] =
+ {
+ { GIMP_HANDEDNESS_LEFT, NC_("handedness", "Left-handed"), NULL },
+ { GIMP_HANDEDNESS_RIGHT, NC_("handedness", "Right-handed"), NULL },
+ { 0, NULL, NULL }
+ };
+
+ static GType type = 0;
+
+ if (G_UNLIKELY (! type))
+ {
+ type = g_enum_register_static ("GimpHandedness", values);
+ gimp_type_set_translation_context (type, "handedness");
+ gimp_enum_set_value_descriptions (type, descs);
+ }
+
+ return type;
+}
+
+GType
+gimp_help_browser_type_get_type (void)
+{
+ static const GEnumValue values[] =
+ {
+ { GIMP_HELP_BROWSER_GIMP, "GIMP_HELP_BROWSER_GIMP", "gimp" },
+ { GIMP_HELP_BROWSER_WEB_BROWSER, "GIMP_HELP_BROWSER_WEB_BROWSER", "web-browser" },
+ { 0, NULL, NULL }
+ };
+
+ static const GimpEnumDesc descs[] =
+ {
+ { GIMP_HELP_BROWSER_GIMP, NC_("help-browser-type", "GIMP help browser"), NULL },
+ { GIMP_HELP_BROWSER_WEB_BROWSER, NC_("help-browser-type", "Web browser"), NULL },
+ { 0, NULL, NULL }
+ };
+
+ static GType type = 0;
+
+ if (G_UNLIKELY (! type))
+ {
+ type = g_enum_register_static ("GimpHelpBrowserType", values);
+ gimp_type_set_translation_context (type, "help-browser-type");
+ gimp_enum_set_value_descriptions (type, descs);
+ }
+
+ return type;
+}
+
+GType
+gimp_icon_size_get_type (void)
+{
+ static const GEnumValue values[] =
+ {
+ { GIMP_ICON_SIZE_AUTO, "GIMP_ICON_SIZE_AUTO", "auto" },
+ { GIMP_ICON_SIZE_THEME, "GIMP_ICON_SIZE_THEME", "theme" },
+ { GIMP_ICON_SIZE_SMALL, "GIMP_ICON_SIZE_SMALL", "small" },
+ { GIMP_ICON_SIZE_MEDIUM, "GIMP_ICON_SIZE_MEDIUM", "medium" },
+ { GIMP_ICON_SIZE_LARGE, "GIMP_ICON_SIZE_LARGE", "large" },
+ { GIMP_ICON_SIZE_HUGE, "GIMP_ICON_SIZE_HUGE", "huge" },
+ { 0, NULL, NULL }
+ };
+
+ static const GimpEnumDesc descs[] =
+ {
+ { GIMP_ICON_SIZE_AUTO, NC_("icon-size", "Guess ideal size"), NULL },
+ { GIMP_ICON_SIZE_THEME, NC_("icon-size", "Theme-set size"), NULL },
+ { GIMP_ICON_SIZE_SMALL, NC_("icon-size", "Small size"), NULL },
+ { GIMP_ICON_SIZE_MEDIUM, NC_("icon-size", "Medium size"), NULL },
+ { GIMP_ICON_SIZE_LARGE, NC_("icon-size", "Large size"), NULL },
+ { GIMP_ICON_SIZE_HUGE, NC_("icon-size", "Huge size"), NULL },
+ { 0, NULL, NULL }
+ };
+
+ static GType type = 0;
+
+ if (G_UNLIKELY (! type))
+ {
+ type = g_enum_register_static ("GimpIconSize", values);
+ gimp_type_set_translation_context (type, "icon-size");
+ gimp_enum_set_value_descriptions (type, descs);
+ }
+
+ return type;
+}
+
+GType
+gimp_position_get_type (void)
+{
+ static const GEnumValue values[] =
+ {
+ { GIMP_POSITION_TOP, "GIMP_POSITION_TOP", "top" },
+ { GIMP_POSITION_BOTTOM, "GIMP_POSITION_BOTTOM", "bottom" },
+ { GIMP_POSITION_LEFT, "GIMP_POSITION_LEFT", "left" },
+ { GIMP_POSITION_RIGHT, "GIMP_POSITION_RIGHT", "right" },
+ { 0, NULL, NULL }
+ };
+
+ static const GimpEnumDesc descs[] =
+ {
+ { GIMP_POSITION_TOP, NC_("position", "Top"), NULL },
+ { GIMP_POSITION_BOTTOM, NC_("position", "Bottom"), NULL },
+ { GIMP_POSITION_LEFT, NC_("position", "Left"), NULL },
+ { GIMP_POSITION_RIGHT, NC_("position", "Right"), NULL },
+ { 0, NULL, NULL }
+ };
+
+ static GType type = 0;
+
+ if (G_UNLIKELY (! type))
+ {
+ type = g_enum_register_static ("GimpPosition", values);
+ gimp_type_set_translation_context (type, "position");
+ gimp_enum_set_value_descriptions (type, descs);
+ }
+
+ return type;
+}
+
+GType
+gimp_space_bar_action_get_type (void)
+{
+ static const GEnumValue values[] =
+ {
+ { GIMP_SPACE_BAR_ACTION_NONE, "GIMP_SPACE_BAR_ACTION_NONE", "none" },
+ { GIMP_SPACE_BAR_ACTION_PAN, "GIMP_SPACE_BAR_ACTION_PAN", "pan" },
+ { GIMP_SPACE_BAR_ACTION_MOVE, "GIMP_SPACE_BAR_ACTION_MOVE", "move" },
+ { 0, NULL, NULL }
+ };
+
+ static const GimpEnumDesc descs[] =
+ {
+ { GIMP_SPACE_BAR_ACTION_NONE, NC_("space-bar-action", "No action"), NULL },
+ { GIMP_SPACE_BAR_ACTION_PAN, NC_("space-bar-action", "Pan view"), NULL },
+ { GIMP_SPACE_BAR_ACTION_MOVE, NC_("space-bar-action", "Switch to Move tool"), NULL },
+ { 0, NULL, NULL }
+ };
+
+ static GType type = 0;
+
+ if (G_UNLIKELY (! type))
+ {
+ type = g_enum_register_static ("GimpSpaceBarAction", values);
+ gimp_type_set_translation_context (type, "space-bar-action");
+ gimp_enum_set_value_descriptions (type, descs);
+ }
+
+ return type;
+}
+
+GType
+gimp_tool_group_menu_mode_get_type (void)
+{
+ static const GEnumValue values[] =
+ {
+ { GIMP_TOOL_GROUP_MENU_MODE_SHOW_ON_CLICK, "GIMP_TOOL_GROUP_MENU_MODE_SHOW_ON_CLICK", "click" },
+ { GIMP_TOOL_GROUP_MENU_MODE_SHOW_ON_HOVER, "GIMP_TOOL_GROUP_MENU_MODE_SHOW_ON_HOVER", "hover" },
+ { GIMP_TOOL_GROUP_MENU_MODE_SHOW_ON_HOVER_SINGLE_COLUMN, "GIMP_TOOL_GROUP_MENU_MODE_SHOW_ON_HOVER_SINGLE_COLUMN", "hover-single-column" },
+ { 0, NULL, NULL }
+ };
+
+ static const GimpEnumDesc descs[] =
+ {
+ { GIMP_TOOL_GROUP_MENU_MODE_SHOW_ON_CLICK, NC_("tool-group-menu-mode", "Show on click"), NULL },
+ { GIMP_TOOL_GROUP_MENU_MODE_SHOW_ON_HOVER, NC_("tool-group-menu-mode", "Show on hover"), NULL },
+ { GIMP_TOOL_GROUP_MENU_MODE_SHOW_ON_HOVER_SINGLE_COLUMN, NC_("tool-group-menu-mode", "Show on hover in single column"), NULL },
+ { 0, NULL, NULL }
+ };
+
+ static GType type = 0;
+
+ if (G_UNLIKELY (! type))
+ {
+ type = g_enum_register_static ("GimpToolGroupMenuMode", values);
+ gimp_type_set_translation_context (type, "tool-group-menu-mode");
+ gimp_enum_set_value_descriptions (type, descs);
+ }
+
+ return type;
+}
+
+GType
+gimp_window_hint_get_type (void)
+{
+ static const GEnumValue values[] =
+ {
+ { GIMP_WINDOW_HINT_NORMAL, "GIMP_WINDOW_HINT_NORMAL", "normal" },
+ { GIMP_WINDOW_HINT_UTILITY, "GIMP_WINDOW_HINT_UTILITY", "utility" },
+ { GIMP_WINDOW_HINT_KEEP_ABOVE, "GIMP_WINDOW_HINT_KEEP_ABOVE", "keep-above" },
+ { 0, NULL, NULL }
+ };
+
+ static const GimpEnumDesc descs[] =
+ {
+ { GIMP_WINDOW_HINT_NORMAL, NC_("window-hint", "Normal window"), NULL },
+ { GIMP_WINDOW_HINT_UTILITY, NC_("window-hint", "Utility window"), NULL },
+ { GIMP_WINDOW_HINT_KEEP_ABOVE, NC_("window-hint", "Keep above"), NULL },
+ { 0, NULL, NULL }
+ };
+
+ static GType type = 0;
+
+ if (G_UNLIKELY (! type))
+ {
+ type = g_enum_register_static ("GimpWindowHint", values);
+ gimp_type_set_translation_context (type, "window-hint");
+ gimp_enum_set_value_descriptions (type, descs);
+ }
+
+ return type;
+}
+
+GType
+gimp_zoom_quality_get_type (void)
+{
+ static const GEnumValue values[] =
+ {
+ { GIMP_ZOOM_QUALITY_LOW, "GIMP_ZOOM_QUALITY_LOW", "low" },
+ { GIMP_ZOOM_QUALITY_HIGH, "GIMP_ZOOM_QUALITY_HIGH", "high" },
+ { 0, NULL, NULL }
+ };
+
+ static const GimpEnumDesc descs[] =
+ {
+ { GIMP_ZOOM_QUALITY_LOW, NC_("zoom-quality", "Low"), NULL },
+ { GIMP_ZOOM_QUALITY_HIGH, NC_("zoom-quality", "High"), NULL },
+ { 0, NULL, NULL }
+ };
+
+ static GType type = 0;
+
+ if (G_UNLIKELY (! type))
+ {
+ type = g_enum_register_static ("GimpZoomQuality", values);
+ gimp_type_set_translation_context (type, "zoom-quality");
+ gimp_enum_set_value_descriptions (type, descs);
+ }
+
+ return type;
+}
+
+
+/* Generated data ends here */
+
diff --git a/app/config/config-enums.h b/app/config/config-enums.h
new file mode 100644
index 0000000..c2d30bb
--- /dev/null
+++ b/app/config/config-enums.h
@@ -0,0 +1,173 @@
+/* GIMP - The GNU Image Manipulation Program
+ * Copyright (C) 1995 Spencer Kimball and Peter Mattis
+ *
+ * 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 __CONFIG_ENUMS_H__
+#define __CONFIG_ENUMS_H__
+
+
+#define GIMP_TYPE_CANVAS_PADDING_MODE (gimp_canvas_padding_mode_get_type ())
+
+GType gimp_canvas_padding_mode_get_type (void) G_GNUC_CONST;
+
+typedef enum
+{
+ GIMP_CANVAS_PADDING_MODE_DEFAULT, /*< desc="From theme" >*/
+ GIMP_CANVAS_PADDING_MODE_LIGHT_CHECK, /*< desc="Light check color" >*/
+ GIMP_CANVAS_PADDING_MODE_DARK_CHECK, /*< desc="Dark check color" >*/
+ GIMP_CANVAS_PADDING_MODE_CUSTOM, /*< desc="Custom color" >*/
+ GIMP_CANVAS_PADDING_MODE_RESET = -1 /*< skip >*/
+} GimpCanvasPaddingMode;
+
+
+#define GIMP_TYPE_CURSOR_FORMAT (gimp_cursor_format_get_type ())
+
+GType gimp_cursor_format_get_type (void) G_GNUC_CONST;
+
+typedef enum
+{
+ GIMP_CURSOR_FORMAT_BITMAP, /*< desc="Black & white" >*/
+ GIMP_CURSOR_FORMAT_PIXBUF /*< desc="Fancy" >*/
+} GimpCursorFormat;
+
+
+#define GIMP_TYPE_CURSOR_MODE (gimp_cursor_mode_get_type ())
+
+GType gimp_cursor_mode_get_type (void) G_GNUC_CONST;
+
+typedef enum
+{
+ GIMP_CURSOR_MODE_TOOL_ICON, /*< desc="Tool icon" >*/
+ GIMP_CURSOR_MODE_TOOL_CROSSHAIR, /*< desc="Tool icon with crosshair" >*/
+ GIMP_CURSOR_MODE_CROSSHAIR /*< desc="Crosshair only" >*/
+} GimpCursorMode;
+
+
+#define GIMP_TYPE_EXPORT_FILE_TYPE (gimp_export_file_type_get_type ())
+
+GType gimp_export_file_type_get_type (void) G_GNUC_CONST;
+
+typedef enum
+{
+ GIMP_EXPORT_FILE_PNG, /*< desc="PNG Image" >*/
+ GIMP_EXPORT_FILE_JPG, /*< desc="JPEG Image" >*/
+ GIMP_EXPORT_FILE_ORA, /*< desc="OpenRaster Image" >*/
+ GIMP_EXPORT_FILE_PSD, /*< desc="Photoshop Image" >*/
+ GIMP_EXPORT_FILE_PDF, /*< desc="Portable Document Format" >*/
+ GIMP_EXPORT_FILE_TIF, /*< desc="TIFF Image" >*/
+ GIMP_EXPORT_FILE_BMP, /*< desc="Windows BMP Image" >*/
+ GIMP_EXPORT_FILE_WEBP, /*< desc="WebP Image" >*/
+} GimpExportFileType;
+
+
+#define GIMP_TYPE_HANDEDNESS (gimp_handedness_get_type ())
+
+GType gimp_handedness_get_type (void) G_GNUC_CONST;
+
+typedef enum
+{
+ GIMP_HANDEDNESS_LEFT, /*< desc="Left-handed" >*/
+ GIMP_HANDEDNESS_RIGHT /*< desc="Right-handed" >*/
+} GimpHandedness;
+
+
+#define GIMP_TYPE_HELP_BROWSER_TYPE (gimp_help_browser_type_get_type ())
+
+GType gimp_help_browser_type_get_type (void) G_GNUC_CONST;
+
+typedef enum
+{
+ GIMP_HELP_BROWSER_GIMP, /*< desc="GIMP help browser" >*/
+ GIMP_HELP_BROWSER_WEB_BROWSER /*< desc="Web browser" >*/
+} GimpHelpBrowserType;
+
+
+#define GIMP_TYPE_ICON_SIZE (gimp_icon_size_get_type ())
+
+GType gimp_icon_size_get_type (void) G_GNUC_CONST;
+
+typedef enum
+{
+ GIMP_ICON_SIZE_AUTO, /*< desc="Guess ideal size" > */
+ GIMP_ICON_SIZE_THEME, /*< desc="Theme-set size" > */
+ GIMP_ICON_SIZE_SMALL, /*< desc="Small size" > */
+ GIMP_ICON_SIZE_MEDIUM, /*< desc="Medium size" > */
+ GIMP_ICON_SIZE_LARGE, /*< desc="Large size" > */
+ GIMP_ICON_SIZE_HUGE /*< desc="Huge size" > */
+} GimpIconSize;
+
+
+#define GIMP_TYPE_POSITION (gimp_position_get_type ())
+
+GType gimp_position_get_type (void) G_GNUC_CONST;
+
+typedef enum
+{
+ GIMP_POSITION_TOP, /*< desc="Top" >*/
+ GIMP_POSITION_BOTTOM, /*< desc="Bottom" >*/
+ GIMP_POSITION_LEFT, /*< desc="Left" >*/
+ GIMP_POSITION_RIGHT /*< desc="Right" >*/
+} GimpPosition;
+
+
+#define GIMP_TYPE_SPACE_BAR_ACTION (gimp_space_bar_action_get_type ())
+
+GType gimp_space_bar_action_get_type (void) G_GNUC_CONST;
+
+typedef enum
+{
+ GIMP_SPACE_BAR_ACTION_NONE, /*< desc="No action" >*/
+ GIMP_SPACE_BAR_ACTION_PAN, /*< desc="Pan view" >*/
+ GIMP_SPACE_BAR_ACTION_MOVE /*< desc="Switch to Move tool" >*/
+} GimpSpaceBarAction;
+
+
+#define GIMP_TYPE_TOOL_GROUP_MENU_MODE (gimp_tool_group_menu_mode_get_type ())
+
+GType gimp_tool_group_menu_mode_get_type (void) G_GNUC_CONST;
+
+typedef enum
+{
+ GIMP_TOOL_GROUP_MENU_MODE_SHOW_ON_CLICK, /*< desc="Show on click" >*/
+ GIMP_TOOL_GROUP_MENU_MODE_SHOW_ON_HOVER, /*< desc="Show on hover" >*/
+ GIMP_TOOL_GROUP_MENU_MODE_SHOW_ON_HOVER_SINGLE_COLUMN /*< desc="Show on hover in single column" >*/
+} GimpToolGroupMenuMode;
+
+
+#define GIMP_TYPE_WINDOW_HINT (gimp_window_hint_get_type ())
+
+GType gimp_window_hint_get_type (void) G_GNUC_CONST;
+
+typedef enum
+{
+ GIMP_WINDOW_HINT_NORMAL, /*< desc="Normal window" >*/
+ GIMP_WINDOW_HINT_UTILITY, /*< desc="Utility window" >*/
+ GIMP_WINDOW_HINT_KEEP_ABOVE /*< desc="Keep above" >*/
+} GimpWindowHint;
+
+
+#define GIMP_TYPE_ZOOM_QUALITY (gimp_zoom_quality_get_type ())
+
+GType gimp_zoom_quality_get_type (void) G_GNUC_CONST;
+
+typedef enum
+{
+ GIMP_ZOOM_QUALITY_LOW, /*< desc="Low" >*/
+ GIMP_ZOOM_QUALITY_HIGH /*< desc="High" >*/
+} GimpZoomQuality;
+
+
+#endif /* __CONFIG_ENUMS_H__ */
diff --git a/app/config/config-types.h b/app/config/config-types.h
new file mode 100644
index 0000000..40b0802
--- /dev/null
+++ b/app/config/config-types.h
@@ -0,0 +1,59 @@
+/* GIMP - The GNU Image Manipulation Program
+ * Copyright (C) 1995 Spencer Kimball and Peter Mattis
+ *
+ * GimpConfig typedefs
+ * Copyright (C) 2001-2002 Sven Neumann <sven@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 __CONFIG_TYPES_H__
+#define __CONFIG_TYPES_H__
+
+
+#include "libgimpconfig/gimpconfigtypes.h"
+
+#include "config/config-enums.h"
+
+
+#define GIMP_OPACITY_TRANSPARENT 0.0
+#define GIMP_OPACITY_OPAQUE 1.0
+
+
+typedef struct _GimpGeglConfig GimpGeglConfig;
+typedef struct _GimpCoreConfig GimpCoreConfig;
+typedef struct _GimpDisplayConfig GimpDisplayConfig;
+typedef struct _GimpGuiConfig GimpGuiConfig;
+typedef struct _GimpDialogConfig GimpDialogConfig;
+typedef struct _GimpLangRc GimpLangRc;
+typedef struct _GimpPluginConfig GimpPluginConfig;
+typedef struct _GimpRc GimpRc;
+
+typedef struct _GimpXmlParser GimpXmlParser;
+
+typedef struct _GimpDisplayOptions GimpDisplayOptions;
+
+/* should be in core/core-types.h */
+typedef struct _GimpGrid GimpGrid;
+typedef struct _GimpTemplate GimpTemplate;
+
+
+/* for now these are defines, but can be turned into something
+ * fancier for nicer debugging
+ */
+#define gimp_assert g_assert
+#define gimp_assert_not_reached g_assert_not_reached
+
+
+#endif /* __CONFIG_TYPES_H__ */
diff --git a/app/config/gimpconfig-dump.c b/app/config/gimpconfig-dump.c
new file mode 100644
index 0000000..1a2b376
--- /dev/null
+++ b/app/config/gimpconfig-dump.c
@@ -0,0 +1,644 @@
+/* GIMP - The GNU Image Manipulation Program
+ * Copyright (C) 1995 Spencer Kimball and Peter Mattis
+ *
+ * GimpConfig object property dumper.
+ * Copyright (C) 2001-2006 Sven Neumann <sven@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/>.
+ */
+
+#include "config.h"
+
+#include <stdlib.h>
+#include <string.h>
+
+#include <cairo.h>
+#include <gegl.h>
+#include <gdk-pixbuf/gdk-pixbuf.h>
+
+#ifdef G_OS_WIN32
+#include <gio/gwin32outputstream.h>
+#else
+#include <gio/gunixoutputstream.h>
+#endif
+
+#include "libgimpbase/gimpbase.h"
+#include "libgimpcolor/gimpcolor.h"
+#include "libgimpconfig/gimpconfig.h"
+
+#include "config-types.h"
+
+#include "gimpconfig-dump.h"
+#include "gimprc.h"
+
+
+
+static void dump_gimprc_system (GimpConfig *rc,
+ GimpConfigWriter *writer,
+ GOutputStream *output);
+static void dump_gimprc_manpage (GimpConfig *rc,
+ GimpConfigWriter *writer,
+ GOutputStream *output);
+static gchar * dump_describe_param (GParamSpec *param_spec);
+static void dump_with_linebreaks (GOutputStream *output,
+ const gchar *text);
+
+
+gboolean
+gimp_config_dump (GObject *gimp,
+ GimpConfigDumpFormat format)
+{
+ GOutputStream *output;
+ GimpConfigWriter *writer;
+ GimpConfig *rc;
+
+ g_return_val_if_fail (G_IS_OBJECT (gimp), FALSE);
+
+ rc = g_object_new (GIMP_TYPE_RC,
+ "gimp", gimp,
+ NULL);
+
+#ifdef G_OS_WIN32
+ output = g_win32_output_stream_new ((gpointer) 1, FALSE);
+#else
+ output = g_unix_output_stream_new (1, FALSE);
+#endif
+
+ writer = gimp_config_writer_new_stream (output, NULL, NULL);
+
+ switch (format)
+ {
+ case GIMP_CONFIG_DUMP_NONE:
+ break;
+
+ case GIMP_CONFIG_DUMP_GIMPRC:
+ gimp_config_writer_comment (writer,
+ "Dump of the GIMP default configuration");
+ gimp_config_writer_linefeed (writer);
+ gimp_config_serialize_properties (rc, writer);
+ gimp_config_writer_linefeed (writer);
+ break;
+
+ case GIMP_CONFIG_DUMP_GIMPRC_SYSTEM:
+ dump_gimprc_system (rc, writer, output);
+ break;
+
+ case GIMP_CONFIG_DUMP_GIMPRC_MANPAGE:
+ dump_gimprc_manpage (rc, writer, output);
+ break;
+ }
+
+ gimp_config_writer_finish (writer, NULL, NULL);
+ g_object_unref (output);
+ g_object_unref (rc);
+
+ return TRUE;
+}
+
+
+static const gchar system_gimprc_header[] =
+"This is the system-wide gimprc file. Any change made in this file "
+"will affect all users of this system, provided that they are not "
+"overriding the default values in their personal gimprc file.\n"
+"\n"
+"Lines that start with a '#' are comments. Blank lines are ignored.\n"
+"\n"
+"By default everything in this file is commented out. The file then "
+"documents the default values and shows what changes are possible.\n"
+"\n"
+"The variable ${gimp_dir} is set to the value of the environment "
+"variable GIMP2_DIRECTORY or, if that is not set, the compiled-in "
+"default value is used. If GIMP2_DIRECTORY is not an absolute path, "
+"it is interpreted relative to your home directory.";
+
+static void
+dump_gimprc_system (GimpConfig *rc,
+ GimpConfigWriter *writer,
+ GOutputStream *output)
+{
+ GObjectClass *klass;
+ GParamSpec **property_specs;
+ guint n_property_specs;
+ guint i;
+
+ gimp_config_writer_comment (writer, system_gimprc_header);
+ gimp_config_writer_linefeed (writer);
+
+ klass = G_OBJECT_GET_CLASS (rc);
+ property_specs = g_object_class_list_properties (klass, &n_property_specs);
+
+ for (i = 0; i < n_property_specs; i++)
+ {
+ GParamSpec *prop_spec = property_specs[i];
+ gchar *comment;
+
+ if (! (prop_spec->flags & GIMP_CONFIG_PARAM_SERIALIZE))
+ continue;
+
+ if (prop_spec->flags & GIMP_CONFIG_PARAM_IGNORE)
+ continue;
+
+ comment = dump_describe_param (prop_spec);
+ if (comment)
+ {
+ gimp_config_writer_comment (writer, comment);
+ g_free (comment);
+ }
+
+ gimp_config_writer_comment_mode (writer, TRUE);
+ gimp_config_writer_linefeed (writer);
+
+ if (! strcmp (prop_spec->name, "num-processors"))
+ {
+ gimp_config_writer_open (writer, "num-processors");
+ gimp_config_writer_printf (writer, "1");
+ gimp_config_writer_close (writer);
+ }
+ else if (! strcmp (prop_spec->name, "tile-cache-size"))
+ {
+ gimp_config_writer_open (writer, "tile-cache-size");
+ gimp_config_writer_printf (writer, "2g");
+ gimp_config_writer_close (writer);
+ }
+ else if (! strcmp (prop_spec->name, "undo-size"))
+ {
+ gimp_config_writer_open (writer, "undo-size");
+ gimp_config_writer_printf (writer, "1g");
+ gimp_config_writer_close (writer);
+ }
+ else if (! strcmp (prop_spec->name, "mypaint-brush-path"))
+ {
+ gchar *path = g_strdup_printf ("@mypaint_brushes_dir@%s"
+ "~/.mypaint/brushes",
+ G_SEARCHPATH_SEPARATOR_S);
+
+ gimp_config_writer_open (writer, "mypaint-brush-path");
+ gimp_config_writer_string (writer, path);
+ gimp_config_writer_close (writer);
+
+ g_free (path);
+ }
+ else
+ {
+ gimp_config_serialize_property (rc, prop_spec, writer);
+ }
+
+ gimp_config_writer_comment_mode (writer, FALSE);
+ gimp_config_writer_linefeed (writer);
+ }
+
+ g_free (property_specs);
+}
+
+
+static const gchar man_page_header[] =
+".\\\" This man-page is auto-generated by gimp --dump-gimprc-manpage.\n"
+"\n"
+".TH GIMPRC 5 \"Version @GIMP_VERSION@\" \"GIMP Manual Pages\"\n"
+".SH NAME\n"
+"gimprc \\- gimp configuration file\n"
+".SH DESCRIPTION\n"
+"The\n"
+".B gimprc\n"
+"file is a configuration file read by GIMP when it starts up. There\n"
+"are two of these: one system-wide one stored in\n"
+"@gimpsysconfdir@/gimprc and a per-user @manpage_gimpdir@/gimprc\n"
+"which may override system settings.\n"
+"\n"
+"Comments are introduced by a hash sign (#), and continue until the end\n"
+"of the line. Blank lines are ignored.\n"
+"\n"
+"The\n"
+".B gimprc\n"
+"file associates values with properties. These properties may be set\n"
+"by lisp-like assignments of the form:\n"
+".IP\n"
+"\\f3(\\f2property\\-name\\ value\\f3)\\f1\n"
+".TP\n"
+"where:\n"
+".TP 10\n"
+".I property\\-name\n"
+"is one of the property names described below.\n"
+".TP\n"
+".I value\n"
+"is the value the property is to be set to.\n"
+".PP\n"
+"\n"
+"Either spaces or tabs may be used to separate the name from the value.\n"
+".PP\n"
+".SH PROPERTIES\n"
+"Valid properties and their default values are:\n"
+"\n";
+
+static const gchar *man_page_path =
+".PP\n"
+".SH PATH EXPANSION\n"
+"Strings of type PATH are expanded in a manner similar to\n"
+".BR bash (1).\n"
+"Specifically: tilde (~) is expanded to the user's home directory. Note that\n"
+"the bash feature of being able to refer to other user's home directories\n"
+"by writing ~userid/ is not valid in this file.\n"
+"\n"
+"${variable} is expanded to the current value of an environment variable.\n"
+"There are a few variables that are pre-defined:\n"
+".TP\n"
+".I gimp_dir\n"
+"The personal gimp directory which is set to the value of the environment\n"
+"variable GIMP2_DIRECTORY or to @manpage_gimpdir@.\n"
+".TP\n"
+".I gimp_data_dir\n"
+"Base for paths to shareable data, which is set to the value of the\n"
+"environment variable GIMP2_DATADIR or to the compiled-in default value\n"
+"@gimpdatadir@.\n"
+".TP\n"
+".I gimp_plug_in_dir\n"
+"Base to paths for architecture-specific plug-ins and modules, which is set\n"
+"to the value of the environment variable GIMP2_PLUGINDIR or to the\n"
+"compiled-in default value @gimpplugindir@.\n"
+".TP\n"
+".I gimp_sysconf_dir\n"
+"Path to configuration files, which is set to the value of the environment\n"
+"variable GIMP2_SYSCONFDIR or to the compiled-in default value \n"
+"@gimpsysconfdir@.\n"
+".TP\n"
+".I gimp_cache_dir\n"
+"Path to cached files, which is set to the value of the environment\n"
+"variable GIMP2_CACHEDIR or to the system default for per-user cached files.\n"
+".TP\n"
+".I gimp_temp_dir\n"
+"Path to temporary files, which is set to the value of the environment\n"
+"variable GIMP2_TEMPDIR or to the system default for temporary files.\n"
+"\n";
+
+static const gchar man_page_footer[] =
+".SH FILES\n"
+".TP\n"
+".I @gimpsysconfdir@/gimprc\n"
+"System-wide configuration file\n"
+".TP\n"
+".I @manpage_gimpdir@/gimprc\n"
+"Per-user configuration file\n"
+"\n"
+".SH \"SEE ALSO\"\n"
+".BR gimp (1)\n";
+
+
+static void
+dump_gimprc_manpage (GimpConfig *rc,
+ GimpConfigWriter *writer,
+ GOutputStream *output)
+{
+ GObjectClass *klass;
+ GParamSpec **property_specs;
+ guint n_property_specs;
+ guint i;
+
+ g_output_stream_printf (output, NULL, NULL, NULL,
+ "%s", man_page_header);
+
+ klass = G_OBJECT_GET_CLASS (rc);
+ property_specs = g_object_class_list_properties (klass, &n_property_specs);
+
+ for (i = 0; i < n_property_specs; i++)
+ {
+ GParamSpec *prop_spec = property_specs[i];
+ gchar *desc;
+ gboolean success;
+
+ if (! (prop_spec->flags & GIMP_CONFIG_PARAM_SERIALIZE))
+ continue;
+
+ if (prop_spec->flags & GIMP_CONFIG_PARAM_IGNORE)
+ continue;
+
+ g_output_stream_printf (output, NULL, NULL, NULL,
+ ".TP\n");
+
+ if (! strcmp (prop_spec->name, "num-processors"))
+ {
+ gimp_config_writer_open (writer, "num-processors");
+ gimp_config_writer_printf (writer, "1");
+ gimp_config_writer_close (writer);
+
+ success = TRUE;
+ }
+ else if (! strcmp (prop_spec->name, "tile-cache-size"))
+ {
+ gimp_config_writer_open (writer, "tile-cache-size");
+ gimp_config_writer_printf (writer, "2g");
+ gimp_config_writer_close (writer);
+
+ success = TRUE;
+ }
+ else if (! strcmp (prop_spec->name, "undo-size"))
+ {
+ gimp_config_writer_open (writer, "undo-size");
+ gimp_config_writer_printf (writer, "1g");
+ gimp_config_writer_close (writer);
+
+ success = TRUE;
+ }
+ else if (! strcmp (prop_spec->name, "mypaint-brush-path"))
+ {
+ gchar *path = g_strdup_printf ("@mypaint_brushes_dir@%s"
+ "~/.mypaint/brushes",
+ G_SEARCHPATH_SEPARATOR_S);
+
+ gimp_config_writer_open (writer, "mypaint-brush-path");
+ gimp_config_writer_string (writer, path);
+ gimp_config_writer_close (writer);
+
+ g_free (path);
+
+ success = TRUE;
+ }
+ else
+ {
+ success = gimp_config_serialize_property (rc, prop_spec, writer);
+ }
+
+ if (success)
+ {
+ g_output_stream_printf (output, NULL, NULL, NULL,
+ "\n");
+
+ desc = dump_describe_param (prop_spec);
+
+ dump_with_linebreaks (output, desc);
+
+ g_output_stream_printf (output, NULL, NULL, NULL,
+ "\n");
+
+ g_free (desc);
+ }
+ }
+
+ g_free (property_specs);
+
+ g_output_stream_printf (output, NULL, NULL, NULL,
+ "%s", man_page_path);
+ g_output_stream_printf (output, NULL, NULL, NULL,
+ "%s", man_page_footer);
+}
+
+
+static const gchar display_format_description[] =
+"This is a format string; certain % character sequences are recognised and "
+"expanded as follows:\n"
+"\n"
+"%% literal percent sign\n"
+"%f bare filename, or \"Untitled\"\n"
+"%F full path to file, or \"Untitled\"\n"
+"%p PDB image id\n"
+"%i view instance number\n"
+"%t image type (RGB, grayscale, indexed)\n"
+"%z zoom factor as a percentage\n"
+"%s source scale factor\n"
+"%d destination scale factor\n"
+"%Dx expands to x if the image is dirty, the empty string otherwise\n"
+"%Cx expands to x if the image is clean, the empty string otherwise\n"
+"%B expands to (modified) if the image is dirty, the empty string otherwise\n"
+"%A expands to (clean) if the image is clean, the empty string otherwise\n"
+"%Nx expands to x if the image is export-dirty, the empty string otherwise\n"
+"%Ex expands to x if the image is export-clean, the empty string otherwise\n"
+"%l the number of layers\n"
+"%L the number of layers (long form)\n"
+"%m memory used by the image\n"
+"%n the name of the active layer/channel\n"
+"%P the PDB id of the active layer/channel\n"
+"%w image width in pixels\n"
+"%W image width in real-world units\n"
+"%h image height in pixels\n"
+"%H image height in real-world units\n"
+"%M the image size expressed in megapixels\n"
+"%u unit symbol\n"
+"%U unit abbreviation\n"
+"%x the width of the active layer/channel in pixels\n"
+"%X the width of the active layer/channel in real-world units\n"
+"%y the height of the active layer/channel in pixels\n"
+"%Y the height of the active layer/channel in real-world units\n"
+"%o the name of the image's color profile\n\n";
+
+
+static gchar *
+dump_describe_param (GParamSpec *param_spec)
+{
+ const gchar *blurb = g_param_spec_get_blurb (param_spec);
+ const gchar *values = NULL;
+
+ if (!blurb)
+ {
+ g_warning ("FIXME: Property '%s' has no blurb.", param_spec->name);
+
+ blurb = g_strdup_printf ("The %s property has no description.",
+ param_spec->name);
+ }
+
+ if (GIMP_IS_PARAM_SPEC_RGB (param_spec))
+ {
+ if (gimp_param_spec_rgb_has_alpha (param_spec))
+ values =
+ "The color is specified in the form (color-rgba red green blue "
+ "alpha) with channel values as floats in the range of 0.0 to 1.0.";
+ else
+ values =
+ "The color is specified in the form (color-rgb red green blue) "
+ "with channel values as floats in the range of 0.0 to 1.0.";
+ }
+ else if (GIMP_IS_PARAM_SPEC_MEMSIZE (param_spec))
+ {
+ values =
+ "The integer size can contain a suffix of 'B', 'K', 'M' or 'G' which "
+ "makes GIMP interpret the size as being specified in bytes, kilobytes, "
+ "megabytes or gigabytes. If no suffix is specified the size defaults "
+ "to being specified in kilobytes.";
+ }
+ else if (GIMP_IS_PARAM_SPEC_CONFIG_PATH (param_spec))
+ {
+ switch (gimp_param_spec_config_path_type (param_spec))
+ {
+ case GIMP_CONFIG_PATH_FILE:
+ values = "This is a single filename.";
+ break;
+
+ case GIMP_CONFIG_PATH_FILE_LIST:
+ switch (G_SEARCHPATH_SEPARATOR)
+ {
+ case ':':
+ values = "This is a colon-separated list of files.";
+ break;
+ case ';':
+ values = "This is a semicolon-separated list of files.";
+ break;
+ default:
+ g_warning ("unhandled G_SEARCHPATH_SEPARATOR value");
+ break;
+ }
+ break;
+
+ case GIMP_CONFIG_PATH_DIR:
+ values = "This is a single folder.";
+ break;
+
+ case GIMP_CONFIG_PATH_DIR_LIST:
+ switch (G_SEARCHPATH_SEPARATOR)
+ {
+ case ':':
+ values = "This is a colon-separated list of folders to search.";
+ break;
+ case ';':
+ values = "This is a semicolon-separated list of folders to search.";
+ break;
+ default:
+ g_warning ("unhandled G_SEARCHPATH_SEPARATOR value");
+ break;
+ }
+ break;
+ }
+ }
+ else if (GIMP_IS_PARAM_SPEC_UNIT (param_spec))
+ {
+ values =
+ "The unit can be one inches, millimeters, points or picas plus "
+ "those in your user units database.";
+ }
+ else if (g_type_is_a (param_spec->value_type, GIMP_TYPE_CONFIG))
+ {
+ values = "This is a parameter list.";
+ }
+ else
+ {
+ switch (G_TYPE_FUNDAMENTAL (param_spec->value_type))
+ {
+ case G_TYPE_BOOLEAN:
+ values = "Possible values are yes and no.";
+ break;
+ case G_TYPE_INT:
+ case G_TYPE_UINT:
+ case G_TYPE_LONG:
+ case G_TYPE_ULONG:
+ values = "This is an integer value.";
+ break;
+ case G_TYPE_FLOAT:
+ case G_TYPE_DOUBLE:
+ values = "This is a float value.";
+ break;
+ case G_TYPE_STRING:
+ /* eek */
+ if (strcmp (g_param_spec_get_name (param_spec), "image-title-format")
+ &&
+ strcmp (g_param_spec_get_name (param_spec), "image-status-format"))
+ {
+ values = "This is a string value.";
+ }
+ else
+ {
+ values = display_format_description;
+ }
+ break;
+ case G_TYPE_ENUM:
+ {
+ GEnumClass *enum_class;
+ GEnumValue *enum_value;
+ GString *str;
+ gint i;
+
+ enum_class = g_type_class_peek (param_spec->value_type);
+
+ str = g_string_new (blurb);
+
+ g_string_append (str, " Possible values are ");
+
+ for (i = 0, enum_value = enum_class->values;
+ i < enum_class->n_values;
+ i++, enum_value++)
+ {
+ g_string_append (str, enum_value->value_nick);
+
+ switch (enum_class->n_values - i)
+ {
+ case 1:
+ g_string_append_c (str, '.');
+ break;
+ case 2:
+ g_string_append (str, " and ");
+ break;
+ default:
+ g_string_append (str, ", ");
+ break;
+ }
+ }
+
+ return g_string_free (str, FALSE);
+ }
+ break;
+ default:
+ break;
+ }
+ }
+
+ if (!values)
+ g_warning ("FIXME: Can't tell anything about a %s.",
+ g_type_name (param_spec->value_type));
+
+ if (strcmp (blurb, "") == 0)
+ return g_strdup_printf ("%s", values);
+ else
+ return g_strdup_printf ("%s %s", blurb, values);
+}
+
+
+#define LINE_LENGTH 78
+
+static void
+dump_with_linebreaks (GOutputStream *output,
+ const gchar *text)
+{
+ gint len = strlen (text);
+
+ while (len > 0)
+ {
+ const gchar *t;
+ gint i, space;
+
+ /* groff doesn't like lines to start with a single quote */
+ if (*text == '\'')
+ g_output_stream_printf (output, NULL, NULL, NULL,
+ "\\&"); /* a zero width space */
+
+ for (t = text, i = 0, space = 0;
+ *t != '\n' && (i <= LINE_LENGTH || space == 0) && i < len;
+ t++, i++)
+ {
+ if (g_ascii_isspace (*t))
+ space = i;
+ }
+
+ if (i > LINE_LENGTH && space && *t != '\n')
+ i = space;
+
+ g_output_stream_write_all (output, text, i, NULL, NULL, NULL);
+ g_output_stream_printf (output, NULL, NULL, NULL,
+ "\n");
+
+ if (*t == '\n')
+ g_output_stream_printf (output, NULL, NULL, NULL,
+ ".br\n");
+
+ i++;
+
+ text += i;
+ len -= i;
+ }
+}
diff --git a/app/config/gimpconfig-dump.h b/app/config/gimpconfig-dump.h
new file mode 100644
index 0000000..ead2da3
--- /dev/null
+++ b/app/config/gimpconfig-dump.h
@@ -0,0 +1,37 @@
+/* GIMP - The GNU Image Manipulation Program
+ * Copyright (C) 1995-1997 Spencer Kimball and Peter Mattis
+ *
+ * Copyright (C) 2003 Sven Neumann <sven@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_CONFIG_DUMP_H__
+#define __GIMP_CONFIG_DUMP_H__
+
+
+typedef enum
+{
+ GIMP_CONFIG_DUMP_NONE,
+ GIMP_CONFIG_DUMP_GIMPRC,
+ GIMP_CONFIG_DUMP_GIMPRC_SYSTEM,
+ GIMP_CONFIG_DUMP_GIMPRC_MANPAGE
+} GimpConfigDumpFormat;
+
+
+gboolean gimp_config_dump (GObject *gimp,
+ GimpConfigDumpFormat format);
+
+
+#endif /* __GIMP_CONFIG_DUMP_H__ */
diff --git a/app/config/gimpconfig-file.c b/app/config/gimpconfig-file.c
new file mode 100644
index 0000000..9823b8f
--- /dev/null
+++ b/app/config/gimpconfig-file.c
@@ -0,0 +1,241 @@
+/* GIMP - The GNU Image Manipulation Program
+ * Copyright (C) 1995-1997 Spencer Kimball and Peter Mattis
+ *
+ * File Utitility functions for GimpConfig.
+ * Copyright (C) 2001-2003 Sven Neumann <sven@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/>.
+ */
+
+#include "config.h"
+
+#include <errno.h>
+#include <sys/types.h>
+
+#include <gio/gio.h>
+#include <glib/gstdio.h>
+
+#include "libgimpbase/gimpbase.h"
+#include "libgimpconfig/gimpconfig.h"
+
+#ifdef G_OS_WIN32
+#include "libgimpbase/gimpwin32-io.h"
+#endif
+
+#include "config-types.h"
+
+#include "gimpconfig-file.h"
+
+#include "gimp-intl.h"
+
+
+gboolean
+gimp_config_file_copy (const gchar *source,
+ const gchar *dest,
+ const gchar *old_options_pattern,
+ GRegexEvalCallback update_callback,
+ GError **error)
+{
+ gchar buffer[8192];
+ FILE *sfile;
+ FILE *dfile;
+ GStatBuf stat_buf;
+ gint nbytes;
+ gint unwritten_len = 0;
+ GRegex *old_options_regexp = NULL;
+
+ if (old_options_pattern && update_callback)
+ {
+ old_options_regexp = g_regex_new (old_options_pattern, 0, 0, error);
+
+ /* error set by g_regex_new. */
+ if (! old_options_regexp)
+ return FALSE;
+ }
+
+ sfile = g_fopen (source, "rb");
+ if (sfile == NULL)
+ {
+ g_set_error (error, G_FILE_ERROR, g_file_error_from_errno (errno),
+ _("Could not open '%s' for reading: %s"),
+ gimp_filename_to_utf8 (source), g_strerror (errno));
+ if (old_options_regexp)
+ g_regex_unref (old_options_regexp);
+ return FALSE;
+ }
+
+ dfile = g_fopen (dest, "wb");
+ if (dfile == NULL)
+ {
+ g_set_error (error, G_FILE_ERROR, g_file_error_from_errno (errno),
+ _("Could not open '%s' for writing: %s"),
+ gimp_filename_to_utf8 (dest), g_strerror (errno));
+ fclose (sfile);
+ if (old_options_regexp)
+ g_regex_unref (old_options_regexp);
+ return FALSE;
+ }
+
+ while ((nbytes = fread (buffer + unwritten_len, 1,
+ sizeof (buffer) - unwritten_len, sfile)) > 0 || unwritten_len)
+ {
+ size_t read_len = nbytes + unwritten_len;
+ size_t write_len;
+ gchar* eol = NULL;
+ gchar* write_bytes = NULL;
+
+ if (old_options_regexp && update_callback)
+ {
+ eol = g_strrstr_len (buffer, read_len, "\n");
+ if (eol)
+ {
+ *eol = '\0';
+ read_len = strlen (buffer) + 1;
+ *eol++ = '\n';
+ }
+ else if (! feof (sfile))
+ {
+ gchar format[256];
+
+ /* We are in unlikely case where a single config line is
+ * longer than the buffer!
+ */
+
+ g_snprintf (format, sizeof (format),
+ _("Error parsing '%%s': line longer than %s characters."),
+ G_GINT64_FORMAT);
+
+ g_set_error (error, GIMP_CONFIG_ERROR, GIMP_CONFIG_ERROR_PARSE,
+ format,
+ gimp_filename_to_utf8 (source),
+ (gint64) sizeof (buffer));
+
+ fclose (sfile);
+ fclose (dfile);
+ g_regex_unref (old_options_regexp);
+ return FALSE;
+ }
+
+ write_bytes = g_regex_replace_eval (old_options_regexp, buffer,
+ read_len, 0, 0, update_callback,
+ NULL, error);
+ if (write_bytes == NULL)
+ {
+ /* error already set. */
+ fclose (sfile);
+ fclose (dfile);
+ g_regex_unref (old_options_regexp);
+ return FALSE;
+ }
+ write_len = strlen (write_bytes);
+ }
+ else
+ {
+ write_bytes = buffer;
+ write_len = read_len;
+ }
+
+ if (fwrite (write_bytes, 1, write_len, dfile) < write_len)
+ {
+ g_set_error (error, G_FILE_ERROR, g_file_error_from_errno (errno),
+ _("Error writing '%s': %s"),
+ gimp_filename_to_utf8 (dest), g_strerror (errno));
+ if (old_options_regexp && update_callback)
+ {
+ g_free (write_bytes);
+ g_regex_unref (old_options_regexp);
+ }
+ fclose (sfile);
+ fclose (dfile);
+ return FALSE;
+ }
+
+ if (old_options_regexp && update_callback)
+ {
+ g_free (write_bytes);
+
+ if (eol)
+ {
+ unwritten_len = nbytes + unwritten_len - read_len;
+ memmove (buffer, eol, unwritten_len);
+ }
+ else
+ /* EOF */
+ break;
+ }
+ }
+
+ if (ferror (sfile))
+ {
+ g_set_error (error, G_FILE_ERROR, g_file_error_from_errno (errno),
+ _("Error reading '%s': %s"),
+ gimp_filename_to_utf8 (source), g_strerror (errno));
+ fclose (sfile);
+ fclose (dfile);
+ if (old_options_regexp)
+ g_regex_unref (old_options_regexp);
+ return FALSE;
+ }
+
+ fclose (sfile);
+
+ if (fclose (dfile) == EOF)
+ {
+ g_set_error (error, G_FILE_ERROR, g_file_error_from_errno (errno),
+ _("Error writing '%s': %s"),
+ gimp_filename_to_utf8 (dest), g_strerror (errno));
+ if (old_options_regexp)
+ g_regex_unref (old_options_regexp);
+ return FALSE;
+ }
+
+ if (g_stat (source, &stat_buf) == 0)
+ {
+ g_chmod (dest, stat_buf.st_mode);
+ }
+
+ if (old_options_regexp)
+ g_regex_unref (old_options_regexp);
+ return TRUE;
+}
+
+gboolean
+gimp_config_file_backup_on_error (GFile *file,
+ const gchar *name,
+ GError **error)
+{
+ gchar *path;
+ gchar *backup;
+ gboolean success;
+
+ g_return_val_if_fail (G_IS_FILE (file), FALSE);
+ g_return_val_if_fail (name != NULL, FALSE);
+ g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
+
+ path = g_file_get_path (file);
+ backup = g_strconcat (path, "~", NULL);
+
+ success = gimp_config_file_copy (path, backup, NULL, NULL, error);
+
+ if (success)
+ g_message (_("There was an error parsing your '%s' file. "
+ "Default values will be used. A backup of your "
+ "configuration has been created at '%s'."),
+ name, gimp_filename_to_utf8 (backup));
+
+ g_free (backup);
+ g_free (path);
+
+ return success;
+}
diff --git a/app/config/gimpconfig-file.h b/app/config/gimpconfig-file.h
new file mode 100644
index 0000000..fc61886
--- /dev/null
+++ b/app/config/gimpconfig-file.h
@@ -0,0 +1,36 @@
+/* GIMP - The GNU Image Manipulation Program
+ * Copyright (C) 1995-1997 Spencer Kimball and Peter Mattis
+ *
+ * File utitility functions for GimpConfig.
+ * Copyright (C) 2001-2003 Sven Neumann <sven@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_CONFIG_FILE_H__
+#define __GIMP_CONFIG_FILE_H__
+
+
+gboolean gimp_config_file_copy (const gchar *source,
+ const gchar *dest,
+ const gchar *old_options_regexp,
+ GRegexEvalCallback update_callback,
+ GError **error);
+
+gboolean gimp_config_file_backup_on_error (GFile *file,
+ const gchar *name,
+ GError **error);
+
+
+#endif /* __GIMP_CONFIG_FILE_H__ */
diff --git a/app/config/gimpconfig-utils.c b/app/config/gimpconfig-utils.c
new file mode 100644
index 0000000..fbe08d3
--- /dev/null
+++ b/app/config/gimpconfig-utils.c
@@ -0,0 +1,223 @@
+/* GIMP - The GNU Image Manipulation Program
+ * Copyright (C) 1995-1997 Spencer Kimball and Peter Mattis
+ *
+ * Utitility functions for GimpConfig.
+ * Copyright (C) 2001-2003 Sven Neumann <sven@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/>.
+ */
+
+#include "config.h"
+
+#include <gio/gio.h>
+
+#include "libgimpbase/gimpbase.h"
+#include "libgimpconfig/gimpconfig.h"
+
+#include "config-types.h"
+
+#include "gimpconfig-utils.h"
+
+
+static void
+gimp_config_connect_notify (GObject *src,
+ GParamSpec *param_spec,
+ GObject *dest)
+{
+ if (param_spec->flags & G_PARAM_READABLE)
+ {
+ GParamSpec *dest_spec;
+
+ dest_spec = g_object_class_find_property (G_OBJECT_GET_CLASS (dest),
+ param_spec->name);
+
+ if (dest_spec &&
+ (dest_spec->value_type == param_spec->value_type) &&
+ (dest_spec->flags & G_PARAM_WRITABLE) &&
+ (dest_spec->flags & G_PARAM_CONSTRUCT_ONLY) == 0)
+ {
+ GValue value = G_VALUE_INIT;
+
+ g_value_init (&value, param_spec->value_type);
+
+ g_object_get_property (src, param_spec->name, &value);
+
+ g_signal_handlers_block_by_func (dest,
+ gimp_config_connect_notify, src);
+ g_object_set_property (dest, param_spec->name, &value);
+ g_signal_handlers_unblock_by_func (dest,
+ gimp_config_connect_notify, src);
+
+ g_value_unset (&value);
+ }
+ }
+}
+
+/**
+ * gimp_config_connect:
+ * @a: a #GObject
+ * @b: another #GObject
+ * @property_name: the name of a property to connect or %NULL for all
+ *
+ * Connects the two object @a and @b in a way that property changes of
+ * one are propagated to the other. This is a two-way connection.
+ *
+ * If @property_name is %NULL the connection is setup for all
+ * properties. It is not required that @a and @b are of the same type.
+ * Only changes on properties that exist in both object classes and
+ * are of the same value_type are propagated.
+ **/
+void
+gimp_config_connect (GObject *a,
+ GObject *b,
+ const gchar *property_name)
+{
+ gchar *signal_name;
+
+ g_return_if_fail (a != b);
+ g_return_if_fail (G_IS_OBJECT (a) && G_IS_OBJECT (b));
+
+ if (property_name)
+ signal_name = g_strconcat ("notify::", property_name, NULL);
+ else
+ signal_name = "notify";
+
+ g_signal_connect_object (a, signal_name,
+ G_CALLBACK (gimp_config_connect_notify),
+ b, 0);
+ g_signal_connect_object (b, signal_name,
+ G_CALLBACK (gimp_config_connect_notify),
+ a, 0);
+
+ if (property_name)
+ g_free (signal_name);
+}
+
+static void
+gimp_config_connect_full_notify (GObject *src,
+ GParamSpec *param_spec,
+ GObject *dest)
+{
+ if (param_spec->flags & G_PARAM_READABLE)
+ {
+ gchar *attach_key;
+ gchar *dest_prop_name;
+ GParamSpec *dest_spec = NULL;
+
+ attach_key = g_strdup_printf ("%p-%s", dest, param_spec->name);
+ dest_prop_name = g_object_get_data (src, attach_key);
+ g_free (attach_key);
+
+ if (dest_prop_name)
+ dest_spec = g_object_class_find_property (G_OBJECT_GET_CLASS (dest),
+ dest_prop_name);
+
+ if (dest_spec &&
+ (dest_spec->value_type == param_spec->value_type) &&
+ (dest_spec->flags & G_PARAM_WRITABLE) &&
+ (dest_spec->flags & G_PARAM_CONSTRUCT_ONLY) == 0)
+ {
+ GValue value = G_VALUE_INIT;
+
+ g_value_init (&value, param_spec->value_type);
+
+ g_object_get_property (src, param_spec->name, &value);
+
+ g_signal_handlers_block_by_func (dest,
+ gimp_config_connect_full_notify, src);
+ g_object_set_property (dest, dest_prop_name, &value);
+ g_signal_handlers_unblock_by_func (dest,
+ gimp_config_connect_full_notify, src);
+
+ g_value_unset (&value);
+ }
+ }
+}
+
+/**
+ * gimp_config_connect_full:
+ * @a: a #GObject
+ * @b: another #GObject
+ * @property_name_a: the name of a property of @a to connect
+ * @property_name_b: the name of a property of @b to connect
+ *
+ * Connects the two object @a and @b in a way that property changes of
+ * one are propagated to the other. This is a two-way connection.
+ *
+ * If @property_name is %NULL the connection is setup for all
+ * properties. It is not required that @a and @b are of the same type.
+ * Only changes on properties that exist in both object classes and
+ * are of the same value_type are propagated.
+ **/
+void
+gimp_config_connect_full (GObject *a,
+ GObject *b,
+ const gchar *property_name_a,
+ const gchar *property_name_b)
+{
+ gchar *signal_name;
+ gchar *attach_key;
+
+ g_return_if_fail (a != b);
+ g_return_if_fail (G_IS_OBJECT (a) && G_IS_OBJECT (b));
+ g_return_if_fail (property_name_a != NULL);
+ g_return_if_fail (property_name_b != NULL);
+
+ signal_name = g_strconcat ("notify::", property_name_a, NULL);
+ attach_key = g_strdup_printf ("%p-%s", b, property_name_a);
+
+ g_signal_connect_object (a, signal_name,
+ G_CALLBACK (gimp_config_connect_full_notify),
+ b, 0);
+ g_object_set_data_full (a, attach_key, g_strdup (property_name_b),
+ (GDestroyNotify) g_free);
+
+ g_free (signal_name);
+ g_free (attach_key);
+
+ signal_name = g_strconcat ("notify::", property_name_b, NULL);
+ attach_key = g_strdup_printf ("%p-%s", a, property_name_b);
+
+ g_signal_connect_object (b, signal_name,
+ G_CALLBACK (gimp_config_connect_full_notify),
+ a, 0);
+ g_object_set_data_full (b, attach_key, g_strdup (property_name_a),
+ (GDestroyNotify) g_free);
+
+ g_free (signal_name);
+ g_free (attach_key);
+}
+
+/**
+ * gimp_config_disconnect:
+ * @a: a #GObject
+ * @b: another #GObject
+ *
+ * Removes a connection between @dest and @src that was previously set
+ * up using gimp_config_connect().
+ **/
+void
+gimp_config_disconnect (GObject *a,
+ GObject *b)
+{
+ g_return_if_fail (G_IS_OBJECT (a) && G_IS_OBJECT (b));
+
+ g_signal_handlers_disconnect_by_func (b,
+ G_CALLBACK (gimp_config_connect_notify),
+ a);
+ g_signal_handlers_disconnect_by_func (a,
+ G_CALLBACK (gimp_config_connect_notify),
+ b);
+}
+
diff --git a/app/config/gimpconfig-utils.h b/app/config/gimpconfig-utils.h
new file mode 100644
index 0000000..7928ca9
--- /dev/null
+++ b/app/config/gimpconfig-utils.h
@@ -0,0 +1,36 @@
+/* GIMP - The GNU Image Manipulation Program
+ * Copyright (C) 1995-1997 Spencer Kimball and Peter Mattis
+ *
+ * Utitility functions for GimpConfig.
+ * Copyright (C) 2001-2003 Sven Neumann <sven@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 __APP_GIMP_CONFIG_UTILS_H__
+#define __APP_GIMP_CONFIG_UTILS_H__
+
+
+void gimp_config_connect (GObject *a,
+ GObject *b,
+ const gchar *property_name);
+void gimp_config_connect_full (GObject *a,
+ GObject *b,
+ const gchar *property_name_a,
+ const gchar *property_name_b);
+void gimp_config_disconnect (GObject *a,
+ GObject *b);
+
+
+#endif /* __APP_GIMP_CONFIG_UTILS_H__ */
diff --git a/app/config/gimpcoreconfig.c b/app/config/gimpcoreconfig.c
new file mode 100644
index 0000000..823e808
--- /dev/null
+++ b/app/config/gimpcoreconfig.c
@@ -0,0 +1,1415 @@
+/* GIMP - The GNU Image Manipulation Program
+ * Copyright (C) 1995 Spencer Kimball and Peter Mattis
+ *
+ * GimpCoreConfig class
+ * Copyright (C) 2001 Sven Neumann <sven@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/>.
+ */
+
+#include "config.h"
+
+#include <cairo.h>
+#include <gegl.h>
+#include <gdk-pixbuf/gdk-pixbuf.h>
+
+#ifdef G_OS_WIN32
+#include <shlobj.h>
+
+/* Constant available since Shell32.dll 5.0 */
+#ifndef CSIDL_LOCAL_APPDATA
+#define CSIDL_LOCAL_APPDATA 0x001c
+#endif
+
+#endif
+
+#include "libgimpbase/gimpbase.h"
+#include "libgimpcolor/gimpcolor.h"
+#include "libgimpconfig/gimpconfig.h"
+
+#include "config-types.h"
+
+#include "core/core-types.h"
+#include "core/gimp-utils.h"
+#include "core/gimpgrid.h"
+#include "core/gimptemplate.h"
+
+#include "gimprc-blurbs.h"
+#include "gimpcoreconfig.h"
+
+#include "gimp-intl.h"
+
+
+#define GIMP_DEFAULT_BRUSH "2. Hardness 050"
+#define GIMP_DEFAULT_DYNAMICS "Dynamics Off"
+#define GIMP_DEFAULT_PATTERN "Pine"
+#define GIMP_DEFAULT_PALETTE "Default"
+#define GIMP_DEFAULT_GRADIENT "FG to BG (RGB)"
+#define GIMP_DEFAULT_TOOL_PRESET "Current Options"
+#define GIMP_DEFAULT_FONT "Sans-serif"
+#define GIMP_DEFAULT_MYPAINT_BRUSH "Fixme"
+#define GIMP_DEFAULT_COMMENT "Created with GIMP"
+
+
+enum
+{
+ PROP_0,
+ PROP_LANGUAGE,
+ PROP_INTERPOLATION_TYPE,
+ PROP_DEFAULT_THRESHOLD,
+ PROP_PLUG_IN_PATH,
+ PROP_MODULE_PATH,
+ PROP_INTERPRETER_PATH,
+ PROP_ENVIRON_PATH,
+ PROP_BRUSH_PATH,
+ PROP_BRUSH_PATH_WRITABLE,
+ PROP_DYNAMICS_PATH,
+ PROP_DYNAMICS_PATH_WRITABLE,
+ PROP_MYPAINT_BRUSH_PATH,
+ PROP_MYPAINT_BRUSH_PATH_WRITABLE,
+ PROP_PATTERN_PATH,
+ PROP_PATTERN_PATH_WRITABLE,
+ PROP_PALETTE_PATH,
+ PROP_PALETTE_PATH_WRITABLE,
+ PROP_GRADIENT_PATH,
+ PROP_GRADIENT_PATH_WRITABLE,
+ PROP_TOOL_PRESET_PATH,
+ PROP_TOOL_PRESET_PATH_WRITABLE,
+ PROP_FONT_PATH,
+ PROP_FONT_PATH_WRITABLE,
+ PROP_DEFAULT_BRUSH,
+ PROP_DEFAULT_DYNAMICS,
+ PROP_DEFAULT_MYPAINT_BRUSH,
+ PROP_DEFAULT_PATTERN,
+ PROP_DEFAULT_PALETTE,
+ PROP_DEFAULT_GRADIENT,
+ PROP_DEFAULT_TOOL_PRESET,
+ PROP_DEFAULT_FONT,
+ PROP_GLOBAL_BRUSH,
+ PROP_GLOBAL_DYNAMICS,
+ PROP_GLOBAL_PATTERN,
+ PROP_GLOBAL_PALETTE,
+ PROP_GLOBAL_GRADIENT,
+ PROP_GLOBAL_FONT,
+ PROP_DEFAULT_IMAGE,
+ PROP_DEFAULT_GRID,
+ PROP_UNDO_LEVELS,
+ PROP_UNDO_SIZE,
+ PROP_UNDO_PREVIEW_SIZE,
+ PROP_FILTER_HISTORY_SIZE,
+ PROP_PLUGINRC_PATH,
+ PROP_LAYER_PREVIEWS,
+ PROP_GROUP_LAYER_PREVIEWS,
+ PROP_LAYER_PREVIEW_SIZE,
+ PROP_THUMBNAIL_SIZE,
+ PROP_THUMBNAIL_FILESIZE_LIMIT,
+ PROP_COLOR_MANAGEMENT,
+ PROP_SAVE_DOCUMENT_HISTORY,
+ PROP_QUICK_MASK_COLOR,
+ PROP_IMPORT_PROMOTE_FLOAT,
+ PROP_IMPORT_PROMOTE_DITHER,
+ PROP_IMPORT_ADD_ALPHA,
+ PROP_IMPORT_RAW_PLUG_IN,
+ PROP_EXPORT_FILE_TYPE,
+ PROP_EXPORT_COLOR_PROFILE,
+ PROP_EXPORT_METADATA_EXIF,
+ PROP_EXPORT_METADATA_XMP,
+ PROP_EXPORT_METADATA_IPTC,
+ PROP_DEBUG_POLICY,
+ PROP_CHECK_UPDATES,
+ PROP_CHECK_UPDATE_TIMESTAMP,
+ PROP_LAST_RELEASE_TIMESTAMP,
+ PROP_LAST_RELEASE_COMMENT,
+ PROP_LAST_REVISION,
+ PROP_LAST_KNOWN_RELEASE,
+
+ /* ignored, only for backward compatibility: */
+ PROP_INSTALL_COLORMAP,
+ PROP_MIN_COLORS
+};
+
+
+static void gimp_core_config_finalize (GObject *object);
+static void gimp_core_config_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec);
+static void gimp_core_config_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec);
+static void gimp_core_config_default_image_notify (GObject *object,
+ GParamSpec *pspec,
+ gpointer data);
+static void gimp_core_config_default_grid_notify (GObject *object,
+ GParamSpec *pspec,
+ gpointer data);
+static void gimp_core_config_color_management_notify (GObject *object,
+ GParamSpec *pspec,
+ gpointer data);
+
+
+G_DEFINE_TYPE (GimpCoreConfig, gimp_core_config, GIMP_TYPE_GEGL_CONFIG)
+
+#define parent_class gimp_core_config_parent_class
+
+#ifdef G_OS_WIN32
+/*
+ * Taken from glib 2.35 code / gimpenv.c.
+ * Only temporary until the user-font folder detection can go upstream
+ * in fontconfig!
+ * XXX
+ */
+static gchar *
+get_special_folder (int csidl)
+{
+ wchar_t path[MAX_PATH+1];
+ HRESULT hr;
+ LPITEMIDLIST pidl = NULL;
+ BOOL b;
+ gchar *retval = NULL;
+
+ hr = SHGetSpecialFolderLocation (NULL, csidl, &pidl);
+ if (hr == S_OK)
+ {
+ b = SHGetPathFromIDListW (pidl, path);
+ if (b)
+ retval = g_utf16_to_utf8 (path, -1, NULL, NULL, NULL);
+ CoTaskMemFree (pidl);
+ }
+
+ return retval;
+}
+#endif
+
+static void
+gimp_core_config_class_init (GimpCoreConfigClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+ gchar *path;
+ gchar *mypaint_brushes;
+ GimpRGB red = { 1.0, 0, 0, 0.5 };
+ guint64 undo_size;
+
+ object_class->finalize = gimp_core_config_finalize;
+ object_class->set_property = gimp_core_config_set_property;
+ object_class->get_property = gimp_core_config_get_property;
+
+ GIMP_CONFIG_PROP_STRING (object_class, PROP_LANGUAGE,
+ "language",
+ "Language",
+ LANGUAGE_BLURB,
+ NULL, /* take from environment */
+ GIMP_PARAM_STATIC_STRINGS |
+ GIMP_CONFIG_PARAM_RESTART);
+
+ GIMP_CONFIG_PROP_ENUM (object_class, PROP_INTERPOLATION_TYPE,
+ "interpolation-type",
+ "Interpolation",
+ INTERPOLATION_TYPE_BLURB,
+ GIMP_TYPE_INTERPOLATION_TYPE,
+ GIMP_INTERPOLATION_CUBIC,
+ GIMP_PARAM_STATIC_STRINGS);
+
+ GIMP_CONFIG_PROP_INT (object_class, PROP_DEFAULT_THRESHOLD,
+ "default-threshold",
+ "Default threshold",
+ DEFAULT_THRESHOLD_BLURB,
+ 0, 255, 15,
+ GIMP_PARAM_STATIC_STRINGS);
+
+ path = gimp_config_build_plug_in_path ("plug-ins");
+ GIMP_CONFIG_PROP_PATH (object_class, PROP_PLUG_IN_PATH,
+ "plug-in-path",
+ "Plug-in path",
+ PLUG_IN_PATH_BLURB,
+ GIMP_CONFIG_PATH_DIR_LIST, path,
+ GIMP_PARAM_STATIC_STRINGS |
+ GIMP_CONFIG_PARAM_RESTART);
+ g_free (path);
+
+ path = gimp_config_build_plug_in_path ("modules");
+ GIMP_CONFIG_PROP_PATH (object_class, PROP_MODULE_PATH,
+ "module-path",
+ "Module path",
+ MODULE_PATH_BLURB,
+ GIMP_CONFIG_PATH_DIR_LIST, path,
+ GIMP_PARAM_STATIC_STRINGS |
+ GIMP_CONFIG_PARAM_RESTART);
+ g_free (path);
+
+ path = gimp_config_build_plug_in_path ("interpreters");
+ GIMP_CONFIG_PROP_PATH (object_class, PROP_INTERPRETER_PATH,
+ "interpreter-path",
+ "Interpreter path",
+ INTERPRETER_PATH_BLURB,
+ GIMP_CONFIG_PATH_DIR_LIST, path,
+ GIMP_PARAM_STATIC_STRINGS |
+ GIMP_CONFIG_PARAM_RESTART);
+ g_free (path);
+
+ path = gimp_config_build_plug_in_path ("environ");
+ GIMP_CONFIG_PROP_PATH (object_class, PROP_ENVIRON_PATH,
+ "environ-path",
+ "Environment path",
+ ENVIRON_PATH_BLURB,
+ GIMP_CONFIG_PATH_DIR_LIST, path,
+ GIMP_PARAM_STATIC_STRINGS |
+ GIMP_CONFIG_PARAM_RESTART);
+ g_free (path);
+
+ path = gimp_config_build_data_path ("brushes");
+ GIMP_CONFIG_PROP_PATH (object_class, PROP_BRUSH_PATH,
+ "brush-path",
+ "Brush path",
+ BRUSH_PATH_BLURB,
+ GIMP_CONFIG_PATH_DIR_LIST, path,
+ GIMP_PARAM_STATIC_STRINGS |
+ GIMP_CONFIG_PARAM_CONFIRM);
+ g_free (path);
+
+ path = gimp_config_build_writable_path ("brushes");
+ GIMP_CONFIG_PROP_PATH (object_class, PROP_BRUSH_PATH_WRITABLE,
+ "brush-path-writable",
+ "Writable brush path",
+ BRUSH_PATH_WRITABLE_BLURB,
+ GIMP_CONFIG_PATH_DIR_LIST, path,
+ GIMP_PARAM_STATIC_STRINGS |
+ GIMP_CONFIG_PARAM_CONFIRM);
+ g_free (path);
+
+ path = gimp_config_build_data_path ("dynamics");
+ GIMP_CONFIG_PROP_PATH (object_class, PROP_DYNAMICS_PATH,
+ "dynamics-path",
+ "Dynamics path",
+ DYNAMICS_PATH_BLURB,
+ GIMP_CONFIG_PATH_DIR_LIST, path,
+ GIMP_PARAM_STATIC_STRINGS |
+ GIMP_CONFIG_PARAM_CONFIRM);
+ g_free (path);
+
+ path = gimp_config_build_writable_path ("dynamics");
+ GIMP_CONFIG_PROP_PATH (object_class, PROP_DYNAMICS_PATH_WRITABLE,
+ "dynamics-path-writable",
+ "Writable dynamics path",
+ DYNAMICS_PATH_WRITABLE_BLURB,
+ GIMP_CONFIG_PATH_DIR_LIST, path,
+ GIMP_PARAM_STATIC_STRINGS |
+ GIMP_CONFIG_PARAM_CONFIRM);
+ g_free (path);
+
+#ifdef ENABLE_RELOCATABLE_RESOURCES
+ mypaint_brushes = g_build_filename ("${gimp_installation_dir}",
+ "share", "mypaint-data",
+ "1.0", "brushes", NULL);
+#else
+ mypaint_brushes = g_strdup (MYPAINT_BRUSHES_DIR);
+#endif
+
+ path = g_build_path (G_SEARCHPATH_SEPARATOR_S,
+ "~/.mypaint/brushes",
+ mypaint_brushes,
+ NULL);
+ g_free (mypaint_brushes);
+
+ GIMP_CONFIG_PROP_PATH (object_class, PROP_MYPAINT_BRUSH_PATH,
+ "mypaint-brush-path",
+ "MyPaint brush path",
+ MYPAINT_BRUSH_PATH_BLURB,
+ GIMP_CONFIG_PATH_DIR_LIST, path,
+ GIMP_PARAM_STATIC_STRINGS |
+ GIMP_CONFIG_PARAM_CONFIRM);
+ g_free (path);
+
+ path = g_build_path (G_SEARCHPATH_SEPARATOR_S,
+ "~/.mypaint/brushes",
+ NULL);
+ GIMP_CONFIG_PROP_PATH (object_class, PROP_MYPAINT_BRUSH_PATH_WRITABLE,
+ "mypaint-brush-path-writable",
+ "Writable MyPaint brush path",
+ MYPAINT_BRUSH_PATH_WRITABLE_BLURB,
+ GIMP_CONFIG_PATH_DIR_LIST, path,
+ GIMP_PARAM_STATIC_STRINGS |
+ GIMP_CONFIG_PARAM_CONFIRM);
+ g_free (path);
+
+ path = gimp_config_build_data_path ("patterns");
+ GIMP_CONFIG_PROP_PATH (object_class, PROP_PATTERN_PATH,
+ "pattern-path",
+ "Pattern path",
+ PATTERN_PATH_BLURB,
+ GIMP_CONFIG_PATH_DIR_LIST, path,
+ GIMP_PARAM_STATIC_STRINGS |
+ GIMP_CONFIG_PARAM_CONFIRM);
+ g_free (path);
+
+ path = gimp_config_build_writable_path ("patterns");
+ GIMP_CONFIG_PROP_PATH (object_class, PROP_PATTERN_PATH_WRITABLE,
+ "pattern-path-writable",
+ "Writable pattern path",
+ PATTERN_PATH_WRITABLE_BLURB,
+ GIMP_CONFIG_PATH_DIR_LIST, path,
+ GIMP_PARAM_STATIC_STRINGS |
+ GIMP_CONFIG_PARAM_CONFIRM);
+ g_free (path);
+
+ path = gimp_config_build_data_path ("palettes");
+ GIMP_CONFIG_PROP_PATH (object_class, PROP_PALETTE_PATH,
+ "palette-path",
+ "Palette path",
+ PALETTE_PATH_BLURB,
+ GIMP_CONFIG_PATH_DIR_LIST, path,
+ GIMP_PARAM_STATIC_STRINGS |
+ GIMP_CONFIG_PARAM_CONFIRM);
+ g_free (path);
+
+ path = gimp_config_build_writable_path ("palettes");
+ GIMP_CONFIG_PROP_PATH (object_class, PROP_PALETTE_PATH_WRITABLE,
+ "palette-path-writable",
+ "Writable palette path",
+ PALETTE_PATH_WRITABLE_BLURB,
+ GIMP_CONFIG_PATH_DIR_LIST, path,
+ GIMP_PARAM_STATIC_STRINGS |
+ GIMP_CONFIG_PARAM_CONFIRM);
+ g_free (path);
+
+ path = gimp_config_build_data_path ("gradients");
+ GIMP_CONFIG_PROP_PATH (object_class, PROP_GRADIENT_PATH,
+ "gradient-path",
+ "Gradient path",
+ GRADIENT_PATH_BLURB,
+ GIMP_CONFIG_PATH_DIR_LIST, path,
+ GIMP_PARAM_STATIC_STRINGS |
+ GIMP_CONFIG_PARAM_CONFIRM);
+ g_free (path);
+
+ path = gimp_config_build_writable_path ("gradients");
+ GIMP_CONFIG_PROP_PATH (object_class, PROP_GRADIENT_PATH_WRITABLE,
+ "gradient-path-writable",
+ "Writable gradient path",
+ GRADIENT_PATH_WRITABLE_BLURB,
+ GIMP_CONFIG_PATH_DIR_LIST, path,
+ GIMP_PARAM_STATIC_STRINGS |
+ GIMP_CONFIG_PARAM_CONFIRM);
+ g_free (path);
+
+ path = gimp_config_build_data_path ("tool-presets");
+ GIMP_CONFIG_PROP_PATH (object_class, PROP_TOOL_PRESET_PATH,
+ "tool-preset-path",
+ "Tool preset path",
+ TOOL_PRESET_PATH_BLURB,
+ GIMP_CONFIG_PATH_DIR_LIST, path,
+ GIMP_PARAM_STATIC_STRINGS |
+ GIMP_CONFIG_PARAM_CONFIRM);
+ g_free (path);
+
+ path = gimp_config_build_writable_path ("tool-presets");
+ GIMP_CONFIG_PROP_PATH (object_class, PROP_TOOL_PRESET_PATH_WRITABLE,
+ "tool-preset-path-writable",
+ "Writable tool preset path",
+ TOOL_PRESET_PATH_WRITABLE_BLURB,
+ GIMP_CONFIG_PATH_DIR_LIST, path,
+ GIMP_PARAM_STATIC_STRINGS |
+ GIMP_CONFIG_PARAM_CONFIRM);
+ g_free (path);
+
+ path = gimp_config_build_data_path ("fonts");
+#if defined G_OS_WIN32
+ /* XXX: since a Windows 10 update, build 17704, Microsoft added the
+ * concept of user-installed fonts (until now it was only possible to
+ * have system-wide fonts! How weird is that?).
+ * A feature request at fontconfig is also done, but until this gets
+ * implemented upstream, let's add the folder ourselves in GIMP's
+ * default list of folders.
+ * See: https://gitlab.gnome.org/GNOME/gimp/issues/2949
+ * Also: https://gitlab.freedesktop.org/fontconfig/fontconfig/issues/144
+ */
+ {
+ gchar *user_fonts_dir = get_special_folder (CSIDL_LOCAL_APPDATA);
+
+ if (user_fonts_dir)
+ {
+ gchar *path2;
+ gchar *tmp;
+
+ path2 = g_build_filename (user_fonts_dir,
+ "Microsoft", "Windows", "Fonts", NULL);
+ g_free (user_fonts_dir);
+
+ /* G_SEARCHPATH_SEPARATOR-separated list of folders. */
+ tmp = g_strconcat (path2, G_SEARCHPATH_SEPARATOR_S, path, NULL);
+ g_free (path2);
+ g_free (path);
+ path = tmp;
+ }
+ }
+#endif
+ GIMP_CONFIG_PROP_PATH (object_class, PROP_FONT_PATH,
+ "font-path",
+ "Font path",
+ FONT_PATH_BLURB,
+ GIMP_CONFIG_PATH_DIR_LIST, path,
+ GIMP_PARAM_STATIC_STRINGS |
+ GIMP_CONFIG_PARAM_CONFIRM);
+ g_free (path);
+
+ GIMP_CONFIG_PROP_PATH (object_class, PROP_FONT_PATH_WRITABLE,
+ "font-path-writable",
+ "Writable font path",
+ NULL,
+ GIMP_CONFIG_PATH_DIR_LIST, NULL,
+ GIMP_PARAM_STATIC_STRINGS |
+ GIMP_CONFIG_PARAM_IGNORE);
+
+ GIMP_CONFIG_PROP_STRING (object_class, PROP_DEFAULT_BRUSH,
+ "default-brush",
+ "Default brush",
+ DEFAULT_BRUSH_BLURB,
+ GIMP_DEFAULT_BRUSH,
+ GIMP_PARAM_STATIC_STRINGS);
+
+ GIMP_CONFIG_PROP_STRING (object_class, PROP_DEFAULT_DYNAMICS,
+ "default-dynamics",
+ "Default dynamics",
+ DEFAULT_DYNAMICS_BLURB,
+ GIMP_DEFAULT_DYNAMICS,
+ GIMP_PARAM_STATIC_STRINGS);
+
+ GIMP_CONFIG_PROP_STRING (object_class, PROP_DEFAULT_MYPAINT_BRUSH,
+ "default-mypaint-brush",
+ "Default MyPaint brush",
+ DEFAULT_MYPAINT_BRUSH_BLURB,
+ GIMP_DEFAULT_MYPAINT_BRUSH,
+ GIMP_PARAM_STATIC_STRINGS);
+
+ GIMP_CONFIG_PROP_STRING (object_class, PROP_DEFAULT_PATTERN,
+ "default-pattern",
+ "Default pattern",
+ DEFAULT_PATTERN_BLURB,
+ GIMP_DEFAULT_PATTERN,
+ GIMP_PARAM_STATIC_STRINGS);
+
+ GIMP_CONFIG_PROP_STRING (object_class, PROP_DEFAULT_PALETTE,
+ "default-palette",
+ "Default palette",
+ DEFAULT_PALETTE_BLURB,
+ GIMP_DEFAULT_PALETTE,
+ GIMP_PARAM_STATIC_STRINGS);
+
+ GIMP_CONFIG_PROP_STRING (object_class, PROP_DEFAULT_GRADIENT,
+ "default-gradient",
+ "Default gradient",
+ DEFAULT_GRADIENT_BLURB,
+ GIMP_DEFAULT_GRADIENT,
+ GIMP_PARAM_STATIC_STRINGS);
+
+ GIMP_CONFIG_PROP_STRING (object_class, PROP_DEFAULT_TOOL_PRESET,
+ "default-tool-preset",
+ "Default tool preset",
+ DEFAULT_TOOL_PRESET_BLURB,
+ GIMP_DEFAULT_TOOL_PRESET,
+ GIMP_PARAM_STATIC_STRINGS);
+
+ GIMP_CONFIG_PROP_STRING (object_class, PROP_DEFAULT_FONT,
+ "default-font",
+ "Default font",
+ DEFAULT_FONT_BLURB,
+ GIMP_DEFAULT_FONT,
+ GIMP_PARAM_STATIC_STRINGS);
+
+ GIMP_CONFIG_PROP_BOOLEAN (object_class, PROP_GLOBAL_BRUSH,
+ "global-brush",
+ "Global brush",
+ GLOBAL_BRUSH_BLURB,
+ TRUE,
+ GIMP_PARAM_STATIC_STRINGS);
+
+ GIMP_CONFIG_PROP_BOOLEAN (object_class, PROP_GLOBAL_DYNAMICS,
+ "global-dynamics",
+ "Global dynamics",
+ GLOBAL_DYNAMICS_BLURB,
+ TRUE,
+ GIMP_PARAM_STATIC_STRINGS);
+
+ GIMP_CONFIG_PROP_BOOLEAN (object_class, PROP_GLOBAL_PATTERN,
+ "global-pattern",
+ "Global pattern",
+ GLOBAL_PATTERN_BLURB,
+ TRUE,
+ GIMP_PARAM_STATIC_STRINGS);
+
+ GIMP_CONFIG_PROP_BOOLEAN (object_class, PROP_GLOBAL_PALETTE,
+ "global-palette",
+ "Global palette",
+ GLOBAL_PALETTE_BLURB,
+ TRUE,
+ GIMP_PARAM_STATIC_STRINGS);
+
+ GIMP_CONFIG_PROP_BOOLEAN (object_class, PROP_GLOBAL_GRADIENT,
+ "global-gradient",
+ "Global gradient",
+ GLOBAL_GRADIENT_BLURB,
+ TRUE,
+ GIMP_PARAM_STATIC_STRINGS);
+
+ GIMP_CONFIG_PROP_BOOLEAN (object_class, PROP_GLOBAL_FONT,
+ "global-font",
+ "Global font",
+ GLOBAL_FONT_BLURB,
+ TRUE,
+ GIMP_PARAM_STATIC_STRINGS);
+
+ GIMP_CONFIG_PROP_OBJECT (object_class, PROP_DEFAULT_IMAGE,
+ "default-image",
+ "Default image",
+ DEFAULT_IMAGE_BLURB,
+ GIMP_TYPE_TEMPLATE,
+ GIMP_PARAM_STATIC_STRINGS |
+ GIMP_CONFIG_PARAM_AGGREGATE);
+
+ GIMP_CONFIG_PROP_OBJECT (object_class, PROP_DEFAULT_GRID,
+ "default-grid",
+ "Default grid",
+ DEFAULT_GRID_BLURB,
+ GIMP_TYPE_GRID,
+ GIMP_PARAM_STATIC_STRINGS |
+ GIMP_CONFIG_PARAM_AGGREGATE);
+
+ GIMP_CONFIG_PROP_INT (object_class, PROP_UNDO_LEVELS,
+ "undo-levels",
+ "Undo levels",
+ UNDO_LEVELS_BLURB,
+ 0, 1 << 20, 5,
+ GIMP_PARAM_STATIC_STRINGS |
+ GIMP_CONFIG_PARAM_CONFIRM);
+
+ undo_size = gimp_get_physical_memory_size ();
+
+ if (undo_size > 0)
+ undo_size = undo_size / 8; /* 1/8th of the memory */
+ else
+ undo_size = 1 << 26; /* 64GB */
+
+ GIMP_CONFIG_PROP_MEMSIZE (object_class, PROP_UNDO_SIZE,
+ "undo-size",
+ "Undo size",
+ UNDO_SIZE_BLURB,
+ 0, GIMP_MAX_MEMSIZE, undo_size,
+ GIMP_PARAM_STATIC_STRINGS |
+ GIMP_CONFIG_PARAM_CONFIRM);
+
+ GIMP_CONFIG_PROP_ENUM (object_class, PROP_UNDO_PREVIEW_SIZE,
+ "undo-preview-size",
+ "Undo preview size",
+ UNDO_PREVIEW_SIZE_BLURB,
+ GIMP_TYPE_VIEW_SIZE,
+ GIMP_VIEW_SIZE_LARGE,
+ GIMP_PARAM_STATIC_STRINGS |
+ GIMP_CONFIG_PARAM_RESTART);
+
+ GIMP_CONFIG_PROP_INT (object_class, PROP_FILTER_HISTORY_SIZE,
+ "plug-in-history-size", /* compat name */
+ "Filter history size",
+ FILTER_HISTORY_SIZE_BLURB,
+ 0, 256, 10,
+ GIMP_PARAM_STATIC_STRINGS |
+ GIMP_CONFIG_PARAM_RESTART);
+
+ GIMP_CONFIG_PROP_PATH (object_class,
+ PROP_PLUGINRC_PATH,
+ "pluginrc-path",
+ "plugninrc path",
+ PLUGINRC_PATH_BLURB,
+ GIMP_CONFIG_PATH_FILE,
+ "${gimp_dir}" G_DIR_SEPARATOR_S "pluginrc",
+ GIMP_PARAM_STATIC_STRINGS |
+ GIMP_CONFIG_PARAM_RESTART);
+
+ GIMP_CONFIG_PROP_BOOLEAN (object_class, PROP_LAYER_PREVIEWS,
+ "layer-previews",
+ "Layer previews",
+ LAYER_PREVIEWS_BLURB,
+ TRUE,
+ GIMP_PARAM_STATIC_STRINGS);
+
+ GIMP_CONFIG_PROP_BOOLEAN (object_class, PROP_GROUP_LAYER_PREVIEWS,
+ "group-layer-previews",
+ "Layer group previews",
+ GROUP_LAYER_PREVIEWS_BLURB,
+ TRUE,
+ GIMP_PARAM_STATIC_STRINGS);
+
+ GIMP_CONFIG_PROP_ENUM (object_class, PROP_LAYER_PREVIEW_SIZE,
+ "layer-preview-size",
+ "Layer preview size",
+ LAYER_PREVIEW_SIZE_BLURB,
+ GIMP_TYPE_VIEW_SIZE,
+ GIMP_VIEW_SIZE_MEDIUM,
+ GIMP_PARAM_STATIC_STRINGS);
+
+ GIMP_CONFIG_PROP_ENUM (object_class, PROP_THUMBNAIL_SIZE,
+ "thumbnail-size",
+ "Thumbnail size",
+ THUMBNAIL_SIZE_BLURB,
+ GIMP_TYPE_THUMBNAIL_SIZE,
+ GIMP_THUMBNAIL_SIZE_NORMAL,
+ GIMP_PARAM_STATIC_STRINGS);
+
+ GIMP_CONFIG_PROP_MEMSIZE (object_class, PROP_THUMBNAIL_FILESIZE_LIMIT,
+ "thumbnail-filesize-limit",
+ "Thumbnail file size limit",
+ THUMBNAIL_FILESIZE_LIMIT_BLURB,
+ 0, GIMP_MAX_MEMSIZE, 1 << 22,
+ GIMP_PARAM_STATIC_STRINGS);
+
+ GIMP_CONFIG_PROP_OBJECT (object_class, PROP_COLOR_MANAGEMENT,
+ "color-management",
+ "Color management",
+ COLOR_MANAGEMENT_BLURB,
+ GIMP_TYPE_COLOR_CONFIG,
+ GIMP_PARAM_STATIC_STRINGS |
+ GIMP_CONFIG_PARAM_AGGREGATE);
+
+ GIMP_CONFIG_PROP_BOOLEAN (object_class, PROP_CHECK_UPDATES,
+ "check-updates",
+ "Check for updates",
+ CHECK_UPDATES_BLURB,
+ TRUE,
+ GIMP_PARAM_STATIC_STRINGS);
+
+ GIMP_CONFIG_PROP_INT64 (object_class, PROP_CHECK_UPDATE_TIMESTAMP,
+ "check-update-timestamp",
+ "timestamp of the last update check",
+ CHECK_UPDATE_TIMESTAMP_BLURB,
+ 0, G_MAXINT64, 0,
+ GIMP_PARAM_STATIC_STRINGS);
+
+ GIMP_CONFIG_PROP_INT64 (object_class, PROP_LAST_RELEASE_TIMESTAMP,
+ "last-release-timestamp",
+ "timestamp of the last release",
+ LAST_RELEASE_TIMESTAMP_BLURB,
+ 0, G_MAXINT64, 0,
+ GIMP_PARAM_STATIC_STRINGS);
+
+ GIMP_CONFIG_PROP_STRING (object_class, PROP_LAST_RELEASE_COMMENT,
+ "last-release-comment",
+ "Comment for last release",
+ LAST_KNOWN_RELEASE_BLURB,
+ NULL,
+ GIMP_PARAM_STATIC_STRINGS);
+
+ GIMP_CONFIG_PROP_STRING (object_class, PROP_LAST_KNOWN_RELEASE,
+ "last-known-release",
+ "last known release of GIMP",
+ LAST_KNOWN_RELEASE_BLURB,
+ NULL,
+ GIMP_PARAM_STATIC_STRINGS);
+
+ GIMP_CONFIG_PROP_INT (object_class, PROP_LAST_REVISION,
+ "last-revision",
+ "Last revision of current release",
+ LAST_RELEASE_TIMESTAMP_BLURB,
+ 0, G_MAXINT, 0,
+ GIMP_PARAM_STATIC_STRINGS);
+
+ GIMP_CONFIG_PROP_BOOLEAN (object_class, PROP_SAVE_DOCUMENT_HISTORY,
+ "save-document-history",
+ "Save document history",
+ SAVE_DOCUMENT_HISTORY_BLURB,
+ TRUE,
+ GIMP_PARAM_STATIC_STRINGS);
+
+ GIMP_CONFIG_PROP_RGB (object_class, PROP_QUICK_MASK_COLOR,
+ "quick-mask-color",
+ "Quick mask color",
+ QUICK_MASK_COLOR_BLURB,
+ TRUE, &red,
+ GIMP_PARAM_STATIC_STRINGS);
+
+ GIMP_CONFIG_PROP_BOOLEAN (object_class, PROP_IMPORT_PROMOTE_FLOAT,
+ "import-promote-float",
+ "Import promote float",
+ IMPORT_PROMOTE_FLOAT_BLURB,
+ FALSE,
+ GIMP_PARAM_STATIC_STRINGS);
+
+ GIMP_CONFIG_PROP_BOOLEAN (object_class, PROP_IMPORT_PROMOTE_DITHER,
+ "import-promote-dither",
+ "Import promote dither",
+ IMPORT_PROMOTE_DITHER_BLURB,
+ TRUE,
+ GIMP_PARAM_STATIC_STRINGS);
+
+ GIMP_CONFIG_PROP_BOOLEAN (object_class, PROP_IMPORT_ADD_ALPHA,
+ "import-add-alpha",
+ "Import add alpha",
+ IMPORT_ADD_ALPHA_BLURB,
+ FALSE,
+ GIMP_PARAM_STATIC_STRINGS);
+
+ GIMP_CONFIG_PROP_PATH (object_class, PROP_IMPORT_RAW_PLUG_IN,
+ "import-raw-plug-in",
+ "Import raw plug-in",
+ IMPORT_RAW_PLUG_IN_BLURB,
+ GIMP_CONFIG_PATH_FILE,
+ "",
+ GIMP_PARAM_STATIC_STRINGS |
+ GIMP_CONFIG_PARAM_RESTART);
+
+ GIMP_CONFIG_PROP_ENUM (object_class, PROP_EXPORT_FILE_TYPE,
+ "export-file-type",
+ "Default export file type",
+ EXPORT_FILE_TYPE_BLURB,
+ GIMP_TYPE_EXPORT_FILE_TYPE,
+ GIMP_EXPORT_FILE_PNG,
+ GIMP_PARAM_STATIC_STRINGS);
+
+ GIMP_CONFIG_PROP_BOOLEAN (object_class, PROP_EXPORT_COLOR_PROFILE,
+ "export-color-profile",
+ "Export Color Profile",
+ EXPORT_COLOR_PROFILE_BLURB,
+ TRUE,
+ GIMP_PARAM_STATIC_STRINGS);
+
+ GIMP_CONFIG_PROP_BOOLEAN (object_class, PROP_EXPORT_METADATA_EXIF,
+ "export-metadata-exif",
+ "Export Exif metadata",
+ EXPORT_METADATA_EXIF_BLURB,
+ TRUE,
+ GIMP_PARAM_STATIC_STRINGS);
+
+ GIMP_CONFIG_PROP_BOOLEAN (object_class, PROP_EXPORT_METADATA_XMP,
+ "export-metadata-xmp",
+ "Export XMP metadata",
+ EXPORT_METADATA_XMP_BLURB,
+ TRUE,
+ GIMP_PARAM_STATIC_STRINGS);
+
+ GIMP_CONFIG_PROP_BOOLEAN (object_class, PROP_EXPORT_METADATA_IPTC,
+ "export-metadata-iptc",
+ "Export IPTC metadata",
+ EXPORT_METADATA_IPTC_BLURB,
+ TRUE,
+ GIMP_PARAM_STATIC_STRINGS);
+
+ GIMP_CONFIG_PROP_ENUM (object_class, PROP_DEBUG_POLICY,
+ "debug-policy",
+ "Try generating backtrace upon errors",
+ GENERATE_BACKTRACE_BLURB,
+ GIMP_TYPE_DEBUG_POLICY,
+#ifdef GIMP_UNSTABLE
+ GIMP_DEBUG_POLICY_WARNING,
+#else
+ GIMP_DEBUG_POLICY_FATAL,
+#endif
+ GIMP_PARAM_STATIC_STRINGS);
+
+ /* only for backward compatibility: */
+ GIMP_CONFIG_PROP_BOOLEAN (object_class, PROP_INSTALL_COLORMAP,
+ "install-colormap",
+ NULL, NULL,
+ FALSE,
+ GIMP_PARAM_STATIC_STRINGS |
+ GIMP_CONFIG_PARAM_IGNORE);
+
+ GIMP_CONFIG_PROP_INT (object_class, PROP_MIN_COLORS,
+ "min-colors",
+ NULL, NULL,
+ 27, 256, 144,
+ GIMP_PARAM_STATIC_STRINGS |
+ GIMP_CONFIG_PARAM_IGNORE);
+}
+
+static void
+gimp_core_config_init (GimpCoreConfig *config)
+{
+ config->default_image = g_object_new (GIMP_TYPE_TEMPLATE,
+ "name", "Default Image",
+ "comment", GIMP_DEFAULT_COMMENT,
+ NULL);
+ g_signal_connect (config->default_image, "notify",
+ G_CALLBACK (gimp_core_config_default_image_notify),
+ config);
+
+ config->default_grid = g_object_new (GIMP_TYPE_GRID,
+ "name", "Default Grid",
+ NULL);
+ g_signal_connect (config->default_grid, "notify",
+ G_CALLBACK (gimp_core_config_default_grid_notify),
+ config);
+
+ config->color_management = g_object_new (GIMP_TYPE_COLOR_CONFIG, NULL);
+ g_signal_connect (config->color_management, "notify",
+ G_CALLBACK (gimp_core_config_color_management_notify),
+ config);
+}
+
+static void
+gimp_core_config_finalize (GObject *object)
+{
+ GimpCoreConfig *core_config = GIMP_CORE_CONFIG (object);
+
+ g_free (core_config->language);
+ g_free (core_config->plug_in_path);
+ g_free (core_config->module_path);
+ g_free (core_config->interpreter_path);
+ g_free (core_config->environ_path);
+ g_free (core_config->brush_path);
+ g_free (core_config->brush_path_writable);
+ g_free (core_config->dynamics_path);
+ g_free (core_config->dynamics_path_writable);
+ g_free (core_config->pattern_path);
+ g_free (core_config->pattern_path_writable);
+ g_free (core_config->palette_path);
+ g_free (core_config->palette_path_writable);
+ g_free (core_config->gradient_path);
+ g_free (core_config->gradient_path_writable);
+ g_free (core_config->tool_preset_path);
+ g_free (core_config->tool_preset_path_writable);
+ g_free (core_config->font_path);
+ g_free (core_config->font_path_writable);
+ g_free (core_config->default_brush);
+ g_free (core_config->default_dynamics);
+ g_free (core_config->default_pattern);
+ g_free (core_config->default_palette);
+ g_free (core_config->default_gradient);
+ g_free (core_config->default_tool_preset);
+ g_free (core_config->default_font);
+ g_free (core_config->plug_in_rc_path);
+ g_free (core_config->import_raw_plug_in);
+
+ g_clear_pointer (&core_config->last_known_release, g_free);
+ g_clear_pointer (&core_config->last_release_comment, g_free);
+
+ g_clear_object (&core_config->default_image);
+ g_clear_object (&core_config->default_grid);
+ g_clear_object (&core_config->color_management);
+
+ G_OBJECT_CLASS (parent_class)->finalize (object);
+}
+
+static void
+gimp_core_config_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ GimpCoreConfig *core_config = GIMP_CORE_CONFIG (object);
+
+ switch (property_id)
+ {
+ case PROP_LANGUAGE:
+ g_free (core_config->language);
+ core_config->language = g_value_dup_string (value);
+ break;
+ case PROP_INTERPOLATION_TYPE:
+ core_config->interpolation_type = g_value_get_enum (value);
+ break;
+ case PROP_DEFAULT_THRESHOLD:
+ core_config->default_threshold = g_value_get_int (value);
+ break;
+ case PROP_PLUG_IN_PATH:
+ g_free (core_config->plug_in_path);
+ core_config->plug_in_path = g_value_dup_string (value);
+ break;
+ case PROP_MODULE_PATH:
+ g_free (core_config->module_path);
+ core_config->module_path = g_value_dup_string (value);
+ break;
+ case PROP_INTERPRETER_PATH:
+ g_free (core_config->interpreter_path);
+ core_config->interpreter_path = g_value_dup_string (value);
+ break;
+ case PROP_ENVIRON_PATH:
+ g_free (core_config->environ_path);
+ core_config->environ_path = g_value_dup_string (value);
+ break;
+ case PROP_BRUSH_PATH:
+ g_free (core_config->brush_path);
+ core_config->brush_path = g_value_dup_string (value);
+ break;
+ case PROP_BRUSH_PATH_WRITABLE:
+ g_free (core_config->brush_path_writable);
+ core_config->brush_path_writable = g_value_dup_string (value);
+ break;
+ case PROP_DYNAMICS_PATH:
+ g_free (core_config->dynamics_path);
+ core_config->dynamics_path = g_value_dup_string (value);
+ break;
+ case PROP_DYNAMICS_PATH_WRITABLE:
+ g_free (core_config->dynamics_path_writable);
+ core_config->dynamics_path_writable = g_value_dup_string (value);
+ break;
+ case PROP_MYPAINT_BRUSH_PATH:
+ g_free (core_config->mypaint_brush_path);
+ core_config->mypaint_brush_path = g_value_dup_string (value);
+ break;
+ case PROP_MYPAINT_BRUSH_PATH_WRITABLE:
+ g_free (core_config->mypaint_brush_path_writable);
+ core_config->mypaint_brush_path_writable = g_value_dup_string (value);
+ break;
+ case PROP_PATTERN_PATH:
+ g_free (core_config->pattern_path);
+ core_config->pattern_path = g_value_dup_string (value);
+ break;
+ case PROP_PATTERN_PATH_WRITABLE:
+ g_free (core_config->pattern_path_writable);
+ core_config->pattern_path_writable = g_value_dup_string (value);
+ break;
+ case PROP_PALETTE_PATH:
+ g_free (core_config->palette_path);
+ core_config->palette_path = g_value_dup_string (value);
+ break;
+ case PROP_PALETTE_PATH_WRITABLE:
+ g_free (core_config->palette_path_writable);
+ core_config->palette_path_writable = g_value_dup_string (value);
+ break;
+ case PROP_GRADIENT_PATH:
+ g_free (core_config->gradient_path);
+ core_config->gradient_path = g_value_dup_string (value);
+ break;
+ case PROP_GRADIENT_PATH_WRITABLE:
+ g_free (core_config->gradient_path_writable);
+ core_config->gradient_path_writable = g_value_dup_string (value);
+ break;
+ case PROP_TOOL_PRESET_PATH:
+ g_free (core_config->tool_preset_path);
+ core_config->tool_preset_path = g_value_dup_string (value);
+ break;
+ case PROP_TOOL_PRESET_PATH_WRITABLE:
+ g_free (core_config->tool_preset_path_writable);
+ core_config->tool_preset_path_writable = g_value_dup_string (value);
+ break;
+ case PROP_FONT_PATH:
+ g_free (core_config->font_path);
+ core_config->font_path = g_value_dup_string (value);
+ break;
+ case PROP_FONT_PATH_WRITABLE:
+ g_free (core_config->font_path_writable);
+ core_config->font_path_writable = g_value_dup_string (value);
+ break;
+ case PROP_DEFAULT_BRUSH:
+ g_free (core_config->default_brush);
+ core_config->default_brush = g_value_dup_string (value);
+ break;
+ case PROP_DEFAULT_DYNAMICS:
+ g_free (core_config->default_dynamics);
+ core_config->default_dynamics = g_value_dup_string (value);
+ break;
+ case PROP_DEFAULT_MYPAINT_BRUSH:
+ g_free (core_config->default_mypaint_brush);
+ core_config->default_mypaint_brush = g_value_dup_string (value);
+ break;
+ case PROP_DEFAULT_PATTERN:
+ g_free (core_config->default_pattern);
+ core_config->default_pattern = g_value_dup_string (value);
+ break;
+ case PROP_DEFAULT_PALETTE:
+ g_free (core_config->default_palette);
+ core_config->default_palette = g_value_dup_string (value);
+ break;
+ case PROP_DEFAULT_GRADIENT:
+ g_free (core_config->default_gradient);
+ core_config->default_gradient = g_value_dup_string (value);
+ break;
+ case PROP_DEFAULT_TOOL_PRESET:
+ g_free (core_config->default_tool_preset);
+ core_config->default_tool_preset = g_value_dup_string (value);
+ break;
+ case PROP_DEFAULT_FONT:
+ g_free (core_config->default_font);
+ core_config->default_font = g_value_dup_string (value);
+ break;
+ case PROP_GLOBAL_BRUSH:
+ core_config->global_brush = g_value_get_boolean (value);
+ break;
+ case PROP_GLOBAL_DYNAMICS:
+ core_config->global_dynamics = g_value_get_boolean (value);
+ break;
+ case PROP_GLOBAL_PATTERN:
+ core_config->global_pattern = g_value_get_boolean (value);
+ break;
+ case PROP_GLOBAL_PALETTE:
+ core_config->global_palette = g_value_get_boolean (value);
+ break;
+ case PROP_GLOBAL_GRADIENT:
+ core_config->global_gradient = g_value_get_boolean (value);
+ break;
+ case PROP_GLOBAL_FONT:
+ core_config->global_font = g_value_get_boolean (value);
+ break;
+ case PROP_DEFAULT_IMAGE:
+ if (g_value_get_object (value))
+ gimp_config_sync (g_value_get_object (value) ,
+ G_OBJECT (core_config->default_image), 0);
+ break;
+ case PROP_DEFAULT_GRID:
+ if (g_value_get_object (value))
+ gimp_config_sync (g_value_get_object (value),
+ G_OBJECT (core_config->default_grid), 0);
+ break;
+ case PROP_FILTER_HISTORY_SIZE:
+ core_config->filter_history_size = g_value_get_int (value);
+ break;
+ case PROP_UNDO_LEVELS:
+ core_config->levels_of_undo = g_value_get_int (value);
+ break;
+ case PROP_UNDO_SIZE:
+ core_config->undo_size = g_value_get_uint64 (value);
+ break;
+ case PROP_UNDO_PREVIEW_SIZE:
+ core_config->undo_preview_size = g_value_get_enum (value);
+ break;
+ case PROP_PLUGINRC_PATH:
+ g_free (core_config->plug_in_rc_path);
+ core_config->plug_in_rc_path = g_value_dup_string (value);
+ break;
+ case PROP_LAYER_PREVIEWS:
+ core_config->layer_previews = g_value_get_boolean (value);
+ break;
+ case PROP_GROUP_LAYER_PREVIEWS:
+ core_config->group_layer_previews = g_value_get_boolean (value);
+ break;
+ case PROP_LAYER_PREVIEW_SIZE:
+ core_config->layer_preview_size = g_value_get_enum (value);
+ break;
+ case PROP_THUMBNAIL_SIZE:
+ core_config->thumbnail_size = g_value_get_enum (value);
+ break;
+ case PROP_THUMBNAIL_FILESIZE_LIMIT:
+ core_config->thumbnail_filesize_limit = g_value_get_uint64 (value);
+ break;
+ case PROP_COLOR_MANAGEMENT:
+ if (g_value_get_object (value))
+ gimp_config_sync (g_value_get_object (value),
+ G_OBJECT (core_config->color_management), 0);
+ break;
+ case PROP_CHECK_UPDATES:
+ core_config->check_updates = g_value_get_boolean (value);
+ break;
+ case PROP_CHECK_UPDATE_TIMESTAMP:
+ core_config->check_update_timestamp = g_value_get_int64 (value);
+ break;
+ case PROP_LAST_RELEASE_TIMESTAMP:
+ core_config->last_release_timestamp = g_value_get_int64 (value);
+ break;
+ case PROP_LAST_RELEASE_COMMENT:
+ g_clear_pointer (&core_config->last_release_comment, g_free);
+ core_config->last_release_comment = g_value_dup_string (value);
+ break;
+ case PROP_LAST_REVISION:
+ core_config->last_revision = g_value_get_int (value);
+ break;
+ case PROP_LAST_KNOWN_RELEASE:
+ g_clear_pointer (&core_config->last_known_release, g_free);
+ core_config->last_known_release = g_value_dup_string (value);
+ break;
+ case PROP_SAVE_DOCUMENT_HISTORY:
+ core_config->save_document_history = g_value_get_boolean (value);
+ break;
+ case PROP_QUICK_MASK_COLOR:
+ gimp_value_get_rgb (value, &core_config->quick_mask_color);
+ break;
+ case PROP_IMPORT_PROMOTE_FLOAT:
+ core_config->import_promote_float = g_value_get_boolean (value);
+ break;
+ case PROP_IMPORT_PROMOTE_DITHER:
+ core_config->import_promote_dither = g_value_get_boolean (value);
+ break;
+ case PROP_IMPORT_ADD_ALPHA:
+ core_config->import_add_alpha = g_value_get_boolean (value);
+ break;
+ case PROP_IMPORT_RAW_PLUG_IN:
+ g_free (core_config->import_raw_plug_in);
+ core_config->import_raw_plug_in = g_value_dup_string (value);
+ break;
+ case PROP_EXPORT_FILE_TYPE:
+ core_config->export_file_type = g_value_get_enum (value);
+ break;
+ case PROP_EXPORT_COLOR_PROFILE:
+ core_config->export_color_profile = g_value_get_boolean (value);
+ break;
+ case PROP_EXPORT_METADATA_EXIF:
+ core_config->export_metadata_exif = g_value_get_boolean (value);
+ break;
+ case PROP_EXPORT_METADATA_XMP:
+ core_config->export_metadata_xmp = g_value_get_boolean (value);
+ break;
+ case PROP_EXPORT_METADATA_IPTC:
+ core_config->export_metadata_iptc = g_value_get_boolean (value);
+ break;
+ case PROP_DEBUG_POLICY:
+ core_config->debug_policy = g_value_get_enum (value);
+ break;
+
+ case PROP_INSTALL_COLORMAP:
+ case PROP_MIN_COLORS:
+ /* ignored */
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+ break;
+ }
+}
+
+static void
+gimp_core_config_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ GimpCoreConfig *core_config = GIMP_CORE_CONFIG (object);
+
+ switch (property_id)
+ {
+ case PROP_LANGUAGE:
+ g_value_set_string (value, core_config->language);
+ break;
+ case PROP_INTERPOLATION_TYPE:
+ g_value_set_enum (value, core_config->interpolation_type);
+ break;
+ case PROP_DEFAULT_THRESHOLD:
+ g_value_set_int (value, core_config->default_threshold);
+ break;
+ case PROP_PLUG_IN_PATH:
+ g_value_set_string (value, core_config->plug_in_path);
+ break;
+ case PROP_MODULE_PATH:
+ g_value_set_string (value, core_config->module_path);
+ break;
+ case PROP_INTERPRETER_PATH:
+ g_value_set_string (value, core_config->interpreter_path);
+ break;
+ case PROP_ENVIRON_PATH:
+ g_value_set_string (value, core_config->environ_path);
+ break;
+ case PROP_BRUSH_PATH:
+ g_value_set_string (value, core_config->brush_path);
+ break;
+ case PROP_BRUSH_PATH_WRITABLE:
+ g_value_set_string (value, core_config->brush_path_writable);
+ break;
+ case PROP_DYNAMICS_PATH:
+ g_value_set_string (value, core_config->dynamics_path);
+ break;
+ case PROP_DYNAMICS_PATH_WRITABLE:
+ g_value_set_string (value, core_config->dynamics_path_writable);
+ break;
+ case PROP_MYPAINT_BRUSH_PATH:
+ g_value_set_string (value, core_config->mypaint_brush_path);
+ break;
+ case PROP_MYPAINT_BRUSH_PATH_WRITABLE:
+ g_value_set_string (value, core_config->mypaint_brush_path_writable);
+ break;
+ case PROP_PATTERN_PATH:
+ g_value_set_string (value, core_config->pattern_path);
+ break;
+ case PROP_PATTERN_PATH_WRITABLE:
+ g_value_set_string (value, core_config->pattern_path_writable);
+ break;
+ case PROP_PALETTE_PATH:
+ g_value_set_string (value, core_config->palette_path);
+ break;
+ case PROP_PALETTE_PATH_WRITABLE:
+ g_value_set_string (value, core_config->palette_path_writable);
+ break;
+ case PROP_GRADIENT_PATH:
+ g_value_set_string (value, core_config->gradient_path);
+ break;
+ case PROP_GRADIENT_PATH_WRITABLE:
+ g_value_set_string (value, core_config->gradient_path_writable);
+ break;
+ case PROP_TOOL_PRESET_PATH:
+ g_value_set_string (value, core_config->tool_preset_path);
+ break;
+ case PROP_TOOL_PRESET_PATH_WRITABLE:
+ g_value_set_string (value, core_config->tool_preset_path_writable);
+ break;
+ case PROP_FONT_PATH:
+ g_value_set_string (value, core_config->font_path);
+ break;
+ case PROP_FONT_PATH_WRITABLE:
+ g_value_set_string (value, core_config->font_path_writable);
+ break;
+ case PROP_DEFAULT_BRUSH:
+ g_value_set_string (value, core_config->default_brush);
+ break;
+ case PROP_DEFAULT_DYNAMICS:
+ g_value_set_string (value, core_config->default_dynamics);
+ break;
+ case PROP_DEFAULT_MYPAINT_BRUSH:
+ g_value_set_string (value, core_config->default_mypaint_brush);
+ break;
+ case PROP_DEFAULT_PATTERN:
+ g_value_set_string (value, core_config->default_pattern);
+ break;
+ case PROP_DEFAULT_PALETTE:
+ g_value_set_string (value, core_config->default_palette);
+ break;
+ case PROP_DEFAULT_GRADIENT:
+ g_value_set_string (value, core_config->default_gradient);
+ break;
+ case PROP_DEFAULT_TOOL_PRESET:
+ g_value_set_string (value, core_config->default_tool_preset);
+ break;
+ case PROP_DEFAULT_FONT:
+ g_value_set_string (value, core_config->default_font);
+ break;
+ case PROP_GLOBAL_BRUSH:
+ g_value_set_boolean (value, core_config->global_brush);
+ break;
+ case PROP_GLOBAL_DYNAMICS:
+ g_value_set_boolean (value, core_config->global_dynamics);
+ break;
+ case PROP_GLOBAL_PATTERN:
+ g_value_set_boolean (value, core_config->global_pattern);
+ break;
+ case PROP_GLOBAL_PALETTE:
+ g_value_set_boolean (value, core_config->global_palette);
+ break;
+ case PROP_GLOBAL_GRADIENT:
+ g_value_set_boolean (value, core_config->global_gradient);
+ break;
+ case PROP_GLOBAL_FONT:
+ g_value_set_boolean (value, core_config->global_font);
+ break;
+ case PROP_DEFAULT_IMAGE:
+ g_value_set_object (value, core_config->default_image);
+ break;
+ case PROP_DEFAULT_GRID:
+ g_value_set_object (value, core_config->default_grid);
+ break;
+ case PROP_FILTER_HISTORY_SIZE:
+ g_value_set_int (value, core_config->filter_history_size);
+ break;
+ case PROP_UNDO_LEVELS:
+ g_value_set_int (value, core_config->levels_of_undo);
+ break;
+ case PROP_UNDO_SIZE:
+ g_value_set_uint64 (value, core_config->undo_size);
+ break;
+ case PROP_UNDO_PREVIEW_SIZE:
+ g_value_set_enum (value, core_config->undo_preview_size);
+ break;
+ case PROP_PLUGINRC_PATH:
+ g_value_set_string (value, core_config->plug_in_rc_path);
+ break;
+ case PROP_LAYER_PREVIEWS:
+ g_value_set_boolean (value, core_config->layer_previews);
+ break;
+ case PROP_GROUP_LAYER_PREVIEWS:
+ g_value_set_boolean (value, core_config->group_layer_previews);
+ break;
+ case PROP_LAYER_PREVIEW_SIZE:
+ g_value_set_enum (value, core_config->layer_preview_size);
+ break;
+ case PROP_THUMBNAIL_SIZE:
+ g_value_set_enum (value, core_config->thumbnail_size);
+ break;
+ case PROP_THUMBNAIL_FILESIZE_LIMIT:
+ g_value_set_uint64 (value, core_config->thumbnail_filesize_limit);
+ break;
+ case PROP_COLOR_MANAGEMENT:
+ g_value_set_object (value, core_config->color_management);
+ break;
+ case PROP_CHECK_UPDATES:
+ g_value_set_boolean (value, core_config->check_updates);
+ break;
+ case PROP_CHECK_UPDATE_TIMESTAMP:
+ g_value_set_int64 (value, core_config->check_update_timestamp);
+ break;
+ case PROP_LAST_RELEASE_TIMESTAMP:
+ g_value_set_int64 (value, core_config->last_release_timestamp);
+ break;
+ case PROP_LAST_RELEASE_COMMENT:
+ g_value_set_string (value, core_config->last_release_comment);
+ break;
+ case PROP_LAST_REVISION:
+ g_value_set_int (value, core_config->last_revision);
+ break;
+ case PROP_LAST_KNOWN_RELEASE:
+ g_value_set_string (value, core_config->last_known_release);
+ break;
+ case PROP_SAVE_DOCUMENT_HISTORY:
+ g_value_set_boolean (value, core_config->save_document_history);
+ break;
+ case PROP_QUICK_MASK_COLOR:
+ gimp_value_set_rgb (value, &core_config->quick_mask_color);
+ break;
+ case PROP_IMPORT_PROMOTE_FLOAT:
+ g_value_set_boolean (value, core_config->import_promote_float);
+ break;
+ case PROP_IMPORT_PROMOTE_DITHER:
+ g_value_set_boolean (value, core_config->import_promote_dither);
+ break;
+ case PROP_IMPORT_ADD_ALPHA:
+ g_value_set_boolean (value, core_config->import_add_alpha);
+ break;
+ case PROP_IMPORT_RAW_PLUG_IN:
+ g_value_set_string (value, core_config->import_raw_plug_in);
+ break;
+ case PROP_EXPORT_FILE_TYPE:
+ g_value_set_enum (value, core_config->export_file_type);
+ break;
+ case PROP_EXPORT_COLOR_PROFILE:
+ g_value_set_boolean (value, core_config->export_color_profile);
+ break;
+ case PROP_EXPORT_METADATA_EXIF:
+ g_value_set_boolean (value, core_config->export_metadata_exif);
+ break;
+ case PROP_EXPORT_METADATA_XMP:
+ g_value_set_boolean (value, core_config->export_metadata_xmp);
+ break;
+ case PROP_EXPORT_METADATA_IPTC:
+ g_value_set_boolean (value, core_config->export_metadata_iptc);
+ break;
+ case PROP_DEBUG_POLICY:
+ g_value_set_enum (value, core_config->debug_policy);
+ break;
+
+ case PROP_INSTALL_COLORMAP:
+ case PROP_MIN_COLORS:
+ /* ignored */
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+ break;
+ }
+}
+
+static void
+gimp_core_config_default_image_notify (GObject *object,
+ GParamSpec *pspec,
+ gpointer data)
+{
+ g_object_notify (G_OBJECT (data), "default-image");
+}
+
+static void
+gimp_core_config_default_grid_notify (GObject *object,
+ GParamSpec *pspec,
+ gpointer data)
+{
+ g_object_notify (G_OBJECT (data), "default-grid");
+}
+
+static void
+gimp_core_config_color_management_notify (GObject *object,
+ GParamSpec *pspec,
+ gpointer data)
+{
+ g_object_notify (G_OBJECT (data), "color-management");
+}
diff --git a/app/config/gimpcoreconfig.h b/app/config/gimpcoreconfig.h
new file mode 100644
index 0000000..f413ae4
--- /dev/null
+++ b/app/config/gimpcoreconfig.h
@@ -0,0 +1,123 @@
+/* GIMP - The GNU Image Manipulation Program
+ * Copyright (C) 1995 Spencer Kimball and Peter Mattis
+ *
+ * GimpCoreConfig class
+ * Copyright (C) 2001 Sven Neumann <sven@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_CORE_CONFIG_H__
+#define __GIMP_CORE_CONFIG_H__
+
+#include "operations/operations-enums.h"
+#include "core/core-enums.h"
+
+#include "config/gimpgeglconfig.h"
+
+
+#define GIMP_TYPE_CORE_CONFIG (gimp_core_config_get_type ())
+#define GIMP_CORE_CONFIG(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GIMP_TYPE_CORE_CONFIG, GimpCoreConfig))
+#define GIMP_CORE_CONFIG_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GIMP_TYPE_CORE_CONFIG, GimpCoreConfigClass))
+#define GIMP_IS_CORE_CONFIG(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GIMP_TYPE_CORE_CONFIG))
+#define GIMP_IS_CORE_CONFIG_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GIMP_TYPE_CORE_CONFIG))
+
+
+typedef struct _GimpCoreConfigClass GimpCoreConfigClass;
+
+struct _GimpCoreConfig
+{
+ GimpGeglConfig parent_instance;
+
+ gchar *language;
+ GimpInterpolationType interpolation_type;
+ gint default_threshold;
+ gchar *plug_in_path;
+ gchar *module_path;
+ gchar *interpreter_path;
+ gchar *environ_path;
+ gchar *brush_path;
+ gchar *brush_path_writable;
+ gchar *dynamics_path;
+ gchar *dynamics_path_writable;
+ gchar *mypaint_brush_path;
+ gchar *mypaint_brush_path_writable;
+ gchar *pattern_path;
+ gchar *pattern_path_writable;
+ gchar *palette_path;
+ gchar *palette_path_writable;
+ gchar *gradient_path;
+ gchar *gradient_path_writable;
+ gchar *tool_preset_path;
+ gchar *tool_preset_path_writable;
+ gchar *font_path;
+ gchar *font_path_writable; /* unused */
+ gchar *default_brush;
+ gchar *default_dynamics;
+ gchar *default_mypaint_brush;
+ gchar *default_pattern;
+ gchar *default_palette;
+ gchar *default_tool_preset;
+ gchar *default_gradient;
+ gchar *default_font;
+ gboolean global_brush;
+ gboolean global_dynamics;
+ gboolean global_pattern;
+ gboolean global_palette;
+ gboolean global_gradient;
+ gboolean global_font;
+ GimpTemplate *default_image;
+ GimpGrid *default_grid;
+ gint levels_of_undo;
+ guint64 undo_size;
+ GimpViewSize undo_preview_size;
+ gint filter_history_size;
+ gchar *plug_in_rc_path;
+ gboolean layer_previews;
+ gboolean group_layer_previews;
+ GimpViewSize layer_preview_size;
+ GimpThumbnailSize thumbnail_size;
+ guint64 thumbnail_filesize_limit;
+ GimpColorConfig *color_management;
+ gboolean save_document_history;
+ GimpRGB quick_mask_color;
+ gboolean import_promote_float;
+ gboolean import_promote_dither;
+ gboolean import_add_alpha;
+ gchar *import_raw_plug_in;
+ GimpExportFileType export_file_type;
+ gboolean export_color_profile;
+ gboolean export_metadata_exif;
+ gboolean export_metadata_xmp;
+ gboolean export_metadata_iptc;
+ GimpDebugPolicy debug_policy;
+
+ gboolean check_updates;
+ gint64 check_update_timestamp;
+ gchar *last_known_release;
+ gint64 last_release_timestamp;
+ gchar *last_release_comment;
+ gint last_revision;
+};
+
+struct _GimpCoreConfigClass
+{
+ GimpGeglConfigClass parent_class;
+};
+
+
+GType gimp_core_config_get_type (void) G_GNUC_CONST;
+
+
+#endif /* GIMP_CORE_CONFIG_H__ */
diff --git a/app/config/gimpdialogconfig.c b/app/config/gimpdialogconfig.c
new file mode 100644
index 0000000..f81d778
--- /dev/null
+++ b/app/config/gimpdialogconfig.c
@@ -0,0 +1,991 @@
+/* GIMP - The GNU Image Manipulation Program
+ * Copyright (C) 1995 Spencer Kimball and Peter Mattis
+ *
+ * GimpDialogConfig class
+ * Copyright (C) 2016 Michael Natterer <mitch@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/>.
+ */
+
+#include "config.h"
+
+#include <cairo.h>
+#include <gdk-pixbuf/gdk-pixbuf.h>
+#include <gegl.h>
+
+#include "libgimpbase/gimpbase.h"
+#include "libgimpcolor/gimpcolor.h"
+#include "libgimpconfig/gimpconfig.h"
+
+#include "core/core-types.h" /* fill and stroke options */
+#include "core/gimp.h"
+#include "core/gimpstrokeoptions.h"
+
+#include "config-types.h"
+
+#include "gimprc-blurbs.h"
+#include "gimpdialogconfig.h"
+
+#include "gimp-intl.h"
+
+
+enum
+{
+ PROP_0,
+
+ PROP_GIMP,
+
+ PROP_COLOR_PROFILE_POLICY,
+
+ PROP_COLOR_PROFILE_PATH,
+
+ PROP_IMAGE_CONVERT_PROFILE_INTENT,
+ PROP_IMAGE_CONVERT_PROFILE_BPC,
+
+ PROP_IMAGE_CONVERT_PRECISION_LAYER_DITHER_METHOD,
+ PROP_IMAGE_CONVERT_PRECISION_TEXT_LAYER_DITHER_METHOD,
+ PROP_IMAGE_CONVERT_PRECISION_CHANNEL_DITHER_METHOD,
+
+ PROP_IMAGE_CONVERT_INDEXED_PALETTE_TYPE,
+ PROP_IMAGE_CONVERT_INDEXED_MAX_COLORS,
+ PROP_IMAGE_CONVERT_INDEXED_REMOVE_DUPLICATES,
+ PROP_IMAGE_CONVERT_INDEXED_DITHER_TYPE,
+ PROP_IMAGE_CONVERT_INDEXED_DITHER_ALPHA,
+ PROP_IMAGE_CONVERT_INDEXED_DITHER_TEXT_LAYERS,
+
+ PROP_IMAGE_RESIZE_FILL_TYPE,
+ PROP_IMAGE_RESIZE_LAYER_SET,
+ PROP_IMAGE_RESIZE_RESIZE_TEXT_LAYERS,
+
+ PROP_LAYER_NEW_NAME,
+ PROP_LAYER_NEW_MODE,
+ PROP_LAYER_NEW_BLEND_SPACE,
+ PROP_LAYER_NEW_COMPOSITE_SPACE,
+ PROP_LAYER_NEW_COMPOSITE_MODE,
+ PROP_LAYER_NEW_OPACITY,
+ PROP_LAYER_NEW_FILL_TYPE,
+
+ PROP_LAYER_RESIZE_FILL_TYPE,
+
+ PROP_LAYER_ADD_MASK_TYPE,
+ PROP_LAYER_ADD_MASK_INVERT,
+
+ PROP_LAYER_MERGE_TYPE,
+ PROP_LAYER_MERGE_ACTIVE_GROUP_ONLY,
+ PROP_LAYER_MERGE_DISCARD_INVISIBLE,
+
+ PROP_CHANNEL_NEW_NAME,
+ PROP_CHANNEL_NEW_COLOR,
+
+ PROP_VECTORS_NEW_NAME,
+
+ PROP_VECTORS_EXPORT_PATH,
+ PROP_VECTORS_EXPORT_ACTIVE_ONLY,
+
+ PROP_VECTORS_IMPORT_PATH,
+ PROP_VECTORS_IMPORT_MERGE,
+ PROP_VECTORS_IMPORT_SCALE,
+
+ PROP_SELECTION_FEATHER_RADIUS,
+ PROP_SELECTION_FEATHER_EDGE_LOCK,
+
+ PROP_SELECTION_GROW_RADIUS,
+
+ PROP_SELECTION_SHRINK_RADIUS,
+ PROP_SELECTION_SHRINK_EDGE_LOCK,
+
+ PROP_SELECTION_BORDER_RADIUS,
+ PROP_SELECTION_BORDER_STYLE,
+ PROP_SELECTION_BORDER_EDGE_LOCK,
+
+ PROP_FILL_OPTIONS,
+ PROP_STROKE_OPTIONS
+};
+
+
+typedef struct _GimpDialogConfigPrivate GimpDialogConfigPrivate;
+
+struct _GimpDialogConfigPrivate
+{
+ Gimp *gimp;
+};
+
+#define GET_PRIVATE(config) \
+ ((GimpDialogConfigPrivate *) gimp_dialog_config_get_instance_private ((GimpDialogConfig *) (config)))
+
+
+static void gimp_dialog_config_constructed (GObject *object);
+static void gimp_dialog_config_finalize (GObject *object);
+static void gimp_dialog_config_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec);
+static void gimp_dialog_config_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec);
+
+static void gimp_dialog_config_fill_options_notify (GObject *object,
+ GParamSpec *pspec,
+ gpointer data);
+static void gimp_dialog_config_stroke_options_notify (GObject *object,
+ GParamSpec *pspec,
+ gpointer data);
+
+
+G_DEFINE_TYPE_WITH_PRIVATE (GimpDialogConfig, gimp_dialog_config,
+ GIMP_TYPE_GUI_CONFIG)
+
+#define parent_class gimp_dialog_config_parent_class
+
+
+static void
+gimp_dialog_config_class_init (GimpDialogConfigClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+ GimpRGB half_transparent = { 0.0, 0.0, 0.0, 0.5 };
+
+ object_class->constructed = gimp_dialog_config_constructed;
+ object_class->finalize = gimp_dialog_config_finalize;
+ object_class->set_property = gimp_dialog_config_set_property;
+ object_class->get_property = gimp_dialog_config_get_property;
+
+ g_object_class_install_property (object_class, PROP_GIMP,
+ g_param_spec_object ("gimp",
+ NULL, NULL,
+ GIMP_TYPE_GIMP,
+ GIMP_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT_ONLY));
+
+ GIMP_CONFIG_PROP_ENUM (object_class, PROP_COLOR_PROFILE_POLICY,
+ "color-profile-policy",
+ "Color profile policy",
+ COLOR_PROFILE_POLICY_BLURB,
+ GIMP_TYPE_COLOR_PROFILE_POLICY,
+ GIMP_COLOR_PROFILE_POLICY_ASK,
+ GIMP_PARAM_STATIC_STRINGS);
+
+ GIMP_CONFIG_PROP_PATH (object_class, PROP_COLOR_PROFILE_PATH,
+ "color-profile-path",
+ "Default color profile folder path",
+ COLOR_PROFILE_PATH_BLURB,
+ GIMP_CONFIG_PATH_FILE,
+ NULL,
+ GIMP_PARAM_STATIC_STRINGS);
+
+ GIMP_CONFIG_PROP_ENUM (object_class, PROP_IMAGE_CONVERT_PROFILE_INTENT,
+ "image-convert-profile-intent",
+ "Default rendering intent for color profile conversion",
+ IMAGE_CONVERT_PROFILE_INTENT_BLURB,
+ GIMP_TYPE_COLOR_RENDERING_INTENT,
+ GIMP_COLOR_RENDERING_INTENT_RELATIVE_COLORIMETRIC,
+ GIMP_PARAM_STATIC_STRINGS);
+
+ GIMP_CONFIG_PROP_BOOLEAN (object_class, PROP_IMAGE_CONVERT_PROFILE_BPC,
+ "image-convert-profile-black-point-compensation",
+ "Default 'Black point compensation' for "
+ "color profile conversion",
+ IMAGE_CONVERT_PROFILE_BPC_BLURB,
+ TRUE,
+ GIMP_PARAM_STATIC_STRINGS);
+
+ GIMP_CONFIG_PROP_ENUM (object_class,
+ PROP_IMAGE_CONVERT_PRECISION_LAYER_DITHER_METHOD,
+ "image-convert-precision-layer-dither-method",
+ "Default layer dither type for precision conversion",
+ IMAGE_CONVERT_PRECISION_LAYER_DITHER_METHOD_BLURB,
+ GEGL_TYPE_DITHER_METHOD,
+ GEGL_DITHER_NONE,
+ GIMP_PARAM_STATIC_STRINGS);
+
+ GIMP_CONFIG_PROP_ENUM (object_class,
+ PROP_IMAGE_CONVERT_PRECISION_TEXT_LAYER_DITHER_METHOD,
+ "image-convert-precision-text-layer-dither-method",
+ "Default text layer dither type for precision conversion",
+ IMAGE_CONVERT_PRECISION_TEXT_LAYER_DITHER_METHOD_BLURB,
+ GEGL_TYPE_DITHER_METHOD,
+ GEGL_DITHER_NONE,
+ GIMP_PARAM_STATIC_STRINGS);
+
+ GIMP_CONFIG_PROP_ENUM (object_class,
+ PROP_IMAGE_CONVERT_PRECISION_CHANNEL_DITHER_METHOD,
+ "image-convert-precision-channel-dither-method",
+ "Default channel dither type for precision conversion",
+ IMAGE_CONVERT_PRECISION_CHANNEL_DITHER_METHOD_BLURB,
+ GEGL_TYPE_DITHER_METHOD,
+ GEGL_DITHER_NONE,
+ GIMP_PARAM_STATIC_STRINGS);
+
+ GIMP_CONFIG_PROP_ENUM (object_class,
+ PROP_IMAGE_CONVERT_INDEXED_PALETTE_TYPE,
+ "image-convert-indexed-palette-type",
+ "Default palette type for indexed conversion",
+ IMAGE_CONVERT_INDEXED_PALETTE_TYPE_BLURB,
+ GIMP_TYPE_CONVERT_PALETTE_TYPE,
+ GIMP_CONVERT_PALETTE_GENERATE,
+ GIMP_PARAM_STATIC_STRINGS);
+
+ GIMP_CONFIG_PROP_INT (object_class,
+ PROP_IMAGE_CONVERT_INDEXED_MAX_COLORS,
+ "image-convert-indexed-max-colors",
+ "Default maximum number of colors for indexed conversion",
+ IMAGE_CONVERT_INDEXED_MAX_COLORS_BLURB,
+ 2, 256, 256,
+ GIMP_PARAM_STATIC_STRINGS);
+
+ GIMP_CONFIG_PROP_BOOLEAN (object_class,
+ PROP_IMAGE_CONVERT_INDEXED_REMOVE_DUPLICATES,
+ "image-convert-indexed-remove-duplicates",
+ "Default remove duplicates for indexed conversion",
+ IMAGE_CONVERT_INDEXED_REMOVE_DUPLICATES_BLURB,
+ TRUE,
+ GIMP_PARAM_STATIC_STRINGS);
+
+ GIMP_CONFIG_PROP_ENUM (object_class,
+ PROP_IMAGE_CONVERT_INDEXED_DITHER_TYPE,
+ "image-convert-indexed-dither-type",
+ "Default dither type for indexed conversion",
+ IMAGE_CONVERT_INDEXED_DITHER_TYPE_BLURB,
+ GIMP_TYPE_CONVERT_DITHER_TYPE,
+ GIMP_CONVERT_DITHER_NONE,
+ GIMP_PARAM_STATIC_STRINGS);
+
+ GIMP_CONFIG_PROP_BOOLEAN (object_class,
+ PROP_IMAGE_CONVERT_INDEXED_DITHER_ALPHA,
+ "image-convert-indexed-dither-alpha",
+ "Default dither alpha for indexed conversion",
+ IMAGE_CONVERT_INDEXED_DITHER_ALPHA_BLURB,
+ FALSE,
+ GIMP_PARAM_STATIC_STRINGS);
+
+ GIMP_CONFIG_PROP_BOOLEAN (object_class,
+ PROP_IMAGE_CONVERT_INDEXED_DITHER_TEXT_LAYERS,
+ "image-convert-indexed-dither-text-layers",
+ "Default dither text layers for indexed conversion",
+ IMAGE_CONVERT_INDEXED_DITHER_TEXT_LAYERS_BLURB,
+ FALSE,
+ GIMP_PARAM_STATIC_STRINGS);
+
+ GIMP_CONFIG_PROP_ENUM (object_class, PROP_IMAGE_RESIZE_FILL_TYPE,
+ "image-resize-fill-type",
+ "Default image resize fill type",
+ IMAGE_RESIZE_FILL_TYPE_BLURB,
+ GIMP_TYPE_FILL_TYPE,
+ GIMP_FILL_TRANSPARENT,
+ GIMP_PARAM_STATIC_STRINGS);
+
+ GIMP_CONFIG_PROP_ENUM (object_class, PROP_IMAGE_RESIZE_LAYER_SET,
+ "image-resize-layer-set",
+ "Default image resize layer set",
+ IMAGE_RESIZE_LAYER_SET_BLURB,
+ GIMP_TYPE_ITEM_SET,
+ GIMP_ITEM_SET_NONE,
+ GIMP_PARAM_STATIC_STRINGS);
+
+ GIMP_CONFIG_PROP_BOOLEAN (object_class, PROP_IMAGE_RESIZE_RESIZE_TEXT_LAYERS,
+ "image-resize-resize-text-layers",
+ "Default image resize text layers",
+ IMAGE_RESIZE_RESIZE_TEXT_LAYERS_BLURB,
+ FALSE,
+ GIMP_PARAM_STATIC_STRINGS);
+
+ GIMP_CONFIG_PROP_STRING (object_class, PROP_LAYER_NEW_NAME,
+ "layer-new-name",
+ "Default new layer name",
+ LAYER_NEW_NAME_BLURB,
+ _("Layer"),
+ GIMP_PARAM_STATIC_STRINGS);
+
+ GIMP_CONFIG_PROP_ENUM (object_class, PROP_LAYER_NEW_MODE,
+ "layer-new-mode",
+ "Default new layer mode",
+ LAYER_NEW_MODE_BLURB,
+ GIMP_TYPE_LAYER_MODE,
+ GIMP_LAYER_MODE_NORMAL,
+ GIMP_PARAM_STATIC_STRINGS);
+
+ GIMP_CONFIG_PROP_ENUM (object_class, PROP_LAYER_NEW_BLEND_SPACE,
+ "layer-new-blend-space",
+ "Default new layer blend space",
+ LAYER_NEW_BLEND_SPACE_BLURB,
+ GIMP_TYPE_LAYER_COLOR_SPACE,
+ GIMP_LAYER_COLOR_SPACE_AUTO,
+ GIMP_PARAM_STATIC_STRINGS);
+
+ GIMP_CONFIG_PROP_ENUM (object_class, PROP_LAYER_NEW_COMPOSITE_SPACE,
+ "layer-new-composite-space",
+ "Default new layer composite space",
+ LAYER_NEW_COMPOSITE_SPACE_BLURB,
+ GIMP_TYPE_LAYER_COLOR_SPACE,
+ GIMP_LAYER_COLOR_SPACE_AUTO,
+ GIMP_PARAM_STATIC_STRINGS);
+
+ GIMP_CONFIG_PROP_ENUM (object_class, PROP_LAYER_NEW_COMPOSITE_MODE,
+ "layer-new-composite-mode",
+ "Default new layer composite mode",
+ LAYER_NEW_COMPOSITE_MODE_BLURB,
+ GIMP_TYPE_LAYER_COMPOSITE_MODE,
+ GIMP_LAYER_COMPOSITE_AUTO,
+ GIMP_PARAM_STATIC_STRINGS);
+
+ GIMP_CONFIG_PROP_DOUBLE (object_class, PROP_LAYER_NEW_OPACITY,
+ "layer-new-opacity",
+ "Default new layer opacity",
+ LAYER_NEW_OPACITY_BLURB,
+ GIMP_OPACITY_TRANSPARENT, GIMP_OPACITY_OPAQUE,
+ GIMP_OPACITY_OPAQUE,
+ GIMP_PARAM_STATIC_STRINGS);
+
+ GIMP_CONFIG_PROP_ENUM (object_class, PROP_LAYER_NEW_FILL_TYPE,
+ "layer-new-fill-type",
+ "Default new layer fill type",
+ LAYER_NEW_FILL_TYPE_BLURB,
+ GIMP_TYPE_FILL_TYPE,
+ GIMP_FILL_TRANSPARENT,
+ GIMP_PARAM_STATIC_STRINGS);
+
+ GIMP_CONFIG_PROP_ENUM (object_class, PROP_LAYER_RESIZE_FILL_TYPE,
+ "layer-resize-fill-type",
+ "Default layer resize fill type",
+ LAYER_RESIZE_FILL_TYPE_BLURB,
+ GIMP_TYPE_FILL_TYPE,
+ GIMP_FILL_TRANSPARENT,
+ GIMP_PARAM_STATIC_STRINGS);
+
+ GIMP_CONFIG_PROP_ENUM (object_class, PROP_LAYER_ADD_MASK_TYPE,
+ "layer-add-mask-type",
+ "Default layer mask type",
+ LAYER_ADD_MASK_TYPE_BLURB,
+ GIMP_TYPE_ADD_MASK_TYPE,
+ GIMP_ADD_MASK_WHITE,
+ GIMP_PARAM_STATIC_STRINGS);
+
+ GIMP_CONFIG_PROP_BOOLEAN (object_class, PROP_LAYER_ADD_MASK_INVERT,
+ "layer-add-mask-invert",
+ "Default layer mask invert",
+ LAYER_ADD_MASK_INVERT_BLURB,
+ FALSE,
+ GIMP_PARAM_STATIC_STRINGS);
+
+ GIMP_CONFIG_PROP_ENUM (object_class, PROP_LAYER_MERGE_TYPE,
+ "layer-merge-type",
+ "Default layer merge type",
+ LAYER_MERGE_TYPE_BLURB,
+ GIMP_TYPE_MERGE_TYPE,
+ GIMP_EXPAND_AS_NECESSARY,
+ GIMP_PARAM_STATIC_STRINGS);
+
+ GIMP_CONFIG_PROP_BOOLEAN (object_class, PROP_LAYER_MERGE_ACTIVE_GROUP_ONLY,
+ "layer-merge-active-group-only",
+ "Default layer merge active group only",
+ LAYER_MERGE_ACTIVE_GROUP_ONLY_BLURB,
+ TRUE,
+ GIMP_PARAM_STATIC_STRINGS);
+
+ GIMP_CONFIG_PROP_BOOLEAN (object_class, PROP_LAYER_MERGE_DISCARD_INVISIBLE,
+ "layer-merge-discard-invisible",
+ "Default layer merge discard invisible",
+ LAYER_MERGE_DISCARD_INVISIBLE_BLURB,
+ FALSE,
+ GIMP_PARAM_STATIC_STRINGS);
+
+ GIMP_CONFIG_PROP_STRING (object_class, PROP_CHANNEL_NEW_NAME,
+ "channel-new-name",
+ "Default new channel name",
+ CHANNEL_NEW_NAME_BLURB,
+ _("Channel"),
+ GIMP_PARAM_STATIC_STRINGS);
+
+ GIMP_CONFIG_PROP_RGB (object_class, PROP_CHANNEL_NEW_COLOR,
+ "channel-new-color",
+ "Default new channel color and opacity",
+ CHANNEL_NEW_COLOR_BLURB,
+ TRUE,
+ &half_transparent,
+ GIMP_PARAM_STATIC_STRINGS);
+
+ GIMP_CONFIG_PROP_STRING (object_class, PROP_VECTORS_NEW_NAME,
+ "path-new-name",
+ "Default new path name",
+ VECTORS_NEW_NAME_BLURB,
+ _("Path"),
+ GIMP_PARAM_STATIC_STRINGS);
+
+ GIMP_CONFIG_PROP_PATH (object_class, PROP_VECTORS_EXPORT_PATH,
+ "path-export-path",
+ "Default path export folder path",
+ VECTORS_EXPORT_PATH_BLURB,
+ GIMP_CONFIG_PATH_FILE,
+ NULL,
+ GIMP_PARAM_STATIC_STRINGS);
+
+ GIMP_CONFIG_PROP_BOOLEAN (object_class, PROP_VECTORS_EXPORT_ACTIVE_ONLY,
+ "path-export-active-only",
+ "Default export only the active path",
+ VECTORS_EXPORT_ACTIVE_ONLY_BLURB,
+ TRUE,
+ GIMP_PARAM_STATIC_STRINGS);
+
+ GIMP_CONFIG_PROP_PATH (object_class, PROP_VECTORS_IMPORT_PATH,
+ "path-import-path",
+ "Default path import folder path",
+ VECTORS_IMPORT_PATH_BLURB,
+ GIMP_CONFIG_PATH_FILE,
+ NULL,
+ GIMP_PARAM_STATIC_STRINGS);
+
+ GIMP_CONFIG_PROP_BOOLEAN (object_class, PROP_VECTORS_IMPORT_MERGE,
+ "path-import-merge",
+ "Default merge imported vectors",
+ VECTORS_IMPORT_MERGE_BLURB,
+ FALSE,
+ GIMP_PARAM_STATIC_STRINGS);
+
+ GIMP_CONFIG_PROP_BOOLEAN (object_class, PROP_VECTORS_IMPORT_SCALE,
+ "path-import-scale",
+ "Default scale imported vectors",
+ VECTORS_IMPORT_SCALE_BLURB,
+ FALSE,
+ GIMP_PARAM_STATIC_STRINGS);
+
+ GIMP_CONFIG_PROP_DOUBLE (object_class, PROP_SELECTION_FEATHER_RADIUS,
+ "selection-feather-radius",
+ "Selection feather radius",
+ SELECTION_FEATHER_RADIUS_BLURB,
+ 0.0, 32767.0, 5.0,
+ GIMP_PARAM_STATIC_STRINGS);
+
+ GIMP_CONFIG_PROP_BOOLEAN (object_class, PROP_SELECTION_FEATHER_EDGE_LOCK,
+ "selection-feather-edge-lock",
+ "Selection feather edge lock",
+ SELECTION_FEATHER_EDGE_LOCK_BLURB,
+ TRUE,
+ GIMP_PARAM_STATIC_STRINGS);
+
+ GIMP_CONFIG_PROP_DOUBLE (object_class, PROP_SELECTION_GROW_RADIUS,
+ "selection-grow-radius",
+ "Selection grow radius",
+ SELECTION_GROW_RADIUS_BLURB,
+ 1.0, 32767.0, 1.0,
+ GIMP_PARAM_STATIC_STRINGS);
+
+ GIMP_CONFIG_PROP_DOUBLE (object_class, PROP_SELECTION_SHRINK_RADIUS,
+ "selection-shrink-radius",
+ "Selection shrink radius",
+ SELECTION_SHRINK_RADIUS_BLURB,
+ 1.0, 32767.0, 1.0,
+ GIMP_PARAM_STATIC_STRINGS);
+
+ GIMP_CONFIG_PROP_BOOLEAN (object_class, PROP_SELECTION_SHRINK_EDGE_LOCK,
+ "selection-shrink-edge-lock",
+ "Selection shrink edge lock",
+ SELECTION_SHRINK_EDGE_LOCK_BLURB,
+ FALSE,
+ GIMP_PARAM_STATIC_STRINGS);
+
+ GIMP_CONFIG_PROP_DOUBLE (object_class, PROP_SELECTION_BORDER_RADIUS,
+ "selection-border-radius",
+ "Selection border radius",
+ SELECTION_BORDER_RADIUS_BLURB,
+ 1.0, 32767.0, 5.0,
+ GIMP_PARAM_STATIC_STRINGS);
+
+ GIMP_CONFIG_PROP_BOOLEAN (object_class, PROP_SELECTION_BORDER_EDGE_LOCK,
+ "selection-border-edge-lock",
+ "Selection border edge lock",
+ SELECTION_BORDER_EDGE_LOCK_BLURB,
+ FALSE,
+ GIMP_PARAM_STATIC_STRINGS);
+
+ GIMP_CONFIG_PROP_ENUM (object_class, PROP_SELECTION_BORDER_STYLE,
+ "selection-border-style",
+ "Selection border style",
+ SELECTION_BORDER_STYLE_BLURB,
+ GIMP_TYPE_CHANNEL_BORDER_STYLE,
+ GIMP_CHANNEL_BORDER_STYLE_SMOOTH,
+ GIMP_PARAM_STATIC_STRINGS);
+
+ GIMP_CONFIG_PROP_OBJECT (object_class, PROP_FILL_OPTIONS,
+ "fill-options",
+ "Fill Options",
+ FILL_OPTIONS_BLURB,
+ GIMP_TYPE_FILL_OPTIONS,
+ GIMP_PARAM_STATIC_STRINGS |
+ GIMP_CONFIG_PARAM_AGGREGATE);
+
+ GIMP_CONFIG_PROP_OBJECT (object_class, PROP_STROKE_OPTIONS,
+ "stroke-options",
+ "Stroke Options",
+ STROKE_OPTIONS_BLURB,
+ GIMP_TYPE_STROKE_OPTIONS,
+ GIMP_PARAM_STATIC_STRINGS |
+ GIMP_CONFIG_PARAM_AGGREGATE);
+}
+
+static void
+gimp_dialog_config_init (GimpDialogConfig *config)
+{
+}
+
+static void
+gimp_dialog_config_constructed (GObject *object)
+{
+ GimpDialogConfig *config = GIMP_DIALOG_CONFIG (object);
+ GimpDialogConfigPrivate *priv = GET_PRIVATE (object);
+ GimpContext *context;
+
+ G_OBJECT_CLASS (parent_class)->constructed (object);
+
+ gimp_assert (GIMP_IS_GIMP (priv->gimp));
+
+ context = gimp_get_user_context (priv->gimp);
+
+ config->fill_options = gimp_fill_options_new (priv->gimp, context, TRUE);
+ gimp_context_set_serialize_properties (GIMP_CONTEXT (config->fill_options),
+ 0);
+
+ g_signal_connect (config->fill_options, "notify",
+ G_CALLBACK (gimp_dialog_config_fill_options_notify),
+ config);
+
+ config->stroke_options = gimp_stroke_options_new (priv->gimp, context, TRUE);
+ gimp_context_set_serialize_properties (GIMP_CONTEXT (config->stroke_options),
+ 0);
+
+ g_signal_connect (config->stroke_options, "notify",
+ G_CALLBACK (gimp_dialog_config_stroke_options_notify),
+ config);
+}
+
+static void
+gimp_dialog_config_finalize (GObject *object)
+{
+ GimpDialogConfig *config = GIMP_DIALOG_CONFIG (object);
+
+ g_clear_pointer (&config->color_profile_path, g_free);
+ g_clear_pointer (&config->layer_new_name, g_free);
+ g_clear_pointer (&config->channel_new_name, g_free);
+ g_clear_pointer (&config->vectors_new_name, g_free);
+ g_clear_pointer (&config->vectors_export_path, g_free);
+ g_clear_pointer (&config->vectors_import_path, g_free);
+
+ g_clear_object (&config->fill_options);
+ g_clear_object (&config->stroke_options);
+
+ G_OBJECT_CLASS (parent_class)->finalize (object);
+}
+
+static void
+gimp_dialog_config_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ GimpDialogConfig *config = GIMP_DIALOG_CONFIG (object);
+ GimpDialogConfigPrivate *priv = GET_PRIVATE (object);
+
+ switch (property_id)
+ {
+ case PROP_GIMP:
+ priv->gimp = g_value_get_object (value); /* don't ref */
+ break;
+
+ case PROP_COLOR_PROFILE_POLICY:
+ config->color_profile_policy = g_value_get_enum (value);
+ break;
+
+ case PROP_COLOR_PROFILE_PATH:
+ if (config->color_profile_path)
+ g_free (config->color_profile_path);
+ config->color_profile_path = g_value_dup_string (value);
+ break;
+
+ case PROP_IMAGE_CONVERT_PROFILE_INTENT:
+ config->image_convert_profile_intent = g_value_get_enum (value);
+ break;
+ case PROP_IMAGE_CONVERT_PROFILE_BPC:
+ config->image_convert_profile_bpc = g_value_get_boolean (value);
+ break;
+
+ case PROP_IMAGE_CONVERT_PRECISION_LAYER_DITHER_METHOD:
+ config->image_convert_precision_layer_dither_method =
+ g_value_get_enum (value);
+ break;
+ case PROP_IMAGE_CONVERT_PRECISION_TEXT_LAYER_DITHER_METHOD:
+ config->image_convert_precision_text_layer_dither_method =
+ g_value_get_enum (value);
+ break;
+ case PROP_IMAGE_CONVERT_PRECISION_CHANNEL_DITHER_METHOD:
+ config->image_convert_precision_channel_dither_method =
+ g_value_get_enum (value);
+ break;
+
+ case PROP_IMAGE_CONVERT_INDEXED_PALETTE_TYPE:
+ config->image_convert_indexed_palette_type = g_value_get_enum (value);
+ break;
+ case PROP_IMAGE_CONVERT_INDEXED_MAX_COLORS:
+ config->image_convert_indexed_max_colors = g_value_get_int (value);
+ break;
+ case PROP_IMAGE_CONVERT_INDEXED_REMOVE_DUPLICATES:
+ config->image_convert_indexed_remove_duplicates = g_value_get_boolean (value);
+ break;
+ case PROP_IMAGE_CONVERT_INDEXED_DITHER_TYPE:
+ config->image_convert_indexed_dither_type = g_value_get_enum (value);
+ break;
+ case PROP_IMAGE_CONVERT_INDEXED_DITHER_ALPHA:
+ config->image_convert_indexed_dither_alpha = g_value_get_boolean (value);
+ break;
+ case PROP_IMAGE_CONVERT_INDEXED_DITHER_TEXT_LAYERS:
+ config->image_convert_indexed_dither_text_layers = g_value_get_boolean (value);
+ break;
+
+ case PROP_IMAGE_RESIZE_FILL_TYPE:
+ config->image_resize_fill_type = g_value_get_enum (value);
+ break;
+ case PROP_IMAGE_RESIZE_LAYER_SET:
+ config->image_resize_layer_set = g_value_get_enum (value);
+ break;
+ case PROP_IMAGE_RESIZE_RESIZE_TEXT_LAYERS:
+ config->image_resize_resize_text_layers = g_value_get_boolean (value);
+ break;
+
+ case PROP_LAYER_NEW_NAME:
+ if (config->layer_new_name)
+ g_free (config->layer_new_name);
+ config->layer_new_name = g_value_dup_string (value);
+ break;
+ case PROP_LAYER_NEW_MODE:
+ config->layer_new_mode = g_value_get_enum (value);
+ break;
+ case PROP_LAYER_NEW_BLEND_SPACE:
+ config->layer_new_blend_space = g_value_get_enum (value);
+ break;
+ case PROP_LAYER_NEW_COMPOSITE_SPACE:
+ config->layer_new_composite_space = g_value_get_enum (value);
+ break;
+ case PROP_LAYER_NEW_COMPOSITE_MODE:
+ config->layer_new_composite_mode = g_value_get_enum (value);
+ break;
+ case PROP_LAYER_NEW_OPACITY:
+ config->layer_new_opacity = g_value_get_double (value);
+ break;
+ case PROP_LAYER_NEW_FILL_TYPE:
+ config->layer_new_fill_type = g_value_get_enum (value);
+ break;
+
+ case PROP_LAYER_RESIZE_FILL_TYPE:
+ config->layer_resize_fill_type = g_value_get_enum (value);
+ break;
+
+ case PROP_LAYER_ADD_MASK_TYPE:
+ config->layer_add_mask_type = g_value_get_enum (value);
+ break;
+ case PROP_LAYER_ADD_MASK_INVERT:
+ config->layer_add_mask_invert = g_value_get_boolean (value);
+ break;
+
+ case PROP_LAYER_MERGE_TYPE:
+ config->layer_merge_type = g_value_get_enum (value);
+ break;
+ case PROP_LAYER_MERGE_ACTIVE_GROUP_ONLY:
+ config->layer_merge_active_group_only = g_value_get_boolean (value);
+ break;
+ case PROP_LAYER_MERGE_DISCARD_INVISIBLE:
+ config->layer_merge_discard_invisible = g_value_get_boolean (value);
+ break;
+
+ case PROP_CHANNEL_NEW_NAME:
+ if (config->channel_new_name)
+ g_free (config->channel_new_name);
+ config->channel_new_name = g_value_dup_string (value);
+ break;
+ case PROP_CHANNEL_NEW_COLOR:
+ gimp_value_get_rgb (value, &config->channel_new_color);
+ break;
+
+ case PROP_VECTORS_NEW_NAME:
+ if (config->vectors_new_name)
+ g_free (config->vectors_new_name);
+ config->vectors_new_name = g_value_dup_string (value);
+ break;
+
+ case PROP_VECTORS_EXPORT_PATH:
+ if (config->vectors_export_path)
+ g_free (config->vectors_export_path);
+ config->vectors_export_path = g_value_dup_string (value);
+ break;
+ case PROP_VECTORS_EXPORT_ACTIVE_ONLY:
+ config->vectors_export_active_only = g_value_get_boolean (value);
+ break;
+
+ case PROP_VECTORS_IMPORT_PATH:
+ if (config->vectors_import_path)
+ g_free (config->vectors_import_path);
+ config->vectors_import_path = g_value_dup_string (value);
+ break;
+ case PROP_VECTORS_IMPORT_MERGE:
+ config->vectors_import_merge = g_value_get_boolean (value);
+ break;
+ case PROP_VECTORS_IMPORT_SCALE:
+ config->vectors_import_scale = g_value_get_boolean (value);
+ break;
+
+ case PROP_SELECTION_FEATHER_RADIUS:
+ config->selection_feather_radius = g_value_get_double (value);
+ break;
+ case PROP_SELECTION_FEATHER_EDGE_LOCK:
+ config->selection_feather_edge_lock = g_value_get_boolean (value);
+ break;
+
+ case PROP_SELECTION_GROW_RADIUS:
+ config->selection_grow_radius = g_value_get_double (value);
+ break;
+
+ case PROP_SELECTION_SHRINK_RADIUS:
+ config->selection_shrink_radius = g_value_get_double (value);
+ break;
+ case PROP_SELECTION_SHRINK_EDGE_LOCK:
+ config->selection_shrink_edge_lock = g_value_get_boolean (value);
+ break;
+
+ case PROP_SELECTION_BORDER_RADIUS:
+ config->selection_border_radius = g_value_get_double (value);
+ break;
+ case PROP_SELECTION_BORDER_EDGE_LOCK:
+ config->selection_border_edge_lock = g_value_get_boolean (value);
+ break;
+ case PROP_SELECTION_BORDER_STYLE:
+ config->selection_border_style = g_value_get_enum (value);
+ break;
+
+ case PROP_FILL_OPTIONS:
+ if (g_value_get_object (value))
+ gimp_config_sync (g_value_get_object (value) ,
+ G_OBJECT (config->fill_options), 0);
+ break;
+ case PROP_STROKE_OPTIONS:
+ if (g_value_get_object (value))
+ gimp_config_sync (g_value_get_object (value) ,
+ G_OBJECT (config->stroke_options), 0);
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+ break;
+ }
+}
+
+static void
+gimp_dialog_config_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ GimpDialogConfig *config = GIMP_DIALOG_CONFIG (object);
+ GimpDialogConfigPrivate *priv = GET_PRIVATE (object);
+
+ switch (property_id)
+ {
+ case PROP_GIMP:
+ g_value_set_object (value, priv->gimp);
+ break;
+
+ case PROP_COLOR_PROFILE_POLICY:
+ g_value_set_enum (value, config->color_profile_policy);
+ break;
+
+ case PROP_COLOR_PROFILE_PATH:
+ g_value_set_string (value, config->color_profile_path);
+ break;
+
+ case PROP_IMAGE_CONVERT_PROFILE_INTENT:
+ g_value_set_enum (value, config->image_convert_profile_intent);
+ break;
+ case PROP_IMAGE_CONVERT_PROFILE_BPC:
+ g_value_set_boolean (value, config->image_convert_profile_bpc);
+ break;
+
+ case PROP_IMAGE_CONVERT_PRECISION_LAYER_DITHER_METHOD:
+ g_value_set_enum (value,
+ config->image_convert_precision_layer_dither_method);
+ break;
+ case PROP_IMAGE_CONVERT_PRECISION_TEXT_LAYER_DITHER_METHOD:
+ g_value_set_enum (value,
+ config->image_convert_precision_text_layer_dither_method);
+ break;
+ case PROP_IMAGE_CONVERT_PRECISION_CHANNEL_DITHER_METHOD:
+ g_value_set_enum (value,
+ config->image_convert_precision_channel_dither_method);
+ break;
+
+ case PROP_IMAGE_CONVERT_INDEXED_PALETTE_TYPE:
+ g_value_set_enum (value, config->image_convert_indexed_palette_type);
+ break;
+ case PROP_IMAGE_CONVERT_INDEXED_MAX_COLORS:
+ g_value_set_int (value, config->image_convert_indexed_max_colors);
+ break;
+ case PROP_IMAGE_CONVERT_INDEXED_REMOVE_DUPLICATES:
+ g_value_set_boolean (value, config->image_convert_indexed_remove_duplicates);
+ break;
+ case PROP_IMAGE_CONVERT_INDEXED_DITHER_TYPE:
+ g_value_set_enum (value, config->image_convert_indexed_dither_type);
+ break;
+ case PROP_IMAGE_CONVERT_INDEXED_DITHER_ALPHA:
+ g_value_set_boolean (value, config->image_convert_indexed_dither_alpha);
+ break;
+ case PROP_IMAGE_CONVERT_INDEXED_DITHER_TEXT_LAYERS:
+ g_value_set_boolean (value, config->image_convert_indexed_dither_text_layers);
+ break;
+
+ case PROP_IMAGE_RESIZE_FILL_TYPE:
+ g_value_set_enum (value, config->image_resize_fill_type);
+ break;
+ case PROP_IMAGE_RESIZE_LAYER_SET:
+ g_value_set_enum (value, config->image_resize_layer_set);
+ break;
+ case PROP_IMAGE_RESIZE_RESIZE_TEXT_LAYERS:
+ g_value_set_boolean (value, config->image_resize_resize_text_layers);
+ break;
+
+ case PROP_LAYER_NEW_NAME:
+ g_value_set_string (value, config->layer_new_name);
+ break;
+ case PROP_LAYER_NEW_MODE:
+ g_value_set_enum (value, config->layer_new_mode);
+ break;
+ case PROP_LAYER_NEW_BLEND_SPACE:
+ g_value_set_enum (value, config->layer_new_blend_space);
+ break;
+ case PROP_LAYER_NEW_COMPOSITE_SPACE:
+ g_value_set_enum (value, config->layer_new_composite_space);
+ break;
+ case PROP_LAYER_NEW_COMPOSITE_MODE:
+ g_value_set_enum (value, config->layer_new_composite_mode);
+ break;
+ case PROP_LAYER_NEW_OPACITY:
+ g_value_set_double (value, config->layer_new_opacity);
+ break;
+ case PROP_LAYER_NEW_FILL_TYPE:
+ g_value_set_enum (value, config->layer_new_fill_type);
+ break;
+
+ case PROP_LAYER_RESIZE_FILL_TYPE:
+ g_value_set_enum (value, config->layer_resize_fill_type);
+ break;
+
+ case PROP_LAYER_ADD_MASK_TYPE:
+ g_value_set_enum (value, config->layer_add_mask_type);
+ break;
+ case PROP_LAYER_ADD_MASK_INVERT:
+ g_value_set_boolean (value, config->layer_add_mask_invert);
+ break;
+
+ case PROP_LAYER_MERGE_TYPE:
+ g_value_set_enum (value, config->layer_merge_type);
+ break;
+ case PROP_LAYER_MERGE_ACTIVE_GROUP_ONLY:
+ g_value_set_boolean (value, config->layer_merge_active_group_only);
+ break;
+ case PROP_LAYER_MERGE_DISCARD_INVISIBLE:
+ g_value_set_boolean (value, config->layer_merge_discard_invisible);
+ break;
+
+ case PROP_CHANNEL_NEW_NAME:
+ g_value_set_string (value, config->channel_new_name);
+ break;
+ case PROP_CHANNEL_NEW_COLOR:
+ gimp_value_set_rgb (value, &config->channel_new_color);
+ break;
+
+ case PROP_VECTORS_NEW_NAME:
+ g_value_set_string (value, config->vectors_new_name);
+ break;
+
+ case PROP_VECTORS_EXPORT_PATH:
+ g_value_set_string (value, config->vectors_export_path);
+ break;
+ case PROP_VECTORS_EXPORT_ACTIVE_ONLY:
+ g_value_set_boolean (value, config->vectors_export_active_only);
+ break;
+
+ case PROP_VECTORS_IMPORT_PATH:
+ g_value_set_string (value, config->vectors_import_path);
+ break;
+ case PROP_VECTORS_IMPORT_MERGE:
+ g_value_set_boolean (value, config->vectors_import_merge);
+ break;
+ case PROP_VECTORS_IMPORT_SCALE:
+ g_value_set_boolean (value, config->vectors_import_scale);
+ break;
+
+ case PROP_SELECTION_FEATHER_RADIUS:
+ g_value_set_double (value, config->selection_feather_radius);
+ break;
+ case PROP_SELECTION_FEATHER_EDGE_LOCK:
+ g_value_set_boolean (value, config->selection_feather_edge_lock);
+ break;
+
+ case PROP_SELECTION_GROW_RADIUS:
+ g_value_set_double (value, config->selection_grow_radius);
+ break;
+
+ case PROP_SELECTION_SHRINK_RADIUS:
+ g_value_set_double (value, config->selection_shrink_radius);
+ break;
+ case PROP_SELECTION_SHRINK_EDGE_LOCK:
+ g_value_set_boolean (value, config->selection_shrink_edge_lock);
+ break;
+
+ case PROP_SELECTION_BORDER_RADIUS:
+ g_value_set_double (value, config->selection_border_radius);
+ break;
+ case PROP_SELECTION_BORDER_EDGE_LOCK:
+ g_value_set_boolean (value, config->selection_border_edge_lock);
+ break;
+ case PROP_SELECTION_BORDER_STYLE:
+ g_value_set_enum (value, config->selection_border_style);
+ break;
+
+ case PROP_FILL_OPTIONS:
+ g_value_set_object (value, config->fill_options);
+ break;
+ case PROP_STROKE_OPTIONS:
+ g_value_set_object (value, config->stroke_options);
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+ break;
+ }
+}
+
+static void
+gimp_dialog_config_fill_options_notify (GObject *object,
+ GParamSpec *pspec,
+ gpointer data)
+{
+ /* ignore notifications on parent class properties such as fg/bg */
+ if (pspec->owner_type == G_TYPE_FROM_INSTANCE (object))
+ g_object_notify (G_OBJECT (data), "fill-options");
+}
+
+static void
+gimp_dialog_config_stroke_options_notify (GObject *object,
+ GParamSpec *pspec,
+ gpointer data)
+{
+ /* see above */
+ if (pspec->owner_type == G_TYPE_FROM_INSTANCE (object))
+ g_object_notify (G_OBJECT (data), "stroke-options");
+}
diff --git a/app/config/gimpdialogconfig.h b/app/config/gimpdialogconfig.h
new file mode 100644
index 0000000..1053f6d
--- /dev/null
+++ b/app/config/gimpdialogconfig.h
@@ -0,0 +1,123 @@
+/* GIMP - The GNU Image Manipulation Program
+ * Copyright (C) 1995 Spencer Kimball and Peter Mattis
+ *
+ * GimpDialogConfig class
+ * Copyright (C) 2016 Michael Natterer <mitch@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_DIALOG_CONFIG_H__
+#define __GIMP_DIALOG_CONFIG_H__
+
+#include "config/gimpguiconfig.h"
+
+
+/* We don't want to include stuff from core/ here, instead do the next
+ * less ugly hack...
+ */
+typedef struct _GimpFillOptions GimpFillOptions;
+typedef struct _GimpStrokeOptions GimpStrokeOptions;
+
+
+#define GIMP_TYPE_DIALOG_CONFIG (gimp_dialog_config_get_type ())
+#define GIMP_DIALOG_CONFIG(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GIMP_TYPE_DIALOG_CONFIG, GimpDialogConfig))
+#define GIMP_DIALOG_CONFIG_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GIMP_TYPE_DIALOG_CONFIG, GimpDialogConfigClass))
+#define GIMP_IS_DIALOG_CONFIG(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GIMP_TYPE_DIALOG_CONFIG))
+#define GIMP_IS_DIALOG_CONFIG_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GIMP_TYPE_DIALOG_CONFIG))
+
+
+typedef struct _GimpDialogConfigClass GimpDialogConfigClass;
+
+struct _GimpDialogConfig
+{
+ GimpGuiConfig parent_instance;
+
+ GimpColorProfilePolicy color_profile_policy;
+
+ gchar *color_profile_path;
+
+ GimpColorRenderingIntent image_convert_profile_intent;
+ gboolean image_convert_profile_bpc;
+
+ GeglDitherMethod image_convert_precision_layer_dither_method;
+ GeglDitherMethod image_convert_precision_text_layer_dither_method;
+ GeglDitherMethod image_convert_precision_channel_dither_method;
+
+ GimpConvertPaletteType image_convert_indexed_palette_type;
+ gint image_convert_indexed_max_colors;
+ gboolean image_convert_indexed_remove_duplicates;
+ GimpConvertDitherType image_convert_indexed_dither_type;
+ gboolean image_convert_indexed_dither_alpha;
+ gboolean image_convert_indexed_dither_text_layers;
+
+ GimpFillType image_resize_fill_type;
+ GimpItemSet image_resize_layer_set;
+ gboolean image_resize_resize_text_layers;
+
+ gchar *layer_new_name;
+ GimpLayerMode layer_new_mode;
+ GimpLayerColorSpace layer_new_blend_space;
+ GimpLayerColorSpace layer_new_composite_space;
+ GimpLayerCompositeMode layer_new_composite_mode;
+ gdouble layer_new_opacity;
+ GimpFillType layer_new_fill_type;
+
+ GimpFillType layer_resize_fill_type;
+
+ GimpAddMaskType layer_add_mask_type;
+ gboolean layer_add_mask_invert;
+
+ GimpMergeType layer_merge_type;
+ gboolean layer_merge_active_group_only;
+ gboolean layer_merge_discard_invisible;
+
+ gchar *channel_new_name;
+ GimpRGB channel_new_color;
+
+ gchar *vectors_new_name;
+
+ gchar *vectors_export_path;
+ gboolean vectors_export_active_only;
+
+ gchar *vectors_import_path;
+ gboolean vectors_import_merge;
+ gboolean vectors_import_scale;
+
+ gdouble selection_feather_radius;
+ gboolean selection_feather_edge_lock;
+
+ gdouble selection_grow_radius;
+
+ gdouble selection_shrink_radius;
+ gboolean selection_shrink_edge_lock;
+
+ gdouble selection_border_radius;
+ gboolean selection_border_edge_lock;
+ GimpChannelBorderStyle selection_border_style;
+
+ GimpFillOptions *fill_options;
+ GimpStrokeOptions *stroke_options;
+};
+
+struct _GimpDialogConfigClass
+{
+ GimpGuiConfigClass parent_class;
+};
+
+
+GType gimp_dialog_config_get_type (void) G_GNUC_CONST;
+
+
+#endif /* GIMP_DIALOG_CONFIG_H__ */
diff --git a/app/config/gimpdisplayconfig.c b/app/config/gimpdisplayconfig.c
new file mode 100644
index 0000000..d38a6a1
--- /dev/null
+++ b/app/config/gimpdisplayconfig.c
@@ -0,0 +1,623 @@
+/* GIMP - The GNU Image Manipulation Program
+ * Copyright (C) 1995 Spencer Kimball and Peter Mattis
+ *
+ * GimpDisplayConfig class
+ * Copyright (C) 2001 Sven Neumann <sven@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/>.
+ */
+
+#include "config.h"
+
+#include <cairo.h>
+#include <gegl.h>
+#include <gdk-pixbuf/gdk-pixbuf.h>
+
+#include "libgimpbase/gimpbase.h"
+#include "libgimpcolor/gimpcolor.h"
+#include "libgimpconfig/gimpconfig.h"
+
+#include "config-types.h"
+
+#include "gimprc-blurbs.h"
+#include "gimpdisplayconfig.h"
+#include "gimpdisplayoptions.h"
+
+#include "gimp-intl.h"
+
+
+#define DEFAULT_ACTIVATE_ON_FOCUS TRUE
+#define DEFAULT_MONITOR_RESOLUTION 96.0
+#define DEFAULT_MARCHING_ANTS_SPEED 200
+#define DEFAULT_USE_EVENT_HISTORY FALSE
+
+enum
+{
+ PROP_0,
+ PROP_TRANSPARENCY_SIZE,
+ PROP_TRANSPARENCY_TYPE,
+ PROP_SNAP_DISTANCE,
+ PROP_MARCHING_ANTS_SPEED,
+ PROP_RESIZE_WINDOWS_ON_ZOOM,
+ PROP_RESIZE_WINDOWS_ON_RESIZE,
+ PROP_DEFAULT_SHOW_ALL,
+ PROP_DEFAULT_DOT_FOR_DOT,
+ PROP_INITIAL_ZOOM_TO_FIT,
+ PROP_CURSOR_MODE,
+ PROP_CURSOR_UPDATING,
+ PROP_SHOW_BRUSH_OUTLINE,
+ PROP_SNAP_BRUSH_OUTLINE,
+ PROP_SHOW_PAINT_TOOL_CURSOR,
+ PROP_IMAGE_TITLE_FORMAT,
+ PROP_IMAGE_STATUS_FORMAT,
+ PROP_MONITOR_XRESOLUTION,
+ PROP_MONITOR_YRESOLUTION,
+ PROP_MONITOR_RES_FROM_GDK,
+ PROP_NAV_PREVIEW_SIZE,
+ PROP_DEFAULT_VIEW,
+ PROP_DEFAULT_FULLSCREEN_VIEW,
+ PROP_ACTIVATE_ON_FOCUS,
+ PROP_SPACE_BAR_ACTION,
+ PROP_ZOOM_QUALITY,
+ PROP_USE_EVENT_HISTORY,
+
+ /* ignored, only for backward compatibility: */
+ PROP_DEFAULT_SNAP_TO_GUIDES,
+ PROP_DEFAULT_SNAP_TO_GRID,
+ PROP_DEFAULT_SNAP_TO_CANVAS,
+ PROP_DEFAULT_SNAP_TO_PATH,
+ PROP_CONFIRM_ON_CLOSE,
+ PROP_XOR_COLOR,
+ PROP_PERFECT_MOUSE
+};
+
+
+static void gimp_display_config_finalize (GObject *object);
+static void gimp_display_config_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec);
+static void gimp_display_config_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec);
+
+static void gimp_display_config_view_notify (GObject *object,
+ GParamSpec *pspec,
+ gpointer data);
+static void gimp_display_config_fullscreen_notify (GObject *object,
+ GParamSpec *pspec,
+ gpointer data);
+
+
+G_DEFINE_TYPE (GimpDisplayConfig, gimp_display_config, GIMP_TYPE_CORE_CONFIG)
+
+#define parent_class gimp_display_config_parent_class
+
+
+static void
+gimp_display_config_class_init (GimpDisplayConfigClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+ GimpRGB color = { 0, 0, 0, 0 };
+
+ object_class->finalize = gimp_display_config_finalize;
+ object_class->set_property = gimp_display_config_set_property;
+ object_class->get_property = gimp_display_config_get_property;
+
+ GIMP_CONFIG_PROP_ENUM (object_class, PROP_TRANSPARENCY_SIZE,
+ "transparency-size",
+ "Transparency size",
+ TRANSPARENCY_SIZE_BLURB,
+ GIMP_TYPE_CHECK_SIZE,
+ GIMP_CHECK_SIZE_MEDIUM_CHECKS,
+ GIMP_PARAM_STATIC_STRINGS);
+
+ GIMP_CONFIG_PROP_ENUM (object_class, PROP_TRANSPARENCY_TYPE,
+ "transparency-type",
+ "Transparency type",
+ TRANSPARENCY_TYPE_BLURB,
+ GIMP_TYPE_CHECK_TYPE,
+ GIMP_CHECK_TYPE_GRAY_CHECKS,
+ GIMP_PARAM_STATIC_STRINGS);
+
+ GIMP_CONFIG_PROP_INT (object_class, PROP_SNAP_DISTANCE,
+ "snap-distance",
+ "Snap distance",
+ DEFAULT_SNAP_DISTANCE_BLURB,
+ 1, 255, 8,
+ GIMP_PARAM_STATIC_STRINGS);
+
+ GIMP_CONFIG_PROP_INT (object_class, PROP_MARCHING_ANTS_SPEED,
+ "marching-ants-speed",
+ "Marching ants speed",
+ MARCHING_ANTS_SPEED_BLURB,
+ 10, 10000, DEFAULT_MARCHING_ANTS_SPEED,
+ GIMP_PARAM_STATIC_STRINGS);
+
+ GIMP_CONFIG_PROP_BOOLEAN (object_class, PROP_RESIZE_WINDOWS_ON_ZOOM,
+ "resize-windows-on-zoom",
+ "Resize windows on zoom",
+ RESIZE_WINDOWS_ON_ZOOM_BLURB,
+ FALSE,
+ GIMP_PARAM_STATIC_STRINGS);
+
+ GIMP_CONFIG_PROP_BOOLEAN (object_class, PROP_RESIZE_WINDOWS_ON_RESIZE,
+ "resize-windows-on-resize",
+ "Resize windows on resize",
+ RESIZE_WINDOWS_ON_RESIZE_BLURB,
+ FALSE,
+ GIMP_PARAM_STATIC_STRINGS);
+
+ GIMP_CONFIG_PROP_BOOLEAN (object_class, PROP_DEFAULT_SHOW_ALL,
+ "default-show-all",
+ "Default show-all",
+ DEFAULT_SHOW_ALL_BLURB,
+ FALSE,
+ GIMP_PARAM_STATIC_STRINGS);
+
+ GIMP_CONFIG_PROP_BOOLEAN (object_class, PROP_DEFAULT_DOT_FOR_DOT,
+ "default-dot-for-dot",
+ "Default dot-for-dot",
+ DEFAULT_DOT_FOR_DOT_BLURB,
+ TRUE,
+ GIMP_PARAM_STATIC_STRINGS);
+
+ GIMP_CONFIG_PROP_BOOLEAN (object_class, PROP_INITIAL_ZOOM_TO_FIT,
+ "initial-zoom-to-fit",
+ "Initial zoom-to-fit",
+ INITIAL_ZOOM_TO_FIT_BLURB,
+ TRUE,
+ GIMP_PARAM_STATIC_STRINGS);
+
+ GIMP_CONFIG_PROP_ENUM (object_class, PROP_CURSOR_MODE,
+ "cursor-mode",
+ "Cursor mode",
+ CURSOR_MODE_BLURB,
+ GIMP_TYPE_CURSOR_MODE,
+ GIMP_CURSOR_MODE_TOOL_CROSSHAIR,
+ GIMP_PARAM_STATIC_STRINGS);
+
+ GIMP_CONFIG_PROP_BOOLEAN (object_class, PROP_CURSOR_UPDATING,
+ "cursor-updating",
+ "Cursor updating",
+ CURSOR_UPDATING_BLURB,
+ TRUE,
+ GIMP_PARAM_STATIC_STRINGS);
+
+ GIMP_CONFIG_PROP_BOOLEAN (object_class, PROP_SHOW_BRUSH_OUTLINE,
+ "show-brush-outline",
+ "Show brush outline",
+ SHOW_BRUSH_OUTLINE_BLURB,
+ TRUE,
+ GIMP_PARAM_STATIC_STRINGS);
+
+ GIMP_CONFIG_PROP_BOOLEAN (object_class, PROP_SNAP_BRUSH_OUTLINE,
+ "snap-brush-outline",
+ "Snap brush outline",
+ SNAP_BRUSH_OUTLINE_BLURB,
+ FALSE,
+ GIMP_PARAM_STATIC_STRINGS);
+
+ GIMP_CONFIG_PROP_BOOLEAN (object_class, PROP_SHOW_PAINT_TOOL_CURSOR,
+ "show-paint-tool-cursor",
+ "Show paint tool cursor",
+ SHOW_PAINT_TOOL_CURSOR_BLURB,
+ TRUE,
+ GIMP_PARAM_STATIC_STRINGS);
+
+ GIMP_CONFIG_PROP_STRING (object_class, PROP_IMAGE_TITLE_FORMAT,
+ "image-title-format",
+ "Image title format",
+ IMAGE_TITLE_FORMAT_BLURB,
+ GIMP_CONFIG_DEFAULT_IMAGE_TITLE_FORMAT,
+ GIMP_PARAM_STATIC_STRINGS);
+
+ GIMP_CONFIG_PROP_STRING (object_class, PROP_IMAGE_STATUS_FORMAT,
+ "image-status-format",
+ "Image statusbar format",
+ IMAGE_STATUS_FORMAT_BLURB,
+ GIMP_CONFIG_DEFAULT_IMAGE_STATUS_FORMAT,
+ GIMP_PARAM_STATIC_STRINGS);
+
+ GIMP_CONFIG_PROP_RESOLUTION (object_class, PROP_MONITOR_XRESOLUTION,
+ "monitor-xresolution",
+ "Monitor resolution X",
+ MONITOR_XRESOLUTION_BLURB,
+ DEFAULT_MONITOR_RESOLUTION,
+ GIMP_PARAM_STATIC_STRINGS);
+
+ GIMP_CONFIG_PROP_RESOLUTION (object_class, PROP_MONITOR_YRESOLUTION,
+ "monitor-yresolution",
+ "Monitor resolution Y",
+ MONITOR_YRESOLUTION_BLURB,
+ DEFAULT_MONITOR_RESOLUTION,
+ GIMP_PARAM_STATIC_STRINGS);
+
+ GIMP_CONFIG_PROP_BOOLEAN (object_class, PROP_MONITOR_RES_FROM_GDK,
+ "monitor-resolution-from-windowing-system",
+ "Monitor resolution from windowing system",
+ MONITOR_RES_FROM_GDK_BLURB,
+ TRUE,
+ GIMP_PARAM_STATIC_STRINGS);
+
+ GIMP_CONFIG_PROP_ENUM (object_class, PROP_NAV_PREVIEW_SIZE,
+ "navigation-preview-size",
+ "Navigation preview size",
+ NAVIGATION_PREVIEW_SIZE_BLURB,
+ GIMP_TYPE_VIEW_SIZE,
+ GIMP_VIEW_SIZE_MEDIUM,
+ GIMP_PARAM_STATIC_STRINGS);
+
+ GIMP_CONFIG_PROP_OBJECT (object_class, PROP_DEFAULT_VIEW,
+ "default-view",
+ "Default view options",
+ DEFAULT_VIEW_BLURB,
+ GIMP_TYPE_DISPLAY_OPTIONS,
+ GIMP_PARAM_STATIC_STRINGS |
+ GIMP_CONFIG_PARAM_AGGREGATE);
+
+ GIMP_CONFIG_PROP_OBJECT (object_class, PROP_DEFAULT_FULLSCREEN_VIEW,
+ "default-fullscreen-view",
+ "Default fullscreen view options",
+ DEFAULT_FULLSCREEN_VIEW_BLURB,
+ GIMP_TYPE_DISPLAY_OPTIONS,
+ GIMP_PARAM_STATIC_STRINGS |
+ GIMP_CONFIG_PARAM_AGGREGATE);
+
+ GIMP_CONFIG_PROP_BOOLEAN (object_class, PROP_ACTIVATE_ON_FOCUS,
+ "activate-on-focus",
+ "Activate on focus",
+ ACTIVATE_ON_FOCUS_BLURB,
+ DEFAULT_ACTIVATE_ON_FOCUS,
+ GIMP_PARAM_STATIC_STRINGS);
+
+ GIMP_CONFIG_PROP_ENUM (object_class, PROP_SPACE_BAR_ACTION,
+ "space-bar-action",
+ "Space bar action",
+ SPACE_BAR_ACTION_BLURB,
+ GIMP_TYPE_SPACE_BAR_ACTION,
+ GIMP_SPACE_BAR_ACTION_PAN,
+ GIMP_PARAM_STATIC_STRINGS);
+
+ GIMP_CONFIG_PROP_ENUM (object_class, PROP_ZOOM_QUALITY,
+ "zoom-quality",
+ "Zoom quality",
+ ZOOM_QUALITY_BLURB,
+ GIMP_TYPE_ZOOM_QUALITY,
+ GIMP_ZOOM_QUALITY_HIGH,
+ GIMP_PARAM_STATIC_STRINGS);
+
+ GIMP_CONFIG_PROP_BOOLEAN (object_class, PROP_USE_EVENT_HISTORY,
+ "use-event-history",
+ "Use event history",
+ DEFAULT_USE_EVENT_HISTORY_BLURB,
+ DEFAULT_USE_EVENT_HISTORY,
+ GIMP_PARAM_STATIC_STRINGS);
+
+ /* only for backward compatibility: */
+ GIMP_CONFIG_PROP_BOOLEAN (object_class, PROP_DEFAULT_SNAP_TO_GUIDES,
+ "default-snap-to-guides",
+ NULL, NULL,
+ TRUE,
+ GIMP_PARAM_STATIC_STRINGS |
+ GIMP_CONFIG_PARAM_IGNORE);
+
+ GIMP_CONFIG_PROP_BOOLEAN (object_class, PROP_DEFAULT_SNAP_TO_GRID,
+ "default-snap-to-grid",
+ NULL, NULL,
+ FALSE,
+ GIMP_PARAM_STATIC_STRINGS |
+ GIMP_CONFIG_PARAM_IGNORE);
+
+ GIMP_CONFIG_PROP_BOOLEAN (object_class, PROP_DEFAULT_SNAP_TO_CANVAS,
+ "default-snap-to-canvas",
+ NULL, NULL,
+ FALSE,
+ GIMP_PARAM_STATIC_STRINGS |
+ GIMP_CONFIG_PARAM_IGNORE);
+
+ GIMP_CONFIG_PROP_BOOLEAN (object_class, PROP_DEFAULT_SNAP_TO_PATH,
+ "default-snap-to-path",
+ NULL, NULL,
+ FALSE,
+ GIMP_PARAM_STATIC_STRINGS |
+ GIMP_CONFIG_PARAM_IGNORE);
+
+ GIMP_CONFIG_PROP_BOOLEAN (object_class, PROP_CONFIRM_ON_CLOSE,
+ "confirm-on-close",
+ NULL, NULL,
+ TRUE,
+ GIMP_PARAM_STATIC_STRINGS |
+ GIMP_CONFIG_PARAM_IGNORE);
+
+ GIMP_CONFIG_PROP_RGB (object_class, PROP_XOR_COLOR,
+ "xor-color",
+ NULL, NULL,
+ FALSE, &color,
+ GIMP_PARAM_STATIC_STRINGS |
+ GIMP_CONFIG_PARAM_IGNORE);
+
+ GIMP_CONFIG_PROP_BOOLEAN (object_class, PROP_PERFECT_MOUSE,
+ "perfect-mouse",
+ NULL, NULL,
+ TRUE,
+ GIMP_PARAM_STATIC_STRINGS |
+ GIMP_CONFIG_PARAM_IGNORE);
+}
+
+static void
+gimp_display_config_init (GimpDisplayConfig *config)
+{
+ config->default_view =
+ g_object_new (GIMP_TYPE_DISPLAY_OPTIONS, NULL);
+
+ g_signal_connect (config->default_view, "notify",
+ G_CALLBACK (gimp_display_config_view_notify),
+ config);
+
+ config->default_fullscreen_view =
+ g_object_new (GIMP_TYPE_DISPLAY_OPTIONS, NULL);
+
+ g_signal_connect (config->default_fullscreen_view, "notify",
+ G_CALLBACK (gimp_display_config_fullscreen_notify),
+ config);
+}
+
+static void
+gimp_display_config_finalize (GObject *object)
+{
+ GimpDisplayConfig *display_config = GIMP_DISPLAY_CONFIG (object);
+
+ g_free (display_config->image_title_format);
+ g_free (display_config->image_status_format);
+
+ g_clear_object (&display_config->default_view);
+ g_clear_object (&display_config->default_fullscreen_view);
+
+ G_OBJECT_CLASS (parent_class)->finalize (object);
+}
+
+static void
+gimp_display_config_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ GimpDisplayConfig *display_config = GIMP_DISPLAY_CONFIG (object);
+
+ switch (property_id)
+ {
+ case PROP_TRANSPARENCY_SIZE:
+ display_config->transparency_size = g_value_get_enum (value);
+ break;
+ case PROP_TRANSPARENCY_TYPE:
+ display_config->transparency_type = g_value_get_enum (value);
+ break;
+ case PROP_SNAP_DISTANCE:
+ display_config->snap_distance = g_value_get_int (value);
+ break;
+ case PROP_MARCHING_ANTS_SPEED:
+ display_config->marching_ants_speed = g_value_get_int (value);
+ break;
+ case PROP_RESIZE_WINDOWS_ON_ZOOM:
+ display_config->resize_windows_on_zoom = g_value_get_boolean (value);
+ break;
+ case PROP_RESIZE_WINDOWS_ON_RESIZE:
+ display_config->resize_windows_on_resize = g_value_get_boolean (value);
+ break;
+ case PROP_DEFAULT_SHOW_ALL:
+ display_config->default_show_all = g_value_get_boolean (value);
+ break;
+ case PROP_DEFAULT_DOT_FOR_DOT:
+ display_config->default_dot_for_dot = g_value_get_boolean (value);
+ break;
+ case PROP_INITIAL_ZOOM_TO_FIT:
+ display_config->initial_zoom_to_fit = g_value_get_boolean (value);
+ break;
+ case PROP_CURSOR_MODE:
+ display_config->cursor_mode = g_value_get_enum (value);
+ break;
+ case PROP_CURSOR_UPDATING:
+ display_config->cursor_updating = g_value_get_boolean (value);
+ break;
+ case PROP_SHOW_BRUSH_OUTLINE:
+ display_config->show_brush_outline = g_value_get_boolean (value);
+ break;
+ case PROP_SNAP_BRUSH_OUTLINE:
+ display_config->snap_brush_outline = g_value_get_boolean (value);
+ break;
+ case PROP_SHOW_PAINT_TOOL_CURSOR:
+ display_config->show_paint_tool_cursor = g_value_get_boolean (value);
+ break;
+ case PROP_IMAGE_TITLE_FORMAT:
+ g_free (display_config->image_title_format);
+ display_config->image_title_format = g_value_dup_string (value);
+ break;
+ case PROP_IMAGE_STATUS_FORMAT:
+ g_free (display_config->image_status_format);
+ display_config->image_status_format = g_value_dup_string (value);
+ break;
+ case PROP_MONITOR_XRESOLUTION:
+ display_config->monitor_xres = g_value_get_double (value);
+ break;
+ case PROP_MONITOR_YRESOLUTION:
+ display_config->monitor_yres = g_value_get_double (value);
+ break;
+ case PROP_MONITOR_RES_FROM_GDK:
+ display_config->monitor_res_from_gdk = g_value_get_boolean (value);
+ break;
+ case PROP_NAV_PREVIEW_SIZE:
+ display_config->nav_preview_size = g_value_get_enum (value);
+ break;
+ case PROP_DEFAULT_VIEW:
+ if (g_value_get_object (value))
+ gimp_config_sync (g_value_get_object (value),
+ G_OBJECT (display_config->default_view), 0);
+ break;
+ case PROP_DEFAULT_FULLSCREEN_VIEW:
+ if (g_value_get_object (value))
+ gimp_config_sync (g_value_get_object (value),
+ G_OBJECT (display_config->default_fullscreen_view),
+ 0);
+ break;
+ case PROP_ACTIVATE_ON_FOCUS:
+ display_config->activate_on_focus = g_value_get_boolean (value);
+ break;
+ case PROP_SPACE_BAR_ACTION:
+ display_config->space_bar_action = g_value_get_enum (value);
+ break;
+ case PROP_ZOOM_QUALITY:
+ display_config->zoom_quality = g_value_get_enum (value);
+ break;
+ case PROP_USE_EVENT_HISTORY:
+ display_config->use_event_history = g_value_get_boolean (value);
+ break;
+
+ case PROP_DEFAULT_SNAP_TO_GUIDES:
+ case PROP_DEFAULT_SNAP_TO_GRID:
+ case PROP_DEFAULT_SNAP_TO_CANVAS:
+ case PROP_DEFAULT_SNAP_TO_PATH:
+ case PROP_CONFIRM_ON_CLOSE:
+ case PROP_XOR_COLOR:
+ case PROP_PERFECT_MOUSE:
+ /* ignored */
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+ break;
+ }
+}
+
+static void
+gimp_display_config_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ GimpDisplayConfig *display_config = GIMP_DISPLAY_CONFIG (object);
+
+ switch (property_id)
+ {
+ case PROP_TRANSPARENCY_SIZE:
+ g_value_set_enum (value, display_config->transparency_size);
+ break;
+ case PROP_TRANSPARENCY_TYPE:
+ g_value_set_enum (value, display_config->transparency_type);
+ break;
+ case PROP_SNAP_DISTANCE:
+ g_value_set_int (value, display_config->snap_distance);
+ break;
+ case PROP_MARCHING_ANTS_SPEED:
+ g_value_set_int (value, display_config->marching_ants_speed);
+ break;
+ case PROP_RESIZE_WINDOWS_ON_ZOOM:
+ g_value_set_boolean (value, display_config->resize_windows_on_zoom);
+ break;
+ case PROP_RESIZE_WINDOWS_ON_RESIZE:
+ g_value_set_boolean (value, display_config->resize_windows_on_resize);
+ break;
+ case PROP_DEFAULT_SHOW_ALL:
+ g_value_set_boolean (value, display_config->default_show_all);
+ break;
+ case PROP_DEFAULT_DOT_FOR_DOT:
+ g_value_set_boolean (value, display_config->default_dot_for_dot);
+ break;
+ case PROP_INITIAL_ZOOM_TO_FIT:
+ g_value_set_boolean (value, display_config->initial_zoom_to_fit);
+ break;
+ case PROP_CURSOR_MODE:
+ g_value_set_enum (value, display_config->cursor_mode);
+ break;
+ case PROP_CURSOR_UPDATING:
+ g_value_set_boolean (value, display_config->cursor_updating);
+ break;
+ case PROP_SHOW_BRUSH_OUTLINE:
+ g_value_set_boolean (value, display_config->show_brush_outline);
+ break;
+ case PROP_SNAP_BRUSH_OUTLINE:
+ g_value_set_boolean (value, display_config->snap_brush_outline);
+ break;
+ case PROP_SHOW_PAINT_TOOL_CURSOR:
+ g_value_set_boolean (value, display_config->show_paint_tool_cursor);
+ break;
+ case PROP_IMAGE_TITLE_FORMAT:
+ g_value_set_string (value, display_config->image_title_format);
+ break;
+ case PROP_IMAGE_STATUS_FORMAT:
+ g_value_set_string (value, display_config->image_status_format);
+ break;
+ case PROP_MONITOR_XRESOLUTION:
+ g_value_set_double (value, display_config->monitor_xres);
+ break;
+ case PROP_MONITOR_YRESOLUTION:
+ g_value_set_double (value, display_config->monitor_yres);
+ break;
+ case PROP_MONITOR_RES_FROM_GDK:
+ g_value_set_boolean (value, display_config->monitor_res_from_gdk);
+ break;
+ case PROP_NAV_PREVIEW_SIZE:
+ g_value_set_enum (value, display_config->nav_preview_size);
+ break;
+ case PROP_DEFAULT_VIEW:
+ g_value_set_object (value, display_config->default_view);
+ break;
+ case PROP_DEFAULT_FULLSCREEN_VIEW:
+ g_value_set_object (value, display_config->default_fullscreen_view);
+ break;
+ case PROP_ACTIVATE_ON_FOCUS:
+ g_value_set_boolean (value, display_config->activate_on_focus);
+ break;
+ case PROP_SPACE_BAR_ACTION:
+ g_value_set_enum (value, display_config->space_bar_action);
+ break;
+ case PROP_ZOOM_QUALITY:
+ g_value_set_enum (value, display_config->zoom_quality);
+ break;
+ case PROP_USE_EVENT_HISTORY:
+ g_value_set_boolean (value, display_config->use_event_history);
+ break;
+
+ case PROP_DEFAULT_SNAP_TO_GUIDES:
+ case PROP_DEFAULT_SNAP_TO_GRID:
+ case PROP_DEFAULT_SNAP_TO_CANVAS:
+ case PROP_DEFAULT_SNAP_TO_PATH:
+ case PROP_CONFIRM_ON_CLOSE:
+ case PROP_XOR_COLOR:
+ case PROP_PERFECT_MOUSE:
+ /* ignored */
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+ break;
+ }
+}
+
+static void
+gimp_display_config_view_notify (GObject *object,
+ GParamSpec *pspec,
+ gpointer data)
+{
+ g_object_notify (G_OBJECT (data), "default-view");
+}
+
+static void
+gimp_display_config_fullscreen_notify (GObject *object,
+ GParamSpec *pspec,
+ gpointer data)
+{
+ g_object_notify (G_OBJECT (data), "default-fullscreen-view");
+}
diff --git a/app/config/gimpdisplayconfig.h b/app/config/gimpdisplayconfig.h
new file mode 100644
index 0000000..e4c2a72
--- /dev/null
+++ b/app/config/gimpdisplayconfig.h
@@ -0,0 +1,81 @@
+/* GIMP - The GNU Image Manipulation Program
+ * Copyright (C) 1995 Spencer Kimball and Peter Mattis
+ *
+ * GimpDisplayConfig class
+ * Copyright (C) 2001 Sven Neumann <sven@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_DISPLAY_CONFIG_H__
+#define __GIMP_DISPLAY_CONFIG_H__
+
+#include "config/gimpcoreconfig.h"
+
+
+#define GIMP_CONFIG_DEFAULT_IMAGE_TITLE_FORMAT "%D*%f-%p.%i (%t, %o, %L) %wx%h"
+#define GIMP_CONFIG_DEFAULT_IMAGE_STATUS_FORMAT "%n (%m)"
+
+
+#define GIMP_TYPE_DISPLAY_CONFIG (gimp_display_config_get_type ())
+#define GIMP_DISPLAY_CONFIG(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GIMP_TYPE_DISPLAY_CONFIG, GimpDisplayConfig))
+#define GIMP_DISPLAY_CONFIG_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GIMP_TYPE_DISPLAY_CONFIG, GimpDisplayConfigClass))
+#define GIMP_IS_DISPLAY_CONFIG(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GIMP_TYPE_DISPLAY_CONFIG))
+#define GIMP_IS_DISPLAY_CONFIG_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GIMP_TYPE_DISPLAY_CONFIG))
+
+
+typedef struct _GimpDisplayConfigClass GimpDisplayConfigClass;
+
+struct _GimpDisplayConfig
+{
+ GimpCoreConfig parent_instance;
+
+ GimpCheckSize transparency_size;
+ GimpCheckType transparency_type;
+ gint snap_distance;
+ gint marching_ants_speed;
+ gboolean resize_windows_on_zoom;
+ gboolean resize_windows_on_resize;
+ gboolean default_show_all;
+ gboolean default_dot_for_dot;
+ gboolean initial_zoom_to_fit;
+ GimpCursorMode cursor_mode;
+ gboolean cursor_updating;
+ gboolean show_brush_outline;
+ gboolean snap_brush_outline;
+ gboolean show_paint_tool_cursor;
+ gchar *image_title_format;
+ gchar *image_status_format;
+ gdouble monitor_xres;
+ gdouble monitor_yres;
+ gboolean monitor_res_from_gdk;
+ GimpViewSize nav_preview_size;
+ GimpDisplayOptions *default_view;
+ GimpDisplayOptions *default_fullscreen_view;
+ gboolean activate_on_focus;
+ GimpSpaceBarAction space_bar_action;
+ GimpZoomQuality zoom_quality;
+ gboolean use_event_history;
+};
+
+struct _GimpDisplayConfigClass
+{
+ GimpCoreConfigClass parent_class;
+};
+
+
+GType gimp_display_config_get_type (void) G_GNUC_CONST;
+
+
+#endif /* GIMP_DISPLAY_CONFIG_H__ */
diff --git a/app/config/gimpdisplayoptions.c b/app/config/gimpdisplayoptions.c
new file mode 100644
index 0000000..b51a653
--- /dev/null
+++ b/app/config/gimpdisplayoptions.c
@@ -0,0 +1,597 @@
+/* GIMP - The GNU Image Manipulation Program
+ * Copyright (C) 1995 Spencer Kimball and Peter Mattis
+ *
+ * GimpDisplayOptions
+ * Copyright (C) 2003 Sven Neumann <sven@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/>.
+ */
+
+#include "config.h"
+
+#include <cairo.h>
+#include <gegl.h>
+#include <gdk-pixbuf/gdk-pixbuf.h>
+
+#include "libgimpbase/gimpbase.h"
+#include "libgimpmath/gimpmath.h"
+#include "libgimpcolor/gimpcolor.h"
+#include "libgimpconfig/gimpconfig.h"
+
+#include "config-types.h"
+
+#include "gimprc-blurbs.h"
+
+#include "gimpdisplayoptions.h"
+
+#include "gimp-intl.h"
+
+
+enum
+{
+ PROP_0,
+ PROP_SHOW_MENUBAR,
+ PROP_SHOW_STATUSBAR,
+ PROP_SHOW_RULERS,
+ PROP_SHOW_SCROLLBARS,
+ PROP_SHOW_SELECTION,
+ PROP_SHOW_LAYER_BOUNDARY,
+ PROP_SHOW_CANVAS_BOUNDARY,
+ PROP_SHOW_GUIDES,
+ PROP_SHOW_GRID,
+ PROP_SHOW_SAMPLE_POINTS,
+ PROP_SNAP_TO_GUIDES,
+ PROP_SNAP_TO_GRID,
+ PROP_SNAP_TO_CANVAS,
+ PROP_SNAP_TO_PATH,
+ PROP_PADDING_MODE,
+ PROP_PADDING_COLOR,
+ PROP_PADDING_IN_SHOW_ALL
+};
+
+
+static void gimp_display_options_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec);
+static void gimp_display_options_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec);
+
+
+G_DEFINE_TYPE_WITH_CODE (GimpDisplayOptions,
+ gimp_display_options,
+ G_TYPE_OBJECT,
+ G_IMPLEMENT_INTERFACE (GIMP_TYPE_CONFIG, NULL))
+
+typedef struct _GimpDisplayOptions GimpDisplayOptionsFullscreen;
+typedef struct _GimpDisplayOptionsClass GimpDisplayOptionsFullscreenClass;
+
+#define gimp_display_options_fullscreen_init gimp_display_options_init
+
+G_DEFINE_TYPE_WITH_CODE (GimpDisplayOptionsFullscreen,
+ gimp_display_options_fullscreen,
+ GIMP_TYPE_DISPLAY_OPTIONS,
+ G_IMPLEMENT_INTERFACE (GIMP_TYPE_CONFIG, NULL))
+
+typedef struct _GimpDisplayOptions GimpDisplayOptionsNoImage;
+typedef struct _GimpDisplayOptionsClass GimpDisplayOptionsNoImageClass;
+
+#define gimp_display_options_no_image_init gimp_display_options_init
+
+G_DEFINE_TYPE_WITH_CODE (GimpDisplayOptionsNoImage,
+ gimp_display_options_no_image,
+ GIMP_TYPE_DISPLAY_OPTIONS,
+ G_IMPLEMENT_INTERFACE (GIMP_TYPE_CONFIG, NULL))
+
+
+static void
+gimp_display_options_class_init (GimpDisplayOptionsClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+ GimpRGB white;
+
+ gimp_rgba_set (&white, 1.0, 1.0, 1.0, GIMP_OPACITY_OPAQUE);
+
+ object_class->set_property = gimp_display_options_set_property;
+ object_class->get_property = gimp_display_options_get_property;
+
+ GIMP_CONFIG_PROP_BOOLEAN (object_class, PROP_SHOW_MENUBAR,
+ "show-menubar",
+ "Show menubar",
+ SHOW_MENUBAR_BLURB,
+ TRUE,
+ GIMP_PARAM_STATIC_STRINGS);
+
+ GIMP_CONFIG_PROP_BOOLEAN (object_class, PROP_SHOW_STATUSBAR,
+ "show-statusbar",
+ "Show statusbar",
+ SHOW_STATUSBAR_BLURB,
+ TRUE,
+ GIMP_PARAM_STATIC_STRINGS);
+
+ GIMP_CONFIG_PROP_BOOLEAN (object_class, PROP_SHOW_RULERS,
+ "show-rulers",
+ "Show rulers",
+ SHOW_RULERS_BLURB,
+ TRUE,
+ GIMP_PARAM_STATIC_STRINGS);
+
+ GIMP_CONFIG_PROP_BOOLEAN (object_class, PROP_SHOW_SCROLLBARS,
+ "show-scrollbars",
+ "Show scrollbars",
+ SHOW_SCROLLBARS_BLURB,
+ TRUE,
+ GIMP_PARAM_STATIC_STRINGS);
+
+ GIMP_CONFIG_PROP_BOOLEAN (object_class, PROP_SHOW_SELECTION,
+ "show-selection",
+ "Show selection",
+ SHOW_SELECTION_BLURB,
+ TRUE,
+ GIMP_PARAM_STATIC_STRINGS);
+
+ GIMP_CONFIG_PROP_BOOLEAN (object_class, PROP_SHOW_LAYER_BOUNDARY,
+ "show-layer-boundary",
+ "Show layer boundary",
+ SHOW_LAYER_BOUNDARY_BLURB,
+ TRUE,
+ GIMP_PARAM_STATIC_STRINGS);
+
+ GIMP_CONFIG_PROP_BOOLEAN (object_class, PROP_SHOW_CANVAS_BOUNDARY,
+ "show-canvas-boundary",
+ "Show canvas boundary",
+ SHOW_CANVAS_BOUNDARY_BLURB,
+ TRUE,
+ GIMP_PARAM_STATIC_STRINGS);
+
+ GIMP_CONFIG_PROP_BOOLEAN (object_class, PROP_SHOW_GUIDES,
+ "show-guides",
+ "Show guides",
+ SHOW_GUIDES_BLURB,
+ TRUE,
+ GIMP_PARAM_STATIC_STRINGS);
+
+ GIMP_CONFIG_PROP_BOOLEAN (object_class, PROP_SHOW_GRID,
+ "show-grid",
+ "Show grid",
+ SHOW_GRID_BLURB,
+ FALSE,
+ GIMP_PARAM_STATIC_STRINGS);
+
+ GIMP_CONFIG_PROP_BOOLEAN (object_class, PROP_SHOW_SAMPLE_POINTS,
+ "show-sample-points",
+ "Show sample points",
+ SHOW_SAMPLE_POINTS_BLURB,
+ TRUE,
+ GIMP_PARAM_STATIC_STRINGS);
+
+ GIMP_CONFIG_PROP_BOOLEAN (object_class, PROP_SNAP_TO_GUIDES,
+ "snap-to-guides",
+ "Snap to guides",
+ SNAP_TO_GUIDES_BLURB,
+ TRUE,
+ GIMP_PARAM_STATIC_STRINGS);
+
+ GIMP_CONFIG_PROP_BOOLEAN (object_class, PROP_SNAP_TO_GRID,
+ "snap-to-grid",
+ "Snap to grid",
+ SNAP_TO_GRID_BLURB,
+ FALSE,
+ GIMP_PARAM_STATIC_STRINGS);
+
+ GIMP_CONFIG_PROP_BOOLEAN (object_class, PROP_SNAP_TO_CANVAS,
+ "snap-to-canvas",
+ "Snap to canvas",
+ SNAP_TO_CANVAS_BLURB,
+ FALSE,
+ GIMP_PARAM_STATIC_STRINGS);
+
+ GIMP_CONFIG_PROP_BOOLEAN (object_class, PROP_SNAP_TO_PATH,
+ "snap-to-path",
+ "Snap to path",
+ SNAP_TO_PATH_BLURB,
+ FALSE,
+ GIMP_PARAM_STATIC_STRINGS);
+
+ GIMP_CONFIG_PROP_ENUM (object_class, PROP_PADDING_MODE,
+ "padding-mode",
+ "Padding mode",
+ CANVAS_PADDING_MODE_BLURB,
+ GIMP_TYPE_CANVAS_PADDING_MODE,
+ GIMP_CANVAS_PADDING_MODE_DEFAULT,
+ GIMP_PARAM_STATIC_STRINGS);
+
+ GIMP_CONFIG_PROP_RGB (object_class, PROP_PADDING_COLOR,
+ "padding-color",
+ "Padding color",
+ CANVAS_PADDING_COLOR_BLURB,
+ FALSE, &white,
+ GIMP_PARAM_STATIC_STRINGS);
+
+ GIMP_CONFIG_PROP_BOOLEAN (object_class, PROP_PADDING_IN_SHOW_ALL,
+ "padding-in-show-all",
+ "Keep padding in \"Show All\" mode",
+ CANVAS_PADDING_IN_SHOW_ALL_BLURB,
+ FALSE,
+ GIMP_PARAM_STATIC_STRINGS);
+}
+
+static void
+gimp_display_options_fullscreen_class_init (GimpDisplayOptionsFullscreenClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+ GimpRGB black;
+
+ gimp_rgba_set (&black, 0.0, 0.0, 0.0, GIMP_OPACITY_OPAQUE);
+
+ object_class->set_property = gimp_display_options_set_property;
+ object_class->get_property = gimp_display_options_get_property;
+
+ GIMP_CONFIG_PROP_BOOLEAN (object_class, PROP_SHOW_MENUBAR,
+ "show-menubar",
+ "Show menubar",
+ SHOW_MENUBAR_BLURB,
+ FALSE,
+ GIMP_PARAM_STATIC_STRINGS);
+
+ GIMP_CONFIG_PROP_BOOLEAN (object_class, PROP_SHOW_STATUSBAR,
+ "show-statusbar",
+ "Show statusbar",
+ SHOW_STATUSBAR_BLURB,
+ FALSE,
+ GIMP_PARAM_STATIC_STRINGS);
+
+ GIMP_CONFIG_PROP_BOOLEAN (object_class, PROP_SHOW_RULERS,
+ "show-rulers",
+ "Show rulers",
+ SHOW_RULERS_BLURB,
+ FALSE,
+ GIMP_PARAM_STATIC_STRINGS);
+
+ GIMP_CONFIG_PROP_BOOLEAN (object_class, PROP_SHOW_SCROLLBARS,
+ "show-scrollbars",
+ "Show scrollbars",
+ SHOW_SCROLLBARS_BLURB,
+ FALSE,
+ GIMP_PARAM_STATIC_STRINGS);
+
+ GIMP_CONFIG_PROP_BOOLEAN (object_class, PROP_SHOW_SELECTION,
+ "show-selection",
+ "Show selection",
+ SHOW_SELECTION_BLURB,
+ FALSE,
+ GIMP_PARAM_STATIC_STRINGS);
+
+ GIMP_CONFIG_PROP_BOOLEAN (object_class, PROP_SHOW_LAYER_BOUNDARY,
+ "show-layer-boundary",
+ "Show layer boundary",
+ SHOW_LAYER_BOUNDARY_BLURB,
+ FALSE,
+ GIMP_PARAM_STATIC_STRINGS);
+
+ GIMP_CONFIG_PROP_BOOLEAN (object_class, PROP_SHOW_CANVAS_BOUNDARY,
+ "show-canvas-boundary",
+ "Show canvas boundary",
+ SHOW_CANVAS_BOUNDARY_BLURB,
+ FALSE,
+ GIMP_PARAM_STATIC_STRINGS);
+
+ GIMP_CONFIG_PROP_BOOLEAN (object_class, PROP_SHOW_GUIDES,
+ "show-guides",
+ "Show guides",
+ SHOW_GUIDES_BLURB,
+ FALSE,
+ GIMP_PARAM_STATIC_STRINGS);
+
+ GIMP_CONFIG_PROP_BOOLEAN (object_class, PROP_SHOW_GRID,
+ "show-grid",
+ "Show grid",
+ SHOW_GRID_BLURB,
+ FALSE,
+ GIMP_PARAM_STATIC_STRINGS);
+
+ GIMP_CONFIG_PROP_BOOLEAN (object_class, PROP_SHOW_SAMPLE_POINTS,
+ "show-sample-points",
+ "Show sample points",
+ SHOW_SAMPLE_POINTS_BLURB,
+ FALSE,
+ GIMP_PARAM_STATIC_STRINGS);
+
+ GIMP_CONFIG_PROP_BOOLEAN (object_class, PROP_SNAP_TO_GUIDES,
+ "snap-to-guides",
+ "Snap to guides",
+ SNAP_TO_GUIDES_BLURB,
+ TRUE,
+ GIMP_PARAM_STATIC_STRINGS);
+
+ GIMP_CONFIG_PROP_BOOLEAN (object_class, PROP_SNAP_TO_GRID,
+ "snap-to-grid",
+ "Snap to grid",
+ SHOW_SCROLLBARS_BLURB,
+ FALSE,
+ GIMP_PARAM_STATIC_STRINGS);
+
+ GIMP_CONFIG_PROP_BOOLEAN (object_class, PROP_SNAP_TO_CANVAS,
+ "snap-to-canvas",
+ "Snap to canvas",
+ SNAP_TO_CANVAS_BLURB,
+ FALSE,
+ GIMP_PARAM_STATIC_STRINGS);
+
+ GIMP_CONFIG_PROP_BOOLEAN (object_class, PROP_SNAP_TO_PATH,
+ "snap-to-path",
+ "Snap to path",
+ SNAP_TO_PATH_BLURB,
+ FALSE,
+ GIMP_PARAM_STATIC_STRINGS);
+
+ GIMP_CONFIG_PROP_ENUM (object_class, PROP_PADDING_MODE,
+ "padding-mode",
+ "Padding mode",
+ CANVAS_PADDING_MODE_BLURB,
+ GIMP_TYPE_CANVAS_PADDING_MODE,
+ GIMP_CANVAS_PADDING_MODE_CUSTOM,
+ GIMP_PARAM_STATIC_STRINGS);
+
+ GIMP_CONFIG_PROP_RGB (object_class, PROP_PADDING_COLOR,
+ "padding-color",
+ "Padding color",
+ CANVAS_PADDING_COLOR_BLURB,
+ FALSE, &black,
+ GIMP_PARAM_STATIC_STRINGS);
+
+ GIMP_CONFIG_PROP_BOOLEAN (object_class, PROP_PADDING_IN_SHOW_ALL,
+ "padding-in-show-all",
+ "Keep padding in \"Show All\" mode",
+ CANVAS_PADDING_IN_SHOW_ALL_BLURB,
+ FALSE,
+ GIMP_PARAM_STATIC_STRINGS);
+}
+
+static void
+gimp_display_options_no_image_class_init (GimpDisplayOptionsNoImageClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+ object_class->set_property = gimp_display_options_set_property;
+ object_class->get_property = gimp_display_options_get_property;
+
+ GIMP_CONFIG_PROP_BOOLEAN (object_class, PROP_SHOW_RULERS,
+ "show-rulers",
+ "Show rulers",
+ SHOW_RULERS_BLURB,
+ FALSE,
+ GIMP_PARAM_STATIC_STRINGS);
+
+ GIMP_CONFIG_PROP_BOOLEAN (object_class, PROP_SHOW_SCROLLBARS,
+ "show-scrollbars",
+ "Show scrollbars",
+ SHOW_SCROLLBARS_BLURB,
+ FALSE,
+ GIMP_PARAM_STATIC_STRINGS);
+
+ GIMP_CONFIG_PROP_BOOLEAN (object_class, PROP_SHOW_SELECTION,
+ "show-selection",
+ "Show selection",
+ SHOW_SELECTION_BLURB,
+ FALSE,
+ GIMP_PARAM_STATIC_STRINGS);
+
+ GIMP_CONFIG_PROP_BOOLEAN (object_class, PROP_SHOW_LAYER_BOUNDARY,
+ "show-layer-boundary",
+ "Show layer boundary",
+ SHOW_LAYER_BOUNDARY_BLURB,
+ FALSE,
+ GIMP_PARAM_STATIC_STRINGS);
+
+ GIMP_CONFIG_PROP_BOOLEAN (object_class, PROP_SHOW_CANVAS_BOUNDARY,
+ "show-canvas-boundary",
+ "Show canvas boundary",
+ SHOW_CANVAS_BOUNDARY_BLURB,
+ FALSE,
+ GIMP_PARAM_STATIC_STRINGS);
+
+ GIMP_CONFIG_PROP_BOOLEAN (object_class, PROP_SHOW_GUIDES,
+ "show-guides",
+ "Show guides",
+ SHOW_GUIDES_BLURB,
+ FALSE,
+ GIMP_PARAM_STATIC_STRINGS);
+
+ GIMP_CONFIG_PROP_BOOLEAN (object_class, PROP_SHOW_GRID,
+ "show-grid",
+ "Show grid",
+ SHOW_GRID_BLURB,
+ FALSE,
+ GIMP_PARAM_STATIC_STRINGS);
+
+ GIMP_CONFIG_PROP_BOOLEAN (object_class, PROP_SHOW_SAMPLE_POINTS,
+ "show-sample-points",
+ "Show sample points",
+ SHOW_SAMPLE_POINTS_BLURB,
+ FALSE,
+ GIMP_PARAM_STATIC_STRINGS);
+
+ GIMP_CONFIG_PROP_BOOLEAN (object_class, PROP_SNAP_TO_GUIDES,
+ "snap-to-guides",
+ "Snap to guides",
+ SNAP_TO_GUIDES_BLURB,
+ TRUE,
+ GIMP_PARAM_STATIC_STRINGS);
+
+ GIMP_CONFIG_PROP_BOOLEAN (object_class, PROP_SNAP_TO_GRID,
+ "snap-to-grid",
+ "Snap to grid",
+ SHOW_SCROLLBARS_BLURB,
+ FALSE,
+ GIMP_PARAM_STATIC_STRINGS);
+
+ GIMP_CONFIG_PROP_BOOLEAN (object_class, PROP_SNAP_TO_CANVAS,
+ "snap-to-canvas",
+ "Snap to canvas",
+ SNAP_TO_CANVAS_BLURB,
+ FALSE,
+ GIMP_PARAM_STATIC_STRINGS);
+
+ GIMP_CONFIG_PROP_BOOLEAN (object_class, PROP_SNAP_TO_PATH,
+ "snap-to-path",
+ "Snap tp path",
+ SNAP_TO_PATH_BLURB,
+ FALSE,
+ GIMP_PARAM_STATIC_STRINGS);
+}
+
+static void
+gimp_display_options_init (GimpDisplayOptions *options)
+{
+ options->padding_mode_set = FALSE;
+}
+
+static void
+gimp_display_options_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ GimpDisplayOptions *options = GIMP_DISPLAY_OPTIONS (object);
+
+ switch (property_id)
+ {
+ case PROP_SHOW_MENUBAR:
+ options->show_menubar = g_value_get_boolean (value);
+ break;
+ case PROP_SHOW_STATUSBAR:
+ options->show_statusbar = g_value_get_boolean (value);
+ break;
+ case PROP_SHOW_RULERS:
+ options->show_rulers = g_value_get_boolean (value);
+ break;
+ case PROP_SHOW_SCROLLBARS:
+ options->show_scrollbars = g_value_get_boolean (value);
+ break;
+ case PROP_SHOW_SELECTION:
+ options->show_selection = g_value_get_boolean (value);
+ break;
+ case PROP_SHOW_LAYER_BOUNDARY:
+ options->show_layer_boundary = g_value_get_boolean (value);
+ break;
+ case PROP_SHOW_CANVAS_BOUNDARY:
+ options->show_canvas_boundary = g_value_get_boolean (value);
+ break;
+ case PROP_SHOW_GUIDES:
+ options->show_guides = g_value_get_boolean (value);
+ break;
+ case PROP_SHOW_GRID:
+ options->show_grid = g_value_get_boolean (value);
+ break;
+ case PROP_SHOW_SAMPLE_POINTS:
+ options->show_sample_points = g_value_get_boolean (value);
+ break;
+ case PROP_SNAP_TO_GUIDES:
+ options->snap_to_guides = g_value_get_boolean (value);
+ break;
+ case PROP_SNAP_TO_GRID:
+ options->snap_to_grid = g_value_get_boolean (value);
+ break;
+ case PROP_SNAP_TO_CANVAS:
+ options->snap_to_canvas = g_value_get_boolean (value);
+ break;
+ case PROP_SNAP_TO_PATH:
+ options->snap_to_path = g_value_get_boolean (value);
+ break;
+ case PROP_PADDING_MODE:
+ options->padding_mode = g_value_get_enum (value);
+ break;
+ case PROP_PADDING_COLOR:
+ options->padding_color = *(GimpRGB *) g_value_get_boxed (value);
+ break;
+ case PROP_PADDING_IN_SHOW_ALL:
+ options->padding_in_show_all = g_value_get_boolean (value);
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+ break;
+ }
+}
+
+static void
+gimp_display_options_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ GimpDisplayOptions *options = GIMP_DISPLAY_OPTIONS (object);
+
+ switch (property_id)
+ {
+ case PROP_SHOW_MENUBAR:
+ g_value_set_boolean (value, options->show_menubar);
+ break;
+ case PROP_SHOW_STATUSBAR:
+ g_value_set_boolean (value, options->show_statusbar);
+ break;
+ case PROP_SHOW_RULERS:
+ g_value_set_boolean (value, options->show_rulers);
+ break;
+ case PROP_SHOW_SCROLLBARS:
+ g_value_set_boolean (value, options->show_scrollbars);
+ break;
+ case PROP_SHOW_SELECTION:
+ g_value_set_boolean (value, options->show_selection);
+ break;
+ case PROP_SHOW_LAYER_BOUNDARY:
+ g_value_set_boolean (value, options->show_layer_boundary);
+ break;
+ case PROP_SHOW_CANVAS_BOUNDARY:
+ g_value_set_boolean (value, options->show_canvas_boundary);
+ break;
+ case PROP_SHOW_GUIDES:
+ g_value_set_boolean (value, options->show_guides);
+ break;
+ case PROP_SHOW_GRID:
+ g_value_set_boolean (value, options->show_grid);
+ break;
+ case PROP_SHOW_SAMPLE_POINTS:
+ g_value_set_boolean (value, options->show_sample_points);
+ break;
+ case PROP_SNAP_TO_GUIDES:
+ g_value_set_boolean (value, options->snap_to_guides);
+ break;
+ case PROP_SNAP_TO_GRID:
+ g_value_set_boolean (value, options->snap_to_grid);
+ break;
+ case PROP_SNAP_TO_CANVAS:
+ g_value_set_boolean (value, options->snap_to_canvas);
+ break;
+ case PROP_SNAP_TO_PATH:
+ g_value_set_boolean (value, options->snap_to_path);
+ break;
+ case PROP_PADDING_MODE:
+ g_value_set_enum (value, options->padding_mode);
+ break;
+ case PROP_PADDING_COLOR:
+ g_value_set_boxed (value, &options->padding_color);
+ break;
+ case PROP_PADDING_IN_SHOW_ALL:
+ g_value_set_boolean (value, options->padding_in_show_all);
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+ break;
+ }
+}
diff --git a/app/config/gimpdisplayoptions.h b/app/config/gimpdisplayoptions.h
new file mode 100644
index 0000000..8da5e7a
--- /dev/null
+++ b/app/config/gimpdisplayoptions.h
@@ -0,0 +1,78 @@
+/* GIMP - The GNU Image Manipulation Program
+ * Copyright (C) 1995 Spencer Kimball and Peter Mattis
+ *
+ * GimpDisplayOptions
+ * Copyright (C) 2003 Sven Neumann <sven@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_DISPLAY_OPTIONS_H__
+#define __GIMP_DISPLAY_OPTIONS_H__
+
+
+#define GIMP_TYPE_DISPLAY_OPTIONS (gimp_display_options_get_type ())
+#define GIMP_TYPE_DISPLAY_OPTIONS_FULLSCREEN (gimp_display_options_fullscreen_get_type ())
+#define GIMP_TYPE_DISPLAY_OPTIONS_NO_IMAGE (gimp_display_options_no_image_get_type ())
+
+#define GIMP_DISPLAY_OPTIONS(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GIMP_TYPE_DISPLAY_OPTIONS, GimpDisplayOptions))
+#define GIMP_DISPLAY_OPTIONS_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GIMP_TYPE_DISPLAY_OPTIONS, GimpDisplayOptionsClass))
+#define GIMP_IS_DISPLAY_OPTIONS(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GIMP_TYPE_DISPLAY_OPTIONS))
+#define GIMP_IS_DISPLAY_OPTIONS_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GIMP_TYPE_DISPLAY_OPTIONS))
+#define GIMP_DISPLAY_OPTIONS_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GIMP_TYPE_DISPLAY_OPTIONS, GimpDisplayOptionsClass))
+
+
+typedef struct _GimpDisplayOptionsClass GimpDisplayOptionsClass;
+
+struct _GimpDisplayOptions
+{
+ GObject parent_instance;
+
+ /* GimpImageWindow options */
+ gboolean show_menubar;
+ gboolean show_statusbar;
+
+ /* GimpDisplayShell options */
+ gboolean show_rulers;
+ gboolean show_scrollbars;
+ gboolean show_selection;
+ gboolean show_layer_boundary;
+ gboolean show_canvas_boundary;
+ gboolean show_guides;
+ gboolean show_grid;
+ gboolean show_sample_points;
+
+ gboolean snap_to_guides;
+ gboolean snap_to_grid;
+ gboolean snap_to_canvas;
+ gboolean snap_to_path;
+
+ GimpCanvasPaddingMode padding_mode;
+ GimpRGB padding_color;
+ gboolean padding_mode_set;
+ gboolean padding_in_show_all;
+};
+
+struct _GimpDisplayOptionsClass
+{
+ GObjectClass parent_class;
+};
+
+
+GType gimp_display_options_get_type (void) G_GNUC_CONST;
+GType gimp_display_options_fullscreen_get_type (void) G_GNUC_CONST;
+GType gimp_display_options_no_image_get_type (void) G_GNUC_CONST;
+
+
+#endif /* __GIMP_DISPLAY_OPTIONS_H__ */
diff --git a/app/config/gimpgeglconfig.c b/app/config/gimpgeglconfig.c
new file mode 100644
index 0000000..1994c44
--- /dev/null
+++ b/app/config/gimpgeglconfig.c
@@ -0,0 +1,273 @@
+/* GIMP - The GNU Image Manipulation Program
+ * Copyright (C) 1995 Spencer Kimball and Peter Mattis
+ *
+ * GimpGeglConfig class
+ * Copyright (C) 2001 Sven Neumann <sven@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/>.
+ */
+
+#include "config.h"
+
+#include <gio/gio.h>
+#include <gegl.h>
+
+#include "libgimpbase/gimpbase.h"
+#include "libgimpconfig/gimpconfig.h"
+
+#include "core/core-types.h" /* eek */
+
+#include "gimprc-blurbs.h"
+#include "gimpgeglconfig.h"
+
+#include "core/gimp-utils.h"
+
+#include "gimp-debug.h"
+
+#include "gimp-intl.h"
+
+
+#define GIMP_DEFAULT_SWAP_COMPRESSION "fast"
+
+#define GIMP_MAX_MEM_PROCESS (MIN (G_MAXSIZE, GIMP_MAX_MEMSIZE))
+
+
+enum
+{
+ PROP_0,
+ PROP_TEMP_PATH,
+ PROP_SWAP_PATH,
+ PROP_SWAP_COMPRESSION,
+ PROP_NUM_PROCESSORS,
+ PROP_TILE_CACHE_SIZE,
+ PROP_USE_OPENCL,
+
+ /* ignored, only for backward compatibility: */
+ PROP_STINGY_MEMORY_USE
+};
+
+
+static void gimp_gegl_config_constructed (GObject *object);
+static void gimp_gegl_config_finalize (GObject *object);
+static void gimp_gegl_config_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec);
+static void gimp_gegl_config_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec);
+
+
+G_DEFINE_TYPE (GimpGeglConfig, gimp_gegl_config, G_TYPE_OBJECT)
+
+#define parent_class gimp_gegl_config_parent_class
+
+
+static void
+gimp_gegl_config_class_init (GimpGeglConfigClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+ gint n_threads;
+ gint max_n_threads;
+ guint64 memory_size;
+
+ parent_class = g_type_class_peek_parent (klass);
+
+ object_class->constructed = gimp_gegl_config_constructed;
+ object_class->finalize = gimp_gegl_config_finalize;
+ object_class->set_property = gimp_gegl_config_set_property;
+ object_class->get_property = gimp_gegl_config_get_property;
+
+ GIMP_CONFIG_PROP_PATH (object_class, PROP_TEMP_PATH,
+ "temp-path",
+ "Temp path",
+ TEMP_PATH_BLURB,
+ GIMP_CONFIG_PATH_DIR,
+ "${gimp_temp_dir}",
+ GIMP_PARAM_STATIC_STRINGS |
+ GIMP_CONFIG_PARAM_RESTART);
+
+ GIMP_CONFIG_PROP_PATH (object_class, PROP_SWAP_PATH,
+ "swap-path",
+ "Swap path",
+ SWAP_PATH_BLURB,
+ GIMP_CONFIG_PATH_DIR,
+ "${gimp_cache_dir}",
+ GIMP_PARAM_STATIC_STRINGS |
+ GIMP_CONFIG_PARAM_RESTART);
+
+ GIMP_CONFIG_PROP_STRING (object_class, PROP_SWAP_COMPRESSION,
+ "swap-compression",
+ "Swap compression",
+ SWAP_COMPRESSION_BLURB,
+ GIMP_DEFAULT_SWAP_COMPRESSION,
+ GIMP_PARAM_STATIC_STRINGS);
+
+ n_threads = g_get_num_processors ();
+
+ max_n_threads =
+ G_PARAM_SPEC_INT (g_object_class_find_property (G_OBJECT_GET_CLASS (gegl_config ()),
+ "threads"))->maximum;
+
+ n_threads = MIN (n_threads, max_n_threads);
+
+ GIMP_CONFIG_PROP_INT (object_class, PROP_NUM_PROCESSORS,
+ "num-processors",
+ "Number of threads to use",
+ NUM_PROCESSORS_BLURB,
+ 1, max_n_threads, n_threads,
+ GIMP_PARAM_STATIC_STRINGS);
+
+ memory_size = gimp_get_physical_memory_size ();
+
+ /* limit to the amount one process can handle */
+ memory_size = MIN (GIMP_MAX_MEM_PROCESS, memory_size);
+
+ if (memory_size > 0)
+ memory_size = memory_size / 2; /* half the memory */
+ else
+ memory_size = 1 << 30; /* 1GB */
+
+ GIMP_CONFIG_PROP_MEMSIZE (object_class, PROP_TILE_CACHE_SIZE,
+ "tile-cache-size",
+ "Tile cache size",
+ TILE_CACHE_SIZE_BLURB,
+ 0, GIMP_MAX_MEM_PROCESS,
+ memory_size,
+ GIMP_PARAM_STATIC_STRINGS |
+ GIMP_CONFIG_PARAM_CONFIRM);
+
+ GIMP_CONFIG_PROP_BOOLEAN (object_class, PROP_USE_OPENCL,
+ "use-opencl",
+ "Use OpenCL",
+ USE_OPENCL_BLURB,
+ FALSE,
+ GIMP_PARAM_STATIC_STRINGS);
+
+ /* only for backward compatibility: */
+ GIMP_CONFIG_PROP_BOOLEAN (object_class, PROP_STINGY_MEMORY_USE,
+ "stingy-memory-use",
+ NULL, NULL,
+ FALSE,
+ GIMP_CONFIG_PARAM_IGNORE);
+}
+
+static void
+gimp_gegl_config_init (GimpGeglConfig *config)
+{
+}
+
+static void
+gimp_gegl_config_constructed (GObject *object)
+{
+ G_OBJECT_CLASS (parent_class)->constructed (object);
+
+ gimp_debug_add_instance (object, G_OBJECT_GET_CLASS (object));
+}
+
+static void
+gimp_gegl_config_finalize (GObject *object)
+{
+ GimpGeglConfig *gegl_config = GIMP_GEGL_CONFIG (object);
+
+ g_free (gegl_config->temp_path);
+ g_free (gegl_config->swap_path);
+ g_free (gegl_config->swap_compression);
+
+ gimp_debug_remove_instance (object);
+
+ G_OBJECT_CLASS (parent_class)->finalize (object);
+}
+
+static void
+gimp_gegl_config_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ GimpGeglConfig *gegl_config = GIMP_GEGL_CONFIG (object);
+
+ switch (property_id)
+ {
+ case PROP_TEMP_PATH:
+ g_free (gegl_config->temp_path);
+ gegl_config->temp_path = g_value_dup_string (value);
+ break;
+ case PROP_SWAP_PATH:
+ g_free (gegl_config->swap_path);
+ gegl_config->swap_path = g_value_dup_string (value);
+ break;
+ case PROP_SWAP_COMPRESSION:
+ g_free (gegl_config->swap_compression);
+ gegl_config->swap_compression = g_value_dup_string (value);
+ break;
+ case PROP_NUM_PROCESSORS:
+ gegl_config->num_processors = g_value_get_int (value);
+ break;
+ case PROP_TILE_CACHE_SIZE:
+ gegl_config->tile_cache_size = g_value_get_uint64 (value);
+ break;
+ case PROP_USE_OPENCL:
+ gegl_config->use_opencl = g_value_get_boolean (value);
+ break;
+
+ case PROP_STINGY_MEMORY_USE:
+ /* ignored */
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+ break;
+ }
+}
+
+static void
+gimp_gegl_config_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ GimpGeglConfig *gegl_config = GIMP_GEGL_CONFIG (object);
+
+ switch (property_id)
+ {
+ case PROP_TEMP_PATH:
+ g_value_set_string (value, gegl_config->temp_path);
+ break;
+ case PROP_SWAP_PATH:
+ g_value_set_string (value, gegl_config->swap_path);
+ break;
+ case PROP_SWAP_COMPRESSION:
+ g_value_set_string (value, gegl_config->swap_compression);
+ break;
+ case PROP_NUM_PROCESSORS:
+ g_value_set_int (value, gegl_config->num_processors);
+ break;
+ case PROP_TILE_CACHE_SIZE:
+ g_value_set_uint64 (value, gegl_config->tile_cache_size);
+ break;
+ case PROP_USE_OPENCL:
+ g_value_set_boolean (value, gegl_config->use_opencl);
+ break;
+
+ case PROP_STINGY_MEMORY_USE:
+ /* ignored */
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+ break;
+ }
+}
diff --git a/app/config/gimpgeglconfig.h b/app/config/gimpgeglconfig.h
new file mode 100644
index 0000000..4ca948f
--- /dev/null
+++ b/app/config/gimpgeglconfig.h
@@ -0,0 +1,55 @@
+/* GIMP - The GNU Image Manipulation Program
+ * Copyright (C) 1995 Spencer Kimball and Peter Mattis
+ *
+ * GimpGeglConfig class
+ * Copyright (C) 2001 Sven Neumann <sven@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_GEGL_CONFIG_H__
+#define __GIMP_GEGL_CONFIG_H__
+
+
+#define GIMP_TYPE_GEGL_CONFIG (gimp_gegl_config_get_type ())
+#define GIMP_GEGL_CONFIG(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GIMP_TYPE_GEGL_CONFIG, GimpGeglConfig))
+#define GIMP_GEGL_CONFIG_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GIMP_TYPE_GEGL_CONFIG, GimpGeglConfigClass))
+#define GIMP_IS_GEGL_CONFIG(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GIMP_TYPE_GEGL_CONFIG))
+#define GIMP_IS_GEGL_CONFIG_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GIMP_TYPE_GEGL_CONFIG))
+
+
+typedef struct _GimpGeglConfigClass GimpGeglConfigClass;
+
+struct _GimpGeglConfig
+{
+ GObject parent_instance;
+
+ gchar *temp_path;
+ gchar *swap_path;
+ gchar *swap_compression;
+ gint num_processors;
+ guint64 tile_cache_size;
+ gboolean use_opencl;
+};
+
+struct _GimpGeglConfigClass
+{
+ GObjectClass parent_class;
+};
+
+
+GType gimp_gegl_config_get_type (void) G_GNUC_CONST;
+
+
+#endif /* GIMP_GEGL_CONFIG_H__ */
diff --git a/app/config/gimpguiconfig.c b/app/config/gimpguiconfig.c
new file mode 100644
index 0000000..79ff839
--- /dev/null
+++ b/app/config/gimpguiconfig.c
@@ -0,0 +1,1017 @@
+/* GIMP - The GNU Image Manipulation Program
+ * Copyright (C) 1995 Spencer Kimball and Peter Mattis
+ *
+ * GimpGuiConfig class
+ * Copyright (C) 2001 Sven Neumann <sven@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/>.
+ */
+
+#include "config.h"
+
+#include <gio/gio.h>
+
+#include "libgimpbase/gimpbase.h"
+#include "libgimpconfig/gimpconfig.h"
+
+#include "config-types.h"
+
+#include "gimprc-blurbs.h"
+#include "gimpguiconfig.h"
+
+#include "gimp-intl.h"
+
+
+#ifdef HAVE_WEBKIT
+#define DEFAULT_HELP_BROWSER GIMP_HELP_BROWSER_GIMP
+#else
+#define DEFAULT_HELP_BROWSER GIMP_HELP_BROWSER_WEB_BROWSER
+#endif
+
+#define DEFAULT_USER_MANUAL_ONLINE_URI \
+ "https://docs.gimp.org/" GIMP_APP_VERSION_STRING
+
+
+enum
+{
+ SIZE_CHANGED,
+ LAST_SIGNAL
+};
+
+enum
+{
+ PROP_0,
+ PROP_EDIT_NON_VISIBLE,
+ PROP_MOVE_TOOL_CHANGES_ACTIVE,
+ PROP_FILTER_TOOL_MAX_RECENT,
+ PROP_FILTER_TOOL_USE_LAST_SETTINGS,
+ PROP_FILTER_TOOL_SHOW_COLOR_OPTIONS,
+ PROP_TRUST_DIRTY_FLAG,
+ PROP_SAVE_DEVICE_STATUS,
+ PROP_DEVICES_SHARE_TOOL,
+ PROP_SAVE_SESSION_INFO,
+ PROP_RESTORE_SESSION,
+ PROP_RESTORE_MONITOR,
+ PROP_SAVE_TOOL_OPTIONS,
+ PROP_COMPACT_SLIDERS,
+ PROP_SHOW_TOOLTIPS,
+ PROP_TEAROFF_MENUS,
+ PROP_CAN_CHANGE_ACCELS,
+ PROP_SAVE_ACCELS,
+ PROP_RESTORE_ACCELS,
+ PROP_LAST_OPENED_SIZE,
+ PROP_MAX_NEW_IMAGE_SIZE,
+ PROP_TOOLBOX_COLOR_AREA,
+ PROP_TOOLBOX_FOO_AREA,
+ PROP_TOOLBOX_IMAGE_AREA,
+ PROP_TOOLBOX_WILBER,
+ PROP_TOOLBOX_GROUPS,
+ PROP_TOOLBOX_GROUP_MENU_MODE,
+ PROP_THEME_PATH,
+ PROP_THEME,
+ PROP_ICON_THEME_PATH,
+ PROP_ICON_THEME,
+ PROP_ICON_SIZE,
+ PROP_USE_HELP,
+ PROP_SHOW_HELP_BUTTON,
+ PROP_HELP_LOCALES,
+ PROP_HELP_BROWSER,
+ PROP_SEARCH_SHOW_UNAVAILABLE_ACTIONS,
+ PROP_ACTION_HISTORY_SIZE,
+ PROP_USER_MANUAL_ONLINE,
+ PROP_USER_MANUAL_ONLINE_URI,
+ PROP_DOCK_WINDOW_HINT,
+ PROP_CURSOR_HANDEDNESS,
+
+ PROP_PLAYGROUND_NPD_TOOL,
+ PROP_PLAYGROUND_SEAMLESS_CLONE_TOOL,
+
+ PROP_HIDE_DOCKS,
+ PROP_SINGLE_WINDOW_MODE,
+ PROP_SHOW_TABS,
+ PROP_TABS_POSITION,
+ PROP_LAST_TIP_SHOWN,
+
+ /* ignored, only for backward compatibility: */
+ PROP_CURSOR_FORMAT,
+ PROP_IMAGE_MAP_TOOL_MAX_RECENT,
+ PROP_INFO_WINDOW_PER_DISPLAY,
+ PROP_MENU_MNEMONICS,
+ PROP_SHOW_TOOL_TIPS,
+ PROP_SHOW_TIPS,
+ PROP_TOOLBOX_WINDOW_HINT,
+ PROP_TRANSIENT_DOCKS,
+ PROP_WEB_BROWSER
+};
+
+
+static void gimp_gui_config_finalize (GObject *object);
+static void gimp_gui_config_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec);
+static void gimp_gui_config_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec);
+
+static void monitor_resolution_changed (GimpDisplayConfig *display_config,
+ GParamSpec *pspec,
+ GimpGuiConfig *gui_config);
+
+G_DEFINE_TYPE (GimpGuiConfig, gimp_gui_config, GIMP_TYPE_DISPLAY_CONFIG)
+
+#define parent_class gimp_gui_config_parent_class
+
+static guint signals[LAST_SIGNAL] = { 0, };
+
+static void
+gimp_gui_config_class_init (GimpGuiConfigClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+ gchar *path;
+
+ signals[SIZE_CHANGED] =
+ g_signal_new ("size-changed",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_FIRST,
+ G_STRUCT_OFFSET (GimpGuiConfigClass, size_changed),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+
+ object_class->finalize = gimp_gui_config_finalize;
+ object_class->set_property = gimp_gui_config_set_property;
+ object_class->get_property = gimp_gui_config_get_property;
+
+ GIMP_CONFIG_PROP_BOOLEAN (object_class, PROP_EDIT_NON_VISIBLE,
+ "edit-non-visible",
+ "Non-visible layers can be edited",
+ EDIT_NON_VISIBLE_BLURB,
+ FALSE,
+ GIMP_PARAM_STATIC_STRINGS);
+
+ GIMP_CONFIG_PROP_BOOLEAN (object_class, PROP_MOVE_TOOL_CHANGES_ACTIVE,
+ "move-tool-changes-active",
+ "Move tool changes active layer",
+ MOVE_TOOL_CHANGES_ACTIVE_BLURB,
+ FALSE,
+ GIMP_PARAM_STATIC_STRINGS);
+
+ GIMP_CONFIG_PROP_INT (object_class, PROP_FILTER_TOOL_MAX_RECENT,
+ "filter-tool-max-recent",
+ "Max recent settings to keep in filters",
+ FILTER_TOOL_MAX_RECENT_BLURB,
+ 0, 255, 10,
+ GIMP_PARAM_STATIC_STRINGS);
+
+ GIMP_CONFIG_PROP_BOOLEAN (object_class, PROP_FILTER_TOOL_USE_LAST_SETTINGS,
+ "filter-tool-use-last-settings",
+ "Use last used settings in filters",
+ FILTER_TOOL_USE_LAST_SETTINGS_BLURB,
+ FALSE,
+ GIMP_PARAM_STATIC_STRINGS);
+
+ GIMP_CONFIG_PROP_BOOLEAN (object_class, PROP_FILTER_TOOL_SHOW_COLOR_OPTIONS,
+ "filter-tool-show-color-options",
+ "Show avanced color options in filters",
+ FILTER_TOOL_SHOW_COLOR_OPTIONS_BLURB,
+ FALSE,
+ GIMP_PARAM_STATIC_STRINGS);
+
+ GIMP_CONFIG_PROP_BOOLEAN (object_class, PROP_TRUST_DIRTY_FLAG,
+ "trust-dirty-flag",
+ "Trust dirty flag",
+ TRUST_DIRTY_FLAG_BLURB,
+ FALSE,
+ GIMP_PARAM_STATIC_STRINGS);
+
+ GIMP_CONFIG_PROP_BOOLEAN (object_class, PROP_SAVE_DEVICE_STATUS,
+ "save-device-status",
+ "Save device status",
+ SAVE_DEVICE_STATUS_BLURB,
+ TRUE,
+ GIMP_PARAM_STATIC_STRINGS);
+
+ GIMP_CONFIG_PROP_BOOLEAN (object_class, PROP_DEVICES_SHARE_TOOL,
+ "devices-share-tool",
+ "Devices share tool",
+ DEVICES_SHARE_TOOL_BLURB,
+ FALSE,
+ GIMP_PARAM_STATIC_STRINGS);
+
+ GIMP_CONFIG_PROP_BOOLEAN (object_class, PROP_SAVE_SESSION_INFO,
+ "save-session-info",
+ "Save session",
+ SAVE_SESSION_INFO_BLURB,
+ TRUE,
+ GIMP_PARAM_STATIC_STRINGS);
+
+ GIMP_CONFIG_PROP_BOOLEAN (object_class, PROP_RESTORE_SESSION,
+ "restore-session",
+ "Restore session",
+ RESTORE_SESSION_BLURB,
+ TRUE,
+ GIMP_PARAM_STATIC_STRINGS);
+
+ GIMP_CONFIG_PROP_BOOLEAN (object_class, PROP_RESTORE_MONITOR,
+ "restore-monitor",
+ "Restore monitor",
+ RESTORE_MONITOR_BLURB,
+ FALSE,
+ GIMP_PARAM_STATIC_STRINGS);
+
+ GIMP_CONFIG_PROP_BOOLEAN (object_class, PROP_SAVE_TOOL_OPTIONS,
+ "save-tool-options",
+ "Save tool options",
+ SAVE_TOOL_OPTIONS_BLURB,
+ TRUE,
+ GIMP_PARAM_STATIC_STRINGS);
+
+ GIMP_CONFIG_PROP_BOOLEAN (object_class, PROP_COMPACT_SLIDERS,
+ "compact-sliders",
+ "Compact sliders",
+ COMPACT_SLIDERS_BLURB,
+ TRUE,
+ GIMP_PARAM_STATIC_STRINGS);
+
+ GIMP_CONFIG_PROP_BOOLEAN (object_class, PROP_SHOW_TOOLTIPS,
+ "show-tooltips",
+ "Show tooltips",
+ SHOW_TOOLTIPS_BLURB,
+ TRUE,
+ GIMP_PARAM_STATIC_STRINGS |
+ GIMP_CONFIG_PARAM_RESTART);
+
+ GIMP_CONFIG_PROP_BOOLEAN (object_class, PROP_TEAROFF_MENUS,
+ "tearoff-menus",
+ "Tearoff menus",
+ TEAROFF_MENUS_BLURB,
+ TRUE,
+ GIMP_PARAM_STATIC_STRINGS);
+
+ GIMP_CONFIG_PROP_BOOLEAN (object_class, PROP_CAN_CHANGE_ACCELS,
+ "can-change-accels",
+ "Can change accelerators",
+ CAN_CHANGE_ACCELS_BLURB,
+ FALSE,
+ GIMP_PARAM_STATIC_STRINGS);
+
+ GIMP_CONFIG_PROP_BOOLEAN (object_class, PROP_SAVE_ACCELS,
+ "save-accels",
+ "Save accelerators",
+ SAVE_ACCELS_BLURB,
+ TRUE,
+ GIMP_PARAM_STATIC_STRINGS);
+
+ GIMP_CONFIG_PROP_BOOLEAN (object_class, PROP_RESTORE_ACCELS,
+ "restore-accels",
+ "Restore acclerator",
+ RESTORE_ACCELS_BLURB,
+ TRUE,
+ GIMP_PARAM_STATIC_STRINGS);
+
+ GIMP_CONFIG_PROP_INT (object_class, PROP_LAST_OPENED_SIZE,
+ "last-opened-size",
+ "Size of recently used menu",
+ LAST_OPENED_SIZE_BLURB,
+ 0, 1024, 10,
+ GIMP_PARAM_STATIC_STRINGS |
+ GIMP_CONFIG_PARAM_RESTART);
+
+ GIMP_CONFIG_PROP_MEMSIZE (object_class, PROP_MAX_NEW_IMAGE_SIZE,
+ "max-new-image-size",
+ "Maximum new image size",
+ MAX_NEW_IMAGE_SIZE_BLURB,
+ 0, GIMP_MAX_MEMSIZE, 1 << 27, /* 128MB */
+ GIMP_PARAM_STATIC_STRINGS);
+
+ GIMP_CONFIG_PROP_BOOLEAN (object_class, PROP_TOOLBOX_COLOR_AREA,
+ "toolbox-color-area",
+ "Show toolbox color area",
+ TOOLBOX_COLOR_AREA_BLURB,
+ TRUE,
+ GIMP_PARAM_STATIC_STRINGS);
+
+ GIMP_CONFIG_PROP_BOOLEAN (object_class, PROP_TOOLBOX_FOO_AREA,
+ "toolbox-foo-area",
+ "Show toolbox foo area",
+ TOOLBOX_FOO_AREA_BLURB,
+ FALSE,
+ GIMP_PARAM_STATIC_STRINGS);
+
+ GIMP_CONFIG_PROP_BOOLEAN (object_class, PROP_TOOLBOX_IMAGE_AREA,
+ "toolbox-image-area",
+ "Show toolbox image area",
+ TOOLBOX_IMAGE_AREA_BLURB,
+ FALSE,
+ GIMP_PARAM_STATIC_STRINGS);
+
+ GIMP_CONFIG_PROP_BOOLEAN (object_class, PROP_TOOLBOX_WILBER,
+ "toolbox-wilber",
+ "Show toolbox wilber",
+ TOOLBOX_WILBER_BLURB,
+ TRUE,
+ GIMP_PARAM_STATIC_STRINGS);
+
+ GIMP_CONFIG_PROP_BOOLEAN (object_class, PROP_TOOLBOX_GROUPS,
+ "toolbox-groups",
+ "Use toolbox groups",
+ TOOLBOX_GROUPS_BLURB,
+ TRUE,
+ GIMP_PARAM_STATIC_STRINGS);
+
+ GIMP_CONFIG_PROP_ENUM (object_class, PROP_TOOLBOX_GROUP_MENU_MODE,
+ "toolbox-group-menu-mode",
+ "Toolbox group menu mode",
+ TOOLBOX_GROUP_MENU_MODE_BLURB,
+ GIMP_TYPE_TOOL_GROUP_MENU_MODE,
+ GIMP_TOOL_GROUP_MENU_MODE_SHOW_ON_HOVER_SINGLE_COLUMN,
+ GIMP_PARAM_STATIC_STRINGS);
+
+ path = gimp_config_build_data_path ("themes");
+ GIMP_CONFIG_PROP_PATH (object_class, PROP_THEME_PATH,
+ "theme-path",
+ "Theme path",
+ THEME_PATH_BLURB,
+ GIMP_CONFIG_PATH_DIR_LIST, path,
+ GIMP_PARAM_STATIC_STRINGS |
+ GIMP_CONFIG_PARAM_RESTART);
+ g_free (path);
+
+ GIMP_CONFIG_PROP_STRING (object_class, PROP_THEME,
+ "theme",
+ "Theme",
+ THEME_BLURB,
+ GIMP_CONFIG_DEFAULT_THEME,
+ GIMP_PARAM_STATIC_STRINGS);
+
+ path = gimp_config_build_data_path ("icons");
+ GIMP_CONFIG_PROP_PATH (object_class, PROP_ICON_THEME_PATH,
+ "icon-theme-path",
+ "Icon theme path",
+ ICON_THEME_PATH_BLURB,
+ GIMP_CONFIG_PATH_DIR_LIST, path,
+ GIMP_PARAM_STATIC_STRINGS |
+ GIMP_CONFIG_PARAM_RESTART);
+ g_free (path);
+
+ GIMP_CONFIG_PROP_STRING (object_class, PROP_ICON_THEME,
+ "icon-theme",
+ "Icon theme",
+ ICON_THEME_BLURB,
+ GIMP_CONFIG_DEFAULT_ICON_THEME,
+ GIMP_PARAM_STATIC_STRINGS);
+ GIMP_CONFIG_PROP_ENUM (object_class, PROP_ICON_SIZE,
+ "icon-size",
+ "icon-size",
+ ICON_SIZE_BLURB,
+ GIMP_TYPE_ICON_SIZE,
+ GIMP_ICON_SIZE_AUTO,
+ GIMP_PARAM_STATIC_STRINGS);
+
+ GIMP_CONFIG_PROP_BOOLEAN (object_class, PROP_USE_HELP,
+ "use-help",
+ "Use help",
+ USE_HELP_BLURB,
+ TRUE,
+ GIMP_PARAM_STATIC_STRINGS);
+
+ GIMP_CONFIG_PROP_BOOLEAN (object_class, PROP_SHOW_HELP_BUTTON,
+ "show-help-button",
+ "Show help button",
+ SHOW_HELP_BUTTON_BLURB,
+ TRUE,
+ GIMP_PARAM_STATIC_STRINGS);
+
+ GIMP_CONFIG_PROP_STRING (object_class, PROP_HELP_LOCALES,
+ "help-locales",
+ "Help locales",
+ HELP_LOCALES_BLURB,
+ "",
+ GIMP_PARAM_STATIC_STRINGS);
+
+ GIMP_CONFIG_PROP_ENUM (object_class, PROP_HELP_BROWSER,
+ "help-browser",
+ "Help browser",
+ HELP_BROWSER_BLURB,
+ GIMP_TYPE_HELP_BROWSER_TYPE,
+ DEFAULT_HELP_BROWSER,
+ GIMP_PARAM_STATIC_STRINGS);
+
+ GIMP_CONFIG_PROP_BOOLEAN (object_class, PROP_USER_MANUAL_ONLINE,
+ "user-manual-online",
+ "User manual online",
+ USER_MANUAL_ONLINE_BLURB,
+ FALSE,
+ GIMP_PARAM_STATIC_STRINGS);
+
+ GIMP_CONFIG_PROP_STRING (object_class, PROP_USER_MANUAL_ONLINE_URI,
+ "user-manual-online-uri",
+ "User manual online URI",
+ USER_MANUAL_ONLINE_URI_BLURB,
+ DEFAULT_USER_MANUAL_ONLINE_URI,
+ GIMP_PARAM_STATIC_STRINGS);
+
+ GIMP_CONFIG_PROP_BOOLEAN (object_class, PROP_SEARCH_SHOW_UNAVAILABLE_ACTIONS,
+ "search-show-unavailable-actions",
+ "Show unavailable actions",
+ SEARCH_SHOW_UNAVAILABLE_BLURB,
+ FALSE,
+ GIMP_PARAM_STATIC_STRINGS);
+
+ GIMP_CONFIG_PROP_INT (object_class, PROP_ACTION_HISTORY_SIZE,
+ "action-history-size",
+ "Action history size",
+ ACTION_HISTORY_SIZE_BLURB,
+ 0, 1000, 100,
+ GIMP_PARAM_STATIC_STRINGS);
+
+ GIMP_CONFIG_PROP_ENUM (object_class, PROP_DOCK_WINDOW_HINT,
+ "dock-window-hint",
+ "Dock window hint",
+ DOCK_WINDOW_HINT_BLURB,
+ GIMP_TYPE_WINDOW_HINT,
+ GIMP_WINDOW_HINT_UTILITY,
+ GIMP_PARAM_STATIC_STRINGS |
+ GIMP_CONFIG_PARAM_RESTART);
+
+ GIMP_CONFIG_PROP_ENUM (object_class, PROP_CURSOR_HANDEDNESS,
+ "cursor-handedness",
+ "Cursor handedness",
+ CURSOR_HANDEDNESS_BLURB,
+ GIMP_TYPE_HANDEDNESS,
+ GIMP_HANDEDNESS_RIGHT,
+ GIMP_PARAM_STATIC_STRINGS);
+
+ GIMP_CONFIG_PROP_BOOLEAN (object_class, PROP_PLAYGROUND_NPD_TOOL,
+ "playground-npd-tool",
+ "Playground N-Point Deformation tool",
+ PLAYGROUND_NPD_TOOL_BLURB,
+ FALSE,
+ GIMP_PARAM_STATIC_STRINGS |
+ GIMP_CONFIG_PARAM_RESTART);
+
+ GIMP_CONFIG_PROP_BOOLEAN (object_class,
+ PROP_PLAYGROUND_SEAMLESS_CLONE_TOOL,
+ "playground-seamless-clone-tool",
+ "Playground Seamless Clone tool",
+ PLAYGROUND_SEAMLESS_CLONE_TOOL_BLURB,
+ FALSE,
+ GIMP_PARAM_STATIC_STRINGS |
+ GIMP_CONFIG_PARAM_RESTART);
+
+ g_object_class_install_property (object_class, PROP_HIDE_DOCKS,
+ g_param_spec_boolean ("hide-docks",
+ NULL,
+ HIDE_DOCKS_BLURB,
+ FALSE,
+ G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT |
+ GIMP_PARAM_STATIC_STRINGS));
+
+ g_object_class_install_property (object_class, PROP_SINGLE_WINDOW_MODE,
+ g_param_spec_boolean ("single-window-mode",
+ NULL,
+ SINGLE_WINDOW_MODE_BLURB,
+ TRUE,
+ G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT |
+ GIMP_PARAM_STATIC_STRINGS));
+
+ g_object_class_install_property (object_class, PROP_SHOW_TABS,
+ g_param_spec_boolean ("show-tabs",
+ NULL,
+ SHOW_TABS_BLURB,
+ TRUE,
+ G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT |
+ GIMP_PARAM_STATIC_STRINGS));
+
+ g_object_class_install_property (object_class, PROP_TABS_POSITION,
+ g_param_spec_enum ("tabs-position", NULL, NULL,
+ GIMP_TYPE_POSITION,
+ GIMP_POSITION_TOP,
+ G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT |
+ GIMP_PARAM_STATIC_STRINGS));
+
+ g_object_class_install_property (object_class, PROP_LAST_TIP_SHOWN,
+ g_param_spec_int ("last-tip-shown",
+ NULL, NULL,
+ 0, G_MAXINT, 0,
+ G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT |
+ GIMP_PARAM_STATIC_STRINGS));
+
+ /* only for backward compatibility: */
+ GIMP_CONFIG_PROP_ENUM (object_class, PROP_CURSOR_FORMAT,
+ "cursor-format",
+ NULL, NULL,
+ GIMP_TYPE_CURSOR_FORMAT,
+ GIMP_CURSOR_FORMAT_PIXBUF,
+ GIMP_PARAM_STATIC_STRINGS |
+ GIMP_CONFIG_PARAM_IGNORE);
+
+ GIMP_CONFIG_PROP_INT (object_class, PROP_IMAGE_MAP_TOOL_MAX_RECENT,
+ "image-map-tool-max-recent",
+ NULL, NULL,
+ 0, 255, 10,
+ GIMP_PARAM_STATIC_STRINGS |
+ GIMP_CONFIG_PARAM_IGNORE);
+
+ GIMP_CONFIG_PROP_BOOLEAN (object_class, PROP_INFO_WINDOW_PER_DISPLAY,
+ "info-window-per-display",
+ NULL, NULL,
+ FALSE,
+ GIMP_PARAM_STATIC_STRINGS |
+ GIMP_CONFIG_PARAM_IGNORE);
+
+ GIMP_CONFIG_PROP_BOOLEAN (object_class, PROP_MENU_MNEMONICS,
+ "menu-mnemonics",
+ NULL, NULL,
+ TRUE,
+ GIMP_PARAM_STATIC_STRINGS |
+ GIMP_CONFIG_PARAM_IGNORE);
+
+ GIMP_CONFIG_PROP_BOOLEAN (object_class, PROP_SHOW_TOOL_TIPS,
+ "show-tool-tips",
+ NULL, NULL,
+ FALSE,
+ GIMP_PARAM_STATIC_STRINGS |
+ GIMP_CONFIG_PARAM_IGNORE);
+
+ GIMP_CONFIG_PROP_BOOLEAN (object_class, PROP_SHOW_TIPS,
+ "show-tips",
+ NULL, NULL,
+ FALSE,
+ GIMP_PARAM_STATIC_STRINGS |
+ GIMP_CONFIG_PARAM_IGNORE);
+
+ GIMP_CONFIG_PROP_ENUM (object_class, PROP_TOOLBOX_WINDOW_HINT,
+ "toolbox-window-hint",
+ NULL, NULL,
+ GIMP_TYPE_WINDOW_HINT,
+ GIMP_WINDOW_HINT_UTILITY,
+ GIMP_PARAM_STATIC_STRINGS |
+ GIMP_CONFIG_PARAM_IGNORE);
+
+ GIMP_CONFIG_PROP_BOOLEAN (object_class, PROP_TRANSIENT_DOCKS,
+ "transient-docks",
+ NULL, NULL,
+ FALSE,
+ GIMP_PARAM_STATIC_STRINGS |
+ GIMP_CONFIG_PARAM_IGNORE);
+
+ GIMP_CONFIG_PROP_PATH (object_class, PROP_WEB_BROWSER,
+ "web-browser",
+ NULL, NULL,
+ GIMP_CONFIG_PATH_FILE,
+ "not used any longer",
+ GIMP_PARAM_STATIC_STRINGS |
+ GIMP_CONFIG_PARAM_IGNORE);
+}
+
+static void
+gimp_gui_config_init (GimpGuiConfig *config)
+{
+}
+
+static void
+gimp_gui_config_finalize (GObject *object)
+{
+ GimpGuiConfig *gui_config = GIMP_GUI_CONFIG (object);
+
+ g_free (gui_config->theme_path);
+ g_free (gui_config->theme);
+ g_free (gui_config->icon_theme_path);
+ g_free (gui_config->icon_theme);
+ g_free (gui_config->help_locales);
+ g_free (gui_config->user_manual_online_uri);
+
+ G_OBJECT_CLASS (parent_class)->finalize (object);
+}
+
+static void
+gimp_gui_config_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ GimpGuiConfig *gui_config = GIMP_GUI_CONFIG (object);
+
+ switch (property_id)
+ {
+ case PROP_EDIT_NON_VISIBLE:
+ gui_config->edit_non_visible = g_value_get_boolean (value);
+ break;
+ case PROP_MOVE_TOOL_CHANGES_ACTIVE:
+ gui_config->move_tool_changes_active = g_value_get_boolean (value);
+ break;
+ case PROP_FILTER_TOOL_MAX_RECENT:
+ case PROP_IMAGE_MAP_TOOL_MAX_RECENT:
+ gui_config->filter_tool_max_recent = g_value_get_int (value);
+ break;
+ case PROP_FILTER_TOOL_USE_LAST_SETTINGS:
+ gui_config->filter_tool_use_last_settings = g_value_get_boolean (value);
+ break;
+ case PROP_FILTER_TOOL_SHOW_COLOR_OPTIONS:
+ gui_config->filter_tool_show_color_options = g_value_get_boolean (value);
+ break;
+ case PROP_TRUST_DIRTY_FLAG:
+ gui_config->trust_dirty_flag = g_value_get_boolean (value);
+ break;
+ case PROP_SAVE_DEVICE_STATUS:
+ gui_config->save_device_status = g_value_get_boolean (value);
+ break;
+ case PROP_DEVICES_SHARE_TOOL:
+ gui_config->devices_share_tool = g_value_get_boolean (value);
+ break;
+ case PROP_SAVE_SESSION_INFO:
+ gui_config->save_session_info = g_value_get_boolean (value);
+ break;
+ case PROP_RESTORE_SESSION:
+ gui_config->restore_session = g_value_get_boolean (value);
+ break;
+ case PROP_RESTORE_MONITOR:
+ gui_config->restore_monitor = g_value_get_boolean (value);
+ break;
+ case PROP_SAVE_TOOL_OPTIONS:
+ gui_config->save_tool_options = g_value_get_boolean (value);
+ break;
+ case PROP_COMPACT_SLIDERS:
+ gui_config->compact_sliders = g_value_get_boolean (value);
+ break;
+ case PROP_SHOW_TOOLTIPS:
+ gui_config->show_tooltips = g_value_get_boolean (value);
+ break;
+ case PROP_TEAROFF_MENUS:
+ gui_config->tearoff_menus = g_value_get_boolean (value);
+ break;
+ case PROP_CAN_CHANGE_ACCELS:
+ gui_config->can_change_accels = g_value_get_boolean (value);
+ break;
+ case PROP_SAVE_ACCELS:
+ gui_config->save_accels = g_value_get_boolean (value);
+ break;
+ case PROP_RESTORE_ACCELS:
+ gui_config->restore_accels = g_value_get_boolean (value);
+ break;
+ case PROP_LAST_OPENED_SIZE:
+ gui_config->last_opened_size = g_value_get_int (value);
+ break;
+ case PROP_MAX_NEW_IMAGE_SIZE:
+ gui_config->max_new_image_size = g_value_get_uint64 (value);
+ break;
+ case PROP_TOOLBOX_COLOR_AREA:
+ gui_config->toolbox_color_area = g_value_get_boolean (value);
+ break;
+ case PROP_TOOLBOX_FOO_AREA:
+ gui_config->toolbox_foo_area = g_value_get_boolean (value);
+ break;
+ case PROP_TOOLBOX_IMAGE_AREA:
+ gui_config->toolbox_image_area = g_value_get_boolean (value);
+ break;
+ case PROP_TOOLBOX_WILBER:
+ gui_config->toolbox_wilber = g_value_get_boolean (value);
+ break;
+ case PROP_TOOLBOX_GROUPS:
+ gui_config->toolbox_groups = g_value_get_boolean (value);
+ break;
+ case PROP_TOOLBOX_GROUP_MENU_MODE:
+ gui_config->toolbox_group_menu_mode = g_value_get_enum (value);
+ break;
+ case PROP_THEME_PATH:
+ g_free (gui_config->theme_path);
+ gui_config->theme_path = g_value_dup_string (value);
+ break;
+ case PROP_THEME:
+ g_free (gui_config->theme);
+ gui_config->theme = g_value_dup_string (value);
+ break;
+ case PROP_ICON_THEME_PATH:
+ g_free (gui_config->icon_theme_path);
+ gui_config->icon_theme_path = g_value_dup_string (value);
+ break;
+ case PROP_ICON_THEME:
+ g_free (gui_config->icon_theme);
+ gui_config->icon_theme = g_value_dup_string (value);
+ break;
+ case PROP_ICON_SIZE:
+ {
+ GimpIconSize size = g_value_get_enum (value);
+
+ g_signal_handlers_disconnect_by_func (GIMP_DISPLAY_CONFIG (gui_config),
+ G_CALLBACK (monitor_resolution_changed),
+ gui_config);
+ if (size == GIMP_ICON_SIZE_AUTO)
+ {
+ g_signal_connect (GIMP_DISPLAY_CONFIG (gui_config),
+ "notify::monitor-xresolution",
+ G_CALLBACK (monitor_resolution_changed),
+ gui_config);
+ g_signal_connect (GIMP_DISPLAY_CONFIG (gui_config),
+ "notify::monitor-yresolution",
+ G_CALLBACK (monitor_resolution_changed),
+ gui_config);
+ }
+ gui_config->icon_size = size;
+ g_signal_emit (gui_config, signals[SIZE_CHANGED], 0);
+ }
+ break;
+ case PROP_USE_HELP:
+ gui_config->use_help = g_value_get_boolean (value);
+ break;
+ case PROP_SHOW_HELP_BUTTON:
+ gui_config->show_help_button = g_value_get_boolean (value);
+ break;
+ case PROP_HELP_LOCALES:
+ g_free (gui_config->help_locales);
+ gui_config->help_locales = g_value_dup_string (value);
+ break;
+ case PROP_HELP_BROWSER:
+ gui_config->help_browser = g_value_get_enum (value);
+ break;
+ case PROP_USER_MANUAL_ONLINE:
+ gui_config->user_manual_online = g_value_get_boolean (value);
+ break;
+ case PROP_USER_MANUAL_ONLINE_URI:
+ g_free (gui_config->user_manual_online_uri);
+ gui_config->user_manual_online_uri = g_value_dup_string (value);
+ break;
+ case PROP_SEARCH_SHOW_UNAVAILABLE_ACTIONS:
+ gui_config->search_show_unavailable = g_value_get_boolean (value);
+ break;
+ case PROP_ACTION_HISTORY_SIZE:
+ gui_config->action_history_size = g_value_get_int (value);
+ break;
+ case PROP_DOCK_WINDOW_HINT:
+ gui_config->dock_window_hint = g_value_get_enum (value);
+ break;
+ case PROP_CURSOR_HANDEDNESS:
+ gui_config->cursor_handedness = g_value_get_enum (value);
+ break;
+
+ case PROP_PLAYGROUND_NPD_TOOL:
+ gui_config->playground_npd_tool = g_value_get_boolean (value);
+ break;
+ case PROP_PLAYGROUND_SEAMLESS_CLONE_TOOL:
+ gui_config->playground_seamless_clone_tool = g_value_get_boolean (value);
+ break;
+
+ case PROP_HIDE_DOCKS:
+ gui_config->hide_docks = g_value_get_boolean (value);
+ break;
+ case PROP_SINGLE_WINDOW_MODE:
+ gui_config->single_window_mode = g_value_get_boolean (value);
+ break;
+ case PROP_SHOW_TABS:
+ gui_config->show_tabs = g_value_get_boolean (value);
+ break;
+ case PROP_TABS_POSITION:
+ gui_config->tabs_position = g_value_get_enum (value);
+ break;
+ case PROP_LAST_TIP_SHOWN:
+ gui_config->last_tip_shown = g_value_get_int (value);
+ break;
+
+ case PROP_CURSOR_FORMAT:
+ case PROP_INFO_WINDOW_PER_DISPLAY:
+ case PROP_MENU_MNEMONICS:
+ case PROP_SHOW_TOOL_TIPS:
+ case PROP_SHOW_TIPS:
+ case PROP_TOOLBOX_WINDOW_HINT:
+ case PROP_TRANSIENT_DOCKS:
+ case PROP_WEB_BROWSER:
+ /* ignored */
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+ break;
+ }
+}
+
+static void
+gimp_gui_config_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ GimpGuiConfig *gui_config = GIMP_GUI_CONFIG (object);
+
+ switch (property_id)
+ {
+ case PROP_EDIT_NON_VISIBLE:
+ g_value_set_boolean (value, gui_config->edit_non_visible);
+ break;
+ case PROP_MOVE_TOOL_CHANGES_ACTIVE:
+ g_value_set_boolean (value, gui_config->move_tool_changes_active);
+ break;
+ case PROP_FILTER_TOOL_MAX_RECENT:
+ case PROP_IMAGE_MAP_TOOL_MAX_RECENT:
+ g_value_set_int (value, gui_config->filter_tool_max_recent);
+ break;
+ case PROP_FILTER_TOOL_USE_LAST_SETTINGS:
+ g_value_set_boolean (value, gui_config->filter_tool_use_last_settings);
+ break;
+ case PROP_FILTER_TOOL_SHOW_COLOR_OPTIONS:
+ g_value_set_boolean (value, gui_config->filter_tool_show_color_options);
+ break;
+ case PROP_TRUST_DIRTY_FLAG:
+ g_value_set_boolean (value, gui_config->trust_dirty_flag);
+ break;
+ case PROP_SAVE_DEVICE_STATUS:
+ g_value_set_boolean (value, gui_config->save_device_status);
+ break;
+ case PROP_DEVICES_SHARE_TOOL:
+ g_value_set_boolean (value, gui_config->devices_share_tool);
+ break;
+ case PROP_SAVE_SESSION_INFO:
+ g_value_set_boolean (value, gui_config->save_session_info);
+ break;
+ case PROP_RESTORE_SESSION:
+ g_value_set_boolean (value, gui_config->restore_session);
+ break;
+ case PROP_RESTORE_MONITOR:
+ g_value_set_boolean (value, gui_config->restore_monitor);
+ break;
+ case PROP_SAVE_TOOL_OPTIONS:
+ g_value_set_boolean (value, gui_config->save_tool_options);
+ break;
+ case PROP_COMPACT_SLIDERS:
+ g_value_set_boolean (value, gui_config->compact_sliders);
+ break;
+ case PROP_SHOW_TOOLTIPS:
+ g_value_set_boolean (value, gui_config->show_tooltips);
+ break;
+ case PROP_TEAROFF_MENUS:
+ g_value_set_boolean (value, gui_config->tearoff_menus);
+ break;
+ case PROP_CAN_CHANGE_ACCELS:
+ g_value_set_boolean (value, gui_config->can_change_accels);
+ break;
+ case PROP_SAVE_ACCELS:
+ g_value_set_boolean (value, gui_config->save_accels);
+ break;
+ case PROP_RESTORE_ACCELS:
+ g_value_set_boolean (value, gui_config->restore_accels);
+ break;
+ case PROP_LAST_OPENED_SIZE:
+ g_value_set_int (value, gui_config->last_opened_size);
+ break;
+ case PROP_MAX_NEW_IMAGE_SIZE:
+ g_value_set_uint64 (value, gui_config->max_new_image_size);
+ break;
+ case PROP_TOOLBOX_COLOR_AREA:
+ g_value_set_boolean (value, gui_config->toolbox_color_area);
+ break;
+ case PROP_TOOLBOX_FOO_AREA:
+ g_value_set_boolean (value, gui_config->toolbox_foo_area);
+ break;
+ case PROP_TOOLBOX_IMAGE_AREA:
+ g_value_set_boolean (value, gui_config->toolbox_image_area);
+ break;
+ case PROP_TOOLBOX_WILBER:
+ g_value_set_boolean (value, gui_config->toolbox_wilber);
+ break;
+ case PROP_TOOLBOX_GROUPS:
+ g_value_set_boolean (value, gui_config->toolbox_groups);
+ break;
+ case PROP_TOOLBOX_GROUP_MENU_MODE:
+ g_value_set_enum (value, gui_config->toolbox_group_menu_mode);
+ break;
+ case PROP_THEME_PATH:
+ g_value_set_string (value, gui_config->theme_path);
+ break;
+ case PROP_THEME:
+ g_value_set_string (value, gui_config->theme);
+ break;
+ case PROP_ICON_THEME_PATH:
+ g_value_set_string (value, gui_config->icon_theme_path);
+ break;
+ case PROP_ICON_THEME:
+ g_value_set_string (value, gui_config->icon_theme);
+ break;
+ case PROP_ICON_SIZE:
+ g_value_set_enum (value, gui_config->icon_size);
+ break;
+ case PROP_USE_HELP:
+ g_value_set_boolean (value, gui_config->use_help);
+ break;
+ case PROP_SHOW_HELP_BUTTON:
+ g_value_set_boolean (value, gui_config->show_help_button);
+ break;
+ case PROP_HELP_LOCALES:
+ g_value_set_string (value, gui_config->help_locales);
+ break;
+ case PROP_HELP_BROWSER:
+ g_value_set_enum (value, gui_config->help_browser);
+ break;
+ case PROP_USER_MANUAL_ONLINE:
+ g_value_set_boolean (value, gui_config->user_manual_online);
+ break;
+ case PROP_USER_MANUAL_ONLINE_URI:
+ g_value_set_string (value, gui_config->user_manual_online_uri);
+ break;
+ case PROP_SEARCH_SHOW_UNAVAILABLE_ACTIONS:
+ g_value_set_boolean (value, gui_config->search_show_unavailable);
+ break;
+ case PROP_ACTION_HISTORY_SIZE:
+ g_value_set_int (value, gui_config->action_history_size);
+ break;
+ case PROP_DOCK_WINDOW_HINT:
+ g_value_set_enum (value, gui_config->dock_window_hint);
+ break;
+ case PROP_CURSOR_HANDEDNESS:
+ g_value_set_enum (value, gui_config->cursor_handedness);
+ break;
+
+ case PROP_PLAYGROUND_NPD_TOOL:
+ g_value_set_boolean (value, gui_config->playground_npd_tool);
+ break;
+ case PROP_PLAYGROUND_SEAMLESS_CLONE_TOOL:
+ g_value_set_boolean (value, gui_config->playground_seamless_clone_tool);
+ break;
+
+ case PROP_HIDE_DOCKS:
+ g_value_set_boolean (value, gui_config->hide_docks);
+ break;
+ case PROP_SINGLE_WINDOW_MODE:
+ g_value_set_boolean (value, gui_config->single_window_mode);
+ break;
+ case PROP_SHOW_TABS:
+ g_value_set_boolean (value, gui_config->show_tabs);
+ break;
+ case PROP_TABS_POSITION:
+ g_value_set_enum (value, gui_config->tabs_position);
+ break;
+ case PROP_LAST_TIP_SHOWN:
+ g_value_set_int (value, gui_config->last_tip_shown);
+ break;
+
+ case PROP_CURSOR_FORMAT:
+ case PROP_INFO_WINDOW_PER_DISPLAY:
+ case PROP_MENU_MNEMONICS:
+ case PROP_SHOW_TOOL_TIPS:
+ case PROP_SHOW_TIPS:
+ case PROP_TOOLBOX_WINDOW_HINT:
+ case PROP_TRANSIENT_DOCKS:
+ case PROP_WEB_BROWSER:
+ /* ignored */
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+ break;
+ }
+}
+
+static void
+monitor_resolution_changed (GimpDisplayConfig *display_config,
+ GParamSpec *pspec,
+ GimpGuiConfig *gui_config)
+{
+ if (gui_config->icon_size == GIMP_ICON_SIZE_AUTO)
+ {
+ g_signal_emit (gui_config, signals[SIZE_CHANGED], 0);
+ }
+}
+
+GimpIconSize
+gimp_gui_config_detect_icon_size (GimpGuiConfig *gui_config)
+{
+ GimpIconSize size = gui_config->icon_size;
+
+ if (size == GIMP_ICON_SIZE_AUTO)
+ {
+ GimpDisplayConfig *display_config;
+
+ display_config = GIMP_DISPLAY_CONFIG (gui_config);
+
+ if (display_config->monitor_xres < 100.0 ||
+ display_config->monitor_yres < 100.0)
+ size = GIMP_ICON_SIZE_SMALL;
+ else if (display_config->monitor_xres < 192.0 ||
+ display_config->monitor_yres < 192.0)
+ size = GIMP_ICON_SIZE_MEDIUM;
+ else if (display_config->monitor_xres < 250.0 ||
+ display_config->monitor_yres < 250.0)
+ size = GIMP_ICON_SIZE_LARGE;
+ else
+ size = GIMP_ICON_SIZE_HUGE;
+ }
+
+ return size;
+}
diff --git a/app/config/gimpguiconfig.h b/app/config/gimpguiconfig.h
new file mode 100644
index 0000000..b2a25ee
--- /dev/null
+++ b/app/config/gimpguiconfig.h
@@ -0,0 +1,110 @@
+/* GIMP - The GNU Image Manipulation Program
+ * Copyright (C) 1995 Spencer Kimball and Peter Mattis
+ *
+ * GimpGuiConfig class
+ * Copyright (C) 2001 Sven Neumann <sven@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_GUI_CONFIG_H__
+#define __GIMP_GUI_CONFIG_H__
+
+#include "config/gimpdisplayconfig.h"
+
+
+#define GIMP_CONFIG_DEFAULT_THEME "Dark"
+#define GIMP_CONFIG_DEFAULT_ICON_THEME "Symbolic"
+
+
+#define GIMP_TYPE_GUI_CONFIG (gimp_gui_config_get_type ())
+#define GIMP_GUI_CONFIG(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GIMP_TYPE_GUI_CONFIG, GimpGuiConfig))
+#define GIMP_GUI_CONFIG_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GIMP_TYPE_GUI_CONFIG, GimpGuiConfigClass))
+#define GIMP_IS_GUI_CONFIG(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GIMP_TYPE_GUI_CONFIG))
+#define GIMP_IS_GUI_CONFIG_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GIMP_TYPE_GUI_CONFIG))
+
+
+typedef struct _GimpGuiConfigClass GimpGuiConfigClass;
+
+struct _GimpGuiConfig
+{
+ GimpDisplayConfig parent_instance;
+
+ gboolean edit_non_visible;
+ gboolean move_tool_changes_active;
+ gint filter_tool_max_recent;
+ gboolean filter_tool_use_last_settings;
+ gboolean filter_tool_show_color_options;
+ gboolean trust_dirty_flag;
+ gboolean save_device_status;
+ gboolean devices_share_tool;
+ gboolean save_session_info;
+ gboolean restore_session;
+ gboolean restore_monitor;
+ gboolean save_tool_options;
+ gboolean compact_sliders;
+ gboolean show_tooltips;
+ gboolean tearoff_menus;
+ gboolean can_change_accels;
+ gboolean save_accels;
+ gboolean restore_accels;
+ gint last_opened_size;
+ guint64 max_new_image_size;
+ gboolean toolbox_color_area;
+ gboolean toolbox_foo_area;
+ gboolean toolbox_image_area;
+ gboolean toolbox_wilber;
+ gboolean toolbox_groups;
+ GimpToolGroupMenuMode toolbox_group_menu_mode;
+ gchar *theme_path;
+ gchar *theme;
+ gchar *icon_theme_path;
+ gchar *icon_theme;
+ GimpIconSize icon_size;
+ gboolean use_help;
+ gboolean show_help_button;
+ gchar *help_locales;
+ GimpHelpBrowserType help_browser;
+ gboolean user_manual_online;
+ gchar *user_manual_online_uri;
+ gboolean search_show_unavailable;
+ gint action_history_size;
+ GimpWindowHint dock_window_hint;
+ GimpHandedness cursor_handedness;
+
+ /* experimental playground */
+ gboolean playground_npd_tool;
+ gboolean playground_seamless_clone_tool;
+
+ /* saved in sessionrc */
+ gboolean hide_docks;
+ gboolean single_window_mode;
+ gboolean show_tabs;
+ GimpPosition tabs_position;
+ gint last_tip_shown;
+};
+
+struct _GimpGuiConfigClass
+{
+ GimpDisplayConfigClass parent_class;
+
+ void (* size_changed) (GimpGuiConfig *config);
+};
+
+
+GType gimp_gui_config_get_type (void) G_GNUC_CONST;
+
+GimpIconSize gimp_gui_config_detect_icon_size (GimpGuiConfig *config);
+
+#endif /* GIMP_GUI_CONFIG_H__ */
diff --git a/app/config/gimplangrc.c b/app/config/gimplangrc.c
new file mode 100644
index 0000000..34e26f4
--- /dev/null
+++ b/app/config/gimplangrc.c
@@ -0,0 +1,280 @@
+/* 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/>.
+ */
+
+#include "config.h"
+
+#include <gio/gio.h>
+
+#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
new file mode 100644
index 0000000..62412fd
--- /dev/null
+++ b/app/config/gimplangrc.h
@@ -0,0 +1,60 @@
+/* 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/gimppluginconfig.c b/app/config/gimppluginconfig.c
new file mode 100644
index 0000000..5fb4fe2
--- /dev/null
+++ b/app/config/gimppluginconfig.c
@@ -0,0 +1,217 @@
+/* GIMP - The GNU Image Manipulation Program
+ * Copyright (C) 1995 Spencer Kimball and Peter Mattis
+ *
+ * GimpPluginConfig class
+ * Copyright (C) 2001 Sven Neumann <sven@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/>.
+ */
+
+#include "config.h"
+
+#include <gio/gio.h>
+#include <gegl.h>
+
+#include "libgimpbase/gimpbase.h"
+#include "libgimpconfig/gimpconfig.h"
+
+#include "config-types.h"
+
+#include "gimprc-blurbs.h"
+#include "gimppluginconfig.h"
+
+
+enum
+{
+ PROP_0,
+ PROP_FRACTALEXPLORER_PATH,
+ PROP_GFIG_PATH,
+ PROP_GFLARE_PATH,
+ PROP_GIMPRESSIONIST_PATH,
+ PROP_SCRIPT_FU_PATH
+};
+
+
+static void gimp_plugin_config_finalize (GObject *object);
+static void gimp_plugin_config_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec);
+static void gimp_plugin_config_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec);
+
+
+G_DEFINE_TYPE (GimpPluginConfig, gimp_plugin_config, GIMP_TYPE_DIALOG_CONFIG)
+
+#define parent_class gimp_plugin_config_parent_class
+
+
+static void
+gimp_plugin_config_class_init (GimpPluginConfigClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+ gchar *path;
+
+ object_class->finalize = gimp_plugin_config_finalize;
+ object_class->set_property = gimp_plugin_config_set_property;
+ object_class->get_property = gimp_plugin_config_get_property;
+
+ path = gimp_config_build_data_path ("fractalexplorer");
+ GIMP_CONFIG_PROP_PATH (object_class,
+ PROP_FRACTALEXPLORER_PATH,
+ "fractalexplorer-path",
+ "Fractal Explorer path",
+ FRACTALEXPLORER_PATH_BLURB,
+ GIMP_CONFIG_PATH_DIR_LIST, path,
+ GIMP_PARAM_STATIC_STRINGS);
+ g_free (path);
+
+ path = gimp_config_build_data_path ("gfig");
+ GIMP_CONFIG_PROP_PATH (object_class,
+ PROP_GFIG_PATH,
+ "gfig-path",
+ "GFig path",
+ GFIG_PATH_BLURB,
+ GIMP_CONFIG_PATH_DIR_LIST, path,
+ GIMP_PARAM_STATIC_STRINGS);
+ g_free (path);
+
+ path = gimp_config_build_data_path ("gflare");
+ GIMP_CONFIG_PROP_PATH (object_class,
+ PROP_GFLARE_PATH,
+ "gflare-path",
+ "GFlare path",
+ GFLARE_PATH_BLURB,
+ GIMP_CONFIG_PATH_DIR_LIST, path,
+ GIMP_PARAM_STATIC_STRINGS);
+ g_free (path);
+
+ path = gimp_config_build_data_path ("gimpressionist");
+ GIMP_CONFIG_PROP_PATH (object_class,
+ PROP_GIMPRESSIONIST_PATH,
+ "gimpressionist-path",
+ "GIMPressionist path",
+ GIMPRESSIONIST_PATH_BLURB,
+ GIMP_CONFIG_PATH_DIR_LIST, path,
+ GIMP_PARAM_STATIC_STRINGS);
+ g_free (path);
+
+ path = gimp_config_build_data_path ("scripts");
+ GIMP_CONFIG_PROP_PATH (object_class,
+ PROP_SCRIPT_FU_PATH,
+ "script-fu-path",
+ "Script-Fu path",
+ SCRIPT_FU_PATH_BLURB,
+ GIMP_CONFIG_PATH_DIR_LIST, path,
+ GIMP_PARAM_STATIC_STRINGS);
+ g_free (path);
+}
+
+static void
+gimp_plugin_config_init (GimpPluginConfig *config)
+{
+}
+
+static void
+gimp_plugin_config_finalize (GObject *object)
+{
+ GimpPluginConfig *plugin_config = GIMP_PLUGIN_CONFIG (object);
+
+ g_free (plugin_config->fractalexplorer_path);
+ g_free (plugin_config->gfig_path);
+ g_free (plugin_config->gflare_path);
+ g_free (plugin_config->gimpressionist_path);
+ g_free (plugin_config->script_fu_path);
+
+ G_OBJECT_CLASS (parent_class)->finalize (object);
+}
+
+static void
+gimp_plugin_config_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ GimpPluginConfig *plugin_config = GIMP_PLUGIN_CONFIG (object);
+
+ switch (property_id)
+ {
+ case PROP_FRACTALEXPLORER_PATH:
+ g_free (plugin_config->fractalexplorer_path);
+ plugin_config->fractalexplorer_path = g_value_dup_string (value);
+ break;
+
+ case PROP_GFIG_PATH:
+ g_free (plugin_config->gfig_path);
+ plugin_config->gfig_path = g_value_dup_string (value);
+ break;
+
+ case PROP_GFLARE_PATH:
+ g_free (plugin_config->gflare_path);
+ plugin_config->gflare_path = g_value_dup_string (value);
+ break;
+
+ case PROP_GIMPRESSIONIST_PATH:
+ g_free (plugin_config->gimpressionist_path);
+ plugin_config->gimpressionist_path = g_value_dup_string (value);
+ break;
+
+ case PROP_SCRIPT_FU_PATH:
+ g_free (plugin_config->script_fu_path);
+ plugin_config->script_fu_path = g_value_dup_string (value);
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+ break;
+ }
+}
+
+static void
+gimp_plugin_config_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ GimpPluginConfig *plugin_config = GIMP_PLUGIN_CONFIG (object);
+
+ switch (property_id)
+ {
+ case PROP_FRACTALEXPLORER_PATH:
+ g_value_set_string (value, plugin_config->fractalexplorer_path);
+ break;
+
+ case PROP_GFIG_PATH:
+ g_value_set_string (value, plugin_config->gfig_path);
+ break;
+
+ case PROP_GFLARE_PATH:
+ g_value_set_string (value, plugin_config->gflare_path);
+ break;
+
+ case PROP_GIMPRESSIONIST_PATH:
+ g_value_set_string (value, plugin_config->gimpressionist_path);
+ break;
+
+ case PROP_SCRIPT_FU_PATH:
+ g_value_set_string (value, plugin_config->script_fu_path);
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+ break;
+ }
+}
diff --git a/app/config/gimppluginconfig.h b/app/config/gimppluginconfig.h
new file mode 100644
index 0000000..e9b0f53
--- /dev/null
+++ b/app/config/gimppluginconfig.h
@@ -0,0 +1,56 @@
+/* GIMP - The GNU Image Manipulation Program
+ * Copyright (C) 1995 Spencer Kimball and Peter Mattis
+ *
+ * GimpPluginConfig class
+ * Copyright (C) 2001 Sven Neumann <sven@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_PLUGIN_CONFIG_H__
+#define __GIMP_PLUGIN_CONFIG_H__
+
+#include "config/gimpdialogconfig.h"
+
+
+#define GIMP_TYPE_PLUGIN_CONFIG (gimp_plugin_config_get_type ())
+#define GIMP_PLUGIN_CONFIG(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GIMP_TYPE_PLUGIN_CONFIG, GimpPluginConfig))
+#define GIMP_PLUGIN_CONFIG_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GIMP_TYPE_PLUGIN_CONFIG, GimpPluginConfigClass))
+#define GIMP_IS_PLUGIN_CONFIG(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GIMP_TYPE_PLUGIN_CONFIG))
+#define GIMP_IS_PLUGIN_CONFIG_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GIMP_TYPE_PLUGIN_CONFIG))
+
+
+typedef struct _GimpPluginConfigClass GimpPluginConfigClass;
+
+struct _GimpPluginConfig
+{
+ GimpDialogConfig parent_instance;
+
+ gchar *fractalexplorer_path;
+ gchar *gfig_path;
+ gchar *gflare_path;
+ gchar *gimpressionist_path;
+ gchar *script_fu_path;
+};
+
+struct _GimpPluginConfigClass
+{
+ GimpGuiConfigClass parent_class;
+};
+
+
+GType gimp_plugin_config_get_type (void) G_GNUC_CONST;
+
+
+#endif /* GIMP_PLUGIN_CONFIG_H__ */
diff --git a/app/config/gimprc-blurbs.h b/app/config/gimprc-blurbs.h
new file mode 100644
index 0000000..51b771a
--- /dev/null
+++ b/app/config/gimprc-blurbs.h
@@ -0,0 +1,747 @@
+/* gimprc-blurbs.h -- descriptions for gimprc properties */
+
+#ifndef __GIMP_RC_BLURBS_H__
+#define __GIMP_RC_BLURBS_H__
+
+
+/* Not all strings defined here are used in the user interface
+ * (the preferences dialog mainly) and only those that are should
+ * be marked for translation.
+ */
+
+#define ACTIVATE_ON_FOCUS_BLURB \
+_("When enabled, an image will become the active image when its image " \
+ "window receives the focus. This is useful for window managers using " \
+ "\"click to focus\".")
+
+#define BRUSH_PATH_BLURB \
+"Sets the brush search path."
+
+#define BRUSH_PATH_WRITABLE_BLURB ""
+
+#define DYNAMICS_PATH_BLURB \
+_("Sets the dynamics search path.")
+
+#define DYNAMICS_PATH_WRITABLE_BLURB ""
+
+#define TOOL_PRESET_PATH_BLURB \
+_("Sets the dynamics search path.")
+
+#define TOOL_PRESET_PATH_WRITABLE_BLURB ""
+
+#define CANVAS_PADDING_COLOR_BLURB \
+_("Sets the canvas padding color used if the padding mode is set to " \
+ "custom color.")
+
+#define CANVAS_PADDING_IN_SHOW_ALL_BLURB \
+_("Specifies whether to keep the canvas padding when \"View -> Show All\" " \
+ "is enabled.")
+
+#define CANVAS_PADDING_MODE_BLURB \
+_("Specifies how the area around the image should be drawn.")
+
+#define CHECK_UPDATES_BLURB \
+_("Check for availability of GIMP updates through background internet queries.")
+
+#define CHECK_UPDATE_TIMESTAMP_BLURB \
+_("Timestamp of the last update check.")
+
+#define COLOR_MANAGEMENT_BLURB \
+"Defines the color management behavior."
+
+#define COLOR_PROFILE_POLICY_BLURB \
+_("How to handle embedded color profiles when opening a file.")
+
+#define COLOR_PROFILE_PATH_BLURB \
+_("Sets the default folder path for all color profile file dialogs.")
+
+#define COMPACT_SLIDERS_BLURB \
+_("Use compact style for sliders.")
+
+#define CURSOR_MODE_BLURB \
+_("Sets the type of mouse pointers to use.")
+
+#define CURSOR_HANDEDNESS_BLURB \
+_("Sets the handedness for cursor positioning.")
+
+#define CURSOR_UPDATING_BLURB \
+_("Context-dependent mouse pointers are helpful. They are enabled by " \
+ "default. However, they require overhead that you may want to do without.")
+
+#define DEFAULT_BRUSH_BLURB \
+"Specify a default brush. The brush is searched for in the " \
+"specified brush path."
+
+#define DEFAULT_DYNAMICS_BLURB \
+"Specify a default dynamics. The dynamics is searched for in the " \
+"specified dynamics path."
+
+#define DEFAULT_TOOL_PRESET_BLURB \
+"Specify a default tool preset. The tool preset is searched for in the " \
+"specified tool prests path."
+
+#define DEFAULT_SHOW_ALL_BLURB \
+_("Show full image content by default.")
+
+#define DEFAULT_DOT_FOR_DOT_BLURB \
+_("When enabled, this will ensure that each pixel of an image gets " \
+ "mapped to a pixel on the screen.")
+
+#define DEFAULT_FONT_BLURB \
+"Specify a default font."
+
+#define DEFAULT_GRADIENT_BLURB \
+"Specify a default gradient."
+
+#define DEFAULT_GRID_BLURB \
+"Specify a default image grid."
+
+#define DEFAULT_IMAGE_BLURB \
+"Sets the default image in the \"File/New\" dialog."
+
+#define DEFAULT_MYPAINT_BRUSH_BLURB \
+"Specify a default MyPaint brush."
+
+#define DEFAULT_PATTERN_BLURB \
+"Specify a default pattern."
+
+#define DEFAULT_PALETTE_BLURB \
+"Specify a default palette."
+
+#define DEFAULT_SNAP_DISTANCE_BLURB \
+_("This is the distance in pixels where Guide and Grid snapping " \
+ "activates.")
+
+#define SNAP_TO_GUIDES_BLURB \
+_("Snap to guides by default in new image windows.")
+
+#define SNAP_TO_GRID_BLURB \
+_("Snap to the grid by default in new image windows.")
+
+#define SNAP_TO_CANVAS_BLURB \
+_("Snap to the canvas edges by default in new image windows.")
+
+#define SNAP_TO_PATH_BLURB \
+_("Snap to the active path by default in new image windows.")
+
+#define DEFAULT_THRESHOLD_BLURB \
+_("Tools such as fuzzy-select and bucket fill find regions based on a " \
+ "seed-fill algorithm. The seed fill starts at the initially selected " \
+ "pixel and progresses in all directions until the difference of pixel " \
+ "intensity from the original is greater than a specified threshold. " \
+ "This value represents the default threshold.")
+
+#define DEFAULT_VIEW_BLURB \
+"Sets the default settings for the image view."
+
+#define DEFAULT_FULLSCREEN_VIEW_BLURB \
+"Sets the default settings used when an image is viewed in fullscreen mode."
+
+#define DOCK_WINDOW_HINT_BLURB \
+_("The window type hint that is set on dock windows and the toolbox " \
+ "window. This may affect the way your window manager decorates and " \
+ "handles these windows.")
+
+#define ENVIRON_PATH_BLURB \
+"Sets the environ search path."
+
+#define FRACTALEXPLORER_PATH_BLURB \
+"Where to search for fractals used by the Fractal Explorer plug-in."
+
+#define GFIG_PATH_BLURB \
+"Where to search for Gfig figures used by the Gfig plug-in."
+
+#define GFLARE_PATH_BLURB \
+"Where to search for gflares used by the GFlare plug-in."
+
+#define GIMPRESSIONIST_PATH_BLURB \
+"Where to search for data used by the Gimpressionist plug-in."
+
+#define GLOBAL_BRUSH_BLURB \
+_("When enabled, the selected brush will be used for all tools.")
+
+#define GLOBAL_DYNAMICS_BLURB \
+_("When enabled, the selected dynamics will be used for all tools.")
+
+#define GLOBAL_FONT_BLURB \
+"When enabled, the selected font will be used for all tools."
+
+#define GLOBAL_GRADIENT_BLURB \
+_("When enabled, the selected gradient will be used for all tools.")
+
+#define GLOBAL_PATTERN_BLURB \
+_("When enabled, the selected pattern will be used for all tools.")
+
+#define GLOBAL_PALETTE_BLURB \
+"When enabled, the selected palette will be used for all tools."
+
+#define GRADIENT_PATH_BLURB \
+"Sets the gradient search path."
+
+#define GRADIENT_PATH_WRITABLE_BLURB ""
+
+#define FONT_PATH_BLURB \
+"Where to look for fonts in addition to the system-wide installed fonts."
+
+#define HELP_BROWSER_BLURB \
+_("Sets the browser used by the help system.")
+
+#define HELP_LOCALES_BLURB \
+"Specifies the language preferences used by the help system. This is a " \
+"colon-separated list of language identifiers with decreasing priority. " \
+"If empty, the language is taken from the user's locale setting."
+
+#define FILTER_TOOL_MAX_RECENT_BLURB \
+_("How many recent settings to keep around in filter tools.")
+
+#define FILTER_TOOL_USE_LAST_SETTINGS_BLURB \
+_("Default to the last used settings in filter tools.")
+
+#define FILTER_TOOL_SHOW_COLOR_OPTIONS_BLURB \
+_("Show advanced color options in filter tools.")
+
+#define IMAGE_STATUS_FORMAT_BLURB \
+_("Sets the text to appear in image window status bars.")
+
+#define IMAGE_TITLE_FORMAT_BLURB \
+_("Sets the text to appear in image window titles.")
+
+#define IMPORT_PROMOTE_FLOAT_BLURB \
+_("Promote imported images to floating point precision. Does not apply " \
+ "to indexed images.")
+
+#define IMPORT_PROMOTE_DITHER_BLURB \
+_("When promoting imported images to floating point precision, also add " \
+ "minimal noise in order to distribute color values a bit.")
+
+#define IMPORT_ADD_ALPHA_BLURB \
+_("Add an alpha channel to all layers of imported images.")
+
+#define IMPORT_RAW_PLUG_IN_BLURB \
+_("Which plug-in to use for importing raw digital camera files.")
+
+#define EXPORT_FILE_TYPE_BLURB \
+_("Export file type used by default.")
+
+#define EXPORT_COLOR_PROFILE_BLURB \
+_("Export the image's color profile by default.")
+
+/* Translators: tooltip for configuration option (checkbox).
+ * It determines how file export plug-ins handle Exif by default.
+ */
+#define EXPORT_METADATA_EXIF_BLURB \
+_("Export Exif metadata by default.")
+
+/* Translators: tooltip for configuration option (checkbox).
+ * It determines how file export plug-ins handle XMP by default.
+ */
+#define EXPORT_METADATA_XMP_BLURB \
+_("Export XMP metadata by default.")
+
+/* Translators: tooltip for configuration option (checkbox).
+ * It determines how file export plug-ins handle IPTC by default.
+ */
+#define EXPORT_METADATA_IPTC_BLURB \
+_("Export IPTC metadata by default.")
+
+#define GENERATE_BACKTRACE_BLURB \
+_("Try generating debug data for bug reporting when appropriate.")
+
+#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.")
+
+#define INTERPOLATION_TYPE_BLURB \
+_("Sets the level of interpolation used for scaling and other " \
+ "transformations.")
+
+#define INTERPRETER_PATH_BLURB \
+"Sets the interpreter search path."
+
+#define LANGUAGE_BLURB \
+_("Specifies the language to use for the user interface.")
+
+#define LAST_KNOWN_RELEASE_BLURB \
+_("The last known release version of GIMP as queried from official website.")
+
+#define LAST_OPENED_SIZE_BLURB \
+_("How many recently opened image filenames to keep on the File menu.")
+
+#define LAST_RELEASE_TIMESTAMP_BLURB \
+_("The timestamp for the last known release date.")
+
+#define LAST_REVISION_BLURB \
+_("The last revision number for the release.")
+
+#define MARCHING_ANTS_SPEED_BLURB \
+_("Speed of marching ants in the selection outline. This value is in " \
+ "milliseconds (less time indicates faster marching).")
+
+#define MAX_NEW_IMAGE_SIZE_BLURB \
+_("GIMP will warn the user if an attempt is made to create an image that " \
+ "would take more memory than the size specified here.")
+
+#define MODULE_PATH_BLURB \
+"Sets the module search path."
+
+#define MONITOR_RES_FROM_GDK_BLURB \
+"When enabled, GIMP will use the monitor resolution from the windowing system."
+
+#define MONITOR_XRESOLUTION_BLURB \
+_("Sets the monitor's horizontal resolution, in dots per inch. If set to " \
+ "0, forces the X server to be queried for both horizontal and vertical " \
+ "resolution information.")
+
+#define MONITOR_YRESOLUTION_BLURB \
+_("Sets the monitor's vertical resolution, in dots per inch. If set to " \
+ "0, forces the X server to be queried for both horizontal and vertical " \
+ "resolution information.")
+
+#define EDIT_NON_VISIBLE_BLURB \
+_("When enabled, non-visible layers can be edited as normal.")
+
+#define MOVE_TOOL_CHANGES_ACTIVE_BLURB \
+_("If enabled, the move tool sets the edited layer or path as active. " \
+ "This used to be the default behaviour in older versions.")
+
+#define MYPAINT_BRUSH_PATH_BLURB \
+"Sets the brush search path."
+
+#define MYPAINT_BRUSH_PATH_WRITABLE_BLURB ""
+
+#define NAVIGATION_PREVIEW_SIZE_BLURB \
+_("Sets the size of the navigation preview available in the lower right " \
+ "corner of the image window.")
+
+#define NUM_PROCESSORS_BLURB \
+_("Sets how many threads GIMP should use for operations that support it.")
+
+#define PALETTE_PATH_BLURB \
+"Sets the palette search path."
+
+#define PALETTE_PATH_WRITABLE_BLURB ""
+
+#define PATTERN_PATH_BLURB \
+"Sets the pattern search path."
+
+#define PATTERN_PATH_WRITABLE_BLURB ""
+
+#define FILTER_HISTORY_SIZE_BLURB \
+"How many recently used filters and plug-ins to keep on the Filters menu."
+
+#define PLUG_IN_PATH_BLURB \
+"Sets the plug-in search path."
+
+#define PLUGINRC_PATH_BLURB \
+"Sets the pluginrc search path."
+
+#define LAYER_PREVIEWS_BLURB \
+_("Sets whether GIMP should create previews of layers and channels. " \
+ "Previews in the layers and channels dialog are nice to have but they " \
+ "can slow things down when working with large images.")
+
+#define GROUP_LAYER_PREVIEWS_BLURB \
+_("Sets whether GIMP should create previews of layer groups. " \
+ "Layer group previews are more expensive than ordinary layer previews.")
+
+#define LAYER_PREVIEW_SIZE_BLURB \
+_("Sets the preview size used for layers and channel previews in newly " \
+ "created dialogs.")
+
+#define QUICK_MASK_COLOR_BLURB \
+_("Sets the default quick mask color.")
+
+#define RESIZE_WINDOWS_ON_RESIZE_BLURB \
+_("When enabled, the image window will automatically resize itself " \
+ "whenever the physical image size changes. This setting only takes " \
+ "effect in multi-window mode.")
+
+#define RESIZE_WINDOWS_ON_ZOOM_BLURB \
+_("When enabled, the image window will automatically resize itself " \
+ "when zooming into and out of images. This setting only takes " \
+ "effect in multi-window mode.")
+
+#define RESTORE_SESSION_BLURB \
+_("Let GIMP try to restore your last saved session on each startup.")
+
+#define RESTORE_MONITOR_BLURB \
+_("When enabled, GIMP will try to restore windows on the monitor they " \
+ "were open before. When disabled, windows will appear on the currently " \
+ "used monitor.")
+
+#define SAVE_DEVICE_STATUS_BLURB \
+_("Remember the current tool, pattern, color, and brush across GIMP " \
+ "sessions.")
+
+#define DEVICES_SHARE_TOOL_BLURB \
+_("When enabled, the same tool and tool options will be used for all " \
+ "input devices. No tool switching will occur when the input device " \
+ "changes.")
+
+#define SAVE_DOCUMENT_HISTORY_BLURB \
+_("Keep a permanent record of all opened and saved files in the Recent " \
+ "Documents list.")
+
+#define SAVE_SESSION_INFO_BLURB \
+_("Save the positions and sizes of the main dialogs when GIMP exits.")
+
+#define SAVE_TOOL_OPTIONS_BLURB \
+_("Save the tool options when GIMP exits.")
+
+#define SCRIPT_FU_PATH_BLURB \
+"This path will be searched for scripts when the Script-Fu plug-in is run."
+
+#define SHOW_BRUSH_OUTLINE_BLURB \
+_("When enabled, all paint tools will show a preview of the current " \
+ "brush's outline.")
+
+#define SNAP_BRUSH_OUTLINE_BLURB \
+_("When enabled, the brush outline will snap to individual dabs while " \
+ "painting.")
+
+#define SHOW_HELP_BUTTON_BLURB \
+_("When enabled, dialogs will show a help button that gives access to " \
+ "the related help page. Without this button, the help page can still " \
+ "be reached by pressing F1.")
+
+#define SHOW_PAINT_TOOL_CURSOR_BLURB \
+_("When enabled, the mouse pointer will be shown over the image while " \
+ "using a paint tool.")
+
+#define SHOW_MENUBAR_BLURB \
+_("When enabled, the menubar is visible by default. This can also be " \
+ "toggled with the \"View->Show Menubar\" command.")
+
+#define SHOW_RULERS_BLURB \
+_("When enabled, the rulers are visible by default. This can also be " \
+ "toggled with the \"View->Show Rulers\" command.")
+
+#define SHOW_SCROLLBARS_BLURB \
+_("When enabled, the scrollbars are visible by default. This can also be " \
+ "toggled with the \"View->Show Scrollbars\" command.")
+
+#define SHOW_STATUSBAR_BLURB \
+_("When enabled, the statusbar is visible by default. This can also be " \
+ "toggled with the \"View->Show Statusbar\" command.")
+
+#define SHOW_SELECTION_BLURB \
+_("When enabled, the selection is visible by default. This can also be " \
+ "toggled with the \"View->Show Selection\" command.")
+
+#define SHOW_LAYER_BOUNDARY_BLURB \
+_("When enabled, the layer boundary is visible by default. This can also " \
+ "be toggled with the \"View->Show Layer Boundary\" command.")
+
+#define SHOW_CANVAS_BOUNDARY_BLURB \
+_("When enabled, the canvas boundary is visible by default. This can also " \
+ "be toggled with the \"View->Show Canvas Boundary\" command.")
+
+#define SHOW_GUIDES_BLURB \
+_("When enabled, the guides are visible by default. This can also be " \
+ "toggled with the \"View->Show Guides\" command.")
+
+#define SHOW_GRID_BLURB \
+_("When enabled, the grid is visible by default. This can also be toggled " \
+ "with the \"View->Show Grid\" command.")
+
+#define SHOW_SAMPLE_POINTS_BLURB \
+_("When enabled, the sample points are visible by default. This can also be " \
+ "toggled with the \"View->Show Sample Points\" command.")
+
+#define SHOW_TOOLTIPS_BLURB \
+_("Show a tooltip when the pointer hovers over an item.")
+
+#define SINGLE_WINDOW_MODE_BLURB \
+_("Use GIMP in a single-window mode.")
+
+#define HIDE_DOCKS_BLURB \
+_("Hide docks and other windows, leaving only image windows.")
+
+#define SHOW_TABS_BLURB \
+_("Show the image tabs bar in single window mode.")
+
+#define PLAYGROUND_NPD_TOOL_BLURB \
+_("Enable the N-Point Deformation tool.")
+
+#define PLAYGROUND_HANDLE_TRANSFORM_TOOL_BLURB \
+_("Enable the Handle Transform tool.")
+
+#define PLAYGROUND_SYMMETRY_BLURB \
+_("Enable symmetry on painting.")
+
+#define PLAYGROUND_MYBRUSH_TOOL_BLURB \
+_("Enable the MyPaint Brush tool.")
+
+#define PLAYGROUND_SEAMLESS_CLONE_TOOL_BLURB \
+_("Enable the Seamless Clone tool.")
+
+#define SPACE_BAR_ACTION_BLURB \
+_("What to do when the space bar is pressed in the image window.")
+
+#define SWAP_COMPRESSION_BLURB \
+_("The compression method used for tile data stored in the swap file.")
+
+#define SWAP_PATH_BLURB \
+_("Sets the swap file location. GIMP uses a tile based memory allocation " \
+ "scheme. The swap file is used to quickly and easily swap tiles out to " \
+ "disk and back in. Be aware that the swap file can easily get very large " \
+ "if GIMP is used with large images. " \
+ "Also, things can get horribly slow if the swap file is created on " \
+ "a folder that is mounted over NFS. For these reasons, it may be " \
+ "desirable to put your swap file in \"/tmp\".")
+
+#define TEAROFF_MENUS_BLURB \
+_("When enabled, menus can be torn off.")
+
+#define CAN_CHANGE_ACCELS_BLURB \
+_("When enabled, you can change keyboard shortcuts for menu items " \
+ "by hitting a key combination while the menu item is highlighted.")
+
+#define SAVE_ACCELS_BLURB \
+_("Save changed keyboard shortcuts when GIMP exits.")
+
+#define RESTORE_ACCELS_BLURB \
+_("Restore saved keyboard shortcuts on each GIMP startup.")
+
+#define TEMP_PATH_BLURB \
+_("Sets the folder for temporary storage. Files will appear here " \
+ "during the course of running GIMP. Most files will disappear " \
+ "when GIMP exits, but some files are likely to remain, so it " \
+ "is best if this folder not be one that is shared by other users.")
+
+#define THEME_BLURB \
+_("The name of the theme to use.")
+
+#define THEME_PATH_BLURB \
+"Sets the theme search path."
+
+#define ICON_THEME_BLURB \
+"The name of the icon theme to use."
+
+#define ICON_SIZE_BLURB \
+"The size of the icons to use."
+
+#define ICON_THEME_PATH_BLURB \
+"Sets the icon theme search path."
+
+#define IMAGE_CONVERT_PROFILE_INTENT_BLURB \
+_("Sets the default rendering intent for the 'Convert to Color Profile' dialog.")
+
+#define IMAGE_CONVERT_PROFILE_BPC_BLURB \
+_("Sets the default 'Black Point Compensation' state for the " \
+ "'Convert to Color Profile' dialog.")
+
+#define IMAGE_CONVERT_PRECISION_LAYER_DITHER_METHOD_BLURB \
+_("Sets the default layer dithering method for the 'Convert Precision' dialog.")
+
+#define IMAGE_CONVERT_PRECISION_TEXT_LAYER_DITHER_METHOD_BLURB \
+_("Sets the default text layer dithering method for the 'Convert Precision' dialog.")
+
+#define IMAGE_CONVERT_PRECISION_CHANNEL_DITHER_METHOD_BLURB \
+_("Sets the default channel dithering method for the 'Convert Precision' dialog.")
+
+#define IMAGE_CONVERT_INDEXED_PALETTE_TYPE_BLURB \
+_("Sets the default palette type for the 'Convert to Indexed' dialog.")
+
+#define IMAGE_CONVERT_INDEXED_MAX_COLORS_BLURB \
+_("Sets the default maximum number of colors for the 'Convert to Indexed' dialog.")
+
+#define IMAGE_CONVERT_INDEXED_REMOVE_DUPLICATES_BLURB \
+_("Sets the default 'Remove duplicate colors' state for the 'Convert to Indexed' dialog.")
+
+#define IMAGE_CONVERT_INDEXED_DITHER_TYPE_BLURB \
+_("Sets the default dithering type for the 'Convert to Indexed' dialog.")
+
+#define IMAGE_CONVERT_INDEXED_DITHER_ALPHA_BLURB \
+_("Sets the default 'Dither alpha' state for the 'Convert to Indexed' dialog.")
+
+#define IMAGE_CONVERT_INDEXED_DITHER_TEXT_LAYERS_BLURB \
+_("Sets the default 'Dither text layers' state for the 'Convert to Indexed' dialog.")
+
+#define IMAGE_RESIZE_FILL_TYPE_BLURB \
+_("Sets the default fill type for the 'Canvas Size' dialog.")
+
+#define IMAGE_RESIZE_LAYER_SET_BLURB \
+_("Sets the default set of layers to resize for the 'Canvas Size' dialog.")
+
+#define IMAGE_RESIZE_RESIZE_TEXT_LAYERS_BLURB \
+_("Sets the default 'Resize text layers' state for the 'Canvas Size' dialog.")
+
+#define LAYER_NEW_NAME_BLURB \
+_("Sets the default layer name for the 'New Layer' dialog.")
+
+#define LAYER_NEW_MODE_BLURB \
+_("Sets the default mode for the 'New Layer' dialog.")
+
+#define LAYER_NEW_BLEND_SPACE_BLURB \
+_("Sets the default blend space for the 'New Layer' dialog.")
+
+#define LAYER_NEW_COMPOSITE_SPACE_BLURB \
+_("Sets the default composite space for the 'New Layer' dialog.")
+
+#define LAYER_NEW_COMPOSITE_MODE_BLURB \
+_("Sets the default composite mode for the 'New Layer' dialog.")
+
+#define LAYER_NEW_OPACITY_BLURB \
+_("Sets the default opacity for the 'New Layer' dialog.")
+
+#define LAYER_NEW_FILL_TYPE_BLURB \
+_("Sets the default fill type for the 'New Layer' dialog.")
+
+#define LAYER_RESIZE_FILL_TYPE_BLURB \
+_("Sets the default fill type for the 'Layer Boundary Size' dialog.")
+
+#define LAYER_ADD_MASK_TYPE_BLURB \
+_("Sets the default mask for the 'Add Layer Mask' dialog.")
+
+#define LAYER_ADD_MASK_INVERT_BLURB \
+_("Sets the default 'invert mask' state for the 'Add Layer Mask' dialog.")
+
+#define LAYER_MERGE_TYPE_BLURB \
+_("Sets the default merge type for the 'Merge Visible Layers' dialog.")
+
+#define LAYER_MERGE_ACTIVE_GROUP_ONLY_BLURB \
+_("Sets the default 'Active group only' for the 'Merge Visible Layers' dialog.")
+
+#define LAYER_MERGE_DISCARD_INVISIBLE_BLURB \
+_("Sets the default 'Discard invisible' for the 'Merge Visible Layers' dialog.")
+
+#define CHANNEL_NEW_NAME_BLURB \
+_("Sets the default channel name for the 'New Channel' dialog.")
+
+#define CHANNEL_NEW_COLOR_BLURB \
+_("Sets the default color and opacity for the 'New Channel' dialog.")
+
+#define VECTORS_NEW_NAME_BLURB \
+_("Sets the default path name for the 'New Path' dialog.")
+
+#define VECTORS_EXPORT_PATH_BLURB \
+_("Sets the default folder path for the 'Export Path' dialog.")
+
+#define VECTORS_EXPORT_ACTIVE_ONLY_BLURB \
+_("Sets the default 'Export the active path' state for the 'Export Path' dialog.")
+
+#define VECTORS_IMPORT_PATH_BLURB \
+_("Sets the default folder path for the 'Import Path' dialog.")
+
+#define VECTORS_IMPORT_MERGE_BLURB \
+_("Sets the default 'Merge imported paths' state for the 'Import Path' dialog.")
+
+#define VECTORS_IMPORT_SCALE_BLURB \
+_("Sets the default 'Scale imported paths to fit size' state for the 'Import Path' dialog.")
+
+#define SELECTION_FEATHER_RADIUS_BLURB \
+_("Sets the default feather radius for the 'Feather Selection' dialog.")
+
+#define SELECTION_FEATHER_EDGE_LOCK_BLURB \
+_("Sets the default 'Selected areas continue outside the image' setting " \
+ "for the 'Feather Selection' dialog.")
+
+#define SELECTION_GROW_RADIUS_BLURB \
+_("Sets the default grow radius for the 'Grow Selection' dialog.")
+
+#define SELECTION_SHRINK_RADIUS_BLURB \
+_("Sets the default shrink radius for the 'Shrink Selection' dialog.")
+
+#define SELECTION_SHRINK_EDGE_LOCK_BLURB \
+_("Sets the default 'Selected areas continue outside the image' setting " \
+ "for the 'Shrink Selection' dialog.")
+
+#define SELECTION_BORDER_RADIUS_BLURB \
+_("Sets the default border radius for the 'Border Selection' dialog.")
+
+#define SELECTION_BORDER_EDGE_LOCK_BLURB \
+_("Sets the default 'Selected areas continue outside the image' setting " \
+ "for the 'Border Selection' dialog.")
+
+#define SELECTION_BORDER_STYLE_BLURB \
+_("Sets the default border style for the 'Border Selection' dialog.")
+
+#define FILL_OPTIONS_BLURB \
+"The default fill options for the fill dialogs."
+
+#define STROKE_OPTIONS_BLURB \
+"The default stroke options for the stroke dialogs."
+
+#define THUMBNAIL_SIZE_BLURB \
+_("Sets the size of the thumbnail shown in the Open dialog.")
+
+#define THUMBNAIL_FILESIZE_LIMIT_BLURB \
+_("The thumbnail in the Open dialog will be automatically updated " \
+ "if the file being previewed is smaller than the size set here.")
+
+#define TILE_CACHE_SIZE_BLURB \
+_("When the amount of pixel data exceeds this limit, GIMP will start to " \
+ "swap tiles to disk. This is a lot slower but it makes it possible to " \
+ "work on images that wouldn't fit into memory otherwise. If you have a " \
+ "lot of RAM, you may want to set this to a higher value.")
+
+#define TOOLBOX_COLOR_AREA_BLURB \
+_("Show the current foreground and background colors in the toolbox.")
+
+#define TOOLBOX_FOO_AREA_BLURB \
+_("Show the currently selected brush, pattern and gradient in the toolbox.")
+
+#define TOOLBOX_GROUP_MENU_MODE_BLURB \
+_("Menu mode of grouped tools.")
+
+#define TOOLBOX_GROUPS_BLURB \
+_("Use a single toolbox button for grouped tools.")
+
+#define TOOLBOX_IMAGE_AREA_BLURB \
+_("Show the currently active image in the toolbox.")
+
+#define TOOLBOX_WILBER_BLURB \
+_("Show the GIMP mascot at the top of the toolbox.")
+
+#define TRANSPARENCY_TYPE_BLURB \
+_("Sets the manner in which transparency is displayed in images.")
+
+#define TRANSPARENCY_SIZE_BLURB \
+_("Sets the size of the checkerboard used to display transparency.")
+
+#define TRUST_DIRTY_FLAG_BLURB \
+_("When enabled, GIMP will not save an image if it has not been changed " \
+ "since it was opened.")
+
+#define UNDO_LEVELS_BLURB \
+_("Sets the minimal number of operations that can be undone. More undo " \
+ "levels are kept available until the undo-size limit is reached.")
+
+#define UNDO_SIZE_BLURB \
+_("Sets an upper limit to the memory that is used per image to keep " \
+ "operations on the undo stack. Regardless of this setting, at least " \
+ "as many undo-levels as configured can be undone.")
+
+#define UNDO_PREVIEW_SIZE_BLURB \
+_("Sets the size of the previews in the Undo History.")
+
+#define USE_HELP_BLURB \
+_("When enabled, pressing F1 will open the help browser.")
+
+#define USE_OPENCL_BLURB \
+_("When enabled, uses OpenCL for some operations.")
+
+#define USER_MANUAL_ONLINE_BLURB \
+"When enabled, the online user manual will be used by the help system. " \
+"Otherwise the locally installed copy is used."
+
+#define USER_MANUAL_ONLINE_URI_BLURB \
+"The location of the online user manual. This is used if " \
+"'user-manual-online' is enabled."
+
+#define ZOOM_QUALITY_BLURB \
+"There's a tradeoff between speed and quality of the zoomed-out display."
+
+#define DEFAULT_USE_EVENT_HISTORY_BLURB \
+"Bugs in event history buffer are frequent so in case of cursor " \
+"offset problems turning it off helps."
+
+#define SEARCH_SHOW_UNAVAILABLE_BLURB \
+_("When enabled, a search of actions will also return inactive actions.")
+
+#define ACTION_HISTORY_SIZE_BLURB \
+_("The maximum number of actions saved in history.")
+
+
+#endif /* __GIMP_RC_BLURBS_H__ */
diff --git a/app/config/gimprc-deserialize.c b/app/config/gimprc-deserialize.c
new file mode 100644
index 0000000..0278485
--- /dev/null
+++ b/app/config/gimprc-deserialize.c
@@ -0,0 +1,174 @@
+/* GIMP - The GNU Image Manipulation Program
+ * Copyright (C) 1995 Spencer Kimball and Peter Mattis
+ *
+ * GimpRc deserialization routines
+ * Copyright (C) 2001-2002 Sven Neumann <sven@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/>.
+ */
+
+#include "config.h"
+
+#include <cairo.h>
+#include <gegl.h>
+#include <gdk-pixbuf/gdk-pixbuf.h>
+
+#include "libgimpcolor/gimpcolor.h"
+#include "libgimpmath/gimpmath.h"
+#include "libgimpconfig/gimpconfig.h"
+
+#include "config-types.h"
+
+#include "gimprc-deserialize.h"
+#include "gimprc-unknown.h"
+
+#include "gimp-intl.h"
+
+
+static GTokenType gimp_rc_deserialize_unknown (GimpConfig *config,
+ GScanner *scanner);
+
+
+gboolean
+gimp_rc_deserialize (GimpConfig *config,
+ GScanner *scanner,
+ gint nest_level,
+ gpointer data)
+{
+ GObjectClass *klass;
+ GParamSpec **property_specs;
+ guint n_property_specs;
+ guint i;
+ guint scope_id;
+ guint old_scope_id;
+ GTokenType token;
+ GTokenType next;
+
+ g_return_val_if_fail (GIMP_IS_CONFIG (config), FALSE);
+
+ klass = G_OBJECT_GET_CLASS (config);
+
+ property_specs = g_object_class_list_properties (klass, &n_property_specs);
+ if (! property_specs)
+ return TRUE;
+
+ scope_id = g_type_qname (G_TYPE_FROM_INSTANCE (config));
+ old_scope_id = g_scanner_set_scope (scanner, scope_id);
+
+ for (i = 0; i < n_property_specs; i++)
+ {
+ GParamSpec *prop_spec = property_specs[i];
+
+ if (prop_spec->flags & GIMP_CONFIG_PARAM_SERIALIZE)
+ {
+ g_scanner_scope_add_symbol (scanner, scope_id,
+ prop_spec->name, prop_spec);
+ }
+ }
+
+ g_free (property_specs);
+
+ g_object_freeze_notify (G_OBJECT (config));
+
+ token = G_TOKEN_LEFT_PAREN;
+
+ while (TRUE)
+ {
+ next = g_scanner_peek_next_token (scanner);
+
+ if (G_UNLIKELY (next != token && ! (token == G_TOKEN_SYMBOL &&
+ next == G_TOKEN_IDENTIFIER)))
+ {
+ break;
+ }
+
+ token = g_scanner_get_next_token (scanner);
+
+ switch (token)
+ {
+ case G_TOKEN_LEFT_PAREN:
+ token = G_TOKEN_SYMBOL;
+ break;
+
+ case G_TOKEN_IDENTIFIER:
+ token = gimp_rc_deserialize_unknown (config, scanner);
+ break;
+
+ case G_TOKEN_SYMBOL:
+ token = gimp_config_deserialize_property (config,
+ scanner, nest_level);
+ break;
+
+ case G_TOKEN_RIGHT_PAREN:
+ token = G_TOKEN_LEFT_PAREN;
+ break;
+
+ default: /* do nothing */
+ break;
+ }
+ }
+
+ g_scanner_set_scope (scanner, old_scope_id);
+
+ g_object_thaw_notify (G_OBJECT (config));
+
+ if (token == G_TOKEN_NONE)
+ return FALSE;
+
+ /* If the unknown token value couldn't be parsed the default error
+ message is rather confusing. We try to produce something more
+ meaningful here ...
+ */
+ if (token == G_TOKEN_STRING && next == G_TOKEN_IDENTIFIER)
+ {
+ g_scanner_unexp_token (scanner, G_TOKEN_SYMBOL, NULL, NULL, NULL,
+ _("fatal parse error"), TRUE);
+ return FALSE;
+ }
+
+ return gimp_config_deserialize_return (scanner, token, nest_level);
+}
+
+static GTokenType
+gimp_rc_deserialize_unknown (GimpConfig *config,
+ GScanner *scanner)
+{
+ gchar *key;
+ guint old_scope_id;
+
+ old_scope_id = g_scanner_set_scope (scanner, 0);
+
+ if (g_scanner_peek_next_token (scanner) != G_TOKEN_STRING)
+ return G_TOKEN_STRING;
+
+ key = g_strdup (scanner->value.v_identifier);
+
+ g_scanner_get_next_token (scanner);
+
+ g_scanner_set_scope (scanner, old_scope_id);
+
+ if (! g_utf8_validate (scanner->value.v_string, -1, NULL))
+ {
+ g_scanner_error (scanner,
+ _("value for token %s is not a valid UTF-8 string"),
+ key);
+ g_free (key);
+ return G_TOKEN_NONE;
+ }
+
+ gimp_rc_add_unknown_token (config, key, scanner->value.v_string);
+ g_free (key);
+
+ return G_TOKEN_RIGHT_PAREN;
+}
diff --git a/app/config/gimprc-deserialize.h b/app/config/gimprc-deserialize.h
new file mode 100644
index 0000000..06b39fc
--- /dev/null
+++ b/app/config/gimprc-deserialize.h
@@ -0,0 +1,31 @@
+/* GIMP - The GNU Image Manipulation Program
+ * Copyright (C) 1995 Spencer Kimball and Peter Mattis
+ *
+ * GimpRc deserialization routines
+ * Copyright (C) 2001-2005 Sven Neumann <sven@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_RC_DESERIALIZE_H__
+#define __GIMP_RC_DESERIALIZE_H__
+
+
+gboolean gimp_rc_deserialize (GimpConfig *config,
+ GScanner *scanner,
+ gint nest_level,
+ gpointer data);
+
+
+#endif /* __GIMP_RC_DESERIALIZE_H__ */
diff --git a/app/config/gimprc-serialize.c b/app/config/gimprc-serialize.c
new file mode 100644
index 0000000..add6ac0
--- /dev/null
+++ b/app/config/gimprc-serialize.c
@@ -0,0 +1,120 @@
+/* GIMP - The GNU Image Manipulation Program
+ * Copyright (C) 1995 Spencer Kimball and Peter Mattis
+ *
+ * GimpRc serialization routines
+ * Copyright (C) 2001-2005 Sven Neumann <sven@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/>.
+ */
+
+#include "config.h"
+
+#include <gio/gio.h>
+#include <gegl.h>
+
+#include "libgimpbase/gimpbase.h"
+#include "libgimpconfig/gimpconfig.h"
+
+#include "config-types.h"
+
+#include "gimprc.h"
+#include "gimprc-serialize.h"
+#include "gimprc-unknown.h"
+
+
+static gboolean gimp_rc_serialize_properties_diff (GimpConfig *config,
+ GimpConfig *compare,
+ GimpConfigWriter *writer);
+static gboolean gimp_rc_serialize_unknown_tokens (GimpConfig *config,
+ GimpConfigWriter *writer);
+
+
+gboolean
+gimp_rc_serialize (GimpConfig *config,
+ GimpConfigWriter *writer,
+ gpointer data)
+{
+ if (data && GIMP_IS_RC (data))
+ {
+ if (! gimp_rc_serialize_properties_diff (config, data, writer))
+ return FALSE;
+ }
+ else
+ {
+ if (! gimp_config_serialize_properties (config, writer))
+ return FALSE;
+ }
+
+ return gimp_rc_serialize_unknown_tokens (config, writer);
+}
+
+static gboolean
+gimp_rc_serialize_properties_diff (GimpConfig *config,
+ GimpConfig *compare,
+ GimpConfigWriter *writer)
+{
+ GList *diff;
+ GList *list;
+ gboolean retval = TRUE;
+
+ g_return_val_if_fail (G_IS_OBJECT (config), FALSE);
+ g_return_val_if_fail (G_IS_OBJECT (compare), FALSE);
+ g_return_val_if_fail (G_TYPE_FROM_INSTANCE (config) ==
+ G_TYPE_FROM_INSTANCE (compare), FALSE);
+
+ diff = gimp_config_diff (G_OBJECT (config),
+ G_OBJECT (compare), GIMP_CONFIG_PARAM_SERIALIZE);
+
+ for (list = diff; list; list = g_list_next (list))
+ {
+ GParamSpec *prop_spec = list->data;
+
+ if (! (prop_spec->flags & GIMP_CONFIG_PARAM_SERIALIZE))
+ continue;
+
+ if (! gimp_config_serialize_property (config, prop_spec, writer))
+ {
+ retval = FALSE;
+ break;
+ }
+ }
+
+ g_list_free (diff);
+
+ return retval;
+}
+
+static void
+serialize_unknown_token (const gchar *key,
+ const gchar *value,
+ gpointer data)
+{
+ GimpConfigWriter *writer = data;
+
+ gimp_config_writer_open (writer, key);
+ gimp_config_writer_string (writer, value);
+ gimp_config_writer_close (writer);
+}
+
+static gboolean
+gimp_rc_serialize_unknown_tokens (GimpConfig *config,
+ GimpConfigWriter *writer)
+{
+ g_return_val_if_fail (G_IS_OBJECT (config), FALSE);
+
+ gimp_config_writer_linefeed (writer);
+ gimp_rc_foreach_unknown_token (config, serialize_unknown_token, writer);
+
+ return TRUE;
+}
diff --git a/app/config/gimprc-serialize.h b/app/config/gimprc-serialize.h
new file mode 100644
index 0000000..d314835
--- /dev/null
+++ b/app/config/gimprc-serialize.h
@@ -0,0 +1,30 @@
+/* GIMP - The GNU Image Manipulation Program
+ * Copyright (C) 1995 Spencer Kimball and Peter Mattis
+ *
+ * GimpRc serialization routines
+ * Copyright (C) 2001-2005 Sven Neumann <sven@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_RC_SERIALIZE_H__
+#define __GIMP_RC_SERIALIZE_H__
+
+
+gboolean gimp_rc_serialize (GimpConfig *config,
+ GimpConfigWriter *writer,
+ gpointer data);
+
+
+#endif /* __GIMP_RC_SERIALIZE_H__ */
diff --git a/app/config/gimprc-unknown.c b/app/config/gimprc-unknown.c
new file mode 100644
index 0000000..055b240
--- /dev/null
+++ b/app/config/gimprc-unknown.c
@@ -0,0 +1,214 @@
+/* GIMP - The GNU Image Manipulation Program
+ * Copyright (C) 1995 Spencer Kimball and Peter Mattis
+ *
+ * GimpRc serialization and deserialization helpers
+ * Copyright (C) 2001-2005 Sven Neumann <sven@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/>.
+ */
+
+#include "config.h"
+
+#include <string.h>
+
+#include <gio/gio.h>
+
+#include "libgimpbase/gimpbase.h"
+#include "libgimpconfig/gimpconfig.h"
+
+#include "config-types.h"
+
+#include "gimprc-unknown.h"
+
+
+/*
+ * Code to store and lookup unknown tokens (string key/value pairs).
+ */
+
+#define GIMP_RC_UNKNOWN_TOKENS "gimp-rc-unknown-tokens"
+
+typedef struct
+{
+ gchar *key;
+ gchar *value;
+} GimpConfigToken;
+
+static void gimp_rc_destroy_unknown_tokens (GSList *unknown_tokens);
+
+
+/**
+ * gimp_rc_add_unknown_token:
+ * @config: a #GObject.
+ * @key: a nul-terminated string to identify the value.
+ * @value: a nul-terminated string representing the value.
+ *
+ * This function adds arbitrary key/value pairs to a GObject. It's
+ * purpose is to attach additional data to a #GimpConfig object that
+ * can be stored along with the object properties when serializing the
+ * object to a configuration file. Please note however that the
+ * default gimp_config_serialize() implementation does not serialize
+ * unknown tokens.
+ *
+ * If you want to remove a key/value pair from the object, call this
+ * function with a %NULL @value.
+ **/
+void
+gimp_rc_add_unknown_token (GimpConfig *config,
+ const gchar *key,
+ const gchar *value)
+{
+ GimpConfigToken *token;
+ GSList *unknown_tokens;
+ GSList *last;
+ GSList *list;
+
+ g_return_if_fail (GIMP_IS_CONFIG (config));
+ g_return_if_fail (key != NULL);
+
+ unknown_tokens = (GSList *) g_object_get_data (G_OBJECT (config),
+ GIMP_RC_UNKNOWN_TOKENS);
+
+ for (last = NULL, list = unknown_tokens;
+ list;
+ last = list, list = g_slist_next (list))
+ {
+ token = (GimpConfigToken *) list->data;
+
+ if (strcmp (token->key, key) == 0)
+ {
+ g_free (token->value);
+
+ if (value)
+ {
+ token->value = g_strdup (value);
+ }
+ else
+ {
+ g_free (token->key);
+
+ unknown_tokens = g_slist_remove (unknown_tokens, token);
+ g_object_set_data_full (G_OBJECT (config),
+ GIMP_RC_UNKNOWN_TOKENS,
+ unknown_tokens,
+ (GDestroyNotify) gimp_rc_destroy_unknown_tokens);
+ }
+
+ return;
+ }
+ }
+
+ if (!value)
+ return;
+
+ token = g_slice_new (GimpConfigToken);
+ token->key = g_strdup (key);
+ token->value = g_strdup (value);
+
+ if (last)
+ {
+ last = g_slist_last (g_slist_append (last, token));
+ }
+ else
+ {
+ unknown_tokens = g_slist_append (NULL, token);
+
+ g_object_set_data_full (G_OBJECT (config),
+ GIMP_RC_UNKNOWN_TOKENS,
+ unknown_tokens,
+ (GDestroyNotify) gimp_rc_destroy_unknown_tokens);
+ }
+}
+
+/**
+ * gimp_rc_lookup_unknown_token:
+ * @config: a #GObject.
+ * @key: a nul-terminated string to identify the value.
+ *
+ * This function retrieves data that was previously attached using
+ * gimp_rc_add_unknown_token(). You should not free or modify
+ * the returned string.
+ *
+ * Returns: a pointer to a constant string.
+ **/
+const gchar *
+gimp_rc_lookup_unknown_token (GimpConfig *config,
+ const gchar *key)
+{
+ GSList *unknown_tokens;
+ GSList *list;
+
+ g_return_val_if_fail (GIMP_IS_CONFIG (config), NULL);
+ g_return_val_if_fail (key != NULL, NULL);
+
+ unknown_tokens = g_object_get_data (G_OBJECT (config),
+ GIMP_RC_UNKNOWN_TOKENS);
+
+ for (list = unknown_tokens; list; list = g_slist_next (list))
+ {
+ GimpConfigToken *token = list->data;
+
+ if (strcmp (token->key, key) == 0)
+ return token->value;
+ }
+
+ return NULL;
+}
+
+/**
+ * gimp_rc_foreach_unknown_token:
+ * @config: a #GObject.
+ * @func: a function to call for each key/value pair.
+ * @user_data: data to pass to @func.
+ *
+ * Calls @func for each key/value stored with the @config using
+ * gimp_rc_add_unknown_token().
+ **/
+void
+gimp_rc_foreach_unknown_token (GimpConfig *config,
+ GimpConfigForeachFunc func,
+ gpointer user_data)
+{
+ GSList *unknown_tokens;
+ GSList *list;
+
+ g_return_if_fail (GIMP_IS_CONFIG (config));
+ g_return_if_fail (func != NULL);
+
+ unknown_tokens = g_object_get_data (G_OBJECT (config),
+ GIMP_RC_UNKNOWN_TOKENS);
+
+ for (list = unknown_tokens; list; list = g_slist_next (list))
+ {
+ GimpConfigToken *token = list->data;
+
+ func (token->key, token->value, user_data);
+ }
+}
+
+static void
+gimp_rc_destroy_unknown_tokens (GSList *unknown_tokens)
+{
+ GSList *list;
+
+ for (list = unknown_tokens; list; list = g_slist_next (list))
+ {
+ GimpConfigToken *token = list->data;
+
+ g_free (token->key);
+ g_free (token->value);
+ g_slice_free (GimpConfigToken, token);
+ }
+
+ g_slist_free (unknown_tokens);
+}
diff --git a/app/config/gimprc-unknown.h b/app/config/gimprc-unknown.h
new file mode 100644
index 0000000..33a6243
--- /dev/null
+++ b/app/config/gimprc-unknown.h
@@ -0,0 +1,40 @@
+/* GIMP - The GNU Image Manipulation Program
+ * Copyright (C) 1995-1997 Spencer Kimball and Peter Mattis
+ *
+ * GimpRc serialization and deserialization helpers
+ * Copyright (C) 2001-2005 Sven Neumann <sven@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_RC_UNKNOWN_H__
+#define __GIMP_RC_UNKNOWN_H__
+
+
+typedef void (* GimpConfigForeachFunc) (const gchar *key,
+ const gchar *value,
+ gpointer user_data);
+
+
+void gimp_rc_add_unknown_token (GimpConfig *config,
+ const gchar *key,
+ const gchar *value);
+const gchar * gimp_rc_lookup_unknown_token (GimpConfig *config,
+ const gchar *key);
+void gimp_rc_foreach_unknown_token (GimpConfig *config,
+ GimpConfigForeachFunc func,
+ gpointer user_data);
+
+
+#endif /* __GIMP_RC_UNKNOWN_H__ */
diff --git a/app/config/gimprc.c b/app/config/gimprc.c
new file mode 100644
index 0000000..53d54e5
--- /dev/null
+++ b/app/config/gimprc.c
@@ -0,0 +1,593 @@
+/* GIMP - The GNU Image Manipulation Program
+ * Copyright (C) 1995 Spencer Kimball and Peter Mattis
+ *
+ * GimpRc, the object for GIMPs user configuration file gimprc.
+ * Copyright (C) 2001-2002 Sven Neumann <sven@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/>.
+ */
+
+#include "config.h"
+
+#include <string.h>
+
+#include <gio/gio.h>
+#include <gegl.h>
+
+#include "libgimpbase/gimpbase.h"
+#include "libgimpconfig/gimpconfig.h"
+
+#include "config-types.h"
+
+#include "gimpconfig-file.h"
+#include "gimprc.h"
+#include "gimprc-deserialize.h"
+#include "gimprc-serialize.h"
+#include "gimprc-unknown.h"
+
+#include "gimp-intl.h"
+
+
+enum
+{
+ PROP_0,
+ PROP_VERBOSE,
+ PROP_SYSTEM_GIMPRC,
+ PROP_USER_GIMPRC
+};
+
+
+static void gimp_rc_config_iface_init (GimpConfigInterface *iface);
+
+static void gimp_rc_dispose (GObject *object);
+static void gimp_rc_finalize (GObject *object);
+static void gimp_rc_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec);
+static void gimp_rc_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec);
+
+static GimpConfig * gimp_rc_duplicate (GimpConfig *object);
+static gboolean gimp_rc_idle_save (GimpRc *rc);
+static void gimp_rc_notify (GimpRc *rc,
+ GParamSpec *param,
+ gpointer data);
+
+
+G_DEFINE_TYPE_WITH_CODE (GimpRc, gimp_rc, GIMP_TYPE_PLUGIN_CONFIG,
+ G_IMPLEMENT_INTERFACE (GIMP_TYPE_CONFIG,
+ gimp_rc_config_iface_init))
+
+#define parent_class gimp_rc_parent_class
+
+
+static void
+gimp_rc_class_init (GimpRcClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+ object_class->dispose = gimp_rc_dispose;
+ object_class->finalize = gimp_rc_finalize;
+ object_class->set_property = gimp_rc_set_property;
+ object_class->get_property = gimp_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));
+
+ 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));
+
+ 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));
+}
+
+static void
+gimp_rc_init (GimpRc *rc)
+{
+ rc->autosave = FALSE;
+ rc->save_idle_id = 0;
+}
+
+static void
+gimp_rc_dispose (GObject *object)
+{
+ GimpRc *rc = GIMP_RC (object);
+
+ if (rc->save_idle_id)
+ gimp_rc_idle_save (rc);
+
+ G_OBJECT_CLASS (parent_class)->dispose (object);
+}
+
+static void
+gimp_rc_finalize (GObject *object)
+{
+ GimpRc *rc = GIMP_RC (object);
+
+ g_clear_object (&rc->system_gimprc);
+ g_clear_object (&rc->user_gimprc);
+
+ G_OBJECT_CLASS (parent_class)->finalize (object);
+}
+
+static void
+gimp_rc_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ GimpRc *rc = GIMP_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;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+ break;
+ }
+}
+
+static void
+gimp_rc_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ GimpRc *rc = GIMP_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;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+ break;
+ }
+}
+
+static void
+gimp_rc_config_iface_init (GimpConfigInterface *iface)
+{
+ iface->serialize = gimp_rc_serialize;
+ iface->deserialize = gimp_rc_deserialize;
+ iface->duplicate = gimp_rc_duplicate;
+}
+
+static void
+gimp_rc_duplicate_unknown_token (const gchar *key,
+ const gchar *value,
+ gpointer user_data)
+{
+ gimp_rc_add_unknown_token (GIMP_CONFIG (user_data), key, value);
+}
+
+static GimpConfig *
+gimp_rc_duplicate (GimpConfig *config)
+{
+ GObject *gimp;
+ GimpConfig *dup;
+
+ g_object_get (config, "gimp", &gimp, NULL);
+
+ dup = g_object_new (GIMP_TYPE_RC,
+ "gimp", gimp,
+ NULL);
+
+ if (gimp)
+ g_object_unref (gimp);
+
+ gimp_config_sync (G_OBJECT (config), G_OBJECT (dup), 0);
+
+ gimp_rc_foreach_unknown_token (config,
+ gimp_rc_duplicate_unknown_token, dup);
+
+ return dup;
+}
+
+static gboolean
+gimp_rc_idle_save (GimpRc *rc)
+{
+ gimp_rc_save (rc);
+
+ rc->save_idle_id = 0;
+
+ return FALSE;
+}
+
+static void
+gimp_rc_notify (GimpRc *rc,
+ GParamSpec *param,
+ gpointer data)
+{
+ if (!rc->autosave)
+ return;
+
+ if (!rc->save_idle_id)
+ rc->save_idle_id = g_idle_add ((GSourceFunc) gimp_rc_idle_save, rc);
+}
+
+/**
+ * gimp_rc_new:
+ * @gimp: a #Gimp
+ * @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 and saving
+ *
+ * Creates a new GimpRc object and loads the system-wide and the user
+ * configuration files.
+ *
+ * Returns: the new #GimpRc.
+ */
+GimpRc *
+gimp_rc_new (GObject *gimp,
+ GFile *system_gimprc,
+ GFile *user_gimprc,
+ gboolean verbose)
+{
+ GimpRc *rc;
+
+ g_return_val_if_fail (G_IS_OBJECT (gimp), NULL);
+ 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_RC,
+ "gimp", gimp,
+ "verbose", verbose,
+ "system-gimprc", system_gimprc,
+ "user-gimprc", user_gimprc,
+ NULL);
+
+ gimp_rc_load_system (rc);
+ gimp_rc_load_user (rc);
+
+ return rc;
+}
+
+void
+gimp_rc_load_system (GimpRc *rc)
+{
+ GError *error = NULL;
+
+ g_return_if_fail (GIMP_IS_RC (rc));
+
+ if (rc->verbose)
+ g_print ("Parsing '%s'\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);
+ }
+}
+
+void
+gimp_rc_load_user (GimpRc *rc)
+{
+ GError *error = NULL;
+
+ g_return_if_fail (GIMP_IS_RC (rc));
+
+ if (rc->verbose)
+ g_print ("Parsing '%s'\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);
+
+ gimp_config_file_backup_on_error (rc->user_gimprc, "gimprc", NULL);
+ }
+
+ g_clear_error (&error);
+ }
+}
+
+void
+gimp_rc_set_autosave (GimpRc *rc,
+ gboolean autosave)
+{
+ g_return_if_fail (GIMP_IS_RC (rc));
+
+ autosave = autosave ? TRUE : FALSE;
+
+ if (rc->autosave == autosave)
+ return;
+
+ if (autosave)
+ g_signal_connect (rc, "notify",
+ G_CALLBACK (gimp_rc_notify),
+ NULL);
+ else
+ g_signal_handlers_disconnect_by_func (rc, gimp_rc_notify, NULL);
+
+ rc->autosave = autosave;
+}
+
+
+/**
+ * gimp_rc_query:
+ * @rc: a #GimpRc object.
+ * @key: a string used as a key for the lookup.
+ *
+ * This function looks up @key in the object properties of @rc. If
+ * there's a matching property, a string representation of its value
+ * is returned. If no property is found, the list of unknown tokens
+ * attached to the @rc object is searched.
+ *
+ * Return value: a newly allocated string representing the value or %NULL
+ * if the key couldn't be found.
+ **/
+gchar *
+gimp_rc_query (GimpRc *rc,
+ const gchar *key)
+{
+ GObjectClass *klass;
+ GObject *rc_object;
+ GParamSpec **property_specs;
+ GParamSpec *prop_spec;
+ guint i, n_property_specs;
+ gchar *retval = NULL;
+
+ g_return_val_if_fail (GIMP_IS_RC (rc), NULL);
+ g_return_val_if_fail (key != NULL, NULL);
+
+ rc_object = G_OBJECT (rc);
+ klass = G_OBJECT_GET_CLASS (rc);
+
+ property_specs = g_object_class_list_properties (klass, &n_property_specs);
+
+ if (!property_specs)
+ return NULL;
+
+ for (i = 0, prop_spec = NULL; i < n_property_specs && !prop_spec; i++)
+ {
+ prop_spec = property_specs[i];
+
+ if (! (prop_spec->flags & GIMP_CONFIG_PARAM_SERIALIZE) ||
+ strcmp (prop_spec->name, key))
+ {
+ prop_spec = NULL;
+ }
+ }
+
+ if (prop_spec)
+ {
+ GString *str = g_string_new (NULL);
+ GValue value = G_VALUE_INIT;
+
+ g_value_init (&value, prop_spec->value_type);
+ g_object_get_property (rc_object, prop_spec->name, &value);
+
+ if (gimp_config_serialize_value (&value, str, FALSE))
+ retval = g_string_free (str, FALSE);
+ else
+ g_string_free (str, TRUE);
+
+ g_value_unset (&value);
+ }
+ else
+ {
+ retval = g_strdup (gimp_rc_lookup_unknown_token (GIMP_CONFIG (rc), key));
+ }
+
+ g_free (property_specs);
+
+ if (!retval)
+ {
+ const gchar * const path_tokens[] =
+ {
+ "gimp_dir",
+ "gimp_data_dir",
+ "gimp_plug_in_dir",
+ "gimp_plugin_dir",
+ "gimp_sysconf_dir"
+ };
+
+ for (i = 0; !retval && i < G_N_ELEMENTS (path_tokens); i++)
+ if (strcmp (key, path_tokens[i]) == 0)
+ retval = g_strdup_printf ("${%s}", path_tokens[i]);
+ }
+
+ if (retval)
+ {
+ gchar *tmp = gimp_config_path_expand (retval, FALSE, NULL);
+
+ if (tmp)
+ {
+ g_free (retval);
+ retval = tmp;
+ }
+ }
+
+ return retval;
+}
+
+/**
+ * gimp_rc_set_unknown_token:
+ * @gimprc: a #GimpRc object.
+ * @token:
+ * @value:
+ *
+ * Calls gimp_rc_add_unknown_token() and triggers an idle-save if
+ * autosave is enabled on @gimprc.
+ **/
+void
+gimp_rc_set_unknown_token (GimpRc *rc,
+ const gchar *token,
+ const gchar *value)
+{
+ g_return_if_fail (GIMP_IS_RC (rc));
+
+ gimp_rc_add_unknown_token (GIMP_CONFIG (rc), token, value);
+
+ if (rc->autosave)
+ gimp_rc_notify (rc, NULL, NULL);
+}
+
+/**
+ * gimp_rc_save:
+ * @gimprc: a #GimpRc object.
+ *
+ * Saves any settings that differ from the system-wide defined
+ * defaults to the users personal gimprc file.
+ **/
+void
+gimp_rc_save (GimpRc *rc)
+{
+ GObject *gimp;
+ GimpRc *global;
+ gchar *header;
+ GError *error = NULL;
+
+ const gchar *top =
+ "GIMP gimprc\n"
+ "\n"
+ "This is your personal gimprc file. Any variable defined in this file "
+ "takes precedence over the value defined in the system-wide gimprc: ";
+ const gchar *bottom =
+ "\n"
+ "Most values can be set within GIMP by changing some options in "
+ "the Preferences dialog.";
+ const gchar *footer =
+ "end of gimprc";
+
+ g_return_if_fail (GIMP_IS_RC (rc));
+
+ g_object_get (rc, "gimp", &gimp, NULL);
+
+ global = g_object_new (GIMP_TYPE_RC,
+ "gimp", gimp,
+ NULL);
+
+ if (gimp)
+ g_object_unref (gimp);
+
+ gimp_config_deserialize_gfile (GIMP_CONFIG (global),
+ rc->system_gimprc, NULL, NULL);
+
+ header = g_strconcat (top, gimp_file_get_utf8_name (rc->system_gimprc),
+ bottom, NULL);
+
+ if (rc->verbose)
+ g_print ("Writing '%s'\n",
+ gimp_file_get_utf8_name (rc->user_gimprc));
+
+ if (! gimp_config_serialize_to_gfile (GIMP_CONFIG (rc),
+ rc->user_gimprc,
+ header, footer, global,
+ &error))
+ {
+ g_message ("%s", error->message);
+ g_error_free (error);
+ }
+
+ g_free (header);
+ g_object_unref (global);
+}
+
+/**
+ * gimp_rc_migrate:
+ * @rc: a #GimpRc object.
+ *
+ * Resets all GimpParamConfigPath properties of the passed rc object
+ * to their default values, in order to prevent paths in a migrated
+ * gimprc to refer to folders in the old GIMP's user directory.
+ **/
+void
+gimp_rc_migrate (GimpRc *rc)
+{
+ GParamSpec **pspecs;
+ guint n_pspecs;
+ gint i;
+
+ g_return_if_fail (GIMP_IS_RC (rc));
+
+ pspecs = g_object_class_list_properties (G_OBJECT_GET_CLASS (rc), &n_pspecs);
+
+ for (i = 0; i < n_pspecs; i++)
+ {
+ GParamSpec *pspec = pspecs[i];
+
+ if (GIMP_IS_PARAM_SPEC_CONFIG_PATH (pspec))
+ {
+ GValue value = G_VALUE_INIT;
+
+ g_value_init (&value, pspec->value_type);
+
+ g_param_value_set_default (pspec, &value);
+ g_object_set_property (G_OBJECT (rc), pspec->name, &value);
+
+ g_value_unset (&value);
+ }
+ }
+
+ g_free (pspecs);
+}
diff --git a/app/config/gimprc.h b/app/config/gimprc.h
new file mode 100644
index 0000000..fbe47a1
--- /dev/null
+++ b/app/config/gimprc.h
@@ -0,0 +1,77 @@
+/* GIMP - The GNU Image Manipulation Program
+ * Copyright (C) 1995 Spencer Kimball and Peter Mattis
+ *
+ * GimpRc
+ * Copyright (C) 2001 Sven Neumann <sven@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_RC_H__
+#define __GIMP_RC_H__
+
+#include "config/gimppluginconfig.h"
+
+
+#define GIMP_TYPE_RC (gimp_rc_get_type ())
+#define GIMP_RC(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GIMP_TYPE_RC, GimpRc))
+#define GIMP_RC_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GIMP_TYPE_RC, GimpRcClass))
+#define GIMP_IS_RC(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GIMP_TYPE_RC))
+#define GIMP_IS_RC_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GIMP_TYPE_RC))
+
+
+typedef struct _GimpRcClass GimpRcClass;
+
+struct _GimpRc
+{
+ GimpPluginConfig parent_instance;
+
+ GFile *user_gimprc;
+ GFile *system_gimprc;
+ gboolean verbose;
+ gboolean autosave;
+ guint save_idle_id;
+};
+
+struct _GimpRcClass
+{
+ GimpPluginConfigClass parent_class;
+};
+
+
+GType gimp_rc_get_type (void) G_GNUC_CONST;
+
+GimpRc * gimp_rc_new (GObject *gimp,
+ GFile *system_gimprc,
+ GFile *user_gimprc,
+ gboolean verbose);
+
+void gimp_rc_load_system (GimpRc *rc);
+void gimp_rc_load_user (GimpRc *rc);
+
+void gimp_rc_set_autosave (GimpRc *rc,
+ gboolean autosave);
+void gimp_rc_save (GimpRc *rc);
+
+gchar * gimp_rc_query (GimpRc *rc,
+ const gchar *key);
+
+void gimp_rc_set_unknown_token (GimpRc *rc,
+ const gchar *token,
+ const gchar *value);
+
+void gimp_rc_migrate (GimpRc *rc);
+
+
+#endif /* GIMP_RC_H__ */
diff --git a/app/config/gimpxmlparser.c b/app/config/gimpxmlparser.c
new file mode 100644
index 0000000..1bec8f8
--- /dev/null
+++ b/app/config/gimpxmlparser.c
@@ -0,0 +1,404 @@
+/* GIMP - The GNU Image Manipulation Program
+ * Copyright (C) 1995-1997 Spencer Kimball and Peter Mattis
+ *
+ * GimpXmlParser
+ * Copyright (C) 2003 Sven Neumann <sven@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/>.
+ */
+
+#include "config.h"
+
+#include <string.h>
+
+#include <gio/gio.h>
+
+#include "config-types.h"
+
+#include "gimpxmlparser.h"
+
+
+struct _GimpXmlParser
+{
+ GMarkupParseContext *context;
+};
+
+
+static gboolean parse_encoding (const gchar *text,
+ gint text_len,
+ gchar **encodind);
+
+
+/**
+ * gimp_xml_parser_new:
+ * @markup_parser: a #GMarkupParser
+ * @user_data: user data to pass to #GMarkupParser functions
+ *
+ * GimpXmlParser is a thin wrapper around GMarkupParser. This function
+ * creates one for you and sets up a GMarkupParseContext.
+ *
+ * Return value: a new #GimpXmlParser
+ **/
+GimpXmlParser *
+gimp_xml_parser_new (const GMarkupParser *markup_parser,
+ gpointer user_data)
+{
+ GimpXmlParser *parser;
+
+ g_return_val_if_fail (markup_parser != NULL, NULL);
+
+ parser = g_slice_new (GimpXmlParser);
+
+ parser->context = g_markup_parse_context_new (markup_parser,
+ 0, user_data, NULL);
+
+ return parser;
+}
+
+/**
+ * gimp_xml_parser_parse_file:
+ * @parser: a #GimpXmlParser
+ * @filename: name of a file to parse
+ * @error: return location for possible errors
+ *
+ * This function creates a GIOChannel for @filename and calls
+ * gimp_xml_parser_parse_io_channel() for you.
+ *
+ * Return value: %TRUE on success, %FALSE otherwise
+ **/
+gboolean
+gimp_xml_parser_parse_file (GimpXmlParser *parser,
+ const gchar *filename,
+ GError **error)
+{
+ GIOChannel *io;
+ gboolean success;
+
+ g_return_val_if_fail (parser != NULL, FALSE);
+ g_return_val_if_fail (filename != NULL, FALSE);
+ g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
+
+ io = g_io_channel_new_file (filename, "r", error);
+ if (!io)
+ return FALSE;
+
+ success = gimp_xml_parser_parse_io_channel (parser, io, error);
+
+ g_io_channel_unref (io);
+
+ return success;
+}
+
+/**
+ * gimp_xml_parser_parse_gfile:
+ * @parser: a #GimpXmlParser
+ * @file: the #GFile to parse
+ * @error: return location for possible errors
+ *
+ * This function creates a GIOChannel for @file and calls
+ * gimp_xml_parser_parse_io_channel() for you.
+ *
+ * Return value: %TRUE on success, %FALSE otherwise
+ **/
+gboolean
+gimp_xml_parser_parse_gfile (GimpXmlParser *parser,
+ GFile *file,
+ GError **error)
+{
+ gchar *path;
+ gboolean success;
+
+ g_return_val_if_fail (parser != NULL, FALSE);
+ g_return_val_if_fail (G_IS_FILE (file), FALSE);
+
+ path = g_file_get_path (file);
+
+ success = gimp_xml_parser_parse_file (parser, path, error);
+
+ g_free (path);
+
+ return success;
+}
+
+/**
+ * gimp_xml_parser_parse_fd:
+ * @parser: a #GimpXmlParser
+ * @fd: a file descriptor
+ * @error: return location for possible errors
+ *
+ * This function creates a GIOChannel for @fd and calls
+ * gimp_xml_parser_parse_io_channel() for you.
+ *
+ * Return value: %TRUE on success, %FALSE otherwise
+ **/
+gboolean
+gimp_xml_parser_parse_fd (GimpXmlParser *parser,
+ gint fd,
+ GError **error)
+{
+ GIOChannel *io;
+ gboolean success;
+
+ g_return_val_if_fail (parser != NULL, FALSE);
+ g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
+
+#ifdef G_OS_WIN32
+ io = g_io_channel_win32_new_fd (fd);
+#else
+ io = g_io_channel_unix_new (fd);
+#endif
+
+ success = gimp_xml_parser_parse_io_channel (parser, io, error);
+
+ g_io_channel_unref (io);
+
+ return success;
+}
+
+/**
+ * gimp_xml_parser_parse_io_channel:
+ * @parser: a #GimpXmlParser
+ * @io: a #GIOChannel
+ * @error: return location for possible errors
+ *
+ * Makes @parser read from the specified @io channel. This function
+ * returns when the GIOChannel becomes empty (end of file) or an
+ * error occurs, either reading from @io or parsing the read data.
+ *
+ * This function tries to determine the character encoding from the
+ * XML header and converts the content to UTF-8 for you. For this
+ * feature to work, the XML header with the encoding attribute must be
+ * contained in the first 4096 bytes read. Otherwise UTF-8 encoding
+ * will be assumed and parsing may break later if this assumption
+ * was wrong.
+ *
+ * Return value: %TRUE on success, %FALSE otherwise
+ **/
+gboolean
+gimp_xml_parser_parse_io_channel (GimpXmlParser *parser,
+ GIOChannel *io,
+ GError **error)
+{
+ GIOStatus status;
+ gchar buffer[4096];
+ gsize len = 0;
+ gsize bytes;
+ const gchar *io_encoding;
+ gchar *encoding = NULL;
+
+ g_return_val_if_fail (parser != NULL, FALSE);
+ g_return_val_if_fail (io != NULL, FALSE);
+ g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
+
+ io_encoding = g_io_channel_get_encoding (io);
+ if (g_strcmp0 (io_encoding, "UTF-8"))
+ {
+ g_warning ("gimp_xml_parser_parse_io_channel():\n"
+ "The encoding has already been set on this GIOChannel!");
+ return FALSE;
+ }
+
+ /* try to determine the encoding */
+
+ g_io_channel_set_encoding (io, NULL, NULL);
+
+ while (len < sizeof (buffer))
+ {
+ status = g_io_channel_read_chars (io, buffer + len, 1, &bytes, error);
+ len += bytes;
+
+ if (status == G_IO_STATUS_ERROR)
+ return FALSE;
+ if (status == G_IO_STATUS_EOF)
+ break;
+
+ if (parse_encoding (buffer, len, &encoding))
+ break;
+ }
+
+ if (encoding)
+ {
+ if (! g_io_channel_set_encoding (io, encoding, error))
+ return FALSE;
+
+ g_free (encoding);
+ }
+ else
+ {
+ g_io_channel_set_encoding (io, "UTF-8", NULL);
+ }
+
+ while (TRUE)
+ {
+ if (!g_markup_parse_context_parse (parser->context, buffer, len, error))
+ return FALSE;
+
+ status = g_io_channel_read_chars (io,
+ buffer, sizeof (buffer), &len, error);
+
+ switch (status)
+ {
+ case G_IO_STATUS_ERROR:
+ return FALSE;
+ case G_IO_STATUS_EOF:
+ return g_markup_parse_context_end_parse (parser->context, error);
+ case G_IO_STATUS_NORMAL:
+ case G_IO_STATUS_AGAIN:
+ break;
+ }
+ }
+}
+
+/**
+ * gimp_xml_parser_parse_buffer:
+ * @parser: a #GimpXmlParser
+ * @buffer: a string buffer
+ * @len: the number of byes in @buffer or -1 if @buffer is nul-terminated
+ * @error: return location for possible errors
+ *
+ * This function uses the given @parser to parse the XML in @buffer.
+ *
+ * Return value: %TRUE on success, %FALSE otherwise
+ **/
+gboolean
+gimp_xml_parser_parse_buffer (GimpXmlParser *parser,
+ const gchar *buffer,
+ gssize len,
+ GError **error)
+{
+ gchar *encoding = NULL;
+ gchar *conv = NULL;
+ gboolean success;
+
+ g_return_val_if_fail (parser != NULL, FALSE);
+ g_return_val_if_fail (buffer != NULL || len == 0, FALSE);
+ g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
+
+ if (len < 0)
+ len = strlen (buffer);
+
+ if (parse_encoding (buffer, len, &encoding) && encoding)
+ {
+ if (g_ascii_strcasecmp (encoding, "UTF-8") &&
+ g_ascii_strcasecmp (encoding, "UTF8"))
+ {
+ gsize written;
+
+ conv = g_convert (buffer, len,
+ "UTF-8", encoding, NULL, &written, error);
+ if (! conv)
+ {
+ g_free (encoding);
+ return FALSE;
+ }
+
+ len = written;
+ }
+
+ g_free (encoding);
+ }
+
+ success = g_markup_parse_context_parse (parser->context,
+ conv ? conv : buffer, len, error);
+
+ if (conv)
+ g_free (conv);
+
+ return success;
+}
+
+/**
+ * gimp_xml_parser_free:
+ * @parser: a #GimpXmlParser
+ *
+ * Frees the resources allocated for @parser. You must not access
+ * @parser after calling this function.
+ **/
+void
+gimp_xml_parser_free (GimpXmlParser *parser)
+{
+ g_return_if_fail (parser != NULL);
+
+ g_markup_parse_context_free (parser->context);
+ g_slice_free (GimpXmlParser, parser);
+}
+
+
+/* Try to determine encoding from XML header. This function returns
+ FALSE when it doesn't have enough text to parse. It returns TRUE
+ and sets encoding when the XML header has been parsed.
+ */
+static gboolean
+parse_encoding (const gchar *text,
+ gint text_len,
+ gchar **encoding)
+{
+ const gchar *start;
+ const gchar *end;
+ gint i;
+
+ g_return_val_if_fail (text, FALSE);
+
+ if (text_len < 20)
+ return FALSE;
+
+ start = g_strstr_len (text, text_len, "<?xml");
+ if (!start)
+ return FALSE;
+
+ end = g_strstr_len (start, text_len - (start - text), "?>");
+ if (!end)
+ return FALSE;
+
+ *encoding = NULL;
+
+ text_len = end - start;
+ if (text_len < 12)
+ return TRUE;
+
+ start = g_strstr_len (start + 1, text_len - 1, "encoding");
+ if (!start)
+ return TRUE;
+
+ start += 8;
+
+ while (start < end && *start == ' ')
+ start++;
+
+ if (*start != '=')
+ return TRUE;
+
+ start++;
+
+ while (start < end && *start == ' ')
+ start++;
+
+ if (*start != '\"' && *start != '\'')
+ return TRUE;
+
+ text_len = end - start;
+ if (text_len < 1)
+ return TRUE;
+
+ for (i = 1; i < text_len; i++)
+ if (start[i] == start[0])
+ break;
+
+ if (i == text_len || i < 3)
+ return TRUE;
+
+ *encoding = g_strndup (start + 1, i - 1);
+
+ return TRUE;
+}
diff --git a/app/config/gimpxmlparser.h b/app/config/gimpxmlparser.h
new file mode 100644
index 0000000..f744472
--- /dev/null
+++ b/app/config/gimpxmlparser.h
@@ -0,0 +1,46 @@
+/* GIMP - The GNU Image Manipulation Program
+ * Copyright (C) 1995-1997 Spencer Kimball and Peter Mattis
+ *
+ * GimpXmlParser
+ * Copyright (C) 2003 Sven Neumann <sven@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_XML_PARSER_H__
+#define __GIMP_XML_PARSER_H__
+
+
+GimpXmlParser * gimp_xml_parser_new (const GMarkupParser *markup_parser,
+ gpointer user_data);
+gboolean gimp_xml_parser_parse_file (GimpXmlParser *parser,
+ const gchar *filename,
+ GError **error);
+gboolean gimp_xml_parser_parse_gfile (GimpXmlParser *parser,
+ GFile *file,
+ GError **error);
+gboolean gimp_xml_parser_parse_fd (GimpXmlParser *parser,
+ gint fd,
+ GError **error);
+gboolean gimp_xml_parser_parse_io_channel (GimpXmlParser *parser,
+ GIOChannel *io,
+ GError **error);
+gboolean gimp_xml_parser_parse_buffer (GimpXmlParser *parser,
+ const gchar *buffer,
+ gssize len,
+ GError **error);
+void gimp_xml_parser_free (GimpXmlParser *parser);
+
+
+#endif /* __GIMP_XML_PARSER_H__ */
diff --git a/app/config/test-config.c b/app/config/test-config.c
new file mode 100644
index 0000000..1aff0a4
--- /dev/null
+++ b/app/config/test-config.c
@@ -0,0 +1,278 @@
+/* GIMP - The GNU Image Manipulation Program
+ * Copyright (C) 1995 Spencer Kimball and Peter Mattis
+ *
+ * Test suite for GimpConfig.
+ * Copyright (C) 2001-2002 Sven Neumann <sven@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/>.
+ */
+
+#include "config.h"
+
+#include "stdlib.h"
+#include "string.h"
+
+#include <gio/gio.h>
+
+#include "libgimpbase/gimpbase.h"
+#include "libgimpbase/gimpbase-private.h"
+#include "libgimpconfig/gimpconfig.h"
+
+#include "core/core-types.h"
+#include "core/gimpgrid.h"
+
+#include "gimprc-unknown.h"
+
+
+static void notify_callback (GObject *object,
+ GParamSpec *pspec);
+static void output_unknown_token (const gchar *key,
+ const gchar *value,
+ gpointer data);
+
+static void units_init (void);
+
+
+int
+main (int argc,
+ char *argv[])
+{
+ GimpConfig *grid;
+ GimpConfig *grid2;
+ const gchar *filename = "foorc";
+ gchar *header;
+ gchar *result;
+ GList *list;
+ gint i;
+ GError *error = NULL;
+
+ for (i = 1; i < argc; i++)
+ {
+ if (strcmp (argv[i], "--g-fatal-warnings") == 0)
+ {
+ GLogLevelFlags fatal_mask;
+
+ fatal_mask = g_log_set_always_fatal (G_LOG_FATAL_MASK);
+ fatal_mask |= G_LOG_LEVEL_WARNING | G_LOG_LEVEL_CRITICAL;
+ g_log_set_always_fatal (fatal_mask);
+ }
+ }
+
+ units_init ();
+
+ g_print ("\nTesting GimpConfig ...\n");
+
+ g_print (" Creating a new Grid object ...");
+ grid = g_object_new (GIMP_TYPE_GRID, NULL);
+ g_print (" done.\n");
+
+ g_print (" Adding the unknown token (foobar \"hadjaha\") ...");
+ gimp_rc_add_unknown_token (grid, "foobar", "hadjaha");
+ g_print (" done.\n");
+
+ g_print (" Serializing %s to '%s' ...",
+ g_type_name (G_TYPE_FROM_INSTANCE (grid)), filename);
+
+ if (! gimp_config_serialize_to_file (grid,
+ filename,
+ "foorc", "end of foorc",
+ NULL, &error))
+ {
+ g_print ("%s\n", error->message);
+ return EXIT_FAILURE;
+ }
+ g_print (" done.\n");
+
+ g_signal_connect (grid, "notify",
+ G_CALLBACK (notify_callback),
+ NULL);
+
+ g_print (" Deserializing from '%s' ...\n", filename);
+ if (! gimp_config_deserialize_file (grid, filename, NULL, &error))
+ {
+ g_print ("%s\n", error->message);
+ return EXIT_FAILURE;
+ }
+ header = " Unknown string tokens:\n";
+ gimp_rc_foreach_unknown_token (grid, output_unknown_token, &header);
+ g_print (" done.\n\n");
+
+ g_print (" Changing a property ...");
+ g_object_set (grid, "style", GIMP_GRID_DOTS, NULL);
+
+ g_print (" Testing gimp_config_duplicate() ...");
+ grid2 = gimp_config_duplicate (grid);
+ g_print (" done.\n");
+
+ g_signal_connect (grid2, "notify",
+ G_CALLBACK (notify_callback),
+ NULL);
+
+ g_print (" Changing a property in the duplicate ...");
+ g_object_set (grid2, "xspacing", 20.0, NULL);
+
+ g_print (" Creating a diff between the two ...");
+ for (list = gimp_config_diff (G_OBJECT (grid), G_OBJECT (grid2), 0);
+ list;
+ list = list->next)
+ {
+ GParamSpec *pspec = list->data;
+
+ g_print ("%c%s", (list->prev ? ',' : ' '), pspec->name);
+ }
+ g_print ("\n\n");
+
+ g_object_unref (grid2);
+
+ g_print (" Deserializing from gimpconfig.c (should fail) ...");
+ if (! gimp_config_deserialize_file (grid, "gimpconfig.c", NULL, &error))
+ {
+ g_print (" OK, failed. The error was:\n %s\n", error->message);
+ g_error_free (error);
+ error = NULL;
+ }
+ else
+ {
+ g_print ("This test should have failed :-(\n");
+ return EXIT_FAILURE;
+ }
+
+ g_print (" Serializing to a string and back ... ");
+
+ result = gimp_config_serialize_to_string (grid, NULL);
+
+ grid2 = g_object_new (GIMP_TYPE_GRID, NULL);
+
+ if (! gimp_config_deserialize_string (grid2, result, -1, NULL, &error))
+ {
+ g_print ("failed!\nThe error was:\n %s\n", error->message);
+ g_error_free (error);
+ return EXIT_FAILURE;
+ }
+ else
+ {
+ GList *diff = gimp_config_diff (G_OBJECT (grid), G_OBJECT (grid2), 0);
+
+ if (diff)
+ {
+ GList *list;
+
+ g_print ("succeeded but properties differ:\n");
+ for (list = diff; list; list = list->next)
+ {
+ GParamSpec *pspec = list->data;
+ g_print (" %s\n", pspec->name);
+ }
+ return EXIT_FAILURE;
+ }
+
+ g_print ("OK (%u bytes)\n", result ? (guint) strlen (result) : 0);
+ }
+
+ g_free (result);
+ g_object_unref (grid2);
+ g_object_unref (grid);
+
+ g_print ("\nFinished test of GimpConfig.\n\n");
+
+ return EXIT_SUCCESS;
+}
+
+static void
+notify_callback (GObject *object,
+ GParamSpec *pspec)
+{
+ GString *str;
+ GValue value = G_VALUE_INIT;
+
+ g_return_if_fail (G_IS_OBJECT (object));
+ g_return_if_fail (G_IS_PARAM_SPEC (pspec));
+
+ g_value_init (&value, pspec->value_type);
+ g_object_get_property (object, pspec->name, &value);
+
+ str = g_string_new (NULL);
+
+ if (gimp_config_serialize_value (&value, str, TRUE))
+ {
+ g_print (" %s -> %s\n", pspec->name, str->str);
+ }
+ else
+ {
+ g_print (" %s changed but we failed to serialize its value!\n",
+ pspec->name);
+ }
+
+ g_string_free (str, TRUE);
+ g_value_unset (&value);
+}
+
+static void
+output_unknown_token (const gchar *key,
+ const gchar *value,
+ gpointer data)
+{
+ gchar **header = (gchar **) data;
+ gchar *escaped = g_strescape (value, NULL);
+
+ if (*header)
+ {
+ g_print ("%s", *header);
+ *header = NULL;
+ }
+
+ g_print (" %s \"%s\"\n", key, escaped);
+
+ g_free (escaped);
+}
+
+
+/* minimal dummy units implementation */
+
+static const gchar *
+unit_get_identifier (GimpUnit unit)
+{
+ switch (unit)
+ {
+ case GIMP_UNIT_PIXEL:
+ return "pixels";
+ case GIMP_UNIT_INCH:
+ return "inches";
+ case GIMP_UNIT_MM:
+ return "millimeters";
+ case GIMP_UNIT_POINT:
+ return "points";
+ case GIMP_UNIT_PICA:
+ return "picas";
+ default:
+ return NULL;
+ }
+}
+
+static gint
+unit_get_number_of_units (void)
+{
+ return GIMP_UNIT_END;
+}
+
+static void
+units_init (void)
+{
+ GimpUnitVtable vtable;
+
+ vtable.unit_get_number_of_units = unit_get_number_of_units;
+ vtable.unit_get_identifier = unit_get_identifier;
+
+ gimp_base_init (&vtable);
+}