diff options
Diffstat (limited to 'libgimpbase')
49 files changed, 20154 insertions, 0 deletions
diff --git a/libgimpbase/Makefile.am b/libgimpbase/Makefile.am new file mode 100644 index 0000000..4214939 --- /dev/null +++ b/libgimpbase/Makefile.am @@ -0,0 +1,264 @@ +## Process this file with automake to produce Makefile.in + +if PLATFORM_WIN32 +no_undefined = -no-undefined +endif + +if PLATFORM_OSX +xobjective_c = "-xobjective-c" +xobjective_cxx = "-xobjective-c++" +xnone = "-xnone" +framework_cocoa = -framework Cocoa +endif + +if OS_WIN32 +ole32_lib = -lole32 +gimpbase_def = gimpbase.def +libgimpbase_export_symbols = -export-symbols $(srcdir)/gimpbase.def + +install-libtool-import-lib: + $(INSTALL) .libs/libgimpbase-$(GIMP_API_VERSION).dll.a $(DESTDIR)$(libdir) + $(INSTALL) $(srcdir)/gimpbase.def $(DESTDIR)$(libdir) + +uninstall-libtool-import-lib: + -rm $(DESTDIR)$(libdir)/libgimpbase-$(GIMP_API_VERSION).dll.a + -rm $(DESTDIR)$(libdir)/gimpbase.def +else +libm = -lm +install-libtool-import-lib: +uninstall-libtool-import-lib: +endif + +if MS_LIB_AVAILABLE +noinst_DATA = gimpbase-$(GIMP_API_VERSION).lib + +install-ms-lib: + $(INSTALL) gimpbase-$(GIMP_API_VERSION).lib $(DESTDIR)$(libdir) + +uninstall-ms-lib: + -rm $(DESTDIR)$(libdir)/gimpbase-$(GIMP_API_VERSION).lib + +gimpbase-@GIMP_API_VERSION@.lib: gimpbase.def + lib -name:libgimpbase-$(GIMP_API_VERSION)-@LT_CURRENT_MINUS_AGE@.dll -def:gimpbase.def -out:$@ + +else +install-ms-lib: +uninstall-ms-lib: +endif + +libgimpbaseincludedir = $(includedir)/gimp-$(GIMP_API_VERSION)/libgimpbase + +AM_CPPFLAGS = \ + -DPREFIX=\""$(prefix)"\" \ + -DGIMPDIR=\""$(gimpdir)"\" \ + -DGIMPDATADIR=\""$(gimpdatadir)"\" \ + -DLOCALEDIR=\""$(gimplocaledir)"\" \ + -DPLUGINDIR=\""$(gimpplugindir)"\" \ + -DGIMPSYSCONFDIR=\""$(gimpsysconfdir)"\" \ + -DGIMP_PACKAGE=\""@PACKAGE@"\" \ + -DGIMP_DATA_VERSION=\"$(GIMP_DATA_VERSION)\" \ + -DGIMP_USER_VERSION=\"$(GIMP_USER_VERSION)\" \ + -DGIMP_SYSCONF_VERSION=\"$(GIMP_SYSCONF_VERSION)\" \ + -DGIMP_PLUGIN_VERSION=\"$(GIMP_PLUGIN_VERSION)\" \ + -DG_LOG_DOMAIN=\"LibGimpBase\" \ + -DGIMP_BASE_COMPILATION \ + -I$(top_srcdir) \ + $(GIO_CFLAGS) \ + $(GEXIV2_CFLAGS) \ + -I$(includedir) + +AM_CFLAGS = \ + $(xobjective_c) + +AM_CXXFLAGS = \ + $(xobjective_cxx) + +AM_CCASFLAGS = \ + -I$(top_builddir) \ + -I$(top_srcdir) + +AM_LDFLAGS = \ + $(xnone) + +EXTRA_DIST = \ + gimpbase.def + +lib_LTLIBRARIES = libgimpbase-@GIMP_API_VERSION@.la + +# help `make' along by giving another name for the file, which it knows +# how to build +../libgimpbase/gimpversion.h: gimpversion.h + @: + + +libgimpbase_sources = \ + gimpbase.h \ + gimpbaseenums.h \ + gimpcompatenums.h \ + gimpbasetypes.h \ + gimpbasetypes.c \ + gimplimits.h \ + gimpparam.h \ + gimpversion.h \ + \ + gimpbase-private.c \ + gimpbase-private.h \ + gimpchecks.c \ + gimpchecks.h \ + gimpcpuaccel.c \ + gimpcpuaccel.h \ + gimpdatafiles.c \ + gimpdatafiles.h \ + gimpenv.c \ + gimpenv.h \ + gimpmemsize.c \ + gimpmemsize.h \ + gimpmetadata.c \ + gimpmetadata.h \ + gimpparasite.c \ + gimpparasite.h \ + gimpparasiteio.c \ + gimpparasiteio.h \ + gimpprotocol.c \ + gimpprotocol.h \ + gimprectangle.c \ + gimprectangle.h \ + gimpreloc.c \ + gimpreloc.h \ + gimpsignal.c \ + gimpsignal.h \ + gimpunit.c \ + gimpunit.h \ + gimputils.c \ + gimputils.h \ + gimpvaluearray.c \ + gimpvaluearray.h \ + gimpwin32-io.h \ + gimpwire.c \ + gimpwire.h + +libgimpbase_built_sources = \ + gimpbaseenums.c \ + gimpcompatenums.c + +libgimpbase_@GIMP_API_VERSION@_la_SOURCES = \ + $(libgimpbase_sources) \ + $(libgimpbase_built_sources) + + +libgimpbaseinclude_HEADERS = \ + gimpbase.h \ + gimpbaseenums.h \ + gimpbasetypes.h \ + gimpcpuaccel.h \ + gimplimits.h \ + gimpparam.h \ + gimpversion.h \ + \ + gimpchecks.h \ + gimpdatafiles.h \ + gimpenv.h \ + gimpmemsize.h \ + gimpmetadata.h \ + gimpparasite.h \ + gimpparasiteio.h \ + gimprectangle.h \ + gimpsignal.h \ + gimpunit.h \ + gimputils.h \ + gimpvaluearray.h + +libgimpbase_@GIMP_API_VERSION@_la_LDFLAGS = \ + -version-info $(LT_VERSION_INFO) \ + $(no_undefined) \ + $(libgimpbase_export_symbols) \ + $(framework_cocoa) \ + $(xnone) + +EXTRA_libgimpbase_@GIMP_API_VERSION@_la_DEPENDENCIES = $(gimpbase_def) + +libgimpbase_@GIMP_API_VERSION@_la_LIBADD = \ + $(GIO_LIBS) \ + $(GEXIV2_LIBS) \ + $(libm) \ + $(ole32_lib) + +install-data-local: install-ms-lib install-libtool-import-lib + +uninstall-local: uninstall-ms-lib uninstall-libtool-import-lib + +# +# test programs, not to be built by default and never installed +# + +TESTS = test-cpu-accel + +test_cpu_accel_SOURCES = test-cpu-accel.c + +test_cpu_accel_DEPENDENCIES = \ + $(top_builddir)/libgimpbase/libgimpbase-$(GIMP_API_VERSION).la + +test_cpu_accel_LDADD = \ + $(GLIB_LIBS) \ + $(test_cpu_accel_DEPENDENCIES) + + +EXTRA_PROGRAMS = test-cpu-accel + + +# +# rules to generate built sources +# + +gen_sources = xgen-bec xgen-cec +CLEANFILES = $(EXTRA_PROGRAMS) $(gen_sources) + +xgen-bec: $(srcdir)/gimpbaseenums.h $(GIMP_MKENUMS) Makefile.am + $(AM_V_GEN) $(GIMP_MKENUMS) \ + --fhead "#include \"config.h\"\n#include <glib-object.h>\n#undef GIMP_DISABLE_DEPRECATED\n#include \"gimpbasetypes.h\"\n#include \"libgimp/libgimp-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_domain (type, GETTEXT_PACKAGE \"-libgimp\");\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)/gimpbaseenums.c: xgen-bec + $(AM_V_GEN) if ! cmp -s $< $@; then \ + cp $< $@; \ + else \ + touch $@ 2> /dev/null \ + || true; \ + fi + +xgen-cec: $(srcdir)/gimpcompatenums.h $(GIMP_MKENUMS) Makefile.am + $(AM_V_GEN) $(GIMP_MKENUMS) \ + --fhead "#include \"config.h\"\n#include <glib-object.h>\n#include \"gimpbasetypes.h\"\n#include \"gimpcompatenums.h\"\n#include \"libgimp/libgimp-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_domain (type, GETTEXT_PACKAGE \"-libgimp\");\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)/gimpcompatenums.c: xgen-cec + $(AM_V_GEN) if ! cmp -s $< $@; then \ + cp $< $@; \ + else \ + touch $@ 2> /dev/null \ + || true; \ + fi + +DISTCLEANFILES = gimpversion.h diff --git a/libgimpbase/Makefile.in b/libgimpbase/Makefile.in new file mode 100644 index 0000000..419ea65 --- /dev/null +++ b/libgimpbase/Makefile.in @@ -0,0 +1,1660 @@ +# 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@ +TESTS = test-cpu-accel$(EXEEXT) +EXTRA_PROGRAMS = test-cpu-accel$(EXEEXT) +subdir = libgimpbase +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 $(libgimpbaseinclude_HEADERS) \ + $(am__DIST_COMMON) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +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__installdirs = "$(DESTDIR)$(libdir)" \ + "$(DESTDIR)$(libgimpbaseincludedir)" +LTLIBRARIES = $(lib_LTLIBRARIES) +am__DEPENDENCIES_1 = +libgimpbase_@GIMP_API_VERSION@_la_DEPENDENCIES = \ + $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) +am__objects_1 = gimpbasetypes.lo gimpbase-private.lo gimpchecks.lo \ + gimpcpuaccel.lo gimpdatafiles.lo gimpenv.lo gimpmemsize.lo \ + gimpmetadata.lo gimpparasite.lo gimpparasiteio.lo \ + gimpprotocol.lo gimprectangle.lo gimpreloc.lo gimpsignal.lo \ + gimpunit.lo gimputils.lo gimpvaluearray.lo gimpwire.lo +am__objects_2 = gimpbaseenums.lo gimpcompatenums.lo +am_libgimpbase_@GIMP_API_VERSION@_la_OBJECTS = $(am__objects_1) \ + $(am__objects_2) +libgimpbase_@GIMP_API_VERSION@_la_OBJECTS = \ + $(am_libgimpbase_@GIMP_API_VERSION@_la_OBJECTS) +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 = +libgimpbase_@GIMP_API_VERSION@_la_LINK = $(LIBTOOL) $(AM_V_lt) \ + --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link \ + $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(libgimpbase_@GIMP_API_VERSION@_la_LDFLAGS) $(LDFLAGS) -o $@ +am_test_cpu_accel_OBJECTS = test-cpu-accel.$(OBJEXT) +test_cpu_accel_OBJECTS = $(am_test_cpu_accel_OBJECTS) +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)/gimpbase-private.Plo \ + ./$(DEPDIR)/gimpbaseenums.Plo ./$(DEPDIR)/gimpbasetypes.Plo \ + ./$(DEPDIR)/gimpchecks.Plo ./$(DEPDIR)/gimpcompatenums.Plo \ + ./$(DEPDIR)/gimpcpuaccel.Plo ./$(DEPDIR)/gimpdatafiles.Plo \ + ./$(DEPDIR)/gimpenv.Plo ./$(DEPDIR)/gimpmemsize.Plo \ + ./$(DEPDIR)/gimpmetadata.Plo ./$(DEPDIR)/gimpparasite.Plo \ + ./$(DEPDIR)/gimpparasiteio.Plo ./$(DEPDIR)/gimpprotocol.Plo \ + ./$(DEPDIR)/gimprectangle.Plo ./$(DEPDIR)/gimpreloc.Plo \ + ./$(DEPDIR)/gimpsignal.Plo ./$(DEPDIR)/gimpunit.Plo \ + ./$(DEPDIR)/gimputils.Plo ./$(DEPDIR)/gimpvaluearray.Plo \ + ./$(DEPDIR)/gimpwire.Plo ./$(DEPDIR)/test-cpu-accel.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 = $(libgimpbase_@GIMP_API_VERSION@_la_SOURCES) \ + $(test_cpu_accel_SOURCES) +DIST_SOURCES = $(libgimpbase_@GIMP_API_VERSION@_la_SOURCES) \ + $(test_cpu_accel_SOURCES) +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +DATA = $(noinst_DATA) +HEADERS = $(libgimpbaseinclude_HEADERS) +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='[0;31m'; \ + grn='[0;32m'; \ + lgn='[1;32m'; \ + blu='[1;34m'; \ + mgn='[0;35m'; \ + brg='[1m'; \ + std='[m'; \ + fi; \ +} +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@ +@PLATFORM_WIN32_TRUE@no_undefined = -no-undefined +@PLATFORM_OSX_TRUE@xobjective_c = "-xobjective-c" +@PLATFORM_OSX_TRUE@xobjective_cxx = "-xobjective-c++" +@PLATFORM_OSX_TRUE@xnone = "-xnone" +@PLATFORM_OSX_TRUE@framework_cocoa = -framework Cocoa +@OS_WIN32_TRUE@ole32_lib = -lole32 +@OS_WIN32_TRUE@gimpbase_def = gimpbase.def +@OS_WIN32_TRUE@libgimpbase_export_symbols = -export-symbols $(srcdir)/gimpbase.def +@OS_WIN32_FALSE@libm = -lm +@MS_LIB_AVAILABLE_TRUE@noinst_DATA = gimpbase-$(GIMP_API_VERSION).lib +libgimpbaseincludedir = $(includedir)/gimp-$(GIMP_API_VERSION)/libgimpbase +AM_CPPFLAGS = \ + -DPREFIX=\""$(prefix)"\" \ + -DGIMPDIR=\""$(gimpdir)"\" \ + -DGIMPDATADIR=\""$(gimpdatadir)"\" \ + -DLOCALEDIR=\""$(gimplocaledir)"\" \ + -DPLUGINDIR=\""$(gimpplugindir)"\" \ + -DGIMPSYSCONFDIR=\""$(gimpsysconfdir)"\" \ + -DGIMP_PACKAGE=\""@PACKAGE@"\" \ + -DGIMP_DATA_VERSION=\"$(GIMP_DATA_VERSION)\" \ + -DGIMP_USER_VERSION=\"$(GIMP_USER_VERSION)\" \ + -DGIMP_SYSCONF_VERSION=\"$(GIMP_SYSCONF_VERSION)\" \ + -DGIMP_PLUGIN_VERSION=\"$(GIMP_PLUGIN_VERSION)\" \ + -DG_LOG_DOMAIN=\"LibGimpBase\" \ + -DGIMP_BASE_COMPILATION \ + -I$(top_srcdir) \ + $(GIO_CFLAGS) \ + $(GEXIV2_CFLAGS) \ + -I$(includedir) + +AM_CFLAGS = \ + $(xobjective_c) + +AM_CXXFLAGS = \ + $(xobjective_cxx) + +AM_CCASFLAGS = \ + -I$(top_builddir) \ + -I$(top_srcdir) + +AM_LDFLAGS = \ + $(xnone) + +EXTRA_DIST = \ + gimpbase.def + +lib_LTLIBRARIES = libgimpbase-@GIMP_API_VERSION@.la +libgimpbase_sources = \ + gimpbase.h \ + gimpbaseenums.h \ + gimpcompatenums.h \ + gimpbasetypes.h \ + gimpbasetypes.c \ + gimplimits.h \ + gimpparam.h \ + gimpversion.h \ + \ + gimpbase-private.c \ + gimpbase-private.h \ + gimpchecks.c \ + gimpchecks.h \ + gimpcpuaccel.c \ + gimpcpuaccel.h \ + gimpdatafiles.c \ + gimpdatafiles.h \ + gimpenv.c \ + gimpenv.h \ + gimpmemsize.c \ + gimpmemsize.h \ + gimpmetadata.c \ + gimpmetadata.h \ + gimpparasite.c \ + gimpparasite.h \ + gimpparasiteio.c \ + gimpparasiteio.h \ + gimpprotocol.c \ + gimpprotocol.h \ + gimprectangle.c \ + gimprectangle.h \ + gimpreloc.c \ + gimpreloc.h \ + gimpsignal.c \ + gimpsignal.h \ + gimpunit.c \ + gimpunit.h \ + gimputils.c \ + gimputils.h \ + gimpvaluearray.c \ + gimpvaluearray.h \ + gimpwin32-io.h \ + gimpwire.c \ + gimpwire.h + +libgimpbase_built_sources = \ + gimpbaseenums.c \ + gimpcompatenums.c + +libgimpbase_@GIMP_API_VERSION@_la_SOURCES = \ + $(libgimpbase_sources) \ + $(libgimpbase_built_sources) + +libgimpbaseinclude_HEADERS = \ + gimpbase.h \ + gimpbaseenums.h \ + gimpbasetypes.h \ + gimpcpuaccel.h \ + gimplimits.h \ + gimpparam.h \ + gimpversion.h \ + \ + gimpchecks.h \ + gimpdatafiles.h \ + gimpenv.h \ + gimpmemsize.h \ + gimpmetadata.h \ + gimpparasite.h \ + gimpparasiteio.h \ + gimprectangle.h \ + gimpsignal.h \ + gimpunit.h \ + gimputils.h \ + gimpvaluearray.h + +libgimpbase_@GIMP_API_VERSION@_la_LDFLAGS = \ + -version-info $(LT_VERSION_INFO) \ + $(no_undefined) \ + $(libgimpbase_export_symbols) \ + $(framework_cocoa) \ + $(xnone) + +EXTRA_libgimpbase_@GIMP_API_VERSION@_la_DEPENDENCIES = $(gimpbase_def) +libgimpbase_@GIMP_API_VERSION@_la_LIBADD = \ + $(GIO_LIBS) \ + $(GEXIV2_LIBS) \ + $(libm) \ + $(ole32_lib) + +test_cpu_accel_SOURCES = test-cpu-accel.c +test_cpu_accel_DEPENDENCIES = \ + $(top_builddir)/libgimpbase/libgimpbase-$(GIMP_API_VERSION).la + +test_cpu_accel_LDADD = \ + $(GLIB_LIBS) \ + $(test_cpu_accel_DEPENDENCIES) + + +# +# rules to generate built sources +# +gen_sources = xgen-bec xgen-cec +CLEANFILES = $(EXTRA_PROGRAMS) $(gen_sources) +DISTCLEANFILES = gimpversion.h +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 libgimpbase/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu libgimpbase/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): + +install-libLTLIBRARIES: $(lib_LTLIBRARIES) + @$(NORMAL_INSTALL) + @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \ + list2=; for p in $$list; do \ + if test -f $$p; then \ + list2="$$list2 $$p"; \ + else :; fi; \ + done; \ + test -z "$$list2" || { \ + echo " $(MKDIR_P) '$(DESTDIR)$(libdir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(libdir)" || exit 1; \ + echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(libdir)'"; \ + $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(libdir)"; \ + } + +uninstall-libLTLIBRARIES: + @$(NORMAL_UNINSTALL) + @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \ + for p in $$list; do \ + $(am__strip_dir) \ + echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(libdir)/$$f'"; \ + $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(libdir)/$$f"; \ + done + +clean-libLTLIBRARIES: + -test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES) + @list='$(lib_LTLIBRARIES)'; \ + locs=`for p in $$list; do echo $$p; done | \ + sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ + sort -u`; \ + test -z "$$locs" || { \ + echo rm -f $${locs}; \ + rm -f $${locs}; \ + } + +libgimpbase-@GIMP_API_VERSION@.la: $(libgimpbase_@GIMP_API_VERSION@_la_OBJECTS) $(libgimpbase_@GIMP_API_VERSION@_la_DEPENDENCIES) $(EXTRA_libgimpbase_@GIMP_API_VERSION@_la_DEPENDENCIES) + $(AM_V_CCLD)$(libgimpbase_@GIMP_API_VERSION@_la_LINK) -rpath $(libdir) $(libgimpbase_@GIMP_API_VERSION@_la_OBJECTS) $(libgimpbase_@GIMP_API_VERSION@_la_LIBADD) $(LIBS) + +test-cpu-accel$(EXEEXT): $(test_cpu_accel_OBJECTS) $(test_cpu_accel_DEPENDENCIES) $(EXTRA_test_cpu_accel_DEPENDENCIES) + @rm -f test-cpu-accel$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(test_cpu_accel_OBJECTS) $(test_cpu_accel_LDADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gimpbase-private.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gimpbaseenums.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gimpbasetypes.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gimpchecks.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gimpcompatenums.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gimpcpuaccel.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gimpdatafiles.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gimpenv.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gimpmemsize.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gimpmetadata.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gimpparasite.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gimpparasiteio.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gimpprotocol.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gimprectangle.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gimpreloc.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gimpsignal.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gimpunit.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gimputils.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gimpvaluearray.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gimpwire.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-cpu-accel.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 +install-libgimpbaseincludeHEADERS: $(libgimpbaseinclude_HEADERS) + @$(NORMAL_INSTALL) + @list='$(libgimpbaseinclude_HEADERS)'; test -n "$(libgimpbaseincludedir)" || list=; \ + if test -n "$$list"; then \ + echo " $(MKDIR_P) '$(DESTDIR)$(libgimpbaseincludedir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(libgimpbaseincludedir)" || exit 1; \ + fi; \ + for p in $$list; do \ + if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ + echo "$$d$$p"; \ + done | $(am__base_list) | \ + while read files; do \ + echo " $(INSTALL_HEADER) $$files '$(DESTDIR)$(libgimpbaseincludedir)'"; \ + $(INSTALL_HEADER) $$files "$(DESTDIR)$(libgimpbaseincludedir)" || exit $$?; \ + done + +uninstall-libgimpbaseincludeHEADERS: + @$(NORMAL_UNINSTALL) + @list='$(libgimpbaseinclude_HEADERS)'; test -n "$(libgimpbaseincludedir)" || list=; \ + files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ + dir='$(DESTDIR)$(libgimpbaseincludedir)'; $(am__uninstall_files_from_dir) + +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-cpu-accel.log: test-cpu-accel$(EXEEXT) + @p='test-cpu-accel$(EXEEXT)'; \ + b='test-cpu-accel'; \ + $(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 $(LTLIBRARIES) $(DATA) $(HEADERS) +installdirs: + for dir in "$(DESTDIR)$(libdir)" "$(DESTDIR)$(libgimpbaseincludedir)"; do \ + test -z "$$dir" || $(MKDIR_P) "$$dir"; \ + done +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) + -test -z "$(DISTCLEANFILES)" || rm -f $(DISTCLEANFILES) + +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-libLTLIBRARIES clean-libtool \ + mostlyclean-am + +distclean: distclean-am + -rm -f ./$(DEPDIR)/gimpbase-private.Plo + -rm -f ./$(DEPDIR)/gimpbaseenums.Plo + -rm -f ./$(DEPDIR)/gimpbasetypes.Plo + -rm -f ./$(DEPDIR)/gimpchecks.Plo + -rm -f ./$(DEPDIR)/gimpcompatenums.Plo + -rm -f ./$(DEPDIR)/gimpcpuaccel.Plo + -rm -f ./$(DEPDIR)/gimpdatafiles.Plo + -rm -f ./$(DEPDIR)/gimpenv.Plo + -rm -f ./$(DEPDIR)/gimpmemsize.Plo + -rm -f ./$(DEPDIR)/gimpmetadata.Plo + -rm -f ./$(DEPDIR)/gimpparasite.Plo + -rm -f ./$(DEPDIR)/gimpparasiteio.Plo + -rm -f ./$(DEPDIR)/gimpprotocol.Plo + -rm -f ./$(DEPDIR)/gimprectangle.Plo + -rm -f ./$(DEPDIR)/gimpreloc.Plo + -rm -f ./$(DEPDIR)/gimpsignal.Plo + -rm -f ./$(DEPDIR)/gimpunit.Plo + -rm -f ./$(DEPDIR)/gimputils.Plo + -rm -f ./$(DEPDIR)/gimpvaluearray.Plo + -rm -f ./$(DEPDIR)/gimpwire.Plo + -rm -f ./$(DEPDIR)/test-cpu-accel.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-data-local install-libgimpbaseincludeHEADERS + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: install-libLTLIBRARIES + +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)/gimpbase-private.Plo + -rm -f ./$(DEPDIR)/gimpbaseenums.Plo + -rm -f ./$(DEPDIR)/gimpbasetypes.Plo + -rm -f ./$(DEPDIR)/gimpchecks.Plo + -rm -f ./$(DEPDIR)/gimpcompatenums.Plo + -rm -f ./$(DEPDIR)/gimpcpuaccel.Plo + -rm -f ./$(DEPDIR)/gimpdatafiles.Plo + -rm -f ./$(DEPDIR)/gimpenv.Plo + -rm -f ./$(DEPDIR)/gimpmemsize.Plo + -rm -f ./$(DEPDIR)/gimpmetadata.Plo + -rm -f ./$(DEPDIR)/gimpparasite.Plo + -rm -f ./$(DEPDIR)/gimpparasiteio.Plo + -rm -f ./$(DEPDIR)/gimpprotocol.Plo + -rm -f ./$(DEPDIR)/gimprectangle.Plo + -rm -f ./$(DEPDIR)/gimpreloc.Plo + -rm -f ./$(DEPDIR)/gimpsignal.Plo + -rm -f ./$(DEPDIR)/gimpunit.Plo + -rm -f ./$(DEPDIR)/gimputils.Plo + -rm -f ./$(DEPDIR)/gimpvaluearray.Plo + -rm -f ./$(DEPDIR)/gimpwire.Plo + -rm -f ./$(DEPDIR)/test-cpu-accel.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: uninstall-libLTLIBRARIES \ + uninstall-libgimpbaseincludeHEADERS uninstall-local + +.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-libLTLIBRARIES \ + clean-libtool 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-data-local install-dvi install-dvi-am install-exec \ + install-exec-am install-html install-html-am install-info \ + install-info-am install-libLTLIBRARIES \ + install-libgimpbaseincludeHEADERS 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 \ + uninstall-libLTLIBRARIES uninstall-libgimpbaseincludeHEADERS \ + uninstall-local + +.PRECIOUS: Makefile + + +@OS_WIN32_TRUE@install-libtool-import-lib: +@OS_WIN32_TRUE@ $(INSTALL) .libs/libgimpbase-$(GIMP_API_VERSION).dll.a $(DESTDIR)$(libdir) +@OS_WIN32_TRUE@ $(INSTALL) $(srcdir)/gimpbase.def $(DESTDIR)$(libdir) + +@OS_WIN32_TRUE@uninstall-libtool-import-lib: +@OS_WIN32_TRUE@ -rm $(DESTDIR)$(libdir)/libgimpbase-$(GIMP_API_VERSION).dll.a +@OS_WIN32_TRUE@ -rm $(DESTDIR)$(libdir)/gimpbase.def +@OS_WIN32_FALSE@install-libtool-import-lib: +@OS_WIN32_FALSE@uninstall-libtool-import-lib: + +@MS_LIB_AVAILABLE_TRUE@install-ms-lib: +@MS_LIB_AVAILABLE_TRUE@ $(INSTALL) gimpbase-$(GIMP_API_VERSION).lib $(DESTDIR)$(libdir) + +@MS_LIB_AVAILABLE_TRUE@uninstall-ms-lib: +@MS_LIB_AVAILABLE_TRUE@ -rm $(DESTDIR)$(libdir)/gimpbase-$(GIMP_API_VERSION).lib + +@MS_LIB_AVAILABLE_TRUE@gimpbase-@GIMP_API_VERSION@.lib: gimpbase.def +@MS_LIB_AVAILABLE_TRUE@ lib -name:libgimpbase-$(GIMP_API_VERSION)-@LT_CURRENT_MINUS_AGE@.dll -def:gimpbase.def -out:$@ + +@MS_LIB_AVAILABLE_FALSE@install-ms-lib: +@MS_LIB_AVAILABLE_FALSE@uninstall-ms-lib: + +# help `make' along by giving another name for the file, which it knows +# how to build +../libgimpbase/gimpversion.h: gimpversion.h + @: + +install-data-local: install-ms-lib install-libtool-import-lib + +uninstall-local: uninstall-ms-lib uninstall-libtool-import-lib + +xgen-bec: $(srcdir)/gimpbaseenums.h $(GIMP_MKENUMS) Makefile.am + $(AM_V_GEN) $(GIMP_MKENUMS) \ + --fhead "#include \"config.h\"\n#include <glib-object.h>\n#undef GIMP_DISABLE_DEPRECATED\n#include \"gimpbasetypes.h\"\n#include \"libgimp/libgimp-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_domain (type, GETTEXT_PACKAGE \"-libgimp\");\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)/gimpbaseenums.c: xgen-bec + $(AM_V_GEN) if ! cmp -s $< $@; then \ + cp $< $@; \ + else \ + touch $@ 2> /dev/null \ + || true; \ + fi + +xgen-cec: $(srcdir)/gimpcompatenums.h $(GIMP_MKENUMS) Makefile.am + $(AM_V_GEN) $(GIMP_MKENUMS) \ + --fhead "#include \"config.h\"\n#include <glib-object.h>\n#include \"gimpbasetypes.h\"\n#include \"gimpcompatenums.h\"\n#include \"libgimp/libgimp-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_domain (type, GETTEXT_PACKAGE \"-libgimp\");\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)/gimpcompatenums.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/libgimpbase/gimpbase-private.c b/libgimpbase/gimpbase-private.c new file mode 100644 index 0000000..7703fce --- /dev/null +++ b/libgimpbase/gimpbase-private.c @@ -0,0 +1,93 @@ +/* LIBGIMP - The GIMP Library + * Copyright (C) 1995-1997 Peter Mattis and Spencer Kimball + * + * gimpbase-private.c + * Copyright (C) 2003 Sven Neumann <sven@gimp.org> + * + * This library is free software: you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see + * <https://www.gnu.org/licenses/>. + */ + +#include "config.h" + +#include <gio/gio.h> + +#include "gimpbasetypes.h" + +#include "gimpbase-private.h" +#include "gimpcompatenums.h" + + +GimpUnitVtable _gimp_unit_vtable = { NULL, }; + + +void +gimp_base_init (GimpUnitVtable *vtable) +{ + static gboolean gimp_base_initialized = FALSE; + + g_return_if_fail (vtable != NULL); + + if (gimp_base_initialized) + g_error ("gimp_base_init() must only be called once!"); + + _gimp_unit_vtable = *vtable; + + gimp_base_compat_enums_init (); + + gimp_base_initialized = TRUE; +} + +void +gimp_base_compat_enums_init (void) +{ + static gboolean gimp_base_compat_initialized = FALSE; + GQuark quark; + + if (gimp_base_compat_initialized) + return; + + quark = g_quark_from_static_string ("gimp-compat-enum"); + + g_type_set_qdata (GIMP_TYPE_ADD_MASK_TYPE, quark, + (gpointer) GIMP_TYPE_ADD_MASK_TYPE_COMPAT); + g_type_set_qdata (GIMP_TYPE_BLEND_MODE, quark, + (gpointer) GIMP_TYPE_BLEND_MODE_COMPAT); + g_type_set_qdata (GIMP_TYPE_BUCKET_FILL_MODE, quark, + (gpointer) GIMP_TYPE_BUCKET_FILL_MODE_COMPAT); + g_type_set_qdata (GIMP_TYPE_CHANNEL_TYPE, quark, + (gpointer) GIMP_TYPE_CHANNEL_TYPE_COMPAT); + g_type_set_qdata (GIMP_TYPE_CLONE_TYPE, quark, + (gpointer) GIMP_TYPE_CLONE_TYPE_COMPAT); + g_type_set_qdata (GIMP_TYPE_CONVERT_PALETTE_TYPE, quark, + (gpointer) GIMP_TYPE_CONVERT_PALETTE_TYPE_COMPAT); + g_type_set_qdata (GIMP_TYPE_CONVOLVE_TYPE, quark, + (gpointer) GIMP_TYPE_CONVOLVE_TYPE_COMPAT); + g_type_set_qdata (GIMP_TYPE_DESATURATE_MODE, quark, + (gpointer) GIMP_TYPE_DESATURATE_MODE_COMPAT); + g_type_set_qdata (GIMP_TYPE_DODGE_BURN_TYPE, quark, + (gpointer) GIMP_TYPE_DODGE_BURN_TYPE_COMPAT); + g_type_set_qdata (GIMP_TYPE_FILL_TYPE, quark, + (gpointer) GIMP_TYPE_FILL_TYPE_COMPAT); + g_type_set_qdata (GIMP_TYPE_HUE_RANGE, quark, + (gpointer) GIMP_TYPE_HUE_RANGE_COMPAT); + g_type_set_qdata (GIMP_TYPE_ICON_TYPE, quark, + (gpointer) GIMP_TYPE_ICON_TYPE_COMPAT); + g_type_set_qdata (GIMP_TYPE_INTERPOLATION_TYPE, quark, + (gpointer) GIMP_TYPE_INTERPOLATION_TYPE_COMPAT); + g_type_set_qdata (GIMP_TYPE_TRANSFER_MODE, quark, + (gpointer) GIMP_TYPE_TRANSFER_MODE_COMPAT); + + gimp_base_compat_initialized = TRUE; +} diff --git a/libgimpbase/gimpbase-private.h b/libgimpbase/gimpbase-private.h new file mode 100644 index 0000000..a36b4a7 --- /dev/null +++ b/libgimpbase/gimpbase-private.h @@ -0,0 +1,69 @@ +/* LIBGIMP - The GIMP Library + * Copyright (C) 1995-1997 Peter Mattis and Spencer Kimball + * + * gimpbase-private.h + * Copyright (C) 2003 Sven Neumann <sven@gimp.org> + * + * This library is free software: you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see + * <https://www.gnu.org/licenses/>. + */ + +#ifndef __GIMP_BASE_PRIVATE_H__ +#define __GIMP_BASE_PRIVATE_H__ + + +typedef struct _GimpUnitVtable GimpUnitVtable; + +struct _GimpUnitVtable +{ + gint (* unit_get_number_of_units) (void); + gint (* unit_get_number_of_built_in_units) (void); + + GimpUnit (* unit_new) (gchar *identifier, + gdouble factor, + gint digits, + gchar *symbol, + gchar *abbreviation, + gchar *singular, + gchar *plural); + gboolean (* unit_get_deletion_flag) (GimpUnit unit); + void (* unit_set_deletion_flag) (GimpUnit unit, + gboolean deletion_flag); + + gdouble (* unit_get_factor) (GimpUnit unit); + gint (* unit_get_digits) (GimpUnit unit); + const gchar * (* unit_get_identifier) (GimpUnit unit); + const gchar * (* unit_get_symbol) (GimpUnit unit); + const gchar * (* unit_get_abbreviation) (GimpUnit unit); + const gchar * (* unit_get_singular) (GimpUnit unit); + const gchar * (* unit_get_plural) (GimpUnit unit); + + void (* _reserved_1) (void); + void (* _reserved_2) (void); + void (* _reserved_3) (void); + void (* _reserved_4) (void); +}; + + +extern GimpUnitVtable _gimp_unit_vtable; + + +G_BEGIN_DECLS + +void gimp_base_init (GimpUnitVtable *vtable); +void gimp_base_compat_enums_init (void); + +G_END_DECLS + +#endif /* __GIMP_BASE_PRIVATE_H__ */ diff --git a/libgimpbase/gimpbase.def b/libgimpbase/gimpbase.def new file mode 100644 index 0000000..2efc1de --- /dev/null +++ b/libgimpbase/gimpbase.def @@ -0,0 +1,244 @@ +EXPORTS + gimp_add_mask_type_compat_get_type + gimp_add_mask_type_get_type + gimp_any_to_utf8 + gimp_base_compat_enums_init + gimp_base_init + gimp_blend_mode_compat_get_type + gimp_blend_mode_get_type + gimp_brush_generated_shape_get_type + gimp_bucket_fill_mode_compat_get_type + gimp_bucket_fill_mode_get_type + gimp_cache_directory + gimp_canonicalize_identifier + gimp_cap_style_get_type + gimp_channel_ops_get_type + gimp_channel_type_compat_get_type + gimp_channel_type_get_type + gimp_check_size_get_type + gimp_check_type_get_type + gimp_checks_get_shades + gimp_clone_type_compat_get_type + gimp_clone_type_get_type + gimp_color_tag_get_type + gimp_component_type_get_type + gimp_convert_dither_type_compat_get_type + gimp_convert_palette_type_compat_get_type + gimp_convert_palette_type_get_type + gimp_convolve_type_compat_get_type + gimp_convolve_type_get_type + gimp_cpu_accel_get_support + gimp_cpu_accel_set_use + gimp_data_directory + gimp_data_directory_file + gimp_datafiles_check_extension + gimp_datafiles_read_directories + gimp_desaturate_mode_compat_get_type + gimp_desaturate_mode_get_type + gimp_directory + gimp_directory_file + gimp_dodge_burn_type_compat_get_type + gimp_dodge_burn_type_get_type + gimp_enum_get_desc + gimp_enum_get_value + gimp_enum_get_value_descriptions + gimp_enum_set_value_descriptions + gimp_enum_value_get_abbrev + gimp_enum_value_get_desc + gimp_enum_value_get_help + gimp_env_init + gimp_escape_uline + gimp_file_get_utf8_name + gimp_file_has_extension + gimp_file_show_in_file_manager + gimp_filename_to_utf8 + gimp_fill_type_compat_get_type + gimp_fill_type_get_type + gimp_flags_get_first_desc + gimp_flags_get_first_value + gimp_flags_get_value_descriptions + gimp_flags_set_value_descriptions + gimp_flags_value_get_abbrev + gimp_flags_value_get_desc + gimp_flags_value_get_help + gimp_foreground_extract_mode_get_type + gimp_gradient_blend_color_space_get_type + gimp_gradient_segment_color_get_type + gimp_gradient_segment_type_get_type + gimp_gradient_type_get_type + gimp_grid_style_get_type + gimp_gtkrc + gimp_hue_range_compat_get_type + gimp_hue_range_get_type + gimp_icon_type_compat_get_type + gimp_icon_type_get_type + gimp_image_base_type_get_type + gimp_image_type_get_type + gimp_ink_blob_type_get_type + gimp_installation_directory + gimp_installation_directory_file + gimp_interpolation_type_compat_get_type + gimp_interpolation_type_get_type + gimp_join_style_get_type + gimp_layer_mode_effects_get_type + gimp_locale_directory + gimp_locale_directory_file + gimp_major_version + gimp_mask_apply_mode_get_type + gimp_memsize_deserialize + gimp_memsize_get_type + gimp_memsize_serialize + gimp_memsize_to_string + gimp_merge_type_get_type + gimp_message_handler_type_get_type + gimp_metadata_add_xmp_history + gimp_metadata_deserialize + gimp_metadata_duplicate + gimp_metadata_get_colorspace + gimp_metadata_get_guid + gimp_metadata_get_resolution + gimp_metadata_get_type + gimp_metadata_is_tag_supported + gimp_metadata_load_from_file + gimp_metadata_new + gimp_metadata_save_to_file + gimp_metadata_serialize + gimp_metadata_set_bits_per_sample + gimp_metadata_set_colorspace + gimp_metadata_set_from_exif + gimp_metadata_set_from_iptc + gimp_metadata_set_from_xmp + gimp_metadata_set_pixel_size + gimp_metadata_set_resolution + gimp_micro_version + gimp_minor_version + gimp_offset_type_get_type + gimp_orientation_type_get_type + gimp_paint_application_mode_get_type + gimp_param_memsize_get_type + gimp_param_parasite_get_type + gimp_param_spec_memsize + gimp_param_spec_parasite + gimp_param_spec_unit + gimp_param_spec_value_array + gimp_param_unit_get_type + gimp_param_value_array_get_type + gimp_parasite_compare + gimp_parasite_copy + gimp_parasite_data + gimp_parasite_data_size + gimp_parasite_flags + gimp_parasite_free + gimp_parasite_get_type + gimp_parasite_has_flag + gimp_parasite_is_persistent + gimp_parasite_is_type + gimp_parasite_is_undoable + gimp_parasite_name + gimp_parasite_new + gimp_path_free + gimp_path_get_user_writable_dir + gimp_path_parse + gimp_path_to_str + gimp_pdb_arg_type_get_type + gimp_pdb_error_handler_get_type + gimp_pdb_proc_type_get_type + gimp_pdb_status_type_get_type + gimp_personal_rc_file + gimp_pixels_to_units + gimp_pixpipe_params_build + gimp_pixpipe_params_free + gimp_pixpipe_params_init + gimp_pixpipe_params_parse + gimp_plug_in_directory + gimp_plug_in_directory_file + gimp_precision_get_type + gimp_progress_command_get_type + gimp_rectangle_intersect + gimp_rectangle_union + gimp_repeat_mode_get_type + gimp_rotation_type_get_type + gimp_run_mode_get_type + gimp_select_criterion_get_type + gimp_signal_private + gimp_size_type_get_type + gimp_stack_trace_available + gimp_stack_trace_mode_get_type + gimp_stack_trace_print + gimp_stack_trace_query + gimp_strip_uline + gimp_stroke_method_get_type + gimp_sysconf_directory + gimp_sysconf_directory_file + gimp_temp_directory + gimp_text_direction_get_type + gimp_text_hint_style_get_type + gimp_text_justification_get_type + gimp_transfer_mode_compat_get_type + gimp_transfer_mode_get_type + gimp_transform_direction_get_type + gimp_transform_resize_get_type + gimp_type_get_translation_context + gimp_type_get_translation_domain + gimp_type_set_translation_context + gimp_type_set_translation_domain + gimp_unit_format_string + gimp_unit_get_abbreviation + gimp_unit_get_deletion_flag + gimp_unit_get_digits + gimp_unit_get_factor + gimp_unit_get_identifier + gimp_unit_get_number_of_built_in_units + gimp_unit_get_number_of_units + gimp_unit_get_plural + gimp_unit_get_scaled_digits + gimp_unit_get_singular + gimp_unit_get_symbol + gimp_unit_get_type + gimp_unit_is_metric + gimp_unit_new + gimp_unit_set_deletion_flag + gimp_units_to_pixels + gimp_units_to_points + gimp_user_directory + gimp_user_directory_get_type + gimp_utf8_strtrim + gimp_value_array_append + gimp_value_array_get_type + gimp_value_array_index + gimp_value_array_insert + gimp_value_array_length + gimp_value_array_new + gimp_value_array_prepend + gimp_value_array_ref + gimp_value_array_remove + gimp_value_array_truncate + gimp_value_array_unref + gimp_vectors_stroke_type_get_type + gimp_wire_clear_error + gimp_wire_destroy + gimp_wire_error + gimp_wire_flush + gimp_wire_read + gimp_wire_read_msg + gimp_wire_register + gimp_wire_set_flusher + gimp_wire_set_reader + gimp_wire_set_writer + gimp_wire_write + gimp_wire_write_msg + gp_config_write + gp_extension_ack_write + gp_has_init_write + gp_init + gp_params_destroy + gp_proc_install_write + gp_proc_return_write + gp_proc_run_write + gp_proc_uninstall_write + gp_quit_write + gp_temp_proc_return_write + gp_temp_proc_run_write + gp_tile_ack_write + gp_tile_data_write + gp_tile_req_write diff --git a/libgimpbase/gimpbase.h b/libgimpbase/gimpbase.h new file mode 100644 index 0000000..2cc1c4f --- /dev/null +++ b/libgimpbase/gimpbase.h @@ -0,0 +1,46 @@ +/* LIBGIMP - The GIMP Library + * Copyright (C) 1995-1997 Peter Mattis and Spencer Kimball + * + * This library is free software: you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This library 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see + * <https://www.gnu.org/licenses/>. + */ + +#ifndef __GIMP_BASE_H__ +#define __GIMP_BASE_H__ + +#define __GIMP_BASE_H_INSIDE__ + +#include <libgimpbase/gimpbasetypes.h> + +#include <libgimpbase/gimpchecks.h> +#include <libgimpbase/gimpcpuaccel.h> +#include <libgimpbase/gimpdatafiles.h> +#include <libgimpbase/gimpenv.h> +#include <libgimpbase/gimplimits.h> +#include <libgimpbase/gimpmemsize.h> +#include <libgimpbase/gimpmetadata.h> +#include <libgimpbase/gimpparasite.h> +#include <libgimpbase/gimprectangle.h> +#include <libgimpbase/gimpunit.h> +#include <libgimpbase/gimputils.h> +#include <libgimpbase/gimpversion.h> +#include <libgimpbase/gimpvaluearray.h> + +#ifndef G_OS_WIN32 +#include <libgimpbase/gimpsignal.h> +#endif + +#undef __GIMP_BASE_H_INSIDE__ + +#endif /* __GIMP_BASE_H__ */ diff --git a/libgimpbase/gimpbaseenums.c b/libgimpbase/gimpbaseenums.c new file mode 100644 index 0000000..186e48e --- /dev/null +++ b/libgimpbase/gimpbaseenums.c @@ -0,0 +1,2045 @@ + +/* Generated data (by gimp-mkenums) */ + +#include "config.h" +#include <glib-object.h> +#undef GIMP_DISABLE_DEPRECATED +#include "gimpbasetypes.h" +#include "libgimp/libgimp-intl.h" + +/* enumerations from "gimpbaseenums.h" */ +GType +gimp_add_mask_type_get_type (void) +{ + static const GEnumValue values[] = + { + { GIMP_ADD_MASK_WHITE, "GIMP_ADD_MASK_WHITE", "white" }, + { GIMP_ADD_MASK_BLACK, "GIMP_ADD_MASK_BLACK", "black" }, + { GIMP_ADD_MASK_ALPHA, "GIMP_ADD_MASK_ALPHA", "alpha" }, + { GIMP_ADD_MASK_ALPHA_TRANSFER, "GIMP_ADD_MASK_ALPHA_TRANSFER", "alpha-transfer" }, + { GIMP_ADD_MASK_SELECTION, "GIMP_ADD_MASK_SELECTION", "selection" }, + { GIMP_ADD_MASK_COPY, "GIMP_ADD_MASK_COPY", "copy" }, + { GIMP_ADD_MASK_CHANNEL, "GIMP_ADD_MASK_CHANNEL", "channel" }, + { 0, NULL, NULL } + }; + + static const GimpEnumDesc descs[] = + { + { GIMP_ADD_MASK_WHITE, NC_("add-mask-type", "_White (full opacity)"), NULL }, + { GIMP_ADD_MASK_BLACK, NC_("add-mask-type", "_Black (full transparency)"), NULL }, + { GIMP_ADD_MASK_ALPHA, NC_("add-mask-type", "Layer's _alpha channel"), NULL }, + { GIMP_ADD_MASK_ALPHA_TRANSFER, NC_("add-mask-type", "_Transfer layer's alpha channel"), NULL }, + { GIMP_ADD_MASK_SELECTION, NC_("add-mask-type", "_Selection"), NULL }, + { GIMP_ADD_MASK_COPY, NC_("add-mask-type", "_Grayscale copy of layer"), NULL }, + { GIMP_ADD_MASK_CHANNEL, NC_("add-mask-type", "C_hannel"), NULL }, + { 0, NULL, NULL } + }; + + static GType type = 0; + + if (G_UNLIKELY (! type)) + { + type = g_enum_register_static ("GimpAddMaskType", values); + gimp_type_set_translation_domain (type, GETTEXT_PACKAGE "-libgimp"); + gimp_type_set_translation_context (type, "add-mask-type"); + gimp_enum_set_value_descriptions (type, descs); + } + + return type; +} + +GType +gimp_blend_mode_get_type (void) +{ + static const GEnumValue values[] = + { + { GIMP_BLEND_FG_BG_RGB, "GIMP_BLEND_FG_BG_RGB", "fg-bg-rgb" }, + { GIMP_BLEND_FG_BG_HSV, "GIMP_BLEND_FG_BG_HSV", "fg-bg-hsv" }, + { GIMP_BLEND_FG_TRANSPARENT, "GIMP_BLEND_FG_TRANSPARENT", "fg-transparent" }, + { GIMP_BLEND_CUSTOM, "GIMP_BLEND_CUSTOM", "custom" }, + { 0, NULL, NULL } + }; + + static const GimpEnumDesc descs[] = + { + { GIMP_BLEND_FG_BG_RGB, NC_("blend-mode", "FG to BG (RGB)"), NULL }, + { GIMP_BLEND_FG_BG_HSV, NC_("blend-mode", "FG to BG (HSV)"), NULL }, + { GIMP_BLEND_FG_TRANSPARENT, NC_("blend-mode", "FG to transparent"), NULL }, + { GIMP_BLEND_CUSTOM, NC_("blend-mode", "Custom gradient"), NULL }, + { 0, NULL, NULL } + }; + + static GType type = 0; + + if (G_UNLIKELY (! type)) + { + type = g_enum_register_static ("GimpBlendMode", values); + gimp_type_set_translation_domain (type, GETTEXT_PACKAGE "-libgimp"); + gimp_type_set_translation_context (type, "blend-mode"); + gimp_enum_set_value_descriptions (type, descs); + } + + return type; +} + +GType +gimp_brush_generated_shape_get_type (void) +{ + static const GEnumValue values[] = + { + { GIMP_BRUSH_GENERATED_CIRCLE, "GIMP_BRUSH_GENERATED_CIRCLE", "circle" }, + { GIMP_BRUSH_GENERATED_SQUARE, "GIMP_BRUSH_GENERATED_SQUARE", "square" }, + { GIMP_BRUSH_GENERATED_DIAMOND, "GIMP_BRUSH_GENERATED_DIAMOND", "diamond" }, + { 0, NULL, NULL } + }; + + static const GimpEnumDesc descs[] = + { + { GIMP_BRUSH_GENERATED_CIRCLE, NC_("brush-generated-shape", "Circle"), NULL }, + { GIMP_BRUSH_GENERATED_SQUARE, NC_("brush-generated-shape", "Square"), NULL }, + { GIMP_BRUSH_GENERATED_DIAMOND, NC_("brush-generated-shape", "Diamond"), NULL }, + { 0, NULL, NULL } + }; + + static GType type = 0; + + if (G_UNLIKELY (! type)) + { + type = g_enum_register_static ("GimpBrushGeneratedShape", values); + gimp_type_set_translation_domain (type, GETTEXT_PACKAGE "-libgimp"); + gimp_type_set_translation_context (type, "brush-generated-shape"); + gimp_enum_set_value_descriptions (type, descs); + } + + return type; +} + +GType +gimp_bucket_fill_mode_get_type (void) +{ + static const GEnumValue values[] = + { + { GIMP_BUCKET_FILL_FG, "GIMP_BUCKET_FILL_FG", "fg" }, + { GIMP_BUCKET_FILL_BG, "GIMP_BUCKET_FILL_BG", "bg" }, + { GIMP_BUCKET_FILL_PATTERN, "GIMP_BUCKET_FILL_PATTERN", "pattern" }, + { 0, NULL, NULL } + }; + + static const GimpEnumDesc descs[] = + { + { GIMP_BUCKET_FILL_FG, NC_("bucket-fill-mode", "FG color fill"), NULL }, + { GIMP_BUCKET_FILL_BG, NC_("bucket-fill-mode", "BG color fill"), NULL }, + { GIMP_BUCKET_FILL_PATTERN, NC_("bucket-fill-mode", "Pattern fill"), NULL }, + { 0, NULL, NULL } + }; + + static GType type = 0; + + if (G_UNLIKELY (! type)) + { + type = g_enum_register_static ("GimpBucketFillMode", values); + gimp_type_set_translation_domain (type, GETTEXT_PACKAGE "-libgimp"); + gimp_type_set_translation_context (type, "bucket-fill-mode"); + gimp_enum_set_value_descriptions (type, descs); + } + + return type; +} + +GType +gimp_cap_style_get_type (void) +{ + static const GEnumValue values[] = + { + { GIMP_CAP_BUTT, "GIMP_CAP_BUTT", "butt" }, + { GIMP_CAP_ROUND, "GIMP_CAP_ROUND", "round" }, + { GIMP_CAP_SQUARE, "GIMP_CAP_SQUARE", "square" }, + { 0, NULL, NULL } + }; + + static const GimpEnumDesc descs[] = + { + { GIMP_CAP_BUTT, NC_("cap-style", "Butt"), NULL }, + { GIMP_CAP_ROUND, NC_("cap-style", "Round"), NULL }, + { GIMP_CAP_SQUARE, NC_("cap-style", "Square"), NULL }, + { 0, NULL, NULL } + }; + + static GType type = 0; + + if (G_UNLIKELY (! type)) + { + type = g_enum_register_static ("GimpCapStyle", values); + gimp_type_set_translation_domain (type, GETTEXT_PACKAGE "-libgimp"); + gimp_type_set_translation_context (type, "cap-style"); + gimp_enum_set_value_descriptions (type, descs); + } + + return type; +} + +GType +gimp_channel_ops_get_type (void) +{ + static const GEnumValue values[] = + { + { GIMP_CHANNEL_OP_ADD, "GIMP_CHANNEL_OP_ADD", "add" }, + { GIMP_CHANNEL_OP_SUBTRACT, "GIMP_CHANNEL_OP_SUBTRACT", "subtract" }, + { GIMP_CHANNEL_OP_REPLACE, "GIMP_CHANNEL_OP_REPLACE", "replace" }, + { GIMP_CHANNEL_OP_INTERSECT, "GIMP_CHANNEL_OP_INTERSECT", "intersect" }, + { 0, NULL, NULL } + }; + + static const GimpEnumDesc descs[] = + { + { GIMP_CHANNEL_OP_ADD, NC_("channel-ops", "Add to the current selection"), NULL }, + { GIMP_CHANNEL_OP_SUBTRACT, NC_("channel-ops", "Subtract from the current selection"), NULL }, + { GIMP_CHANNEL_OP_REPLACE, NC_("channel-ops", "Replace the current selection"), NULL }, + { GIMP_CHANNEL_OP_INTERSECT, NC_("channel-ops", "Intersect with the current selection"), NULL }, + { 0, NULL, NULL } + }; + + static GType type = 0; + + if (G_UNLIKELY (! type)) + { + type = g_enum_register_static ("GimpChannelOps", values); + gimp_type_set_translation_domain (type, GETTEXT_PACKAGE "-libgimp"); + gimp_type_set_translation_context (type, "channel-ops"); + gimp_enum_set_value_descriptions (type, descs); + } + + return type; +} + +GType +gimp_channel_type_get_type (void) +{ + static const GEnumValue values[] = + { + { GIMP_CHANNEL_RED, "GIMP_CHANNEL_RED", "red" }, + { GIMP_CHANNEL_GREEN, "GIMP_CHANNEL_GREEN", "green" }, + { GIMP_CHANNEL_BLUE, "GIMP_CHANNEL_BLUE", "blue" }, + { GIMP_CHANNEL_GRAY, "GIMP_CHANNEL_GRAY", "gray" }, + { GIMP_CHANNEL_INDEXED, "GIMP_CHANNEL_INDEXED", "indexed" }, + { GIMP_CHANNEL_ALPHA, "GIMP_CHANNEL_ALPHA", "alpha" }, + { 0, NULL, NULL } + }; + + static const GimpEnumDesc descs[] = + { + { GIMP_CHANNEL_RED, NC_("channel-type", "Red"), NULL }, + { GIMP_CHANNEL_GREEN, NC_("channel-type", "Green"), NULL }, + { GIMP_CHANNEL_BLUE, NC_("channel-type", "Blue"), NULL }, + { GIMP_CHANNEL_GRAY, NC_("channel-type", "Gray"), NULL }, + { GIMP_CHANNEL_INDEXED, NC_("channel-type", "Indexed"), NULL }, + { GIMP_CHANNEL_ALPHA, NC_("channel-type", "Alpha"), NULL }, + { 0, NULL, NULL } + }; + + static GType type = 0; + + if (G_UNLIKELY (! type)) + { + type = g_enum_register_static ("GimpChannelType", values); + gimp_type_set_translation_domain (type, GETTEXT_PACKAGE "-libgimp"); + gimp_type_set_translation_context (type, "channel-type"); + gimp_enum_set_value_descriptions (type, descs); + } + + return type; +} + +GType +gimp_check_size_get_type (void) +{ + static const GEnumValue values[] = + { + { GIMP_CHECK_SIZE_SMALL_CHECKS, "GIMP_CHECK_SIZE_SMALL_CHECKS", "small-checks" }, + { GIMP_CHECK_SIZE_MEDIUM_CHECKS, "GIMP_CHECK_SIZE_MEDIUM_CHECKS", "medium-checks" }, + { GIMP_CHECK_SIZE_LARGE_CHECKS, "GIMP_CHECK_SIZE_LARGE_CHECKS", "large-checks" }, + { 0, NULL, NULL } + }; + + static const GimpEnumDesc descs[] = + { + { GIMP_CHECK_SIZE_SMALL_CHECKS, NC_("check-size", "Small"), NULL }, + { GIMP_CHECK_SIZE_MEDIUM_CHECKS, NC_("check-size", "Medium"), NULL }, + { GIMP_CHECK_SIZE_LARGE_CHECKS, NC_("check-size", "Large"), NULL }, + { 0, NULL, NULL } + }; + + static GType type = 0; + + if (G_UNLIKELY (! type)) + { + type = g_enum_register_static ("GimpCheckSize", values); + gimp_type_set_translation_domain (type, GETTEXT_PACKAGE "-libgimp"); + gimp_type_set_translation_context (type, "check-size"); + gimp_enum_set_value_descriptions (type, descs); + } + + return type; +} + +GType +gimp_check_type_get_type (void) +{ + static const GEnumValue values[] = + { + { GIMP_CHECK_TYPE_LIGHT_CHECKS, "GIMP_CHECK_TYPE_LIGHT_CHECKS", "light-checks" }, + { GIMP_CHECK_TYPE_GRAY_CHECKS, "GIMP_CHECK_TYPE_GRAY_CHECKS", "gray-checks" }, + { GIMP_CHECK_TYPE_DARK_CHECKS, "GIMP_CHECK_TYPE_DARK_CHECKS", "dark-checks" }, + { GIMP_CHECK_TYPE_WHITE_ONLY, "GIMP_CHECK_TYPE_WHITE_ONLY", "white-only" }, + { GIMP_CHECK_TYPE_GRAY_ONLY, "GIMP_CHECK_TYPE_GRAY_ONLY", "gray-only" }, + { GIMP_CHECK_TYPE_BLACK_ONLY, "GIMP_CHECK_TYPE_BLACK_ONLY", "black-only" }, + { 0, NULL, NULL } + }; + + static const GimpEnumDesc descs[] = + { + { GIMP_CHECK_TYPE_LIGHT_CHECKS, NC_("check-type", "Light checks"), NULL }, + { GIMP_CHECK_TYPE_GRAY_CHECKS, NC_("check-type", "Mid-tone checks"), NULL }, + { GIMP_CHECK_TYPE_DARK_CHECKS, NC_("check-type", "Dark checks"), NULL }, + { GIMP_CHECK_TYPE_WHITE_ONLY, NC_("check-type", "White only"), NULL }, + { GIMP_CHECK_TYPE_GRAY_ONLY, NC_("check-type", "Gray only"), NULL }, + { GIMP_CHECK_TYPE_BLACK_ONLY, NC_("check-type", "Black only"), NULL }, + { 0, NULL, NULL } + }; + + static GType type = 0; + + if (G_UNLIKELY (! type)) + { + type = g_enum_register_static ("GimpCheckType", values); + gimp_type_set_translation_domain (type, GETTEXT_PACKAGE "-libgimp"); + gimp_type_set_translation_context (type, "check-type"); + gimp_enum_set_value_descriptions (type, descs); + } + + return type; +} + +GType +gimp_clone_type_get_type (void) +{ + static const GEnumValue values[] = + { + { GIMP_CLONE_IMAGE, "GIMP_CLONE_IMAGE", "image" }, + { GIMP_CLONE_PATTERN, "GIMP_CLONE_PATTERN", "pattern" }, + { 0, NULL, NULL } + }; + + static const GimpEnumDesc descs[] = + { + { GIMP_CLONE_IMAGE, NC_("clone-type", "Image"), NULL }, + { GIMP_CLONE_PATTERN, NC_("clone-type", "Pattern"), NULL }, + { 0, NULL, NULL } + }; + + static GType type = 0; + + if (G_UNLIKELY (! type)) + { + type = g_enum_register_static ("GimpCloneType", values); + gimp_type_set_translation_domain (type, GETTEXT_PACKAGE "-libgimp"); + gimp_type_set_translation_context (type, "clone-type"); + gimp_enum_set_value_descriptions (type, descs); + } + + return type; +} + +GType +gimp_color_tag_get_type (void) +{ + static const GEnumValue values[] = + { + { GIMP_COLOR_TAG_NONE, "GIMP_COLOR_TAG_NONE", "none" }, + { GIMP_COLOR_TAG_BLUE, "GIMP_COLOR_TAG_BLUE", "blue" }, + { GIMP_COLOR_TAG_GREEN, "GIMP_COLOR_TAG_GREEN", "green" }, + { GIMP_COLOR_TAG_YELLOW, "GIMP_COLOR_TAG_YELLOW", "yellow" }, + { GIMP_COLOR_TAG_ORANGE, "GIMP_COLOR_TAG_ORANGE", "orange" }, + { GIMP_COLOR_TAG_BROWN, "GIMP_COLOR_TAG_BROWN", "brown" }, + { GIMP_COLOR_TAG_RED, "GIMP_COLOR_TAG_RED", "red" }, + { GIMP_COLOR_TAG_VIOLET, "GIMP_COLOR_TAG_VIOLET", "violet" }, + { GIMP_COLOR_TAG_GRAY, "GIMP_COLOR_TAG_GRAY", "gray" }, + { 0, NULL, NULL } + }; + + static const GimpEnumDesc descs[] = + { + { GIMP_COLOR_TAG_NONE, NC_("color-tag", "None"), NULL }, + { GIMP_COLOR_TAG_BLUE, NC_("color-tag", "Blue"), NULL }, + { GIMP_COLOR_TAG_GREEN, NC_("color-tag", "Green"), NULL }, + { GIMP_COLOR_TAG_YELLOW, NC_("color-tag", "Yellow"), NULL }, + { GIMP_COLOR_TAG_ORANGE, NC_("color-tag", "Orange"), NULL }, + { GIMP_COLOR_TAG_BROWN, NC_("color-tag", "Brown"), NULL }, + { GIMP_COLOR_TAG_RED, NC_("color-tag", "Red"), NULL }, + { GIMP_COLOR_TAG_VIOLET, NC_("color-tag", "Violet"), NULL }, + { GIMP_COLOR_TAG_GRAY, NC_("color-tag", "Gray"), NULL }, + { 0, NULL, NULL } + }; + + static GType type = 0; + + if (G_UNLIKELY (! type)) + { + type = g_enum_register_static ("GimpColorTag", values); + gimp_type_set_translation_domain (type, GETTEXT_PACKAGE "-libgimp"); + gimp_type_set_translation_context (type, "color-tag"); + gimp_enum_set_value_descriptions (type, descs); + } + + return type; +} + +GType +gimp_component_type_get_type (void) +{ + static const GEnumValue values[] = + { + { GIMP_COMPONENT_TYPE_U8, "GIMP_COMPONENT_TYPE_U8", "u8" }, + { GIMP_COMPONENT_TYPE_U16, "GIMP_COMPONENT_TYPE_U16", "u16" }, + { GIMP_COMPONENT_TYPE_U32, "GIMP_COMPONENT_TYPE_U32", "u32" }, + { GIMP_COMPONENT_TYPE_HALF, "GIMP_COMPONENT_TYPE_HALF", "half" }, + { GIMP_COMPONENT_TYPE_FLOAT, "GIMP_COMPONENT_TYPE_FLOAT", "float" }, + { GIMP_COMPONENT_TYPE_DOUBLE, "GIMP_COMPONENT_TYPE_DOUBLE", "double" }, + { 0, NULL, NULL } + }; + + static const GimpEnumDesc descs[] = + { + { GIMP_COMPONENT_TYPE_U8, NC_("component-type", "8-bit integer"), NULL }, + { GIMP_COMPONENT_TYPE_U16, NC_("component-type", "16-bit integer"), NULL }, + { GIMP_COMPONENT_TYPE_U32, NC_("component-type", "32-bit integer"), NULL }, + { GIMP_COMPONENT_TYPE_HALF, NC_("component-type", "16-bit floating point"), NULL }, + { GIMP_COMPONENT_TYPE_FLOAT, NC_("component-type", "32-bit floating point"), NULL }, + { GIMP_COMPONENT_TYPE_DOUBLE, NC_("component-type", "64-bit floating point"), NULL }, + { 0, NULL, NULL } + }; + + static GType type = 0; + + if (G_UNLIKELY (! type)) + { + type = g_enum_register_static ("GimpComponentType", values); + gimp_type_set_translation_domain (type, GETTEXT_PACKAGE "-libgimp"); + gimp_type_set_translation_context (type, "component-type"); + gimp_enum_set_value_descriptions (type, descs); + } + + return type; +} + +GType +gimp_convert_palette_type_get_type (void) +{ + static const GEnumValue values[] = + { + { GIMP_CONVERT_PALETTE_GENERATE, "GIMP_CONVERT_PALETTE_GENERATE", "generate" }, + { GIMP_CONVERT_PALETTE_WEB, "GIMP_CONVERT_PALETTE_WEB", "web" }, + { GIMP_CONVERT_PALETTE_MONO, "GIMP_CONVERT_PALETTE_MONO", "mono" }, + { GIMP_CONVERT_PALETTE_CUSTOM, "GIMP_CONVERT_PALETTE_CUSTOM", "custom" }, + { 0, NULL, NULL } + }; + + static const GimpEnumDesc descs[] = + { + { GIMP_CONVERT_PALETTE_GENERATE, NC_("convert-palette-type", "Generate optimum palette"), NULL }, + { GIMP_CONVERT_PALETTE_WEB, NC_("convert-palette-type", "Use web-optimized palette"), NULL }, + { GIMP_CONVERT_PALETTE_MONO, NC_("convert-palette-type", "Use black and white (1-bit) palette"), NULL }, + { GIMP_CONVERT_PALETTE_CUSTOM, NC_("convert-palette-type", "Use custom palette"), NULL }, + { 0, NULL, NULL } + }; + + static GType type = 0; + + if (G_UNLIKELY (! type)) + { + type = g_enum_register_static ("GimpConvertPaletteType", values); + gimp_type_set_translation_domain (type, GETTEXT_PACKAGE "-libgimp"); + gimp_type_set_translation_context (type, "convert-palette-type"); + gimp_enum_set_value_descriptions (type, descs); + } + + return type; +} + +GType +gimp_convolve_type_get_type (void) +{ + static const GEnumValue values[] = + { + { GIMP_CONVOLVE_BLUR, "GIMP_CONVOLVE_BLUR", "blur" }, + { GIMP_CONVOLVE_SHARPEN, "GIMP_CONVOLVE_SHARPEN", "sharpen" }, + { 0, NULL, NULL } + }; + + static const GimpEnumDesc descs[] = + { + { GIMP_CONVOLVE_BLUR, NC_("convolve-type", "Blur"), NULL }, + { GIMP_CONVOLVE_SHARPEN, NC_("convolve-type", "Sharpen"), NULL }, + { 0, NULL, NULL } + }; + + static GType type = 0; + + if (G_UNLIKELY (! type)) + { + type = g_enum_register_static ("GimpConvolveType", values); + gimp_type_set_translation_domain (type, GETTEXT_PACKAGE "-libgimp"); + gimp_type_set_translation_context (type, "convolve-type"); + gimp_enum_set_value_descriptions (type, descs); + } + + return type; +} + +GType +gimp_desaturate_mode_get_type (void) +{ + static const GEnumValue values[] = + { + { GIMP_DESATURATE_LIGHTNESS, "GIMP_DESATURATE_LIGHTNESS", "lightness" }, + { GIMP_DESATURATE_LUMA, "GIMP_DESATURATE_LUMA", "luma" }, + { GIMP_DESATURATE_AVERAGE, "GIMP_DESATURATE_AVERAGE", "average" }, + { GIMP_DESATURATE_LUMINANCE, "GIMP_DESATURATE_LUMINANCE", "luminance" }, + { GIMP_DESATURATE_VALUE, "GIMP_DESATURATE_VALUE", "value" }, + { 0, NULL, NULL } + }; + + static const GimpEnumDesc descs[] = + { + { GIMP_DESATURATE_LIGHTNESS, NC_("desaturate-mode", "Lightness (HSL)"), NULL }, + { GIMP_DESATURATE_LUMA, NC_("desaturate-mode", "Luma"), NULL }, + { GIMP_DESATURATE_AVERAGE, NC_("desaturate-mode", "Average (HSI Intensity)"), NULL }, + { GIMP_DESATURATE_LUMINANCE, NC_("desaturate-mode", "Luminance"), NULL }, + { GIMP_DESATURATE_VALUE, NC_("desaturate-mode", "Value (HSV)"), NULL }, + { 0, NULL, NULL } + }; + + static GType type = 0; + + if (G_UNLIKELY (! type)) + { + type = g_enum_register_static ("GimpDesaturateMode", values); + gimp_type_set_translation_domain (type, GETTEXT_PACKAGE "-libgimp"); + gimp_type_set_translation_context (type, "desaturate-mode"); + gimp_enum_set_value_descriptions (type, descs); + } + + return type; +} + +GType +gimp_dodge_burn_type_get_type (void) +{ + static const GEnumValue values[] = + { + { GIMP_DODGE_BURN_TYPE_DODGE, "GIMP_DODGE_BURN_TYPE_DODGE", "dodge" }, + { GIMP_DODGE_BURN_TYPE_BURN, "GIMP_DODGE_BURN_TYPE_BURN", "burn" }, + { 0, NULL, NULL } + }; + + static const GimpEnumDesc descs[] = + { + { GIMP_DODGE_BURN_TYPE_DODGE, NC_("dodge-burn-type", "Dodge"), NULL }, + { GIMP_DODGE_BURN_TYPE_BURN, NC_("dodge-burn-type", "Burn"), NULL }, + { 0, NULL, NULL } + }; + + static GType type = 0; + + if (G_UNLIKELY (! type)) + { + type = g_enum_register_static ("GimpDodgeBurnType", values); + gimp_type_set_translation_domain (type, GETTEXT_PACKAGE "-libgimp"); + gimp_type_set_translation_context (type, "dodge-burn-type"); + gimp_enum_set_value_descriptions (type, descs); + } + + return type; +} + +GType +gimp_fill_type_get_type (void) +{ + static const GEnumValue values[] = + { + { GIMP_FILL_FOREGROUND, "GIMP_FILL_FOREGROUND", "foreground" }, + { GIMP_FILL_BACKGROUND, "GIMP_FILL_BACKGROUND", "background" }, + { GIMP_FILL_WHITE, "GIMP_FILL_WHITE", "white" }, + { GIMP_FILL_TRANSPARENT, "GIMP_FILL_TRANSPARENT", "transparent" }, + { GIMP_FILL_PATTERN, "GIMP_FILL_PATTERN", "pattern" }, + { 0, NULL, NULL } + }; + + static const GimpEnumDesc descs[] = + { + { GIMP_FILL_FOREGROUND, NC_("fill-type", "Foreground color"), NULL }, + { GIMP_FILL_BACKGROUND, NC_("fill-type", "Background color"), NULL }, + { GIMP_FILL_WHITE, NC_("fill-type", "White"), NULL }, + { GIMP_FILL_TRANSPARENT, NC_("fill-type", "Transparency"), NULL }, + { GIMP_FILL_PATTERN, NC_("fill-type", "Pattern"), NULL }, + { 0, NULL, NULL } + }; + + static GType type = 0; + + if (G_UNLIKELY (! type)) + { + type = g_enum_register_static ("GimpFillType", values); + gimp_type_set_translation_domain (type, GETTEXT_PACKAGE "-libgimp"); + gimp_type_set_translation_context (type, "fill-type"); + gimp_enum_set_value_descriptions (type, descs); + } + + return type; +} + +GType +gimp_foreground_extract_mode_get_type (void) +{ + static const GEnumValue values[] = + { + { GIMP_FOREGROUND_EXTRACT_SIOX, "GIMP_FOREGROUND_EXTRACT_SIOX", "siox" }, + { GIMP_FOREGROUND_EXTRACT_MATTING, "GIMP_FOREGROUND_EXTRACT_MATTING", "matting" }, + { 0, NULL, NULL } + }; + + static const GimpEnumDesc descs[] = + { + { GIMP_FOREGROUND_EXTRACT_SIOX, "GIMP_FOREGROUND_EXTRACT_SIOX", NULL }, + { GIMP_FOREGROUND_EXTRACT_MATTING, "GIMP_FOREGROUND_EXTRACT_MATTING", NULL }, + { 0, NULL, NULL } + }; + + static GType type = 0; + + if (G_UNLIKELY (! type)) + { + type = g_enum_register_static ("GimpForegroundExtractMode", values); + gimp_type_set_translation_domain (type, GETTEXT_PACKAGE "-libgimp"); + gimp_type_set_translation_context (type, "foreground-extract-mode"); + gimp_enum_set_value_descriptions (type, descs); + } + + return type; +} + +GType +gimp_gradient_blend_color_space_get_type (void) +{ + static const GEnumValue values[] = + { + { GIMP_GRADIENT_BLEND_RGB_PERCEPTUAL, "GIMP_GRADIENT_BLEND_RGB_PERCEPTUAL", "rgb-perceptual" }, + { GIMP_GRADIENT_BLEND_RGB_LINEAR, "GIMP_GRADIENT_BLEND_RGB_LINEAR", "rgb-linear" }, + { GIMP_GRADIENT_BLEND_CIE_LAB, "GIMP_GRADIENT_BLEND_CIE_LAB", "cie-lab" }, + { 0, NULL, NULL } + }; + + static const GimpEnumDesc descs[] = + { + { GIMP_GRADIENT_BLEND_RGB_PERCEPTUAL, NC_("gradient-blend-color-space", "Perceptual RGB"), NULL }, + { GIMP_GRADIENT_BLEND_RGB_LINEAR, NC_("gradient-blend-color-space", "Linear RGB"), NULL }, + { GIMP_GRADIENT_BLEND_CIE_LAB, NC_("gradient-blend-color-space", "CIE Lab"), NULL }, + { 0, NULL, NULL } + }; + + static GType type = 0; + + if (G_UNLIKELY (! type)) + { + type = g_enum_register_static ("GimpGradientBlendColorSpace", values); + gimp_type_set_translation_domain (type, GETTEXT_PACKAGE "-libgimp"); + gimp_type_set_translation_context (type, "gradient-blend-color-space"); + gimp_enum_set_value_descriptions (type, descs); + } + + return type; +} + +GType +gimp_gradient_segment_color_get_type (void) +{ + static const GEnumValue values[] = + { + { GIMP_GRADIENT_SEGMENT_RGB, "GIMP_GRADIENT_SEGMENT_RGB", "rgb" }, + { GIMP_GRADIENT_SEGMENT_HSV_CCW, "GIMP_GRADIENT_SEGMENT_HSV_CCW", "hsv-ccw" }, + { GIMP_GRADIENT_SEGMENT_HSV_CW, "GIMP_GRADIENT_SEGMENT_HSV_CW", "hsv-cw" }, + { 0, NULL, NULL } + }; + + static const GimpEnumDesc descs[] = + { + { GIMP_GRADIENT_SEGMENT_RGB, NC_("gradient-segment-color", "RGB"), NULL }, + { GIMP_GRADIENT_SEGMENT_HSV_CCW, NC_("gradient-segment-color", "HSV (counter-clockwise hue)"), NULL }, + /* Translators: this is an abbreviated version of "HSV (counter-clockwise hue)". + Keep it short. */ + { GIMP_GRADIENT_SEGMENT_HSV_CCW, NC_("gradient-segment-color", "HSV (ccw)"), NULL }, + { GIMP_GRADIENT_SEGMENT_HSV_CW, NC_("gradient-segment-color", "HSV (clockwise hue)"), NULL }, + /* Translators: this is an abbreviated version of "HSV (clockwise hue)". + Keep it short. */ + { GIMP_GRADIENT_SEGMENT_HSV_CW, NC_("gradient-segment-color", "HSV (cw)"), NULL }, + { 0, NULL, NULL } + }; + + static GType type = 0; + + if (G_UNLIKELY (! type)) + { + type = g_enum_register_static ("GimpGradientSegmentColor", values); + gimp_type_set_translation_domain (type, GETTEXT_PACKAGE "-libgimp"); + gimp_type_set_translation_context (type, "gradient-segment-color"); + gimp_enum_set_value_descriptions (type, descs); + } + + return type; +} + +GType +gimp_gradient_segment_type_get_type (void) +{ + static const GEnumValue values[] = + { + { GIMP_GRADIENT_SEGMENT_LINEAR, "GIMP_GRADIENT_SEGMENT_LINEAR", "linear" }, + { GIMP_GRADIENT_SEGMENT_CURVED, "GIMP_GRADIENT_SEGMENT_CURVED", "curved" }, + { GIMP_GRADIENT_SEGMENT_SINE, "GIMP_GRADIENT_SEGMENT_SINE", "sine" }, + { GIMP_GRADIENT_SEGMENT_SPHERE_INCREASING, "GIMP_GRADIENT_SEGMENT_SPHERE_INCREASING", "sphere-increasing" }, + { GIMP_GRADIENT_SEGMENT_SPHERE_DECREASING, "GIMP_GRADIENT_SEGMENT_SPHERE_DECREASING", "sphere-decreasing" }, + { GIMP_GRADIENT_SEGMENT_STEP, "GIMP_GRADIENT_SEGMENT_STEP", "step" }, + { 0, NULL, NULL } + }; + + static const GimpEnumDesc descs[] = + { + { GIMP_GRADIENT_SEGMENT_LINEAR, NC_("gradient-segment-type", "Linear"), NULL }, + { GIMP_GRADIENT_SEGMENT_CURVED, NC_("gradient-segment-type", "Curved"), NULL }, + { GIMP_GRADIENT_SEGMENT_SINE, NC_("gradient-segment-type", "Sinusoidal"), NULL }, + { GIMP_GRADIENT_SEGMENT_SPHERE_INCREASING, NC_("gradient-segment-type", "Spherical (increasing)"), NULL }, + /* Translators: this is an abbreviated version of "Spherical (increasing)". + Keep it short. */ + { GIMP_GRADIENT_SEGMENT_SPHERE_INCREASING, NC_("gradient-segment-type", "Spherical (inc)"), NULL }, + { GIMP_GRADIENT_SEGMENT_SPHERE_DECREASING, NC_("gradient-segment-type", "Spherical (decreasing)"), NULL }, + /* Translators: this is an abbreviated version of "Spherical (decreasing)". + Keep it short. */ + { GIMP_GRADIENT_SEGMENT_SPHERE_DECREASING, NC_("gradient-segment-type", "Spherical (dec)"), NULL }, + { GIMP_GRADIENT_SEGMENT_STEP, NC_("gradient-segment-type", "Step"), NULL }, + { 0, NULL, NULL } + }; + + static GType type = 0; + + if (G_UNLIKELY (! type)) + { + type = g_enum_register_static ("GimpGradientSegmentType", values); + gimp_type_set_translation_domain (type, GETTEXT_PACKAGE "-libgimp"); + gimp_type_set_translation_context (type, "gradient-segment-type"); + gimp_enum_set_value_descriptions (type, descs); + } + + return type; +} + +GType +gimp_gradient_type_get_type (void) +{ + static const GEnumValue values[] = + { + { GIMP_GRADIENT_LINEAR, "GIMP_GRADIENT_LINEAR", "linear" }, + { GIMP_GRADIENT_BILINEAR, "GIMP_GRADIENT_BILINEAR", "bilinear" }, + { GIMP_GRADIENT_RADIAL, "GIMP_GRADIENT_RADIAL", "radial" }, + { GIMP_GRADIENT_SQUARE, "GIMP_GRADIENT_SQUARE", "square" }, + { GIMP_GRADIENT_CONICAL_SYMMETRIC, "GIMP_GRADIENT_CONICAL_SYMMETRIC", "conical-symmetric" }, + { GIMP_GRADIENT_CONICAL_ASYMMETRIC, "GIMP_GRADIENT_CONICAL_ASYMMETRIC", "conical-asymmetric" }, + { GIMP_GRADIENT_SHAPEBURST_ANGULAR, "GIMP_GRADIENT_SHAPEBURST_ANGULAR", "shapeburst-angular" }, + { GIMP_GRADIENT_SHAPEBURST_SPHERICAL, "GIMP_GRADIENT_SHAPEBURST_SPHERICAL", "shapeburst-spherical" }, + { GIMP_GRADIENT_SHAPEBURST_DIMPLED, "GIMP_GRADIENT_SHAPEBURST_DIMPLED", "shapeburst-dimpled" }, + { GIMP_GRADIENT_SPIRAL_CLOCKWISE, "GIMP_GRADIENT_SPIRAL_CLOCKWISE", "spiral-clockwise" }, + { GIMP_GRADIENT_SPIRAL_ANTICLOCKWISE, "GIMP_GRADIENT_SPIRAL_ANTICLOCKWISE", "spiral-anticlockwise" }, + { 0, NULL, NULL } + }; + + static const GimpEnumDesc descs[] = + { + { GIMP_GRADIENT_LINEAR, NC_("gradient-type", "Linear"), NULL }, + { GIMP_GRADIENT_BILINEAR, NC_("gradient-type", "Bi-linear"), NULL }, + { GIMP_GRADIENT_RADIAL, NC_("gradient-type", "Radial"), NULL }, + { GIMP_GRADIENT_SQUARE, NC_("gradient-type", "Square"), NULL }, + { GIMP_GRADIENT_CONICAL_SYMMETRIC, NC_("gradient-type", "Conical (symmetric)"), NULL }, + /* Translators: this is an abbreviated version of "Conical (symmetric)". + Keep it short. */ + { GIMP_GRADIENT_CONICAL_SYMMETRIC, NC_("gradient-type", "Conical (sym)"), NULL }, + { GIMP_GRADIENT_CONICAL_ASYMMETRIC, NC_("gradient-type", "Conical (asymmetric)"), NULL }, + /* Translators: this is an abbreviated version of "Conical (asymmetric)". + Keep it short. */ + { GIMP_GRADIENT_CONICAL_ASYMMETRIC, NC_("gradient-type", "Conical (asym)"), NULL }, + { GIMP_GRADIENT_SHAPEBURST_ANGULAR, NC_("gradient-type", "Shaped (angular)"), NULL }, + { GIMP_GRADIENT_SHAPEBURST_SPHERICAL, NC_("gradient-type", "Shaped (spherical)"), NULL }, + { GIMP_GRADIENT_SHAPEBURST_DIMPLED, NC_("gradient-type", "Shaped (dimpled)"), NULL }, + { GIMP_GRADIENT_SPIRAL_CLOCKWISE, NC_("gradient-type", "Spiral (clockwise)"), NULL }, + /* Translators: this is an abbreviated version of "Spiral (clockwise)". + Keep it short. */ + { GIMP_GRADIENT_SPIRAL_CLOCKWISE, NC_("gradient-type", "Spiral (cw)"), NULL }, + { GIMP_GRADIENT_SPIRAL_ANTICLOCKWISE, NC_("gradient-type", "Spiral (counter-clockwise)"), NULL }, + /* Translators: this is an abbreviated version of "Spiral (counter-clockwise)". + Keep it short. */ + { GIMP_GRADIENT_SPIRAL_ANTICLOCKWISE, NC_("gradient-type", "Spiral (ccw)"), NULL }, + { 0, NULL, NULL } + }; + + static GType type = 0; + + if (G_UNLIKELY (! type)) + { + type = g_enum_register_static ("GimpGradientType", values); + gimp_type_set_translation_domain (type, GETTEXT_PACKAGE "-libgimp"); + gimp_type_set_translation_context (type, "gradient-type"); + gimp_enum_set_value_descriptions (type, descs); + } + + return type; +} + +GType +gimp_grid_style_get_type (void) +{ + static const GEnumValue values[] = + { + { GIMP_GRID_DOTS, "GIMP_GRID_DOTS", "dots" }, + { GIMP_GRID_INTERSECTIONS, "GIMP_GRID_INTERSECTIONS", "intersections" }, + { GIMP_GRID_ON_OFF_DASH, "GIMP_GRID_ON_OFF_DASH", "on-off-dash" }, + { GIMP_GRID_DOUBLE_DASH, "GIMP_GRID_DOUBLE_DASH", "double-dash" }, + { GIMP_GRID_SOLID, "GIMP_GRID_SOLID", "solid" }, + { 0, NULL, NULL } + }; + + static const GimpEnumDesc descs[] = + { + { GIMP_GRID_DOTS, NC_("grid-style", "Intersections (dots)"), NULL }, + { GIMP_GRID_INTERSECTIONS, NC_("grid-style", "Intersections (crosshairs)"), NULL }, + { GIMP_GRID_ON_OFF_DASH, NC_("grid-style", "Dashed"), NULL }, + { GIMP_GRID_DOUBLE_DASH, NC_("grid-style", "Double dashed"), NULL }, + { GIMP_GRID_SOLID, NC_("grid-style", "Solid"), NULL }, + { 0, NULL, NULL } + }; + + static GType type = 0; + + if (G_UNLIKELY (! type)) + { + type = g_enum_register_static ("GimpGridStyle", values); + gimp_type_set_translation_domain (type, GETTEXT_PACKAGE "-libgimp"); + gimp_type_set_translation_context (type, "grid-style"); + gimp_enum_set_value_descriptions (type, descs); + } + + return type; +} + +GType +gimp_hue_range_get_type (void) +{ + static const GEnumValue values[] = + { + { GIMP_HUE_RANGE_ALL, "GIMP_HUE_RANGE_ALL", "all" }, + { GIMP_HUE_RANGE_RED, "GIMP_HUE_RANGE_RED", "red" }, + { GIMP_HUE_RANGE_YELLOW, "GIMP_HUE_RANGE_YELLOW", "yellow" }, + { GIMP_HUE_RANGE_GREEN, "GIMP_HUE_RANGE_GREEN", "green" }, + { GIMP_HUE_RANGE_CYAN, "GIMP_HUE_RANGE_CYAN", "cyan" }, + { GIMP_HUE_RANGE_BLUE, "GIMP_HUE_RANGE_BLUE", "blue" }, + { GIMP_HUE_RANGE_MAGENTA, "GIMP_HUE_RANGE_MAGENTA", "magenta" }, + { 0, NULL, NULL } + }; + + static const GimpEnumDesc descs[] = + { + { GIMP_HUE_RANGE_ALL, "GIMP_HUE_RANGE_ALL", NULL }, + { GIMP_HUE_RANGE_RED, "GIMP_HUE_RANGE_RED", NULL }, + { GIMP_HUE_RANGE_YELLOW, "GIMP_HUE_RANGE_YELLOW", NULL }, + { GIMP_HUE_RANGE_GREEN, "GIMP_HUE_RANGE_GREEN", NULL }, + { GIMP_HUE_RANGE_CYAN, "GIMP_HUE_RANGE_CYAN", NULL }, + { GIMP_HUE_RANGE_BLUE, "GIMP_HUE_RANGE_BLUE", NULL }, + { GIMP_HUE_RANGE_MAGENTA, "GIMP_HUE_RANGE_MAGENTA", NULL }, + { 0, NULL, NULL } + }; + + static GType type = 0; + + if (G_UNLIKELY (! type)) + { + type = g_enum_register_static ("GimpHueRange", values); + gimp_type_set_translation_domain (type, GETTEXT_PACKAGE "-libgimp"); + gimp_type_set_translation_context (type, "hue-range"); + gimp_enum_set_value_descriptions (type, descs); + } + + return type; +} + +GType +gimp_icon_type_get_type (void) +{ + static const GEnumValue values[] = + { + { GIMP_ICON_TYPE_ICON_NAME, "GIMP_ICON_TYPE_ICON_NAME", "icon-name" }, + { GIMP_ICON_TYPE_INLINE_PIXBUF, "GIMP_ICON_TYPE_INLINE_PIXBUF", "inline-pixbuf" }, + { GIMP_ICON_TYPE_IMAGE_FILE, "GIMP_ICON_TYPE_IMAGE_FILE", "image-file" }, + { 0, NULL, NULL } + }; + + static const GimpEnumDesc descs[] = + { + { GIMP_ICON_TYPE_ICON_NAME, NC_("icon-type", "Icon name"), NULL }, + { GIMP_ICON_TYPE_INLINE_PIXBUF, NC_("icon-type", "Inline pixbuf"), NULL }, + { GIMP_ICON_TYPE_IMAGE_FILE, NC_("icon-type", "Image file"), NULL }, + { 0, NULL, NULL } + }; + + static GType type = 0; + + if (G_UNLIKELY (! type)) + { + type = g_enum_register_static ("GimpIconType", values); + gimp_type_set_translation_domain (type, GETTEXT_PACKAGE "-libgimp"); + gimp_type_set_translation_context (type, "icon-type"); + gimp_enum_set_value_descriptions (type, descs); + } + + return type; +} + +GType +gimp_image_base_type_get_type (void) +{ + static const GEnumValue values[] = + { + { GIMP_RGB, "GIMP_RGB", "rgb" }, + { GIMP_GRAY, "GIMP_GRAY", "gray" }, + { GIMP_INDEXED, "GIMP_INDEXED", "indexed" }, + { 0, NULL, NULL } + }; + + static const GimpEnumDesc descs[] = + { + { GIMP_RGB, NC_("image-base-type", "RGB color"), NULL }, + { GIMP_GRAY, NC_("image-base-type", "Grayscale"), NULL }, + { GIMP_INDEXED, NC_("image-base-type", "Indexed color"), NULL }, + { 0, NULL, NULL } + }; + + static GType type = 0; + + if (G_UNLIKELY (! type)) + { + type = g_enum_register_static ("GimpImageBaseType", values); + gimp_type_set_translation_domain (type, GETTEXT_PACKAGE "-libgimp"); + gimp_type_set_translation_context (type, "image-base-type"); + gimp_enum_set_value_descriptions (type, descs); + } + + return type; +} + +GType +gimp_image_type_get_type (void) +{ + static const GEnumValue values[] = + { + { GIMP_RGB_IMAGE, "GIMP_RGB_IMAGE", "rgb-image" }, + { GIMP_RGBA_IMAGE, "GIMP_RGBA_IMAGE", "rgba-image" }, + { GIMP_GRAY_IMAGE, "GIMP_GRAY_IMAGE", "gray-image" }, + { GIMP_GRAYA_IMAGE, "GIMP_GRAYA_IMAGE", "graya-image" }, + { GIMP_INDEXED_IMAGE, "GIMP_INDEXED_IMAGE", "indexed-image" }, + { GIMP_INDEXEDA_IMAGE, "GIMP_INDEXEDA_IMAGE", "indexeda-image" }, + { 0, NULL, NULL } + }; + + static const GimpEnumDesc descs[] = + { + { GIMP_RGB_IMAGE, NC_("image-type", "RGB"), NULL }, + { GIMP_RGBA_IMAGE, NC_("image-type", "RGB-alpha"), NULL }, + { GIMP_GRAY_IMAGE, NC_("image-type", "Grayscale"), NULL }, + { GIMP_GRAYA_IMAGE, NC_("image-type", "Grayscale-alpha"), NULL }, + { GIMP_INDEXED_IMAGE, NC_("image-type", "Indexed"), NULL }, + { GIMP_INDEXEDA_IMAGE, NC_("image-type", "Indexed-alpha"), NULL }, + { 0, NULL, NULL } + }; + + static GType type = 0; + + if (G_UNLIKELY (! type)) + { + type = g_enum_register_static ("GimpImageType", values); + gimp_type_set_translation_domain (type, GETTEXT_PACKAGE "-libgimp"); + gimp_type_set_translation_context (type, "image-type"); + gimp_enum_set_value_descriptions (type, descs); + } + + return type; +} + +GType +gimp_ink_blob_type_get_type (void) +{ + static const GEnumValue values[] = + { + { GIMP_INK_BLOB_TYPE_CIRCLE, "GIMP_INK_BLOB_TYPE_CIRCLE", "circle" }, + { GIMP_INK_BLOB_TYPE_SQUARE, "GIMP_INK_BLOB_TYPE_SQUARE", "square" }, + { GIMP_INK_BLOB_TYPE_DIAMOND, "GIMP_INK_BLOB_TYPE_DIAMOND", "diamond" }, + { 0, NULL, NULL } + }; + + static const GimpEnumDesc descs[] = + { + { GIMP_INK_BLOB_TYPE_CIRCLE, NC_("ink-blob-type", "Circle"), NULL }, + { GIMP_INK_BLOB_TYPE_SQUARE, NC_("ink-blob-type", "Square"), NULL }, + { GIMP_INK_BLOB_TYPE_DIAMOND, NC_("ink-blob-type", "Diamond"), NULL }, + { 0, NULL, NULL } + }; + + static GType type = 0; + + if (G_UNLIKELY (! type)) + { + type = g_enum_register_static ("GimpInkBlobType", values); + gimp_type_set_translation_domain (type, GETTEXT_PACKAGE "-libgimp"); + gimp_type_set_translation_context (type, "ink-blob-type"); + gimp_enum_set_value_descriptions (type, descs); + } + + return type; +} + +GType +gimp_interpolation_type_get_type (void) +{ + static const GEnumValue values[] = + { + { GIMP_INTERPOLATION_NONE, "GIMP_INTERPOLATION_NONE", "none" }, + { GIMP_INTERPOLATION_LINEAR, "GIMP_INTERPOLATION_LINEAR", "linear" }, + { GIMP_INTERPOLATION_CUBIC, "GIMP_INTERPOLATION_CUBIC", "cubic" }, + { GIMP_INTERPOLATION_NOHALO, "GIMP_INTERPOLATION_NOHALO", "nohalo" }, + { GIMP_INTERPOLATION_LOHALO, "GIMP_INTERPOLATION_LOHALO", "lohalo" }, + { 0, NULL, NULL } + }; + + static const GimpEnumDesc descs[] = + { + { GIMP_INTERPOLATION_NONE, NC_("interpolation-type", "None"), NULL }, + { GIMP_INTERPOLATION_LINEAR, NC_("interpolation-type", "Linear"), NULL }, + { GIMP_INTERPOLATION_CUBIC, NC_("interpolation-type", "Cubic"), NULL }, + { GIMP_INTERPOLATION_NOHALO, NC_("interpolation-type", "NoHalo"), NULL }, + { GIMP_INTERPOLATION_LOHALO, NC_("interpolation-type", "LoHalo"), NULL }, + { 0, NULL, NULL } + }; + + static GType type = 0; + + if (G_UNLIKELY (! type)) + { + type = g_enum_register_static ("GimpInterpolationType", values); + gimp_type_set_translation_domain (type, GETTEXT_PACKAGE "-libgimp"); + gimp_type_set_translation_context (type, "interpolation-type"); + gimp_enum_set_value_descriptions (type, descs); + } + + return type; +} + +GType +gimp_join_style_get_type (void) +{ + static const GEnumValue values[] = + { + { GIMP_JOIN_MITER, "GIMP_JOIN_MITER", "miter" }, + { GIMP_JOIN_ROUND, "GIMP_JOIN_ROUND", "round" }, + { GIMP_JOIN_BEVEL, "GIMP_JOIN_BEVEL", "bevel" }, + { 0, NULL, NULL } + }; + + static const GimpEnumDesc descs[] = + { + { GIMP_JOIN_MITER, NC_("join-style", "Miter"), NULL }, + { GIMP_JOIN_ROUND, NC_("join-style", "Round"), NULL }, + { GIMP_JOIN_BEVEL, NC_("join-style", "Bevel"), NULL }, + { 0, NULL, NULL } + }; + + static GType type = 0; + + if (G_UNLIKELY (! type)) + { + type = g_enum_register_static ("GimpJoinStyle", values); + gimp_type_set_translation_domain (type, GETTEXT_PACKAGE "-libgimp"); + gimp_type_set_translation_context (type, "join-style"); + gimp_enum_set_value_descriptions (type, descs); + } + + return type; +} + +GType +gimp_mask_apply_mode_get_type (void) +{ + static const GEnumValue values[] = + { + { GIMP_MASK_APPLY, "GIMP_MASK_APPLY", "apply" }, + { GIMP_MASK_DISCARD, "GIMP_MASK_DISCARD", "discard" }, + { 0, NULL, NULL } + }; + + static const GimpEnumDesc descs[] = + { + { GIMP_MASK_APPLY, "GIMP_MASK_APPLY", NULL }, + { GIMP_MASK_DISCARD, "GIMP_MASK_DISCARD", NULL }, + { 0, NULL, NULL } + }; + + static GType type = 0; + + if (G_UNLIKELY (! type)) + { + type = g_enum_register_static ("GimpMaskApplyMode", values); + gimp_type_set_translation_domain (type, GETTEXT_PACKAGE "-libgimp"); + gimp_type_set_translation_context (type, "mask-apply-mode"); + gimp_enum_set_value_descriptions (type, descs); + } + + return type; +} + +GType +gimp_merge_type_get_type (void) +{ + static const GEnumValue values[] = + { + { GIMP_EXPAND_AS_NECESSARY, "GIMP_EXPAND_AS_NECESSARY", "expand-as-necessary" }, + { GIMP_CLIP_TO_IMAGE, "GIMP_CLIP_TO_IMAGE", "clip-to-image" }, + { GIMP_CLIP_TO_BOTTOM_LAYER, "GIMP_CLIP_TO_BOTTOM_LAYER", "clip-to-bottom-layer" }, + { GIMP_FLATTEN_IMAGE, "GIMP_FLATTEN_IMAGE", "flatten-image" }, + { 0, NULL, NULL } + }; + + static const GimpEnumDesc descs[] = + { + { GIMP_EXPAND_AS_NECESSARY, NC_("merge-type", "Expanded as necessary"), NULL }, + { GIMP_CLIP_TO_IMAGE, NC_("merge-type", "Clipped to image"), NULL }, + { GIMP_CLIP_TO_BOTTOM_LAYER, NC_("merge-type", "Clipped to bottom layer"), NULL }, + { GIMP_FLATTEN_IMAGE, NC_("merge-type", "Flatten"), NULL }, + { 0, NULL, NULL } + }; + + static GType type = 0; + + if (G_UNLIKELY (! type)) + { + type = g_enum_register_static ("GimpMergeType", values); + gimp_type_set_translation_domain (type, GETTEXT_PACKAGE "-libgimp"); + gimp_type_set_translation_context (type, "merge-type"); + gimp_enum_set_value_descriptions (type, descs); + } + + return type; +} + +GType +gimp_message_handler_type_get_type (void) +{ + static const GEnumValue values[] = + { + { GIMP_MESSAGE_BOX, "GIMP_MESSAGE_BOX", "message-box" }, + { GIMP_CONSOLE, "GIMP_CONSOLE", "console" }, + { GIMP_ERROR_CONSOLE, "GIMP_ERROR_CONSOLE", "error-console" }, + { 0, NULL, NULL } + }; + + static const GimpEnumDesc descs[] = + { + { GIMP_MESSAGE_BOX, "GIMP_MESSAGE_BOX", NULL }, + { GIMP_CONSOLE, "GIMP_CONSOLE", NULL }, + { GIMP_ERROR_CONSOLE, "GIMP_ERROR_CONSOLE", NULL }, + { 0, NULL, NULL } + }; + + static GType type = 0; + + if (G_UNLIKELY (! type)) + { + type = g_enum_register_static ("GimpMessageHandlerType", values); + gimp_type_set_translation_domain (type, GETTEXT_PACKAGE "-libgimp"); + gimp_type_set_translation_context (type, "message-handler-type"); + gimp_enum_set_value_descriptions (type, descs); + } + + return type; +} + +GType +gimp_offset_type_get_type (void) +{ + static const GEnumValue values[] = + { + { GIMP_OFFSET_BACKGROUND, "GIMP_OFFSET_BACKGROUND", "background" }, + { GIMP_OFFSET_TRANSPARENT, "GIMP_OFFSET_TRANSPARENT", "transparent" }, + { GIMP_OFFSET_WRAP_AROUND, "GIMP_OFFSET_WRAP_AROUND", "wrap-around" }, + { 0, NULL, NULL } + }; + + static const GimpEnumDesc descs[] = + { + { GIMP_OFFSET_BACKGROUND, "GIMP_OFFSET_BACKGROUND", NULL }, + { GIMP_OFFSET_TRANSPARENT, "GIMP_OFFSET_TRANSPARENT", NULL }, + { GIMP_OFFSET_WRAP_AROUND, "GIMP_OFFSET_WRAP_AROUND", NULL }, + { 0, NULL, NULL } + }; + + static GType type = 0; + + if (G_UNLIKELY (! type)) + { + type = g_enum_register_static ("GimpOffsetType", values); + gimp_type_set_translation_domain (type, GETTEXT_PACKAGE "-libgimp"); + gimp_type_set_translation_context (type, "offset-type"); + gimp_enum_set_value_descriptions (type, descs); + } + + return type; +} + +GType +gimp_orientation_type_get_type (void) +{ + static const GEnumValue values[] = + { + { GIMP_ORIENTATION_HORIZONTAL, "GIMP_ORIENTATION_HORIZONTAL", "horizontal" }, + { GIMP_ORIENTATION_VERTICAL, "GIMP_ORIENTATION_VERTICAL", "vertical" }, + { GIMP_ORIENTATION_UNKNOWN, "GIMP_ORIENTATION_UNKNOWN", "unknown" }, + { 0, NULL, NULL } + }; + + static const GimpEnumDesc descs[] = + { + { GIMP_ORIENTATION_HORIZONTAL, NC_("orientation-type", "Horizontal"), NULL }, + { GIMP_ORIENTATION_VERTICAL, NC_("orientation-type", "Vertical"), NULL }, + { GIMP_ORIENTATION_UNKNOWN, NC_("orientation-type", "Unknown"), NULL }, + { 0, NULL, NULL } + }; + + static GType type = 0; + + if (G_UNLIKELY (! type)) + { + type = g_enum_register_static ("GimpOrientationType", values); + gimp_type_set_translation_domain (type, GETTEXT_PACKAGE "-libgimp"); + gimp_type_set_translation_context (type, "orientation-type"); + gimp_enum_set_value_descriptions (type, descs); + } + + return type; +} + +GType +gimp_paint_application_mode_get_type (void) +{ + static const GEnumValue values[] = + { + { GIMP_PAINT_CONSTANT, "GIMP_PAINT_CONSTANT", "constant" }, + { GIMP_PAINT_INCREMENTAL, "GIMP_PAINT_INCREMENTAL", "incremental" }, + { 0, NULL, NULL } + }; + + static const GimpEnumDesc descs[] = + { + { GIMP_PAINT_CONSTANT, NC_("paint-application-mode", "Constant"), NULL }, + { GIMP_PAINT_INCREMENTAL, NC_("paint-application-mode", "Incremental"), NULL }, + { 0, NULL, NULL } + }; + + static GType type = 0; + + if (G_UNLIKELY (! type)) + { + type = g_enum_register_static ("GimpPaintApplicationMode", values); + gimp_type_set_translation_domain (type, GETTEXT_PACKAGE "-libgimp"); + gimp_type_set_translation_context (type, "paint-application-mode"); + gimp_enum_set_value_descriptions (type, descs); + } + + return type; +} + +GType +gimp_pdb_arg_type_get_type (void) +{ + static const GEnumValue values[] = + { + { GIMP_PDB_INT32, "GIMP_PDB_INT32", "int32" }, + { GIMP_PDB_INT16, "GIMP_PDB_INT16", "int16" }, + { GIMP_PDB_INT8, "GIMP_PDB_INT8", "int8" }, + { GIMP_PDB_FLOAT, "GIMP_PDB_FLOAT", "float" }, + { GIMP_PDB_STRING, "GIMP_PDB_STRING", "string" }, + { GIMP_PDB_INT32ARRAY, "GIMP_PDB_INT32ARRAY", "int32array" }, + { GIMP_PDB_INT16ARRAY, "GIMP_PDB_INT16ARRAY", "int16array" }, + { GIMP_PDB_INT8ARRAY, "GIMP_PDB_INT8ARRAY", "int8array" }, + { GIMP_PDB_FLOATARRAY, "GIMP_PDB_FLOATARRAY", "floatarray" }, + { GIMP_PDB_STRINGARRAY, "GIMP_PDB_STRINGARRAY", "stringarray" }, + { GIMP_PDB_COLOR, "GIMP_PDB_COLOR", "color" }, + { GIMP_PDB_ITEM, "GIMP_PDB_ITEM", "item" }, + { GIMP_PDB_DISPLAY, "GIMP_PDB_DISPLAY", "display" }, + { GIMP_PDB_IMAGE, "GIMP_PDB_IMAGE", "image" }, + { GIMP_PDB_LAYER, "GIMP_PDB_LAYER", "layer" }, + { GIMP_PDB_CHANNEL, "GIMP_PDB_CHANNEL", "channel" }, + { GIMP_PDB_DRAWABLE, "GIMP_PDB_DRAWABLE", "drawable" }, + { GIMP_PDB_SELECTION, "GIMP_PDB_SELECTION", "selection" }, + { GIMP_PDB_COLORARRAY, "GIMP_PDB_COLORARRAY", "colorarray" }, + { GIMP_PDB_VECTORS, "GIMP_PDB_VECTORS", "vectors" }, + { GIMP_PDB_PARASITE, "GIMP_PDB_PARASITE", "parasite" }, + { GIMP_PDB_STATUS, "GIMP_PDB_STATUS", "status" }, + { GIMP_PDB_END, "GIMP_PDB_END", "end" }, + { 0, NULL, NULL } + }; + + static const GimpEnumDesc descs[] = + { + { GIMP_PDB_INT32, "GIMP_PDB_INT32", NULL }, + { GIMP_PDB_INT16, "GIMP_PDB_INT16", NULL }, + { GIMP_PDB_INT8, "GIMP_PDB_INT8", NULL }, + { GIMP_PDB_FLOAT, "GIMP_PDB_FLOAT", NULL }, + { GIMP_PDB_STRING, "GIMP_PDB_STRING", NULL }, + { GIMP_PDB_INT32ARRAY, "GIMP_PDB_INT32ARRAY", NULL }, + { GIMP_PDB_INT16ARRAY, "GIMP_PDB_INT16ARRAY", NULL }, + { GIMP_PDB_INT8ARRAY, "GIMP_PDB_INT8ARRAY", NULL }, + { GIMP_PDB_FLOATARRAY, "GIMP_PDB_FLOATARRAY", NULL }, + { GIMP_PDB_STRINGARRAY, "GIMP_PDB_STRINGARRAY", NULL }, + { GIMP_PDB_COLOR, "GIMP_PDB_COLOR", NULL }, + { GIMP_PDB_ITEM, "GIMP_PDB_ITEM", NULL }, + { GIMP_PDB_DISPLAY, "GIMP_PDB_DISPLAY", NULL }, + { GIMP_PDB_IMAGE, "GIMP_PDB_IMAGE", NULL }, + { GIMP_PDB_LAYER, "GIMP_PDB_LAYER", NULL }, + { GIMP_PDB_CHANNEL, "GIMP_PDB_CHANNEL", NULL }, + { GIMP_PDB_DRAWABLE, "GIMP_PDB_DRAWABLE", NULL }, + { GIMP_PDB_SELECTION, "GIMP_PDB_SELECTION", NULL }, + { GIMP_PDB_COLORARRAY, "GIMP_PDB_COLORARRAY", NULL }, + { GIMP_PDB_VECTORS, "GIMP_PDB_VECTORS", NULL }, + { GIMP_PDB_PARASITE, "GIMP_PDB_PARASITE", NULL }, + { GIMP_PDB_STATUS, "GIMP_PDB_STATUS", NULL }, + { GIMP_PDB_END, "GIMP_PDB_END", NULL }, + { 0, NULL, NULL } + }; + + static GType type = 0; + + if (G_UNLIKELY (! type)) + { + type = g_enum_register_static ("GimpPDBArgType", values); + gimp_type_set_translation_domain (type, GETTEXT_PACKAGE "-libgimp"); + gimp_type_set_translation_context (type, "pdb-arg-type"); + gimp_enum_set_value_descriptions (type, descs); + } + + return type; +} + +GType +gimp_pdb_error_handler_get_type (void) +{ + static const GEnumValue values[] = + { + { GIMP_PDB_ERROR_HANDLER_INTERNAL, "GIMP_PDB_ERROR_HANDLER_INTERNAL", "internal" }, + { GIMP_PDB_ERROR_HANDLER_PLUGIN, "GIMP_PDB_ERROR_HANDLER_PLUGIN", "plugin" }, + { 0, NULL, NULL } + }; + + static const GimpEnumDesc descs[] = + { + { GIMP_PDB_ERROR_HANDLER_INTERNAL, "GIMP_PDB_ERROR_HANDLER_INTERNAL", NULL }, + { GIMP_PDB_ERROR_HANDLER_PLUGIN, "GIMP_PDB_ERROR_HANDLER_PLUGIN", NULL }, + { 0, NULL, NULL } + }; + + static GType type = 0; + + if (G_UNLIKELY (! type)) + { + type = g_enum_register_static ("GimpPDBErrorHandler", values); + gimp_type_set_translation_domain (type, GETTEXT_PACKAGE "-libgimp"); + gimp_type_set_translation_context (type, "pdb-error-handler"); + gimp_enum_set_value_descriptions (type, descs); + } + + return type; +} + +GType +gimp_pdb_proc_type_get_type (void) +{ + static const GEnumValue values[] = + { + { GIMP_INTERNAL, "GIMP_INTERNAL", "internal" }, + { GIMP_PLUGIN, "GIMP_PLUGIN", "plugin" }, + { GIMP_EXTENSION, "GIMP_EXTENSION", "extension" }, + { GIMP_TEMPORARY, "GIMP_TEMPORARY", "temporary" }, + { 0, NULL, NULL } + }; + + static const GimpEnumDesc descs[] = + { + { GIMP_INTERNAL, NC_("pdb-proc-type", "Internal GIMP procedure"), NULL }, + { GIMP_PLUGIN, NC_("pdb-proc-type", "GIMP Plug-In"), NULL }, + { GIMP_EXTENSION, NC_("pdb-proc-type", "GIMP Extension"), NULL }, + { GIMP_TEMPORARY, NC_("pdb-proc-type", "Temporary Procedure"), NULL }, + { 0, NULL, NULL } + }; + + static GType type = 0; + + if (G_UNLIKELY (! type)) + { + type = g_enum_register_static ("GimpPDBProcType", values); + gimp_type_set_translation_domain (type, GETTEXT_PACKAGE "-libgimp"); + gimp_type_set_translation_context (type, "pdb-proc-type"); + gimp_enum_set_value_descriptions (type, descs); + } + + return type; +} + +GType +gimp_pdb_status_type_get_type (void) +{ + static const GEnumValue values[] = + { + { GIMP_PDB_EXECUTION_ERROR, "GIMP_PDB_EXECUTION_ERROR", "execution-error" }, + { GIMP_PDB_CALLING_ERROR, "GIMP_PDB_CALLING_ERROR", "calling-error" }, + { GIMP_PDB_PASS_THROUGH, "GIMP_PDB_PASS_THROUGH", "pass-through" }, + { GIMP_PDB_SUCCESS, "GIMP_PDB_SUCCESS", "success" }, + { GIMP_PDB_CANCEL, "GIMP_PDB_CANCEL", "cancel" }, + { 0, NULL, NULL } + }; + + static const GimpEnumDesc descs[] = + { + { GIMP_PDB_EXECUTION_ERROR, "GIMP_PDB_EXECUTION_ERROR", NULL }, + { GIMP_PDB_CALLING_ERROR, "GIMP_PDB_CALLING_ERROR", NULL }, + { GIMP_PDB_PASS_THROUGH, "GIMP_PDB_PASS_THROUGH", NULL }, + { GIMP_PDB_SUCCESS, "GIMP_PDB_SUCCESS", NULL }, + { GIMP_PDB_CANCEL, "GIMP_PDB_CANCEL", NULL }, + { 0, NULL, NULL } + }; + + static GType type = 0; + + if (G_UNLIKELY (! type)) + { + type = g_enum_register_static ("GimpPDBStatusType", values); + gimp_type_set_translation_domain (type, GETTEXT_PACKAGE "-libgimp"); + gimp_type_set_translation_context (type, "pdb-status-type"); + gimp_enum_set_value_descriptions (type, descs); + } + + return type; +} + +GType +gimp_precision_get_type (void) +{ + static const GEnumValue values[] = + { + { GIMP_PRECISION_U8_LINEAR, "GIMP_PRECISION_U8_LINEAR", "u8-linear" }, + { GIMP_PRECISION_U8_GAMMA, "GIMP_PRECISION_U8_GAMMA", "u8-gamma" }, + { GIMP_PRECISION_U16_LINEAR, "GIMP_PRECISION_U16_LINEAR", "u16-linear" }, + { GIMP_PRECISION_U16_GAMMA, "GIMP_PRECISION_U16_GAMMA", "u16-gamma" }, + { GIMP_PRECISION_U32_LINEAR, "GIMP_PRECISION_U32_LINEAR", "u32-linear" }, + { GIMP_PRECISION_U32_GAMMA, "GIMP_PRECISION_U32_GAMMA", "u32-gamma" }, + { GIMP_PRECISION_HALF_LINEAR, "GIMP_PRECISION_HALF_LINEAR", "half-linear" }, + { GIMP_PRECISION_HALF_GAMMA, "GIMP_PRECISION_HALF_GAMMA", "half-gamma" }, + { GIMP_PRECISION_FLOAT_LINEAR, "GIMP_PRECISION_FLOAT_LINEAR", "float-linear" }, + { GIMP_PRECISION_FLOAT_GAMMA, "GIMP_PRECISION_FLOAT_GAMMA", "float-gamma" }, + { GIMP_PRECISION_DOUBLE_LINEAR, "GIMP_PRECISION_DOUBLE_LINEAR", "double-linear" }, + { GIMP_PRECISION_DOUBLE_GAMMA, "GIMP_PRECISION_DOUBLE_GAMMA", "double-gamma" }, + { 0, NULL, NULL } + }; + + static const GimpEnumDesc descs[] = + { + { GIMP_PRECISION_U8_LINEAR, NC_("precision", "8-bit linear integer"), NULL }, + { GIMP_PRECISION_U8_GAMMA, NC_("precision", "8-bit gamma integer"), NULL }, + { GIMP_PRECISION_U16_LINEAR, NC_("precision", "16-bit linear integer"), NULL }, + { GIMP_PRECISION_U16_GAMMA, NC_("precision", "16-bit gamma integer"), NULL }, + { GIMP_PRECISION_U32_LINEAR, NC_("precision", "32-bit linear integer"), NULL }, + { GIMP_PRECISION_U32_GAMMA, NC_("precision", "32-bit gamma integer"), NULL }, + { GIMP_PRECISION_HALF_LINEAR, NC_("precision", "16-bit linear floating point"), NULL }, + { GIMP_PRECISION_HALF_GAMMA, NC_("precision", "16-bit gamma floating point"), NULL }, + { GIMP_PRECISION_FLOAT_LINEAR, NC_("precision", "32-bit linear floating point"), NULL }, + { GIMP_PRECISION_FLOAT_GAMMA, NC_("precision", "32-bit gamma floating point"), NULL }, + { GIMP_PRECISION_DOUBLE_LINEAR, NC_("precision", "64-bit linear floating point"), NULL }, + { GIMP_PRECISION_DOUBLE_GAMMA, NC_("precision", "64-bit gamma floating point"), NULL }, + { 0, NULL, NULL } + }; + + static GType type = 0; + + if (G_UNLIKELY (! type)) + { + type = g_enum_register_static ("GimpPrecision", values); + gimp_type_set_translation_domain (type, GETTEXT_PACKAGE "-libgimp"); + gimp_type_set_translation_context (type, "precision"); + gimp_enum_set_value_descriptions (type, descs); + } + + return type; +} + +GType +gimp_progress_command_get_type (void) +{ + static const GEnumValue values[] = + { + { GIMP_PROGRESS_COMMAND_START, "GIMP_PROGRESS_COMMAND_START", "start" }, + { GIMP_PROGRESS_COMMAND_END, "GIMP_PROGRESS_COMMAND_END", "end" }, + { GIMP_PROGRESS_COMMAND_SET_TEXT, "GIMP_PROGRESS_COMMAND_SET_TEXT", "set-text" }, + { GIMP_PROGRESS_COMMAND_SET_VALUE, "GIMP_PROGRESS_COMMAND_SET_VALUE", "set-value" }, + { GIMP_PROGRESS_COMMAND_PULSE, "GIMP_PROGRESS_COMMAND_PULSE", "pulse" }, + { GIMP_PROGRESS_COMMAND_GET_WINDOW, "GIMP_PROGRESS_COMMAND_GET_WINDOW", "get-window" }, + { 0, NULL, NULL } + }; + + static const GimpEnumDesc descs[] = + { + { GIMP_PROGRESS_COMMAND_START, "GIMP_PROGRESS_COMMAND_START", NULL }, + { GIMP_PROGRESS_COMMAND_END, "GIMP_PROGRESS_COMMAND_END", NULL }, + { GIMP_PROGRESS_COMMAND_SET_TEXT, "GIMP_PROGRESS_COMMAND_SET_TEXT", NULL }, + { GIMP_PROGRESS_COMMAND_SET_VALUE, "GIMP_PROGRESS_COMMAND_SET_VALUE", NULL }, + { GIMP_PROGRESS_COMMAND_PULSE, "GIMP_PROGRESS_COMMAND_PULSE", NULL }, + { GIMP_PROGRESS_COMMAND_GET_WINDOW, "GIMP_PROGRESS_COMMAND_GET_WINDOW", NULL }, + { 0, NULL, NULL } + }; + + static GType type = 0; + + if (G_UNLIKELY (! type)) + { + type = g_enum_register_static ("GimpProgressCommand", values); + gimp_type_set_translation_domain (type, GETTEXT_PACKAGE "-libgimp"); + gimp_type_set_translation_context (type, "progress-command"); + gimp_enum_set_value_descriptions (type, descs); + } + + return type; +} + +GType +gimp_repeat_mode_get_type (void) +{ + static const GEnumValue values[] = + { + { GIMP_REPEAT_NONE, "GIMP_REPEAT_NONE", "none" }, + { GIMP_REPEAT_SAWTOOTH, "GIMP_REPEAT_SAWTOOTH", "sawtooth" }, + { GIMP_REPEAT_TRIANGULAR, "GIMP_REPEAT_TRIANGULAR", "triangular" }, + { GIMP_REPEAT_TRUNCATE, "GIMP_REPEAT_TRUNCATE", "truncate" }, + { 0, NULL, NULL } + }; + + static const GimpEnumDesc descs[] = + { + { GIMP_REPEAT_NONE, NC_("repeat-mode", "None (extend)"), NULL }, + { GIMP_REPEAT_SAWTOOTH, NC_("repeat-mode", "Sawtooth wave"), NULL }, + { GIMP_REPEAT_TRIANGULAR, NC_("repeat-mode", "Triangular wave"), NULL }, + { GIMP_REPEAT_TRUNCATE, NC_("repeat-mode", "Truncate"), NULL }, + { 0, NULL, NULL } + }; + + static GType type = 0; + + if (G_UNLIKELY (! type)) + { + type = g_enum_register_static ("GimpRepeatMode", values); + gimp_type_set_translation_domain (type, GETTEXT_PACKAGE "-libgimp"); + gimp_type_set_translation_context (type, "repeat-mode"); + gimp_enum_set_value_descriptions (type, descs); + } + + return type; +} + +GType +gimp_rotation_type_get_type (void) +{ + static const GEnumValue values[] = + { + { GIMP_ROTATE_90, "GIMP_ROTATE_90", "90" }, + { GIMP_ROTATE_180, "GIMP_ROTATE_180", "180" }, + { GIMP_ROTATE_270, "GIMP_ROTATE_270", "270" }, + { 0, NULL, NULL } + }; + + static const GimpEnumDesc descs[] = + { + { GIMP_ROTATE_90, "GIMP_ROTATE_90", NULL }, + { GIMP_ROTATE_180, "GIMP_ROTATE_180", NULL }, + { GIMP_ROTATE_270, "GIMP_ROTATE_270", NULL }, + { 0, NULL, NULL } + }; + + static GType type = 0; + + if (G_UNLIKELY (! type)) + { + type = g_enum_register_static ("GimpRotationType", values); + gimp_type_set_translation_domain (type, GETTEXT_PACKAGE "-libgimp"); + gimp_type_set_translation_context (type, "rotation-type"); + gimp_enum_set_value_descriptions (type, descs); + } + + return type; +} + +GType +gimp_run_mode_get_type (void) +{ + static const GEnumValue values[] = + { + { GIMP_RUN_INTERACTIVE, "GIMP_RUN_INTERACTIVE", "interactive" }, + { GIMP_RUN_NONINTERACTIVE, "GIMP_RUN_NONINTERACTIVE", "noninteractive" }, + { GIMP_RUN_WITH_LAST_VALS, "GIMP_RUN_WITH_LAST_VALS", "with-last-vals" }, + { 0, NULL, NULL } + }; + + static const GimpEnumDesc descs[] = + { + { GIMP_RUN_INTERACTIVE, NC_("run-mode", "Run interactively"), NULL }, + { GIMP_RUN_NONINTERACTIVE, NC_("run-mode", "Run non-interactively"), NULL }, + { GIMP_RUN_WITH_LAST_VALS, NC_("run-mode", "Run with last used values"), NULL }, + { 0, NULL, NULL } + }; + + static GType type = 0; + + if (G_UNLIKELY (! type)) + { + type = g_enum_register_static ("GimpRunMode", values); + gimp_type_set_translation_domain (type, GETTEXT_PACKAGE "-libgimp"); + gimp_type_set_translation_context (type, "run-mode"); + gimp_enum_set_value_descriptions (type, descs); + } + + return type; +} + +GType +gimp_select_criterion_get_type (void) +{ + static const GEnumValue values[] = + { + { GIMP_SELECT_CRITERION_COMPOSITE, "GIMP_SELECT_CRITERION_COMPOSITE", "composite" }, + { GIMP_SELECT_CRITERION_R, "GIMP_SELECT_CRITERION_R", "r" }, + { GIMP_SELECT_CRITERION_G, "GIMP_SELECT_CRITERION_G", "g" }, + { GIMP_SELECT_CRITERION_B, "GIMP_SELECT_CRITERION_B", "b" }, + { GIMP_SELECT_CRITERION_H, "GIMP_SELECT_CRITERION_H", "h" }, + { GIMP_SELECT_CRITERION_S, "GIMP_SELECT_CRITERION_S", "s" }, + { GIMP_SELECT_CRITERION_V, "GIMP_SELECT_CRITERION_V", "v" }, + { GIMP_SELECT_CRITERION_A, "GIMP_SELECT_CRITERION_A", "a" }, + { GIMP_SELECT_CRITERION_LCH_L, "GIMP_SELECT_CRITERION_LCH_L", "lch-l" }, + { GIMP_SELECT_CRITERION_LCH_C, "GIMP_SELECT_CRITERION_LCH_C", "lch-c" }, + { GIMP_SELECT_CRITERION_LCH_H, "GIMP_SELECT_CRITERION_LCH_H", "lch-h" }, + { 0, NULL, NULL } + }; + + static const GimpEnumDesc descs[] = + { + { GIMP_SELECT_CRITERION_COMPOSITE, NC_("select-criterion", "Composite"), NULL }, + { GIMP_SELECT_CRITERION_R, NC_("select-criterion", "Red"), NULL }, + { GIMP_SELECT_CRITERION_G, NC_("select-criterion", "Green"), NULL }, + { GIMP_SELECT_CRITERION_B, NC_("select-criterion", "Blue"), NULL }, + { GIMP_SELECT_CRITERION_H, NC_("select-criterion", "HSV Hue"), NULL }, + { GIMP_SELECT_CRITERION_S, NC_("select-criterion", "HSV Saturation"), NULL }, + { GIMP_SELECT_CRITERION_V, NC_("select-criterion", "HSV Value"), NULL }, + { GIMP_SELECT_CRITERION_A, NC_("select-criterion", "Alpha"), NULL }, + { GIMP_SELECT_CRITERION_LCH_L, NC_("select-criterion", "LCh Lightness"), NULL }, + { GIMP_SELECT_CRITERION_LCH_C, NC_("select-criterion", "LCh Chroma"), NULL }, + { GIMP_SELECT_CRITERION_LCH_H, NC_("select-criterion", "LCh Hue"), NULL }, + { 0, NULL, NULL } + }; + + static GType type = 0; + + if (G_UNLIKELY (! type)) + { + type = g_enum_register_static ("GimpSelectCriterion", values); + gimp_type_set_translation_domain (type, GETTEXT_PACKAGE "-libgimp"); + gimp_type_set_translation_context (type, "select-criterion"); + gimp_enum_set_value_descriptions (type, descs); + } + + return type; +} + +GType +gimp_size_type_get_type (void) +{ + static const GEnumValue values[] = + { + { GIMP_PIXELS, "GIMP_PIXELS", "pixels" }, + { GIMP_POINTS, "GIMP_POINTS", "points" }, + { 0, NULL, NULL } + }; + + static const GimpEnumDesc descs[] = + { + { GIMP_PIXELS, NC_("size-type", "Pixels"), NULL }, + { GIMP_POINTS, NC_("size-type", "Points"), NULL }, + { 0, NULL, NULL } + }; + + static GType type = 0; + + if (G_UNLIKELY (! type)) + { + type = g_enum_register_static ("GimpSizeType", values); + gimp_type_set_translation_domain (type, GETTEXT_PACKAGE "-libgimp"); + gimp_type_set_translation_context (type, "size-type"); + gimp_enum_set_value_descriptions (type, descs); + } + + return type; +} + +GType +gimp_stack_trace_mode_get_type (void) +{ + static const GEnumValue values[] = + { + { GIMP_STACK_TRACE_NEVER, "GIMP_STACK_TRACE_NEVER", "never" }, + { GIMP_STACK_TRACE_QUERY, "GIMP_STACK_TRACE_QUERY", "query" }, + { GIMP_STACK_TRACE_ALWAYS, "GIMP_STACK_TRACE_ALWAYS", "always" }, + { 0, NULL, NULL } + }; + + static const GimpEnumDesc descs[] = + { + { GIMP_STACK_TRACE_NEVER, "GIMP_STACK_TRACE_NEVER", NULL }, + { GIMP_STACK_TRACE_QUERY, "GIMP_STACK_TRACE_QUERY", NULL }, + { GIMP_STACK_TRACE_ALWAYS, "GIMP_STACK_TRACE_ALWAYS", NULL }, + { 0, NULL, NULL } + }; + + static GType type = 0; + + if (G_UNLIKELY (! type)) + { + type = g_enum_register_static ("GimpStackTraceMode", values); + gimp_type_set_translation_domain (type, GETTEXT_PACKAGE "-libgimp"); + gimp_type_set_translation_context (type, "stack-trace-mode"); + gimp_enum_set_value_descriptions (type, descs); + } + + return type; +} + +GType +gimp_stroke_method_get_type (void) +{ + static const GEnumValue values[] = + { + { GIMP_STROKE_LINE, "GIMP_STROKE_LINE", "line" }, + { GIMP_STROKE_PAINT_METHOD, "GIMP_STROKE_PAINT_METHOD", "paint-method" }, + { 0, NULL, NULL } + }; + + static const GimpEnumDesc descs[] = + { + { GIMP_STROKE_LINE, NC_("stroke-method", "Stroke line"), NULL }, + { GIMP_STROKE_PAINT_METHOD, NC_("stroke-method", "Stroke with a paint tool"), NULL }, + { 0, NULL, NULL } + }; + + static GType type = 0; + + if (G_UNLIKELY (! type)) + { + type = g_enum_register_static ("GimpStrokeMethod", values); + gimp_type_set_translation_domain (type, GETTEXT_PACKAGE "-libgimp"); + gimp_type_set_translation_context (type, "stroke-method"); + gimp_enum_set_value_descriptions (type, descs); + } + + return type; +} + +GType +gimp_text_direction_get_type (void) +{ + static const GEnumValue values[] = + { + { GIMP_TEXT_DIRECTION_LTR, "GIMP_TEXT_DIRECTION_LTR", "ltr" }, + { GIMP_TEXT_DIRECTION_RTL, "GIMP_TEXT_DIRECTION_RTL", "rtl" }, + { GIMP_TEXT_DIRECTION_TTB_RTL, "GIMP_TEXT_DIRECTION_TTB_RTL", "ttb-rtl" }, + { GIMP_TEXT_DIRECTION_TTB_RTL_UPRIGHT, "GIMP_TEXT_DIRECTION_TTB_RTL_UPRIGHT", "ttb-rtl-upright" }, + { GIMP_TEXT_DIRECTION_TTB_LTR, "GIMP_TEXT_DIRECTION_TTB_LTR", "ttb-ltr" }, + { GIMP_TEXT_DIRECTION_TTB_LTR_UPRIGHT, "GIMP_TEXT_DIRECTION_TTB_LTR_UPRIGHT", "ttb-ltr-upright" }, + { 0, NULL, NULL } + }; + + static const GimpEnumDesc descs[] = + { + { GIMP_TEXT_DIRECTION_LTR, NC_("text-direction", "From left to right"), NULL }, + { GIMP_TEXT_DIRECTION_RTL, NC_("text-direction", "From right to left"), NULL }, + { GIMP_TEXT_DIRECTION_TTB_RTL, NC_("text-direction", "Vertical, right to left (mixed orientation)"), NULL }, + { GIMP_TEXT_DIRECTION_TTB_RTL_UPRIGHT, NC_("text-direction", "Vertical, right to left (upright orientation)"), NULL }, + { GIMP_TEXT_DIRECTION_TTB_LTR, NC_("text-direction", "Vertical, left to right (mixed orientation)"), NULL }, + { GIMP_TEXT_DIRECTION_TTB_LTR_UPRIGHT, NC_("text-direction", "Vertical, left to right (upright orientation)"), NULL }, + { 0, NULL, NULL } + }; + + static GType type = 0; + + if (G_UNLIKELY (! type)) + { + type = g_enum_register_static ("GimpTextDirection", values); + gimp_type_set_translation_domain (type, GETTEXT_PACKAGE "-libgimp"); + gimp_type_set_translation_context (type, "text-direction"); + gimp_enum_set_value_descriptions (type, descs); + } + + return type; +} + +GType +gimp_text_hint_style_get_type (void) +{ + static const GEnumValue values[] = + { + { GIMP_TEXT_HINT_STYLE_NONE, "GIMP_TEXT_HINT_STYLE_NONE", "none" }, + { GIMP_TEXT_HINT_STYLE_SLIGHT, "GIMP_TEXT_HINT_STYLE_SLIGHT", "slight" }, + { GIMP_TEXT_HINT_STYLE_MEDIUM, "GIMP_TEXT_HINT_STYLE_MEDIUM", "medium" }, + { GIMP_TEXT_HINT_STYLE_FULL, "GIMP_TEXT_HINT_STYLE_FULL", "full" }, + { 0, NULL, NULL } + }; + + static const GimpEnumDesc descs[] = + { + { GIMP_TEXT_HINT_STYLE_NONE, NC_("text-hint-style", "None"), NULL }, + { GIMP_TEXT_HINT_STYLE_SLIGHT, NC_("text-hint-style", "Slight"), NULL }, + { GIMP_TEXT_HINT_STYLE_MEDIUM, NC_("text-hint-style", "Medium"), NULL }, + { GIMP_TEXT_HINT_STYLE_FULL, NC_("text-hint-style", "Full"), NULL }, + { 0, NULL, NULL } + }; + + static GType type = 0; + + if (G_UNLIKELY (! type)) + { + type = g_enum_register_static ("GimpTextHintStyle", values); + gimp_type_set_translation_domain (type, GETTEXT_PACKAGE "-libgimp"); + gimp_type_set_translation_context (type, "text-hint-style"); + gimp_enum_set_value_descriptions (type, descs); + } + + return type; +} + +GType +gimp_text_justification_get_type (void) +{ + static const GEnumValue values[] = + { + { GIMP_TEXT_JUSTIFY_LEFT, "GIMP_TEXT_JUSTIFY_LEFT", "left" }, + { GIMP_TEXT_JUSTIFY_RIGHT, "GIMP_TEXT_JUSTIFY_RIGHT", "right" }, + { GIMP_TEXT_JUSTIFY_CENTER, "GIMP_TEXT_JUSTIFY_CENTER", "center" }, + { GIMP_TEXT_JUSTIFY_FILL, "GIMP_TEXT_JUSTIFY_FILL", "fill" }, + { 0, NULL, NULL } + }; + + static const GimpEnumDesc descs[] = + { + { GIMP_TEXT_JUSTIFY_LEFT, NC_("text-justification", "Left justified"), NULL }, + { GIMP_TEXT_JUSTIFY_RIGHT, NC_("text-justification", "Right justified"), NULL }, + { GIMP_TEXT_JUSTIFY_CENTER, NC_("text-justification", "Centered"), NULL }, + { GIMP_TEXT_JUSTIFY_FILL, NC_("text-justification", "Filled"), NULL }, + { 0, NULL, NULL } + }; + + static GType type = 0; + + if (G_UNLIKELY (! type)) + { + type = g_enum_register_static ("GimpTextJustification", values); + gimp_type_set_translation_domain (type, GETTEXT_PACKAGE "-libgimp"); + gimp_type_set_translation_context (type, "text-justification"); + gimp_enum_set_value_descriptions (type, descs); + } + + return type; +} + +GType +gimp_transfer_mode_get_type (void) +{ + static const GEnumValue values[] = + { + { GIMP_TRANSFER_SHADOWS, "GIMP_TRANSFER_SHADOWS", "shadows" }, + { GIMP_TRANSFER_MIDTONES, "GIMP_TRANSFER_MIDTONES", "midtones" }, + { GIMP_TRANSFER_HIGHLIGHTS, "GIMP_TRANSFER_HIGHLIGHTS", "highlights" }, + { 0, NULL, NULL } + }; + + static const GimpEnumDesc descs[] = + { + { GIMP_TRANSFER_SHADOWS, NC_("transfer-mode", "Shadows"), NULL }, + { GIMP_TRANSFER_MIDTONES, NC_("transfer-mode", "Midtones"), NULL }, + { GIMP_TRANSFER_HIGHLIGHTS, NC_("transfer-mode", "Highlights"), NULL }, + { 0, NULL, NULL } + }; + + static GType type = 0; + + if (G_UNLIKELY (! type)) + { + type = g_enum_register_static ("GimpTransferMode", values); + gimp_type_set_translation_domain (type, GETTEXT_PACKAGE "-libgimp"); + gimp_type_set_translation_context (type, "transfer-mode"); + gimp_enum_set_value_descriptions (type, descs); + } + + return type; +} + +GType +gimp_transform_direction_get_type (void) +{ + static const GEnumValue values[] = + { + { GIMP_TRANSFORM_FORWARD, "GIMP_TRANSFORM_FORWARD", "forward" }, + { GIMP_TRANSFORM_BACKWARD, "GIMP_TRANSFORM_BACKWARD", "backward" }, + { 0, NULL, NULL } + }; + + static const GimpEnumDesc descs[] = + { + { GIMP_TRANSFORM_FORWARD, NC_("transform-direction", "Normal (Forward)"), NULL }, + { GIMP_TRANSFORM_BACKWARD, NC_("transform-direction", "Corrective (Backward)"), NULL }, + { 0, NULL, NULL } + }; + + static GType type = 0; + + if (G_UNLIKELY (! type)) + { + type = g_enum_register_static ("GimpTransformDirection", values); + gimp_type_set_translation_domain (type, GETTEXT_PACKAGE "-libgimp"); + gimp_type_set_translation_context (type, "transform-direction"); + gimp_enum_set_value_descriptions (type, descs); + } + + return type; +} + +GType +gimp_transform_resize_get_type (void) +{ + static const GEnumValue values[] = + { + { GIMP_TRANSFORM_RESIZE_ADJUST, "GIMP_TRANSFORM_RESIZE_ADJUST", "adjust" }, + { GIMP_TRANSFORM_RESIZE_CLIP, "GIMP_TRANSFORM_RESIZE_CLIP", "clip" }, + { GIMP_TRANSFORM_RESIZE_CROP, "GIMP_TRANSFORM_RESIZE_CROP", "crop" }, + { GIMP_TRANSFORM_RESIZE_CROP_WITH_ASPECT, "GIMP_TRANSFORM_RESIZE_CROP_WITH_ASPECT", "crop-with-aspect" }, + { 0, NULL, NULL } + }; + + static const GimpEnumDesc descs[] = + { + { GIMP_TRANSFORM_RESIZE_ADJUST, NC_("transform-resize", "Adjust"), NULL }, + { GIMP_TRANSFORM_RESIZE_CLIP, NC_("transform-resize", "Clip"), NULL }, + { GIMP_TRANSFORM_RESIZE_CROP, NC_("transform-resize", "Crop to result"), NULL }, + { GIMP_TRANSFORM_RESIZE_CROP_WITH_ASPECT, NC_("transform-resize", "Crop with aspect"), NULL }, + { 0, NULL, NULL } + }; + + static GType type = 0; + + if (G_UNLIKELY (! type)) + { + type = g_enum_register_static ("GimpTransformResize", values); + gimp_type_set_translation_domain (type, GETTEXT_PACKAGE "-libgimp"); + gimp_type_set_translation_context (type, "transform-resize"); + gimp_enum_set_value_descriptions (type, descs); + } + + return type; +} + +GType +gimp_user_directory_get_type (void) +{ + static const GEnumValue values[] = + { + { GIMP_USER_DIRECTORY_DESKTOP, "GIMP_USER_DIRECTORY_DESKTOP", "desktop" }, + { GIMP_USER_DIRECTORY_DOCUMENTS, "GIMP_USER_DIRECTORY_DOCUMENTS", "documents" }, + { GIMP_USER_DIRECTORY_DOWNLOAD, "GIMP_USER_DIRECTORY_DOWNLOAD", "download" }, + { GIMP_USER_DIRECTORY_MUSIC, "GIMP_USER_DIRECTORY_MUSIC", "music" }, + { GIMP_USER_DIRECTORY_PICTURES, "GIMP_USER_DIRECTORY_PICTURES", "pictures" }, + { GIMP_USER_DIRECTORY_PUBLIC_SHARE, "GIMP_USER_DIRECTORY_PUBLIC_SHARE", "public-share" }, + { GIMP_USER_DIRECTORY_TEMPLATES, "GIMP_USER_DIRECTORY_TEMPLATES", "templates" }, + { GIMP_USER_DIRECTORY_VIDEOS, "GIMP_USER_DIRECTORY_VIDEOS", "videos" }, + { 0, NULL, NULL } + }; + + static const GimpEnumDesc descs[] = + { + { GIMP_USER_DIRECTORY_DESKTOP, "GIMP_USER_DIRECTORY_DESKTOP", NULL }, + { GIMP_USER_DIRECTORY_DOCUMENTS, "GIMP_USER_DIRECTORY_DOCUMENTS", NULL }, + { GIMP_USER_DIRECTORY_DOWNLOAD, "GIMP_USER_DIRECTORY_DOWNLOAD", NULL }, + { GIMP_USER_DIRECTORY_MUSIC, "GIMP_USER_DIRECTORY_MUSIC", NULL }, + { GIMP_USER_DIRECTORY_PICTURES, "GIMP_USER_DIRECTORY_PICTURES", NULL }, + { GIMP_USER_DIRECTORY_PUBLIC_SHARE, "GIMP_USER_DIRECTORY_PUBLIC_SHARE", NULL }, + { GIMP_USER_DIRECTORY_TEMPLATES, "GIMP_USER_DIRECTORY_TEMPLATES", NULL }, + { GIMP_USER_DIRECTORY_VIDEOS, "GIMP_USER_DIRECTORY_VIDEOS", NULL }, + { 0, NULL, NULL } + }; + + static GType type = 0; + + if (G_UNLIKELY (! type)) + { + type = g_enum_register_static ("GimpUserDirectory", values); + gimp_type_set_translation_domain (type, GETTEXT_PACKAGE "-libgimp"); + gimp_type_set_translation_context (type, "user-directory"); + gimp_enum_set_value_descriptions (type, descs); + } + + return type; +} + +GType +gimp_vectors_stroke_type_get_type (void) +{ + static const GEnumValue values[] = + { + { GIMP_VECTORS_STROKE_TYPE_BEZIER, "GIMP_VECTORS_STROKE_TYPE_BEZIER", "bezier" }, + { 0, NULL, NULL } + }; + + static const GimpEnumDesc descs[] = + { + { GIMP_VECTORS_STROKE_TYPE_BEZIER, "GIMP_VECTORS_STROKE_TYPE_BEZIER", NULL }, + { 0, NULL, NULL } + }; + + static GType type = 0; + + if (G_UNLIKELY (! type)) + { + type = g_enum_register_static ("GimpVectorsStrokeType", values); + gimp_type_set_translation_domain (type, GETTEXT_PACKAGE "-libgimp"); + gimp_type_set_translation_context (type, "vectors-stroke-type"); + gimp_enum_set_value_descriptions (type, descs); + } + + return type; +} + + +/* Generated data ends here */ + diff --git a/libgimpbase/gimpbaseenums.h b/libgimpbase/gimpbaseenums.h new file mode 100644 index 0000000..b3c6fb7 --- /dev/null +++ b/libgimpbase/gimpbaseenums.h @@ -0,0 +1,1558 @@ +/* LIBGIMP - The GIMP Library + * Copyright (C) 1995-1997 Peter Mattis and Spencer Kimball + * + * This library is free software: you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This library 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see + * <https://www.gnu.org/licenses/>. + */ + +#ifndef __GIMP_BASE_ENUMS_H__ +#define __GIMP_BASE_ENUMS_H__ + + +/** + * SECTION: gimpbaseenums + * @title: gimpbaseenums + * @short_description: Basic GIMP enumeration data types. + * + * Basic GIMP enumeration data types. + **/ + + +G_BEGIN_DECLS + +/* For information look into the C source or the html documentation */ + + +/** + * GimpAddMaskType: + * @GIMP_ADD_MASK_WHITE: White (full opacity) + * @GIMP_ADD_MASK_BLACK: Black (full transparency) + * @GIMP_ADD_MASK_ALPHA: Layer's alpha channel + * @GIMP_ADD_MASK_ALPHA_TRANSFER: Transfer layer's alpha channel + * @GIMP_ADD_MASK_SELECTION: Selection + * @GIMP_ADD_MASK_COPY: Grayscale copy of layer + * @GIMP_ADD_MASK_CHANNEL: Channel + * @GIMP_ADD_WHITE_MASK: Deprecated alias for @GIMP_ADD_MASK_WHITE + * @GIMP_ADD_BLACK_MASK: Deprecated alias for @GIMP_ADD_MASK_BLACK + * @GIMP_ADD_ALPHA_MASK: Deprecated alias for @GIMP_ADD_MASK_ALPHA + * @GIMP_ADD_ALPHA_TRANSFER_MASK: Deprecated alias for + * @GIMP_ADD_MASK_ALPHA_TRANSFER + * @GIMP_ADD_SELECTION_MASK: Deprecated alias for @GIMP_ADD_MASK_SELECTION + * @GIMP_ADD_COPY_MASK: Deprecated alias for @GIMP_ADD_MASK_COPY + * @GIMP_ADD_CHANNEL_MASK: Deprecated aliaa for @GIMP_ADD_MASK_CHANNEL + * + * Modes of initialising a layer mask. + **/ +#define GIMP_TYPE_ADD_MASK_TYPE (gimp_add_mask_type_get_type ()) + +GType gimp_add_mask_type_get_type (void) G_GNUC_CONST; + +typedef enum +{ + GIMP_ADD_MASK_WHITE, /*< desc="_White (full opacity)" >*/ + GIMP_ADD_MASK_BLACK, /*< desc="_Black (full transparency)" >*/ + GIMP_ADD_MASK_ALPHA, /*< desc="Layer's _alpha channel" >*/ + GIMP_ADD_MASK_ALPHA_TRANSFER, /*< desc="_Transfer layer's alpha channel" >*/ + GIMP_ADD_MASK_SELECTION, /*< desc="_Selection" >*/ + GIMP_ADD_MASK_COPY, /*< desc="_Grayscale copy of layer" >*/ + GIMP_ADD_MASK_CHANNEL, /*< desc="C_hannel" >*/ + +#ifndef GIMP_DISABLE_DEPRECATED + GIMP_ADD_WHITE_MASK = GIMP_ADD_MASK_WHITE, /*< skip, pdb-skip >*/ + GIMP_ADD_BLACK_MASK = GIMP_ADD_MASK_BLACK, /*< skip, pdb-skip >*/ + GIMP_ADD_ALPHA_MASK = GIMP_ADD_MASK_ALPHA, /*< skip, pdb-skip >*/ + GIMP_ADD_ALPHA_TRANSFER_MASK = GIMP_ADD_MASK_ALPHA_TRANSFER, /*< skip, pdb-skip >*/ + GIMP_ADD_SELECTION_MASK = GIMP_ADD_MASK_SELECTION, /*< skip, pdb-skip >*/ + GIMP_ADD_COPY_MASK = GIMP_ADD_MASK_COPY, /*< skip, pdb-skip >*/ + GIMP_ADD_CHANNEL_MASK = GIMP_ADD_MASK_CHANNEL /*< skip, pdb-skip >*/ +#endif /* GIMP_DISABLE_DEPRECATED */ +} GimpAddMaskType; + + +/** + * GimpBlendMode: + * @GIMP_BLEND_FG_BG_RGB: FG to BG (RGB) + * @GIMP_BLEND_FG_BG_HSV: FG to BG (HSV) + * @GIMP_BLEND_FG_TRANSPARENT: FG to transparent + * @GIMP_BLEND_CUSTOM: Custom gradient + * @GIMP_FG_BG_RGB_MODE: Deprecated alias for @GIMP_BLEND_FG_BG_RGB + * @GIMP_FG_BG_HSV_MODE: Deprecated alias for @GIMP_BLEND_FG_BG_HSV + * @GIMP_FG_TRANSPARENT_MODE: Deprecated alias for @GIMP_BLEND_FG_TRANSPARENT + * @GIMP_CUSTOM_MODE: Deprecated alias for @GIMP_BLEND_CUSTOM + * + * Types of gradients. + **/ +#define GIMP_TYPE_BLEND_MODE (gimp_blend_mode_get_type ()) + +GType gimp_blend_mode_get_type (void) G_GNUC_CONST; + +typedef enum +{ + GIMP_BLEND_FG_BG_RGB, /*< desc="FG to BG (RGB)" >*/ + GIMP_BLEND_FG_BG_HSV, /*< desc="FG to BG (HSV)" >*/ + GIMP_BLEND_FG_TRANSPARENT, /*< desc="FG to transparent" >*/ + GIMP_BLEND_CUSTOM, /*< desc="Custom gradient" >*/ + +#ifndef GIMP_DISABLE_DEPRECATED + GIMP_FG_BG_RGB_MODE = GIMP_BLEND_FG_BG_RGB, /*< skip, pdb-skip >*/ + GIMP_FG_BG_HSV_MODE = GIMP_BLEND_FG_BG_HSV, /*< skip, pdb-skip >*/ + GIMP_FG_TRANSPARENT_MODE = GIMP_BLEND_FG_TRANSPARENT, /*< skip, pdb-skip >*/ + GIMP_CUSTOM_MODE = GIMP_BLEND_CUSTOM /*< skip, pdb-skip >*/ +#endif /* GIMP_DISABLE_DEPRECATED */ +} GimpBlendMode; + + +/** + * GimpBrushGeneratedShape: + * @GIMP_BRUSH_GENERATED_CIRCLE: Circle + * @GIMP_BRUSH_GENERATED_SQUARE: Square + * @GIMP_BRUSH_GENERATED_DIAMOND: Diamond + * + * Shapes of generated brushes. + **/ +#define GIMP_TYPE_BRUSH_GENERATED_SHAPE (gimp_brush_generated_shape_get_type ()) + +GType gimp_brush_generated_shape_get_type (void) G_GNUC_CONST; + +typedef enum +{ + GIMP_BRUSH_GENERATED_CIRCLE, /*< desc="Circle" >*/ + GIMP_BRUSH_GENERATED_SQUARE, /*< desc="Square" >*/ + GIMP_BRUSH_GENERATED_DIAMOND /*< desc="Diamond" >*/ +} GimpBrushGeneratedShape; + + +/** + * GimpBucketFillMode: + * @GIMP_BUCKET_FILL_FG: FG color fill + * @GIMP_BUCKET_FILL_BG: BG color fill + * @GIMP_BUCKET_FILL_PATTERN: Pattern fill + * @GIMP_FG_BUCKET_FILL: Deprecated alias for @GIMP_BUCKET_FILL_FG + * @GIMP_BG_BUCKET_FILL: Deprecated alias for @GIMP_BUCKET_FILL_BG + * @GIMP_PATTERN_BUCKET_FILL: Deprecated alias for @GIMP_BUCKET_FILL_PATTERN + * + * Bucket fill modes. + */ +#define GIMP_TYPE_BUCKET_FILL_MODE (gimp_bucket_fill_mode_get_type ()) + +GType gimp_bucket_fill_mode_get_type (void) G_GNUC_CONST; + +typedef enum +{ + GIMP_BUCKET_FILL_FG, /*< desc="FG color fill" >*/ + GIMP_BUCKET_FILL_BG, /*< desc="BG color fill" >*/ + GIMP_BUCKET_FILL_PATTERN, /*< desc="Pattern fill" >*/ + +#ifndef GIMP_DISABLE_DEPRECATED + GIMP_FG_BUCKET_FILL = GIMP_BUCKET_FILL_FG, /*< skip, pdb-skip >*/ + GIMP_BG_BUCKET_FILL = GIMP_BUCKET_FILL_BG, /*< skip, pdb-skip >*/ + GIMP_PATTERN_BUCKET_FILL = GIMP_BUCKET_FILL_PATTERN /*< skip, pdb-skip >*/ +#endif /* GIMP_DISABLE_DEPRECATED */ +} GimpBucketFillMode; + + +/** + * GimpCapStyle: + * @GIMP_CAP_BUTT: Butt + * @GIMP_CAP_ROUND: Round + * @GIMP_CAP_SQUARE: Square + * + * Style of line endings. + **/ +#define GIMP_TYPE_CAP_STYLE (gimp_cap_style_get_type ()) + +GType gimp_cap_style_get_type (void) G_GNUC_CONST; + +typedef enum +{ + GIMP_CAP_BUTT, /*< desc="Butt" >*/ + GIMP_CAP_ROUND, /*< desc="Round" >*/ + GIMP_CAP_SQUARE /*< desc="Square" >*/ +} GimpCapStyle; + + +/** + * GimpChannelOps: + * @GIMP_CHANNEL_OP_ADD: Add to the current selection + * @GIMP_CHANNEL_OP_SUBTRACT: Subtract from the current selection + * @GIMP_CHANNEL_OP_REPLACE: Replace the current selection + * @GIMP_CHANNEL_OP_INTERSECT: Intersect with the current selection + * + * Operations to combine channels and selections. + **/ +#define GIMP_TYPE_CHANNEL_OPS (gimp_channel_ops_get_type ()) + +GType gimp_channel_ops_get_type (void) G_GNUC_CONST; + +typedef enum +{ + GIMP_CHANNEL_OP_ADD, /*< desc="Add to the current selection" >*/ + GIMP_CHANNEL_OP_SUBTRACT, /*< desc="Subtract from the current selection" >*/ + GIMP_CHANNEL_OP_REPLACE, /*< desc="Replace the current selection" >*/ + GIMP_CHANNEL_OP_INTERSECT /*< desc="Intersect with the current selection" >*/ +} GimpChannelOps; + + +/** + * GimpChannelType: + * @GIMP_CHANNEL_RED: Red + * @GIMP_CHANNEL_GREEN: Green + * @GIMP_CHANNEL_BLUE: Blue + * @GIMP_CHANNEL_GRAY: Gray + * @GIMP_CHANNEL_INDEXED: Indexed + * @GIMP_CHANNEL_ALPHA: Alpha + * @GIMP_RED_CHANNEL: Deprecated alias for @GIMP_CHANNEL_RED + * @GIMP_GREEN_CHANNEL: Deprecated alias for @GIMP_CHANNEL_GREEN + * @GIMP_BLUE_CHANNEL: Deprecated alias for @GIMP_CHANNEL_BLUE + * @GIMP_GRAY_CHANNEL: Deprecated alias for @GIMP_CHANNEL_GRAY + * @GIMP_INDEXED_CHANNEL: Deprecated alias for @GIMP_CHANNEL_INDEXED + * @GIMP_ALPHA_CHANNEL: Deprecated alias for @GIMP_CHANNEL_ALPHA + * + * Channels (as in color components). + **/ +#define GIMP_TYPE_CHANNEL_TYPE (gimp_channel_type_get_type ()) + +GType gimp_channel_type_get_type (void) G_GNUC_CONST; + +typedef enum +{ + GIMP_CHANNEL_RED, /*< desc="Red" >*/ + GIMP_CHANNEL_GREEN, /*< desc="Green" >*/ + GIMP_CHANNEL_BLUE, /*< desc="Blue" >*/ + GIMP_CHANNEL_GRAY, /*< desc="Gray" >*/ + GIMP_CHANNEL_INDEXED, /*< desc="Indexed" >*/ + GIMP_CHANNEL_ALPHA, /*< desc="Alpha" >*/ + +#ifndef GIMP_DISABLE_DEPRECATED + GIMP_RED_CHANNEL = GIMP_CHANNEL_RED, /*< skip, pdb-skip >*/ + GIMP_GREEN_CHANNEL = GIMP_CHANNEL_GREEN, /*< skip, pdb-skip >*/ + GIMP_BLUE_CHANNEL = GIMP_CHANNEL_BLUE, /*< skip, pdb-skip >*/ + GIMP_GRAY_CHANNEL = GIMP_CHANNEL_GRAY, /*< skip, pdb-skip >*/ + GIMP_INDEXED_CHANNEL = GIMP_CHANNEL_INDEXED, /*< skip, pdb-skip >*/ + GIMP_ALPHA_CHANNEL = GIMP_CHANNEL_ALPHA /*< skip, pdb-skip >*/ +#endif /* GIMP_DISABLE_DEPRECATED */ +} GimpChannelType; + + +/** + * GimpCheckSize: + * @GIMP_CHECK_SIZE_SMALL_CHECKS: Small + * @GIMP_CHECK_SIZE_MEDIUM_CHECKS: Medium + * @GIMP_CHECK_SIZE_LARGE_CHECKS: Large + * + * Size of the checkerboard indicating transparency. + **/ +#define GIMP_TYPE_CHECK_SIZE (gimp_check_size_get_type ()) + +GType gimp_check_size_get_type (void) G_GNUC_CONST; + +typedef enum /*< pdb-skip >*/ +{ + GIMP_CHECK_SIZE_SMALL_CHECKS = 0, /*< desc="Small" >*/ + GIMP_CHECK_SIZE_MEDIUM_CHECKS = 1, /*< desc="Medium" >*/ + GIMP_CHECK_SIZE_LARGE_CHECKS = 2 /*< desc="Large" >*/ +} GimpCheckSize; + + +/** + * GimpCheckType: + * @GIMP_CHECK_TYPE_LIGHT_CHECKS: Light checks + * @GIMP_CHECK_TYPE_GRAY_CHECKS: Mid-tone checks + * @GIMP_CHECK_TYPE_DARK_CHECKS: Dark checks + * @GIMP_CHECK_TYPE_WHITE_ONLY: White only + * @GIMP_CHECK_TYPE_GRAY_ONLY: Gray only + * @GIMP_CHECK_TYPE_BLACK_ONLY: Black only + * + * Color/Brightness of the checkerboard indicating transparency. + **/ +#define GIMP_TYPE_CHECK_TYPE (gimp_check_type_get_type ()) + +GType gimp_check_type_get_type (void) G_GNUC_CONST; + +typedef enum /*< pdb-skip >*/ +{ + GIMP_CHECK_TYPE_LIGHT_CHECKS = 0, /*< desc="Light checks" >*/ + GIMP_CHECK_TYPE_GRAY_CHECKS = 1, /*< desc="Mid-tone checks" >*/ + GIMP_CHECK_TYPE_DARK_CHECKS = 2, /*< desc="Dark checks" >*/ + GIMP_CHECK_TYPE_WHITE_ONLY = 3, /*< desc="White only" >*/ + GIMP_CHECK_TYPE_GRAY_ONLY = 4, /*< desc="Gray only" >*/ + GIMP_CHECK_TYPE_BLACK_ONLY = 5 /*< desc="Black only" >*/ +} GimpCheckType; + + +/** + * GimpCloneType: + * @GIMP_CLONE_IMAGE: Clone from an image/drawable source + * @GIMP_CLONE_PATTERN: Clone from a pattern source + * @GIMP_IMAGE_CLONE: Deprecated alias for @GIMP_CLONE_IMAGE + * @GIMP_PATTERN_CLONE: Deprecated alias for @GIMP_CLONE_PATTERN + * + * Clone sources. + **/ +#define GIMP_TYPE_CLONE_TYPE (gimp_clone_type_get_type ()) + +GType gimp_clone_type_get_type (void) G_GNUC_CONST; + +typedef enum +{ + GIMP_CLONE_IMAGE, /*< desc="Image" >*/ + GIMP_CLONE_PATTERN, /*< desc="Pattern" >*/ + +#ifndef GIMP_DISABLE_DEPRECATED + GIMP_IMAGE_CLONE = GIMP_CLONE_IMAGE, /*< skip, pdb-skip >*/ + GIMP_PATTERN_CLONE = GIMP_CLONE_PATTERN /*< skip, pdb-skip >*/ +#endif /* GIMP_DISABLE_DEPRECATED */ +} GimpCloneType; + + +/** + * GimpColorTag: + * @GIMP_COLOR_TAG_NONE: None + * @GIMP_COLOR_TAG_BLUE: Blue + * @GIMP_COLOR_TAG_GREEN: Green + * @GIMP_COLOR_TAG_YELLOW: Yellow + * @GIMP_COLOR_TAG_ORANGE: Orange + * @GIMP_COLOR_TAG_BROWN: Brown + * @GIMP_COLOR_TAG_RED: Red + * @GIMP_COLOR_TAG_VIOLET: Violet + * @GIMP_COLOR_TAG_GRAY: Gray + * + * Possible tag colors. + * + * Since: 2.10 + **/ +#define GIMP_TYPE_COLOR_TAG (gimp_color_tag_get_type ()) + +GType gimp_color_tag_get_type (void) G_GNUC_CONST; + +typedef enum +{ + GIMP_COLOR_TAG_NONE, /*< desc="None" >*/ + GIMP_COLOR_TAG_BLUE, /*< desc="Blue" >*/ + GIMP_COLOR_TAG_GREEN, /*< desc="Green" >*/ + GIMP_COLOR_TAG_YELLOW, /*< desc="Yellow" >*/ + GIMP_COLOR_TAG_ORANGE, /*< desc="Orange" >*/ + GIMP_COLOR_TAG_BROWN, /*< desc="Brown" >*/ + GIMP_COLOR_TAG_RED, /*< desc="Red" >*/ + GIMP_COLOR_TAG_VIOLET, /*< desc="Violet" >*/ + GIMP_COLOR_TAG_GRAY /*< desc="Gray" >*/ +} GimpColorTag; + + +/** + * GimpComponentType: + * @GIMP_COMPONENT_TYPE_U8: 8-bit integer + * @GIMP_COMPONENT_TYPE_U16: 16-bit integer + * @GIMP_COMPONENT_TYPE_U32: 32-bit integer + * @GIMP_COMPONENT_TYPE_HALF: 16-bit floating point + * @GIMP_COMPONENT_TYPE_FLOAT: 32-bit floating point + * @GIMP_COMPONENT_TYPE_DOUBLE: 64-bit floating point + * + * Encoding types of image components. + * + * Since: 2.10 + **/ +#define GIMP_TYPE_COMPONENT_TYPE (gimp_component_type_get_type ()) + +GType gimp_component_type_get_type (void) G_GNUC_CONST; + +typedef enum +{ + GIMP_COMPONENT_TYPE_U8 = 100, /*< desc="8-bit integer" >*/ + GIMP_COMPONENT_TYPE_U16 = 200, /*< desc="16-bit integer" >*/ + GIMP_COMPONENT_TYPE_U32 = 300, /*< desc="32-bit integer" >*/ + GIMP_COMPONENT_TYPE_HALF = 500, /*< desc="16-bit floating point" >*/ + GIMP_COMPONENT_TYPE_FLOAT = 600, /*< desc="32-bit floating point" >*/ + GIMP_COMPONENT_TYPE_DOUBLE = 700 /*< desc="64-bit floating point" >*/ +} GimpComponentType; + + +/** + * GimpConvertPaletteType: + * @GIMP_CONVERT_PALETTE_GENERATE: Generate optimum palette + * @GIMP_CONVERT_PALETTE_REUSE: Don't use this one + * @GIMP_CONVERT_PALETTE_WEB: Use web-optimized palette + * @GIMP_CONVERT_PALETTE_MONO: Use black and white (1-bit) palette + * @GIMP_CONVERT_PALETTE_CUSTOM: Use custom palette + * @GIMP_MAKE_PALETTE: Deprecated alias for + * @GIMP_CONVERT_PALETTE_GENERATE + * @GIMP_REUSE_PALETTE: Deprecated alias for + * @GIMP_CONVERT_PALETTE_REUSE + * @GIMP_WEB_PALETTE: Deprecated alias for + * @GIMP_CONVERT_PALETTE_WEB + * @GIMP_MONO_PALETTE: Deprecated alias for + @GIMP_CONVERT_PALETTE_MONO + * @GIMP_CUSTOM_PALETTE: Deprecated alias for + * @GIMP_CONVERT_PALETTE_CUSTOM + * + * Types of palettes for indexed conversion. + **/ +#define GIMP_TYPE_CONVERT_PALETTE_TYPE (gimp_convert_palette_type_get_type ()) + +GType gimp_convert_palette_type_get_type (void) G_GNUC_CONST; + +typedef enum +{ + GIMP_CONVERT_PALETTE_GENERATE, /*< desc="Generate optimum palette" >*/ + GIMP_CONVERT_PALETTE_REUSE, /*< skip >*/ + GIMP_CONVERT_PALETTE_WEB, /*< desc="Use web-optimized palette" >*/ + GIMP_CONVERT_PALETTE_MONO, /*< desc="Use black and white (1-bit) palette" >*/ + GIMP_CONVERT_PALETTE_CUSTOM, /*< desc="Use custom palette" >*/ + +#ifndef GIMP_DISABLE_DEPRECATED + GIMP_MAKE_PALETTE = GIMP_CONVERT_PALETTE_GENERATE, /*< skip, pdb-skip >*/ + GIMP_REUSE_PALETTE = GIMP_CONVERT_PALETTE_REUSE, /*< skip, pdb-skip >*/ + GIMP_WEB_PALETTE = GIMP_CONVERT_PALETTE_WEB, /*< skip, pdb-skip >*/ + GIMP_MONO_PALETTE = GIMP_CONVERT_PALETTE_MONO, /*< skip, pdb-skip >*/ + GIMP_CUSTOM_PALETTE = GIMP_CONVERT_PALETTE_CUSTOM /*< skip, pdb-skip >*/ +#endif /* GIMP_DISABLE_DEPRECATED */ +} GimpConvertPaletteType; + + +/** + * GimpConvolveType: + * @GIMP_CONVOLVE_BLUR: Blur + * @GIMP_CONVOLVE_SHARPEN: Sharpen + * @GIMP_BLUR_CONVOLVE: Deprecated alias for @GIMP_CONVOLVE_BLUR + * @GIMP_SHARPEN_CONVOLVE: Deprecated alias for @GIMP_CONVOLVE_SHARPEN + * + * Types of convolutions. + **/ +#define GIMP_TYPE_CONVOLVE_TYPE (gimp_convolve_type_get_type ()) + +GType gimp_convolve_type_get_type (void) G_GNUC_CONST; + +typedef enum +{ + GIMP_CONVOLVE_BLUR, /*< desc="Blur" >*/ + GIMP_CONVOLVE_SHARPEN, /*< desc="Sharpen" >*/ + +#ifndef GIMP_DISABLE_DEPRECATED + GIMP_BLUR_CONVOLVE = GIMP_CONVOLVE_BLUR, /*< skip, pdb-skip >*/ + GIMP_SHARPEN_CONVOLVE = GIMP_CONVOLVE_SHARPEN /*< skip, pdb-skip >*/ +#endif /* GIMP_DISABLE_DEPRECATED */ +} GimpConvolveType; + + +/** + * GimpDesaturateMode: + * @GIMP_DESATURATE_LIGHTNESS: Lightness (HSL) + * @GIMP_DESATURATE_LUMA: Luma + * @GIMP_DESATURATE_AVERAGE: Average (HSI Intensity) + * @GIMP_DESATURATE_LUMINANCE: Luminance + * @GIMP_DESATURATE_VALUE: Value (HSV) + * @GIMP_DESATURATE_LUMINOSITY: Deprecated alias for @GIMP_DESATURATE_LUMA + * + * Grayscale conversion methods. + **/ +#define GIMP_TYPE_DESATURATE_MODE (gimp_desaturate_mode_get_type ()) + +GType gimp_desaturate_mode_get_type (void) G_GNUC_CONST; + +typedef enum +{ + GIMP_DESATURATE_LIGHTNESS, /*< desc="Lightness (HSL)" >*/ + GIMP_DESATURATE_LUMA, /*< desc="Luma" >*/ + GIMP_DESATURATE_AVERAGE, /*< desc="Average (HSI Intensity)" >*/ + GIMP_DESATURATE_LUMINANCE, /*< desc="Luminance" >*/ + GIMP_DESATURATE_VALUE, /*< desc="Value (HSV)" >*/ + +#ifndef GIMP_DISABLE_DEPRECATED + GIMP_DESATURATE_LUMINOSITY = GIMP_DESATURATE_LUMA /*< skip, pdb-skip >*/ +#endif /* GIMP_DISABLE_DEPRECATED */ +} GimpDesaturateMode; + + +/** + * GimpDodgeBurnType: + * @GIMP_DODGE_BURN_TYPE_DODGE: Dodge + * @GIMP_DODGE_BURN_TYPE_BURN: Burn + * @GIMP_DODGE: Deprecated alias for @GIMP_DODGE_BURN_TYPE_DODGE + * @GIMP_BURN: Deprecated alias for @GIMP_DODGE_BURN_TYPE_BURN + * + * Methods for the dodge/burn operation. + **/ +#define GIMP_TYPE_DODGE_BURN_TYPE (gimp_dodge_burn_type_get_type ()) + +GType gimp_dodge_burn_type_get_type (void) G_GNUC_CONST; + +typedef enum +{ + GIMP_DODGE_BURN_TYPE_DODGE, /*< desc="Dodge" >*/ + GIMP_DODGE_BURN_TYPE_BURN, /*< desc="Burn" >*/ + +#ifndef GIMP_DISABLE_DEPRECATED + GIMP_DODGE = GIMP_DODGE_BURN_TYPE_DODGE, /*< skip, pdb-skip >*/ + GIMP_BURN = GIMP_DODGE_BURN_TYPE_BURN /*< skip, pdb-skip >*/ +#endif /* GIMP_DISABLE_DEPRECATED */ +} GimpDodgeBurnType; + + +/** + * GimpFillType: + * @GIMP_FILL_FOREGROUND: Foreground color + * @GIMP_FILL_BACKGROUND: Background color + * @GIMP_FILL_WHITE: White + * @GIMP_FILL_TRANSPARENT: Transparency + * @GIMP_FILL_PATTERN: Pattern + * @GIMP_FOREGROUND_FILL: Deprecated alias for @GIMP_FILL_FOREGROUND + * @GIMP_BACKGROUND_FILL: Deprecated alias for @GIMP_FILL_BACKGROUND + * @GIMP_WHITE_FILL: Deprecated alias for @GIMP_FILL_WHITE + * @GIMP_TRANSPARENT_FILL: Deprecated alias for @GIMP_FILL_TRANSPARENT + * @GIMP_PATTERN_FILL: Deprecated alias for @GIMP_FILL_PATTERN + * + * Types of filling. + **/ +#define GIMP_TYPE_FILL_TYPE (gimp_fill_type_get_type ()) + +GType gimp_fill_type_get_type (void) G_GNUC_CONST; + +typedef enum +{ + GIMP_FILL_FOREGROUND, /*< desc="Foreground color" >*/ + GIMP_FILL_BACKGROUND, /*< desc="Background color" >*/ + GIMP_FILL_WHITE, /*< desc="White" >*/ + GIMP_FILL_TRANSPARENT, /*< desc="Transparency" >*/ + GIMP_FILL_PATTERN, /*< desc="Pattern" >*/ + +#ifndef GIMP_DISABLE_DEPRECATED + GIMP_FOREGROUND_FILL = GIMP_FILL_FOREGROUND, /*< skip, pdb-skip >*/ + GIMP_BACKGROUND_FILL = GIMP_FILL_BACKGROUND, /*< skip, pdb-skip >*/ + GIMP_WHITE_FILL = GIMP_FILL_WHITE, /*< skip, pdb-skip >*/ + GIMP_TRANSPARENT_FILL = GIMP_FILL_TRANSPARENT, /*< skip, pdb-skip >*/ + GIMP_PATTERN_FILL = GIMP_FILL_PATTERN /*< skip, pdb-skip >*/ +#endif /* GIMP_DISABLE_DEPRECATED */ +} GimpFillType; + + +/** + * GimpForegroundExtractMode: + * @GIMP_FOREGROUND_EXTRACT_SIOX: Siox + * @GIMP_FOREGROUND_EXTRACT_MATTING: Matting (Since 2.10) + * + * Foreground extraxt engines. + **/ +#define GIMP_TYPE_FOREGROUND_EXTRACT_MODE (gimp_foreground_extract_mode_get_type ()) + +GType gimp_foreground_extract_mode_get_type (void) G_GNUC_CONST; + +typedef enum +{ + GIMP_FOREGROUND_EXTRACT_SIOX, + GIMP_FOREGROUND_EXTRACT_MATTING +} GimpForegroundExtractMode; + + +/** + * GimpGradientBlendColorSpace: + * @GIMP_GRADIENT_BLEND_RGB_PERCEPTUAL: Perceptual RGB + * @GIMP_GRADIENT_BLEND_RGB_LINEAR: Linear RGB + * @GIMP_GRADIENT_BLEND_CIE_LAB: CIE Lab + * + * Color space for blending gradients. + * + * Since: 2.10 + */ +#define GIMP_TYPE_GRADIENT_BLEND_COLOR_SPACE (gimp_gradient_blend_color_space_get_type ()) + +GType gimp_gradient_blend_color_space_get_type (void) G_GNUC_CONST; + +typedef enum +{ + GIMP_GRADIENT_BLEND_RGB_PERCEPTUAL, /*< desc="Perceptual RGB", nick=rgb-perceptual >*/ + GIMP_GRADIENT_BLEND_RGB_LINEAR, /*< desc="Linear RGB", nick=rgb-linear >*/ + GIMP_GRADIENT_BLEND_CIE_LAB /*< desc="CIE Lab", nick=cie-lab >*/ +} GimpGradientBlendColorSpace; + + +/** + * GimpGradientSegmentColor: + * @GIMP_GRADIENT_SEGMENT_RGB: RGB + * @GIMP_GRADIENT_SEGMENT_HSV_CCW: HSV (counter-clockwise hue) + * @GIMP_GRADIENT_SEGMENT_HSV_CW: HSV (clockwise hue) + * + * Coloring types for gradient segments. + **/ +#define GIMP_TYPE_GRADIENT_SEGMENT_COLOR (gimp_gradient_segment_color_get_type ()) + +GType gimp_gradient_segment_color_get_type (void) G_GNUC_CONST; + +typedef enum +{ + GIMP_GRADIENT_SEGMENT_RGB, /*< desc="RGB" >*/ + GIMP_GRADIENT_SEGMENT_HSV_CCW, /*< desc="HSV (counter-clockwise hue)", abbrev="HSV (ccw)" >*/ + GIMP_GRADIENT_SEGMENT_HSV_CW /*< desc="HSV (clockwise hue)", abbrev="HSV (cw)" >*/ +} GimpGradientSegmentColor; + + +/** + * GimpGradientSegmentType: + * @GIMP_GRADIENT_SEGMENT_LINEAR: Linear + * @GIMP_GRADIENT_SEGMENT_CURVED: Curved + * @GIMP_GRADIENT_SEGMENT_SINE: Sinusoidal + * @GIMP_GRADIENT_SEGMENT_SPHERE_INCREASING: Spherical (increasing) + * @GIMP_GRADIENT_SEGMENT_SPHERE_DECREASING: Spherical (decreasing) + * @GIMP_GRADIENT_SEGMENT_STEP: Step + * + * Transition functions for gradient segments. + **/ +#define GIMP_TYPE_GRADIENT_SEGMENT_TYPE (gimp_gradient_segment_type_get_type ()) + +GType gimp_gradient_segment_type_get_type (void) G_GNUC_CONST; + +typedef enum +{ + GIMP_GRADIENT_SEGMENT_LINEAR, /*< desc="Linear" >*/ + GIMP_GRADIENT_SEGMENT_CURVED, /*< desc="Curved" >*/ + GIMP_GRADIENT_SEGMENT_SINE, /*< desc="Sinusoidal" >*/ + GIMP_GRADIENT_SEGMENT_SPHERE_INCREASING, /*< desc="Spherical (increasing)", abbrev="Spherical (inc)" >*/ + GIMP_GRADIENT_SEGMENT_SPHERE_DECREASING, /*< desc="Spherical (decreasing)", abbrev="Spherical (dec)" >*/ + GIMP_GRADIENT_SEGMENT_STEP /*< desc="Step" >*/ +} GimpGradientSegmentType; + + +/** + * GimpGradientType: + * @GIMP_GRADIENT_LINEAR: Linear + * @GIMP_GRADIENT_BILINEAR: Bi-linear + * @GIMP_GRADIENT_RADIAL: Radial + * @GIMP_GRADIENT_SQUARE: Square + * @GIMP_GRADIENT_CONICAL_SYMMETRIC: Conical (symmetric) + * @GIMP_GRADIENT_CONICAL_ASYMMETRIC: Conical (asymmetric) + * @GIMP_GRADIENT_SHAPEBURST_ANGULAR: Shaped (angular) + * @GIMP_GRADIENT_SHAPEBURST_SPHERICAL: Shaped (spherical) + * @GIMP_GRADIENT_SHAPEBURST_DIMPLED: Shaped (dimpled) + * @GIMP_GRADIENT_SPIRAL_CLOCKWISE: Spiral (clockwise) + * @GIMP_GRADIENT_SPIRAL_ANTICLOCKWISE: Spiral (counter-clockwise) + * + * Gradient shapes. + **/ +#define GIMP_TYPE_GRADIENT_TYPE (gimp_gradient_type_get_type ()) + +GType gimp_gradient_type_get_type (void) G_GNUC_CONST; + +typedef enum +{ + GIMP_GRADIENT_LINEAR, /*< desc="Linear" >*/ + GIMP_GRADIENT_BILINEAR, /*< desc="Bi-linear" >*/ + GIMP_GRADIENT_RADIAL, /*< desc="Radial" >*/ + GIMP_GRADIENT_SQUARE, /*< desc="Square" >*/ + GIMP_GRADIENT_CONICAL_SYMMETRIC, /*< desc="Conical (symmetric)", abbrev="Conical (sym)" >*/ + GIMP_GRADIENT_CONICAL_ASYMMETRIC, /*< desc="Conical (asymmetric)", abbrev="Conical (asym)" >*/ + GIMP_GRADIENT_SHAPEBURST_ANGULAR, /*< desc="Shaped (angular)" >*/ + GIMP_GRADIENT_SHAPEBURST_SPHERICAL, /*< desc="Shaped (spherical)" >*/ + GIMP_GRADIENT_SHAPEBURST_DIMPLED, /*< desc="Shaped (dimpled)" >*/ + GIMP_GRADIENT_SPIRAL_CLOCKWISE, /*< desc="Spiral (clockwise)", abbrev="Spiral (cw)" >*/ + GIMP_GRADIENT_SPIRAL_ANTICLOCKWISE /*< desc="Spiral (counter-clockwise)", abbrev="Spiral (ccw)" >*/ +} GimpGradientType; + + +/** + * GimpGridStyle: + * @GIMP_GRID_DOTS: Intersections (dots) + * @GIMP_GRID_INTERSECTIONS: Intersections (crosshairs) + * @GIMP_GRID_ON_OFF_DASH: Dashed + * @GIMP_GRID_DOUBLE_DASH: Double dashed + * @GIMP_GRID_SOLID: Solid + * + * Rendering types for the display grid. + **/ +#define GIMP_TYPE_GRID_STYLE (gimp_grid_style_get_type ()) + +GType gimp_grid_style_get_type (void) G_GNUC_CONST; + +typedef enum +{ + GIMP_GRID_DOTS, /*< desc="Intersections (dots)" >*/ + GIMP_GRID_INTERSECTIONS, /*< desc="Intersections (crosshairs)" >*/ + GIMP_GRID_ON_OFF_DASH, /*< desc="Dashed" >*/ + GIMP_GRID_DOUBLE_DASH, /*< desc="Double dashed" >*/ + GIMP_GRID_SOLID /*< desc="Solid" >*/ +} GimpGridStyle; + + +/** + * GimpHueRange: + * @GIMP_HUE_RANGE_ALL: All hues + * @GIMP_HUE_RANGE_RED: Red hues + * @GIMP_HUE_RANGE_YELLOW: Yellow hues + * @GIMP_HUE_RANGE_GREEN: Green hues + * @GIMP_HUE_RANGE_CYAN: Cyan hues + * @GIMP_HUE_RANGE_BLUE: Blue hues + * @GIMP_HUE_RANGE_MAGENTA: Magenta hues + * @GIMP_ALL_HUES: Deprecated alias for @GIMP_HUE_RANGE_ALL + * @GIMP_RED_HUES: Deprecated alias for @GIMP_HUE_RANGE_RED + * @GIMP_YELLOW_HUES: Deprecated alias for @GIMP_HUE_RANGE_YELLOW + * @GIMP_GREEN_HUES: Deprecated alias for @GIMP_HUE_RANGE_GREEN + * @GIMP_CYAN_HUES: Deprecated alias for @GIMP_HUE_RANGE_CYAN + * @GIMP_BLUE_HUES: Deprecated alias for @GIMP_HUE_RANGE_BLUE + * @GIMP_MAGENTA_HUES: Deprecated alias for @GIMP_HUE_RANGE_MAGENTA + * + * Hue ranges. + **/ +#define GIMP_TYPE_HUE_RANGE (gimp_hue_range_get_type ()) + +GType gimp_hue_range_get_type (void) G_GNUC_CONST; + +typedef enum +{ + GIMP_HUE_RANGE_ALL, + GIMP_HUE_RANGE_RED, + GIMP_HUE_RANGE_YELLOW, + GIMP_HUE_RANGE_GREEN, + GIMP_HUE_RANGE_CYAN, + GIMP_HUE_RANGE_BLUE, + GIMP_HUE_RANGE_MAGENTA, + +#ifndef GIMP_DISABLE_DEPRECATED + GIMP_ALL_HUES = GIMP_HUE_RANGE_ALL, /*< skip, pdb-skip >*/ + GIMP_RED_HUES = GIMP_HUE_RANGE_RED, /*< skip, pdb-skip >*/ + GIMP_YELLOW_HUES = GIMP_HUE_RANGE_YELLOW, /*< skip, pdb-skip >*/ + GIMP_GREEN_HUES = GIMP_HUE_RANGE_GREEN, /*< skip, pdb-skip >*/ + GIMP_CYAN_HUES = GIMP_HUE_RANGE_CYAN, /*< skip, pdb-skip >*/ + GIMP_BLUE_HUES = GIMP_HUE_RANGE_BLUE, /*< skip, pdb-skip >*/ + GIMP_MAGENTA_HUES = GIMP_HUE_RANGE_MAGENTA /*< skip, pdb-skip >*/ +#endif /* GIMP_DISABLE_DEPRECATED */ +} GimpHueRange; + + +/** + * GimpIconType: + * @GIMP_ICON_TYPE_ICON_NAME: Icon name + * @GIMP_ICON_TYPE_INLINE_PIXBUF: Inline pixbuf + * @GIMP_ICON_TYPE_IMAGE_FILE: Image file + * @GIMP_ICON_TYPE_STOCK_ID: Deprecated alias for + * @GIMP_ICON_TYPE_ICON_NAME, old stock IDs + * are interpreted as icon names + * + * Icon types for plug-ins to register. + **/ +#define GIMP_TYPE_ICON_TYPE (gimp_icon_type_get_type ()) + +GType gimp_icon_type_get_type (void) G_GNUC_CONST; + +typedef enum +{ + GIMP_ICON_TYPE_ICON_NAME, /*< desc="Icon name" >*/ + GIMP_ICON_TYPE_INLINE_PIXBUF, /*< desc="Inline pixbuf" >*/ + GIMP_ICON_TYPE_IMAGE_FILE, /*< desc="Image file" >*/ + +#ifndef GIMP_DISABLE_DEPRECATED + GIMP_ICON_TYPE_STOCK_ID = GIMP_ICON_TYPE_ICON_NAME /*< skip, pdb-skip >*/ +#endif /* GIMP_DISABLE_DEPRECATED */ +} GimpIconType; + + +/** + * GimpImageBaseType: + * @GIMP_RGB: RGB color + * @GIMP_GRAY: Grayscale + * @GIMP_INDEXED: Indexed color + * + * Image color models. + **/ +#define GIMP_TYPE_IMAGE_BASE_TYPE (gimp_image_base_type_get_type ()) + +GType gimp_image_base_type_get_type (void) G_GNUC_CONST; + +typedef enum +{ + GIMP_RGB, /*< desc="RGB color" >*/ + GIMP_GRAY, /*< desc="Grayscale" >*/ + GIMP_INDEXED /*< desc="Indexed color" >*/ +} GimpImageBaseType; + + +/** + * GimpImageType: + * @GIMP_RGB_IMAGE: RGB + * @GIMP_RGBA_IMAGE: RGB-alpha + * @GIMP_GRAY_IMAGE: Grayscale + * @GIMP_GRAYA_IMAGE: Grayscale-alpha + * @GIMP_INDEXED_IMAGE: Indexed + * @GIMP_INDEXEDA_IMAGE: Indexed-alpha + * + * Possible drawable types. + **/ +#define GIMP_TYPE_IMAGE_TYPE (gimp_image_type_get_type ()) + +GType gimp_image_type_get_type (void) G_GNUC_CONST; + +typedef enum +{ + GIMP_RGB_IMAGE, /*< desc="RGB" >*/ + GIMP_RGBA_IMAGE, /*< desc="RGB-alpha" >*/ + GIMP_GRAY_IMAGE, /*< desc="Grayscale" >*/ + GIMP_GRAYA_IMAGE, /*< desc="Grayscale-alpha" >*/ + GIMP_INDEXED_IMAGE, /*< desc="Indexed" >*/ + GIMP_INDEXEDA_IMAGE /*< desc="Indexed-alpha" >*/ +} GimpImageType; + + +/** + * GimpInkBlobType: + * @GIMP_INK_BLOB_TYPE_CIRCLE: Circle + * @GIMP_INK_BLOB_TYPE_SQUARE: Square + * @GIMP_INK_BLOB_TYPE_DIAMOND: Diamond + * + * Ink tool tips. + **/ +#define GIMP_TYPE_INK_BLOB_TYPE (gimp_ink_blob_type_get_type ()) + +GType gimp_ink_blob_type_get_type (void) G_GNUC_CONST; + +typedef enum +{ + GIMP_INK_BLOB_TYPE_CIRCLE, /*< desc="Circle" >*/ + GIMP_INK_BLOB_TYPE_SQUARE, /*< desc="Square" >*/ + GIMP_INK_BLOB_TYPE_DIAMOND /*< desc="Diamond" >*/ +} GimpInkBlobType; + + +/** + * GimpInterpolationType: + * @GIMP_INTERPOLATION_NONE: None + * @GIMP_INTERPOLATION_LINEAR: Linear + * @GIMP_INTERPOLATION_CUBIC: Cubic + * @GIMP_INTERPOLATION_NOHALO: NoHalo + * @GIMP_INTERPOLATION_LOHALO: LoHalo + * @GIMP_INTERPOLATION_LANCZOS: Deprecated alias for @GIMP_INTERPOLATION_NOHALO + * + * Interpolation types. + **/ +#define GIMP_TYPE_INTERPOLATION_TYPE (gimp_interpolation_type_get_type ()) + +GType gimp_interpolation_type_get_type (void) G_GNUC_CONST; + +typedef enum +{ + GIMP_INTERPOLATION_NONE, /*< desc="None" >*/ + GIMP_INTERPOLATION_LINEAR, /*< desc="Linear" >*/ + GIMP_INTERPOLATION_CUBIC, /*< desc="Cubic" >*/ + GIMP_INTERPOLATION_NOHALO, /*< desc="NoHalo" >*/ + GIMP_INTERPOLATION_LOHALO, /*< desc="LoHalo" >*/ + +#ifndef GIMP_DISABLE_DEPRECATED + GIMP_INTERPOLATION_LANCZOS = GIMP_INTERPOLATION_NOHALO /*< skip, pdb-skip >*/ +#endif /* GIMP_DISABLE_DEPRECATED */ +} GimpInterpolationType; + + +/** + * GimpJoinStyle: + * @GIMP_JOIN_MITER: Miter + * @GIMP_JOIN_ROUND: Round + * @GIMP_JOIN_BEVEL: Bevel + * + * Line join styles. + **/ +#define GIMP_TYPE_JOIN_STYLE (gimp_join_style_get_type ()) + +GType gimp_join_style_get_type (void) G_GNUC_CONST; + +typedef enum +{ + GIMP_JOIN_MITER, /*< desc="Miter" >*/ + GIMP_JOIN_ROUND, /*< desc="Round" >*/ + GIMP_JOIN_BEVEL /*< desc="Bevel" >*/ +} GimpJoinStyle; + + +/** + * GimpMaskApplyMode: + * @GIMP_MASK_APPLY: Apply the mask + * @GIMP_MASK_DISCARD: Discard the mask + * + * Layer mask apply modes. + **/ +#define GIMP_TYPE_MASK_APPLY_MODE (gimp_mask_apply_mode_get_type ()) + +GType gimp_mask_apply_mode_get_type (void) G_GNUC_CONST; + +typedef enum +{ + GIMP_MASK_APPLY, + GIMP_MASK_DISCARD +} GimpMaskApplyMode; + + +/** + * GimpMergeType: + * @GIMP_EXPAND_AS_NECESSARY: Expanded as necessary + * @GIMP_CLIP_TO_IMAGE: Clipped to image + * @GIMP_CLIP_TO_BOTTOM_LAYER: Clipped to bottom layer + * @GIMP_FLATTEN_IMAGE: Flatten + * + * Types of merging layers. + **/ +#define GIMP_TYPE_MERGE_TYPE (gimp_merge_type_get_type ()) + +GType gimp_merge_type_get_type (void) G_GNUC_CONST; + +typedef enum +{ + GIMP_EXPAND_AS_NECESSARY, /*< desc="Expanded as necessary" >*/ + GIMP_CLIP_TO_IMAGE, /*< desc="Clipped to image" >*/ + GIMP_CLIP_TO_BOTTOM_LAYER, /*< desc="Clipped to bottom layer" >*/ + GIMP_FLATTEN_IMAGE /*< desc="Flatten" >*/ +} GimpMergeType; + + +/** + * GimpMessageHandlerType: + * @GIMP_MESSAGE_BOX: A popup dialog + * @GIMP_CONSOLE: The terminal + * @GIMP_ERROR_CONSOLE: The error console dockable + * + * How to present messages. + **/ +#define GIMP_TYPE_MESSAGE_HANDLER_TYPE (gimp_message_handler_type_get_type ()) + +GType gimp_message_handler_type_get_type (void) G_GNUC_CONST; + +typedef enum +{ + GIMP_MESSAGE_BOX, + GIMP_CONSOLE, + GIMP_ERROR_CONSOLE +} GimpMessageHandlerType; + + +/** + * GimpOffsetType: + * @GIMP_OFFSET_BACKGROUND: Background + * @GIMP_OFFSET_TRANSPARENT: Transparent + * @GIMP_OFFSET_WRAP_AROUND: Wrap image around + * + * Background fill types for the offset operation. + **/ +#define GIMP_TYPE_OFFSET_TYPE (gimp_offset_type_get_type ()) + +GType gimp_offset_type_get_type (void) G_GNUC_CONST; + +typedef enum +{ + GIMP_OFFSET_BACKGROUND, + GIMP_OFFSET_TRANSPARENT, + GIMP_OFFSET_WRAP_AROUND +} GimpOffsetType; + + +/** + * GimpOrientationType: + * @GIMP_ORIENTATION_HORIZONTAL: Horizontal + * @GIMP_ORIENTATION_VERTICAL: Vertical + * @GIMP_ORIENTATION_UNKNOWN: Unknown + * + * Orientations for various purposes. + **/ +#define GIMP_TYPE_ORIENTATION_TYPE (gimp_orientation_type_get_type ()) + +GType gimp_orientation_type_get_type (void) G_GNUC_CONST; + +typedef enum +{ + GIMP_ORIENTATION_HORIZONTAL, /*< desc="Horizontal" >*/ + GIMP_ORIENTATION_VERTICAL, /*< desc="Vertical" >*/ + GIMP_ORIENTATION_UNKNOWN /*< desc="Unknown" >*/ +} GimpOrientationType; + + +/** + * GimpPaintApplicationMode: + * @GIMP_PAINT_CONSTANT: Constant + * @GIMP_PAINT_INCREMENTAL: Incremental + * + * Paint application modes. + **/ +#define GIMP_TYPE_PAINT_APPLICATION_MODE (gimp_paint_application_mode_get_type ()) + +GType gimp_paint_application_mode_get_type (void) G_GNUC_CONST; + +typedef enum +{ + GIMP_PAINT_CONSTANT, /*< desc="Constant" >*/ + GIMP_PAINT_INCREMENTAL /*< desc="Incremental" >*/ +} GimpPaintApplicationMode; + + +/** + * GimpPDBArgType: + * @GIMP_PDB_INT32: 32-bit integer + * @GIMP_PDB_INT16: 16-bit integer + * @GIMP_PDB_INT8: 8-bit integer + * @GIMP_PDB_FLOAT: Float + * @GIMP_PDB_STRING: String + * @GIMP_PDB_INT32ARRAY: Array of INT32 + * @GIMP_PDB_INT16ARRAY: Array of INT16 + * @GIMP_PDB_INT8ARRAY: Array of INT8 + * @GIMP_PDB_FLOATARRAY: Array of floats + * @GIMP_PDB_STRINGARRAY: Array of strings + * @GIMP_PDB_COLOR: Color + * @GIMP_PDB_ITEM: Item ID + * @GIMP_PDB_DISPLAY: Display ID + * @GIMP_PDB_IMAGE: Image ID + * @GIMP_PDB_LAYER: Layer ID + * @GIMP_PDB_CHANNEL: Channel ID + * @GIMP_PDB_DRAWABLE: Drawable ID + * @GIMP_PDB_SELECTION: Selection ID + * @GIMP_PDB_COLORARRAY: Array of colors + * @GIMP_PDB_VECTORS: Vectors (psath) ID + * @GIMP_PDB_PARASITE: Parasite + * @GIMP_PDB_STATUS: Procedure return status + * @GIMP_PDB_END: Marker for last enum value + * @GIMP_PDB_PATH: Deprecated alias for @GIMP_PDB_VECTORS + * @GIMP_PDB_BOUNDARY: Deprecated alias for @GIMP_PDB_COLORARRAY + * @GIMP_PDB_REGION: Deprecated alias for @GIMP_PDB_ITEM + * + * Parameter types of the PDB. + **/ +#define GIMP_TYPE_PDB_ARG_TYPE (gimp_pdb_arg_type_get_type ()) + +GType gimp_pdb_arg_type_get_type (void) G_GNUC_CONST; + +typedef enum +{ + GIMP_PDB_INT32, + GIMP_PDB_INT16, + GIMP_PDB_INT8, + GIMP_PDB_FLOAT, + GIMP_PDB_STRING, + GIMP_PDB_INT32ARRAY, + GIMP_PDB_INT16ARRAY, + GIMP_PDB_INT8ARRAY, + GIMP_PDB_FLOATARRAY, + GIMP_PDB_STRINGARRAY, + GIMP_PDB_COLOR, + GIMP_PDB_ITEM, + GIMP_PDB_DISPLAY, + GIMP_PDB_IMAGE, + GIMP_PDB_LAYER, + GIMP_PDB_CHANNEL, + GIMP_PDB_DRAWABLE, + GIMP_PDB_SELECTION, + GIMP_PDB_COLORARRAY, + GIMP_PDB_VECTORS, + GIMP_PDB_PARASITE, + GIMP_PDB_STATUS, + GIMP_PDB_END, + +#ifndef GIMP_DISABLE_DEPRECATED + GIMP_PDB_PATH = GIMP_PDB_VECTORS, /*< skip >*/ + GIMP_PDB_BOUNDARY = GIMP_PDB_COLORARRAY, /*< skip >*/ + GIMP_PDB_REGION = GIMP_PDB_ITEM /*< skip >*/ +#endif /* GIMP_DISABLE_DEPRECATED */ +} GimpPDBArgType; + + +/** + * GimpPDBErrorHandler: + * @GIMP_PDB_ERROR_HANDLER_INTERNAL: Internal + * @GIMP_PDB_ERROR_HANDLER_PLUGIN: Plug-In + * + * PDB error handlers. + **/ +#define GIMP_TYPE_PDB_ERROR_HANDLER (gimp_pdb_error_handler_get_type ()) + +GType gimp_pdb_error_handler_get_type (void) G_GNUC_CONST; + +typedef enum +{ + GIMP_PDB_ERROR_HANDLER_INTERNAL, + GIMP_PDB_ERROR_HANDLER_PLUGIN +} GimpPDBErrorHandler; + + +/** + * GimpPDBProcType: + * @GIMP_INTERNAL: Internal GIMP procedure + * @GIMP_PLUGIN: GIMP Plug-In + * @GIMP_EXTENSION: GIMP Extension + * @GIMP_TEMPORARY: Temporary Procedure + * + * Types of PDB procedures. + **/ +#define GIMP_TYPE_PDB_PROC_TYPE (gimp_pdb_proc_type_get_type ()) + +GType gimp_pdb_proc_type_get_type (void) G_GNUC_CONST; + +typedef enum +{ + GIMP_INTERNAL, /*< desc="Internal GIMP procedure" >*/ + GIMP_PLUGIN, /*< desc="GIMP Plug-In" >*/ + GIMP_EXTENSION, /*< desc="GIMP Extension" >*/ + GIMP_TEMPORARY /*< desc="Temporary Procedure" >*/ +} GimpPDBProcType; + + +/** + * GimpPDBStatusType: + * @GIMP_PDB_EXECUTION_ERROR: Execution error + * @GIMP_PDB_CALLING_ERROR: Calling error + * @GIMP_PDB_PASS_THROUGH: Pass through + * @GIMP_PDB_SUCCESS: Success + * @GIMP_PDB_CANCEL: User cancel + * + * Return status of PDB calls. + **/ +#define GIMP_TYPE_PDB_STATUS_TYPE (gimp_pdb_status_type_get_type ()) + +GType gimp_pdb_status_type_get_type (void) G_GNUC_CONST; + +typedef enum +{ + GIMP_PDB_EXECUTION_ERROR, + GIMP_PDB_CALLING_ERROR, + GIMP_PDB_PASS_THROUGH, + GIMP_PDB_SUCCESS, + GIMP_PDB_CANCEL +} GimpPDBStatusType; + + +/** + * GimpPrecision: + * @GIMP_PRECISION_U8_LINEAR: 8-bit linear integer + * @GIMP_PRECISION_U8_GAMMA: 8-bit gamma integer + * @GIMP_PRECISION_U16_LINEAR: 16-bit linear integer + * @GIMP_PRECISION_U16_GAMMA: 16-bit gamma integer + * @GIMP_PRECISION_U32_LINEAR: 32-bit linear integer + * @GIMP_PRECISION_U32_GAMMA: 32-bit gamma integer + * @GIMP_PRECISION_HALF_LINEAR: 16-bit linear floating point + * @GIMP_PRECISION_HALF_GAMMA: 16-bit gamma floating point + * @GIMP_PRECISION_FLOAT_LINEAR: 32-bit linear floating point + * @GIMP_PRECISION_FLOAT_GAMMA: 32-bit gamma floating point + * @GIMP_PRECISION_DOUBLE_LINEAR: 64-bit linear floating point + * @GIMP_PRECISION_DOUBLE_GAMMA: 64-bit gamma floating point + * + * Precisions for pixel encoding. + * + * Since: 2.10 + **/ +#define GIMP_TYPE_PRECISION (gimp_precision_get_type ()) + +GType gimp_precision_get_type (void) G_GNUC_CONST; + +typedef enum +{ + GIMP_PRECISION_U8_LINEAR = 100, /*< desc="8-bit linear integer" >*/ + GIMP_PRECISION_U8_GAMMA = 150, /*< desc="8-bit gamma integer" >*/ + GIMP_PRECISION_U16_LINEAR = 200, /*< desc="16-bit linear integer" >*/ + GIMP_PRECISION_U16_GAMMA = 250, /*< desc="16-bit gamma integer" >*/ + GIMP_PRECISION_U32_LINEAR = 300, /*< desc="32-bit linear integer" >*/ + GIMP_PRECISION_U32_GAMMA = 350, /*< desc="32-bit gamma integer" >*/ + GIMP_PRECISION_HALF_LINEAR = 500, /*< desc="16-bit linear floating point" >*/ + GIMP_PRECISION_HALF_GAMMA = 550, /*< desc="16-bit gamma floating point" >*/ + GIMP_PRECISION_FLOAT_LINEAR = 600, /*< desc="32-bit linear floating point" >*/ + GIMP_PRECISION_FLOAT_GAMMA = 650, /*< desc="32-bit gamma floating point" >*/ + GIMP_PRECISION_DOUBLE_LINEAR = 700, /*< desc="64-bit linear floating point" >*/ + GIMP_PRECISION_DOUBLE_GAMMA = 750 /*< desc="64-bit gamma floating point" >*/ +} GimpPrecision; + + +/** + * GimpProgressCommand: + * @GIMP_PROGRESS_COMMAND_START: Start a progress + * @GIMP_PROGRESS_COMMAND_END: End the progress + * @GIMP_PROGRESS_COMMAND_SET_TEXT: Set the text + * @GIMP_PROGRESS_COMMAND_SET_VALUE: Set the percentage + * @GIMP_PROGRESS_COMMAND_PULSE: Pulse the progress + * @GIMP_PROGRESS_COMMAND_GET_WINDOW: Get the window where the progress is shown + * + * Commands for the progress API. + **/ +#define GIMP_TYPE_PROGRESS_COMMAND (gimp_progress_command_get_type ()) + +GType gimp_progress_command_get_type (void) G_GNUC_CONST; + +typedef enum +{ + GIMP_PROGRESS_COMMAND_START, + GIMP_PROGRESS_COMMAND_END, + GIMP_PROGRESS_COMMAND_SET_TEXT, + GIMP_PROGRESS_COMMAND_SET_VALUE, + GIMP_PROGRESS_COMMAND_PULSE, + GIMP_PROGRESS_COMMAND_GET_WINDOW +} GimpProgressCommand; + + +/** + * GimpRepeatMode: + * @GIMP_REPEAT_NONE: None (extend) + * @GIMP_REPEAT_SAWTOOTH: Sawtooth wave + * @GIMP_REPEAT_TRIANGULAR: Triangular wave + * @GIMP_REPEAT_TRUNCATE: Truncate + * + * Repeat modes for example for gradients. + **/ +#define GIMP_TYPE_REPEAT_MODE (gimp_repeat_mode_get_type ()) + +GType gimp_repeat_mode_get_type (void) G_GNUC_CONST; + +typedef enum +{ + GIMP_REPEAT_NONE, /*< desc="None (extend)" >*/ + GIMP_REPEAT_SAWTOOTH, /*< desc="Sawtooth wave" >*/ + GIMP_REPEAT_TRIANGULAR, /*< desc="Triangular wave" >*/ + GIMP_REPEAT_TRUNCATE /*< desc="Truncate" >*/ +} GimpRepeatMode; + + +/** + * GimpRotationType: + * @GIMP_ROTATE_90: 90 degrees + * @GIMP_ROTATE_180: 180 degrees + * @GIMP_ROTATE_270: 270 degrees + * + * Types of simple rotations. + **/ +#define GIMP_TYPE_ROTATION_TYPE (gimp_rotation_type_get_type ()) + +GType gimp_rotation_type_get_type (void) G_GNUC_CONST; + +typedef enum +{ + GIMP_ROTATE_90, + GIMP_ROTATE_180, + GIMP_ROTATE_270 +} GimpRotationType; + + +/** + * GimpRunMode: + * @GIMP_RUN_INTERACTIVE: Run interactively + * @GIMP_RUN_NONINTERACTIVE: Run non-interactively + * @GIMP_RUN_WITH_LAST_VALS: Run with last used values + * + * Run modes for plug-ins. + **/ +#define GIMP_TYPE_RUN_MODE (gimp_run_mode_get_type ()) + +GType gimp_run_mode_get_type (void) G_GNUC_CONST; + +typedef enum +{ + GIMP_RUN_INTERACTIVE, /*< desc="Run interactively" >*/ + GIMP_RUN_NONINTERACTIVE, /*< desc="Run non-interactively" >*/ + GIMP_RUN_WITH_LAST_VALS /*< desc="Run with last used values" >*/ +} GimpRunMode; + + +/** + * GimpSelectCriterion: + * @GIMP_SELECT_CRITERION_COMPOSITE: Composite + * @GIMP_SELECT_CRITERION_R: Red + * @GIMP_SELECT_CRITERION_G: Green + * @GIMP_SELECT_CRITERION_B: Blue + * @GIMP_SELECT_CRITERION_H: HSV Hue + * @GIMP_SELECT_CRITERION_S: HSV Saturation + * @GIMP_SELECT_CRITERION_V: HSV Value + * @GIMP_SELECT_CRITERION_A: Alpha + * @GIMP_SELECT_CRITERION_LCH_L: LCh Lightness + * @GIMP_SELECT_CRITERION_LCH_C: LCh Chroma + * @GIMP_SELECT_CRITERION_LCH_H: LCh Hue + * + * Criterions for color similarity. + **/ +#define GIMP_TYPE_SELECT_CRITERION (gimp_select_criterion_get_type ()) + +GType gimp_select_criterion_get_type (void) G_GNUC_CONST; + +typedef enum +{ + GIMP_SELECT_CRITERION_COMPOSITE, /*< desc="Composite" >*/ + GIMP_SELECT_CRITERION_R, /*< desc="Red" >*/ + GIMP_SELECT_CRITERION_G, /*< desc="Green" >*/ + GIMP_SELECT_CRITERION_B, /*< desc="Blue" >*/ + GIMP_SELECT_CRITERION_H, /*< desc="HSV Hue" >*/ + GIMP_SELECT_CRITERION_S, /*< desc="HSV Saturation" >*/ + GIMP_SELECT_CRITERION_V, /*< desc="HSV Value" >*/ + GIMP_SELECT_CRITERION_A, /*< desc="Alpha" >*/ + GIMP_SELECT_CRITERION_LCH_L, /*< desc="LCh Lightness" >*/ + GIMP_SELECT_CRITERION_LCH_C, /*< desc="LCh Chroma" >*/ + GIMP_SELECT_CRITERION_LCH_H, /*< desc="LCh Hue" >*/ +} GimpSelectCriterion; + + +/** + * GimpSizeType: + * @GIMP_PIXELS: Pixels + * @GIMP_POINTS: Points + * + * Size types for the old-style text API. + **/ +#define GIMP_TYPE_SIZE_TYPE (gimp_size_type_get_type ()) + +GType gimp_size_type_get_type (void) G_GNUC_CONST; + +typedef enum +{ + GIMP_PIXELS, /*< desc="Pixels" >*/ + GIMP_POINTS /*< desc="Points" >*/ +} GimpSizeType; + + +/** + * GimpStackTraceMode: + * @GIMP_STACK_TRACE_NEVER: Never + * @GIMP_STACK_TRACE_QUERY: Ask each time + * @GIMP_STACK_TRACE_ALWAYS: Always + * + * When to generate stack traces in case of an error. + **/ +#define GIMP_TYPE_STACK_TRACE_MODE (gimp_stack_trace_mode_get_type ()) + +GType gimp_stack_trace_mode_get_type (void) G_GNUC_CONST; + +typedef enum +{ + GIMP_STACK_TRACE_NEVER, + GIMP_STACK_TRACE_QUERY, + GIMP_STACK_TRACE_ALWAYS +} GimpStackTraceMode; + + +/** + * GimpStrokeMethod: + * @GIMP_STROKE_LINE: Stroke line + * @GIMP_STROKE_PAINT_METHOD: Stroke with a paint tool + * + * Methods of stroking selections and paths. + **/ +#define GIMP_TYPE_STROKE_METHOD (gimp_stroke_method_get_type ()) + +GType gimp_stroke_method_get_type (void) G_GNUC_CONST; + +typedef enum +{ + GIMP_STROKE_LINE, /*< desc="Stroke line" >*/ + GIMP_STROKE_PAINT_METHOD /*< desc="Stroke with a paint tool" >*/ +} GimpStrokeMethod; + + +/** + * GimpTextDirection: + * @GIMP_TEXT_DIRECTION_LTR: From left to right + * @GIMP_TEXT_DIRECTION_RTL: From right to left + * @GIMP_TEXT_DIRECTION_TTB_RTL: Characters are from top to bottom, Lines are from right to left + * @GIMP_TEXT_DIRECTION_TTB_RTL_UPRIGHT: Upright characters are from top to bottom, Lines are from right to left + * @GIMP_TEXT_DIRECTION_TTB_LTR: Characters are from top to bottom, Lines are from left to right + * @GIMP_TEXT_DIRECTION_TTB_LTR_UPRIGHT: Upright characters are from top to bottom, Lines are from left to right + * + * Text directions. + **/ +#define GIMP_TYPE_TEXT_DIRECTION (gimp_text_direction_get_type ()) + +GType gimp_text_direction_get_type (void) G_GNUC_CONST; + +typedef enum +{ + GIMP_TEXT_DIRECTION_LTR, /*< desc="From left to right" >*/ + GIMP_TEXT_DIRECTION_RTL, /*< desc="From right to left" >*/ + GIMP_TEXT_DIRECTION_TTB_RTL, /*< desc="Vertical, right to left (mixed orientation)" >*/ + GIMP_TEXT_DIRECTION_TTB_RTL_UPRIGHT, /*< desc="Vertical, right to left (upright orientation)" >*/ + GIMP_TEXT_DIRECTION_TTB_LTR, /*< desc="Vertical, left to right (mixed orientation)" >*/ + GIMP_TEXT_DIRECTION_TTB_LTR_UPRIGHT /*< desc="Vertical, left to right (upright orientation)" >*/ +} GimpTextDirection; + + +/** + * GimpTextHintStyle: + * @GIMP_TEXT_HINT_STYLE_NONE: None + * @GIMP_TEXT_HINT_STYLE_SLIGHT: Slight + * @GIMP_TEXT_HINT_STYLE_MEDIUM: Medium + * @GIMP_TEXT_HINT_STYLE_FULL: Full + * + * Text hint strengths. + **/ +#define GIMP_TYPE_TEXT_HINT_STYLE (gimp_text_hint_style_get_type ()) + +GType gimp_text_hint_style_get_type (void) G_GNUC_CONST; + +typedef enum +{ + GIMP_TEXT_HINT_STYLE_NONE, /*< desc="None" >*/ + GIMP_TEXT_HINT_STYLE_SLIGHT, /*< desc="Slight" >*/ + GIMP_TEXT_HINT_STYLE_MEDIUM, /*< desc="Medium" >*/ + GIMP_TEXT_HINT_STYLE_FULL /*< desc="Full" >*/ +} GimpTextHintStyle; + + +/** + * GimpTextJustification: + * @GIMP_TEXT_JUSTIFY_LEFT: Left justified + * @GIMP_TEXT_JUSTIFY_RIGHT: Right justified + * @GIMP_TEXT_JUSTIFY_CENTER: Centered + * @GIMP_TEXT_JUSTIFY_FILL: Filled + * + * Text justifications. + **/ +#define GIMP_TYPE_TEXT_JUSTIFICATION (gimp_text_justification_get_type ()) + +GType gimp_text_justification_get_type (void) G_GNUC_CONST; + +typedef enum +{ + GIMP_TEXT_JUSTIFY_LEFT, /*< desc="Left justified" >*/ + GIMP_TEXT_JUSTIFY_RIGHT, /*< desc="Right justified" >*/ + GIMP_TEXT_JUSTIFY_CENTER, /*< desc="Centered" >*/ + GIMP_TEXT_JUSTIFY_FILL /*< desc="Filled" >*/ +} GimpTextJustification; + + +/** + * GimpTransferMode: + * @GIMP_TRANSFER_SHADOWS: Shadows + * @GIMP_TRANSFER_MIDTONES: Midtones + * @GIMP_TRANSFER_HIGHLIGHTS: Highlights + * @GIMP_SHADOWS: Deprecated alias for @GIMP_TRANSFER_SHADOWS + * @GIMP_MIDTONES: Deprecated alias for @GIMP_TRANSFER_MIDTONES + * @GIMP_HIGHLIGHTS: Deprecated alias for @GIMP_TRANSFER_HIGHLIGHTS + * + * For choosing which brightness ranges to transform. + **/ +#define GIMP_TYPE_TRANSFER_MODE (gimp_transfer_mode_get_type ()) + +GType gimp_transfer_mode_get_type (void) G_GNUC_CONST; + +typedef enum +{ + GIMP_TRANSFER_SHADOWS, /*< desc="Shadows" >*/ + GIMP_TRANSFER_MIDTONES, /*< desc="Midtones" >*/ + GIMP_TRANSFER_HIGHLIGHTS, /*< desc="Highlights" >*/ + +#ifndef GIMP_DISABLE_DEPRECATED + GIMP_SHADOWS = GIMP_TRANSFER_SHADOWS, /*< skip, pdb-skip >*/ + GIMP_MIDTONES = GIMP_TRANSFER_MIDTONES, /*< skip, pdb-skip >*/ + GIMP_HIGHLIGHTS = GIMP_TRANSFER_HIGHLIGHTS /*< skip, pdb-skip >*/ +#endif /* GIMP_DISABLE_DEPRECATED */ +} GimpTransferMode; + + +/** + * GimpTransformDirection: + * @GIMP_TRANSFORM_FORWARD: Normal (Forward) + * @GIMP_TRANSFORM_BACKWARD: Corrective (Backward) + * + * Transform directions. + **/ +#define GIMP_TYPE_TRANSFORM_DIRECTION (gimp_transform_direction_get_type ()) + +GType gimp_transform_direction_get_type (void) G_GNUC_CONST; + +typedef enum +{ + GIMP_TRANSFORM_FORWARD, /*< desc="Normal (Forward)" >*/ + GIMP_TRANSFORM_BACKWARD /*< desc="Corrective (Backward)" >*/ +} GimpTransformDirection; + + +/** + * GimpTransformResize: + * @GIMP_TRANSFORM_RESIZE_ADJUST: Adjust + * @GIMP_TRANSFORM_RESIZE_CLIP: Clip + * @GIMP_TRANSFORM_RESIZE_CROP: Crop to result + * @GIMP_TRANSFORM_RESIZE_CROP_WITH_ASPECT: Crop with aspect + * + * Ways of clipping the result when transforming drawables. + **/ +#define GIMP_TYPE_TRANSFORM_RESIZE (gimp_transform_resize_get_type ()) + +GType gimp_transform_resize_get_type (void) G_GNUC_CONST; + +typedef enum +{ + GIMP_TRANSFORM_RESIZE_ADJUST, /*< desc="Adjust" >*/ + GIMP_TRANSFORM_RESIZE_CLIP, /*< desc="Clip" >*/ + GIMP_TRANSFORM_RESIZE_CROP, /*< desc="Crop to result" >*/ + GIMP_TRANSFORM_RESIZE_CROP_WITH_ASPECT /*< desc="Crop with aspect" >*/ +} GimpTransformResize; + + +/** + * GimpUnit: + * @GIMP_UNIT_PIXEL: Pixels + * @GIMP_UNIT_INCH: Inches + * @GIMP_UNIT_MM: Millimeters + * @GIMP_UNIT_POINT: Points + * @GIMP_UNIT_PICA: Picas + * @GIMP_UNIT_END: Marker for end-of-builtin-units + * @GIMP_UNIT_PERCENT: Pseudo-unit percent + * + * Units used for dimensions in images. + **/ +typedef enum /*< skip >*/ +{ + GIMP_UNIT_PIXEL = 0, + + GIMP_UNIT_INCH = 1, + GIMP_UNIT_MM = 2, + GIMP_UNIT_POINT = 3, + GIMP_UNIT_PICA = 4, + + GIMP_UNIT_END = 5, + + GIMP_UNIT_PERCENT = 65536 /*< pdb-skip >*/ +} GimpUnit; + + +#ifndef GIMP_DISABLE_DEPRECATED +/** + * GimpUserDirectory: + * @GIMP_USER_DIRECTORY_DESKTOP: Deprecated + * @GIMP_USER_DIRECTORY_DOCUMENTS: Deprecated + * @GIMP_USER_DIRECTORY_DOWNLOAD: Deprecated + * @GIMP_USER_DIRECTORY_MUSIC: Deprecated + * @GIMP_USER_DIRECTORY_PICTURES: Deprecated + * @GIMP_USER_DIRECTORY_PUBLIC_SHARE: Deprecated + * @GIMP_USER_DIRECTORY_TEMPLATES: Deprecated + * @GIMP_USER_DIRECTORY_VIDEOS: Deprecated + * + * Deprecated enum, don't use. + **/ +#define GIMP_TYPE_USER_DIRECTORY (gimp_user_directory_get_type ()) + +GType gimp_user_directory_get_type (void) G_GNUC_CONST; + +typedef enum +{ + GIMP_USER_DIRECTORY_DESKTOP, + GIMP_USER_DIRECTORY_DOCUMENTS, + GIMP_USER_DIRECTORY_DOWNLOAD, + GIMP_USER_DIRECTORY_MUSIC, + GIMP_USER_DIRECTORY_PICTURES, + GIMP_USER_DIRECTORY_PUBLIC_SHARE, + GIMP_USER_DIRECTORY_TEMPLATES, + GIMP_USER_DIRECTORY_VIDEOS +} GimpUserDirectory; +#endif /* !GIMP_DISABLE_DEPRECATED */ + + +/** + * GimpVectorsStrokeType: + * @GIMP_VECTORS_STROKE_TYPE_BEZIER: A bezier stroke + * + * Possible type of strokes in vectors objects. + **/ +#define GIMP_TYPE_VECTORS_STROKE_TYPE (gimp_vectors_stroke_type_get_type ()) + +GType gimp_vectors_stroke_type_get_type (void) G_GNUC_CONST; + +typedef enum +{ + GIMP_VECTORS_STROKE_TYPE_BEZIER +} GimpVectorsStrokeType; + +G_END_DECLS + +#endif /* __GIMP_BASE_ENUMS_H__ */ diff --git a/libgimpbase/gimpbasetypes.c b/libgimpbase/gimpbasetypes.c new file mode 100644 index 0000000..fe22464 --- /dev/null +++ b/libgimpbase/gimpbasetypes.c @@ -0,0 +1,244 @@ +/* LIBGIMP - The GIMP Library + * Copyright (C) 1995-1997 Spencer Kimball and Peter Mattis + * + * gimpbasetypes.c + * Copyright (C) 2004 Sven Neumann <sven@gimp.org> + * + * This library is free software: you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see + * <https://www.gnu.org/licenses/>. + */ + +#include "config.h" + +#include <glib-object.h> + +#include "gimpbasetypes.h" + + +/** + * SECTION: gimpbasetypes + * @title: gimpbasetypes + * @short_description: Translation between gettext translation domain + * identifier and GType. + * + * Translation between gettext translation domain identifier and + * GType. + **/ + + +static GQuark gimp_translation_domain_quark (void) G_GNUC_CONST; +static GQuark gimp_translation_context_quark (void) G_GNUC_CONST; +static GQuark gimp_value_descriptions_quark (void) G_GNUC_CONST; + + +/** + * gimp_type_set_translation_domain: + * @type: a #GType + * @domain: a constant string that identifies a translation domain or %NULL + * + * This function attaches a constant string as a gettext translation + * domain identifier to a #GType. The only purpose of this function is + * to use it when registering a #G_TYPE_ENUM with translatable value + * names. + * + * Since: 2.2 + **/ +void +gimp_type_set_translation_domain (GType type, + const gchar *domain) +{ + g_type_set_qdata (type, + gimp_translation_domain_quark (), (gpointer) domain); +} + +/** + * gimp_type_get_translation_domain: + * @type: a #GType + * + * Retrieves the gettext translation domain identifier that has been + * previously set using gimp_type_set_translation_domain(). You should + * not need to use this function directly, use gimp_enum_get_value() + * or gimp_enum_value_get_desc() instead. + * + * Return value: the translation domain associated with @type + * or %NULL if no domain was set + * + * Since: 2.2 + **/ +const gchar * +gimp_type_get_translation_domain (GType type) +{ + return (const gchar *) g_type_get_qdata (type, + gimp_translation_domain_quark ()); +} + +/** + * gimp_type_set_translation_context: + * @type: a #GType + * @context: a constant string that identifies a translation context or %NULL + * + * This function attaches a constant string as a translation context + * to a #GType. The only purpose of this function is to use it when + * registering a #G_TYPE_ENUM with translatable value names. + * + * Since: 2.8 + **/ +void +gimp_type_set_translation_context (GType type, + const gchar *context) +{ + g_type_set_qdata (type, + gimp_translation_context_quark (), (gpointer) context); +} + +/** + * gimp_type_get_translation_context: + * @type: a #GType + * + * Retrieves the translation context that has been previously set + * using gimp_type_set_translation_context(). You should not need to + * use this function directly, use gimp_enum_get_value() or + * gimp_enum_value_get_desc() instead. + * + * Return value: the translation context associated with @type + * or %NULL if no context was set + * + * Since: 2.8 + **/ +const gchar * +gimp_type_get_translation_context (GType type) +{ + return (const gchar *) g_type_get_qdata (type, + gimp_translation_context_quark ()); +} + +/** + * gimp_enum_set_value_descriptions: + * @enum_type: a #GType + * @descriptions: a %NULL terminated constant static array of #GimpEnumDesc + * + * Sets the array of human readable and translatable descriptions + * and help texts for enum values. + * + * Since: 2.2 + **/ +void +gimp_enum_set_value_descriptions (GType enum_type, + const GimpEnumDesc *descriptions) +{ + g_return_if_fail (g_type_is_a (enum_type, G_TYPE_ENUM)); + g_return_if_fail (descriptions != NULL); + + g_type_set_qdata (enum_type, + gimp_value_descriptions_quark (), + (gpointer) descriptions); +} + +/** + * gimp_enum_get_value_descriptions: + * @enum_type: a #GType + * + * Retreives the array of human readable and translatable descriptions + * and help texts for enum values. + * + * Returns: a %NULL terminated constant array of #GimpEnumDesc + * + * Since: 2.2 + **/ +const GimpEnumDesc * +gimp_enum_get_value_descriptions (GType enum_type) +{ + g_return_val_if_fail (g_type_is_a (enum_type, G_TYPE_ENUM), NULL); + + return (const GimpEnumDesc *) + g_type_get_qdata (enum_type, gimp_value_descriptions_quark ()); +} + +/** + * gimp_flags_set_value_descriptions: + * @flags_type: a #GType + * @descriptions: a %NULL terminated constant static array of #GimpFlagsDesc + * + * Sets the array of human readable and translatable descriptions + * and help texts for flags values. + * + * Since: 2.2 + **/ +void +gimp_flags_set_value_descriptions (GType flags_type, + const GimpFlagsDesc *descriptions) +{ + g_return_if_fail (g_type_is_a (flags_type, G_TYPE_FLAGS)); + g_return_if_fail (descriptions != NULL); + + g_type_set_qdata (flags_type, + gimp_value_descriptions_quark (), + (gpointer) descriptions); +} + +/** + * gimp_flags_get_value_descriptions: + * @flags_type: a #GType + * + * Retreives the array of human readable and translatable descriptions + * and help texts for flags values. + * + * Returns: a %NULL terminated constant array of #GimpFlagsDesc + * + * Since: 2.2 + **/ +const GimpFlagsDesc * +gimp_flags_get_value_descriptions (GType flags_type) +{ + g_return_val_if_fail (g_type_is_a (flags_type, G_TYPE_FLAGS), NULL); + + return (const GimpFlagsDesc *) + g_type_get_qdata (flags_type, gimp_value_descriptions_quark ()); +} + + +/* private functions */ + +static GQuark +gimp_translation_domain_quark (void) +{ + static GQuark quark = 0; + + if (! quark) + quark = g_quark_from_static_string ("gimp-translation-domain-quark"); + + return quark; +} + +static GQuark +gimp_translation_context_quark (void) +{ + static GQuark quark = 0; + + if (! quark) + quark = g_quark_from_static_string ("gimp-translation-context-quark"); + + return quark; +} + +static GQuark +gimp_value_descriptions_quark (void) +{ + static GQuark quark = 0; + + if (! quark) + quark = g_quark_from_static_string ("gimp-value-descriptions-quark"); + + return quark; +} diff --git a/libgimpbase/gimpbasetypes.h b/libgimpbase/gimpbasetypes.h new file mode 100644 index 0000000..9c3680d --- /dev/null +++ b/libgimpbase/gimpbasetypes.h @@ -0,0 +1,113 @@ +/* LIBGIMP - The GIMP Library + * Copyright (C) 1995-1997 Peter Mattis and Spencer Kimball + * + * This library is free software: you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This library 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see + * <https://www.gnu.org/licenses/>. + */ + +#ifndef __GIMP_BASE_TYPES_H__ +#define __GIMP_BASE_TYPES_H__ + + +#include <libgimpcolor/gimpcolortypes.h> +#include <libgimpmath/gimpmathtypes.h> + +#include <libgimpbase/gimpbaseenums.h> +#include <libgimpbase/gimpparam.h> + + +G_BEGIN_DECLS + +/* For information look into the C source or the html documentation */ + + +/* XXX FIXME move these to a separate file */ + +#ifdef GIMP_DISABLE_DEPRECATION_WARNINGS +#define GIMP_DEPRECATED +#define GIMP_DEPRECATED_FOR(f) +#define GIMP_UNAVAILABLE(maj,min) +#else +#define GIMP_DEPRECATED G_DEPRECATED +#define GIMP_DEPRECATED_FOR(f) G_DEPRECATED_FOR(f) +#define GIMP_UNAVAILABLE(maj,min) G_UNAVAILABLE(maj,min) +#endif + + +typedef struct _GimpParasite GimpParasite; +typedef struct _GimpDatafileData GimpDatafileData; +typedef struct _GimpEnumDesc GimpEnumDesc; +typedef struct _GimpFlagsDesc GimpFlagsDesc; +typedef struct _GimpValueArray GimpValueArray; + + +typedef void (* GimpDatafileLoaderFunc) (const GimpDatafileData *file_data, + gpointer user_data); + +typedef struct _GimpMetadata GimpMetadata; + + +/** + * GimpEnumDesc: + * @value: An enum value. + * @value_desc: The value's description. + * @value_help: The value's help text. + * + * This structure is used to register translatable descriptions and + * help texts for enum values. See gimp_enum_set_value_descriptions(). + **/ +struct _GimpEnumDesc +{ + gint value; + const gchar *value_desc; + const gchar *value_help; +}; + +/** + * GimpFlagsDesc: + * @value: A flag value. + * @value_desc: The value's description. + * @value_help: The value's help text. + * + * This structure is used to register translatable descriptions and + * help texts for flag values. See gimp_flags_set_value_descriptions(). + **/ +struct _GimpFlagsDesc +{ + guint value; + const gchar *value_desc; + const gchar *value_help; +}; + + +void gimp_type_set_translation_domain (GType type, + const gchar *domain); +const gchar * gimp_type_get_translation_domain (GType type); + +void gimp_type_set_translation_context (GType type, + const gchar *context); +const gchar * gimp_type_get_translation_context (GType type); + +void gimp_enum_set_value_descriptions (GType enum_type, + const GimpEnumDesc *descriptions); +const GimpEnumDesc * gimp_enum_get_value_descriptions (GType enum_type); + +void gimp_flags_set_value_descriptions (GType flags_type, + const GimpFlagsDesc *descriptions); +const GimpFlagsDesc * gimp_flags_get_value_descriptions (GType flags_type); + + +G_END_DECLS + +#endif /* __GIMP_BASE_TYPES_H__ */ diff --git a/libgimpbase/gimpchecks.c b/libgimpbase/gimpchecks.c new file mode 100644 index 0000000..589bf6f --- /dev/null +++ b/libgimpbase/gimpchecks.c @@ -0,0 +1,73 @@ +/* LIBGIMP - The GIMP Library + * Copyright (C) 1995-1997 Spencer Kimball and Peter Mattis + * + * gimpchecks.c + * Copyright (C) 2004 Sven Neumann <sven@gimp.org> + * + * This library is free software: you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see + * <https://www.gnu.org/licenses/>. + */ + +#include "config.h" + +#include <glib-object.h> + +#include "gimpbasetypes.h" + +#include "gimpchecks.h" + + +/** + * SECTION: gimpchecks + * @title: gimpchecks + * @short_description: Constants and functions related to rendering + * checkerboards. + * + * Constants and functions related to rendering checkerboards. + **/ + + +/** + * gimp_checks_get_shades: + * @type: the checkerboard type + * @light: return location for the light shade + * @dark: return location for the dark shade + * + * Retrieves the actual shades of gray to use when drawing a + * checkerboard for a certain #GimpCheckType. + * + * Since: 2.2 + **/ +void +gimp_checks_get_shades (GimpCheckType type, + guchar *light, + guchar *dark) +{ + const guchar shades[6][2] = + { + { 204, 255 }, /* LIGHT_CHECKS */ + { 102, 153 }, /* GRAY_CHECKS */ + { 0, 51 }, /* DARK_CHECKS */ + { 255, 255 }, /* WHITE_ONLY */ + { 127, 127 }, /* GRAY_ONLY */ + { 0, 0 } /* BLACK_ONLY */ + }; + + type = MIN (type, 5); + + if (light) + *light = shades[type][1]; + if (dark) + *dark = shades[type][0]; +} diff --git a/libgimpbase/gimpchecks.h b/libgimpbase/gimpchecks.h new file mode 100644 index 0000000..c41a4d6 --- /dev/null +++ b/libgimpbase/gimpchecks.h @@ -0,0 +1,68 @@ +/* LIBGIMP - The GIMP Library + * Copyright (C) 1995-1997 Peter Mattis and Spencer Kimball + * + * This library is free software: you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This library 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see + * <https://www.gnu.org/licenses/>. + */ + +#if !defined (__GIMP_BASE_H_INSIDE__) && !defined (GIMP_BASE_COMPILATION) +#error "Only <libgimpbase/gimpbase.h> can be included directly." +#endif + +#ifndef __GIMP_CHECKS_H__ +#define __GIMP_CHECKS_H__ + +G_BEGIN_DECLS + + +/** + * GIMP_CHECK_SIZE: + * + * The default checkerboard size in pixels. This is configurable in + * the core but GIMP plug-ins can't access the user preference and + * should use this constant instead. + **/ +#define GIMP_CHECK_SIZE 8 + +/** + * GIMP_CHECK_SIZE_SM: + * + * The default small checkerboard size in pixels. + **/ +#define GIMP_CHECK_SIZE_SM 4 + + +/** + * GIMP_CHECK_DARK: + * + * The dark gray value for the default checkerboard pattern. + **/ +#define GIMP_CHECK_DARK 0.4 + +/** + * GIMP_CHECK_LIGHT: + * + * The dark light value for the default checkerboard pattern. + **/ +#define GIMP_CHECK_LIGHT 0.6 + + +void gimp_checks_get_shades (GimpCheckType type, + guchar *light, + guchar *dark); + + +G_END_DECLS + +#endif /* __GIMP_CHECKS_H__ */ diff --git a/libgimpbase/gimpcompatenums.c b/libgimpbase/gimpcompatenums.c new file mode 100644 index 0000000..82fdafe --- /dev/null +++ b/libgimpbase/gimpcompatenums.c @@ -0,0 +1,581 @@ + +/* Generated data (by gimp-mkenums) */ + +#include "config.h" +#include <glib-object.h> +#include "gimpbasetypes.h" +#include "gimpcompatenums.h" +#include "libgimp/libgimp-intl.h" + +/* enumerations from "gimpcompatenums.h" */ +GType +gimp_add_mask_type_compat_get_type (void) +{ + static const GEnumValue values[] = + { + { GIMP_ADD_WHITE_MASK, "GIMP_ADD_WHITE_MASK", "white-mask" }, + { GIMP_ADD_BLACK_MASK, "GIMP_ADD_BLACK_MASK", "black-mask" }, + { GIMP_ADD_ALPHA_MASK, "GIMP_ADD_ALPHA_MASK", "alpha-mask" }, + { GIMP_ADD_ALPHA_TRANSFER_MASK, "GIMP_ADD_ALPHA_TRANSFER_MASK", "alpha-transfer-mask" }, + { GIMP_ADD_SELECTION_MASK, "GIMP_ADD_SELECTION_MASK", "selection-mask" }, + { GIMP_ADD_COPY_MASK, "GIMP_ADD_COPY_MASK", "copy-mask" }, + { GIMP_ADD_CHANNEL_MASK, "GIMP_ADD_CHANNEL_MASK", "channel-mask" }, + { 0, NULL, NULL } + }; + + static const GimpEnumDesc descs[] = + { + { GIMP_ADD_WHITE_MASK, "GIMP_ADD_WHITE_MASK", NULL }, + { GIMP_ADD_BLACK_MASK, "GIMP_ADD_BLACK_MASK", NULL }, + { GIMP_ADD_ALPHA_MASK, "GIMP_ADD_ALPHA_MASK", NULL }, + { GIMP_ADD_ALPHA_TRANSFER_MASK, "GIMP_ADD_ALPHA_TRANSFER_MASK", NULL }, + { GIMP_ADD_SELECTION_MASK, "GIMP_ADD_SELECTION_MASK", NULL }, + { GIMP_ADD_COPY_MASK, "GIMP_ADD_COPY_MASK", NULL }, + { GIMP_ADD_CHANNEL_MASK, "GIMP_ADD_CHANNEL_MASK", NULL }, + { 0, NULL, NULL } + }; + + static GType type = 0; + + if (G_UNLIKELY (! type)) + { + type = g_enum_register_static ("GimpAddMaskTypeCompat", values); + gimp_type_set_translation_domain (type, GETTEXT_PACKAGE "-libgimp"); + gimp_type_set_translation_context (type, "add-mask-type-compat"); + gimp_enum_set_value_descriptions (type, descs); + } + + return type; +} + +GType +gimp_blend_mode_compat_get_type (void) +{ + static const GEnumValue values[] = + { + { GIMP_FG_BG_RGB_MODE, "GIMP_FG_BG_RGB_MODE", "fg-bg-rgb-mode" }, + { GIMP_FG_BG_HSV_MODE, "GIMP_FG_BG_HSV_MODE", "fg-bg-hsv-mode" }, + { GIMP_FG_TRANSPARENT_MODE, "GIMP_FG_TRANSPARENT_MODE", "fg-transparent-mode" }, + { GIMP_CUSTOM_MODE, "GIMP_CUSTOM_MODE", "custom-mode" }, + { 0, NULL, NULL } + }; + + static const GimpEnumDesc descs[] = + { + { GIMP_FG_BG_RGB_MODE, "GIMP_FG_BG_RGB_MODE", NULL }, + { GIMP_FG_BG_HSV_MODE, "GIMP_FG_BG_HSV_MODE", NULL }, + { GIMP_FG_TRANSPARENT_MODE, "GIMP_FG_TRANSPARENT_MODE", NULL }, + { GIMP_CUSTOM_MODE, "GIMP_CUSTOM_MODE", NULL }, + { 0, NULL, NULL } + }; + + static GType type = 0; + + if (G_UNLIKELY (! type)) + { + type = g_enum_register_static ("GimpBlendModeCompat", values); + gimp_type_set_translation_domain (type, GETTEXT_PACKAGE "-libgimp"); + gimp_type_set_translation_context (type, "blend-mode-compat"); + gimp_enum_set_value_descriptions (type, descs); + } + + return type; +} + +GType +gimp_bucket_fill_mode_compat_get_type (void) +{ + static const GEnumValue values[] = + { + { GIMP_FG_BUCKET_FILL, "GIMP_FG_BUCKET_FILL", "fg-bucket-fill" }, + { GIMP_BG_BUCKET_FILL, "GIMP_BG_BUCKET_FILL", "bg-bucket-fill" }, + { GIMP_PATTERN_BUCKET_FILL, "GIMP_PATTERN_BUCKET_FILL", "pattern-bucket-fill" }, + { 0, NULL, NULL } + }; + + static const GimpEnumDesc descs[] = + { + { GIMP_FG_BUCKET_FILL, "GIMP_FG_BUCKET_FILL", NULL }, + { GIMP_BG_BUCKET_FILL, "GIMP_BG_BUCKET_FILL", NULL }, + { GIMP_PATTERN_BUCKET_FILL, "GIMP_PATTERN_BUCKET_FILL", NULL }, + { 0, NULL, NULL } + }; + + static GType type = 0; + + if (G_UNLIKELY (! type)) + { + type = g_enum_register_static ("GimpBucketFillModeCompat", values); + gimp_type_set_translation_domain (type, GETTEXT_PACKAGE "-libgimp"); + gimp_type_set_translation_context (type, "bucket-fill-mode-compat"); + gimp_enum_set_value_descriptions (type, descs); + } + + return type; +} + +GType +gimp_channel_type_compat_get_type (void) +{ + static const GEnumValue values[] = + { + { GIMP_RED_CHANNEL, "GIMP_RED_CHANNEL", "red-channel" }, + { GIMP_GREEN_CHANNEL, "GIMP_GREEN_CHANNEL", "green-channel" }, + { GIMP_BLUE_CHANNEL, "GIMP_BLUE_CHANNEL", "blue-channel" }, + { GIMP_GRAY_CHANNEL, "GIMP_GRAY_CHANNEL", "gray-channel" }, + { GIMP_INDEXED_CHANNEL, "GIMP_INDEXED_CHANNEL", "indexed-channel" }, + { GIMP_ALPHA_CHANNEL, "GIMP_ALPHA_CHANNEL", "alpha-channel" }, + { 0, NULL, NULL } + }; + + static const GimpEnumDesc descs[] = + { + { GIMP_RED_CHANNEL, "GIMP_RED_CHANNEL", NULL }, + { GIMP_GREEN_CHANNEL, "GIMP_GREEN_CHANNEL", NULL }, + { GIMP_BLUE_CHANNEL, "GIMP_BLUE_CHANNEL", NULL }, + { GIMP_GRAY_CHANNEL, "GIMP_GRAY_CHANNEL", NULL }, + { GIMP_INDEXED_CHANNEL, "GIMP_INDEXED_CHANNEL", NULL }, + { GIMP_ALPHA_CHANNEL, "GIMP_ALPHA_CHANNEL", NULL }, + { 0, NULL, NULL } + }; + + static GType type = 0; + + if (G_UNLIKELY (! type)) + { + type = g_enum_register_static ("GimpChannelTypeCompat", values); + gimp_type_set_translation_domain (type, GETTEXT_PACKAGE "-libgimp"); + gimp_type_set_translation_context (type, "channel-type-compat"); + gimp_enum_set_value_descriptions (type, descs); + } + + return type; +} + +GType +gimp_clone_type_compat_get_type (void) +{ + static const GEnumValue values[] = + { + { GIMP_IMAGE_CLONE, "GIMP_IMAGE_CLONE", "image-clone" }, + { GIMP_PATTERN_CLONE, "GIMP_PATTERN_CLONE", "pattern-clone" }, + { 0, NULL, NULL } + }; + + static const GimpEnumDesc descs[] = + { + { GIMP_IMAGE_CLONE, "GIMP_IMAGE_CLONE", NULL }, + { GIMP_PATTERN_CLONE, "GIMP_PATTERN_CLONE", NULL }, + { 0, NULL, NULL } + }; + + static GType type = 0; + + if (G_UNLIKELY (! type)) + { + type = g_enum_register_static ("GimpCloneTypeCompat", values); + gimp_type_set_translation_domain (type, GETTEXT_PACKAGE "-libgimp"); + gimp_type_set_translation_context (type, "clone-type-compat"); + gimp_enum_set_value_descriptions (type, descs); + } + + return type; +} + +GType +gimp_convert_dither_type_compat_get_type (void) +{ + static const GEnumValue values[] = + { + { GIMP_NO_DITHER, "GIMP_NO_DITHER", "no-dither" }, + { GIMP_FS_DITHER, "GIMP_FS_DITHER", "fs-dither" }, + { GIMP_FSLOWBLEED_DITHER, "GIMP_FSLOWBLEED_DITHER", "fslowbleed-dither" }, + { GIMP_FIXED_DITHER, "GIMP_FIXED_DITHER", "fixed-dither" }, + { 0, NULL, NULL } + }; + + static const GimpEnumDesc descs[] = + { + { GIMP_NO_DITHER, "GIMP_NO_DITHER", NULL }, + { GIMP_FS_DITHER, "GIMP_FS_DITHER", NULL }, + { GIMP_FSLOWBLEED_DITHER, "GIMP_FSLOWBLEED_DITHER", NULL }, + { GIMP_FIXED_DITHER, "GIMP_FIXED_DITHER", NULL }, + { 0, NULL, NULL } + }; + + static GType type = 0; + + if (G_UNLIKELY (! type)) + { + type = g_enum_register_static ("GimpConvertDitherTypeCompat", values); + gimp_type_set_translation_domain (type, GETTEXT_PACKAGE "-libgimp"); + gimp_type_set_translation_context (type, "convert-dither-type-compat"); + gimp_enum_set_value_descriptions (type, descs); + } + + return type; +} + +GType +gimp_convert_palette_type_compat_get_type (void) +{ + static const GEnumValue values[] = + { + { GIMP_MAKE_PALETTE, "GIMP_MAKE_PALETTE", "make-palette" }, + { GIMP_REUSE_PALETTE, "GIMP_REUSE_PALETTE", "reuse-palette" }, + { GIMP_WEB_PALETTE, "GIMP_WEB_PALETTE", "web-palette" }, + { GIMP_MONO_PALETTE, "GIMP_MONO_PALETTE", "mono-palette" }, + { GIMP_CUSTOM_PALETTE, "GIMP_CUSTOM_PALETTE", "custom-palette" }, + { 0, NULL, NULL } + }; + + static const GimpEnumDesc descs[] = + { + { GIMP_MAKE_PALETTE, "GIMP_MAKE_PALETTE", NULL }, + { GIMP_REUSE_PALETTE, "GIMP_REUSE_PALETTE", NULL }, + { GIMP_WEB_PALETTE, "GIMP_WEB_PALETTE", NULL }, + { GIMP_MONO_PALETTE, "GIMP_MONO_PALETTE", NULL }, + { GIMP_CUSTOM_PALETTE, "GIMP_CUSTOM_PALETTE", NULL }, + { 0, NULL, NULL } + }; + + static GType type = 0; + + if (G_UNLIKELY (! type)) + { + type = g_enum_register_static ("GimpConvertPaletteTypeCompat", values); + gimp_type_set_translation_domain (type, GETTEXT_PACKAGE "-libgimp"); + gimp_type_set_translation_context (type, "convert-palette-type-compat"); + gimp_enum_set_value_descriptions (type, descs); + } + + return type; +} + +GType +gimp_convolve_type_compat_get_type (void) +{ + static const GEnumValue values[] = + { + { GIMP_BLUR_CONVOLVE, "GIMP_BLUR_CONVOLVE", "blur-convolve" }, + { GIMP_SHARPEN_CONVOLVE, "GIMP_SHARPEN_CONVOLVE", "sharpen-convolve" }, + { 0, NULL, NULL } + }; + + static const GimpEnumDesc descs[] = + { + { GIMP_BLUR_CONVOLVE, "GIMP_BLUR_CONVOLVE", NULL }, + { GIMP_SHARPEN_CONVOLVE, "GIMP_SHARPEN_CONVOLVE", NULL }, + { 0, NULL, NULL } + }; + + static GType type = 0; + + if (G_UNLIKELY (! type)) + { + type = g_enum_register_static ("GimpConvolveTypeCompat", values); + gimp_type_set_translation_domain (type, GETTEXT_PACKAGE "-libgimp"); + gimp_type_set_translation_context (type, "convolve-type-compat"); + gimp_enum_set_value_descriptions (type, descs); + } + + return type; +} + +GType +gimp_desaturate_mode_compat_get_type (void) +{ + static const GEnumValue values[] = + { + { GIMP_DESATURATE_LUMINOSITY, "GIMP_DESATURATE_LUMINOSITY", "luminosity" }, + { 0, NULL, NULL } + }; + + static const GimpEnumDesc descs[] = + { + { GIMP_DESATURATE_LUMINOSITY, "GIMP_DESATURATE_LUMINOSITY", NULL }, + { 0, NULL, NULL } + }; + + static GType type = 0; + + if (G_UNLIKELY (! type)) + { + type = g_enum_register_static ("GimpDesaturateModeCompat", values); + gimp_type_set_translation_domain (type, GETTEXT_PACKAGE "-libgimp"); + gimp_type_set_translation_context (type, "desaturate-mode-compat"); + gimp_enum_set_value_descriptions (type, descs); + } + + return type; +} + +GType +gimp_dodge_burn_type_compat_get_type (void) +{ + static const GEnumValue values[] = + { + { GIMP_DODGE, "GIMP_DODGE", "dodge" }, + { GIMP_BURN, "GIMP_BURN", "burn" }, + { 0, NULL, NULL } + }; + + static const GimpEnumDesc descs[] = + { + { GIMP_DODGE, "GIMP_DODGE", NULL }, + { GIMP_BURN, "GIMP_BURN", NULL }, + { 0, NULL, NULL } + }; + + static GType type = 0; + + if (G_UNLIKELY (! type)) + { + type = g_enum_register_static ("GimpDodgeBurnTypeCompat", values); + gimp_type_set_translation_domain (type, GETTEXT_PACKAGE "-libgimp"); + gimp_type_set_translation_context (type, "dodge-burn-type-compat"); + gimp_enum_set_value_descriptions (type, descs); + } + + return type; +} + +GType +gimp_fill_type_compat_get_type (void) +{ + static const GEnumValue values[] = + { + { GIMP_FOREGROUND_FILL, "GIMP_FOREGROUND_FILL", "foreground-fill" }, + { GIMP_BACKGROUND_FILL, "GIMP_BACKGROUND_FILL", "background-fill" }, + { GIMP_WHITE_FILL, "GIMP_WHITE_FILL", "white-fill" }, + { GIMP_TRANSPARENT_FILL, "GIMP_TRANSPARENT_FILL", "transparent-fill" }, + { GIMP_PATTERN_FILL, "GIMP_PATTERN_FILL", "pattern-fill" }, + { 0, NULL, NULL } + }; + + static const GimpEnumDesc descs[] = + { + { GIMP_FOREGROUND_FILL, "GIMP_FOREGROUND_FILL", NULL }, + { GIMP_BACKGROUND_FILL, "GIMP_BACKGROUND_FILL", NULL }, + { GIMP_WHITE_FILL, "GIMP_WHITE_FILL", NULL }, + { GIMP_TRANSPARENT_FILL, "GIMP_TRANSPARENT_FILL", NULL }, + { GIMP_PATTERN_FILL, "GIMP_PATTERN_FILL", NULL }, + { 0, NULL, NULL } + }; + + static GType type = 0; + + if (G_UNLIKELY (! type)) + { + type = g_enum_register_static ("GimpFillTypeCompat", values); + gimp_type_set_translation_domain (type, GETTEXT_PACKAGE "-libgimp"); + gimp_type_set_translation_context (type, "fill-type-compat"); + gimp_enum_set_value_descriptions (type, descs); + } + + return type; +} + +GType +gimp_hue_range_compat_get_type (void) +{ + static const GEnumValue values[] = + { + { GIMP_ALL_HUES, "GIMP_ALL_HUES", "all-hues" }, + { GIMP_RED_HUES, "GIMP_RED_HUES", "red-hues" }, + { GIMP_YELLOW_HUES, "GIMP_YELLOW_HUES", "yellow-hues" }, + { GIMP_GREEN_HUES, "GIMP_GREEN_HUES", "green-hues" }, + { GIMP_CYAN_HUES, "GIMP_CYAN_HUES", "cyan-hues" }, + { GIMP_BLUE_HUES, "GIMP_BLUE_HUES", "blue-hues" }, + { GIMP_MAGENTA_HUES, "GIMP_MAGENTA_HUES", "magenta-hues" }, + { 0, NULL, NULL } + }; + + static const GimpEnumDesc descs[] = + { + { GIMP_ALL_HUES, "GIMP_ALL_HUES", NULL }, + { GIMP_RED_HUES, "GIMP_RED_HUES", NULL }, + { GIMP_YELLOW_HUES, "GIMP_YELLOW_HUES", NULL }, + { GIMP_GREEN_HUES, "GIMP_GREEN_HUES", NULL }, + { GIMP_CYAN_HUES, "GIMP_CYAN_HUES", NULL }, + { GIMP_BLUE_HUES, "GIMP_BLUE_HUES", NULL }, + { GIMP_MAGENTA_HUES, "GIMP_MAGENTA_HUES", NULL }, + { 0, NULL, NULL } + }; + + static GType type = 0; + + if (G_UNLIKELY (! type)) + { + type = g_enum_register_static ("GimpHueRangeCompat", values); + gimp_type_set_translation_domain (type, GETTEXT_PACKAGE "-libgimp"); + gimp_type_set_translation_context (type, "hue-range-compat"); + gimp_enum_set_value_descriptions (type, descs); + } + + return type; +} + +GType +gimp_icon_type_compat_get_type (void) +{ + static const GEnumValue values[] = + { + { GIMP_ICON_TYPE_STOCK_ID, "GIMP_ICON_TYPE_STOCK_ID", "id" }, + { 0, NULL, NULL } + }; + + static const GimpEnumDesc descs[] = + { + { GIMP_ICON_TYPE_STOCK_ID, "GIMP_ICON_TYPE_STOCK_ID", NULL }, + { 0, NULL, NULL } + }; + + static GType type = 0; + + if (G_UNLIKELY (! type)) + { + type = g_enum_register_static ("GimpIconTypeCompat", values); + gimp_type_set_translation_domain (type, GETTEXT_PACKAGE "-libgimp"); + gimp_type_set_translation_context (type, "icon-type-compat"); + gimp_enum_set_value_descriptions (type, descs); + } + + return type; +} + +GType +gimp_interpolation_type_compat_get_type (void) +{ + static const GEnumValue values[] = + { + { GIMP_INTERPOLATION_LANCZOS, "GIMP_INTERPOLATION_LANCZOS", "lanczos" }, + { 0, NULL, NULL } + }; + + static const GimpEnumDesc descs[] = + { + { GIMP_INTERPOLATION_LANCZOS, "GIMP_INTERPOLATION_LANCZOS", NULL }, + { 0, NULL, NULL } + }; + + static GType type = 0; + + if (G_UNLIKELY (! type)) + { + type = g_enum_register_static ("GimpInterpolationTypeCompat", values); + gimp_type_set_translation_domain (type, GETTEXT_PACKAGE "-libgimp"); + gimp_type_set_translation_context (type, "interpolation-type-compat"); + gimp_enum_set_value_descriptions (type, descs); + } + + return type; +} + +GType +gimp_layer_mode_effects_get_type (void) +{ + static const GEnumValue values[] = + { + { GIMP_NORMAL_MODE, "GIMP_NORMAL_MODE", "normal-mode" }, + { GIMP_DISSOLVE_MODE, "GIMP_DISSOLVE_MODE", "dissolve-mode" }, + { GIMP_BEHIND_MODE, "GIMP_BEHIND_MODE", "behind-mode" }, + { GIMP_MULTIPLY_MODE, "GIMP_MULTIPLY_MODE", "multiply-mode" }, + { GIMP_SCREEN_MODE, "GIMP_SCREEN_MODE", "screen-mode" }, + { GIMP_OVERLAY_MODE, "GIMP_OVERLAY_MODE", "overlay-mode" }, + { GIMP_DIFFERENCE_MODE, "GIMP_DIFFERENCE_MODE", "difference-mode" }, + { GIMP_ADDITION_MODE, "GIMP_ADDITION_MODE", "addition-mode" }, + { GIMP_SUBTRACT_MODE, "GIMP_SUBTRACT_MODE", "subtract-mode" }, + { GIMP_DARKEN_ONLY_MODE, "GIMP_DARKEN_ONLY_MODE", "darken-only-mode" }, + { GIMP_LIGHTEN_ONLY_MODE, "GIMP_LIGHTEN_ONLY_MODE", "lighten-only-mode" }, + { GIMP_HUE_MODE, "GIMP_HUE_MODE", "hue-mode" }, + { GIMP_SATURATION_MODE, "GIMP_SATURATION_MODE", "saturation-mode" }, + { GIMP_COLOR_MODE, "GIMP_COLOR_MODE", "color-mode" }, + { GIMP_VALUE_MODE, "GIMP_VALUE_MODE", "value-mode" }, + { GIMP_DIVIDE_MODE, "GIMP_DIVIDE_MODE", "divide-mode" }, + { GIMP_DODGE_MODE, "GIMP_DODGE_MODE", "dodge-mode" }, + { GIMP_BURN_MODE, "GIMP_BURN_MODE", "burn-mode" }, + { GIMP_HARDLIGHT_MODE, "GIMP_HARDLIGHT_MODE", "hardlight-mode" }, + { GIMP_SOFTLIGHT_MODE, "GIMP_SOFTLIGHT_MODE", "softlight-mode" }, + { GIMP_GRAIN_EXTRACT_MODE, "GIMP_GRAIN_EXTRACT_MODE", "grain-extract-mode" }, + { GIMP_GRAIN_MERGE_MODE, "GIMP_GRAIN_MERGE_MODE", "grain-merge-mode" }, + { GIMP_COLOR_ERASE_MODE, "GIMP_COLOR_ERASE_MODE", "color-erase-mode" }, + { 0, NULL, NULL } + }; + + static const GimpEnumDesc descs[] = + { + { GIMP_NORMAL_MODE, "GIMP_NORMAL_MODE", NULL }, + { GIMP_DISSOLVE_MODE, "GIMP_DISSOLVE_MODE", NULL }, + { GIMP_BEHIND_MODE, "GIMP_BEHIND_MODE", NULL }, + { GIMP_MULTIPLY_MODE, "GIMP_MULTIPLY_MODE", NULL }, + { GIMP_SCREEN_MODE, "GIMP_SCREEN_MODE", NULL }, + { GIMP_OVERLAY_MODE, "GIMP_OVERLAY_MODE", NULL }, + { GIMP_DIFFERENCE_MODE, "GIMP_DIFFERENCE_MODE", NULL }, + { GIMP_ADDITION_MODE, "GIMP_ADDITION_MODE", NULL }, + { GIMP_SUBTRACT_MODE, "GIMP_SUBTRACT_MODE", NULL }, + { GIMP_DARKEN_ONLY_MODE, "GIMP_DARKEN_ONLY_MODE", NULL }, + { GIMP_LIGHTEN_ONLY_MODE, "GIMP_LIGHTEN_ONLY_MODE", NULL }, + { GIMP_HUE_MODE, "GIMP_HUE_MODE", NULL }, + { GIMP_SATURATION_MODE, "GIMP_SATURATION_MODE", NULL }, + { GIMP_COLOR_MODE, "GIMP_COLOR_MODE", NULL }, + { GIMP_VALUE_MODE, "GIMP_VALUE_MODE", NULL }, + { GIMP_DIVIDE_MODE, "GIMP_DIVIDE_MODE", NULL }, + { GIMP_DODGE_MODE, "GIMP_DODGE_MODE", NULL }, + { GIMP_BURN_MODE, "GIMP_BURN_MODE", NULL }, + { GIMP_HARDLIGHT_MODE, "GIMP_HARDLIGHT_MODE", NULL }, + { GIMP_SOFTLIGHT_MODE, "GIMP_SOFTLIGHT_MODE", NULL }, + { GIMP_GRAIN_EXTRACT_MODE, "GIMP_GRAIN_EXTRACT_MODE", NULL }, + { GIMP_GRAIN_MERGE_MODE, "GIMP_GRAIN_MERGE_MODE", NULL }, + { GIMP_COLOR_ERASE_MODE, "GIMP_COLOR_ERASE_MODE", NULL }, + { 0, NULL, NULL } + }; + + static GType type = 0; + + if (G_UNLIKELY (! type)) + { + type = g_enum_register_static ("GimpLayerModeEffects", values); + gimp_type_set_translation_domain (type, GETTEXT_PACKAGE "-libgimp"); + gimp_type_set_translation_context (type, "layer-mode-effects"); + gimp_enum_set_value_descriptions (type, descs); + } + + return type; +} + +GType +gimp_transfer_mode_compat_get_type (void) +{ + static const GEnumValue values[] = + { + { GIMP_SHADOWS, "GIMP_SHADOWS", "shadows" }, + { GIMP_MIDTONES, "GIMP_MIDTONES", "midtones" }, + { GIMP_HIGHLIGHTS, "GIMP_HIGHLIGHTS", "highlights" }, + { 0, NULL, NULL } + }; + + static const GimpEnumDesc descs[] = + { + { GIMP_SHADOWS, "GIMP_SHADOWS", NULL }, + { GIMP_MIDTONES, "GIMP_MIDTONES", NULL }, + { GIMP_HIGHLIGHTS, "GIMP_HIGHLIGHTS", NULL }, + { 0, NULL, NULL } + }; + + static GType type = 0; + + if (G_UNLIKELY (! type)) + { + type = g_enum_register_static ("GimpTransferModeCompat", values); + gimp_type_set_translation_domain (type, GETTEXT_PACKAGE "-libgimp"); + gimp_type_set_translation_context (type, "transfer-mode-compat"); + gimp_enum_set_value_descriptions (type, descs); + } + + return type; +} + + +/* Generated data ends here */ + diff --git a/libgimpbase/gimpcompatenums.h b/libgimpbase/gimpcompatenums.h new file mode 100644 index 0000000..173dee9 --- /dev/null +++ b/libgimpbase/gimpcompatenums.h @@ -0,0 +1,252 @@ +/* LIBGIMP - The GIMP Library + * Copyright (C) 1995-1997 Peter Mattis and Spencer Kimball + * + * This library is free software: you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This library 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see + * <https://www.gnu.org/licenses/>. + */ + +#ifndef __GIMP_COMPAT_ENUMS_H__ +#define __GIMP_COMPAT_ENUMS_H__ + + +G_BEGIN_DECLS + +/* These enums exist only for compatibility, their nicks are needed + * for config file parsing; they are registered in gimp_base_init(). + */ + + +#define GIMP_TYPE_ADD_MASK_TYPE_COMPAT (gimp_add_mask_type_compat_get_type ()) + +GType gimp_add_mask_type_compat_get_type (void) G_GNUC_CONST; + +typedef enum +{ + GIMP_ADD_WHITE_MASK = GIMP_ADD_MASK_WHITE, + GIMP_ADD_BLACK_MASK = GIMP_ADD_MASK_BLACK, + GIMP_ADD_ALPHA_MASK = GIMP_ADD_MASK_ALPHA, + GIMP_ADD_ALPHA_TRANSFER_MASK = GIMP_ADD_MASK_ALPHA_TRANSFER, + GIMP_ADD_SELECTION_MASK = GIMP_ADD_MASK_SELECTION, + GIMP_ADD_COPY_MASK = GIMP_ADD_MASK_COPY, + GIMP_ADD_CHANNEL_MASK = GIMP_ADD_MASK_CHANNEL +} GimpAddMaskTypeCompat; + + +#define GIMP_TYPE_BLEND_MODE_COMPAT (gimp_blend_mode_compat_get_type ()) + +GType gimp_blend_mode_compat_get_type (void) G_GNUC_CONST; + +typedef enum +{ + GIMP_FG_BG_RGB_MODE = GIMP_BLEND_FG_BG_RGB, + GIMP_FG_BG_HSV_MODE = GIMP_BLEND_FG_BG_HSV, + GIMP_FG_TRANSPARENT_MODE = GIMP_BLEND_FG_TRANSPARENT, + GIMP_CUSTOM_MODE = GIMP_BLEND_CUSTOM +} GimpBlendModeCompat; + + +#define GIMP_TYPE_BUCKET_FILL_MODE_COMPAT (gimp_bucket_fill_mode_compat_get_type ()) + +GType gimp_bucket_fill_mode_compat_get_type (void) G_GNUC_CONST; + +typedef enum +{ + GIMP_FG_BUCKET_FILL = GIMP_BUCKET_FILL_FG, + GIMP_BG_BUCKET_FILL = GIMP_BUCKET_FILL_BG, + GIMP_PATTERN_BUCKET_FILL = GIMP_BUCKET_FILL_PATTERN +} GimpBucketFillModeCompat; + + +#define GIMP_TYPE_CHANNEL_TYPE_COMPAT (gimp_channel_type_compat_get_type ()) + +GType gimp_channel_type_compat_get_type (void) G_GNUC_CONST; + +typedef enum +{ + GIMP_RED_CHANNEL = GIMP_CHANNEL_RED, + GIMP_GREEN_CHANNEL = GIMP_CHANNEL_GREEN, + GIMP_BLUE_CHANNEL = GIMP_CHANNEL_BLUE, + GIMP_GRAY_CHANNEL = GIMP_CHANNEL_GRAY, + GIMP_INDEXED_CHANNEL = GIMP_CHANNEL_INDEXED, + GIMP_ALPHA_CHANNEL = GIMP_CHANNEL_ALPHA +} GimpChannelTypeCompat; + + +#define GIMP_TYPE_CLONE_TYPE_COMPAT (gimp_clone_type_compat_get_type ()) + +GType gimp_clone_type_compat_get_type (void) G_GNUC_CONST; + +typedef enum +{ + GIMP_IMAGE_CLONE = GIMP_CLONE_IMAGE, + GIMP_PATTERN_CLONE = GIMP_CLONE_PATTERN +} GimpCloneTypeCompat; + + +#define GIMP_TYPE_CONVERT_DITHER_TYPE_COMPAT (gimp_convert_dither_type_compat_get_type ()) + +GType gimp_convert_dither_type_compat_get_type (void) G_GNUC_CONST; + +typedef enum +{ + GIMP_NO_DITHER, + GIMP_FS_DITHER, + GIMP_FSLOWBLEED_DITHER, + GIMP_FIXED_DITHER +} GimpConvertDitherTypeCompat; + + +#define GIMP_TYPE_CONVERT_PALETTE_TYPE_COMPAT (gimp_convert_palette_type_compat_get_type ()) + +GType gimp_convert_palette_type_compat_get_type (void) G_GNUC_CONST; + +typedef enum +{ + GIMP_MAKE_PALETTE, + GIMP_REUSE_PALETTE, + GIMP_WEB_PALETTE, + GIMP_MONO_PALETTE, + GIMP_CUSTOM_PALETTE +} GimpConvertPaletteTypeCompat; + + +#define GIMP_TYPE_CONVOLVE_TYPE_COMPAT (gimp_convolve_type_compat_get_type ()) + +GType gimp_convolve_type_compat_get_type (void) G_GNUC_CONST; + +typedef enum +{ + GIMP_BLUR_CONVOLVE = GIMP_CONVOLVE_BLUR, + GIMP_SHARPEN_CONVOLVE = GIMP_CONVOLVE_SHARPEN +} GimpConvolveTypeCompat; + + +#define GIMP_TYPE_DESATURATE_MODE_COMPAT (gimp_desaturate_mode_compat_get_type ()) + +GType gimp_desaturate_mode_compat_get_type (void) G_GNUC_CONST; + +typedef enum +{ + GIMP_DESATURATE_LUMINOSITY = GIMP_DESATURATE_LUMA +} GimpDesaturateModeCompat; + + +#define GIMP_TYPE_DODGE_BURN_TYPE_COMPAT (gimp_dodge_burn_type_compat_get_type ()) + +GType gimp_dodge_burn_type_compat_get_type (void) G_GNUC_CONST; + +typedef enum +{ + GIMP_DODGE = GIMP_DODGE_BURN_TYPE_DODGE, + GIMP_BURN = GIMP_DODGE_BURN_TYPE_BURN +} GimpDodgeBurnTypeCompat; + + +#define GIMP_TYPE_FILL_TYPE_COMPAT (gimp_fill_type_compat_get_type ()) + +GType gimp_fill_type_compat_get_type (void) G_GNUC_CONST; + +typedef enum +{ + GIMP_FOREGROUND_FILL = GIMP_FILL_FOREGROUND, + GIMP_BACKGROUND_FILL = GIMP_FILL_BACKGROUND, + GIMP_WHITE_FILL = GIMP_FILL_WHITE, + GIMP_TRANSPARENT_FILL = GIMP_FILL_TRANSPARENT, + GIMP_PATTERN_FILL = GIMP_FILL_PATTERN +} GimpFillTypeCompat; + + +#define GIMP_TYPE_HUE_RANGE_COMPAT (gimp_hue_range_compat_get_type ()) + +GType gimp_hue_range_compat_get_type (void) G_GNUC_CONST; + +typedef enum +{ + GIMP_ALL_HUES = GIMP_HUE_RANGE_ALL, + GIMP_RED_HUES = GIMP_HUE_RANGE_RED, + GIMP_YELLOW_HUES = GIMP_HUE_RANGE_YELLOW, + GIMP_GREEN_HUES = GIMP_HUE_RANGE_GREEN, + GIMP_CYAN_HUES = GIMP_HUE_RANGE_CYAN, + GIMP_BLUE_HUES = GIMP_HUE_RANGE_BLUE, + GIMP_MAGENTA_HUES = GIMP_HUE_RANGE_MAGENTA +} GimpHueRangeCompat; + + +#define GIMP_TYPE_ICON_TYPE_COMPAT (gimp_icon_type_compat_get_type ()) + +GType gimp_icon_type_compat_get_type (void) G_GNUC_CONST; + +typedef enum +{ + GIMP_ICON_TYPE_STOCK_ID = GIMP_ICON_TYPE_ICON_NAME +} GimpIconTypeCompat; + + +#define GIMP_TYPE_INTERPOLATION_TYPE_COMPAT (gimp_interpolation_type_compat_get_type ()) + +GType gimp_interpolation_type_compat_get_type (void) G_GNUC_CONST; + +typedef enum +{ + GIMP_INTERPOLATION_LANCZOS = GIMP_INTERPOLATION_NOHALO +} GimpInterpolationTypeCompat; + + +#define GIMP_TYPE_LAYER_MODE_EFFECTS (gimp_layer_mode_effects_get_type ()) + +GType gimp_layer_mode_effects_get_type (void) G_GNUC_CONST; + +typedef enum +{ + GIMP_NORMAL_MODE, + GIMP_DISSOLVE_MODE, + GIMP_BEHIND_MODE, + GIMP_MULTIPLY_MODE, + GIMP_SCREEN_MODE, + GIMP_OVERLAY_MODE, + GIMP_DIFFERENCE_MODE, + GIMP_ADDITION_MODE, + GIMP_SUBTRACT_MODE, + GIMP_DARKEN_ONLY_MODE, + GIMP_LIGHTEN_ONLY_MODE, + GIMP_HUE_MODE, + GIMP_SATURATION_MODE, + GIMP_COLOR_MODE, + GIMP_VALUE_MODE, + GIMP_DIVIDE_MODE, + GIMP_DODGE_MODE, + GIMP_BURN_MODE, + GIMP_HARDLIGHT_MODE, + GIMP_SOFTLIGHT_MODE, + GIMP_GRAIN_EXTRACT_MODE, + GIMP_GRAIN_MERGE_MODE, + GIMP_COLOR_ERASE_MODE +} GimpLayerModeEffects; + + +#define GIMP_TYPE_TRANSFER_MODE_COMPAT (gimp_transfer_mode_compat_get_type ()) + +GType gimp_transfer_mode_compat_get_type (void) G_GNUC_CONST; + +typedef enum +{ + GIMP_SHADOWS = GIMP_TRANSFER_SHADOWS, + GIMP_MIDTONES = GIMP_TRANSFER_MIDTONES, + GIMP_HIGHLIGHTS = GIMP_TRANSFER_HIGHLIGHTS +} GimpTransferModeCompat; + + +G_END_DECLS + +#endif /* __GIMP_COMPAT_ENUMS_H__ */ diff --git a/libgimpbase/gimpcpuaccel.c b/libgimpbase/gimpcpuaccel.c new file mode 100644 index 0000000..86a2d49 --- /dev/null +++ b/libgimpbase/gimpcpuaccel.c @@ -0,0 +1,531 @@ +/* LIBGIMP - The GIMP Library + * Copyright (C) 1995-1997 Peter Mattis and Spencer Kimball + * + * This library is free software: you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see + * <https://www.gnu.org/licenses/>. + */ + +/* + * x86 bits Copyright (C) Manish Singh <yosh@gimp.org> + */ + +/* + * PPC CPU acceleration detection was taken from DirectFB but seems to be + * originating from mpeg2dec with the following copyright: + * + * Copyright (C) 1999-2001 Aaron Holtzman <aholtzma@ess.engr.uvic.ca> + */ + +#include "config.h" + +#include <string.h> +#include <signal.h> +#include <setjmp.h> + +#include <glib.h> + +#include "gimpcpuaccel.h" + + +/** + * SECTION: gimpcpuaccel + * @title: gimpcpuaccel + * @short_description: Functions to query and configure CPU acceleration. + * + * Functions to query and configure CPU acceleration. + **/ + + +static GimpCpuAccelFlags cpu_accel (void) G_GNUC_CONST; + + +static gboolean use_cpu_accel = TRUE; + + +/** + * gimp_cpu_accel_get_support: + * + * Query for CPU acceleration support. + * + * Return value: #GimpCpuAccelFlags as supported by the CPU. + * + * Since: 2.4 + */ +GimpCpuAccelFlags +gimp_cpu_accel_get_support (void) +{ + return use_cpu_accel ? cpu_accel () : GIMP_CPU_ACCEL_NONE; +} + +/** + * gimp_cpu_accel_set_use: + * @use: whether to use CPU acceleration features or not + * + * This function is for internal use only. + * + * Since: 2.4 + */ +void +gimp_cpu_accel_set_use (gboolean use) +{ + use_cpu_accel = use ? TRUE : FALSE; +} + + +#if defined(ARCH_X86) && defined(USE_MMX) && defined(__GNUC__) + +#define HAVE_ACCEL 1 + + +typedef enum +{ + ARCH_X86_VENDOR_NONE, + ARCH_X86_VENDOR_INTEL, + ARCH_X86_VENDOR_AMD, + ARCH_X86_VENDOR_CENTAUR, + ARCH_X86_VENDOR_CYRIX, + ARCH_X86_VENDOR_NSC, + ARCH_X86_VENDOR_TRANSMETA, + ARCH_X86_VENDOR_NEXGEN, + ARCH_X86_VENDOR_RISE, + ARCH_X86_VENDOR_UMC, + ARCH_X86_VENDOR_SIS, + ARCH_X86_VENDOR_HYGON, + ARCH_X86_VENDOR_UNKNOWN = 0xff +} X86Vendor; + +enum +{ + ARCH_X86_INTEL_FEATURE_MMX = 1 << 23, + ARCH_X86_INTEL_FEATURE_XMM = 1 << 25, + ARCH_X86_INTEL_FEATURE_XMM2 = 1 << 26, + + ARCH_X86_AMD_FEATURE_MMXEXT = 1 << 22, + ARCH_X86_AMD_FEATURE_3DNOW = 1 << 31, + + ARCH_X86_CENTAUR_FEATURE_MMX = 1 << 23, + ARCH_X86_CENTAUR_FEATURE_MMXEXT = 1 << 24, + ARCH_X86_CENTAUR_FEATURE_3DNOW = 1 << 31, + + ARCH_X86_CYRIX_FEATURE_MMX = 1 << 23, + ARCH_X86_CYRIX_FEATURE_MMXEXT = 1 << 24 +}; + +enum +{ + ARCH_X86_INTEL_FEATURE_PNI = 1 << 0, + ARCH_X86_INTEL_FEATURE_SSSE3 = 1 << 9, + ARCH_X86_INTEL_FEATURE_SSE4_1 = 1 << 19, + ARCH_X86_INTEL_FEATURE_SSE4_2 = 1 << 20, + ARCH_X86_INTEL_FEATURE_AVX = 1 << 28 +}; + +#if !defined(ARCH_X86_64) && (defined(PIC) || defined(__PIC__)) +#define cpuid(op,eax,ebx,ecx,edx) \ + __asm__ ("movl %%ebx, %%esi\n\t" \ + "cpuid\n\t" \ + "xchgl %%ebx,%%esi" \ + : "=a" (eax), \ + "=S" (ebx), \ + "=c" (ecx), \ + "=d" (edx) \ + : "0" (op)) +#else +#define cpuid(op,eax,ebx,ecx,edx) \ + __asm__ ("cpuid" \ + : "=a" (eax), \ + "=b" (ebx), \ + "=c" (ecx), \ + "=d" (edx) \ + : "0" (op)) +#endif + + +static X86Vendor +arch_get_vendor (void) +{ + guint32 eax, ebx, ecx, edx; + union{ + gchar idaschar[16]; + int idasint[4]; + }id; + +#ifndef ARCH_X86_64 + /* Only need to check this on ia32 */ + __asm__ ("pushfl\n\t" + "pushfl\n\t" + "popl %0\n\t" + "movl %0,%1\n\t" + "xorl $0x200000,%0\n\t" + "pushl %0\n\t" + "popfl\n\t" + "pushfl\n\t" + "popl %0\n\t" + "popfl" + : "=a" (eax), + "=c" (ecx) + : + : "cc"); + + if (eax == ecx) + return ARCH_X86_VENDOR_NONE; +#endif + + cpuid (0, eax, ebx, ecx, edx); + + if (eax == 0) + return ARCH_X86_VENDOR_NONE; + + id.idasint[0] = ebx; + id.idasint[1] = edx; + id.idasint[2] = ecx; + + id.idaschar[12] = '\0'; + +#ifdef ARCH_X86_64 + if (strcmp (id.idaschar, "AuthenticAMD") == 0) + return ARCH_X86_VENDOR_AMD; + else if (strcmp (id.idaschar, "HygonGenuine") == 0) + return ARCH_X86_VENDOR_HYGON; + else if (strcmp (id.idaschar, "GenuineIntel") == 0) + return ARCH_X86_VENDOR_INTEL; +#else + if (strcmp (id.idaschar, "GenuineIntel") == 0) + return ARCH_X86_VENDOR_INTEL; + else if (strcmp (id.idaschar, "AuthenticAMD") == 0) + return ARCH_X86_VENDOR_AMD; + else if (strcmp (id.idaschar, "HygonGenuine") == 0) + return ARCH_X86_VENDOR_HYGON; + else if (strcmp (id.idaschar, "CentaurHauls") == 0) + return ARCH_X86_VENDOR_CENTAUR; + else if (strcmp (id.idaschar, "CyrixInstead") == 0) + return ARCH_X86_VENDOR_CYRIX; + else if (strcmp (id.idaschar, "Geode by NSC") == 0) + return ARCH_X86_VENDOR_NSC; + else if (strcmp (id.idaschar, "GenuineTMx86") == 0 || + strcmp (id.idaschar, "TransmetaCPU") == 0) + return ARCH_X86_VENDOR_TRANSMETA; + else if (strcmp (id.idaschar, "NexGenDriven") == 0) + return ARCH_X86_VENDOR_NEXGEN; + else if (strcmp (id.idaschar, "RiseRiseRise") == 0) + return ARCH_X86_VENDOR_RISE; + else if (strcmp (id.idaschar, "UMC UMC UMC ") == 0) + return ARCH_X86_VENDOR_UMC; + else if (strcmp (id.idaschar, "SiS SiS SiS ") == 0) + return ARCH_X86_VENDOR_SIS; +#endif + + return ARCH_X86_VENDOR_UNKNOWN; +} + +static guint32 +arch_accel_intel (void) +{ + guint32 caps = 0; + +#ifdef USE_MMX + { + guint32 eax, ebx, ecx, edx; + + cpuid (1, eax, ebx, ecx, edx); + + if ((edx & ARCH_X86_INTEL_FEATURE_MMX) == 0) + return 0; + + caps = GIMP_CPU_ACCEL_X86_MMX; + +#ifdef USE_SSE + if (edx & ARCH_X86_INTEL_FEATURE_XMM) + caps |= GIMP_CPU_ACCEL_X86_SSE | GIMP_CPU_ACCEL_X86_MMXEXT; + + if (edx & ARCH_X86_INTEL_FEATURE_XMM2) + caps |= GIMP_CPU_ACCEL_X86_SSE2; + + if (ecx & ARCH_X86_INTEL_FEATURE_PNI) + caps |= GIMP_CPU_ACCEL_X86_SSE3; + + if (ecx & ARCH_X86_INTEL_FEATURE_SSSE3) + caps |= GIMP_CPU_ACCEL_X86_SSSE3; + + if (ecx & ARCH_X86_INTEL_FEATURE_SSE4_1) + caps |= GIMP_CPU_ACCEL_X86_SSE4_1; + + if (ecx & ARCH_X86_INTEL_FEATURE_SSE4_2) + caps |= GIMP_CPU_ACCEL_X86_SSE4_2; + + if (ecx & ARCH_X86_INTEL_FEATURE_AVX) + caps |= GIMP_CPU_ACCEL_X86_AVX; +#endif /* USE_SSE */ + } +#endif /* USE_MMX */ + + return caps; +} + +static guint32 +arch_accel_amd (void) +{ + guint32 caps; + + caps = arch_accel_intel (); + +#ifdef USE_MMX + { + guint32 eax, ebx, ecx, edx; + + cpuid (0x80000000, eax, ebx, ecx, edx); + + if (eax < 0x80000001) + return caps; + +#ifdef USE_SSE + cpuid (0x80000001, eax, ebx, ecx, edx); + + if (edx & ARCH_X86_AMD_FEATURE_3DNOW) + caps |= GIMP_CPU_ACCEL_X86_3DNOW; + + if (edx & ARCH_X86_AMD_FEATURE_MMXEXT) + caps |= GIMP_CPU_ACCEL_X86_MMXEXT; +#endif /* USE_SSE */ + } +#endif /* USE_MMX */ + + return caps; +} + +static guint32 +arch_accel_centaur (void) +{ + guint32 caps; + + caps = arch_accel_intel (); + +#ifdef USE_MMX + { + guint32 eax, ebx, ecx, edx; + + cpuid (0x80000000, eax, ebx, ecx, edx); + + if (eax < 0x80000001) + return caps; + + cpuid (0x80000001, eax, ebx, ecx, edx); + + if (edx & ARCH_X86_CENTAUR_FEATURE_MMX) + caps |= GIMP_CPU_ACCEL_X86_MMX; + +#ifdef USE_SSE + if (edx & ARCH_X86_CENTAUR_FEATURE_3DNOW) + caps |= GIMP_CPU_ACCEL_X86_3DNOW; + + if (edx & ARCH_X86_CENTAUR_FEATURE_MMXEXT) + caps |= GIMP_CPU_ACCEL_X86_MMXEXT; +#endif /* USE_SSE */ + } +#endif /* USE_MMX */ + + return caps; +} + +static guint32 +arch_accel_cyrix (void) +{ + guint32 caps; + + caps = arch_accel_intel (); + +#ifdef USE_MMX + { + guint32 eax, ebx, ecx, edx; + + cpuid (0, eax, ebx, ecx, edx); + + if (eax != 2) + return caps; + + cpuid (0x80000001, eax, ebx, ecx, edx); + + if (edx & ARCH_X86_CYRIX_FEATURE_MMX) + caps |= GIMP_CPU_ACCEL_X86_MMX; + +#ifdef USE_SSE + if (edx & ARCH_X86_CYRIX_FEATURE_MMXEXT) + caps |= GIMP_CPU_ACCEL_X86_MMXEXT; +#endif /* USE_SSE */ + } +#endif /* USE_MMX */ + + return caps; +} + +#ifdef USE_SSE +static jmp_buf sigill_return; + +static void +sigill_handler (gint n) +{ + longjmp (sigill_return, 1); +} + +static gboolean +arch_accel_sse_os_support (void) +{ + if (setjmp (sigill_return)) + { + return FALSE; + } + else + { + signal (SIGILL, sigill_handler); + __asm__ __volatile__ ("xorps %xmm0, %xmm0"); + signal (SIGILL, SIG_DFL); + } + + return TRUE; +} +#endif /* USE_SSE */ + +static guint32 +arch_accel (void) +{ + guint32 caps; + X86Vendor vendor; + + vendor = arch_get_vendor (); + + switch (vendor) + { + case ARCH_X86_VENDOR_NONE: + caps = 0; + break; + + case ARCH_X86_VENDOR_AMD: + case ARCH_X86_VENDOR_HYGON: + caps = arch_accel_amd (); + break; + + case ARCH_X86_VENDOR_CENTAUR: + caps = arch_accel_centaur (); + break; + + case ARCH_X86_VENDOR_CYRIX: + case ARCH_X86_VENDOR_NSC: + caps = arch_accel_cyrix (); + break; + + /* check for what Intel speced, even if UNKNOWN */ + default: + caps = arch_accel_intel (); + break; + } + +#ifdef USE_SSE + if ((caps & GIMP_CPU_ACCEL_X86_SSE) && !arch_accel_sse_os_support ()) + caps &= ~(GIMP_CPU_ACCEL_X86_SSE | GIMP_CPU_ACCEL_X86_SSE2); +#endif + + return caps; +} + +#endif /* ARCH_X86 && USE_MMX && __GNUC__ */ + + +#if defined(ARCH_PPC) && defined (USE_ALTIVEC) + +#if defined(HAVE_ALTIVEC_SYSCTL) + +#include <sys/sysctl.h> + +#define HAVE_ACCEL 1 + +static guint32 +arch_accel (void) +{ + gint sels[2] = { CTL_HW, HW_VECTORUNIT }; + gboolean has_vu = FALSE; + gsize length = sizeof(has_vu); + gint err; + + err = sysctl (sels, 2, &has_vu, &length, NULL, 0); + + if (err == 0 && has_vu) + return GIMP_CPU_ACCEL_PPC_ALTIVEC; + + return 0; +} + +#elif defined(__GNUC__) + +#define HAVE_ACCEL 1 + +static sigjmp_buf jmpbuf; +static volatile sig_atomic_t canjump = 0; + +static void +sigill_handler (gint sig) +{ + if (!canjump) + { + signal (sig, SIG_DFL); + raise (sig); + } + + canjump = 0; + siglongjmp (jmpbuf, 1); +} + +static guint32 +arch_accel (void) +{ + signal (SIGILL, sigill_handler); + + if (sigsetjmp (jmpbuf, 1)) + { + signal (SIGILL, SIG_DFL); + return 0; + } + + canjump = 1; + + asm volatile ("mtspr 256, %0\n\t" + "vand %%v0, %%v0, %%v0" + : + : "r" (-1)); + + signal (SIGILL, SIG_DFL); + + return GIMP_CPU_ACCEL_PPC_ALTIVEC; +} +#endif /* __GNUC__ */ + +#endif /* ARCH_PPC && USE_ALTIVEC */ + + +static GimpCpuAccelFlags +cpu_accel (void) +{ +#ifdef HAVE_ACCEL + static guint32 accel = ~0U; + + if (accel != ~0U) + return accel; + + accel = arch_accel (); + + return (GimpCpuAccelFlags) accel; + +#else /* !HAVE_ACCEL */ + return GIMP_CPU_ACCEL_NONE; +#endif +} diff --git a/libgimpbase/gimpcpuaccel.h b/libgimpbase/gimpcpuaccel.h new file mode 100644 index 0000000..03c0d4b --- /dev/null +++ b/libgimpbase/gimpcpuaccel.h @@ -0,0 +1,76 @@ +/* LIBGIMP - The GIMP Library + * Copyright (C) 1995-1997 Peter Mattis and Spencer Kimball + * + * This library is free software: you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This library 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see + * <https://www.gnu.org/licenses/>. + */ + +#if !defined (__GIMP_BASE_H_INSIDE__) && !defined (GIMP_BASE_COMPILATION) +#error "Only <libgimpbase/gimpbase.h> can be included directly." +#endif + +#ifndef __GIMP_CPU_ACCEL_H__ +#define __GIMP_CPU_ACCEL_H__ + +G_BEGIN_DECLS + + +/** + * GimpCpuAccelFlags: + * @GIMP_CPU_ACCEL_NONE: None + * @GIMP_CPU_ACCEL_X86_MMX: MMX + * @GIMP_CPU_ACCEL_X86_3DNOW: 3dNow + * @GIMP_CPU_ACCEL_X86_MMXEXT: MMXEXT + * @GIMP_CPU_ACCEL_X86_SSE: SSE + * @GIMP_CPU_ACCEL_X86_SSE2: SSE2 + * @GIMP_CPU_ACCEL_X86_SSE3: SSE3 + * @GIMP_CPU_ACCEL_X86_SSSE3: SSSE3 + * @GIMP_CPU_ACCEL_X86_SSE4_1: SSE4_1 + * @GIMP_CPU_ACCEL_X86_SSE4_2: SSE4_2 + * @GIMP_CPU_ACCEL_X86_AVX: AVX + * @GIMP_CPU_ACCEL_PPC_ALTIVEC: Altivec + * + * Types of detectable CPU accelerations + **/ +typedef enum +{ + GIMP_CPU_ACCEL_NONE = 0x0, + + /* x86 accelerations */ + GIMP_CPU_ACCEL_X86_MMX = 0x80000000, + GIMP_CPU_ACCEL_X86_3DNOW = 0x40000000, + GIMP_CPU_ACCEL_X86_MMXEXT = 0x20000000, + GIMP_CPU_ACCEL_X86_SSE = 0x10000000, + GIMP_CPU_ACCEL_X86_SSE2 = 0x08000000, + GIMP_CPU_ACCEL_X86_SSE3 = 0x02000000, + GIMP_CPU_ACCEL_X86_SSSE3 = 0x01000000, + GIMP_CPU_ACCEL_X86_SSE4_1 = 0x00800000, + GIMP_CPU_ACCEL_X86_SSE4_2 = 0x00400000, + GIMP_CPU_ACCEL_X86_AVX = 0x00200000, + + /* powerpc accelerations */ + GIMP_CPU_ACCEL_PPC_ALTIVEC = 0x04000000 +} GimpCpuAccelFlags; + + +GimpCpuAccelFlags gimp_cpu_accel_get_support (void); + + +/* for internal use only */ +void gimp_cpu_accel_set_use (gboolean use); + + +G_END_DECLS + +#endif /* __GIMP_CPU_ACCEL_H__ */ diff --git a/libgimpbase/gimpdatafiles.c b/libgimpbase/gimpdatafiles.c new file mode 100644 index 0000000..535f275 --- /dev/null +++ b/libgimpbase/gimpdatafiles.c @@ -0,0 +1,225 @@ +/* LIBGIMP - The GIMP Library + * Copyright (C) 1995-1997 Peter Mattis and Spencer Kimball + * + * Datafiles module copyight (C) 1996 Federico Mena Quintero + * federico@nuclecu.unam.mx + * + * This library is free software: you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see + * <https://www.gnu.org/licenses/>. + */ + +#include "config.h" + +#include <string.h> + +#include <gio/gio.h> + +#include "gimpbasetypes.h" + +#include "gimpdatafiles.h" +#include "gimpenv.h" + + +/** + * SECTION: gimpdatafiles + * @title: gimpdatafiles + * @short_description: Functions to handle GIMP data files. + * + * Functions to handle GIMP data files. + **/ + + +static inline gboolean is_script (const gchar *filename); + + +/* public functions */ + +gboolean +gimp_datafiles_check_extension (const gchar *filename, + const gchar *extension) +{ + gint name_len; + gint ext_len; + + g_return_val_if_fail (filename != NULL, FALSE); + g_return_val_if_fail (extension != NULL, FALSE); + + name_len = strlen (filename); + ext_len = strlen (extension); + + if (! (name_len && ext_len && (name_len > ext_len))) + return FALSE; + + return (g_ascii_strcasecmp (&filename[name_len - ext_len], extension) == 0); +} + +void +gimp_datafiles_read_directories (const gchar *path_str, + GFileTest flags, + GimpDatafileLoaderFunc loader_func, + gpointer user_data) +{ + gchar *local_path; + GList *path; + GList *list; + + g_return_if_fail (path_str != NULL); + g_return_if_fail (loader_func != NULL); + + local_path = g_strdup (path_str); + + path = gimp_path_parse (local_path, 256, TRUE, NULL); + + for (list = path; list; list = g_list_next (list)) + { + const gchar *dirname = list->data; + GDir *dir; + + dir = g_dir_open (dirname, 0, NULL); + + if (dir) + { + const gchar *dir_ent; + + while ((dir_ent = g_dir_read_name (dir))) + { + gchar *filename; + GFile *file; + GFileInfo *info; + + filename = g_build_filename (dirname, dir_ent, NULL); + file = g_file_new_for_path (filename); + + info = g_file_query_info (file, + G_FILE_ATTRIBUTE_STANDARD_IS_HIDDEN "," + G_FILE_ATTRIBUTE_STANDARD_TYPE "," + G_FILE_ATTRIBUTE_ACCESS_CAN_EXECUTE "," + "time::*", + G_FILE_QUERY_INFO_NONE, + NULL, NULL); + + if (info) + { + GimpDatafileData file_data; + GFileType file_type; + + file_data.filename = filename; + file_data.dirname = dirname; + file_data.basename = dir_ent; + + file_data.atime = + g_file_info_get_attribute_uint64 (info, + G_FILE_ATTRIBUTE_TIME_ACCESS); + + file_data.mtime = + g_file_info_get_attribute_uint64 (info, + G_FILE_ATTRIBUTE_TIME_MODIFIED); + + file_data.ctime = + g_file_info_get_attribute_uint64 (info, + G_FILE_ATTRIBUTE_TIME_CREATED); + + file_type = g_file_info_get_file_type (info); + + if (g_file_info_get_is_hidden (info)) + { + /* do nothing */ + } + else if (flags & G_FILE_TEST_EXISTS) + { + (* loader_func) (&file_data, user_data); + } + else if ((flags & G_FILE_TEST_IS_REGULAR) && + (file_type == G_FILE_TYPE_REGULAR)) + { + (* loader_func) (&file_data, user_data); + } + else if ((flags & G_FILE_TEST_IS_DIR) && + (file_type == G_FILE_TYPE_DIRECTORY)) + { + (* loader_func) (&file_data, user_data); + } + else if ((flags & G_FILE_TEST_IS_SYMLINK) && + (file_type == G_FILE_TYPE_SYMBOLIC_LINK)) + { + (* loader_func) (&file_data, user_data); + } + else if ((flags & G_FILE_TEST_IS_EXECUTABLE) && + (g_file_info_get_attribute_boolean (info, + G_FILE_ATTRIBUTE_ACCESS_CAN_EXECUTE) || + ((file_type == G_FILE_TYPE_REGULAR) && + is_script (filename)))) + { + (* loader_func) (&file_data, user_data); + } + + g_object_unref (info); + } + + g_object_unref (file); + g_free (filename); + } + + g_dir_close (dir); + } + } + + gimp_path_free (path); + g_free (local_path); +} + + +/* private functions */ + +static inline gboolean +is_script (const gchar *filename) +{ +#ifdef G_OS_WIN32 + /* On Windows there is no concept like the Unix executable flag. + * There is a weak emulation provided by the MS C Runtime using file + * extensions (com, exe, cmd, bat). This needs to be extended to treat + * scripts (Python, Perl, ...) as executables, too. We use the PATHEXT + * variable, which is also used by cmd.exe. + */ + static gchar **exts = NULL; + + const gchar *ext = strrchr (filename, '.'); + gchar *pathext; + gint i; + + if (exts == NULL) + { + pathext = (gchar *) g_getenv ("PATHEXT"); + if (pathext != NULL) + { + exts = g_strsplit (pathext, G_SEARCHPATH_SEPARATOR_S, 100); + } + else + { + exts = g_new (gchar *, 1); + exts[0] = NULL; + } + } + + i = 0; + while (exts[i] != NULL) + { + if (g_ascii_strcasecmp (ext, exts[i]) == 0) + return TRUE; + i++; + } +#endif /* G_OS_WIN32 */ + + return FALSE; +} diff --git a/libgimpbase/gimpdatafiles.h b/libgimpbase/gimpdatafiles.h new file mode 100644 index 0000000..c75edab --- /dev/null +++ b/libgimpbase/gimpdatafiles.h @@ -0,0 +1,72 @@ +/* LIBGIMP - The GIMP Library + * Copyright (C) 1995-1997 Peter Mattis and Spencer Kimball + * + * Datafiles module copyight (C) 1996 Federico Mena Quintero + * federico@nuclecu.unam.mx + * + * This library is free software: you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see + * <https://www.gnu.org/licenses/>. + */ + +#if !defined (__GIMP_BASE_H_INSIDE__) && !defined (GIMP_BASE_COMPILATION) +#error "Only <libgimpbase/gimpbase.h> can be included directly." +#endif + +#ifndef __GIMP_DATAFILES_H__ +#define __GIMP_DATAFILES_H__ + +#include <time.h> + +G_BEGIN_DECLS + + +/** + * GimpDatafileData: + * @filename: the data file's full path. + * @dirname: the folder the data file is in. + * @basename: the data file's basename. + * @atime: the last time the file was accessed for reading. + * @mtime: the last time the file was modified. + * @ctime: the time the file was created. + * + * This structure is passed to the #GimpDatafileLoaderFunc given to + * gimp_datafiles_read_directories() for each file encountered in the + * data path. + **/ +struct _GimpDatafileData +{ + const gchar *filename; + const gchar *dirname; + const gchar *basename; + + time_t atime; + time_t mtime; + time_t ctime; +}; + + +GIMP_DEPRECATED +gboolean gimp_datafiles_check_extension (const gchar *filename, + const gchar *extension); + +GIMP_DEPRECATED_FOR(GFileEnumerator) +void gimp_datafiles_read_directories (const gchar *path_str, + GFileTest flags, + GimpDatafileLoaderFunc loader_func, + gpointer user_data); + + +G_END_DECLS + +#endif /* __GIMP_DATAFILES_H__ */ diff --git a/libgimpbase/gimpenv.c b/libgimpbase/gimpenv.c new file mode 100644 index 0000000..10696a5 --- /dev/null +++ b/libgimpbase/gimpenv.c @@ -0,0 +1,1277 @@ +/* LIBGIMP - The GIMP Library + * Copyright (C) 1995-1997 Peter Mattis and Spencer Kimball + * + * gimpenv.c + * Copyright (C) 1999 Tor Lillqvist <tml@iki.fi> + * + * This library is free software: you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see + * <https://www.gnu.org/licenses/>. + */ + +#include "config.h" + +#include <errno.h> +#include <string.h> +#include <sys/types.h> + +#ifdef HAVE_UNISTD_H +#include <unistd.h> +#endif + +#ifdef PLATFORM_OSX +#include <AppKit/AppKit.h> +#endif + +#include <gio/gio.h> +#include <glib/gstdio.h> + +#undef GIMP_DISABLE_DEPRECATED +#include "gimpbasetypes.h" + +#define __GIMP_ENV_C__ +#include "gimpenv.h" +#include "gimpversion.h" +#include "gimpreloc.h" + +#ifdef G_OS_WIN32 +#define STRICT +#define WIN32_LEAN_AND_MEAN +#include <windows.h> +#include <io.h> +#ifndef S_IWUSR +# define S_IWUSR _S_IWRITE +#endif +#ifndef S_IWGRP +#define S_IWGRP (_S_IWRITE>>3) +#define S_IWOTH (_S_IWRITE>>6) +#endif +#ifndef S_ISDIR +# define __S_ISTYPE(mode, mask) (((mode) & _S_IFMT) == (mask)) +# define S_ISDIR(mode) __S_ISTYPE((mode), _S_IFDIR) +#endif +#define uid_t gint +#define gid_t gint +#define geteuid() 0 +#define getegid() 0 + +#include <shlobj.h> + +/* Constant available since Shell32.dll 4.72 */ +#ifndef CSIDL_APPDATA +#define CSIDL_APPDATA 0x001a +#endif + +#endif + + +/** + * SECTION: gimpenv + * @title: gimpenv + * @short_description: Functions to access the GIMP environment. + * + * A set of functions to find the locations of GIMP's data directories + * and configuration files. + **/ + + +static gchar * gimp_env_get_dir (const gchar *gimp_env_name, + const gchar *compile_time_dir, + const gchar *relative_subdir); +#ifdef G_OS_WIN32 +static gchar * get_special_folder (gint csidl); +#endif + + +const guint gimp_major_version = GIMP_MAJOR_VERSION; +const guint gimp_minor_version = GIMP_MINOR_VERSION; +const guint gimp_micro_version = GIMP_MICRO_VERSION; + + +/** + * gimp_env_init: + * @plug_in: must be %TRUE if this function is called from a plug-in + * + * You don't need to care about this function. It is being called for + * you automatically (by means of the MAIN() macro that every plug-in + * runs). Calling it again will cause a fatal error. + * + * Since: 2.4 + */ +void +gimp_env_init (gboolean plug_in) +{ + static gboolean gimp_env_initialized = FALSE; + const gchar *data_home = g_get_user_data_dir (); + + if (gimp_env_initialized) + g_error ("gimp_env_init() must only be called once!"); + + gimp_env_initialized = TRUE; + +#ifndef G_OS_WIN32 + if (plug_in) + { + _gimp_reloc_init_lib (NULL); + } + else if (_gimp_reloc_init (NULL)) + { + /* Set $LD_LIBRARY_PATH to ensure that plugins can be loaded. */ + + const gchar *ldpath = g_getenv ("LD_LIBRARY_PATH"); + gchar *libdir = g_build_filename (gimp_installation_directory (), + "lib", + NULL); + + if (ldpath && *ldpath) + { + gchar *tmp = g_strconcat (libdir, ":", ldpath, NULL); + + g_setenv ("LD_LIBRARY_PATH", tmp, TRUE); + + g_free (tmp); + } + else + { + g_setenv ("LD_LIBRARY_PATH", libdir, TRUE); + } + + g_free (libdir); + } +#endif + + /* The user data directory (XDG_DATA_HOME on Unix) is used to store + * various data, like crash logs (win32) or recently used file history + * (by GTK+). Yet it may be absent, in particular on non-Linux + * platforms. Make sure it exists. + */ + if (! g_file_test (data_home, G_FILE_TEST_IS_DIR)) + { + if (g_mkdir_with_parents (data_home, S_IRUSR | S_IWUSR | S_IXUSR) != 0) + { + g_warning ("Failed to create the data directory '%s': %s", + data_home, g_strerror (errno)); + } + } +} + +/** + * gimp_directory: + * + * Returns the user-specific GIMP settings directory. If the + * environment variable GIMP2_DIRECTORY exists, it is used. If it is + * an absolute path, it is used as is. If it is a relative path, it + * is taken to be a subdirectory of the home directory. If it is a + * relative path, and no home directory can be determined, it is taken + * to be a subdirectory of gimp_data_directory(). + * + * The usual case is that no GIMP2_DIRECTORY environment variable + * exists, and then we use the GIMPDIR subdirectory of the local + * configuration directory: + * + * - UNIX: $XDG_CONFIG_HOME (defaults to $HOME/.config/) + * + * - Windows: CSIDL_APPDATA + * + * - OSX (UNIX exception): the Application Support Directory. + * + * If neither the configuration nor home directory exist, + * g_get_user_config_dir() will return {tmp}/{user_name}/.config/ where + * the temporary directory {tmp} and the {user_name} are determined + * according to platform rules. + * + * In any case, we always return some non-empty string, whether it + * corresponds to an existing directory or not. + * + * In config files such as gimprc, the string ${gimp_dir} expands to + * this directory. + * + * The returned string is owned by GIMP and must not be modified or + * freed. The returned string is in the encoding used for filenames by + * GLib, which isn't necessarily UTF-8 (on Windows it is always + * UTF-8.) + * + * Returns: The user-specific GIMP settings directory. + **/ +const gchar * +gimp_directory (void) +{ + static gchar *gimp_dir = NULL; + static gchar *last_env_gimp_dir = NULL; + + const gchar *env_gimp_dir; + + env_gimp_dir = g_getenv ("GIMP2_DIRECTORY"); + + if (gimp_dir) + { + gboolean gimp2_directory_changed = FALSE; + + /* We have constructed the gimp_dir already. We can return + * gimp_dir unless some parameter gimp_dir depends on has + * changed. For now we just check for changes to GIMP2_DIRECTORY + */ + gimp2_directory_changed = + (env_gimp_dir == NULL && + last_env_gimp_dir != NULL) || + (env_gimp_dir != NULL && + last_env_gimp_dir == NULL) || + (env_gimp_dir != NULL && + last_env_gimp_dir != NULL && + strcmp (env_gimp_dir, last_env_gimp_dir) != 0); + + if (! gimp2_directory_changed) + { + return gimp_dir; + } + else + { + /* Free the old gimp_dir and go on to update it */ + g_free (gimp_dir); + gimp_dir = NULL; + } + } + + /* Remember the GIMP2_DIRECTORY to next invocation so we can check + * if it changes + */ + g_free (last_env_gimp_dir); + last_env_gimp_dir = g_strdup (env_gimp_dir); + + if (env_gimp_dir) + { + if (g_path_is_absolute (env_gimp_dir)) + { + gimp_dir = g_strdup (env_gimp_dir); + } + else + { + const gchar *home_dir = g_get_home_dir (); + + if (home_dir) + gimp_dir = g_build_filename (home_dir, env_gimp_dir, NULL); + else + gimp_dir = g_build_filename (gimp_data_directory (), env_gimp_dir, NULL); + } + } + else if (g_path_is_absolute (GIMPDIR)) + { + gimp_dir = g_strdup (GIMPDIR); + } + else + { +#ifdef PLATFORM_OSX + + NSAutoreleasePool *pool; + NSArray *path; + NSString *library_dir; + + pool = [[NSAutoreleasePool alloc] init]; + + path = NSSearchPathForDirectoriesInDomains (NSApplicationSupportDirectory, + NSUserDomainMask, YES); + library_dir = [path objectAtIndex:0]; + + gimp_dir = g_build_filename ([library_dir UTF8String], + GIMPDIR, GIMP_USER_VERSION, NULL); + + [pool drain]; + +#elif defined G_OS_WIN32 + + gchar *conf_dir = get_special_folder (CSIDL_APPDATA); + + gimp_dir = g_build_filename (conf_dir, + GIMPDIR, GIMP_USER_VERSION, NULL); + g_free(conf_dir); + +#else /* UNIX */ + + /* g_get_user_config_dir () always returns a path as a non-null + * and non-empty string + */ + gimp_dir = g_build_filename (g_get_user_config_dir (), + GIMPDIR, GIMP_USER_VERSION, NULL); + +#endif /* PLATFORM_OSX */ + } + + return gimp_dir; +} + +#ifdef G_OS_WIN32 + +/* Taken from glib 2.35 code. */ +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; +} + +static HMODULE libgimpbase_dll = NULL; + +/* Minimal DllMain that just stores the handle to this DLL */ + +BOOL WINAPI /* Avoid silly "no previous prototype" gcc warning */ +DllMain (HINSTANCE hinstDLL, + DWORD fdwReason, + LPVOID lpvReserved); + +BOOL WINAPI +DllMain (HINSTANCE hinstDLL, + DWORD fdwReason, + LPVOID lpvReserved) +{ + switch (fdwReason) + { + case DLL_PROCESS_ATTACH: + libgimpbase_dll = hinstDLL; + break; + } + + return TRUE; +} + +#endif + +/** + * gimp_installation_directory: + * + * Returns the top installation directory of GIMP. On Unix the + * compile-time defined installation prefix is used. On Windows, the + * installation directory as deduced from the executable's full + * filename is used. On OSX we ask [NSBundle mainBundle] for the + * resource path to check if GIMP is part of a relocatable bundle. + * + * In config files such as gimprc, the string ${gimp_installation_dir} + * expands to this directory. + * + * The returned string is owned by GIMP and must not be modified or + * freed. The returned string is in the encoding used for filenames by + * GLib, which isn't necessarily UTF-8. (On Windows it always is + * UTF-8.) + * + * Since: 2.8 + * + * Returns: The toplevel installation directory of GIMP. + **/ +const gchar * +gimp_installation_directory (void) +{ + static gchar *toplevel = NULL; + + if (toplevel) + return toplevel; + +#ifdef G_OS_WIN32 + + toplevel = g_win32_get_package_installation_directory_of_module (libgimpbase_dll); + if (! toplevel) + g_error ("g_win32_get_package_installation_directory_of_module() failed"); + +#elif PLATFORM_OSX + + { + NSAutoreleasePool *pool; + NSString *resource_path; + gchar *basename; + gchar *basepath; + gchar *dirname; + + pool = [[NSAutoreleasePool alloc] init]; + + resource_path = [[NSBundle mainBundle] resourcePath]; + + basename = g_path_get_basename ([resource_path UTF8String]); + basepath = g_path_get_dirname ([resource_path UTF8String]); + dirname = g_path_get_basename (basepath); + + if (! strcmp (basename, ".libs")) + { + /* we are running from the source dir, do normal unix things */ + + toplevel = _gimp_reloc_find_prefix (PREFIX); + } + else if (! strcmp (basename, "bin")) + { + /* we are running the main app, but not from a bundle, the resource + * path is the directory which contains the executable + */ + + toplevel = g_strdup (basepath); + } + else if (! strcmp (basename, "plug-ins")) + { + /* same for plug-ins, go three levels up from prefix/lib/gimp/x.y */ + + gchar *tmp = g_path_get_dirname (basepath); + gchar *tmp2 = g_path_get_dirname (tmp); + + toplevel = g_path_get_dirname (tmp2); + + g_free (tmp); + g_free (tmp2); + } + else if (! strcmp (dirname, "plug-ins")) + { + /* same for plug-ins in subdirectory, go three levels up from prefix/lib/gimp/x.y */ + + gchar *tmp = g_path_get_dirname (basepath); + gchar *tmp2 = g_path_get_dirname (tmp); + gchar *tmp3 = g_path_get_dirname (tmp2); + + toplevel = g_path_get_dirname (tmp3); + + g_free (tmp); + g_free (tmp2); + g_free (tmp3); + } + else + { + /* if none of the above match, we assume that we are really in a bundle */ + + toplevel = g_strdup ([resource_path UTF8String]); + } + + g_free (basename); + g_free (basepath); + g_free (dirname); + + [pool drain]; + } + +#else + + toplevel = _gimp_reloc_find_prefix (PREFIX); + +#endif + + return toplevel; +} + +/** + * gimp_data_directory: + * + * Returns the default top directory for GIMP data. If the environment + * variable GIMP2_DATADIR exists, that is used. It should be an + * absolute pathname. Otherwise, on Unix the compile-time defined + * directory is used. On Windows, the installation directory as + * deduced from the executable's full filename is used. + * + * Note that the actual directories used for GIMP data files can be + * overridden by the user in the preferences dialog. + * + * In config files such as gimprc, the string ${gimp_data_dir} expands + * to this directory. + * + * The returned string is owned by GIMP and must not be modified or + * freed. The returned string is in the encoding used for filenames by + * GLib, which isn't necessarily UTF-8. (On Windows it always is + * UTF-8.) + * + * Returns: The top directory for GIMP data. + **/ +const gchar * +gimp_data_directory (void) +{ + static gchar *gimp_data_dir = NULL; + + if (! gimp_data_dir) + { + gchar *tmp = g_build_filename ("share", + GIMP_PACKAGE, + GIMP_DATA_VERSION, + NULL); + + gimp_data_dir = gimp_env_get_dir ("GIMP2_DATADIR", GIMPDATADIR, tmp); + g_free (tmp); + } + + return gimp_data_dir; +} + +/** + * gimp_locale_directory: + * + * Returns the top directory for GIMP locale files. If the environment + * variable GIMP2_LOCALEDIR exists, that is used. It should be an + * absolute pathname. Otherwise, on Unix the compile-time defined + * directory is used. On Windows, the installation directory as deduced + * from the executable's full filename is used. + * + * The returned string is owned by GIMP and must not be modified or + * freed. The returned string is in the encoding used for filenames by + * the C library, which isn't necessarily UTF-8. (On Windows, unlike + * the other similar functions here, the return value from this + * function is in the system codepage, never in UTF-8. It can thus be + * passed directly to the bindtextdomain() function from libintl which + * does not handle UTF-8.) + * + * Returns: The top directory for GIMP locale files. + */ +const gchar * +gimp_locale_directory (void) +{ + static gchar *gimp_locale_dir = NULL; + + if (! gimp_locale_dir) + { + gchar *tmp = g_build_filename ("share", + "locale", + NULL); + + gimp_locale_dir = gimp_env_get_dir ("GIMP2_LOCALEDIR", LOCALEDIR, tmp); + g_free (tmp); + +#ifdef G_OS_WIN32 + /* FIXME: g_win32_locale_filename_from_utf8() can actually return + * NULL (we had actual cases of this). Not sure exactly what + * gimp_locale_directory() should do when this happens. Anyway + * that's really broken, and something should be done some day + * about this! + */ + tmp = g_win32_locale_filename_from_utf8 (gimp_locale_dir); + g_free (gimp_locale_dir); + gimp_locale_dir = tmp; +#endif + } + + return gimp_locale_dir; +} + +/** + * gimp_sysconf_directory: + * + * Returns the top directory for GIMP config files. If the environment + * variable GIMP2_SYSCONFDIR exists, that is used. It should be an + * absolute pathname. Otherwise, on Unix the compile-time defined + * directory is used. On Windows, the installation directory as deduced + * from the executable's full filename is used. + * + * In config files such as gimprc, the string ${gimp_sysconf_dir} + * expands to this directory. + * + * The returned string is owned by GIMP and must not be modified or + * freed. The returned string is in the encoding used for filenames by + * GLib, which isn't necessarily UTF-8. (On Windows it always is + * UTF-8.). + * + * Returns: The top directory for GIMP config files. + **/ +const gchar * +gimp_sysconf_directory (void) +{ + static gchar *gimp_sysconf_dir = NULL; + + if (! gimp_sysconf_dir) + { + gchar *tmp = g_build_filename ("etc", + GIMP_PACKAGE, + GIMP_SYSCONF_VERSION, + NULL); + + gimp_sysconf_dir = gimp_env_get_dir ("GIMP2_SYSCONFDIR", GIMPSYSCONFDIR, tmp); + g_free (tmp); + } + + return gimp_sysconf_dir; +} + +/** + * gimp_plug_in_directory: + * + * Returns the default top directory for GIMP plug-ins and modules. If + * the environment variable GIMP2_PLUGINDIR exists, that is used. It + * should be an absolute pathname. Otherwise, on Unix the compile-time + * defined directory is used. On Windows, the installation directory + * as deduced from the executable's full filename is used. + * + * Note that the actual directories used for GIMP plug-ins and modules + * can be overridden by the user in the preferences dialog. + * + * In config files such as gimprc, the string ${gimp_plug_in_dir} + * expands to this directory. + * + * The returned string is owned by GIMP and must not be modified or + * freed. The returned string is in the encoding used for filenames by + * GLib, which isn't necessarily UTF-8. (On Windows it always is + * UTF-8.) + * + * Returns: The top directory for GIMP plug_ins and modules. + **/ +const gchar * +gimp_plug_in_directory (void) +{ + static gchar *gimp_plug_in_dir = NULL; + + if (! gimp_plug_in_dir) + { + gchar *tmp = g_build_filename ("lib", + GIMP_PACKAGE, + GIMP_PLUGIN_VERSION, + NULL); + + gimp_plug_in_dir = gimp_env_get_dir ("GIMP2_PLUGINDIR", PLUGINDIR, tmp); + g_free (tmp); + } + + return gimp_plug_in_dir; +} + +/** + * gimp_cache_directory: + * + * Returns the default top directory for GIMP cached files. If the + * environment variable GIMP2_CACHEDIR exists, that is used. It + * should be an absolute pathname. Otherwise, a subdirectory of the + * directory returned by g_get_user_cache_dir() is used. + * + * Note that the actual directories used for GIMP caches files can + * be overridden by the user in the preferences dialog. + * + * In config files such as gimprc, the string ${gimp_cache_dir} + * expands to this directory. + * + * The returned string is owned by GIMP and must not be modified or + * freed. The returned string is in the encoding used for filenames by + * GLib, which isn't necessarily UTF-8. (On Windows it always is + * UTF-8.). + * + * Since: 2.10.10 + * + * Returns: The default top directory for GIMP cached files. + **/ +const gchar * +gimp_cache_directory (void) +{ + static gchar *gimp_cache_dir = NULL; + + if (! gimp_cache_dir) + { + gchar *tmp = g_build_filename (g_get_user_cache_dir (), + GIMP_PACKAGE, + GIMP_USER_VERSION, + NULL); + + gimp_cache_dir = gimp_env_get_dir ("GIMP2_CACHEDIR", NULL, tmp); + g_free (tmp); + } + + return gimp_cache_dir; +} + +/** + * gimp_temp_directory: + * + * Returns the default top directory for GIMP temporary files. If the + * environment variable GIMP2_TEMPDIR exists, that is used. It + * should be an absolute pathname. Otherwise, a subdirectory of the + * directory returned by g_get_tmp_dir() is used. + * + * In config files such as gimprc, the string ${gimp_temp_dir} expands + * to this directory. + * + * Note that the actual directories used for GIMP temporary files can + * be overridden by the user in the preferences dialog. + * + * The returned string is owned by GIMP and must not be modified or + * freed. The returned string is in the encoding used for filenames by + * GLib, which isn't necessarily UTF-8. (On Windows it always is + * UTF-8.). + * + * Since: 2.10.10 + * + * Returns: The default top directory for GIMP temporary files. + **/ +const gchar * +gimp_temp_directory (void) +{ + static gchar *gimp_temp_dir = NULL; + + if (! gimp_temp_dir) + { + gchar *tmp = g_build_filename (g_get_tmp_dir (), + GIMP_PACKAGE, + GIMP_USER_VERSION, + NULL); + + gimp_temp_dir = gimp_env_get_dir ("GIMP2_TEMPDIR", NULL, tmp); + g_free (tmp); + } + + return gimp_temp_dir; +} + +static GFile * +gimp_child_file (const gchar *parent, + const gchar *element, + va_list args) +{ + GFile *file = g_file_new_for_path (parent); + + while (element) + { + GFile *child = g_file_get_child (file, element); + + g_object_unref (file); + file = child; + + element = va_arg (args, const gchar *); + } + + return file; +} + +/** + * gimp_directory_file: + * @first_element: the first element of a path to a file in the + * user's GIMP directory, or %NULL. + * @...: a %NULL terminated list of the remaining elements of the path + * to the file. + * + * Returns a #GFile in the user's GIMP directory, or the data + * directory itself if @first_element is %NULL. + * + * See also: gimp_directory(). + * + * Since: 2.10 + * + * Returns: a new @GFile for the path, Free with g_object_unref(). + **/ +GFile * +gimp_directory_file (const gchar *first_element, + ...) +{ + GFile *file; + va_list args; + + va_start (args, first_element); + file = gimp_child_file (gimp_directory (), first_element, args); + va_end (args); + + return file; +} + +/** + * gimp_installation_directory_file: + * @first_element: the first element of a path to a file in the + * top installation directory, or %NULL. + * @...: a %NULL terminated list of the remaining elements of the path + * to the file. + * + * Returns a #GFile in the installation directory, or the installation + * directory itself if @first_element is %NULL. + * + * See also: gimp_installation_directory(). + * + * Since: 2.10.10 + * + * Returns: a new @GFile for the path, Free with g_object_unref(). + **/ +GFile * +gimp_installation_directory_file (const gchar *first_element, + ...) +{ + GFile *file; + va_list args; + + va_start (args, first_element); + file = gimp_child_file (gimp_installation_directory (), first_element, args); + va_end (args); + + return file; +} + +/** + * gimp_data_directory_file: + * @first_element: the first element of a path to a file in the + * data directory, or %NULL. + * @...: a %NULL terminated list of the remaining elements of the path + * to the file. + * + * Returns a #GFile in the data directory, or the data directory + * itself if @first_element is %NULL. + * + * See also: gimp_data_directory(). + * + * Since: 2.10 + * + * Returns: a new @GFile for the path, Free with g_object_unref(). + **/ +GFile * +gimp_data_directory_file (const gchar *first_element, + ...) +{ + GFile *file; + va_list args; + + va_start (args, first_element); + file = gimp_child_file (gimp_data_directory (), first_element, args); + va_end (args); + + return file; +} + +/** + * gimp_locale_directory_file: + * @first_element: the first element of a path to a file in the + * locale directory, or %NULL. + * @...: a %NULL terminated list of the remaining elements of the path + * to the file. + * + * Returns a #GFile in the locale directory, or the locale directory + * itself if @first_element is %NULL. + * + * See also: gimp_locale_directory(). + * + * Since: 2.10 + * + * Returns: a new @GFile for the path, Free with g_object_unref(). + **/ +GFile * +gimp_locale_directory_file (const gchar *first_element, + ...) +{ + GFile *file; + va_list args; + + va_start (args, first_element); + file = gimp_child_file (gimp_locale_directory (), first_element, args); + va_end (args); + + return file; +} + +/** + * gimp_sysconf_directory_file: + * @first_element: the first element of a path to a file in the + * sysconf directory, or %NULL. + * @...: a %NULL terminated list of the remaining elements of the path + * to the file. + * + * Returns a #GFile in the sysconf directory, or the sysconf directory + * itself if @first_element is %NULL. + * + * See also: gimp_sysconf_directory(). + * + * Since: 2.10 + * + * Returns: a new @GFile for the path, Free with g_object_unref(). + **/ +GFile * +gimp_sysconf_directory_file (const gchar *first_element, + ...) +{ + GFile *file; + va_list args; + + va_start (args, first_element); + file = gimp_child_file (gimp_sysconf_directory (), first_element, args); + va_end (args); + + return file; +} + +/** + * gimp_plug_in_directory_file: + * @first_element: the first element of a path to a file in the + * plug-in directory, or %NULL. + * @...: a %NULL terminated list of the remaining elements of the path + * to the file. + * + * Returns a #GFile in the plug-in directory, or the plug-in directory + * itself if @first_element is %NULL. + * + * See also: gimp_plug_in_directory(). + * + * Since: 2.10 + * + * Returns: a new @GFile for the path, Free with g_object_unref(). + **/ +GFile * +gimp_plug_in_directory_file (const gchar *first_element, + ...) +{ + GFile *file; + va_list args; + + va_start (args, first_element); + file = gimp_child_file (gimp_plug_in_directory (), first_element, args); + va_end (args); + + return file; +} + +/** + * gimp_user_directory: + * @type: the type of user directory to retrieve + * + * This procedure is deprecated! Use g_get_user_special_dir() instead. + * + * Returns: The path to the specified user directory, or %NULL if the + * logical ID was not found. + * + * Since: 2.4 + **/ +const gchar * +gimp_user_directory (GimpUserDirectory type) +{ + return g_get_user_special_dir ((GUserDirectory) type); +} + +/** + * gimp_personal_rc_file: + * @basename: The basename of a rc_file. + * + * Returns the name of a file in the user-specific GIMP settings directory. + * + * The returned string is newly allocated and should be freed with + * g_free() after use. The returned string is in the encoding used for + * filenames by GLib, which isn't necessarily UTF-8. (On Windows it + * always is UTF-8.) + * + * Returns: The name of a file in the user-specific GIMP settings directory. + **/ +gchar * +gimp_personal_rc_file (const gchar *basename) +{ + return g_build_filename (gimp_directory (), basename, NULL); +} + +/** + * gimp_gtkrc: + * + * Returns the name of GIMP's application-specific gtkrc file. + * + * The returned string is owned by GIMP and must not be modified or + * freed. The returned string is in the encoding used for filenames by + * GLib, which isn't necessarily UTF-8. (On Windows it always is + * UTF-8.) + * + * Returns: The name of GIMP's application-specific gtkrc file. + **/ +const gchar * +gimp_gtkrc (void) +{ + static gchar *gimp_gtkrc_filename = NULL; + + if (! gimp_gtkrc_filename) + gimp_gtkrc_filename = g_build_filename (gimp_data_directory (), + "themes", "System", "gtkrc", + NULL); + + return gimp_gtkrc_filename; +} + +/** + * gimp_path_runtime_fix: + * @path: A pointer to a string (allocated with g_malloc) that is + * (or could be) a pathname. + * + * On Windows, this function checks if the string pointed to by @path + * starts with the compile-time prefix, and in that case, replaces the + * prefix with the run-time one. @path should be a pointer to a + * dynamically allocated (with g_malloc, g_strconcat, etc) string. If + * the replacement takes place, the original string is deallocated, + * and *@path is replaced with a pointer to a new string with the + * run-time prefix spliced in. + * + * On Linux, it does the same thing, but only if BinReloc support is enabled. + * On other Unices, it does nothing because those platforms don't have a + * way to find out where our binary is. + */ +static void +gimp_path_runtime_fix (gchar **path) +{ +#if defined (G_OS_WIN32) && defined (PREFIX) + gchar *p; + + /* Yes, I do mean forward slashes below */ + if (strncmp (*path, PREFIX "/", strlen (PREFIX "/")) == 0) + { + /* This is a compile-time entry. Replace the path with the + * real one on this machine. + */ + p = *path; + *path = g_strconcat (gimp_installation_directory (), + "\\", + *path + strlen (PREFIX "/"), + NULL); + g_free (p); + } + /* Replace forward slashes with backslashes, just for + * completeness */ + p = *path; + while ((p = strchr (p, '/')) != NULL) + { + *p = '\\'; + p++; + } +#elif defined (G_OS_WIN32) + /* without defineing PREFIX do something useful too */ + gchar *p = *path; + if (!g_path_is_absolute (p)) + { + *path = g_build_filename (gimp_installation_directory (), *path, NULL); + g_free (p); + } +#else + gchar *p; + + if (strncmp (*path, PREFIX G_DIR_SEPARATOR_S, + strlen (PREFIX G_DIR_SEPARATOR_S)) == 0) + { + /* This is a compile-time entry. Replace the path with the + * real one on this machine. + */ + p = *path; + *path = g_build_filename (gimp_installation_directory (), + *path + strlen (PREFIX G_DIR_SEPARATOR_S), + NULL); + g_free (p); + } +#endif +} + +/** + * gimp_path_parse: + * @path: A list of directories separated by #G_SEARCHPATH_SEPARATOR. + * @max_paths: The maximum number of directories to return. + * @check: %TRUE if you want the directories to be checked. + * @check_failed: Returns a #GList of path elements for which the + * check failed. + * + * Returns: A #GList of all directories in @path. + **/ +GList * +gimp_path_parse (const gchar *path, + gint max_paths, + gboolean check, + GList **check_failed) +{ + gchar **patharray; + GList *list = NULL; + GList *fail_list = NULL; + gint i; + gboolean exists = TRUE; + + if (!path || !*path || max_paths < 1 || max_paths > 256) + return NULL; + + patharray = g_strsplit (path, G_SEARCHPATH_SEPARATOR_S, max_paths); + + for (i = 0; i < max_paths; i++) + { + GString *dir; + + if (! patharray[i]) + break; + +#ifndef G_OS_WIN32 + if (*patharray[i] == '~') + { + dir = g_string_new (g_get_home_dir ()); + g_string_append (dir, patharray[i] + 1); + } + else +#endif + { + gimp_path_runtime_fix (&patharray[i]); + dir = g_string_new (patharray[i]); + } + + if (check) + exists = g_file_test (dir->str, G_FILE_TEST_IS_DIR); + + if (exists) + { + GList *dup; + + /* check for duplicate entries, see bug #784502 */ + for (dup = list; dup; dup = g_list_next (dup)) + { + if (! strcmp (dir->str, dup->data)) + break; + } + + /* only add to the list if it's not a duplicate */ + if (! dup) + list = g_list_prepend (list, g_strdup (dir->str)); + } + else if (check_failed) + { + fail_list = g_list_prepend (fail_list, g_strdup (dir->str)); + } + + g_string_free (dir, TRUE); + } + + g_strfreev (patharray); + + list = g_list_reverse (list); + + if (check && check_failed) + { + fail_list = g_list_reverse (fail_list); + *check_failed = fail_list; + } + + return list; +} + +/** + * gimp_path_to_str: + * @path: A list of directories as returned by gimp_path_parse(). + * + * Returns: A searchpath string separated by #G_SEARCHPATH_SEPARATOR. + **/ +gchar * +gimp_path_to_str (GList *path) +{ + GString *str = NULL; + GList *list; + gchar *retval = NULL; + + for (list = path; list; list = g_list_next (list)) + { + gchar *dir = list->data; + + if (str) + { + g_string_append_c (str, G_SEARCHPATH_SEPARATOR); + g_string_append (str, dir); + } + else + { + str = g_string_new (dir); + } + } + + if (str) + retval = g_string_free (str, FALSE); + + return retval; +} + +/** + * gimp_path_free: + * @path: A list of directories as returned by gimp_path_parse(). + * + * This function frees the memory allocated for the list and the strings + * it contains. + **/ +void +gimp_path_free (GList *path) +{ + g_list_free_full (path, (GDestroyNotify) g_free); +} + +/** + * gimp_path_get_user_writable_dir: + * @path: A list of directories as returned by gimp_path_parse(). + * + * Note that you have to g_free() the returned string. + * + * Returns: The first directory in @path where the user has write permission. + **/ +gchar * +gimp_path_get_user_writable_dir (GList *path) +{ + GList *list; + uid_t euid; + gid_t egid; + GStatBuf filestat; + gint err; + + g_return_val_if_fail (path != NULL, NULL); + + euid = geteuid (); + egid = getegid (); + + for (list = path; list; list = g_list_next (list)) + { + gchar *dir = list->data; + + /* check if directory exists */ + err = g_stat (dir, &filestat); + + /* this is tricky: + * if a file is e.g. owned by the current user but not user-writable, + * the user has no permission to write to the file regardless + * of his group's or other's write permissions + */ + if (!err && S_ISDIR (filestat.st_mode) && + + ((filestat.st_mode & S_IWUSR) || + + ((filestat.st_mode & S_IWGRP) && + (euid != filestat.st_uid)) || + + ((filestat.st_mode & S_IWOTH) && + (euid != filestat.st_uid) && + (egid != filestat.st_gid)))) + { + return g_strdup (dir); + } + } + + return NULL; +} + +static gchar * +gimp_env_get_dir (const gchar *gimp_env_name, + const gchar *compile_time_dir, + const gchar *relative_subdir) +{ + const gchar *env = g_getenv (gimp_env_name); + + if (env) + { + if (! g_path_is_absolute (env)) + g_error ("%s environment variable should be an absolute path.", + gimp_env_name); + + return g_strdup (env); + } + else if (compile_time_dir) + { + gchar *retval = g_strdup (compile_time_dir); + + gimp_path_runtime_fix (&retval); + + return retval; + } + else if (! g_path_is_absolute (relative_subdir)) + { + return g_build_filename (gimp_installation_directory (), + relative_subdir, + NULL); + } + + return g_strdup (relative_subdir); +} diff --git a/libgimpbase/gimpenv.h b/libgimpbase/gimpenv.h new file mode 100644 index 0000000..04a83af --- /dev/null +++ b/libgimpbase/gimpenv.h @@ -0,0 +1,96 @@ +/* LIBGIMP - The GIMP Library + * Copyright (C) 1995-1997 Peter Mattis and Spencer Kimball + * + * gimpenv.h + * Copyright (C) 1999 Tor Lillqvist <tml@iki.fi> + * + * This library is free software: you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see + * <https://www.gnu.org/licenses/>. + */ + +#if !defined (__GIMP_BASE_H_INSIDE__) && !defined (GIMP_BASE_COMPILATION) +#error "Only <libgimpbase/gimpbase.h> can be included directly." +#endif + +#ifndef __GIMP_ENV_H__ +#define __GIMP_ENV_H__ + + +G_BEGIN_DECLS + +/* For information look into the C source or the html documentation */ + + +#ifdef G_OS_WIN32 +# ifdef __GIMP_ENV_C__ +# define GIMPVAR extern __declspec(dllexport) +# else /* !__GIMP_ENV_C__ */ +# define GIMPVAR extern __declspec(dllimport) +# endif /* !__GIMP_ENV_C__ */ +#else /* !G_OS_WIN32 */ +# define GIMPVAR extern +#endif + +GIMPVAR const guint gimp_major_version; +GIMPVAR const guint gimp_minor_version; +GIMPVAR const guint gimp_micro_version; + + +const gchar * gimp_directory (void) G_GNUC_CONST; +const gchar * gimp_installation_directory (void) G_GNUC_CONST; +const gchar * gimp_data_directory (void) G_GNUC_CONST; +const gchar * gimp_locale_directory (void) G_GNUC_CONST; +const gchar * gimp_sysconf_directory (void) G_GNUC_CONST; +const gchar * gimp_plug_in_directory (void) G_GNUC_CONST; +const gchar * gimp_cache_directory (void) G_GNUC_CONST; +const gchar * gimp_temp_directory (void) G_GNUC_CONST; + +GFile * gimp_directory_file (const gchar *first_element, + ...) G_GNUC_MALLOC; +GFile * gimp_installation_directory_file (const gchar *first_element, + ...) G_GNUC_MALLOC; +GFile * gimp_data_directory_file (const gchar *first_element, + ...) G_GNUC_MALLOC; +GFile * gimp_locale_directory_file (const gchar *first_element, + ...) G_GNUC_MALLOC; +GFile * gimp_sysconf_directory_file (const gchar *first_element, + ...) G_GNUC_MALLOC; +GFile * gimp_plug_in_directory_file (const gchar *first_element, + ...) G_GNUC_MALLOC; + +#ifndef GIMP_DISABLE_DEPRECATED +GIMP_DEPRECATED_FOR(g_get_user_special_dir) +const gchar * gimp_user_directory (GimpUserDirectory type) G_GNUC_CONST; +#endif /* !GIMP_DISABLE_DEPRECATED */ + +const gchar * gimp_gtkrc (void) G_GNUC_CONST; +gchar * gimp_personal_rc_file (const gchar *basename) G_GNUC_MALLOC; + +GList * gimp_path_parse (const gchar *path, + gint max_paths, + gboolean check, + GList **check_failed); +gchar * gimp_path_to_str (GList *path) G_GNUC_MALLOC; +void gimp_path_free (GList *path); + +gchar * gimp_path_get_user_writable_dir (GList *path) G_GNUC_MALLOC; + + +/* should be considered private, don't use! */ +void gimp_env_init (gboolean plug_in); + + +G_END_DECLS + +#endif /* __GIMP_ENV_H__ */ diff --git a/libgimpbase/gimplimits.h b/libgimpbase/gimplimits.h new file mode 100644 index 0000000..75a08b9 --- /dev/null +++ b/libgimpbase/gimplimits.h @@ -0,0 +1,97 @@ +/* LIBGIMP - The GIMP Library + * Copyright (C) 1995-1999 Peter Mattis and Spencer Kimball + * + * gimplimits.h + * Copyright (C) 1999 Michael Natterer <mitschel@cs.tu-berlin.de> + * + * This library is free software: you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see + * <https://www.gnu.org/licenses/>. + */ + +#if !defined (__GIMP_BASE_H_INSIDE__) && !defined (GIMP_BASE_COMPILATION) +#error "Only <libgimpbase/gimpbase.h> can be included directly." +#endif + +#ifndef __GIMP_LIMITS_H__ +#define __GIMP_LIMITS_H__ + +G_BEGIN_DECLS + + +/** + * SECTION: gimplimits + * @title: gimplimits + * @short_description: Boundaries of some GIMP data types and some + * global constants. + * + * Boundaries of some GIMP data types and some global constants. + **/ + + +/** + * GIMP_MIN_IMAGE_SIZE: + * + * The minimum width and height of a GIMP image in pixels. + **/ +#define GIMP_MIN_IMAGE_SIZE 1 + +/** + * GIMP_MAX_IMAGE_SIZE: + * + * The maximum width and height of a GIMP image in pixels. This is a + * somewhat arbitrary value that can be used when an upper value for + * pixel sizes is needed; for example to give a spin button an upper + * limit. + **/ +#define GIMP_MAX_IMAGE_SIZE 524288 /* 2^19 */ + + +/** + * GIMP_MIN_RESOLUTION: + * + * The minimum resolution of a GIMP image in pixels per inch. This is + * a somewhat arbitrary value that can be used when a lower value for a + * resolution is needed. GIMP will not accept resolutions smaller than + * this value. + **/ +#define GIMP_MIN_RESOLUTION 5e-3 /* shouldn't display as 0.000 */ + +/** + * GIMP_MAX_RESOLUTION: + * + * The maximum resolution of a GIMP image in pixels per inch. This is + * a somewhat arbitrary value that can be used to when an upper value + * for a resolution is needed. GIMP will not accept resolutions larger + * than this value. + **/ +#define GIMP_MAX_RESOLUTION 1048576.0 + + +/** + * GIMP_MAX_MEMSIZE: + * + * A large but arbitrary value that can be used when an upper limit + * for a memory size (in bytes) is needed. It is smaller than + * %G_MAXDOUBLE since the #GimpMemsizeEntry doesn't handle larger + * values. + **/ +#define GIMP_MAX_MEMSIZE ((guint64) 1 << 42) /* 4 terabyte; + * needs a 64bit variable + * and must be < G_MAXDOUBLE + */ + + +G_END_DECLS + +#endif /* __GIMP_LIMITS_H__ */ diff --git a/libgimpbase/gimpmemsize.c b/libgimpbase/gimpmemsize.c new file mode 100644 index 0000000..4be14b6 --- /dev/null +++ b/libgimpbase/gimpmemsize.c @@ -0,0 +1,288 @@ +/* LIBGIMP - The GIMP Library + * Copyright (C) 1995-1997 Peter Mattis and Spencer Kimball + * + * This library is free software: you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This library 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see + * <https://www.gnu.org/licenses/>. + */ + +#include "config.h" + +#include <errno.h> + +#include <glib-object.h> + +#include "gimpbasetypes.h" + +#include "gimpmemsize.h" + +#include "libgimp/libgimp-intl.h" + + +/** + * SECTION: gimpmemsize + * @title: gimpmemsize + * @short_description: Functions to (de)serialize a given memory size. + * + * Functions to (de)serialize a given memory size. + **/ + + +static void memsize_to_string (const GValue *src_value, + GValue *dest_value); +static void string_to_memsize (const GValue *src_value, + GValue *dest_value); + + +GType +gimp_memsize_get_type (void) +{ + static GType memsize_type = 0; + + if (! memsize_type) + { + const GTypeInfo type_info = { 0, }; + + memsize_type = g_type_register_static (G_TYPE_UINT64, "GimpMemsize", + &type_info, 0); + + g_value_register_transform_func (memsize_type, G_TYPE_STRING, + memsize_to_string); + g_value_register_transform_func (G_TYPE_STRING, memsize_type, + string_to_memsize); + } + + return memsize_type; +} + +/** + * gimp_memsize_serialize: + * @memsize: memory size in bytes + * + * Creates a string representation of a given memory size. This string + * can be parsed by gimp_memsize_deserialize() and can thus be used in + * config files. It should not be displayed to the user. If you need a + * nice human-readable string please use g_format_size(). + * + * Return value: A newly allocated string representation of @memsize. + * + * Since: 2.2 + **/ +gchar * +gimp_memsize_serialize (guint64 memsize) +{ + if (memsize > (1 << 30) && memsize % (1 << 30) == 0) + return g_strdup_printf ("%" G_GUINT64_FORMAT "G", memsize >> 30); + else if (memsize > (1 << 20) && memsize % (1 << 20) == 0) + return g_strdup_printf ("%" G_GUINT64_FORMAT "M", memsize >> 20); + else if (memsize > (1 << 10) && memsize % (1 << 10) == 0) + return g_strdup_printf ("%" G_GUINT64_FORMAT "k", memsize >> 10); + else + return g_strdup_printf ("%" G_GUINT64_FORMAT, memsize); +} + +/** + * gimp_memsize_deserialize: + * @string: a string as returned by gimp_memsize_serialize() + * @memsize: return location for memory size in bytes + * + * Parses a string representation of a memory size as returned by + * gimp_memsize_serialize(). + * + * Return value: %TRUE if the @string was successfully parsed and + * @memsize has been set, %FALSE otherwise. + * + * Since: 2.2 + **/ +gboolean +gimp_memsize_deserialize (const gchar *string, + guint64 *memsize) +{ + gchar *end; + guint64 size; + + g_return_val_if_fail (string != NULL, FALSE); + g_return_val_if_fail (memsize != NULL, FALSE); + + size = g_ascii_strtoull (string, &end, 0); + + if (size == G_MAXUINT64 && errno == ERANGE) + return FALSE; + + if (end && *end) + { + guint shift; + + switch (g_ascii_tolower (*end)) + { + case 'b': + shift = 0; + break; + case 'k': + shift = 10; + break; + case 'm': + shift = 20; + break; + case 'g': + shift = 30; + break; + default: + return FALSE; + } + + /* protect against overflow */ + if (shift) + { + guint64 limit = G_MAXUINT64 >> shift; + + if (size != (size & limit)) + return FALSE; + + size <<= shift; + } + } + + *memsize = size; + + return TRUE; +} + + +/** + * gimp_memsize_to_string: + * @memsize: A memory size in bytes. + * + * This function is deprecated! Use g_format_size() instead. + * + * Return value: A newly allocated human-readable, translated string. + **/ +gchar * +gimp_memsize_to_string (guint64 memsize) +{ + return g_format_size (memsize); +} + + +static void +memsize_to_string (const GValue *src_value, + GValue *dest_value) +{ + g_value_take_string (dest_value, + gimp_memsize_serialize (g_value_get_uint64 (src_value))); +} + +static void +string_to_memsize (const GValue *src_value, + GValue *dest_value) +{ + const gchar *str; + guint64 memsize; + + str = g_value_get_string (src_value); + + if (str && gimp_memsize_deserialize (str, &memsize)) + { + g_value_set_uint64 (dest_value, memsize); + } + else + { + g_warning ("Can't convert string to GimpMemsize."); + } +} + + +/* + * GIMP_TYPE_PARAM_MEMSIZE + */ + +static void gimp_param_memsize_class_init (GParamSpecClass *class); + +/** + * gimp_param_memsize_get_type: + * + * Reveals the object type + * + * Returns: the #GType for a memsize object + * + * Since: 2.4 + **/ +GType +gimp_param_memsize_get_type (void) +{ + static GType spec_type = 0; + + if (! spec_type) + { + const GTypeInfo type_info = + { + sizeof (GParamSpecClass), + NULL, NULL, + (GClassInitFunc) gimp_param_memsize_class_init, + NULL, NULL, + sizeof (GParamSpecUInt64), + 0, NULL, NULL + }; + + spec_type = g_type_register_static (G_TYPE_PARAM_UINT64, + "GimpParamMemsize", + &type_info, 0); + } + + return spec_type; +} + +static void +gimp_param_memsize_class_init (GParamSpecClass *class) +{ + class->value_type = GIMP_TYPE_MEMSIZE; +} + +/** + * gimp_param_spec_memsize: + * @name: Canonical name of the param + * @nick: Nickname of the param + * @blurb: Brief description of param. + * @minimum: Smallest allowed value of the parameter. + * @maximum: Largest allowed value of the parameter. + * @default_value: Value to use if none is assigned. + * @flags: a combination of #GParamFlags + * + * Creates a param spec to hold a memory size value. + * See g_param_spec_internal() for more information. + * + * Returns: a newly allocated #GParamSpec instance + * + * Since: 2.4 + **/ +GParamSpec * +gimp_param_spec_memsize (const gchar *name, + const gchar *nick, + const gchar *blurb, + guint64 minimum, + guint64 maximum, + guint64 default_value, + GParamFlags flags) +{ + GParamSpecUInt64 *pspec; + + pspec = g_param_spec_internal (GIMP_TYPE_PARAM_MEMSIZE, + name, nick, blurb, flags); + + pspec->minimum = minimum; + pspec->maximum = maximum; + pspec->default_value = default_value; + + return G_PARAM_SPEC (pspec); +} + diff --git a/libgimpbase/gimpmemsize.h b/libgimpbase/gimpmemsize.h new file mode 100644 index 0000000..f9f1201 --- /dev/null +++ b/libgimpbase/gimpmemsize.h @@ -0,0 +1,68 @@ +/* LIBGIMP - The GIMP Library + * Copyright (C) 1995-1997 Peter Mattis and Spencer Kimball + * + * This library is free software: you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This library 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see + * <https://www.gnu.org/licenses/>. + */ + +#if !defined (__GIMP_BASE_H_INSIDE__) && !defined (GIMP_BASE_COMPILATION) +#error "Only <libgimpbase/gimpbase.h> can be included directly." +#endif + +#ifndef __GIMP_MEMSIZE_H__ +#define __GIMP_MEMSIZE_H__ + +G_BEGIN_DECLS + + +/** + * GIMP_TYPE_MEMSIZE: + * + * #GIMP_TYPE_MEMSIZE is a #GType derived from #G_TYPE_UINT64. + **/ + +#define GIMP_TYPE_MEMSIZE (gimp_memsize_get_type ()) +#define GIMP_VALUE_HOLDS_MEMSIZE(value) (G_TYPE_CHECK_VALUE_TYPE ((value), GIMP_TYPE_MEMSIZE)) + +GType gimp_memsize_get_type (void) G_GNUC_CONST; + +gchar * gimp_memsize_serialize (guint64 memsize) G_GNUC_MALLOC; +gboolean gimp_memsize_deserialize (const gchar *string, + guint64 *memsize); + +GIMP_DEPRECATED_FOR(g_format_size) +gchar * gimp_memsize_to_string (guint64 memsize) G_GNUC_MALLOC; + + +/* + * GIMP_TYPE_PARAM_MEMSIZE + */ + +#define GIMP_TYPE_PARAM_MEMSIZE (gimp_param_memsize_get_type ()) +#define GIMP_IS_PARAM_SPEC_MEMSIZE(pspec) (G_TYPE_CHECK_INSTANCE_TYPE ((pspec), GIMP_TYPE_PARAM_MEMSIZE)) + +GType gimp_param_memsize_get_type (void) G_GNUC_CONST; + +GParamSpec * gimp_param_spec_memsize (const gchar *name, + const gchar *nick, + const gchar *blurb, + guint64 minimum, + guint64 maximum, + guint64 default_value, + GParamFlags flags); + + +G_END_DECLS + +#endif /* __GIMP_MEMSIZE_H__ */ diff --git a/libgimpbase/gimpmetadata.c b/libgimpbase/gimpmetadata.c new file mode 100644 index 0000000..9f4f53b --- /dev/null +++ b/libgimpbase/gimpmetadata.c @@ -0,0 +1,1816 @@ +/* LIBGIMPBASE - The GIMP Basic Library + * Copyright (C) 1995-1997 Peter Mattis and Spencer Kimball + * + * gimpmetadata.c + * Copyright (C) 2013 Hartmut Kuhse <hartmutkuhse@src.gnome.org> + * Michael Natterer <mitch@gimp.org> + * + * This library is free software: you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see + * <https://www.gnu.org/licenses/>. + */ + +#include "config.h" + +#include <stdlib.h> +#include <string.h> + +#include <gio/gio.h> +#include <gexiv2/gexiv2.h> + +#include "libgimpmath/gimpmath.h" + +#include "gimpbasetypes.h" + +#include "gimplimits.h" +#include "gimpmetadata.h" +#include "gimpunit.h" + +#include "libgimp/libgimp-intl.h" + +typedef struct _GimpMetadataClass GimpMetadataClass; +typedef struct _GimpMetadataPrivate GimpMetadataPrivate; + +struct _GimpMetadata +{ + GExiv2Metadata parent_instance; +}; + +struct _GimpMetadataPrivate +{ + /* dummy entry to avoid a critical warning due to size 0 */ + gpointer _gimp_reserved1; +}; + +struct _GimpMetadataClass +{ + GExiv2MetadataClass parent_class; + + /* Padding for future expansion */ + void (*_gimp_reserved1) (void); + void (*_gimp_reserved2) (void); + void (*_gimp_reserved3) (void); + void (*_gimp_reserved4) (void); + void (*_gimp_reserved5) (void); + void (*_gimp_reserved6) (void); + void (*_gimp_reserved7) (void); + void (*_gimp_reserved8) (void); +}; + +/** + * SECTION: gimpmetadata + * @title: GimpMetadata + * @short_description: Basic functions for handling #GimpMetadata objects. + * @see_also: gimp_image_metadata_load_prepare(), + * gimp_image_metadata_load_finish(), + * gimp_image_metadata_save_prepare(), + * gimp_image_metadata_save_finish(). + * + * Basic functions for handling #GimpMetadata objects. + **/ + + +#define GIMP_METADATA_ERROR gimp_metadata_error_quark () + +static GQuark gimp_metadata_error_quark (void); +static void gimp_metadata_copy_tag (GExiv2Metadata *src, + GExiv2Metadata *dest, + const gchar *tag); +static void gimp_metadata_copy_tags (GExiv2Metadata *src, + GExiv2Metadata *dest, + const gchar **tags); +static void gimp_metadata_add (GimpMetadata *src, + GimpMetadata *dest); + + +static const gchar *tiff_tags[] = +{ + "Xmp.tiff", + "Exif.Image.ImageWidth", + "Exif.Image.ImageLength", + "Exif.Image.BitsPerSample", + "Exif.Image.Compression", + "Exif.Image.PhotometricInterpretation", + "Exif.Image.FillOrder", + "Exif.Image.SamplesPerPixel", + "Exif.Image.StripOffsets", + "Exif.Image.RowsPerStrip", + "Exif.Image.StripByteCounts", + "Exif.Image.PlanarConfiguration" +}; + +static const gchar *jpeg_tags[] = +{ + "Exif.Image.JPEGProc", + "Exif.Image.JPEGInterchangeFormat", + "Exif.Image.JPEGInterchangeFormatLength", + "Exif.Image.JPEGRestartInterval", + "Exif.Image.JPEGLosslessPredictors", + "Exif.Image.JPEGPointTransforms", + "Exif.Image.JPEGQTables", + "Exif.Image.JPEGDCTables", + "Exif.Image.JPEGACTables" +}; + +static const gchar *unsupported_tags[] = +{ + "Exif.Image.SubIFDs", + "Exif.Image.ClipPath", + "Exif.Image.XClipPathUnits", + "Exif.Image.YClipPathUnits", + "Exif.Image.XPTitle", + "Exif.Image.XPComment", + "Exif.Image.XPAuthor", + "Exif.Image.XPKeywords", + "Exif.Image.XPSubject", + "Exif.Image.DNGVersion", + "Exif.Image.DNGBackwardVersion", + "Exif.Iop", + /* FIXME Even though adding the tags below fixes the issue it's not very flexible. + It might be better in the long run if there was a way for a user to configure which + tags to block or a way for us to detect problems with tags before writing them. */ + /* Issues #1367, #2253. Offending tag is PreviewOffset but the other Preview tags + (PreviewResolution, PreviewLength, PreviewImageBorders) also make no sense because + we are not including a Pentax specific preview image. */ + "Exif.Pentax.Preview", + "Exif.PentaxDng.Preview", + /* Never save the complete brand specific MakerNote data. We load and + * should only save the specific brand tags inside the MakerNote. + * Sometimes the MakerNote is invalid or exiv2 doesn't know how to parse + * it. In that case we still get the (invalid) MakerNote, but not the + * individual tags or just a subset of them. + * If there are recognized brand specific tags, exiv2 will create the + * required MakerNote itself (which in can still be invalid but that's an + * exiv2 issue not ours). */ + "Exif.Photo.MakerNote", + "Exif.MakerNote.ByteOrder", + "Exif.MakerNote.Offset", + /* Photoshop resources can contain sensitive data. We should not save the + * unedited original state. */ + "Exif.Image.ImageResources", + "Exif.Image.0x935c", +}; + +static const guint8 minimal_exif[] = +{ + 0xff, 0xd8, 0xff, 0xe0, 0x00, 0x10, 0x4a, 0x46, 0x49, 0x46, 0x00, 0x01, + 0x01, 0x01, 0x00, 0x5a, 0x00, 0x5a, 0x00, 0x00, 0xff, 0xe1 +}; + +static const guint8 wilber_jpg[] = +{ + 0xff, 0xd8, 0xff, 0xe0, 0x00, 0x10, 0x4a, 0x46, 0x49, 0x46, 0x00, 0x01, + 0x01, 0x01, 0x00, 0x5a, 0x00, 0x5a, 0x00, 0x00, 0xff, 0xdb, 0x00, 0x43, + 0x00, 0x50, 0x37, 0x3c, 0x46, 0x3c, 0x32, 0x50, 0x46, 0x41, 0x46, 0x5a, + 0x55, 0x50, 0x5f, 0x78, 0xc8, 0x82, 0x78, 0x6e, 0x6e, 0x78, 0xf5, 0xaf, + 0xb9, 0x91, 0xc8, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xdb, 0x00, 0x43, 0x01, 0x55, 0x5a, + 0x5a, 0x78, 0x69, 0x78, 0xeb, 0x82, 0x82, 0xeb, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xc0, 0x00, 0x11, 0x08, 0x00, 0x10, 0x00, 0x10, 0x03, + 0x01, 0x22, 0x00, 0x02, 0x11, 0x01, 0x03, 0x11, 0x01, 0xff, 0xc4, 0x00, + 0x16, 0x00, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x01, 0x02, 0xff, 0xc4, 0x00, + 0x1e, 0x10, 0x00, 0x01, 0x05, 0x00, 0x02, 0x03, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x02, 0x03, 0x11, 0x31, + 0x04, 0x12, 0x51, 0x61, 0x71, 0xff, 0xc4, 0x00, 0x14, 0x01, 0x01, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xff, 0xc4, 0x00, 0x14, 0x11, 0x01, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xff, 0xda, 0x00, 0x0c, 0x03, 0x01, 0x00, 0x02, 0x11, 0x03, 0x11, + 0x00, 0x3f, 0x00, 0x18, 0xa0, 0x0e, 0x6d, 0xbc, 0xf5, 0xca, 0xf7, 0x78, + 0xb6, 0xfe, 0x3b, 0x23, 0xb2, 0x1d, 0x64, 0x68, 0xf0, 0x8a, 0x39, 0x4b, + 0x74, 0x9c, 0xa5, 0x5f, 0x35, 0x8a, 0xb2, 0x7e, 0xa0, 0xff, 0xd9, 0x00 +}; + +static const guint wilber_jpg_len = G_N_ELEMENTS (wilber_jpg); + +G_DEFINE_TYPE_WITH_PRIVATE (GimpMetadata, gimp_metadata, GEXIV2_TYPE_METADATA) + + +static void +gimp_metadata_class_init (GimpMetadataClass *klass) +{ + if (! gexiv2_metadata_register_xmp_namespace ("http://ns.adobe.com/DICOM/", + "DICOM")) + { + g_printerr ("Failed to register XMP namespace 'DICOM'\n"); + } + + if (! gexiv2_metadata_register_xmp_namespace ("http://darktable.sf.net/", + "darktable")) + { + g_printerr ("Failed to register XMP namespace 'darktable'\n"); + } + + /* Usage example Xmp.GIMP.tagname */ + if (! gexiv2_metadata_register_xmp_namespace ("http://www.gimp.org/xmp/", + "GIMP")) + { + g_printerr ("Failed to register XMP namespace 'GIMP'\n"); + } +} + +static void +gimp_metadata_init (GimpMetadata *metadata) +{ +} + +/** + * gimp_metadata_get_guid: + * + * Generate Version 4 UUID/GUID. + * + * Return value: The new GUID/UUID string. + * + * Since: 2.10 + */ +gchar * +gimp_metadata_get_guid (void) +{ + GRand *rand; + gint bake; + gchar *GUID; + const gchar *szHex = "0123456789abcdef-"; + + rand = g_rand_new (); + +#define DALLOC 36 + + GUID = g_malloc0 (DALLOC + 1); + + for (bake = 0; bake < DALLOC; bake++) + { + gint r = g_rand_int (rand) % 16; + gchar c = ' '; + + switch (bake) + { + default: + c = szHex [r]; + break; + + case 19 : + c = szHex [(r & 0x03) | 0x08]; + break; + + case 8: + case 13: + case 18: + case 23: + c = '-'; + break; + + case 14: + c = '4'; + break; + } + + GUID[bake] = (bake < DALLOC) ? c : 0x00; + } + + g_rand_free (rand); + + return GUID; +} + +/** + * gimp_metadata_add_history: + * + * Add XMP mm History data to file metadata. + * + * Since: 2.10 + */ +void +gimp_metadata_add_xmp_history (GimpMetadata *metadata, + gchar *state_status) +{ + time_t now; + struct tm *now_tm; + gchar *tmp; + char timestr[256]; + char tzstr[7]; + gchar iid_data[256]; + gchar strdata[1024]; + gchar tagstr[1024]; + gchar *uuid; + gchar *did; + gchar *odid; + gint id_count; + gint found; + gint lastfound; + gint count; + int ii; + + static const gchar *tags[] = + { + "Xmp.xmpMM.InstanceID", + "Xmp.xmpMM.DocumentID", + "Xmp.xmpMM.OriginalDocumentID", + "Xmp.xmpMM.History" + }; + + static const gchar *history_tags[] = + { + "/stEvt:action", + "/stEvt:instanceID", + "/stEvt:when", + "/stEvt:softwareAgent", + "/stEvt:changed" + }; + + g_return_if_fail (GIMP_IS_METADATA (metadata)); + + /* Update new Instance ID */ + uuid = gimp_metadata_get_guid (); + + strcpy (iid_data, "xmp.iid:"); + strcat (iid_data, uuid); + + gexiv2_metadata_set_tag_string (GEXIV2_METADATA (metadata), + tags[0], iid_data); + g_free (uuid); + + /* Update new Document ID if none found */ + did = gexiv2_metadata_get_tag_interpreted_string (GEXIV2_METADATA (metadata), + tags[1]); + if (! did || ! strlen (did)) + { + gchar did_data[256]; + + uuid = gimp_metadata_get_guid (); + + strcpy (did_data, "gimp:docid:gimp:"); + strcat (did_data, uuid); + + gexiv2_metadata_set_tag_string (GEXIV2_METADATA (metadata), + tags[1], did_data); + g_free (uuid); + } + + /* Update new Original Document ID if none found */ + odid = gexiv2_metadata_get_tag_interpreted_string (GEXIV2_METADATA (metadata), + tags[2]); + if (! odid || ! strlen (odid)) + { + gchar did_data[256]; + gchar *uuid = gimp_metadata_get_guid (); + + strcpy (did_data, "xmp.did:"); + strcat (did_data, uuid); + + gexiv2_metadata_set_tag_string (GEXIV2_METADATA (metadata), + tags[2], did_data); + g_free (uuid); + } + + /* Handle Xmp.xmpMM.History */ + + gexiv2_metadata_set_xmp_tag_struct (GEXIV2_METADATA (metadata), + tags[3], + GEXIV2_STRUCTURE_XA_SEQ); + + /* Find current number of entries for Xmp.xmpMM.History */ + found = 0; + for (count = 1; count < 65536; count++) + { + lastfound = 0; + for (ii = 0; ii < 5; ii++) + { + g_snprintf (tagstr, sizeof (tagstr), "%s[%d]%s", + tags[3], count, history_tags[ii]); + + if (gexiv2_metadata_has_tag (GEXIV2_METADATA (metadata), + tagstr)) + { + lastfound = 1; + } + } + + if (lastfound == 0) + break; + + found++; + } + + id_count = found + 1; + + memset (tagstr, 0, sizeof (tagstr)); + memset (strdata, 0, sizeof (strdata)); + + g_snprintf (tagstr, sizeof (tagstr), "%s[%d]%s", + tags[3], id_count, history_tags[0]); + + gexiv2_metadata_set_tag_string (GEXIV2_METADATA (metadata), + tagstr, "saved"); + + memset (tagstr, 0, sizeof (tagstr)); + memset (strdata, 0, sizeof (strdata)); + + uuid = gimp_metadata_get_guid (); + + g_snprintf (tagstr, sizeof (tagstr), "%s[%d]%s", + tags[3], id_count, history_tags[1]); + g_snprintf (strdata, sizeof (strdata), "xmp.iid:%s", + uuid); + + gexiv2_metadata_set_tag_string (GEXIV2_METADATA (metadata), + tagstr, strdata); + g_free(uuid); + + memset (tagstr, 0, sizeof (tagstr)); + memset (strdata, 0, sizeof (strdata)); + + g_snprintf (tagstr, sizeof (tagstr), "%s[%d]%s", + tags[3], id_count, history_tags[2]); + + /* get local time */ + time (&now); + now_tm = localtime (&now); + + /* get timezone and fix format */ + strftime (tzstr, 7, "%z", now_tm); + tzstr[6] = '\0'; + tzstr[5] = tzstr[4]; + tzstr[4] = tzstr[3]; + tzstr[3] = ':'; + + /* get current time and timezone string */ + strftime (timestr, 256, "%Y-%m-%dT%H:%M:%S", now_tm); + tmp = g_strdup_printf ("%s%s", timestr, tzstr); + gexiv2_metadata_set_tag_string (GEXIV2_METADATA (metadata), + tagstr, tmp); + g_free (tmp); + + memset (tagstr, 0, sizeof (tagstr)); + memset (strdata, 0, sizeof (strdata)); + + g_snprintf (tagstr, sizeof (tagstr), "%s[%d]%s", + tags[3], id_count, history_tags[3]); + + gexiv2_metadata_set_tag_string (GEXIV2_METADATA (metadata), + tagstr, + "Gimp 2.10 " +#if defined(_WIN32) || defined(__CYGWIN__) || defined(__MINGW32__) + "(Windows)"); +#elif defined(__linux__) + "(Linux)"); +#elif defined(__APPLE__) && defined(__MACH__) + "(Mac OS)"); +#elif defined(unix) || defined(__unix__) || defined(__unix) + "(Unix)"); +#else + "(Unknown)"); +#endif + + memset (tagstr, 0, sizeof (tagstr)); + memset (strdata, 0, sizeof (strdata)); + + g_snprintf (tagstr, sizeof (tagstr), "%s[%d]%s", + tags[3], id_count, history_tags[4]); + + strcpy (strdata, "/"); + strcat (strdata, state_status); + + gexiv2_metadata_set_tag_string (GEXIV2_METADATA (metadata), + tagstr, strdata); +} + +/** + * gimp_metadata_new: + * + * Creates a new #GimpMetadata instance. + * + * Return value: The new #GimpMetadata. + * + * Since: 2.10 + */ +GimpMetadata * +gimp_metadata_new (void) +{ + GimpMetadata *metadata = NULL; + + if (gexiv2_initialize ()) + { + metadata = g_object_new (GIMP_TYPE_METADATA, NULL); + + if (! gexiv2_metadata_open_buf (GEXIV2_METADATA (metadata), + wilber_jpg, wilber_jpg_len, + NULL)) + { + g_object_unref (metadata); + + return NULL; + } + } + + return metadata; +} + +/** + * gimp_metadata_duplicate: + * @metadata: The object to duplicate, or %NULL. + * + * Duplicates a #GimpMetadata instance. + * + * Return value: The new #GimpMetadata, or %NULL if @metadata is %NULL. + * + * Since: 2.10 + */ +GimpMetadata * +gimp_metadata_duplicate (GimpMetadata *metadata) +{ + GimpMetadata *new_metadata = NULL; + + g_return_val_if_fail (metadata == NULL || GIMP_IS_METADATA (metadata), NULL); + + if (metadata) + { + gchar *xml; + + xml = gimp_metadata_serialize (metadata); + new_metadata = gimp_metadata_deserialize (xml); + g_free (xml); + } + + return new_metadata; +} + +typedef struct +{ + gchar name[1024]; + gboolean base64; + gboolean excessive_message_shown; + GimpMetadata *metadata; +} GimpMetadataParseData; + +static const gchar* +gimp_metadata_attribute_name_to_value (const gchar **attribute_names, + const gchar **attribute_values, + const gchar *name) +{ + while (*attribute_names) + { + if (! strcmp (*attribute_names, name)) + { + return *attribute_values; + } + + attribute_names++; + attribute_values++; + } + + return NULL; +} + +static void +gimp_metadata_deserialize_start_element (GMarkupParseContext *context, + const gchar *element_name, + const gchar **attribute_names, + const gchar **attribute_values, + gpointer user_data, + GError **error) +{ + GimpMetadataParseData *parse_data = user_data; + + if (! strcmp (element_name, "tag")) + { + const gchar *name; + const gchar *encoding; + + name = gimp_metadata_attribute_name_to_value (attribute_names, + attribute_values, + "name"); + encoding = gimp_metadata_attribute_name_to_value (attribute_names, + attribute_values, + "encoding"); + + if (! name) + { + g_set_error (error, GIMP_METADATA_ERROR, 1001, + "Element 'tag' does not contain required attribute 'name'."); + return; + } + + strncpy (parse_data->name, name, sizeof (parse_data->name)); + parse_data->name[sizeof (parse_data->name) - 1] = 0; + + parse_data->base64 = (encoding && ! strcmp (encoding, "base64")); + } +} + +static void +gimp_metadata_deserialize_end_element (GMarkupParseContext *context, + const gchar *element_name, + gpointer user_data, + GError **error) +{ +} + +static void +gimp_metadata_deserialize_text (GMarkupParseContext *context, + const gchar *text, + gsize text_len, + gpointer user_data, + GError **error) +{ + GimpMetadataParseData *parse_data = user_data; + const gchar *current_element; + + current_element = g_markup_parse_context_get_element (context); + + if (! g_strcmp0 (current_element, "tag")) + { + gchar *value = g_strndup (text, text_len); + + if (parse_data->base64) + { + guchar *decoded; + gsize len; + + decoded = g_base64_decode (value, &len); + + if (decoded[len - 1] == '\0') + { + g_free (value); + value = (gchar *) decoded; + } + else + { + g_clear_pointer (&value, g_free); + g_clear_pointer (&decoded, g_free); + } + } + + if (value) + { + GExiv2Metadata *g2_metadata = GEXIV2_METADATA (parse_data->metadata); + gchar **values; + + values = gexiv2_metadata_get_tag_multiple (g2_metadata, + parse_data->name); + + if (values) + { + guint length = g_strv_length (values); + + if (length > 1000 && + ! g_strcmp0 (parse_data->name, "Xmp.photoshop.DocumentAncestors")) + { + /* Issue #8025, see also #7464 Some XCF images can have huge + * amounts of this tag, apparently due to a bug in PhotoShop. + * This makes deserializing it in the way we currently do + * too slow. Until we can change this let's ignore everything + * but the first 1000 values when serializing. */ + + if (! parse_data->excessive_message_shown) + { + g_message ("Excessive number of Xmp.photoshop.DocumentAncestors tags found. " + "Only keeping the first 1000 values."); + parse_data->excessive_message_shown = TRUE; + } + } + else + { + values = g_renew (gchar *, values, length + 2); + values[length] = value; + values[length + 1] = NULL; + + gexiv2_metadata_set_tag_multiple (g2_metadata, + parse_data->name, + (const gchar **) values); + } + g_strfreev (values); + } + else + { + gexiv2_metadata_set_tag_string (GEXIV2_METADATA (g2_metadata), + parse_data->name, + value); + g_free (value); + } + } + } +} + +static void +gimp_metadata_deserialize_error (GMarkupParseContext *context, + GError *error, + gpointer user_data) +{ + g_printerr ("Metadata parse error: %s\n", error->message); +} + +/** + * gimp_metadata_deserialize: + * @metadata_xml: A string of serialized metadata XML. + * + * Deserializes a string of XML that has been created by + * gimp_metadata_serialize(). + * + * Return value: The new #GimpMetadata. + * + * Since: 2.10 + */ +GimpMetadata * +gimp_metadata_deserialize (const gchar *metadata_xml) +{ + GimpMetadata *metadata; + GMarkupParser markup_parser; + GimpMetadataParseData parse_data; + GMarkupParseContext *context; + + g_return_val_if_fail (metadata_xml != NULL, NULL); + + metadata = gimp_metadata_new (); + + parse_data.metadata = metadata; + parse_data.excessive_message_shown = FALSE; + + markup_parser.start_element = gimp_metadata_deserialize_start_element; + markup_parser.end_element = gimp_metadata_deserialize_end_element; + markup_parser.text = gimp_metadata_deserialize_text; + markup_parser.passthrough = NULL; + markup_parser.error = gimp_metadata_deserialize_error; + + context = g_markup_parse_context_new (&markup_parser, 0, &parse_data, NULL); + + g_markup_parse_context_parse (context, + metadata_xml, strlen (metadata_xml), + NULL); + + g_markup_parse_context_unref (context); + + return metadata; +} + +static gchar * +gimp_metadata_escape (const gchar *name, + const gchar *value, + gboolean *base64) +{ + if (! g_utf8_validate (value, -1, NULL)) + { + gchar *encoded; + + encoded = g_base64_encode ((const guchar *) value, strlen (value) + 1); + + g_printerr ("Invalid UTF-8 in metadata value %s, encoding as base64: %s\n", + name, encoded); + + *base64 = TRUE; + + return encoded; + } + + *base64 = FALSE; + + return g_markup_escape_text (value, -1); +} + +static void +gimp_metadata_append_tag (GString *string, + const gchar *name, + gchar *value, + gboolean base64) +{ + if (value) + { + if (base64) + { + g_string_append_printf (string, " <tag name=\"%s\" encoding=\"base64\">%s</tag>\n", + name, value); + } + else + { + g_string_append_printf (string, " <tag name=\"%s\">%s</tag>\n", + name, value); + } + + g_free (value); + } +} + +/** + * gimp_metadata_serialize: + * @metadata: A #GimpMetadata instance. + * + * Serializes @metadata into an XML string that can later be deserialized + * using gimp_metadata_deserialize(). + * + * Return value: The serialized XML string. + * + * Since: 2.10 + */ +gchar * +gimp_metadata_serialize (GimpMetadata *metadata) +{ + GString *string; + gchar **exif_data = NULL; + gchar **iptc_data = NULL; + gchar **xmp_data = NULL; + gchar *value; + gchar *escaped; + gboolean base64; + gint i; + + g_return_val_if_fail (GIMP_IS_METADATA (metadata), NULL); + + string = g_string_new (NULL); + + g_string_append (string, "<?xml version='1.0' encoding='UTF-8'?>\n"); + g_string_append (string, "<metadata>\n"); + + exif_data = gexiv2_metadata_get_exif_tags (GEXIV2_METADATA (metadata)); + + if (exif_data) + { + for (i = 0; exif_data[i] != NULL; i++) + { + value = gexiv2_metadata_get_tag_string (GEXIV2_METADATA (metadata), + exif_data[i]); + escaped = gimp_metadata_escape (exif_data[i], value, &base64); + g_free (value); + + gimp_metadata_append_tag (string, exif_data[i], escaped, base64); + } + + g_strfreev (exif_data); + } + + xmp_data = gexiv2_metadata_get_xmp_tags (GEXIV2_METADATA (metadata)); + + if (xmp_data) + { + for (i = 0; xmp_data[i] != NULL; i++) + { + /* XmpText is always a single value, but structures like + * XmpBag and XmpSeq can have multiple values that need to be + * treated separately or else saving will do things wrong. */ + if (! g_strcmp0 (gexiv2_metadata_get_tag_type (xmp_data[i]), "XmpText")) + { + value = gexiv2_metadata_get_tag_string (GEXIV2_METADATA (metadata), + xmp_data[i]); + escaped = gimp_metadata_escape (xmp_data[i], value, &base64); + g_free (value); + + gimp_metadata_append_tag (string, xmp_data[i], escaped, base64); + } + else + { + gchar **values; + + values = gexiv2_metadata_get_tag_multiple (GEXIV2_METADATA (metadata), + xmp_data[i]); + + if (values) + { + gint vi; + gint cnt = 0; + + if (! g_strcmp0 (xmp_data[i], "Xmp.photoshop.DocumentAncestors")) + { + /* Issue #7464 Some images can have huge amounts of this + * tag (more than 100000 in certain cases), apparently + * due to a bug in PhotoShop. This makes deserializing it + * in the way we currently do too slow. Until we can + * change this let's remove everything but the first 1000 + * values when serializing. */ + cnt = g_strv_length (values); + + if (cnt > 1000) + { + g_message ("Excessive number of Xmp.photoshop.DocumentAncestors tags found: %d. " + "Only keeping the first 1000 values.", cnt); + } + } + + for (vi = 0; values[vi] != NULL && (cnt <= 1000 || vi < 1000); vi++) + { + escaped = gimp_metadata_escape (xmp_data[i], values[vi], &base64); + gimp_metadata_append_tag (string, xmp_data[i], escaped, base64); + } + + g_strfreev (values); + } + } + } + g_strfreev (xmp_data); + } + + iptc_data = gexiv2_metadata_get_iptc_tags (GEXIV2_METADATA (metadata)); + + if (iptc_data) + { + gchar **iptc_tags = iptc_data; + gchar *last_tag = NULL; + + while (*iptc_tags) + { + gchar **values; + + if (last_tag && ! strcmp (*iptc_tags, last_tag)) + { + iptc_tags++; + continue; + } + last_tag = *iptc_tags; + + values = gexiv2_metadata_get_tag_multiple (GEXIV2_METADATA (metadata), + *iptc_tags); + + if (values) + { + for (i = 0; values[i] != NULL; i++) + { + escaped = gimp_metadata_escape (*iptc_tags, values[i], &base64); + gimp_metadata_append_tag (string, *iptc_tags, escaped, base64); + } + + g_strfreev (values); + } + + iptc_tags++; + } + + g_strfreev (iptc_data); + } + + g_string_append (string, "</metadata>\n"); + + return g_string_free (string, FALSE); +} + +/** + * gimp_metadata_load_from_file: + * @file: The #GFile to load the metadata from + * @error: Return location for error message + * + * Loads #GimpMetadata from @file. + * + * Return value: The loaded #GimpMetadata. + * + * Since: 2.10 + */ +GimpMetadata * +gimp_metadata_load_from_file (GFile *file, + GError **error) +{ + GimpMetadata *meta = NULL; + gchar *path; + gchar *filename; + + g_return_val_if_fail (G_IS_FILE (file), NULL); + g_return_val_if_fail (error == NULL || *error == NULL, NULL); + + path = g_file_get_path (file); + + if (! path) + { + g_set_error (error, GIMP_METADATA_ERROR, 0, + _("Can load metadata only from local files")); + return NULL; + } + + filename = g_strdup (path); + + g_free (path); + + if (gexiv2_initialize ()) + { + meta = g_object_new (GIMP_TYPE_METADATA, NULL); + + if (! gexiv2_metadata_open_path (GEXIV2_METADATA (meta), filename, error)) + { + g_object_unref (meta); + g_free (filename); + + return NULL; + } + } + + g_free (filename); + + return meta; +} + +/** + * gimp_metadata_save_to_file: + * @metadata: A #GimpMetadata instance. + * @file: The file to save the metadata to + * @error: Return location for error message + * + * Saves @metadata to @file. + * + * Return value: %TRUE on success, %FALSE otherwise. + * + * Since: 2.10 + */ +gboolean +gimp_metadata_save_to_file (GimpMetadata *metadata, + GFile *file, + GError **error) +{ + gchar *path; + gchar *filename; + gboolean success; + + g_return_val_if_fail (GIMP_IS_METADATA (metadata), FALSE); + g_return_val_if_fail (G_IS_FILE (file), FALSE); + g_return_val_if_fail (error == NULL || *error == NULL, FALSE); + + path = g_file_get_path (file); + + if (! path) + { + g_set_error (error, GIMP_METADATA_ERROR, 0, + _("Can save metadata only to local files")); + return FALSE; + } + + filename = g_strdup (path); + + g_free (path); + + success = gexiv2_metadata_save_file (GEXIV2_METADATA (metadata), + filename, error); + + g_free (filename); + + return success; +} + +/** + * gimp_metadata_set_from_exif: + * @metadata: A #GimpMetadata instance. + * @exif_data: The blob of Exif data to set + * @exif_data_length: Length of @exif_data, in bytes + * @error: Return location for error message + * + * Sets the tags from a piece of Exif data on @metadata. + * + * Return value: %TRUE on success, %FALSE otherwise. + * + * Since: 2.10 + */ +gboolean +gimp_metadata_set_from_exif (GimpMetadata *metadata, + const guchar *exif_data, + gint exif_data_length, + GError **error) +{ + + GByteArray *exif_bytes; + GimpMetadata *exif_metadata; + guint8 data_size[2] = { 0, }; + const guint8 eoi[2] = { 0xff, 0xd9 }; + + g_return_val_if_fail (GIMP_IS_METADATA (metadata), FALSE); + g_return_val_if_fail (exif_data != NULL || exif_data_length == 0, FALSE); + g_return_val_if_fail (error == NULL || *error == NULL, FALSE); + + if (exif_data_length < 0 || exif_data_length + 2 >= 65536) + { + g_set_error (error, GIMP_METADATA_ERROR, 0, + _("Invalid Exif data size.")); + return FALSE; + } + + data_size[0] = ((exif_data_length + 2) & 0xFF00) >> 8; + data_size[1] = ((exif_data_length + 2) & 0x00FF); + + exif_bytes = g_byte_array_new (); + exif_bytes = g_byte_array_append (exif_bytes, + minimal_exif, G_N_ELEMENTS (minimal_exif)); + exif_bytes = g_byte_array_append (exif_bytes, + data_size, 2); + exif_bytes = g_byte_array_append (exif_bytes, + (guint8 *) exif_data, exif_data_length); + exif_bytes = g_byte_array_append (exif_bytes, eoi, 2); + + exif_metadata = gimp_metadata_new (); + + if (! gexiv2_metadata_open_buf (GEXIV2_METADATA (exif_metadata), + exif_bytes->data, exif_bytes->len, error)) + { + g_object_unref (exif_metadata); + g_byte_array_free (exif_bytes, TRUE); + return FALSE; + } + + if (! gexiv2_metadata_has_exif (GEXIV2_METADATA (exif_metadata))) + { + g_set_error (error, GIMP_METADATA_ERROR, 0, + _("Parsing Exif data failed.")); + g_object_unref (exif_metadata); + g_byte_array_free (exif_bytes, TRUE); + return FALSE; + } + + gimp_metadata_add (exif_metadata, metadata); + g_object_unref (exif_metadata); + g_byte_array_free (exif_bytes, TRUE); + + return TRUE; +} + +/** + * gimp_metadata_set_from_iptc: + * @metadata: A #GimpMetadata instance. + * @iptc_data: The blob of Ipc data to set + * @iptc_data_length:Length of @iptc_data, in bytes + * @error: Return location for error message + * + * Sets the tags from a piece of IPTC data on @metadata. + * + * Return value: %TRUE on success, %FALSE otherwise. + * + * Since: 2.10 + */ +gboolean +gimp_metadata_set_from_iptc (GimpMetadata *metadata, + const guchar *iptc_data, + gint iptc_data_length, + GError **error) +{ + GimpMetadata *iptc_metadata; + + g_return_val_if_fail (GIMP_IS_METADATA (metadata), FALSE); + g_return_val_if_fail (iptc_data != NULL || iptc_data_length == 0, FALSE); + g_return_val_if_fail (error == NULL || *error == NULL, FALSE); + + iptc_metadata = gimp_metadata_new (); + + if (! gexiv2_metadata_open_buf (GEXIV2_METADATA (iptc_metadata), + iptc_data, iptc_data_length, error)) + { + g_object_unref (iptc_metadata); + return FALSE; + } + + if (! gexiv2_metadata_has_iptc (GEXIV2_METADATA (iptc_metadata))) + { + g_set_error (error, GIMP_METADATA_ERROR, 0, + _("Parsing IPTC data failed.")); + g_object_unref (iptc_metadata); + return FALSE; + } + + gimp_metadata_add (iptc_metadata, metadata); + g_object_unref (iptc_metadata); + + return TRUE; +} + +/** + * gimp_metadata_set_from_xmp: + * @metadata: A #GimpMetadata instance. + * @xmp_data: The blob of Exif data to set + * @xmp_data_length: Length of @exif_data, in bytes + * @error: Return location for error message + * + * Sets the tags from a piece of XMP data on @metadata. + * + * Return value: %TRUE on success, %FALSE otherwise. + * + * Since: 2.10 + */ +gboolean +gimp_metadata_set_from_xmp (GimpMetadata *metadata, + const guchar *xmp_data, + gint xmp_data_length, + GError **error) +{ + GimpMetadata *xmp_metadata; + + g_return_val_if_fail (GIMP_IS_METADATA (metadata), FALSE); + g_return_val_if_fail (xmp_data != NULL || xmp_data_length == 0, FALSE); + g_return_val_if_fail (error == NULL || *error == NULL, FALSE); + + xmp_metadata = gimp_metadata_new (); + + if (! gexiv2_metadata_open_buf (GEXIV2_METADATA (xmp_metadata), + xmp_data, xmp_data_length, error)) + { + g_object_unref (xmp_metadata); + return FALSE; + } + + if (! gexiv2_metadata_has_xmp (GEXIV2_METADATA (xmp_metadata))) + { + g_set_error (error, GIMP_METADATA_ERROR, 0, + _("Parsing XMP data failed.")); + g_object_unref (xmp_metadata); + return FALSE; + } + + gimp_metadata_add (xmp_metadata, metadata); + g_object_unref (xmp_metadata); + + return TRUE; +} + +/** + * gimp_metadata_set_pixel_size: + * @metadata: A #GimpMetadata instance. + * @width: Width in pixels + * @height: Height in pixels + * + * Sets Exif.Image.ImageWidth and Exif.Image.ImageLength on @metadata. + * If already present, also sets Exif.Photo.PixelXDimension and + * Exif.Photo.PixelYDimension. + * + * Since: 2.10 + */ +void +gimp_metadata_set_pixel_size (GimpMetadata *metadata, + gint width, + gint height) +{ + gchar buffer[32]; + + g_return_if_fail (GIMP_IS_METADATA (metadata)); + + g_snprintf (buffer, sizeof (buffer), "%d", width); + gexiv2_metadata_set_tag_string (GEXIV2_METADATA (metadata), + "Exif.Image.ImageWidth", buffer); + if (gexiv2_metadata_has_tag (GEXIV2_METADATA (metadata), + "Exif.Photo.PixelXDimension")) + { + gexiv2_metadata_set_tag_string (GEXIV2_METADATA (metadata), + "Exif.Photo.PixelXDimension", + buffer); + } + + g_snprintf (buffer, sizeof (buffer), "%d", height); + gexiv2_metadata_set_tag_string (GEXIV2_METADATA (metadata), + "Exif.Image.ImageLength", buffer); + if (gexiv2_metadata_has_tag (GEXIV2_METADATA (metadata), + "Exif.Photo.PixelYDimension")) + { + gexiv2_metadata_set_tag_string (GEXIV2_METADATA (metadata), + "Exif.Photo.PixelYDimension", + buffer); + } +} + +/** + * gimp_metadata_set_bits_per_sample: + * @metadata: A #GimpMetadata instance. + * @bits_per_sample: Bits per pixel, per component + * + * Sets Exif.Image.BitsPerSample on @metadata. + * + * Since: 2.10 + */ +void +gimp_metadata_set_bits_per_sample (GimpMetadata *metadata, + gint bits_per_sample) +{ + gchar buffer[32]; + + g_return_if_fail (GIMP_IS_METADATA (metadata)); + + g_snprintf (buffer, sizeof (buffer), "%d %d %d", + bits_per_sample, bits_per_sample, bits_per_sample); + gexiv2_metadata_set_tag_string (GEXIV2_METADATA (metadata), + "Exif.Image.BitsPerSample", buffer); +} + +/** + * gimp_metadata_get_resolution: + * @metadata: A #GimpMetadata instance. + * @xres: Return location for the X Resolution, in ppi + * @yres: Return location for the Y Resolution, in ppi + * @unit: Return location for the unit unit + * + * Returns values based on Exif.Image.XResolution, + * Exif.Image.YResolution and Exif.Image.ResolutionUnit of @metadata. + * + * Return value: %TRUE on success, %FALSE otherwise. + * + * Since: 2.10 + */ +gboolean +gimp_metadata_get_resolution (GimpMetadata *metadata, + gdouble *xres, + gdouble *yres, + GimpUnit *unit) +{ + gint xnom, xdenom; + gint ynom, ydenom; + + g_return_val_if_fail (GIMP_IS_METADATA (metadata), FALSE); + + if (gexiv2_metadata_get_exif_tag_rational (GEXIV2_METADATA (metadata), + "Exif.Image.XResolution", + &xnom, &xdenom) && + gexiv2_metadata_get_exif_tag_rational (GEXIV2_METADATA (metadata), + "Exif.Image.YResolution", + &ynom, &ydenom)) + { + gchar *un; + gint exif_unit = 2; + + un = gexiv2_metadata_get_tag_string (GEXIV2_METADATA (metadata), + "Exif.Image.ResolutionUnit"); + if (un) + { + exif_unit = atoi (un); + g_free (un); + } + + if (xnom != 0 && xdenom != 0 && + ynom != 0 && ydenom != 0) + { + gdouble xresolution = (gdouble) xnom / (gdouble) xdenom; + gdouble yresolution = (gdouble) ynom / (gdouble) ydenom; + + if (exif_unit == 3) + { + xresolution *= 2.54; + yresolution *= 2.54; + } + + if (xresolution >= GIMP_MIN_RESOLUTION && + xresolution <= GIMP_MAX_RESOLUTION && + yresolution >= GIMP_MIN_RESOLUTION && + yresolution <= GIMP_MAX_RESOLUTION) + { + if (xres) + *xres = xresolution; + + if (yres) + *yres = yresolution; + + if (unit) + { + if (exif_unit == 3) + *unit = GIMP_UNIT_MM; + else + *unit = GIMP_UNIT_INCH; + } + + return TRUE; + } + } + } + + return FALSE; +} + +/** + * gimp_metadata_set_resolution: + * @metadata: A #GimpMetadata instance. + * @xres: The image's X Resolution, in ppi + * @yres: The image's Y Resolution, in ppi + * @unit: The image's unit + * + * Sets Exif.Image.XResolution, Exif.Image.YResolution and + * Exif.Image.ResolutionUnit of @metadata. + * + * Since: 2.10 + */ +void +gimp_metadata_set_resolution (GimpMetadata *metadata, + gdouble xres, + gdouble yres, + GimpUnit unit) +{ + gchar buffer[32]; + gint exif_unit; + gint factor; + + g_return_if_fail (GIMP_IS_METADATA (metadata)); + + if (gimp_unit_is_metric (unit)) + { + xres /= 2.54; + yres /= 2.54; + + exif_unit = 3; + } + else + { + exif_unit = 2; + } + + for (factor = 1; factor <= 100 /* arbitrary */; factor++) + { + if (fabs (xres * factor - ROUND (xres * factor)) < 0.01 && + fabs (yres * factor - ROUND (yres * factor)) < 0.01) + break; + } + + gexiv2_metadata_set_exif_tag_rational (GEXIV2_METADATA (metadata), + "Exif.Image.XResolution", + ROUND (xres * factor), factor); + + gexiv2_metadata_set_exif_tag_rational (GEXIV2_METADATA (metadata), + "Exif.Image.YResolution", + ROUND (yres * factor), factor); + + g_snprintf (buffer, sizeof (buffer), "%d", exif_unit); + gexiv2_metadata_set_tag_string (GEXIV2_METADATA (metadata), + "Exif.Image.ResolutionUnit", buffer); +} + +/** + * gimp_metadata_get_colorspace: + * @metadata: A #GimpMetadata instance. + * + * Returns values based on Exif.Photo.ColorSpace, Xmp.exif.ColorSpace, + * Exif.Iop.InteroperabilityIndex, Exif.Nikon3.ColorSpace, + * Exif.Canon.ColorSpace of @metadata. + * + * Return value: The colorspace specified by above tags. + * + * Since: 2.10 + */ +GimpMetadataColorspace +gimp_metadata_get_colorspace (GimpMetadata *metadata) +{ + glong exif_cs = -1; + + g_return_val_if_fail (GIMP_IS_METADATA (metadata), + GIMP_METADATA_COLORSPACE_UNSPECIFIED); + + /* the logic here was mostly taken from darktable and libkexiv2 */ + + if (gexiv2_metadata_has_tag (GEXIV2_METADATA (metadata), + "Exif.Photo.ColorSpace")) + { + exif_cs = gexiv2_metadata_get_tag_long (GEXIV2_METADATA (metadata), + "Exif.Photo.ColorSpace"); + } + else if (gexiv2_metadata_has_tag (GEXIV2_METADATA (metadata), + "Xmp.exif.ColorSpace")) + { + exif_cs = gexiv2_metadata_get_tag_long (GEXIV2_METADATA (metadata), + "Xmp.exif.ColorSpace"); + } + + if (exif_cs == 0x01) + { + return GIMP_METADATA_COLORSPACE_SRGB; + } + else if (exif_cs == 0x02) + { + return GIMP_METADATA_COLORSPACE_ADOBERGB; + } + else + { + if (exif_cs == 0xffff) + { + gchar *iop_index; + + iop_index = gexiv2_metadata_get_tag_string (GEXIV2_METADATA (metadata), + "Exif.Iop.InteroperabilityIndex"); + + if (! g_strcmp0 (iop_index, "R03")) + { + g_free (iop_index); + + return GIMP_METADATA_COLORSPACE_ADOBERGB; + } + else if (! g_strcmp0 (iop_index, "R98")) + { + g_free (iop_index); + + return GIMP_METADATA_COLORSPACE_SRGB; + } + + g_free (iop_index); + } + + if (gexiv2_metadata_has_tag (GEXIV2_METADATA (metadata), + "Exif.Nikon3.ColorSpace")) + { + glong nikon_cs; + + nikon_cs = gexiv2_metadata_get_tag_long (GEXIV2_METADATA (metadata), + "Exif.Nikon3.ColorSpace"); + + if (nikon_cs == 0x01) + { + return GIMP_METADATA_COLORSPACE_SRGB; + } + else if (nikon_cs == 0x02) + { + return GIMP_METADATA_COLORSPACE_ADOBERGB; + } + } + + if (gexiv2_metadata_has_tag (GEXIV2_METADATA (metadata), + "Exif.Canon.ColorSpace")) + { + glong canon_cs; + + canon_cs = gexiv2_metadata_get_tag_long (GEXIV2_METADATA (metadata), + "Exif.Canon.ColorSpace"); + + if (canon_cs == 0x01) + { + return GIMP_METADATA_COLORSPACE_SRGB; + } + else if (canon_cs == 0x02) + { + return GIMP_METADATA_COLORSPACE_ADOBERGB; + } + } + + if (exif_cs == 0xffff) + return GIMP_METADATA_COLORSPACE_UNCALIBRATED; + } + + return GIMP_METADATA_COLORSPACE_UNSPECIFIED; +} + +/** + * gimp_metadata_set_colorspace: + * @metadata: A #GimpMetadata instance. + * @colorspace: The color space. + * + * Sets Exif.Photo.ColorSpace, Xmp.exif.ColorSpace, + * Exif.Iop.InteroperabilityIndex, Exif.Nikon3.ColorSpace, + * Exif.Canon.ColorSpace of @metadata. + * + * Since: 2.10 + */ +void +gimp_metadata_set_colorspace (GimpMetadata *metadata, + GimpMetadataColorspace colorspace) +{ + GExiv2Metadata *g2metadata = GEXIV2_METADATA (metadata); + + switch (colorspace) + { + case GIMP_METADATA_COLORSPACE_UNSPECIFIED: + gexiv2_metadata_clear_tag (g2metadata, "Exif.Photo.ColorSpace"); + gexiv2_metadata_clear_tag (g2metadata, "Xmp.exif.ColorSpace"); + gexiv2_metadata_clear_tag (g2metadata, "Exif.Iop.InteroperabilityIndex"); + gexiv2_metadata_clear_tag (g2metadata, "Exif.Nikon3.ColorSpace"); + gexiv2_metadata_clear_tag (g2metadata, "Exif.Canon.ColorSpace"); + break; + + case GIMP_METADATA_COLORSPACE_UNCALIBRATED: + gexiv2_metadata_set_tag_long (g2metadata, "Exif.Photo.ColorSpace", 0xffff); + if (gexiv2_metadata_has_tag (g2metadata, "Xmp.exif.ColorSpace")) + gexiv2_metadata_set_tag_long (g2metadata, "Xmp.exif.ColorSpace", 0xffff); + gexiv2_metadata_clear_tag (g2metadata, "Exif.Iop.InteroperabilityIndex"); + gexiv2_metadata_clear_tag (g2metadata, "Exif.Nikon3.ColorSpace"); + gexiv2_metadata_clear_tag (g2metadata, "Exif.Canon.ColorSpace"); + break; + + case GIMP_METADATA_COLORSPACE_SRGB: + gexiv2_metadata_set_tag_long (g2metadata, "Exif.Photo.ColorSpace", 0x01); + + if (gexiv2_metadata_has_tag (g2metadata, "Xmp.exif.ColorSpace")) + gexiv2_metadata_set_tag_long (g2metadata, "Xmp.exif.ColorSpace", 0x01); + + if (gexiv2_metadata_has_tag (g2metadata, "Exif.Iop.InteroperabilityIndex")) + gexiv2_metadata_set_tag_string (g2metadata, + "Exif.Iop.InteroperabilityIndex", "R98"); + + if (gexiv2_metadata_has_tag (g2metadata, "Exif.Nikon3.ColorSpace")) + gexiv2_metadata_set_tag_long (g2metadata, "Exif.Nikon3.ColorSpace", 0x01); + + if (gexiv2_metadata_has_tag (g2metadata, "Exif.Canon.ColorSpace")) + gexiv2_metadata_set_tag_long (g2metadata, "Exif.Canon.ColorSpace", 0x01); + break; + + case GIMP_METADATA_COLORSPACE_ADOBERGB: + gexiv2_metadata_set_tag_long (g2metadata, "Exif.Photo.ColorSpace", 0x02); + + if (gexiv2_metadata_has_tag (g2metadata, "Xmp.exif.ColorSpace")) + gexiv2_metadata_set_tag_long (g2metadata, "Xmp.exif.ColorSpace", 0x02); + + if (gexiv2_metadata_has_tag (g2metadata, "Exif.Iop.InteroperabilityIndex")) + gexiv2_metadata_set_tag_string (g2metadata, + "Exif.Iop.InteroperabilityIndex", "R03"); + + if (gexiv2_metadata_has_tag (g2metadata, "Exif.Nikon3.ColorSpace")) + gexiv2_metadata_set_tag_long (g2metadata, "Exif.Nikon3.ColorSpace", 0x02); + + if (gexiv2_metadata_has_tag (g2metadata, "Exif.Canon.ColorSpace")) + gexiv2_metadata_set_tag_long (g2metadata, "Exif.Canon.ColorSpace", 0x02); + break; + } +} + +/** + * gimp_metadata_is_tag_supported: + * @tag: A metadata tag name + * @mime_type: A mime type + * + * Returns whether @tag is supported in a file of type @mime_type. + * + * Return value: %TRUE if the @tag supported with @mime_type, %FALSE otherwise. + * + * Since: 2.10 + */ +gboolean +gimp_metadata_is_tag_supported (const gchar *tag, + const gchar *mime_type) +{ + gint j; + + g_return_val_if_fail (tag != NULL, FALSE); + g_return_val_if_fail (mime_type != NULL, FALSE); + + for (j = 0; j < G_N_ELEMENTS (unsupported_tags); j++) + { + if (g_str_has_prefix (tag, unsupported_tags[j])) + { + return FALSE; + } + } + + if (! strcmp (mime_type, "image/jpeg")) + { + for (j = 0; j < G_N_ELEMENTS (tiff_tags); j++) + { + if (g_str_has_prefix (tag, tiff_tags[j])) + { + return FALSE; + } + } + } + else if (! strcmp (mime_type, "image/tiff")) + { + for (j = 0; j < G_N_ELEMENTS (jpeg_tags); j++) + { + if (g_str_has_prefix (tag, jpeg_tags[j])) + { + return FALSE; + } + } + } + + return TRUE; +} + + +/* private functions */ + +static GQuark +gimp_metadata_error_quark (void) +{ + static GQuark quark = 0; + + if (G_UNLIKELY (quark == 0)) + quark = g_quark_from_static_string ("gimp-metadata-error-quark"); + + return quark; +} + +static void +gimp_metadata_copy_tag (GExiv2Metadata *src, + GExiv2Metadata *dest, + const gchar *tag) +{ +#if GEXIV2_CHECK_VERSION(0, 12, 2) + gchar **values; + GError *error = NULL; + + values = gexiv2_metadata_try_get_tag_multiple (src, tag, &error); + + if (error) + { + g_printerr ("%s: %s\n", G_STRFUNC, error->message); + g_clear_error (&error); + g_strfreev (values); + } + else if (values) + { + gexiv2_metadata_try_set_tag_multiple (dest, tag, (const gchar **) values, &error); + if (error) + { + g_warning ("%s: failed to set multiple metadata '%s': %s\n", + G_STRFUNC, tag, error->message); + g_clear_error (&error); + } + + g_strfreev (values); + } + else + { + gchar *value = gexiv2_metadata_try_get_tag_string (src, tag, &error); + + if (value) + { + gexiv2_metadata_try_set_tag_string (dest, tag, value, &error); + if (error) + { + g_warning ("%s: failed to set metadata '%s': %s\n", + G_STRFUNC, tag, error->message); + g_clear_error (&error); + } + g_free (value); + } + else if (error) + { + g_warning ("%s: failed to get metadata '%s': %s\n", + G_STRFUNC, tag, error->message); + g_clear_error (&error); + } + } +#else + gchar **values = gexiv2_metadata_get_tag_multiple (src, tag); + + if (values) + { + gexiv2_metadata_set_tag_multiple (dest, tag, (const gchar **) values); + g_strfreev (values); + } + else + { + gchar *value = gexiv2_metadata_get_tag_string (src, tag); + + if (value) + { + gexiv2_metadata_set_tag_string (dest, tag, value); + g_free (value); + } + } +#endif +} + +static void +gimp_metadata_copy_tags (GExiv2Metadata *src, + GExiv2Metadata *dest, + const gchar **tags) +{ + gint i; + + for (i = 0; tags[i] != NULL; i++) + { + /* don't copy the same tag multiple times */ + if (i > 0 && ! strcmp (tags[i], tags[i - 1])) + continue; + + gimp_metadata_copy_tag (src, dest, tags[i]); + } + } + +static void +gimp_metadata_add (GimpMetadata *src, + GimpMetadata *dest) +{ + GExiv2Metadata *g2src = GEXIV2_METADATA (src); + GExiv2Metadata *g2dest = GEXIV2_METADATA (dest); + + if (gexiv2_metadata_get_supports_exif (g2src) && + gexiv2_metadata_get_supports_exif (g2dest)) + { + gchar **exif_tags = gexiv2_metadata_get_exif_tags (g2src); + + if (exif_tags) + { + gimp_metadata_copy_tags (g2src, g2dest, + (const gchar **) exif_tags); + g_strfreev (exif_tags); + } + } + + if (gexiv2_metadata_get_supports_xmp (g2src) && + gexiv2_metadata_get_supports_xmp (g2dest)) + { + gchar **xmp_tags = gexiv2_metadata_get_xmp_tags (g2src); + + if (xmp_tags) + { + gimp_metadata_copy_tags (g2src, g2dest, + (const gchar **) xmp_tags); + g_strfreev (xmp_tags); + } + } + + if (gexiv2_metadata_get_supports_iptc (g2src) && + gexiv2_metadata_get_supports_iptc (g2dest)) + { + gchar **iptc_tags = gexiv2_metadata_get_iptc_tags (g2src); + + if (iptc_tags) + { + gimp_metadata_copy_tags (g2src, g2dest, + (const gchar **) iptc_tags); + g_strfreev (iptc_tags); + } + } +} diff --git a/libgimpbase/gimpmetadata.h b/libgimpbase/gimpmetadata.h new file mode 100644 index 0000000..30a6f39 --- /dev/null +++ b/libgimpbase/gimpmetadata.h @@ -0,0 +1,154 @@ +/* LIBGIMPBASE - The GIMP Basic Library + * Copyright (C) 1995-1997 Peter Mattis and Spencer Kimball + * + * gimpmetadata.h + * Copyright (C) 2013 Hartmut Kuhse <hartmutkuhse@src.gnome.org> + * + * This library is free software: you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see + * <https://www.gnu.org/licenses/>. + */ + +#ifndef __GIMP_METADATA_H__ +#define __GIMP_METADATA_H__ + +G_BEGIN_DECLS + +#define GIMP_TYPE_METADATA (gimp_metadata_get_type ()) +#define GIMP_METADATA(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GIMP_TYPE_METADATA, GimpMetadata)) +#define GIMP_METADATA_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GIMP_TYPE_METADATA, GimpMetadataClass)) +#define GIMP_IS_METADATA(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GIMP_TYPE_METADATA)) +#define GIMP_IS_METADATA_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GIMP_TYPE_METADATA)) +#define GIMP_METADATA_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GIMP_TYPE_METADATA, GimpMetadataClass)) + + +/** + * GimpMetadataLoadFlags: + * @GIMP_METADATA_LOAD_COMMENT: Load the comment + * @GIMP_METADATA_LOAD_RESOLUTION: Load the resolution + * @GIMP_METADATA_LOAD_ORIENTATION: Load the orientation (rotation) + * @GIMP_METADATA_LOAD_COLORSPACE: Load the colorspace + * @GIMP_METADATA_LOAD_ALL: Load all of the above + * + * What metadata to load when importing images. + **/ +typedef enum +{ + GIMP_METADATA_LOAD_COMMENT = 1 << 0, + GIMP_METADATA_LOAD_RESOLUTION = 1 << 1, + GIMP_METADATA_LOAD_ORIENTATION = 1 << 2, + GIMP_METADATA_LOAD_COLORSPACE = 1 << 3, + + GIMP_METADATA_LOAD_ALL = 0xffffffff +} GimpMetadataLoadFlags; + + +/** + * GimpMetadataSaveFlags: + * @GIMP_METADATA_SAVE_EXIF: Save EXIF + * @GIMP_METADATA_SAVE_XMP: Save XMP + * @GIMP_METADATA_SAVE_IPTC: Save IPTC + * @GIMP_METADATA_SAVE_THUMBNAIL: Save a thumbnail of the image + * @GIMP_METADATA_SAVE_COLOR_PROFILE: Save the image's color profile + * Since: 2.10.10 + * @GIMP_METADATA_SAVE_ALL: Save all of the above + * + * What kinds of metadata to save when exporting images. + **/ +typedef enum +{ + GIMP_METADATA_SAVE_EXIF = 1 << 0, + GIMP_METADATA_SAVE_XMP = 1 << 1, + GIMP_METADATA_SAVE_IPTC = 1 << 2, + GIMP_METADATA_SAVE_THUMBNAIL = 1 << 3, + GIMP_METADATA_SAVE_COLOR_PROFILE = 1 << 4, + + GIMP_METADATA_SAVE_ALL = 0xffffffff +} GimpMetadataSaveFlags; + + +/** + * GimpMetadataColorspace: + * @GIMP_METADATA_COLORSPACE_UNSPECIFIED: Unspecified + * @GIMP_METADATA_COLORSPACE_UNCALIBRATED: Uncalibrated + * @GIMP_METADATA_COLORSPACE_SRGB: sRGB + * @GIMP_METADATA_COLORSPACE_ADOBERGB: Adobe RGB + * + * Well-defined colorspace information available from metadata + **/ +typedef enum +{ + GIMP_METADATA_COLORSPACE_UNSPECIFIED, + GIMP_METADATA_COLORSPACE_UNCALIBRATED, + GIMP_METADATA_COLORSPACE_SRGB, + GIMP_METADATA_COLORSPACE_ADOBERGB +} GimpMetadataColorspace; + + +GType gimp_metadata_get_type (void) G_GNUC_CONST; + +GimpMetadata * gimp_metadata_new (void); +GimpMetadata * gimp_metadata_duplicate (GimpMetadata *metadata); + +GimpMetadata * gimp_metadata_deserialize (const gchar *metadata_xml); +gchar * gimp_metadata_serialize (GimpMetadata *metadata); +gchar * gimp_metadata_get_guid (void); + +void gimp_metadata_add_xmp_history (GimpMetadata *metadata, + gchar *state_status); + +GimpMetadata * gimp_metadata_load_from_file (GFile *file, + GError **error); +gboolean gimp_metadata_save_to_file (GimpMetadata *metadata, + GFile *file, + GError **error); + +gboolean gimp_metadata_set_from_exif (GimpMetadata *metadata, + const guchar *exif_data, + gint exif_data_length, + GError **error); +gboolean gimp_metadata_set_from_iptc (GimpMetadata *metadata, + const guchar *iptc_data, + gint iptc_data_length, + GError **error); +gboolean gimp_metadata_set_from_xmp (GimpMetadata *metadata, + const guchar *xmp_data, + gint xmp_data_length, + GError **error); + +void gimp_metadata_set_pixel_size (GimpMetadata *metadata, + gint width, + gint height); +void gimp_metadata_set_bits_per_sample (GimpMetadata *metadata, + gint bits_per_sample); + +gboolean gimp_metadata_get_resolution (GimpMetadata *metadata, + gdouble *xres, + gdouble *yres, + GimpUnit *unit); +void gimp_metadata_set_resolution (GimpMetadata *metadata, + gdouble xres, + gdouble yres, + GimpUnit unit); + +GimpMetadataColorspace + gimp_metadata_get_colorspace (GimpMetadata *metadata); +void gimp_metadata_set_colorspace (GimpMetadata *metadata, + GimpMetadataColorspace colorspace); + +gboolean gimp_metadata_is_tag_supported (const gchar *tag, + const gchar *mime_type); + +G_END_DECLS + +#endif /* __GIMP_METADATA_H__ */ diff --git a/libgimpbase/gimpparam.h b/libgimpbase/gimpparam.h new file mode 100644 index 0000000..6b6427c --- /dev/null +++ b/libgimpbase/gimpparam.h @@ -0,0 +1,66 @@ +/* LIBGIMP - The GIMP Library + * Copyright (C) 1995-1997 Peter Mattis and Spencer Kimball + * + * This library is free software: you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This library 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see + * <https://www.gnu.org/licenses/>. + */ + +#ifndef __GIMP_PARAM_H__ +#define __GIMP_PARAM_H__ + + +/** + * SECTION: gimpparam + * @title: gimpparam + * @short_description: Definitions of useful #GParamFlags. + * + * Definitions of useful #GParamFlags. + **/ + + +/** + * GIMP_PARAM_STATIC_STRINGS: + * + * Since: 2.4 + **/ +#define GIMP_PARAM_STATIC_STRINGS (G_PARAM_STATIC_NAME | \ + G_PARAM_STATIC_NICK | \ + G_PARAM_STATIC_BLURB) + +/** + * GIMP_PARAM_READABLE: + * + * Since: 2.4 + **/ +#define GIMP_PARAM_READABLE (G_PARAM_READABLE | \ + GIMP_PARAM_STATIC_STRINGS) + +/** + * GIMP_PARAM_WRITABLE: + * + * Since: 2.4 + **/ +#define GIMP_PARAM_WRITABLE (G_PARAM_WRITABLE | \ + GIMP_PARAM_STATIC_STRINGS) + +/** + * GIMP_PARAM_READWRITE: + * + * Since: 2.4 + **/ +#define GIMP_PARAM_READWRITE (G_PARAM_READWRITE | \ + GIMP_PARAM_STATIC_STRINGS) + + +#endif /* __GIMP_PARAM_H__ */ diff --git a/libgimpbase/gimpparasite.c b/libgimpbase/gimpparasite.c new file mode 100644 index 0000000..ac66491 --- /dev/null +++ b/libgimpbase/gimpparasite.c @@ -0,0 +1,352 @@ +/* LIBGIMP - The GIMP Library + * Copyright (C) 1995-1997 Peter Mattis and Spencer Kimball + * + * gimpparasite.c + * Copyright (C) 1998 Jay Cox <jaycox@gimp.org> + * + * This library is free software: you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This library 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see + * <https://www.gnu.org/licenses/>. + */ + +#include "config.h" + +#include <stdio.h> +#ifdef HAVE_UNISTD_H +#include <unistd.h> +#endif +#include <string.h> + +#include <glib-object.h> + +#ifdef G_OS_WIN32 +#include <process.h> /* For _getpid() */ +#endif + +#include "gimpbasetypes.h" + +#include "gimpparasite.h" + + +/** + * SECTION: gimpparasite + * @title: GimpParasite + * @short_description: Arbitrary pieces of data which can be attached + * to various GIMP objects. + * @see_also: gimp_image_parasite_attach(), + * gimp_drawable_parasite_attach(), gimp_parasite_attach() + * and their related functions. + * + * Arbitrary pieces of data which can be attached to various GIMP objects. + **/ + + +/* + * GIMP_TYPE_PARASITE + */ + +GType +gimp_parasite_get_type (void) +{ + static GType type = 0; + + if (! type) + type = g_boxed_type_register_static ("GimpParasite", + (GBoxedCopyFunc) gimp_parasite_copy, + (GBoxedFreeFunc) gimp_parasite_free); + + return type; +} + + +/* + * GIMP_TYPE_PARAM_PARASITE + */ + +#define GIMP_PARAM_SPEC_PARASITE(pspec) (G_TYPE_CHECK_INSTANCE_CAST ((pspec), GIMP_TYPE_PARAM_PARASITE, GimpParamSpecParasite)) + +typedef struct _GimpParamSpecParasite GimpParamSpecParasite; + +struct _GimpParamSpecParasite +{ + GParamSpecBoxed parent_instance; +}; + +static void gimp_param_parasite_class_init (GParamSpecClass *class); +static void gimp_param_parasite_init (GParamSpec *pspec); +static gboolean gimp_param_parasite_validate (GParamSpec *pspec, + GValue *value); +static gint gimp_param_parasite_values_cmp (GParamSpec *pspec, + const GValue *value1, + const GValue *value2); + +GType +gimp_param_parasite_get_type (void) +{ + static GType type = 0; + + if (! type) + { + const GTypeInfo type_info = + { + sizeof (GParamSpecClass), + NULL, NULL, + (GClassInitFunc) gimp_param_parasite_class_init, + NULL, NULL, + sizeof (GimpParamSpecParasite), + 0, + (GInstanceInitFunc) gimp_param_parasite_init + }; + + type = g_type_register_static (G_TYPE_PARAM_BOXED, + "GimpParamParasite", + &type_info, 0); + } + + return type; +} + +static void +gimp_param_parasite_class_init (GParamSpecClass *class) +{ + class->value_type = GIMP_TYPE_PARASITE; + class->value_validate = gimp_param_parasite_validate; + class->values_cmp = gimp_param_parasite_values_cmp; +} + +static void +gimp_param_parasite_init (GParamSpec *pspec) +{ +} + +static gboolean +gimp_param_parasite_validate (GParamSpec *pspec, + GValue *value) +{ + GimpParasite *parasite = value->data[0].v_pointer; + + if (! parasite) + { + return TRUE; + } + else if (parasite->name == NULL || + *parasite->name == '\0' || + ! g_utf8_validate (parasite->name, -1, NULL) || + (parasite->size == 0 && parasite->data != NULL) || + (parasite->size > 0 && parasite->data == NULL)) + { + g_value_set_boxed (value, NULL); + return TRUE; + } + + return FALSE; +} + +static gint +gimp_param_parasite_values_cmp (GParamSpec *pspec, + const GValue *value1, + const GValue *value2) +{ + GimpParasite *parasite1 = value1->data[0].v_pointer; + GimpParasite *parasite2 = value2->data[0].v_pointer; + + /* try to return at least *something*, it's useless anyway... */ + + if (! parasite1) + return parasite2 != NULL ? -1 : 0; + else if (! parasite2) + return parasite1 != NULL; + else + return gimp_parasite_compare (parasite1, parasite2); +} + +GParamSpec * +gimp_param_spec_parasite (const gchar *name, + const gchar *nick, + const gchar *blurb, + GParamFlags flags) +{ + GimpParamSpecParasite *parasite_spec; + + parasite_spec = g_param_spec_internal (GIMP_TYPE_PARAM_PARASITE, + name, nick, blurb, flags); + + return G_PARAM_SPEC (parasite_spec); +} + + +#ifdef DEBUG +static void +gimp_parasite_print (GimpParasite *parasite) +{ + if (parasite == NULL) + { + g_print ("pid %d: attempt to print a null parasite\n", getpid ()); + return; + } + + g_print ("pid %d: parasite: %p\n", getpid (), parasite); + + if (parasite->name) + g_print ("\tname: %s\n", parasite->name); + else + g_print ("\tname: NULL\n"); + + g_print ("\tflags: %d\n", parasite->flags); + g_print ("\tsize: %d\n", parasite->size); + if (parasite->size > 0) + g_print ("\tdata: %p\n", parasite->data); +} +#endif + +GimpParasite * +gimp_parasite_new (const gchar *name, + guint32 flags, + guint32 size, + gconstpointer data) +{ + GimpParasite *parasite; + + if (! (name && *name)) + return NULL; + + parasite = g_slice_new (GimpParasite); + parasite->name = g_strdup (name); + parasite->flags = (flags & 0xFF); + parasite->size = size; + + if (size) + parasite->data = g_memdup (data, size); + else + parasite->data = NULL; + + return parasite; +} + +void +gimp_parasite_free (GimpParasite *parasite) +{ + if (parasite == NULL) + return; + + if (parasite->name) + g_free (parasite->name); + + if (parasite->data) + g_free (parasite->data); + + g_slice_free (GimpParasite, parasite); +} + +gboolean +gimp_parasite_is_type (const GimpParasite *parasite, + const gchar *name) +{ + if (!parasite || !parasite->name) + return FALSE; + + return (strcmp (parasite->name, name) == 0); +} + +GimpParasite * +gimp_parasite_copy (const GimpParasite *parasite) +{ + if (parasite == NULL) + return NULL; + + return gimp_parasite_new (parasite->name, parasite->flags, + parasite->size, parasite->data); +} + +gboolean +gimp_parasite_compare (const GimpParasite *a, + const GimpParasite *b) +{ + if (a && b && + a->name && b->name && + strcmp (a->name, b->name) == 0 && + a->flags == b->flags && + a->size == b->size) + { + if (a->data == NULL && b->data == NULL) + return TRUE; + else if (a->data && b->data && memcmp (a->data, b->data, a->size) == 0) + return TRUE; + } + + return FALSE; +} + +gulong +gimp_parasite_flags (const GimpParasite *parasite) +{ + if (parasite == NULL) + return 0; + + return parasite->flags; +} + +gboolean +gimp_parasite_is_persistent (const GimpParasite *parasite) +{ + if (parasite == NULL) + return FALSE; + + return (parasite->flags & GIMP_PARASITE_PERSISTENT); +} + +gboolean +gimp_parasite_is_undoable (const GimpParasite *parasite) +{ + if (parasite == NULL) + return FALSE; + + return (parasite->flags & GIMP_PARASITE_UNDOABLE); +} + +gboolean +gimp_parasite_has_flag (const GimpParasite *parasite, + gulong flag) +{ + if (parasite == NULL) + return FALSE; + + return (parasite->flags & flag); +} + +const gchar * +gimp_parasite_name (const GimpParasite *parasite) +{ + if (parasite) + return parasite->name; + + return NULL; +} + +gconstpointer +gimp_parasite_data (const GimpParasite *parasite) +{ + if (parasite) + return parasite->data; + + return NULL; +} + +glong +gimp_parasite_data_size (const GimpParasite *parasite) +{ + if (parasite) + return parasite->size; + + return 0; +} diff --git a/libgimpbase/gimpparasite.h b/libgimpbase/gimpparasite.h new file mode 100644 index 0000000..3c17bf7 --- /dev/null +++ b/libgimpbase/gimpparasite.h @@ -0,0 +1,113 @@ +/* LIBGIMP - The GIMP Library + * Copyright (C) 1995-1997 Peter Mattis and Spencer Kimball + * + * gimpparasite.h + * Copyright (C) 1998 Jay Cox <jaycox@gimp.org> + * + * This library is free software: you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see + * <https://www.gnu.org/licenses/>. + */ + +#if !defined (__GIMP_BASE_H_INSIDE__) && !defined (GIMP_BASE_COMPILATION) +#error "Only <libgimpbase/gimpbase.h> can be included directly." +#endif + +#ifndef __GIMP_PARASITE_H__ +#define __GIMP_PARASITE_H__ + +G_BEGIN_DECLS + +/* For information look into the C source or the html documentation */ + + +/* + * GIMP_TYPE_PARASITE + */ + +#define GIMP_TYPE_PARASITE (gimp_parasite_get_type ()) +#define GIMP_VALUE_HOLDS_PARASITE(value) (G_TYPE_CHECK_VALUE_TYPE ((value), GIMP_TYPE_PARASITE)) + +GType gimp_parasite_get_type (void) G_GNUC_CONST; + + +/* + * GIMP_TYPE_PARAM_PARASITE + */ + +#define GIMP_TYPE_PARAM_PARASITE (gimp_param_parasite_get_type ()) +#define GIMP_IS_PARAM_SPEC_PARASITE(pspec) (G_TYPE_CHECK_INSTANCE_TYPE ((pspec), GIMP_TYPE_PARAM_PARASITE)) + +GType gimp_param_parasite_get_type (void) G_GNUC_CONST; + +GParamSpec * gimp_param_spec_parasite (const gchar *name, + const gchar *nick, + const gchar *blurb, + GParamFlags flags); + + +#define GIMP_PARASITE_PERSISTENT 1 +#define GIMP_PARASITE_UNDOABLE 2 + +#define GIMP_PARASITE_ATTACH_PARENT (0x80 << 8) +#define GIMP_PARASITE_PARENT_PERSISTENT (GIMP_PARASITE_PERSISTENT << 8) +#define GIMP_PARASITE_PARENT_UNDOABLE (GIMP_PARASITE_UNDOABLE << 8) + +#define GIMP_PARASITE_ATTACH_GRANDPARENT (0x80 << 16) +#define GIMP_PARASITE_GRANDPARENT_PERSISTENT (GIMP_PARASITE_PERSISTENT << 16) +#define GIMP_PARASITE_GRANDPARENT_UNDOABLE (GIMP_PARASITE_UNDOABLE << 16) + + +/** + * GimpParasite: + * @name: the parasite name, USE A UNIQUE PREFIX + * @flags: the parasite flags, like save in XCF etc. + * @size: the parasite size in bytes + * @data: the parasite data, the owner os the parasite is responsible + * for tracking byte order and internal structure + **/ +struct _GimpParasite +{ + gchar *name; + guint32 flags; + guint32 size; + gpointer data; +}; + + +GimpParasite * gimp_parasite_new (const gchar *name, + guint32 flags, + guint32 size, + gconstpointer data); +void gimp_parasite_free (GimpParasite *parasite); + +GimpParasite * gimp_parasite_copy (const GimpParasite *parasite); + +gboolean gimp_parasite_compare (const GimpParasite *a, + const GimpParasite *b); + +gboolean gimp_parasite_is_type (const GimpParasite *parasite, + const gchar *name); +gboolean gimp_parasite_is_persistent (const GimpParasite *parasite); +gboolean gimp_parasite_is_undoable (const GimpParasite *parasite); +gboolean gimp_parasite_has_flag (const GimpParasite *parasite, + gulong flag); +gulong gimp_parasite_flags (const GimpParasite *parasite); +const gchar * gimp_parasite_name (const GimpParasite *parasite); +gconstpointer gimp_parasite_data (const GimpParasite *parasite); +glong gimp_parasite_data_size (const GimpParasite *parasite); + + +G_END_DECLS + +#endif /* __GIMP_PARASITE_H__ */ diff --git a/libgimpbase/gimpparasiteio.c b/libgimpbase/gimpparasiteio.c new file mode 100644 index 0000000..727048a --- /dev/null +++ b/libgimpbase/gimpparasiteio.c @@ -0,0 +1,204 @@ +/* LIBGIMP - The GIMP Library + * Copyright (C) 1995-1997 Peter Mattis and Spencer Kimball + * + * gimpparasiteio.c + * Copyright (C) 1999 Tor Lillqvist <tml@iki.fi> + * + * This library is free software: you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see + * <https://www.gnu.org/licenses/>. + */ + +/* + * Functions for building and parsing string representations of + * various standard parasite types. + */ + +#include "config.h" + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include <glib.h> + +#include "gimpparasiteio.h" + + +/** + * SECTION: gimpparasiteio + * @title: gimpparasiteio + * @short_description: Utility functions to (de)serialize certain C + * structures to/from #GimpParasite's. + * @see_also: #GimpParasite + * + * Utility functions to (de)serialize certain C structures to/from* + * #GimpParasite's. + **/ + + +void +gimp_pixpipe_params_init (GimpPixPipeParams *params) +{ + gint i; + + g_return_if_fail (params != NULL); + + params->step = 100; + params->ncells = 1; + params->cellwidth = 1; + params->cellheight = 1; + params->dim = 1; + params->cols = 1; + params->rows = 1; + params->placement = g_strdup ("constant"); + + for (i = 0; i < GIMP_PIXPIPE_MAXDIM; i++) + params->selection[i] = g_strdup ("random"); + + params->rank[0] = 1; + for (i = 1; i < GIMP_PIXPIPE_MAXDIM; i++) + params->rank[i] = 0; +} + +void +gimp_pixpipe_params_parse (const gchar *string, + GimpPixPipeParams *params) +{ + gchar *copy; + gchar *p, *q, *r; + gint i; + + g_return_if_fail (string != NULL); + g_return_if_fail (params != NULL); + + copy = g_strdup (string); + + q = copy; + while ((p = strtok (q, " \r\n")) != NULL) + { + q = NULL; + r = strchr (p, ':'); + if (r) + *r = 0; + + if (strcmp (p, "ncells") == 0) + { + if (r) + params->ncells = atoi (r + 1); + } + else if (strcmp (p, "step") == 0) + { + if (r) + params->step = atoi (r + 1); + } + else if (strcmp (p, "dim") == 0) + { + if (r) + { + params->dim = atoi (r + 1); + params->dim = CLAMP (params->dim, 1, GIMP_PIXPIPE_MAXDIM); + } + } + else if (strcmp (p, "cols") == 0) + { + if (r) + params->cols = atoi (r + 1); + } + else if (strcmp (p, "rows") == 0) + { + if (r) + params->rows = atoi (r + 1); + } + else if (strcmp (p, "cellwidth") == 0) + { + if (r) + params->cellwidth = atoi (r + 1); + } + else if (strcmp (p, "cellheight") == 0) + { + if (r) + params->cellheight = atoi (r + 1); + } + else if (strcmp (p, "placement") == 0) + { + if (r) + { + g_free (params->placement); + params->placement = g_strdup (r + 1); + } + } + else if (strncmp (p, "rank", strlen ("rank")) == 0 && r) + { + if (r) + { + i = atoi (p + strlen ("rank")); + if (i >= 0 && i < params->dim) + params->rank[i] = atoi (r + 1); + } + } + else if (strncmp (p, "sel", strlen ("sel")) == 0 && r) + { + if (r) + { + i = atoi (p + strlen ("sel")); + if (i >= 0 && i < params->dim) + { + g_free (params->selection[i]); + params->selection[i] = g_strdup (r + 1); + } + } + } + if (r) + *r = ':'; + } + + g_free (copy); +} + +gchar * +gimp_pixpipe_params_build (GimpPixPipeParams *params) +{ + GString *str; + gint i; + + g_return_val_if_fail (params != NULL, NULL); + + str = g_string_new (NULL); + + g_string_printf (str, "ncells:%d cellwidth:%d cellheight:%d " + "step:%d dim:%d cols:%d rows:%d placement:%s", + params->ncells, params->cellwidth, params->cellheight, + params->step, params->dim, + params->cols, params->rows, + params->placement); + + for (i = 0; i < params->dim; i++) + { + g_string_append_printf (str, " rank%d:%d", i, params->rank[i]); + g_string_append_printf (str, " sel%d:%s", i, params->selection[i]); + } + + return g_string_free (str, FALSE); +} + +void +gimp_pixpipe_params_free (GimpPixPipeParams *params) +{ + gint i; + + g_free (params->placement); + + for (i = 0; i < GIMP_PIXPIPE_MAXDIM; i++) + g_free (params->selection[i]); +} diff --git a/libgimpbase/gimpparasiteio.h b/libgimpbase/gimpparasiteio.h new file mode 100644 index 0000000..9024b48 --- /dev/null +++ b/libgimpbase/gimpparasiteio.h @@ -0,0 +1,92 @@ +/* LIBGIMP - The GIMP Library + * Copyright (C) 1995-1997 Peter Mattis and Spencer Kimball + * + * gimpparasiteio.h + * Copyright (C) 1999 Tor Lillqvist <tml@iki.fi> + * + * This library is free software: you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see + * <https://www.gnu.org/licenses/>. + */ + +#ifndef __GIMP_PARASITE_IO_H__ +#define __GIMP_PARASITE_IO_H__ + +G_BEGIN_DECLS + +/* For information look into the C source or the html documentation */ + + +/* Data structures for various standard parasites used by plug-ins and + * the GIMP core, and functions to build and parse their string + * representations. + */ + +/* + * Pixmap brush pipes. + */ + +#define GIMP_PIXPIPE_MAXDIM 4 + +typedef struct _GimpPixPipeParams GimpPixPipeParams; + +/** + * GimpPixPipeParams: + * @step: Step + * @ncells: Number of cells + * @dim: Dimension + * @cols: Columns + * @rows: Rows + * @cellwidth: Cell width + * @cellheight: Cell height + * @placement: Placement + * @free_placement_string: Unused, ignore + * @rank: Rank + * @selection: Selection + * @free_selection_string: Unused, ignore + * + * PLease somebody help documenting this. + **/ +struct _GimpPixPipeParams +{ + gint step; + gint ncells; + gint dim; + gint cols; + gint rows; + gint cellwidth; + gint cellheight; + gchar *placement; + gboolean free_placement_string; + gint rank[GIMP_PIXPIPE_MAXDIM]; + gchar *selection[GIMP_PIXPIPE_MAXDIM]; + /* this flag is now useless. All selection strings are allocated. */ + gboolean free_selection_string; +}; + +/* Initialize with dummy values */ +void gimp_pixpipe_params_init (GimpPixPipeParams *params); + +/* Parse a string into a GimpPixPipeParams */ +void gimp_pixpipe_params_parse (const gchar *parameters, + GimpPixPipeParams *params); + +/* Build a string representation of GimpPixPipeParams */ +gchar * gimp_pixpipe_params_build (GimpPixPipeParams *params) G_GNUC_MALLOC; + +/* Free the internal values. It does not free the struct itself. */ +void gimp_pixpipe_params_free (GimpPixPipeParams *params); + +G_END_DECLS + +#endif /* __GIMP_PARASITE_IO_H__ */ diff --git a/libgimpbase/gimpprotocol.c b/libgimpbase/gimpprotocol.c new file mode 100644 index 0000000..ded796b --- /dev/null +++ b/libgimpbase/gimpprotocol.c @@ -0,0 +1,1934 @@ +/* LIBGIMP - The GIMP Library + * Copyright (C) 1995-1997 Peter Mattis and Spencer Kimball + * + * This library is free software: you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This library 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see + * <https://www.gnu.org/licenses/>. + */ + +#include "config.h" + +#include <glib-object.h> + +#include "gimpbasetypes.h" + +#include "gimpparasite.h" +#include "gimpprotocol.h" +#include "gimpwire.h" + + +static void _gp_quit_read (GIOChannel *channel, + GimpWireMessage *msg, + gpointer user_data); +static void _gp_quit_write (GIOChannel *channel, + GimpWireMessage *msg, + gpointer user_data); +static void _gp_quit_destroy (GimpWireMessage *msg); + +static void _gp_config_read (GIOChannel *channel, + GimpWireMessage *msg, + gpointer user_data); +static void _gp_config_write (GIOChannel *channel, + GimpWireMessage *msg, + gpointer user_data); +static void _gp_config_destroy (GimpWireMessage *msg); + +static void _gp_tile_req_read (GIOChannel *channel, + GimpWireMessage *msg, + gpointer user_data); +static void _gp_tile_req_write (GIOChannel *channel, + GimpWireMessage *msg, + gpointer user_data); +static void _gp_tile_req_destroy (GimpWireMessage *msg); + +static void _gp_tile_ack_read (GIOChannel *channel, + GimpWireMessage *msg, + gpointer user_data); +static void _gp_tile_ack_write (GIOChannel *channel, + GimpWireMessage *msg, + gpointer user_data); +static void _gp_tile_ack_destroy (GimpWireMessage *msg); + +static void _gp_tile_data_read (GIOChannel *channel, + GimpWireMessage *msg, + gpointer user_data); +static void _gp_tile_data_write (GIOChannel *channel, + GimpWireMessage *msg, + gpointer user_data); +static void _gp_tile_data_destroy (GimpWireMessage *msg); + +static void _gp_proc_run_read (GIOChannel *channel, + GimpWireMessage *msg, + gpointer user_data); +static void _gp_proc_run_write (GIOChannel *channel, + GimpWireMessage *msg, + gpointer user_data); +static void _gp_proc_run_destroy (GimpWireMessage *msg); + +static void _gp_proc_return_read (GIOChannel *channel, + GimpWireMessage *msg, + gpointer user_data); +static void _gp_proc_return_write (GIOChannel *channel, + GimpWireMessage *msg, + gpointer user_data); +static void _gp_proc_return_destroy (GimpWireMessage *msg); + +static void _gp_temp_proc_run_read (GIOChannel *channel, + GimpWireMessage *msg, + gpointer user_data); +static void _gp_temp_proc_run_write (GIOChannel *channel, + GimpWireMessage *msg, + gpointer user_data); +static void _gp_temp_proc_run_destroy (GimpWireMessage *msg); + +static void _gp_temp_proc_return_read (GIOChannel *channel, + GimpWireMessage *msg, + gpointer user_data); +static void _gp_temp_proc_return_write (GIOChannel *channel, + GimpWireMessage *msg, + gpointer user_data); +static void _gp_temp_proc_return_destroy (GimpWireMessage *msg); + +static void _gp_proc_install_read (GIOChannel *channel, + GimpWireMessage *msg, + gpointer user_data); +static void _gp_proc_install_write (GIOChannel *channel, + GimpWireMessage *msg, + gpointer user_data); +static void _gp_proc_install_destroy (GimpWireMessage *msg); + +static void _gp_proc_uninstall_read (GIOChannel *channel, + GimpWireMessage *msg, + gpointer user_data); +static void _gp_proc_uninstall_write (GIOChannel *channel, + GimpWireMessage *msg, + gpointer user_data); +static void _gp_proc_uninstall_destroy (GimpWireMessage *msg); + +static void _gp_extension_ack_read (GIOChannel *channel, + GimpWireMessage *msg, + gpointer user_data); +static void _gp_extension_ack_write (GIOChannel *channel, + GimpWireMessage *msg, + gpointer user_data); +static void _gp_extension_ack_destroy (GimpWireMessage *msg); + +static void _gp_params_read (GIOChannel *channel, + GPParam **params, + guint *nparams, + gpointer user_data); +static void _gp_params_write (GIOChannel *channel, + GPParam *params, + gint nparams, + gpointer user_data); + +static void _gp_has_init_read (GIOChannel *channel, + GimpWireMessage *msg, + gpointer user_data); +static void _gp_has_init_write (GIOChannel *channel, + GimpWireMessage *msg, + gpointer user_data); +static void _gp_has_init_destroy (GimpWireMessage *msg); + + + +void +gp_init (void) +{ + gimp_wire_register (GP_QUIT, + _gp_quit_read, + _gp_quit_write, + _gp_quit_destroy); + gimp_wire_register (GP_CONFIG, + _gp_config_read, + _gp_config_write, + _gp_config_destroy); + gimp_wire_register (GP_TILE_REQ, + _gp_tile_req_read, + _gp_tile_req_write, + _gp_tile_req_destroy); + gimp_wire_register (GP_TILE_ACK, + _gp_tile_ack_read, + _gp_tile_ack_write, + _gp_tile_ack_destroy); + gimp_wire_register (GP_TILE_DATA, + _gp_tile_data_read, + _gp_tile_data_write, + _gp_tile_data_destroy); + gimp_wire_register (GP_PROC_RUN, + _gp_proc_run_read, + _gp_proc_run_write, + _gp_proc_run_destroy); + gimp_wire_register (GP_PROC_RETURN, + _gp_proc_return_read, + _gp_proc_return_write, + _gp_proc_return_destroy); + gimp_wire_register (GP_TEMP_PROC_RUN, + _gp_temp_proc_run_read, + _gp_temp_proc_run_write, + _gp_temp_proc_run_destroy); + gimp_wire_register (GP_TEMP_PROC_RETURN, + _gp_temp_proc_return_read, + _gp_temp_proc_return_write, + _gp_temp_proc_return_destroy); + gimp_wire_register (GP_PROC_INSTALL, + _gp_proc_install_read, + _gp_proc_install_write, + _gp_proc_install_destroy); + gimp_wire_register (GP_PROC_UNINSTALL, + _gp_proc_uninstall_read, + _gp_proc_uninstall_write, + _gp_proc_uninstall_destroy); + gimp_wire_register (GP_EXTENSION_ACK, + _gp_extension_ack_read, + _gp_extension_ack_write, + _gp_extension_ack_destroy); + gimp_wire_register (GP_HAS_INIT, + _gp_has_init_read, + _gp_has_init_write, + _gp_has_init_destroy); +} + +gboolean +gp_quit_write (GIOChannel *channel, + gpointer user_data) +{ + GimpWireMessage msg; + + msg.type = GP_QUIT; + msg.data = NULL; + + if (! gimp_wire_write_msg (channel, &msg, user_data)) + return FALSE; + + if (! gimp_wire_flush (channel, user_data)) + return FALSE; + + return TRUE; +} + +gboolean +gp_config_write (GIOChannel *channel, + GPConfig *config, + gpointer user_data) +{ + GimpWireMessage msg; + + msg.type = GP_CONFIG; + msg.data = config; + + if (! gimp_wire_write_msg (channel, &msg, user_data)) + return FALSE; + + if (! gimp_wire_flush (channel, user_data)) + return FALSE; + + return TRUE; +} + +gboolean +gp_tile_req_write (GIOChannel *channel, + GPTileReq *tile_req, + gpointer user_data) +{ + GimpWireMessage msg; + + msg.type = GP_TILE_REQ; + msg.data = tile_req; + + if (! gimp_wire_write_msg (channel, &msg, user_data)) + return FALSE; + + if (! gimp_wire_flush (channel, user_data)) + return FALSE; + + return TRUE; +} + +gboolean +gp_tile_ack_write (GIOChannel *channel, + gpointer user_data) +{ + GimpWireMessage msg; + + msg.type = GP_TILE_ACK; + msg.data = NULL; + + if (! gimp_wire_write_msg (channel, &msg, user_data)) + return FALSE; + + if (! gimp_wire_flush (channel, user_data)) + return FALSE; + + return TRUE; +} + +gboolean +gp_tile_data_write (GIOChannel *channel, + GPTileData *tile_data, + gpointer user_data) +{ + GimpWireMessage msg; + + msg.type = GP_TILE_DATA; + msg.data = tile_data; + + if (! gimp_wire_write_msg (channel, &msg, user_data)) + return FALSE; + + if (! gimp_wire_flush (channel, user_data)) + return FALSE; + + return TRUE; +} + +gboolean +gp_proc_run_write (GIOChannel *channel, + GPProcRun *proc_run, + gpointer user_data) +{ + GimpWireMessage msg; + + msg.type = GP_PROC_RUN; + msg.data = proc_run; + + if (! gimp_wire_write_msg (channel, &msg, user_data)) + return FALSE; + + if (! gimp_wire_flush (channel, user_data)) + return FALSE; + + return TRUE; +} + +gboolean +gp_proc_return_write (GIOChannel *channel, + GPProcReturn *proc_return, + gpointer user_data) +{ + GimpWireMessage msg; + + msg.type = GP_PROC_RETURN; + msg.data = proc_return; + + if (! gimp_wire_write_msg (channel, &msg, user_data)) + return FALSE; + + if (! gimp_wire_flush (channel, user_data)) + return FALSE; + + return TRUE; +} + +gboolean +gp_temp_proc_run_write (GIOChannel *channel, + GPProcRun *proc_run, + gpointer user_data) +{ + GimpWireMessage msg; + + msg.type = GP_TEMP_PROC_RUN; + msg.data = proc_run; + + if (! gimp_wire_write_msg (channel, &msg, user_data)) + return FALSE; + + if (! gimp_wire_flush (channel, user_data)) + return FALSE; + + return TRUE; +} + +gboolean +gp_temp_proc_return_write (GIOChannel *channel, + GPProcReturn *proc_return, + gpointer user_data) +{ + GimpWireMessage msg; + + msg.type = GP_TEMP_PROC_RETURN; + msg.data = proc_return; + + if (! gimp_wire_write_msg (channel, &msg, user_data)) + return FALSE; + + if (! gimp_wire_flush (channel, user_data)) + return FALSE; + + return TRUE; +} + +gboolean +gp_proc_install_write (GIOChannel *channel, + GPProcInstall *proc_install, + gpointer user_data) +{ + GimpWireMessage msg; + + msg.type = GP_PROC_INSTALL; + msg.data = proc_install; + + if (! gimp_wire_write_msg (channel, &msg, user_data)) + return FALSE; + + if (! gimp_wire_flush (channel, user_data)) + return FALSE; + + return TRUE; +} + +gboolean +gp_proc_uninstall_write (GIOChannel *channel, + GPProcUninstall *proc_uninstall, + gpointer user_data) +{ + GimpWireMessage msg; + + msg.type = GP_PROC_UNINSTALL; + msg.data = proc_uninstall; + + if (! gimp_wire_write_msg (channel, &msg, user_data)) + return FALSE; + + if (! gimp_wire_flush (channel, user_data)) + return FALSE; + + return TRUE; +} + +gboolean +gp_extension_ack_write (GIOChannel *channel, + gpointer user_data) +{ + GimpWireMessage msg; + + msg.type = GP_EXTENSION_ACK; + msg.data = NULL; + + if (! gimp_wire_write_msg (channel, &msg, user_data)) + return FALSE; + + if (! gimp_wire_flush (channel, user_data)) + return FALSE; + + return TRUE; +} + +gboolean +gp_has_init_write (GIOChannel *channel, + gpointer user_data) +{ + GimpWireMessage msg; + + msg.type = GP_HAS_INIT; + msg.data = NULL; + + if (! gimp_wire_write_msg (channel, &msg, user_data)) + return FALSE; + + if (! gimp_wire_flush (channel, user_data)) + return FALSE; + + return TRUE; +} + +/* quit */ + +static void +_gp_quit_read (GIOChannel *channel, + GimpWireMessage *msg, + gpointer user_data) +{ +} + +static void +_gp_quit_write (GIOChannel *channel, + GimpWireMessage *msg, + gpointer user_data) +{ +} + +static void +_gp_quit_destroy (GimpWireMessage *msg) +{ +} + +/* config */ + +static void +_gp_config_read (GIOChannel *channel, + GimpWireMessage *msg, + gpointer user_data) +{ + GPConfig *config = g_slice_new0 (GPConfig); + + if (! _gimp_wire_read_int32 (channel, + &config->version, 1, user_data)) + goto cleanup; + if (! _gimp_wire_read_int32 (channel, + &config->tile_width, 1, user_data)) + goto cleanup; + if (! _gimp_wire_read_int32 (channel, + &config->tile_height, 1, user_data)) + goto cleanup; + if (! _gimp_wire_read_int32 (channel, + (guint32 *) &config->shm_ID, 1, user_data)) + goto cleanup; + if (! _gimp_wire_read_int8 (channel, + (guint8 *) &config->check_size, 1, user_data)) + goto cleanup; + if (! _gimp_wire_read_int8 (channel, + (guint8 *) &config->check_type, 1, user_data)) + goto cleanup; + if (! _gimp_wire_read_int8 (channel, + (guint8 *) &config->show_help_button, 1, + user_data)) + goto cleanup; + if (! _gimp_wire_read_int8 (channel, + (guint8 *) &config->use_cpu_accel, 1, + user_data)) + goto cleanup; + if (! _gimp_wire_read_int8 (channel, + (guint8 *) &config->use_opencl, 1, + user_data)) + goto cleanup; + if (! _gimp_wire_read_int8 (channel, + (guint8 *) &config->export_exif, 1, + user_data)) + goto cleanup; + if (! _gimp_wire_read_int8 (channel, + (guint8 *) &config->export_xmp, 1, + user_data)) + goto cleanup; + if (! _gimp_wire_read_int8 (channel, + (guint8 *) &config->export_iptc, 1, + user_data)) + goto cleanup; + if (! _gimp_wire_read_int8 (channel, + (guint8 *) &config->export_profile, 1, + user_data)) + goto cleanup; + if (! _gimp_wire_read_int8 (channel, + (guint8 *) &config->show_tooltips, 1, user_data)) + goto cleanup; + if (! _gimp_wire_read_int32 (channel, + (guint32 *) &config->min_colors, 1, user_data)) + goto cleanup; + if (! _gimp_wire_read_int32 (channel, + (guint32 *) &config->gdisp_ID, 1, user_data)) + goto cleanup; + + if (! _gimp_wire_read_string (channel, + &config->app_name, 1, user_data)) + goto cleanup; + if (! _gimp_wire_read_string (channel, + &config->wm_class, 1, user_data)) + goto cleanup; + if (! _gimp_wire_read_string (channel, + &config->display_name, 1, user_data)) + goto cleanup; + if (! _gimp_wire_read_int32 (channel, + (guint32 *) &config->monitor_number, 1, + user_data)) + goto cleanup; + if (! _gimp_wire_read_int32 (channel, + &config->timestamp, 1, user_data)) + goto cleanup; + + if (config->version < 0x0017) + goto end; + + if (! _gimp_wire_read_string (channel, + &config->icon_theme_dir, 1, user_data)) + goto cleanup; + + if (config->version < 0x0019) + goto end; + + if (! _gimp_wire_read_int64 (channel, + &config->tile_cache_size, 1, user_data)) + goto cleanup; + if (! _gimp_wire_read_string (channel, + &config->swap_path, 1, user_data)) + goto cleanup; + if (! _gimp_wire_read_int32 (channel, + (guint32 *) &config->num_processors, 1, + user_data)) + goto cleanup; + + if (config->version < 0x001A) + goto end; + + if (! _gimp_wire_read_string (channel, + &config->swap_compression, 1, user_data)) + goto cleanup; + + end: + msg->data = config; + return; + + cleanup: + g_free (config->app_name); + g_free (config->wm_class); + g_free (config->display_name); + g_free (config->icon_theme_dir); + g_free (config->swap_path); + g_free (config->swap_compression); + g_slice_free (GPConfig, config); +} + +static void +_gp_config_write (GIOChannel *channel, + GimpWireMessage *msg, + gpointer user_data) +{ + GPConfig *config = msg->data; + + if (! _gimp_wire_write_int32 (channel, + &config->version, 1, user_data)) + return; + if (! _gimp_wire_write_int32 (channel, + &config->tile_width, 1, user_data)) + return; + if (! _gimp_wire_write_int32 (channel, + &config->tile_height, 1, user_data)) + return; + if (! _gimp_wire_write_int32 (channel, + (const guint32 *) &config->shm_ID, 1, + user_data)) + return; + if (! _gimp_wire_write_int8 (channel, + (const guint8 *) &config->check_size, 1, + user_data)) + return; + if (! _gimp_wire_write_int8 (channel, + (const guint8 *) &config->check_type, 1, + user_data)) + return; + if (! _gimp_wire_write_int8 (channel, + (const guint8 *) &config->show_help_button, 1, + user_data)) + return; + if (! _gimp_wire_write_int8 (channel, + (const guint8 *) &config->use_cpu_accel, 1, + user_data)) + return; + if (! _gimp_wire_write_int8 (channel, + (const guint8 *) &config->use_opencl, 1, + user_data)) + return; + if (! _gimp_wire_write_int8 (channel, + (const guint8 *) &config->export_exif, 1, + user_data)) + return; + if (! _gimp_wire_write_int8 (channel, + (const guint8 *) &config->export_xmp, 1, + user_data)) + return; + if (! _gimp_wire_write_int8 (channel, + (const guint8 *) &config->export_iptc, 1, + user_data)) + return; + if (! _gimp_wire_write_int8 (channel, + (const guint8 *) &config->export_profile, 1, + user_data)) + return; + if (! _gimp_wire_write_int8 (channel, + (const guint8 *) &config->show_tooltips, 1, + user_data)) + return; + if (! _gimp_wire_write_int32 (channel, + (const guint32 *) &config->min_colors, 1, + user_data)) + return; + if (! _gimp_wire_write_int32 (channel, + (const guint32 *) &config->gdisp_ID, 1, + user_data)) + return; + if (! _gimp_wire_write_string (channel, + &config->app_name, 1, user_data)) + return; + if (! _gimp_wire_write_string (channel, + &config->wm_class, 1, user_data)) + return; + if (! _gimp_wire_write_string (channel, + &config->display_name, 1, user_data)) + return; + if (! _gimp_wire_write_int32 (channel, + (const guint32 *) &config->monitor_number, 1, + user_data)) + return; + if (! _gimp_wire_write_int32 (channel, + (const guint32 *) &config->timestamp, 1, + user_data)) + return; + + if (config->version < 0x0017) + return; + + if (! _gimp_wire_write_string (channel, + &config->icon_theme_dir, 1, user_data)) + return; + + if (config->version < 0x0019) + return; + + if (! _gimp_wire_write_int64 (channel, + &config->tile_cache_size, 1, user_data)) + return; + if (! _gimp_wire_write_string (channel, + &config->swap_path, 1, user_data)) + return; + if (! _gimp_wire_write_int32 (channel, + (const guint32 *) &config->num_processors, 1, + user_data)) + return; + + if (config->version < 0x001A) + return; + + if (! _gimp_wire_write_string (channel, + &config->swap_compression, 1, user_data)) + return; +} + +static void +_gp_config_destroy (GimpWireMessage *msg) +{ + GPConfig *config = msg->data; + + if (config) + { + g_free (config->app_name); + g_free (config->wm_class); + g_free (config->display_name); + g_free (config->icon_theme_dir); + g_free (config->swap_path); + g_free (config->swap_compression); + g_slice_free (GPConfig, config); + } +} + +/* tile_req */ + +static void +_gp_tile_req_read (GIOChannel *channel, + GimpWireMessage *msg, + gpointer user_data) +{ + GPTileReq *tile_req = g_slice_new0 (GPTileReq); + + if (! _gimp_wire_read_int32 (channel, + (guint32 *) &tile_req->drawable_ID, 1, + user_data)) + goto cleanup; + if (! _gimp_wire_read_int32 (channel, + &tile_req->tile_num, 1, user_data)) + goto cleanup; + if (! _gimp_wire_read_int32 (channel, + &tile_req->shadow, 1, user_data)) + goto cleanup; + + msg->data = tile_req; + return; + + cleanup: + g_slice_free (GPTileReq, tile_req); + msg->data = NULL; +} + +static void +_gp_tile_req_write (GIOChannel *channel, + GimpWireMessage *msg, + gpointer user_data) +{ + GPTileReq *tile_req = msg->data; + + if (! _gimp_wire_write_int32 (channel, + (const guint32 *) &tile_req->drawable_ID, 1, + user_data)) + return; + if (! _gimp_wire_write_int32 (channel, + &tile_req->tile_num, 1, user_data)) + return; + if (! _gimp_wire_write_int32 (channel, + &tile_req->shadow, 1, user_data)) + return; +} + +static void +_gp_tile_req_destroy (GimpWireMessage *msg) +{ + GPTileReq *tile_req = msg->data; + + if (tile_req) + g_slice_free (GPTileReq, msg->data); +} + +/* tile_ack */ + +static void +_gp_tile_ack_read (GIOChannel *channel, + GimpWireMessage *msg, + gpointer user_data) +{ +} + +static void +_gp_tile_ack_write (GIOChannel *channel, + GimpWireMessage *msg, + gpointer user_data) +{ +} + +static void +_gp_tile_ack_destroy (GimpWireMessage *msg) +{ +} + +/* tile_data */ + +static void +_gp_tile_data_read (GIOChannel *channel, + GimpWireMessage *msg, + gpointer user_data) +{ + GPTileData *tile_data = g_slice_new0 (GPTileData); + + if (! _gimp_wire_read_int32 (channel, + (guint32 *) &tile_data->drawable_ID, 1, + user_data)) + goto cleanup; + if (! _gimp_wire_read_int32 (channel, + &tile_data->tile_num, 1, user_data)) + goto cleanup; + if (! _gimp_wire_read_int32 (channel, + &tile_data->shadow, 1, user_data)) + goto cleanup; + if (! _gimp_wire_read_int32 (channel, + &tile_data->bpp, 1, user_data)) + goto cleanup; + if (! _gimp_wire_read_int32 (channel, + &tile_data->width, 1, user_data)) + goto cleanup; + if (! _gimp_wire_read_int32 (channel, + &tile_data->height, 1, user_data)) + goto cleanup; + if (! _gimp_wire_read_int32 (channel, + &tile_data->use_shm, 1, user_data)) + goto cleanup; + + if (!tile_data->use_shm) + { + guint length = tile_data->width * tile_data->height * tile_data->bpp; + + tile_data->data = g_new (guchar, length); + + if (! _gimp_wire_read_int8 (channel, + (guint8 *) tile_data->data, length, + user_data)) + goto cleanup; + } + + msg->data = tile_data; + return; + + cleanup: + g_free (tile_data->data); + g_slice_free (GPTileData, tile_data); + msg->data = NULL; +} + +static void +_gp_tile_data_write (GIOChannel *channel, + GimpWireMessage *msg, + gpointer user_data) +{ + GPTileData *tile_data = msg->data; + + if (! _gimp_wire_write_int32 (channel, + (const guint32 *) &tile_data->drawable_ID, 1, + user_data)) + return; + if (! _gimp_wire_write_int32 (channel, + &tile_data->tile_num, 1, user_data)) + return; + if (! _gimp_wire_write_int32 (channel, + &tile_data->shadow, 1, user_data)) + return; + if (! _gimp_wire_write_int32 (channel, + &tile_data->bpp, 1, user_data)) + return; + if (! _gimp_wire_write_int32 (channel, + &tile_data->width, 1, user_data)) + return; + if (! _gimp_wire_write_int32 (channel, + &tile_data->height, 1, user_data)) + return; + if (! _gimp_wire_write_int32 (channel, + &tile_data->use_shm, 1, user_data)) + return; + + if (!tile_data->use_shm) + { + guint length = tile_data->width * tile_data->height * tile_data->bpp; + + if (! _gimp_wire_write_int8 (channel, + (const guint8 *) tile_data->data, length, + user_data)) + return; + } +} + +static void +_gp_tile_data_destroy (GimpWireMessage *msg) +{ + GPTileData *tile_data = msg->data; + + if (tile_data) + { + if (tile_data->data) + { + g_free (tile_data->data); + tile_data->data = NULL; + } + + g_slice_free (GPTileData, tile_data); + } +} + +/* proc_run */ + +static void +_gp_proc_run_read (GIOChannel *channel, + GimpWireMessage *msg, + gpointer user_data) +{ + GPProcRun *proc_run = g_slice_new0 (GPProcRun); + + if (! _gimp_wire_read_string (channel, &proc_run->name, 1, user_data)) + goto cleanup; + + _gp_params_read (channel, + &proc_run->params, (guint *) &proc_run->nparams, + user_data); + + msg->data = proc_run; + return; + + cleanup: + g_slice_free (GPProcRun, proc_run); + msg->data = NULL; +} + +static void +_gp_proc_run_write (GIOChannel *channel, + GimpWireMessage *msg, + gpointer user_data) +{ + GPProcRun *proc_run = msg->data; + + if (! _gimp_wire_write_string (channel, &proc_run->name, 1, user_data)) + return; + + _gp_params_write (channel, proc_run->params, proc_run->nparams, user_data); +} + +static void +_gp_proc_run_destroy (GimpWireMessage *msg) +{ + GPProcRun *proc_run = msg->data; + + if (proc_run) + { + gp_params_destroy (proc_run->params, proc_run->nparams); + + g_free (proc_run->name); + g_slice_free (GPProcRun, proc_run); + } +} + +/* proc_return */ + +static void +_gp_proc_return_read (GIOChannel *channel, + GimpWireMessage *msg, + gpointer user_data) +{ + GPProcReturn *proc_return = g_slice_new0 (GPProcReturn); + + if (! _gimp_wire_read_string (channel, &proc_return->name, 1, user_data)) + goto cleanup; + + _gp_params_read (channel, + &proc_return->params, (guint *) &proc_return->nparams, + user_data); + + msg->data = proc_return; + return; + + cleanup: + g_slice_free (GPProcReturn, proc_return); + msg->data = NULL; +} + +static void +_gp_proc_return_write (GIOChannel *channel, + GimpWireMessage *msg, + gpointer user_data) +{ + GPProcReturn *proc_return = msg->data; + + if (! _gimp_wire_write_string (channel, &proc_return->name, 1, user_data)) + return; + + _gp_params_write (channel, + proc_return->params, proc_return->nparams, user_data); +} + +static void +_gp_proc_return_destroy (GimpWireMessage *msg) +{ + GPProcReturn *proc_return = msg->data; + + if (proc_return) + { + gp_params_destroy (proc_return->params, proc_return->nparams); + + g_free (proc_return->name); + g_slice_free (GPProcReturn, proc_return); + } +} + +/* temp_proc_run */ + +static void +_gp_temp_proc_run_read (GIOChannel *channel, + GimpWireMessage *msg, + gpointer user_data) +{ + _gp_proc_run_read (channel, msg, user_data); +} + +static void +_gp_temp_proc_run_write (GIOChannel *channel, + GimpWireMessage *msg, + gpointer user_data) +{ + _gp_proc_run_write (channel, msg, user_data); +} + +static void +_gp_temp_proc_run_destroy (GimpWireMessage *msg) +{ + _gp_proc_run_destroy (msg); +} + +/* temp_proc_return */ + +static void +_gp_temp_proc_return_read (GIOChannel *channel, + GimpWireMessage *msg, + gpointer user_data) +{ + _gp_proc_return_read (channel, msg, user_data); +} + +static void +_gp_temp_proc_return_write (GIOChannel *channel, + GimpWireMessage *msg, + gpointer user_data) +{ + _gp_proc_return_write (channel, msg, user_data); +} + +static void +_gp_temp_proc_return_destroy (GimpWireMessage *msg) +{ + _gp_proc_return_destroy (msg); +} + +/* proc_install */ + +static void +_gp_proc_install_read (GIOChannel *channel, + GimpWireMessage *msg, + gpointer user_data) +{ + GPProcInstall *proc_install = g_slice_new0 (GPProcInstall); + gint i; + + if (! _gimp_wire_read_string (channel, + &proc_install->name, 1, user_data)) + goto cleanup; + if (! _gimp_wire_read_string (channel, + &proc_install->blurb, 1, user_data)) + goto cleanup; + if (! _gimp_wire_read_string (channel, + &proc_install->help, 1, user_data)) + goto cleanup; + if (! _gimp_wire_read_string (channel, + &proc_install->author, 1, user_data)) + goto cleanup; + if (! _gimp_wire_read_string (channel, + &proc_install->copyright, 1, user_data)) + goto cleanup; + if (! _gimp_wire_read_string (channel, + &proc_install->date, 1, user_data)) + goto cleanup; + if (! _gimp_wire_read_string (channel, + &proc_install->menu_path, 1, user_data)) + goto cleanup; + if (! _gimp_wire_read_string (channel, + &proc_install->image_types, 1, user_data)) + goto cleanup; + + if (! _gimp_wire_read_int32 (channel, + &proc_install->type, 1, user_data)) + goto cleanup; + if (! _gimp_wire_read_int32 (channel, + &proc_install->nparams, 1, user_data)) + goto cleanup; + if (! _gimp_wire_read_int32 (channel, + &proc_install->nreturn_vals, 1, user_data)) + goto cleanup; + + proc_install->params = g_new0 (GPParamDef, proc_install->nparams); + + for (i = 0; i < proc_install->nparams; i++) + { + if (! _gimp_wire_read_int32 (channel, + (guint32 *) &proc_install->params[i].type, 1, + user_data)) + goto cleanup; + if (! _gimp_wire_read_string (channel, + &proc_install->params[i].name, 1, + user_data)) + goto cleanup; + if (! _gimp_wire_read_string (channel, + &proc_install->params[i].description, 1, + user_data)) + goto cleanup; + } + + proc_install->return_vals = g_new0 (GPParamDef, proc_install->nreturn_vals); + + for (i = 0; i < proc_install->nreturn_vals; i++) + { + if (! _gimp_wire_read_int32 (channel, + (guint32 *) &proc_install->return_vals[i].type, 1, + user_data)) + goto cleanup; + if (! _gimp_wire_read_string (channel, + &proc_install->return_vals[i].name, 1, + user_data)) + goto cleanup; + if (! _gimp_wire_read_string (channel, + &proc_install->return_vals[i].description, 1, + user_data)) + goto cleanup; + } + + msg->data = proc_install; + return; + + cleanup: + g_free (proc_install->name); + g_free (proc_install->blurb); + g_free (proc_install->help); + g_free (proc_install->author); + g_free (proc_install->copyright); + g_free (proc_install->date); + g_free (proc_install->menu_path); + g_free (proc_install->image_types); + + if (proc_install->params) + { + for (i = 0; i < proc_install->nparams; i++) + { + if (!proc_install->params[i].name) + break; + + g_free (proc_install->params[i].name); + g_free (proc_install->params[i].description); + } + + g_free (proc_install->params); + } + + if (proc_install->return_vals) + { + for (i = 0; i < proc_install->nreturn_vals; i++) + { + if (!proc_install->return_vals[i].name) + break; + + g_free (proc_install->return_vals[i].name); + g_free (proc_install->return_vals[i].description); + } + + g_free (proc_install->return_vals); + } + + g_slice_free (GPProcInstall, proc_install); + msg->data = NULL; +} + +static void +_gp_proc_install_write (GIOChannel *channel, + GimpWireMessage *msg, + gpointer user_data) +{ + GPProcInstall *proc_install = msg->data; + gint i; + + if (! _gimp_wire_write_string (channel, + &proc_install->name, 1, user_data)) + return; + if (! _gimp_wire_write_string (channel, + &proc_install->blurb, 1, user_data)) + return; + if (! _gimp_wire_write_string (channel, + &proc_install->help, 1, user_data)) + return; + if (! _gimp_wire_write_string (channel, + &proc_install->author, 1, user_data)) + return; + if (! _gimp_wire_write_string (channel, + &proc_install->copyright, 1, user_data)) + return; + if (! _gimp_wire_write_string (channel, + &proc_install->date, 1, user_data)) + return; + if (! _gimp_wire_write_string (channel, + &proc_install->menu_path, 1, user_data)) + return; + if (! _gimp_wire_write_string (channel, + &proc_install->image_types, 1, user_data)) + return; + + if (! _gimp_wire_write_int32 (channel, + &proc_install->type, 1, user_data)) + return; + if (! _gimp_wire_write_int32 (channel, + &proc_install->nparams, 1, user_data)) + return; + if (! _gimp_wire_write_int32 (channel, + &proc_install->nreturn_vals, 1, user_data)) + return; + + for (i = 0; i < proc_install->nparams; i++) + { + if (! _gimp_wire_write_int32 (channel, + (guint32 *) &proc_install->params[i].type, 1, + user_data)) + return; + if (! _gimp_wire_write_string (channel, + &proc_install->params[i].name, 1, + user_data)) + return; + if (! _gimp_wire_write_string (channel, + &proc_install->params[i].description, 1, + user_data)) + return; + } + + for (i = 0; i < proc_install->nreturn_vals; i++) + { + if (! _gimp_wire_write_int32 (channel, + (guint32 *) &proc_install->return_vals[i].type, 1, + user_data)) + return; + if (! _gimp_wire_write_string (channel, + &proc_install->return_vals[i].name, 1, + user_data)) + return; + if (! _gimp_wire_write_string (channel, + &proc_install->return_vals[i].description, 1, + user_data)) + return; + } +} + +static void +_gp_proc_install_destroy (GimpWireMessage *msg) +{ + GPProcInstall *proc_install = msg->data; + + if (proc_install) + { + gint i; + + g_free (proc_install->name); + g_free (proc_install->blurb); + g_free (proc_install->help); + g_free (proc_install->author); + g_free (proc_install->copyright); + g_free (proc_install->date); + g_free (proc_install->menu_path); + g_free (proc_install->image_types); + + for (i = 0; i < proc_install->nparams; i++) + { + g_free (proc_install->params[i].name); + g_free (proc_install->params[i].description); + } + + for (i = 0; i < proc_install->nreturn_vals; i++) + { + g_free (proc_install->return_vals[i].name); + g_free (proc_install->return_vals[i].description); + } + + g_free (proc_install->params); + g_free (proc_install->return_vals); + g_slice_free (GPProcInstall, proc_install); + } +} + +/* proc_uninstall */ + +static void +_gp_proc_uninstall_read (GIOChannel *channel, + GimpWireMessage *msg, + gpointer user_data) +{ + GPProcUninstall *proc_uninstall = g_slice_new0 (GPProcUninstall); + + if (! _gimp_wire_read_string (channel, &proc_uninstall->name, 1, user_data)) + goto cleanup; + + msg->data = proc_uninstall; + return; + + cleanup: + g_slice_free (GPProcUninstall, proc_uninstall); +} + +static void +_gp_proc_uninstall_write (GIOChannel *channel, + GimpWireMessage *msg, + gpointer user_data) +{ + GPProcUninstall *proc_uninstall = msg->data; + + if (! _gimp_wire_write_string (channel, &proc_uninstall->name, 1, user_data)) + return; +} + +static void +_gp_proc_uninstall_destroy (GimpWireMessage *msg) +{ + GPProcUninstall *proc_uninstall = msg->data; + + if (proc_uninstall) + { + g_free (proc_uninstall->name); + g_slice_free (GPProcUninstall, proc_uninstall); + } +} + +/* extension_ack */ + +static void +_gp_extension_ack_read (GIOChannel *channel, + GimpWireMessage *msg, + gpointer user_data) +{ +} + +static void +_gp_extension_ack_write (GIOChannel *channel, + GimpWireMessage *msg, + gpointer user_data) +{ +} + +static void +_gp_extension_ack_destroy (GimpWireMessage *msg) +{ +} + +/* params */ + +static void +_gp_params_read (GIOChannel *channel, + GPParam **params, + guint *nparams, + gpointer user_data) +{ + gint i, j; + + if (! _gimp_wire_read_int32 (channel, (guint32 *) nparams, 1, user_data)) + return; + + if (*nparams == 0) + { + *params = NULL; + return; + } + + *params = g_new0 (GPParam, *nparams); + + for (i = 0; i < *nparams; i++) + { + if (! _gimp_wire_read_int32 (channel, + (guint32 *) &(*params)[i].type, 1, + user_data)) + goto cleanup; + + switch ((*params)[i].type) + { + case GIMP_PDB_INT32: + if (! _gimp_wire_read_int32 (channel, + (guint32 *) &(*params)[i].data.d_int32, 1, + user_data)) + goto cleanup; + break; + + case GIMP_PDB_INT16: + if (! _gimp_wire_read_int16 (channel, + (guint16 *) &(*params)[i].data.d_int16, 1, + user_data)) + goto cleanup; + break; + + case GIMP_PDB_INT8: + if (! _gimp_wire_read_int8 (channel, + &(*params)[i].data.d_int8, 1, + user_data)) + goto cleanup; + break; + + case GIMP_PDB_FLOAT: + if (! _gimp_wire_read_double (channel, + &(*params)[i].data.d_float, 1, + user_data)) + goto cleanup; + break; + + case GIMP_PDB_STRING: + if (! _gimp_wire_read_string (channel, + &(*params)[i].data.d_string, 1, + user_data)) + goto cleanup; + break; + + case GIMP_PDB_INT32ARRAY: + (*params)[i-1].data.d_int32 = MAX (0, (*params)[i-1].data.d_int32); + (*params)[i].data.d_int32array = g_new (gint32, + (*params)[i-1].data.d_int32); + + if (! _gimp_wire_read_int32 (channel, + (guint32 *) (*params)[i].data.d_int32array, + (*params)[i-1].data.d_int32, + user_data)) + { + g_free ((*params)[i].data.d_int32array); + goto cleanup; + } + break; + + case GIMP_PDB_INT16ARRAY: + (*params)[i-1].data.d_int32 = MAX (0, (*params)[i-1].data.d_int32); + (*params)[i].data.d_int16array = g_new (gint16, + (*params)[i-1].data.d_int32); + if (! _gimp_wire_read_int16 (channel, + (guint16 *) (*params)[i].data.d_int16array, + (*params)[i-1].data.d_int32, + user_data)) + { + g_free ((*params)[i].data.d_int16array); + goto cleanup; + } + break; + + case GIMP_PDB_INT8ARRAY: + (*params)[i-1].data.d_int32 = MAX (0, (*params)[i-1].data.d_int32); + (*params)[i].data.d_int8array = g_new (guint8, + (*params)[i-1].data.d_int32); + if (! _gimp_wire_read_int8 (channel, + (*params)[i].data.d_int8array, + (*params)[i-1].data.d_int32, + user_data)) + { + g_free ((*params)[i].data.d_int8array); + goto cleanup; + } + break; + + case GIMP_PDB_FLOATARRAY: + (*params)[i-1].data.d_int32 = MAX (0, (*params)[i-1].data.d_int32); + (*params)[i].data.d_floatarray = g_new (gdouble, + (*params)[i-1].data.d_int32); + if (! _gimp_wire_read_double (channel, + (*params)[i].data.d_floatarray, + (*params)[i-1].data.d_int32, + user_data)) + { + g_free ((*params)[i].data.d_floatarray); + goto cleanup; + } + break; + + case GIMP_PDB_STRINGARRAY: + (*params)[i-1].data.d_int32 = MAX (0, (*params)[i-1].data.d_int32); + (*params)[i].data.d_stringarray = g_new0 (gchar *, + (*params)[i-1].data.d_int32); + if (! _gimp_wire_read_string (channel, + (*params)[i].data.d_stringarray, + (*params)[i-1].data.d_int32, + user_data)) + { + for (j = 0; j < (*params)[i-1].data.d_int32; j++) + g_free (((*params)[i].data.d_stringarray)[j]); + g_free ((*params)[i].data.d_stringarray); + goto cleanup; + } + break; + + case GIMP_PDB_COLOR: + if (! _gimp_wire_read_color (channel, + &(*params)[i].data.d_color, 1, + user_data)) + goto cleanup; + break; + + case GIMP_PDB_ITEM: + if (! _gimp_wire_read_int32 (channel, + (guint32 *) &(*params)[i].data.d_item, 1, + user_data)) + goto cleanup; + break; + + case GIMP_PDB_DISPLAY: + if (! _gimp_wire_read_int32 (channel, + (guint32 *) &(*params)[i].data.d_display, 1, + user_data)) + goto cleanup; + break; + + case GIMP_PDB_IMAGE: + if (! _gimp_wire_read_int32 (channel, + (guint32 *) &(*params)[i].data.d_image, 1, + user_data)) + goto cleanup; + break; + + case GIMP_PDB_LAYER: + if (! _gimp_wire_read_int32 (channel, + (guint32 *) &(*params)[i].data.d_layer, 1, + user_data)) + goto cleanup; + break; + + case GIMP_PDB_CHANNEL: + if (! _gimp_wire_read_int32 (channel, + (guint32 *) &(*params)[i].data.d_channel, 1, + user_data)) + goto cleanup; + break; + + case GIMP_PDB_DRAWABLE: + if (! _gimp_wire_read_int32 (channel, + (guint32 *) &(*params)[i].data.d_drawable, 1, + user_data)) + goto cleanup; + break; + + case GIMP_PDB_SELECTION: + if (! _gimp_wire_read_int32 (channel, + (guint32 *) &(*params)[i].data.d_selection, 1, + user_data)) + goto cleanup; + break; + + case GIMP_PDB_COLORARRAY: + (*params)[i].data.d_colorarray = g_new (GimpRGB, + (*params)[i-1].data.d_int32); + if (! _gimp_wire_read_color (channel, + (*params)[i].data.d_colorarray, + (*params)[i-1].data.d_int32, + user_data)) + { + g_free ((*params)[i].data.d_colorarray); + goto cleanup; + } + break; + + case GIMP_PDB_VECTORS: + if (! _gimp_wire_read_int32 (channel, + (guint32 *) &(*params)[i].data.d_vectors, 1, + user_data)) + goto cleanup; + break; + + case GIMP_PDB_PARASITE: + if (! _gimp_wire_read_string (channel, + &(*params)[i].data.d_parasite.name, 1, + user_data)) + goto cleanup; + if ((*params)[i].data.d_parasite.name == NULL) + { + /* we have a null parasite */ + (*params)[i].data.d_parasite.data = NULL; + break; + } + if (! _gimp_wire_read_int32 (channel, + &((*params)[i].data.d_parasite.flags), 1, + user_data)) + goto cleanup; + if (! _gimp_wire_read_int32 (channel, + &((*params)[i].data.d_parasite.size), 1, + user_data)) + goto cleanup; + if ((*params)[i].data.d_parasite.size > 0) + { + (*params)[i].data.d_parasite.data = + g_malloc ((*params)[i].data.d_parasite.size); + if (! _gimp_wire_read_int8 (channel, + (*params)[i].data.d_parasite.data, + (*params)[i].data.d_parasite.size, + user_data)) + { + g_free ((*params)[i].data.d_parasite.data); + goto cleanup; + } + } + else + (*params)[i].data.d_parasite.data = NULL; + break; + + case GIMP_PDB_STATUS: + if (! _gimp_wire_read_int32 (channel, + (guint32 *) &(*params)[i].data.d_status, 1, + user_data)) + goto cleanup; + break; + + case GIMP_PDB_END: + break; + } + } + + return; + + cleanup: + *nparams = 0; + g_free (*params); + *params = NULL; +} + +static void +_gp_params_write (GIOChannel *channel, + GPParam *params, + gint nparams, + gpointer user_data) +{ + gint i; + + if (! _gimp_wire_write_int32 (channel, + (const guint32 *) &nparams, 1, user_data)) + return; + + for (i = 0; i < nparams; i++) + { + if (! _gimp_wire_write_int32 (channel, + (const guint32 *) ¶ms[i].type, 1, + user_data)) + return; + + switch (params[i].type) + { + case GIMP_PDB_INT32: + if (! _gimp_wire_write_int32 (channel, + (const guint32 *) ¶ms[i].data.d_int32, 1, + user_data)) + return; + break; + + case GIMP_PDB_INT16: + if (! _gimp_wire_write_int16 (channel, + (const guint16 *) ¶ms[i].data.d_int16, 1, + user_data)) + return; + break; + + case GIMP_PDB_INT8: + if (! _gimp_wire_write_int8 (channel, + (const guint8 *) ¶ms[i].data.d_int8, 1, + user_data)) + return; + break; + + case GIMP_PDB_FLOAT: + if (! _gimp_wire_write_double (channel, + ¶ms[i].data.d_float, 1, + user_data)) + return; + break; + + case GIMP_PDB_STRING: + if (! _gimp_wire_write_string (channel, + ¶ms[i].data.d_string, 1, + user_data)) + return; + break; + + case GIMP_PDB_INT32ARRAY: + if (! _gimp_wire_write_int32 (channel, + (const guint32 *) params[i].data.d_int32array, + params[i-1].data.d_int32, + user_data)) + return; + break; + + case GIMP_PDB_INT16ARRAY: + if (! _gimp_wire_write_int16 (channel, + (const guint16 *) params[i].data.d_int16array, + params[i-1].data.d_int32, + user_data)) + return; + break; + + case GIMP_PDB_INT8ARRAY: + if (! _gimp_wire_write_int8 (channel, + (const guint8 *) params[i].data.d_int8array, + params[i-1].data.d_int32, + user_data)) + return; + break; + + case GIMP_PDB_FLOATARRAY: + if (! _gimp_wire_write_double (channel, + params[i].data.d_floatarray, + params[i-1].data.d_int32, + user_data)) + return; + break; + + case GIMP_PDB_STRINGARRAY: + if (! _gimp_wire_write_string (channel, + params[i].data.d_stringarray, + params[i-1].data.d_int32, + user_data)) + return; + break; + + case GIMP_PDB_COLOR: + if (! _gimp_wire_write_color (channel, + ¶ms[i].data.d_color, 1, user_data)) + return; + break; + + case GIMP_PDB_ITEM: + if (! _gimp_wire_write_int32 (channel, + (const guint32 *) ¶ms[i].data.d_item, 1, + user_data)) + return; + break; + + case GIMP_PDB_DISPLAY: + if (! _gimp_wire_write_int32 (channel, + (const guint32 *) ¶ms[i].data.d_display, 1, + user_data)) + return; + break; + + case GIMP_PDB_IMAGE: + if (! _gimp_wire_write_int32 (channel, + (const guint32 *) ¶ms[i].data.d_image, 1, + user_data)) + return; + break; + + case GIMP_PDB_LAYER: + if (! _gimp_wire_write_int32 (channel, + (const guint32 *) ¶ms[i].data.d_layer, 1, + user_data)) + return; + break; + + case GIMP_PDB_CHANNEL: + if (! _gimp_wire_write_int32 (channel, + (const guint32 *) ¶ms[i].data.d_channel, 1, + user_data)) + return; + break; + + case GIMP_PDB_DRAWABLE: + if (! _gimp_wire_write_int32 (channel, + (const guint32 *) ¶ms[i].data.d_drawable, 1, + user_data)) + return; + break; + + case GIMP_PDB_SELECTION: + if (! _gimp_wire_write_int32 (channel, + (const guint32 *) ¶ms[i].data.d_selection, 1, + user_data)) + return; + break; + + case GIMP_PDB_COLORARRAY: + if (! _gimp_wire_write_color (channel, + params[i].data.d_colorarray, + params[i-1].data.d_int32, + user_data)) + return; + break; + + case GIMP_PDB_VECTORS: + if (! _gimp_wire_write_int32 (channel, + (const guint32 *) ¶ms[i].data.d_vectors, 1, + user_data)) + return; + break; + + case GIMP_PDB_PARASITE: + { + GimpParasite *p = ¶ms[i].data.d_parasite; + + if (p->name == NULL) + { + /* write a null string to signal a null parasite */ + _gimp_wire_write_string (channel, &p->name, 1, user_data); + break; + } + + if (! _gimp_wire_write_string (channel, &p->name, 1, user_data)) + return; + if (! _gimp_wire_write_int32 (channel, &p->flags, 1, user_data)) + return; + if (! _gimp_wire_write_int32 (channel, &p->size, 1, user_data)) + return; + if (p->size > 0) + { + if (! _gimp_wire_write_int8 (channel, + p->data, p->size, user_data)) + return; + } + } + break; + + case GIMP_PDB_STATUS: + if (! _gimp_wire_write_int32 (channel, + (const guint32 *) ¶ms[i].data.d_status, 1, + user_data)) + return; + break; + + case GIMP_PDB_END: + break; + } + } +} + +void +gp_params_destroy (GPParam *params, + gint nparams) +{ + gint i; + + for (i = 0; i < nparams; i++) + { + switch (params[i].type) + { + case GIMP_PDB_INT32: + case GIMP_PDB_INT16: + case GIMP_PDB_INT8: + case GIMP_PDB_FLOAT: + case GIMP_PDB_COLOR: + case GIMP_PDB_ITEM: + case GIMP_PDB_DISPLAY: + case GIMP_PDB_IMAGE: + case GIMP_PDB_LAYER: + case GIMP_PDB_CHANNEL: + case GIMP_PDB_DRAWABLE: + case GIMP_PDB_SELECTION: + case GIMP_PDB_VECTORS: + case GIMP_PDB_STATUS: + break; + + case GIMP_PDB_STRING: + g_free (params[i].data.d_string); + break; + + case GIMP_PDB_INT32ARRAY: + g_free (params[i].data.d_int32array); + break; + + case GIMP_PDB_INT16ARRAY: + g_free (params[i].data.d_int16array); + break; + + case GIMP_PDB_INT8ARRAY: + g_free (params[i].data.d_int8array); + break; + + case GIMP_PDB_FLOATARRAY: + g_free (params[i].data.d_floatarray); + break; + + case GIMP_PDB_STRINGARRAY: + if ((i > 0) && (params[i-1].type == GIMP_PDB_INT32)) + { + gint count = params[i-1].data.d_int32; + gint j; + + for (j = 0; j < count; j++) + g_free (params[i].data.d_stringarray[j]); + + g_free (params[i].data.d_stringarray); + } + break; + + case GIMP_PDB_COLORARRAY: + g_free (params[i].data.d_colorarray); + break; + + case GIMP_PDB_PARASITE: + if (params[i].data.d_parasite.name) + g_free (params[i].data.d_parasite.name); + if (params[i].data.d_parasite.data) + g_free (params[i].data.d_parasite.data); + break; + + case GIMP_PDB_END: + break; + } + } + + g_free (params); +} + +/* has_init */ + +static void +_gp_has_init_read (GIOChannel *channel, + GimpWireMessage *msg, + gpointer user_data) +{ +} + +static void +_gp_has_init_write (GIOChannel *channel, + GimpWireMessage *msg, + gpointer user_data) +{ +} + +static void +_gp_has_init_destroy (GimpWireMessage *msg) +{ +} diff --git a/libgimpbase/gimpprotocol.h b/libgimpbase/gimpprotocol.h new file mode 100644 index 0000000..991abed --- /dev/null +++ b/libgimpbase/gimpprotocol.h @@ -0,0 +1,245 @@ +/* LIBGIMP - The GIMP Library + * Copyright (C) 1995-1997 Peter Mattis and Spencer Kimball + * + * This library is free software: you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see + * <https://www.gnu.org/licenses/>. + */ + +#ifndef __GIMP_PROTOCOL_H__ +#define __GIMP_PROTOCOL_H__ + +G_BEGIN_DECLS + +/* For information look into the C source or the html documentation */ + + +/* Increment every time the protocol changes + */ +#define GIMP_PROTOCOL_VERSION 0x001A + + +enum +{ + GP_QUIT, + GP_CONFIG, + GP_TILE_REQ, + GP_TILE_ACK, + GP_TILE_DATA, + GP_PROC_RUN, + GP_PROC_RETURN, + GP_TEMP_PROC_RUN, + GP_TEMP_PROC_RETURN, + GP_PROC_INSTALL, + GP_PROC_UNINSTALL, + GP_EXTENSION_ACK, + GP_HAS_INIT +}; + + +typedef struct _GPConfig GPConfig; +typedef struct _GPTileReq GPTileReq; +typedef struct _GPTileAck GPTileAck; +typedef struct _GPTileData GPTileData; +typedef struct _GPParam GPParam; +typedef struct _GPParamDef GPParamDef; +typedef struct _GPProcRun GPProcRun; +typedef struct _GPProcReturn GPProcReturn; +typedef struct _GPProcInstall GPProcInstall; +typedef struct _GPProcUninstall GPProcUninstall; + + +struct _GPConfig +{ + guint32 version; + guint32 tile_width; + guint32 tile_height; + gint32 shm_ID; + gint8 check_size; + gint8 check_type; + gint8 show_help_button; + gint8 use_cpu_accel; + gint8 use_opencl; + gint8 export_exif; + gint8 export_xmp; + gint8 export_iptc; + gint8 export_profile; + gint8 show_tooltips; + gint32 min_colors; + gint32 gdisp_ID; + gchar *app_name; + gchar *wm_class; + gchar *display_name; + gint32 monitor_number; + guint32 timestamp; + + /* since protocol version 0x0017: */ + gchar *icon_theme_dir; + + /* since protocol version 0x0019: */ + guint64 tile_cache_size; + gchar *swap_path; + gint32 num_processors; + + /* since protocol version 0x001a: */ + gchar *swap_compression; +}; + +struct _GPTileReq +{ + gint32 drawable_ID; + guint32 tile_num; + guint32 shadow; +}; + +struct _GPTileData +{ + gint32 drawable_ID; + guint32 tile_num; + guint32 shadow; + guint32 bpp; + guint32 width; + guint32 height; + guint32 use_shm; + guchar *data; +}; + +struct _GPParam +{ + guint32 type; + + union + { + gint32 d_int32; + gint16 d_int16; + guint8 d_int8; + gdouble d_float; + gchar *d_string; + gint32 *d_int32array; + gint16 *d_int16array; + guint8 *d_int8array; + gdouble *d_floatarray; + gchar **d_stringarray; + GimpRGB *d_colorarray; + GimpRGB d_color; + struct + { + gint32 x; + gint32 y; + gint32 width; + gint32 height; + } d_region; /* deprecated */ + gint32 d_display; + gint32 d_image; + gint32 d_item; + gint32 d_layer; + gint32 d_channel; + gint32 d_drawable; + gint32 d_selection; + gint32 d_boundary; + gint32 d_path; /* deprecated */ + gint32 d_vectors; + gint32 d_status; + GimpParasite d_parasite; + } data; +}; + +struct _GPParamDef +{ + guint32 type; + gchar *name; + gchar *description; +}; + +struct _GPProcRun +{ + gchar *name; + guint32 nparams; + GPParam *params; +}; + +struct _GPProcReturn +{ + gchar *name; + guint32 nparams; + GPParam *params; +}; + +struct _GPProcInstall +{ + gchar *name; + gchar *blurb; + gchar *help; + gchar *author; + gchar *copyright; + gchar *date; + gchar *menu_path; + gchar *image_types; + guint32 type; + guint32 nparams; + guint32 nreturn_vals; + GPParamDef *params; + GPParamDef *return_vals; +}; + +struct _GPProcUninstall +{ + gchar *name; +}; + + +void gp_init (void); + +gboolean gp_quit_write (GIOChannel *channel, + gpointer user_data); +gboolean gp_config_write (GIOChannel *channel, + GPConfig *config, + gpointer user_data); +gboolean gp_tile_req_write (GIOChannel *channel, + GPTileReq *tile_req, + gpointer user_data); +gboolean gp_tile_ack_write (GIOChannel *channel, + gpointer user_data); +gboolean gp_tile_data_write (GIOChannel *channel, + GPTileData *tile_data, + gpointer user_data); +gboolean gp_proc_run_write (GIOChannel *channel, + GPProcRun *proc_run, + gpointer user_data); +gboolean gp_proc_return_write (GIOChannel *channel, + GPProcReturn *proc_return, + gpointer user_data); +gboolean gp_temp_proc_run_write (GIOChannel *channel, + GPProcRun *proc_run, + gpointer user_data); +gboolean gp_temp_proc_return_write (GIOChannel *channel, + GPProcReturn *proc_return, + gpointer user_data); +gboolean gp_proc_install_write (GIOChannel *channel, + GPProcInstall *proc_install, + gpointer user_data); +gboolean gp_proc_uninstall_write (GIOChannel *channel, + GPProcUninstall *proc_uninstall, + gpointer user_data); +gboolean gp_extension_ack_write (GIOChannel *channel, + gpointer user_data); +gboolean gp_has_init_write (GIOChannel *channel, + gpointer user_data); + +void gp_params_destroy (GPParam *params, + gint nparams); + + +G_END_DECLS + +#endif /* __GIMP_PROTOCOL_H__ */ diff --git a/libgimpbase/gimprectangle.c b/libgimpbase/gimprectangle.c new file mode 100644 index 0000000..678ff82 --- /dev/null +++ b/libgimpbase/gimprectangle.c @@ -0,0 +1,133 @@ +/* LIBGIMP - The GIMP Library + * Copyright (C) 1995-1997 Spencer Kimball and Peter Mattis + * + * gimprectangle.c + * + * This library is free software: you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see + * <https://www.gnu.org/licenses/>. + */ + +#include "config.h" + +#include <glib.h> + +#include "gimprectangle.h" + + +/** + * SECTION: gimprectangle + * @title: gimprectangle + * @short_description: Utility functions dealing with rectangle extents. + * + * Utility functions dealing with rectangle extents. + **/ + + +/** + * gimp_rectangle_intersect: + * @x1: origin of first rectangle + * @y1: origin of first rectangle + * @width1: width of first rectangle + * @height1: height of first rectangle + * @x2: origin of second rectangle + * @y2: origin of second rectangle + * @width2: width of second rectangle + * @height2: height of second rectangle + * @dest_x: return location for origin of intersection (may be %NULL) + * @dest_y: return location for origin of intersection (may be %NULL) + * @dest_width: return location for width of intersection (may be %NULL) + * @dest_height: return location for height of intersection (may be %NULL) + * + * Calculates the intersection of two rectangles. + * + * Return value: %TRUE if the intersection is non-empty, %FALSE otherwise + * + * Since: 2.4 + **/ +gboolean +gimp_rectangle_intersect (gint x1, + gint y1, + gint width1, + gint height1, + gint x2, + gint y2, + gint width2, + gint height2, + gint *dest_x, + gint *dest_y, + gint *dest_width, + gint *dest_height) +{ + gint d_x, d_y; + gint d_w, d_h; + + d_x = MAX (x1, x2); + d_y = MAX (y1, y2); + d_w = MIN (x1 + width1, x2 + width2) - d_x; + d_h = MIN (y1 + height1, y2 + height2) - d_y; + + if (dest_x) *dest_x = d_x; + if (dest_y) *dest_y = d_y; + if (dest_width) *dest_width = d_w; + if (dest_height) *dest_height = d_h; + + return (d_w > 0 && d_h > 0); +} + +/** + * gimp_rectangle_union: + * @x1: origin of first rectangle + * @y1: origin of first rectangle + * @width1: width of first rectangle + * @height1: height of first rectangle + * @x2: origin of second rectangle + * @y2: origin of second rectangle + * @width2: width of second rectangle + * @height2: height of second rectangle + * @dest_x: return location for origin of union (may be %NULL) + * @dest_y: return location for origin of union (may be %NULL) + * @dest_width: return location for width of union (may be %NULL) + * @dest_height: return location for height of union (may be %NULL) + * + * Calculates the union of two rectangles. + * + * Since: 2.8 + **/ +void +gimp_rectangle_union (gint x1, + gint y1, + gint width1, + gint height1, + gint x2, + gint y2, + gint width2, + gint height2, + gint *dest_x, + gint *dest_y, + gint *dest_width, + gint *dest_height) +{ + gint d_x, d_y; + gint d_w, d_h; + + d_x = MIN (x1, x2); + d_y = MIN (y1, y2); + d_w = MAX (x1 + width1, x2 + width2) - d_x; + d_h = MAX (y1 + height1, y2 + height2) - d_y; + + if (dest_x) *dest_x = d_x; + if (dest_y) *dest_y = d_y; + if (dest_width) *dest_width = d_w; + if (dest_height) *dest_height = d_h; +} diff --git a/libgimpbase/gimprectangle.h b/libgimpbase/gimprectangle.h new file mode 100644 index 0000000..8ace674 --- /dev/null +++ b/libgimpbase/gimprectangle.h @@ -0,0 +1,60 @@ +/* LIBGIMP - The GIMP Library + * Copyright (C) 1995-1997 Peter Mattis and Spencer Kimball + * + * This library is free software: you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This library 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see + * <https://www.gnu.org/licenses/>. + */ + +#if !defined (__GIMP_BASE_H_INSIDE__) && !defined (GIMP_BASE_COMPILATION) +#error "Only <libgimpbase/gimpbase.h> can be included directly." +#endif + +#ifndef __GIMP_RECTANGLE_H__ +#define __GIMP_RECTANGLE_H__ + +G_BEGIN_DECLS + +/* For information look into the C source or the html documentation */ + + +gboolean gimp_rectangle_intersect (gint x1, + gint y1, + gint width1, + gint height1, + gint x2, + gint y2, + gint width2, + gint height2, + gint *dest_x, + gint *dest_y, + gint *dest_width, + gint *dest_height); + +void gimp_rectangle_union (gint x1, + gint y1, + gint width1, + gint height1, + gint x2, + gint y2, + gint width2, + gint height2, + gint *dest_x, + gint *dest_y, + gint *dest_width, + gint *dest_height); + + +G_END_DECLS + +#endif /* __GIMP_RECTANGLE_H__ */ diff --git a/libgimpbase/gimpreloc.c b/libgimpbase/gimpreloc.c new file mode 100644 index 0000000..b9fa4df --- /dev/null +++ b/libgimpbase/gimpreloc.c @@ -0,0 +1,435 @@ +/* + * BinReloc - a library for creating relocatable executables + * Written by: Hongli Lai <h.lai@chello.nl> + * http://autopackage.org/ + * + * This source code is public domain. You can relicense this code + * under whatever license you want. + * + * See http://autopackage.org/docs/binreloc/ for + * more information and how to use this. + */ + +#include "config.h" + +#include <stdlib.h> +#include <limits.h> +#include <string.h> + +#if defined(ENABLE_RELOCATABLE_RESOURCES) && ! defined(G_OS_WIN32) +#include <sys/types.h> +#include <sys/stat.h> +#include <unistd.h> +#endif /* ENABLE_RELOCATABLE_RESOURCES && ! G_OS_WIN32 */ + +#include <glib.h> +#include <glib/gstdio.h> + +#include "gimpreloc.h" + + +/* + * Find the canonical filename of the executable. Returns the filename + * (which must be freed) or NULL on error. If the parameter 'error' is + * not NULL, the error code will be stored there, if an error occurred. + */ +static char * +_br_find_exe (GimpBinrelocInitError *error) +{ +#if ! defined(ENABLE_RELOCATABLE_RESOURCES) || defined(G_OS_WIN32) + if (error) + *error = GIMP_RELOC_INIT_ERROR_DISABLED; + return NULL; +#else + char *path, *path2, *line, *result; + size_t buf_size; + ssize_t size; + struct stat stat_buf; + FILE *f; + + /* Read from /proc/self/exe (symlink) */ + if (sizeof (path) > SSIZE_MAX) + buf_size = SSIZE_MAX - 1; + else + buf_size = PATH_MAX - 1; + path = g_try_new (char, buf_size); + if (path == NULL) + { + /* Cannot allocate memory. */ + if (error) + *error = GIMP_RELOC_INIT_ERROR_NOMEM; + return NULL; + } + path2 = g_try_new (char, buf_size); + if (path2 == NULL) + { + /* Cannot allocate memory. */ + if (error) + *error = GIMP_RELOC_INIT_ERROR_NOMEM; + g_free (path); + return NULL; + } + + strncpy (path2, "/proc/self/exe", buf_size - 1); + + while (1) + { + int i; + + size = readlink (path2, path, buf_size - 1); + if (size == -1) + { + /* Error. */ + g_free (path2); + break; + } + + /* readlink() success. */ + path[size] = '\0'; + + /* Check whether the symlink's target is also a symlink. + * We want to get the final target. */ + i = stat (path, &stat_buf); + if (i == -1) + { + /* Error. */ + g_free (path2); + break; + } + + /* stat() success. */ + if (!S_ISLNK (stat_buf.st_mode)) + { + /* path is not a symlink. Done. */ + g_free (path2); + return path; + } + + /* path is a symlink. Continue loop and resolve this. */ + strncpy (path, path2, buf_size - 1); + } + + + /* readlink() or stat() failed; this can happen when the program is + * running in Valgrind 2.2. Read from /proc/self/maps as fallback. */ + + buf_size = PATH_MAX + 128; + line = (char *) g_try_realloc (path, buf_size); + if (line == NULL) + { + /* Cannot allocate memory. */ + g_free (path); + if (error) + *error = GIMP_RELOC_INIT_ERROR_NOMEM; + return NULL; + } + + f = g_fopen ("/proc/self/maps", "r"); + if (f == NULL) + { + g_free (line); + if (error) + *error = GIMP_RELOC_INIT_ERROR_OPEN_MAPS; + return NULL; + } + + /* The first entry should be the executable name. */ + result = fgets (line, (int) buf_size, f); + if (result == NULL) + { + fclose (f); + g_free (line); + if (error) + *error = GIMP_RELOC_INIT_ERROR_READ_MAPS; + return NULL; + } + + /* Get rid of newline character. */ + buf_size = strlen (line); + if (buf_size == 0) + { + /* Huh? An empty string? */ + fclose (f); + g_free (line); + if (error) + *error = GIMP_RELOC_INIT_ERROR_INVALID_MAPS; + return NULL; + } + if (line[buf_size - 1] == 10) + line[buf_size - 1] = 0; + + /* Extract the filename; it is always an absolute path. */ + path = strchr (line, '/'); + + /* Sanity check. */ + if (strstr (line, " r-xp ") == NULL || path == NULL) + { + fclose (f); + g_free (line); + if (error) + *error = GIMP_RELOC_INIT_ERROR_INVALID_MAPS; + return NULL; + } + + path = g_strdup (path); + g_free (line); + fclose (f); + return path; +#endif /* ! ENABLE_RELOCATABLE_RESOURCES || G_OS_WIN32 */ +} + + +/* + * Find the canonical filename of the executable which owns symbol. + * Returns a filename which must be freed, or NULL on error. + */ +static char * +_br_find_exe_for_symbol (const void *symbol, GimpBinrelocInitError *error) +{ +#if ! defined(ENABLE_RELOCATABLE_RESOURCES) || defined(G_OS_WIN32) + if (error) + *error = GIMP_RELOC_INIT_ERROR_DISABLED; + return (char *) NULL; +#else +#define SIZE PATH_MAX + 100 + FILE *f; + size_t address_string_len; + char *address_string, line[SIZE], *found; + + if (symbol == NULL) + return (char *) NULL; + + f = g_fopen ("/proc/self/maps", "r"); + if (f == NULL) + return (char *) NULL; + + address_string_len = 4; + address_string = g_try_new (char, address_string_len); + found = (char *) NULL; + + while (!feof (f)) + { + char *start_addr, *end_addr, *end_addr_end, *file; + void *start_addr_p, *end_addr_p; + size_t len; + + if (fgets (line, SIZE, f) == NULL) + break; + + /* Sanity check. */ + if (strstr (line, " r-xp ") == NULL || strchr (line, '/') == NULL) + continue; + + /* Parse line. */ + start_addr = line; + end_addr = strchr (line, '-'); + file = strchr (line, '/'); + + /* More sanity check. */ + if (!(file > end_addr && end_addr != NULL && end_addr[0] == '-')) + continue; + + end_addr[0] = '\0'; + end_addr++; + end_addr_end = strchr (end_addr, ' '); + if (end_addr_end == NULL) + continue; + + end_addr_end[0] = '\0'; + len = strlen (file); + if (len == 0) + continue; + if (file[len - 1] == '\n') + file[len - 1] = '\0'; + + /* Get rid of "(deleted)" from the filename. */ + len = strlen (file); + if (len > 10 && strcmp (file + len - 10, " (deleted)") == 0) + file[len - 10] = '\0'; + + /* I don't know whether this can happen but better safe than sorry. */ + len = strlen (start_addr); + if (len != strlen (end_addr)) + continue; + + + /* Transform the addresses into a string in the form of 0xdeadbeef, + * then transform that into a pointer. */ + if (address_string_len < len + 3) + { + address_string_len = len + 3; + address_string = (char *) g_try_realloc (address_string, address_string_len); + } + + memcpy (address_string, "0x", 2); + memcpy (address_string + 2, start_addr, len); + address_string[2 + len] = '\0'; + sscanf (address_string, "%p", &start_addr_p); + + memcpy (address_string, "0x", 2); + memcpy (address_string + 2, end_addr, len); + address_string[2 + len] = '\0'; + sscanf (address_string, "%p", &end_addr_p); + + + if (symbol >= start_addr_p && symbol < end_addr_p) + { + found = file; + break; + } + } + + g_free (address_string); + fclose (f); + + if (found == NULL) + return (char *) NULL; + else + return g_strdup (found); +#endif /* ! ENABLE_RELOCATABLE_RESOURCES || G_OS_WIN32 */ +} + + +static gchar *exe = NULL; + +static void set_gerror (GError **error, GimpBinrelocInitError errcode); + + +/* Initialize the BinReloc library (for applications). + * + * This function must be called before using any other BinReloc functions. + * It attempts to locate the application's canonical filename. + * + * @note If you want to use BinReloc for a library, then you should call + * _gimp_reloc_init_lib() instead. + * @note Initialization failure is not fatal. BinReloc functions will just + * fallback to the supplied default path. + * + * @param error If BinReloc failed to initialize, then the error report will + * be stored in this variable. Set to NULL if you don't want an + * error report. See the #GimpBinrelocInitError for a list of error + * codes. + * + * @returns TRUE on success, FALSE if BinReloc failed to initialize. + */ +gboolean +_gimp_reloc_init (GError **error) +{ + GimpBinrelocInitError errcode; + + /* Shut up compiler warning about uninitialized variable. */ + errcode = GIMP_RELOC_INIT_ERROR_NOMEM; + + /* Locate the application's filename. */ + exe = _br_find_exe (&errcode); + if (exe != NULL) + /* Success! */ + return TRUE; + else + { + /* Failed :-( */ + set_gerror (error, errcode); + return FALSE; + } +} + + +/* Initialize the BinReloc library (for libraries). + * + * This function must be called before using any other BinReloc functions. + * It attempts to locate the calling library's canonical filename. + * + * @note The BinReloc source code MUST be included in your library, or this + * function won't work correctly. + * @note Initialization failure is not fatal. BinReloc functions will just + * fallback to the supplied default path. + * + * @returns TRUE on success, FALSE if a filename cannot be found. + */ +gboolean +_gimp_reloc_init_lib (GError **error) +{ + GimpBinrelocInitError errcode; + + /* Shut up compiler warning about uninitialized variable. */ + errcode = GIMP_RELOC_INIT_ERROR_NOMEM; + + exe = _br_find_exe_for_symbol ((const void *) "", &errcode); + if (exe != NULL) + /* Success! */ + return TRUE; + else + { + /* Failed :-( */ + set_gerror (error, errcode); + return exe != NULL; + } +} + +static void +set_gerror (GError **error, GimpBinrelocInitError errcode) +{ + const gchar *error_message; + + if (error == NULL) + return; + + switch (errcode) + { + case GIMP_RELOC_INIT_ERROR_NOMEM: + error_message = "Cannot allocate memory."; + break; + case GIMP_RELOC_INIT_ERROR_OPEN_MAPS: + error_message = "Unable to open /proc/self/maps for reading."; + break; + case GIMP_RELOC_INIT_ERROR_READ_MAPS: + error_message = "Unable to read from /proc/self/maps."; + break; + case GIMP_RELOC_INIT_ERROR_INVALID_MAPS: + error_message = "The file format of /proc/self/maps is invalid."; + break; + case GIMP_RELOC_INIT_ERROR_DISABLED: + error_message = "Binary relocation support is disabled."; + break; + default: + error_message = "Unknown error."; + break; + }; + g_set_error (error, g_quark_from_static_string ("GBinReloc"), + errcode, "%s", error_message); +} + + +/* Locate the prefix in which the current application is installed. + * + * The prefix is generated by the following pseudo-code evaluation: + * \code + * dirname(dirname(exename)) + * \endcode + * + * @param default_prefix A default prefix which will used as fallback. + * @return A string containing the prefix, which must be freed when no + * longer necessary. If BinReloc is not initialized, or if the + * initialization function failed, then a copy of default_prefix + * will be returned. If default_prefix is NULL, then NULL will be + * returned. + */ +gchar * +_gimp_reloc_find_prefix (const gchar *default_prefix) +{ + gchar *dir1, *dir2; + + if (exe == NULL) + { + /* BinReloc not initialized. */ + if (default_prefix != NULL) + return g_strdup (default_prefix); + else + return NULL; + } + + dir1 = g_path_get_dirname (exe); + dir2 = g_path_get_dirname (dir1); + g_free (dir1); + return dir2; +} diff --git a/libgimpbase/gimpreloc.h b/libgimpbase/gimpreloc.h new file mode 100644 index 0000000..a7af912 --- /dev/null +++ b/libgimpbase/gimpreloc.h @@ -0,0 +1,46 @@ +/* + * BinReloc - a library for creating relocatable executables + * Written by: Hongli Lai <h.lai@chello.nl> + * http://autopackage.org/ + * + * This source code is public domain. You can relicense this code + * under whatever license you want. + * + * See http://autopackage.org/docs/binreloc/ for + * more information and how to use this. + */ + +#ifndef __GIMP_RELOC_H__ +#define __GIMP_RELOC_H__ + +G_BEGIN_DECLS + + +/* These error codes can be returned from _gimp_reloc_init() or + * _gimp_reloc_init_lib(). + */ + +typedef enum +{ + /** Cannot allocate memory. */ + GIMP_RELOC_INIT_ERROR_NOMEM, + /** Unable to open /proc/self/maps; see errno for details. */ + GIMP_RELOC_INIT_ERROR_OPEN_MAPS, + /** Unable to read from /proc/self/maps; see errno for details. */ + GIMP_RELOC_INIT_ERROR_READ_MAPS, + /** The file format of /proc/self/maps is invalid; kernel bug? */ + GIMP_RELOC_INIT_ERROR_INVALID_MAPS, + /** BinReloc is disabled (the ENABLE_BINRELOC macro is not defined). */ + GIMP_RELOC_INIT_ERROR_DISABLED +} GimpBinrelocInitError; + + +G_GNUC_INTERNAL gboolean _gimp_reloc_init (GError **error); +G_GNUC_INTERNAL gboolean _gimp_reloc_init_lib (GError **error); + +G_GNUC_INTERNAL gchar * _gimp_reloc_find_prefix (const gchar *default_prefix); + + +G_END_DECLS + +#endif /* _GIMPRELOC_H_ */ diff --git a/libgimpbase/gimpsignal.c b/libgimpbase/gimpsignal.c new file mode 100644 index 0000000..a0221f3 --- /dev/null +++ b/libgimpbase/gimpsignal.c @@ -0,0 +1,110 @@ +/* LIBGIMP - The GIMP Library + * Copyright (C) 1995-1997 Peter Mattis and Spencer Kimball + * + * This library is free software: you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This library 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see + * <https://www.gnu.org/licenses/>. + * + * $Revision$ + */ + +#include "config.h" + +#define _GNU_SOURCE /* for the sigaction stuff */ + +#include <glib.h> + +#include "gimpsignal.h" + + +/** + * SECTION: gimpsignal + * @title: gimpsignal + * @short_description: Portable signal handling. + * @see_also: signal(2), signal(5 or 7), sigaction(2). + * + * Portable signal handling. + **/ + + +/* Courtesy of Austin Donnelly 06-04-2000 to address bug #2742 */ + +/** + * gimp_signal_private: + * @signum: Selects signal to be handled see man 5 signal (or man 7 signal) + * @handler: Handler that maps to signum. Invoked by O/S. + * Handler gets signal that caused invocation. Corresponds + * to the @sa_handler field of the @sigaction struct. + * @flags: Preferences. OR'ed SA_<xxx>. See man sigaction. Corresponds + * to the @sa_flags field of the @sigaction struct. + * + * This function furnishes a workalike for signal(2) but + * which internally invokes sigaction(2) after certain + * sa_flags are set; these primarily to ensure restarting + * of interrupted system calls. See sigaction(2) It is a + * aid to transition and not new development: that effort + * should employ sigaction directly. [gosgood 18.04.2000] + * + * Cause @handler to be run when @signum is delivered. We + * use sigaction(2) rather than signal(2) so that we can control the + * signal handler's environment completely via @flags: some signal(2) + * implementations differ in their semantics, so we need to nail down + * exactly what we want. [austin 06.04.2000] + * + * Returns: A reference to the signal handling function which was + * active before the call to gimp_signal_private(). + */ +GimpSignalHandlerFunc +gimp_signal_private (gint signum, + GimpSignalHandlerFunc handler, + gint flags) +{ +#ifndef G_OS_WIN32 + gint ret; + struct sigaction sa; + struct sigaction osa; + + /* The sa_handler (mandated by POSIX.1) and sa_sigaction (a + * common extension) are often implemented by the OS as members + * of a union. This means you CAN NOT set both, you set one or + * the other. Caveat programmer! + */ + + /* Passing gimp_signal_private a gimp_sighandler of NULL is not + * an error, and generally results in the action for that signal + * being set to SIG_DFL (default behavior). Many OSes define + * SIG_DFL as (void (*)()0, so setting sa_handler to NULL is + * the same thing as passing SIG_DFL to it. + */ + sa.sa_handler = handler; + + /* Mask all signals while handler runs to avoid re-entrancy + * problems. + */ + sigfillset (&sa.sa_mask); + + sa.sa_flags = flags; + + ret = sigaction (signum, &sa, &osa); + + if (ret < 0) + g_error ("unable to set handler for signal %d\n", signum); + + return (GimpSignalHandlerFunc) osa.sa_handler; +#else + return NULL; /* Or g_error()? Should all calls to + * this function really be inside + * #ifdef G_OS_UNIX? + */ +#endif +} diff --git a/libgimpbase/gimpsignal.h b/libgimpbase/gimpsignal.h new file mode 100644 index 0000000..978a394 --- /dev/null +++ b/libgimpbase/gimpsignal.h @@ -0,0 +1,48 @@ +/* LIBGIMP - The GIMP Library + * Copyright (C) 1995-2000 Peter Mattis and Spencer Kimball + * + * This library is free software: you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see + * <https://www.gnu.org/licenses/>. + */ + +#ifndef __GIMP_SIGNAL_H__ +#define __GIMP_SIGNAL_H__ + +#include <signal.h> + +G_BEGIN_DECLS + +/* For information look into the C source or the html documentation */ + + +/** + * GimpSignalHandlerFunc: + * @signum: The number of the signal. Useful if different signals are + * handled by a single handler. + * + * A prototype for a reference to a signal handler functions. Note + * that each function which takes or returns a variable of this type + * also accepts or may return special values defined by your system's + * signal.h header file (like @SIG_DFL or @SIG_IGN). + **/ +typedef void (* GimpSignalHandlerFunc) (gint signum); + +GimpSignalHandlerFunc gimp_signal_private (gint signum, + GimpSignalHandlerFunc handler, + gint flags); + + +G_END_DECLS + +#endif /* __GIMP_SIGNAL_H__ */ diff --git a/libgimpbase/gimpunit.c b/libgimpbase/gimpunit.c new file mode 100644 index 0000000..e0aa626 --- /dev/null +++ b/libgimpbase/gimpunit.c @@ -0,0 +1,755 @@ +/* LIBGIMP - The GIMP Library + * Copyright (C) 1995-1997 Peter Mattis and Spencer Kimball + * + * gimpunit.c + * Copyright (C) 2003 Michael Natterer <mitch@gimp.org> + * + * This library is free software: you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see + * <https://www.gnu.org/licenses/>. + */ + +#include "config.h" + +#include <math.h> +#include <string.h> + +#include <glib-object.h> + +#include "gimpbasetypes.h" + +#include "gimpbase-private.h" +#include "gimpunit.h" + + +/** + * SECTION: gimpunit + * @title: gimpunit + * @short_description: Provides a collection of predefined units and + * functions for creating user-defined units. + * @see_also: #GimpUnitMenu, #GimpSizeEntry. + * + * Provides a collection of predefined units and functions for + * creating user-defined units. + **/ + + +static void unit_to_string (const GValue *src_value, + GValue *dest_value); +static void string_to_unit (const GValue *src_value, + GValue *dest_value); + +GType +gimp_unit_get_type (void) +{ + static GType unit_type = 0; + + if (! unit_type) + { + const GTypeInfo type_info = { 0, }; + + unit_type = g_type_register_static (G_TYPE_INT, "GimpUnit", + &type_info, 0); + + g_value_register_transform_func (unit_type, G_TYPE_STRING, + unit_to_string); + g_value_register_transform_func (G_TYPE_STRING, unit_type, + string_to_unit); + } + + return unit_type; +} + +static void +unit_to_string (const GValue *src_value, + GValue *dest_value) +{ + GimpUnit unit = (GimpUnit) g_value_get_int (src_value); + + g_value_set_string (dest_value, gimp_unit_get_identifier (unit)); +} + +static void +string_to_unit (const GValue *src_value, + GValue *dest_value) +{ + const gchar *str; + gint num_units; + gint i; + + str = g_value_get_string (src_value); + + if (!str || !*str) + goto error; + + num_units = gimp_unit_get_number_of_units (); + + for (i = GIMP_UNIT_PIXEL; i < num_units; i++) + if (strcmp (str, gimp_unit_get_identifier (i)) == 0) + break; + + if (i == num_units) + { + if (strcmp (str, gimp_unit_get_identifier (GIMP_UNIT_PERCENT)) == 0) + i = GIMP_UNIT_PERCENT; + else + goto error; + } + + g_value_set_int (dest_value, i); + return; + + error: + g_warning ("Can't convert string '%s' to GimpUnit.", str); +} + + +/** + * gimp_unit_get_number_of_units: + * + * Returns the number of units which are known to the #GimpUnit system. + * + * Returns: The number of defined units. + **/ +gint +gimp_unit_get_number_of_units (void) +{ + g_return_val_if_fail (_gimp_unit_vtable.unit_get_number_of_units != NULL, + GIMP_UNIT_END); + + return _gimp_unit_vtable.unit_get_number_of_units (); +} + +/** + * gimp_unit_get_number_of_built_in_units: + * + * Returns the number of #GimpUnit's which are hardcoded in the unit system + * (UNIT_INCH, UNIT_MM, UNIT_POINT, UNIT_PICA and the two "pseudo unit" + * UNIT_PIXEL). + * + * Returns: The number of built-in units. + **/ +gint +gimp_unit_get_number_of_built_in_units (void) +{ + g_return_val_if_fail (_gimp_unit_vtable.unit_get_number_of_built_in_units + != NULL, GIMP_UNIT_END); + + return _gimp_unit_vtable.unit_get_number_of_built_in_units (); +} + +/** + * gimp_unit_new: + * @identifier: The unit's identifier string. + * @factor: The unit's factor (how many units are in one inch). + * @digits: The unit's suggested number of digits (see gimp_unit_get_digits()). + * @symbol: The symbol of the unit (e.g. "''" for inch). + * @abbreviation: The abbreviation of the unit. + * @singular: The singular form of the unit. + * @plural: The plural form of the unit. + * + * Returns the integer ID of the new #GimpUnit. + * + * Note that a new unit is always created with its deletion flag + * set to %TRUE. You will have to set it to %FALSE with + * gimp_unit_set_deletion_flag() to make the unit definition persistent. + * + * Returns: The ID of the new unit. + **/ +GimpUnit +gimp_unit_new (gchar *identifier, + gdouble factor, + gint digits, + gchar *symbol, + gchar *abbreviation, + gchar *singular, + gchar *plural) +{ + g_return_val_if_fail (_gimp_unit_vtable.unit_new != NULL, GIMP_UNIT_INCH); + + return _gimp_unit_vtable.unit_new (identifier, factor, digits, + symbol, abbreviation, singular, plural); +} + +/** + * gimp_unit_get_deletion_flag: + * @unit: The unit you want to know the @deletion_flag of. + * + * Returns: The unit's @deletion_flag. + **/ +gboolean +gimp_unit_get_deletion_flag (GimpUnit unit) +{ + g_return_val_if_fail (_gimp_unit_vtable.unit_get_deletion_flag != NULL, FALSE); + + return _gimp_unit_vtable.unit_get_deletion_flag (unit); +} + +/** + * gimp_unit_set_deletion_flag: + * @unit: The unit you want to set the @deletion_flag for. + * @deletion_flag: The new deletion_flag. + * + * Sets a #GimpUnit's @deletion_flag. If the @deletion_flag of a unit is + * %TRUE when GIMP exits, this unit will not be saved in the users's + * "unitrc" file. + * + * Trying to change the @deletion_flag of a built-in unit will be silently + * ignored. + **/ +void +gimp_unit_set_deletion_flag (GimpUnit unit, + gboolean deletion_flag) +{ + g_return_if_fail (_gimp_unit_vtable.unit_set_deletion_flag != NULL); + + _gimp_unit_vtable.unit_set_deletion_flag (unit, deletion_flag); +} + +/** + * gimp_unit_get_factor: + * @unit: The unit you want to know the factor of. + * + * A #GimpUnit's @factor is defined to be: + * + * distance_in_units == (@factor * distance_in_inches) + * + * Returns 0 for @unit == GIMP_UNIT_PIXEL. + * + * Returns: The unit's factor. + **/ +gdouble +gimp_unit_get_factor (GimpUnit unit) +{ + g_return_val_if_fail (_gimp_unit_vtable.unit_get_factor != NULL, 1.0); + + return _gimp_unit_vtable.unit_get_factor (unit); +} + +/** + * gimp_unit_get_digits: + * @unit: The unit you want to know the digits. + * + * Returns the number of digits set for @unit. + * Built-in units' accuracy is approximately the same as an inch with + * two digits. User-defined units can suggest a different accuracy. + * + * Note: the value is as-set by defaults or by the user and does not + * necessary provide enough precision on high-resolution images. + * When the information is needed for a specific image, the use of + * gimp_unit_get_scaled_digits() may be more appropriate. + * + * Returns 0 for @unit == GIMP_UNIT_PIXEL. + * + * Returns: The suggested number of digits. + **/ +gint +gimp_unit_get_digits (GimpUnit unit) +{ + g_return_val_if_fail (_gimp_unit_vtable.unit_get_digits != NULL, 2); + + return _gimp_unit_vtable.unit_get_digits (unit); +} + +/** + * gimp_unit_get_scaled_digits: + * @unit: The unit you want to know the digits. + * @resolution: the resolution in PPI. + * + * Returns the number of digits a @unit field should provide to get + * enough accuracy so that every pixel position shows a different + * value from neighboring pixels. + * + * Note: when needing digit accuracy to display a diagonal distance, + * the @resolution may not correspond to the image's horizontal or + * vertical resolution, but instead to the result of: + * `distance_in_pixel / distance_in_inch`. + * + * Returns: The suggested number of digits. + **/ +gint +gimp_unit_get_scaled_digits (GimpUnit unit, + gdouble resolution) +{ + gint digits; + + g_return_val_if_fail (_gimp_unit_vtable.unit_get_digits != NULL, 2); + + digits = ceil (log10 (1.0 / + gimp_pixels_to_units (1.0, unit, resolution))); + + return MAX (digits, gimp_unit_get_digits (unit)); +} + +/** + * gimp_unit_get_identifier: + * @unit: The unit you want to know the identifier of. + * + * This is an untranslated string and must not be changed or freed. + * + * Returns: The unit's identifier. + **/ +const gchar * +gimp_unit_get_identifier (GimpUnit unit) +{ + g_return_val_if_fail (_gimp_unit_vtable.unit_get_identifier != NULL, NULL); + + return _gimp_unit_vtable.unit_get_identifier (unit); +} + +/** + * gimp_unit_get_symbol: + * @unit: The unit you want to know the symbol of. + * + * This is e.g. "''" for UNIT_INCH. + * + * NOTE: This string must not be changed or freed. + * + * Returns: The unit's symbol. + **/ +const gchar * +gimp_unit_get_symbol (GimpUnit unit) +{ + g_return_val_if_fail (_gimp_unit_vtable.unit_get_symbol != NULL, NULL); + + return _gimp_unit_vtable.unit_get_symbol (unit); +} + +/** + * gimp_unit_get_abbreviation: + * @unit: The unit you want to know the abbreviation of. + * + * For built-in units, this function returns the translated abbreviation + * of the unit. + * + * NOTE: This string must not be changed or freed. + * + * Returns: The unit's abbreviation. + **/ +const gchar * +gimp_unit_get_abbreviation (GimpUnit unit) +{ + g_return_val_if_fail (_gimp_unit_vtable.unit_get_abbreviation != NULL, NULL); + + return _gimp_unit_vtable.unit_get_abbreviation (unit); +} + +/** + * gimp_unit_get_singular: + * @unit: The unit you want to know the singular form of. + * + * For built-in units, this function returns the translated singular form + * of the unit's name. + * + * NOTE: This string must not be changed or freed. + * + * Returns: The unit's singular form. + **/ +const gchar * +gimp_unit_get_singular (GimpUnit unit) +{ + g_return_val_if_fail (_gimp_unit_vtable.unit_get_singular != NULL, NULL); + + return _gimp_unit_vtable.unit_get_singular (unit); +} + +/** + * gimp_unit_get_plural: + * @unit: The unit you want to know the plural form of. + * + * For built-in units, this function returns the translated plural form + * of the unit's name. + * + * NOTE: This string must not be changed or freed. + * + * Returns: The unit's plural form. + **/ +const gchar * +gimp_unit_get_plural (GimpUnit unit) +{ + g_return_val_if_fail (_gimp_unit_vtable.unit_get_plural != NULL, NULL); + + return _gimp_unit_vtable.unit_get_plural (unit); +} + +static gint print (gchar *buf, + gint len, + gint start, + const gchar *fmt, + ...) G_GNUC_PRINTF (4, 5); + +static gint +print (gchar *buf, + gint len, + gint start, + const gchar *fmt, + ...) +{ + va_list args; + gint printed; + + va_start (args, fmt); + + printed = g_vsnprintf (buf + start, len - start, fmt, args); + if (printed < 0) + printed = len - start; + + va_end (args); + + return printed; +} + +/** + * gimp_unit_format_string: + * @format: A printf-like format string which is used to create the unit + * string. + * @unit: A unit. + * + * The @format string supports the following percent expansions: + * + * <informaltable pgwide="1" frame="none" role="enum"> + * <tgroup cols="2"><colspec colwidth="1*"/><colspec colwidth="8*"/> + * <tbody> + * <row> + * <entry>% f</entry> + * <entry>Factor (how many units make up an inch)</entry> + * </row> + * <row> + * <entry>% y</entry> + * <entry>Symbol (e.g. "''" for GIMP_UNIT_INCH)</entry> + * </row> + * <row> + * <entry>% a</entry> + * <entry>Abbreviation</entry> + * </row> + * <row> + * <entry>% s</entry> + * <entry>Singular</entry> + * </row> + * <row> + * <entry>% p</entry> + * <entry>Plural</entry> + * </row> + * <row> + * <entry>%%</entry> + * <entry>Literal percent</entry> + * </row> + * </tbody> + * </tgroup> + * </informaltable> + * + * Returns: A newly allocated string with above percent expressions + * replaced with the resp. strings for @unit. + * + * Since: 2.8 + **/ +gchar * +gimp_unit_format_string (const gchar *format, + GimpUnit unit) +{ + gchar buffer[1024]; + gint i = 0; + + g_return_val_if_fail (format != NULL, NULL); + g_return_val_if_fail (unit == GIMP_UNIT_PERCENT || + (unit >= GIMP_UNIT_PIXEL && + unit < gimp_unit_get_number_of_units ()), NULL); + + while (i < (sizeof (buffer) - 1) && *format) + { + switch (*format) + { + case '%': + format++; + switch (*format) + { + case 0: + g_warning ("%s: unit-menu-format string ended within %%-sequence", + G_STRFUNC); + break; + + case '%': + buffer[i++] = '%'; + break; + + case 'f': /* factor (how many units make up an inch) */ + i += print (buffer, sizeof (buffer), i, "%f", + gimp_unit_get_factor (unit)); + break; + + case 'y': /* symbol ("''" for inch) */ + i += print (buffer, sizeof (buffer), i, "%s", + gimp_unit_get_symbol (unit)); + break; + + case 'a': /* abbreviation */ + i += print (buffer, sizeof (buffer), i, "%s", + gimp_unit_get_abbreviation (unit)); + break; + + case 's': /* singular */ + i += print (buffer, sizeof (buffer), i, "%s", + gimp_unit_get_singular (unit)); + break; + + case 'p': /* plural */ + i += print (buffer, sizeof (buffer), i, "%s", + gimp_unit_get_plural (unit)); + break; + + default: + g_warning ("%s: unit-menu-format contains unknown format " + "sequence '%%%c'", G_STRFUNC, *format); + break; + } + break; + + default: + buffer[i++] = *format; + break; + } + + format++; + } + + buffer[MIN (i, sizeof (buffer) - 1)] = 0; + + return g_strdup (buffer); +} + +/* + * GIMP_TYPE_PARAM_UNIT + */ + +#define GIMP_PARAM_SPEC_UNIT(pspec) (G_TYPE_CHECK_INSTANCE_CAST ((pspec), GIMP_TYPE_PARAM_UNIT, GimpParamSpecUnit)) + +typedef struct _GimpParamSpecUnit GimpParamSpecUnit; + +struct _GimpParamSpecUnit +{ + GParamSpecInt parent_instance; + + gboolean allow_percent; +}; + +static void gimp_param_unit_class_init (GParamSpecClass *class); +static gboolean gimp_param_unit_value_validate (GParamSpec *pspec, + GValue *value); + +/** + * gimp_param_unit_get_type: + * + * Reveals the object type + * + * Returns: the #GType for a unit param object + * + * Since: 2.4 + **/ +GType +gimp_param_unit_get_type (void) +{ + static GType spec_type = 0; + + if (! spec_type) + { + const GTypeInfo type_info = + { + sizeof (GParamSpecClass), + NULL, NULL, + (GClassInitFunc) gimp_param_unit_class_init, + NULL, NULL, + sizeof (GimpParamSpecUnit), + 0, NULL, NULL + }; + + spec_type = g_type_register_static (G_TYPE_PARAM_INT, + "GimpParamUnit", + &type_info, 0); + } + + return spec_type; +} + +static void +gimp_param_unit_class_init (GParamSpecClass *class) +{ + class->value_type = GIMP_TYPE_UNIT; + class->value_validate = gimp_param_unit_value_validate; +} + +static gboolean +gimp_param_unit_value_validate (GParamSpec *pspec, + GValue *value) +{ + GParamSpecInt *ispec = G_PARAM_SPEC_INT (pspec); + GimpParamSpecUnit *uspec = GIMP_PARAM_SPEC_UNIT (pspec); + gint oval = value->data[0].v_int; + + if (!(uspec->allow_percent && value->data[0].v_int == GIMP_UNIT_PERCENT)) + { + value->data[0].v_int = CLAMP (value->data[0].v_int, + ispec->minimum, + gimp_unit_get_number_of_units () - 1); + } + + return value->data[0].v_int != oval; +} + +/** + * gimp_param_spec_unit: + * @name: Canonical name of the param + * @nick: Nickname of the param + * @blurb: Brief description of param. + * @allow_pixels: Whether "pixels" is an allowed unit. + * @allow_percent: Whether "percent" is an allowed unit. + * @default_value: Unit to use if none is assigned. + * @flags: a combination of #GParamFlags + * + * Creates a param spec to hold a units param. + * See g_param_spec_internal() for more information. + * + * Returns: a newly allocated #GParamSpec instance + * + * Since: 2.4 + **/ +GParamSpec * +gimp_param_spec_unit (const gchar *name, + const gchar *nick, + const gchar *blurb, + gboolean allow_pixels, + gboolean allow_percent, + GimpUnit default_value, + GParamFlags flags) +{ + GimpParamSpecUnit *pspec; + GParamSpecInt *ispec; + + pspec = g_param_spec_internal (GIMP_TYPE_PARAM_UNIT, + name, nick, blurb, flags); + + ispec = G_PARAM_SPEC_INT (pspec); + + ispec->default_value = default_value; + ispec->minimum = allow_pixels ? GIMP_UNIT_PIXEL : GIMP_UNIT_INCH; + ispec->maximum = GIMP_UNIT_PERCENT - 1; + + pspec->allow_percent = allow_percent; + + return G_PARAM_SPEC (pspec); +} + +/** + * gimp_pixels_to_units: + * @pixels: value in pixels + * @unit: unit to convert to + * @resolution: resolution in DPI + * + * Converts a @value specified in pixels to @unit. + * + * Returns: @pixels converted to units. + * + * Since: 2.8 + **/ +gdouble +gimp_pixels_to_units (gdouble pixels, + GimpUnit unit, + gdouble resolution) +{ + if (unit == GIMP_UNIT_PIXEL) + return pixels; + + return pixels * gimp_unit_get_factor (unit) / resolution; +} + +/** + * gimp_units_to_pixels: + * @value: value in units + * @unit: unit of @value + * @resolution: resloution in DPI + * + * Converts a @value specified in @unit to pixels. + * + * Returns: @value converted to pixels. + * + * Since: 2.8 + **/ +gdouble +gimp_units_to_pixels (gdouble value, + GimpUnit unit, + gdouble resolution) +{ + if (unit == GIMP_UNIT_PIXEL) + return value; + + return value * resolution / gimp_unit_get_factor (unit); +} + +/** + * gimp_units_to_points: + * @value: value in units + * @unit: unit of @value + * @resolution: resloution in DPI + * + * Converts a @value specified in @unit to points. + * + * Returns: @value converted to points. + * + * Since: 2.8 + **/ +gdouble +gimp_units_to_points (gdouble value, + GimpUnit unit, + gdouble resolution) +{ + if (unit == GIMP_UNIT_POINT) + return value; + + if (unit == GIMP_UNIT_PIXEL) + return (value * gimp_unit_get_factor (GIMP_UNIT_POINT) / resolution); + + return (value * + gimp_unit_get_factor (GIMP_UNIT_POINT) / gimp_unit_get_factor (unit)); +} + +/** + * gimp_unit_is_metric: + * @unit: The unit + * + * Checks if the given @unit is metric. A simplistic test is used + * that looks at the unit's factor and checks if it is 2.54 multiplied + * by some common powers of 10. Currently it checks for mm, cm, dm, m. + * + * See also: gimp_unit_get_factor() + * + * Returns: %TRUE if the @unit is metric. + * + * Since: 2.10 + **/ +gboolean +gimp_unit_is_metric (GimpUnit unit) +{ + gdouble factor; + + if (unit == GIMP_UNIT_MM) + return TRUE; + + factor = gimp_unit_get_factor (unit); + + if (factor == 0.0) + return FALSE; + + return ((ABS (factor - 0.0254) < 1e-7) || /* m */ + (ABS (factor - 0.254) < 1e-6) || /* dm */ + (ABS (factor - 2.54) < 1e-5) || /* cm */ + (ABS (factor - 25.4) < 1e-4)); /* mm */ +} diff --git a/libgimpbase/gimpunit.h b/libgimpbase/gimpunit.h new file mode 100644 index 0000000..c24d94e --- /dev/null +++ b/libgimpbase/gimpunit.h @@ -0,0 +1,110 @@ +/* LIBGIMP - The GIMP Library + * Copyright (C) 1995-1997 Peter Mattis and Spencer Kimball + * + * gimpunit.h + * Copyright (C) 1999-2003 Michael Natterer <mitch@gimp.org> + * + * This library is free software: you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see + * <https://www.gnu.org/licenses/>. + */ + +#if !defined (__GIMP_BASE_H_INSIDE__) && !defined (GIMP_BASE_COMPILATION) +#error "Only <libgimpbase/gimpbase.h> can be included directly." +#endif + +#ifndef __GIMP_UNIT_H__ +#define __GIMP_UNIT_H__ + +G_BEGIN_DECLS + +/* For information look into the C source or the html documentation */ + +/** + * GIMP_TYPE_UNIT: + * + * #GIMP_TYPE_UNIT is a #GType derived from #G_TYPE_INT. + **/ + +#define GIMP_TYPE_UNIT (gimp_unit_get_type ()) +#define GIMP_VALUE_HOLDS_UNIT(value) (G_TYPE_CHECK_VALUE_TYPE ((value), GIMP_TYPE_UNIT)) + +GType gimp_unit_get_type (void) G_GNUC_CONST; + + +/* + * GIMP_TYPE_PARAM_UNIT + */ + +#define GIMP_TYPE_PARAM_UNIT (gimp_param_unit_get_type ()) +#define GIMP_IS_PARAM_SPEC_UNIT(pspec) (G_TYPE_CHECK_INSTANCE_TYPE ((pspec), GIMP_TYPE_PARAM_UNIT)) + +GType gimp_param_unit_get_type (void) G_GNUC_CONST; + +GParamSpec * gimp_param_spec_unit (const gchar *name, + const gchar *nick, + const gchar *blurb, + gboolean allow_pixels, + gboolean allow_percent, + GimpUnit default_value, + GParamFlags flags); + + + +gint gimp_unit_get_number_of_units (void); +gint gimp_unit_get_number_of_built_in_units (void) G_GNUC_CONST; + +GimpUnit gimp_unit_new (gchar *identifier, + gdouble factor, + gint digits, + gchar *symbol, + gchar *abbreviation, + gchar *singular, + gchar *plural); + +gboolean gimp_unit_get_deletion_flag (GimpUnit unit); +void gimp_unit_set_deletion_flag (GimpUnit unit, + gboolean deletion_flag); + +gdouble gimp_unit_get_factor (GimpUnit unit); + +gint gimp_unit_get_digits (GimpUnit unit); +gint gimp_unit_get_scaled_digits (GimpUnit unit, + gdouble resolution); + +const gchar * gimp_unit_get_identifier (GimpUnit unit); + +const gchar * gimp_unit_get_symbol (GimpUnit unit); +const gchar * gimp_unit_get_abbreviation (GimpUnit unit); +const gchar * gimp_unit_get_singular (GimpUnit unit); +const gchar * gimp_unit_get_plural (GimpUnit unit); + +gchar * gimp_unit_format_string (const gchar *format, + GimpUnit unit); + +gdouble gimp_pixels_to_units (gdouble pixels, + GimpUnit unit, + gdouble resolution); +gdouble gimp_units_to_pixels (gdouble value, + GimpUnit unit, + gdouble resolution); +gdouble gimp_units_to_points (gdouble value, + GimpUnit unit, + gdouble resolution); + +gboolean gimp_unit_is_metric (GimpUnit unit); + + +G_END_DECLS + +#endif /* __GIMP_UNIT_H__ */ diff --git a/libgimpbase/gimputils.c b/libgimpbase/gimputils.c new file mode 100644 index 0000000..2ee1338 --- /dev/null +++ b/libgimpbase/gimputils.c @@ -0,0 +1,1603 @@ +/* LIBGIMP - The GIMP Library + * Copyright (C) 1995-1997 Spencer Kimball and Peter Mattis + * + * gimputils.c + * Copyright (C) 2003 Sven Neumann <sven@gimp.org> + * + * This library is free software: you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see + * <https://www.gnu.org/licenses/>. + */ + +#include "config.h" + +#include <stdlib.h> +#include <string.h> +#include <stdio.h> + +#ifdef PLATFORM_OSX +#include <AppKit/AppKit.h> +#endif + +#ifdef HAVE_EXECINFO_H +/* Allowing backtrace() API. */ +#include <execinfo.h> +#endif + +#include <gio/gio.h> +#include <glib/gprintf.h> + +#if defined(G_OS_WIN32) +# include <windows.h> +# include <shlobj.h> + +#else /* G_OS_WIN32 */ + +/* For waitpid() */ +#include <sys/wait.h> +#include <unistd.h> +#include <errno.h> + +/* For thread IDs. */ +#include <sys/types.h> +#include <sys/syscall.h> + +#ifdef HAVE_SYS_PRCTL_H +#include <sys/prctl.h> +#endif + +#ifdef HAVE_SYS_THR_H +#include <sys/thr.h> +#endif + +#endif /* G_OS_WIN32 */ + +#include "gimpbasetypes.h" +#include "gimputils.h" + +#include "libgimp/libgimp-intl.h" + + +/** + * SECTION: gimputils + * @title: gimputils + * @short_description: Utilities of general interest + * + * Utilities of general interest + **/ + +static gboolean gimp_utils_generic_available (const gchar *program, + gint major, + gint minor); +static gboolean gimp_utils_gdb_available (gint major, + gint minor); + +/** + * gimp_utf8_strtrim: + * @str: an UTF-8 encoded string (or %NULL) + * @max_chars: the maximum number of characters before the string get + * trimmed + * + * Creates a (possibly trimmed) copy of @str. The string is cut if it + * exceeds @max_chars characters or on the first newline. The fact + * that the string was trimmed is indicated by appending an ellipsis. + * + * Returns: A (possibly trimmed) copy of @str which should be freed + * using g_free() when it is not needed any longer. + **/ +gchar * +gimp_utf8_strtrim (const gchar *str, + gint max_chars) +{ + /* FIXME: should we make this translatable? */ + const gchar ellipsis[] = "..."; + const gint e_len = strlen (ellipsis); + + if (str) + { + const gchar *p; + const gchar *newline = NULL; + gint chars = 0; + gunichar unichar; + + for (p = str; *p; p = g_utf8_next_char (p)) + { + if (++chars > max_chars) + break; + + unichar = g_utf8_get_char (p); + + switch (g_unichar_break_type (unichar)) + { + case G_UNICODE_BREAK_MANDATORY: + case G_UNICODE_BREAK_LINE_FEED: + newline = p; + break; + default: + continue; + } + + break; + } + + if (*p) + { + gsize len = p - str; + gchar *trimmed = g_new (gchar, len + e_len + 2); + + memcpy (trimmed, str, len); + if (newline) + trimmed[len++] = ' '; + + g_strlcpy (trimmed + len, ellipsis, e_len + 1); + + return trimmed; + } + + return g_strdup (str); + } + + return NULL; +} + +/** + * gimp_any_to_utf8: + * @str: The string to be converted to UTF-8. + * @len: The length of the string, or -1 if the string + * is nul-terminated. + * @warning_format: The message format for the warning message if conversion + * to UTF-8 fails. See the <function>printf()</function> + * documentation. + * @...: The parameters to insert into the format string. + * + * This function takes any string (UTF-8 or not) and always returns a valid + * UTF-8 string. + * + * If @str is valid UTF-8, a copy of the string is returned. + * + * If UTF-8 validation fails, g_locale_to_utf8() is tried and if it + * succeeds the resulting string is returned. + * + * Otherwise, the portion of @str that is UTF-8, concatenated + * with "(invalid UTF-8 string)" is returned. If not even the start + * of @str is valid UTF-8, only "(invalid UTF-8 string)" is returned. + * + * Return value: The UTF-8 string as described above. + **/ +gchar * +gimp_any_to_utf8 (const gchar *str, + gssize len, + const gchar *warning_format, + ...) +{ + const gchar *start_invalid; + gchar *utf8; + + g_return_val_if_fail (str != NULL, NULL); + + if (g_utf8_validate (str, len, &start_invalid)) + { + if (len < 0) + utf8 = g_strdup (str); + else + utf8 = g_strndup (str, len); + } + else + { + utf8 = g_locale_to_utf8 (str, len, NULL, NULL, NULL); + } + + if (! utf8) + { + if (warning_format) + { + va_list warning_args; + + va_start (warning_args, warning_format); + + g_logv (G_LOG_DOMAIN, G_LOG_LEVEL_MESSAGE, + warning_format, warning_args); + + va_end (warning_args); + } + + if (start_invalid > str) + { + gchar *tmp; + + tmp = g_strndup (str, start_invalid - str); + utf8 = g_strconcat (tmp, " ", _("(invalid UTF-8 string)"), NULL); + g_free (tmp); + } + else + { + utf8 = g_strdup (_("(invalid UTF-8 string)")); + } + } + + return utf8; +} + +/** + * gimp_filename_to_utf8: + * @filename: The filename to be converted to UTF-8. + * + * Convert a filename in the filesystem's encoding to UTF-8 + * temporarily. The return value is a pointer to a string that is + * guaranteed to be valid only during the current iteration of the + * main loop or until the next call to gimp_filename_to_utf8(). + * + * The only purpose of this function is to provide an easy way to pass + * a filename in the filesystem encoding to a function that expects an + * UTF-8 encoded filename. + * + * Return value: A temporarily valid UTF-8 representation of @filename. + * This string must not be changed or freed. + **/ +const gchar * +gimp_filename_to_utf8 (const gchar *filename) +{ + /* Simpleminded implementation, but at least allocates just one copy + * of each translation. Could check if already UTF-8, and if so + * return filename as is. Could perhaps (re)use a suitably large + * cyclic buffer, but then would have to verify that all calls + * really need the return value just for a "short" time. + */ + + static GHashTable *ht = NULL; + gchar *filename_utf8; + + if (! filename) + return NULL; + + if (! ht) + ht = g_hash_table_new (g_str_hash, g_str_equal); + + filename_utf8 = g_hash_table_lookup (ht, filename); + + if (! filename_utf8) + { + filename_utf8 = g_filename_display_name (filename); + g_hash_table_insert (ht, g_strdup (filename), filename_utf8); + } + + return filename_utf8; +} + +/** + * gimp_file_get_utf8_name: + * @file: a #GFile + * + * This function works like gimp_filename_to_utf8() and returns + * a UTF-8 encoded string that does not need to be freed. + * + * It converts a #GFile's path or uri to UTF-8 temporarily. The + * return value is a pointer to a string that is guaranteed to be + * valid only during the current iteration of the main loop or until + * the next call to gimp_file_get_utf8_name(). + * + * The only purpose of this function is to provide an easy way to pass + * a #GFile's name to a function that expects an UTF-8 encoded string. + * + * See g_file_get_parse_name(). + * + * Since: 2.10 + * + * Return value: A temporarily valid UTF-8 representation of @file's name. + * This string must not be changed or freed. + **/ +const gchar * +gimp_file_get_utf8_name (GFile *file) +{ + gchar *name; + + g_return_val_if_fail (G_IS_FILE (file), NULL); + + name = g_file_get_parse_name (file); + + g_object_set_data_full (G_OBJECT (file), "gimp-parse-name", name, + (GDestroyNotify) g_free); + + return name; +} + +/** + * gimp_file_has_extension: + * @file: a #GFile + * @extension: an ASCII extension + * + * This function checks if @file's URI ends with @extension. It behaves + * like g_str_has_suffix() on g_file_get_uri(), except that the string + * comparison is done case-insensitively using g_ascii_strcasecmp(). + * + * Since: 2.10 + * + * Return value: %TRUE if @file's URI ends with @extension, + * %FALSE otherwise. + **/ +gboolean +gimp_file_has_extension (GFile *file, + const gchar *extension) +{ + gchar *uri; + gint uri_len; + gint ext_len; + gboolean result = FALSE; + + g_return_val_if_fail (G_IS_FILE (file), FALSE); + g_return_val_if_fail (extension != NULL, FALSE); + + uri = g_file_get_uri (file); + + uri_len = strlen (uri); + ext_len = strlen (extension); + + if (uri_len && ext_len && (uri_len > ext_len)) + { + if (g_ascii_strcasecmp (uri + uri_len - ext_len, extension) == 0) + result = TRUE; + } + + g_free (uri); + + return result; +} + +/** + * gimp_file_show_in_file_manager: + * @file: a #GFile + * @error: return location for a #GError + * + * Shows @file in the system file manager. + * + * Since: 2.10 + * + * Return value: %TRUE on success, %FALSE otherwise. On %FALSE, @error + * is set. + **/ +gboolean +gimp_file_show_in_file_manager (GFile *file, + GError **error) +{ + g_return_val_if_fail (G_IS_FILE (file), FALSE); + g_return_val_if_fail (error == NULL || *error == NULL, FALSE); + +#if defined(G_OS_WIN32) + + { + gboolean ret; + char *filename; + int n; + LPWSTR w_filename = NULL; + ITEMIDLIST *pidl = NULL; + + ret = FALSE; + + /* Calling this function multiple times should do no harm, but it is + easier to put this here as it needs linking against ole32. */ + CoInitialize (NULL); + + filename = g_file_get_path (file); + if (!filename) + { + g_set_error_literal (error, G_FILE_ERROR, 0, + _("File path is NULL")); + goto out; + } + + n = MultiByteToWideChar (CP_UTF8, MB_ERR_INVALID_CHARS, + filename, -1, NULL, 0); + if (n == 0) + { + g_set_error_literal (error, G_FILE_ERROR, 0, + _("Error converting UTF-8 filename to wide char")); + goto out; + } + + w_filename = g_malloc_n (n + 1, sizeof (wchar_t)); + n = MultiByteToWideChar (CP_UTF8, MB_ERR_INVALID_CHARS, + filename, -1, + w_filename, (n + 1) * sizeof (wchar_t)); + if (n == 0) + { + g_set_error_literal (error, G_FILE_ERROR, 0, + _("Error converting UTF-8 filename to wide char")); + goto out; + } + + pidl = ILCreateFromPathW (w_filename); + if (!pidl) + { + g_set_error_literal (error, G_FILE_ERROR, 0, + _("ILCreateFromPath() failed")); + goto out; + } + + SHOpenFolderAndSelectItems (pidl, 0, NULL, 0); + ret = TRUE; + + out: + if (pidl) + ILFree (pidl); + g_free (w_filename); + g_free (filename); + + return ret; + } + +#elif defined(PLATFORM_OSX) + + { + gchar *uri; + NSString *filename; + NSURL *url; + gboolean retval = TRUE; + + uri = g_file_get_uri (file); + filename = [NSString stringWithUTF8String:uri]; + + url = [NSURL URLWithString:filename]; + if (url) + { + NSArray *url_array = [NSArray arrayWithObject:url]; + + [[NSWorkspace sharedWorkspace] activateFileViewerSelectingURLs:url_array]; + } + else + { + g_set_error (error, G_FILE_ERROR, 0, + _("Cannot convert '%s' into a valid NSURL."), uri); + retval = FALSE; + } + + g_free (uri); + + return retval; + } + +#else /* UNIX */ + + { + GDBusProxy *proxy; + GVariant *retval; + GVariantBuilder *builder; + gchar *uri; + + proxy = g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SESSION, + G_DBUS_PROXY_FLAGS_NONE, + NULL, + "org.freedesktop.FileManager1", + "/org/freedesktop/FileManager1", + "org.freedesktop.FileManager1", + NULL, error); + + if (! proxy) + { + g_prefix_error (error, + _("Connecting to org.freedesktop.FileManager1 failed: ")); + return FALSE; + } + + uri = g_file_get_uri (file); + + builder = g_variant_builder_new (G_VARIANT_TYPE ("as")); + g_variant_builder_add (builder, "s", uri); + + g_free (uri); + + retval = g_dbus_proxy_call_sync (proxy, + "ShowItems", + g_variant_new ("(ass)", + builder, + ""), + G_DBUS_CALL_FLAGS_NONE, + -1, NULL, error); + + g_variant_builder_unref (builder); + g_object_unref (proxy); + + if (! retval) + { + g_prefix_error (error, _("Calling ShowItems failed: ")); + return FALSE; + } + + g_variant_unref (retval); + + return TRUE; + } + +#endif +} + +/** + * gimp_strip_uline: + * @str: underline infested string (or %NULL) + * + * This function returns a copy of @str stripped of underline + * characters. This comes in handy when needing to strip mnemonics + * from menu paths etc. + * + * In some languages, mnemonics are handled by adding the mnemonic + * character in brackets (like "File (_F)"). This function recognizes + * this construct and removes the whole bracket construction to get + * rid of the mnemonic (see bug 157561). + * + * Return value: A (possibly stripped) copy of @str which should be + * freed using g_free() when it is not needed any longer. + **/ +gchar * +gimp_strip_uline (const gchar *str) +{ + gchar *escaped; + gchar *p; + gboolean past_bracket = FALSE; + + if (! str) + return NULL; + + p = escaped = g_strdup (str); + + while (*str) + { + if (*str == '_') + { + /* "__" means a literal "_" in the menu path */ + if (str[1] == '_') + { + *p++ = *str++; + str++; + continue; + } + + /* find the "(_X)" construct and remove it entirely */ + if (past_bracket && str[1] && *(g_utf8_next_char (str + 1)) == ')') + { + str = g_utf8_next_char (str + 1) + 1; + p--; + } + else + { + str++; + } + } + else + { + past_bracket = (*str == '('); + + *p++ = *str++; + } + } + + *p = '\0'; + + return escaped; +} + +/** + * gimp_escape_uline: + * @str: Underline infested string (or %NULL) + * + * This function returns a copy of @str with all underline converted + * to two adjacent underlines. This comes in handy when needing to display + * strings with underlines (like filenames) in a place that would convert + * them to mnemonics. + * + * Return value: A (possibly escaped) copy of @str which should be + * freed using g_free() when it is not needed any longer. + * + * Since: 2.2 + **/ +gchar * +gimp_escape_uline (const gchar *str) +{ + gchar *escaped; + gchar *p; + gint n_ulines = 0; + + if (! str) + return NULL; + + for (p = (gchar *) str; *p; p++) + if (*p == '_') + n_ulines++; + + p = escaped = g_malloc (strlen (str) + n_ulines + 1); + + while (*str) + { + if (*str == '_') + *p++ = '_'; + + *p++ = *str++; + } + + *p = '\0'; + + return escaped; +} + +/** + * gimp_canonicalize_identifier: + * @identifier: The identifier string to canonicalize. + * + * Turns any input string into a canonicalized string. + * + * Canonical identifiers are e.g. expected by the PDB for procedure + * and parameter names. Every character of the input string that is + * not either '-', 'a-z', 'A-Z' or '0-9' will be replaced by a '-'. + * + * Return value: The canonicalized identifier. This is a newly + * allocated string that should be freed with g_free() + * when no longer needed. + * + * Since: 2.4 + **/ +gchar * +gimp_canonicalize_identifier (const gchar *identifier) +{ + gchar *canonicalized = NULL; + + if (identifier) + { + gchar *p; + + canonicalized = g_strdup (identifier); + + for (p = canonicalized; *p != 0; p++) + { + gchar c = *p; + + if (c != '-' && + (c < '0' || c > '9') && + (c < 'A' || c > 'Z') && + (c < 'a' || c > 'z')) + *p = '-'; + } + } + + return canonicalized; +} + +/** + * gimp_enum_get_desc: + * @enum_class: a #GEnumClass + * @value: a value from @enum_class + * + * Retrieves #GimpEnumDesc associated with the given value, or %NULL. + * + * Return value: the value's #GimpEnumDesc. + * + * Since: 2.2 + **/ +GimpEnumDesc * +gimp_enum_get_desc (GEnumClass *enum_class, + gint value) +{ + const GimpEnumDesc *value_desc; + + g_return_val_if_fail (G_IS_ENUM_CLASS (enum_class), NULL); + + value_desc = + gimp_enum_get_value_descriptions (G_TYPE_FROM_CLASS (enum_class)); + + if (value_desc) + { + while (value_desc->value_desc) + { + if (value_desc->value == value) + return (GimpEnumDesc *) value_desc; + + value_desc++; + } + } + + return NULL; +} + +/** + * gimp_enum_get_value: + * @enum_type: the #GType of a registered enum + * @value: an integer value + * @value_name: return location for the value's name (or %NULL) + * @value_nick: return location for the value's nick (or %NULL) + * @value_desc: return location for the value's translated description (or %NULL) + * @value_help: return location for the value's translated help (or %NULL) + * + * Checks if @value is valid for the enum registered as @enum_type. + * If the value exists in that enum, its name, nick and its translated + * description and help are returned (if @value_name, @value_nick, + * @value_desc and @value_help are not %NULL). + * + * Return value: %TRUE if @value is valid for the @enum_type, + * %FALSE otherwise + * + * Since: 2.2 + **/ +gboolean +gimp_enum_get_value (GType enum_type, + gint value, + const gchar **value_name, + const gchar **value_nick, + const gchar **value_desc, + const gchar **value_help) +{ + GEnumClass *enum_class; + GEnumValue *enum_value; + gboolean success = FALSE; + + g_return_val_if_fail (G_TYPE_IS_ENUM (enum_type), FALSE); + + enum_class = g_type_class_ref (enum_type); + enum_value = g_enum_get_value (enum_class, value); + + if (enum_value) + { + if (value_name) + *value_name = enum_value->value_name; + + if (value_nick) + *value_nick = enum_value->value_nick; + + if (value_desc || value_help) + { + GimpEnumDesc *enum_desc; + + enum_desc = gimp_enum_get_desc (enum_class, value); + + if (value_desc) + { + if (enum_desc && enum_desc->value_desc) + { + const gchar *context; + + context = gimp_type_get_translation_context (enum_type); + + if (context) /* the new way, using NC_() */ + *value_desc = g_dpgettext2 (gimp_type_get_translation_domain (enum_type), + context, + enum_desc->value_desc); + else /* for backward compatibility */ + *value_desc = g_strip_context (enum_desc->value_desc, + dgettext (gimp_type_get_translation_domain (enum_type), + enum_desc->value_desc)); + } + else + { + *value_desc = NULL; + } + } + + if (value_help) + { + *value_help = ((enum_desc && enum_desc->value_help) ? + dgettext (gimp_type_get_translation_domain (enum_type), + enum_desc->value_help) : + NULL); + } + } + + success = TRUE; + } + + g_type_class_unref (enum_class); + + return success; +} + +/** + * gimp_enum_value_get_desc: + * @enum_class: a #GEnumClass + * @enum_value: a #GEnumValue from @enum_class + * + * Retrieves the translated description for a given @enum_value. + * + * Return value: the translated description of the enum value + * + * Since: 2.2 + **/ +const gchar * +gimp_enum_value_get_desc (GEnumClass *enum_class, + GEnumValue *enum_value) +{ + GType type = G_TYPE_FROM_CLASS (enum_class); + GimpEnumDesc *enum_desc; + + enum_desc = gimp_enum_get_desc (enum_class, enum_value->value); + + if (enum_desc && enum_desc->value_desc) + { + const gchar *context; + + context = gimp_type_get_translation_context (type); + + if (context) /* the new way, using NC_() */ + return g_dpgettext2 (gimp_type_get_translation_domain (type), + context, + enum_desc->value_desc); + else /* for backward compatibility */ + return g_strip_context (enum_desc->value_desc, + dgettext (gimp_type_get_translation_domain (type), + enum_desc->value_desc)); + } + + return enum_value->value_name; +} + +/** + * gimp_enum_value_get_help: + * @enum_class: a #GEnumClass + * @enum_value: a #GEnumValue from @enum_class + * + * Retrieves the translated help for a given @enum_value. + * + * Return value: the translated help of the enum value + * + * Since: 2.2 + **/ +const gchar * +gimp_enum_value_get_help (GEnumClass *enum_class, + GEnumValue *enum_value) +{ + GType type = G_TYPE_FROM_CLASS (enum_class); + GimpEnumDesc *enum_desc; + + enum_desc = gimp_enum_get_desc (enum_class, enum_value->value); + + if (enum_desc && enum_desc->value_help) + return dgettext (gimp_type_get_translation_domain (type), + enum_desc->value_help); + + return NULL; +} + +/** + * gimp_enum_value_get_abbrev: + * @enum_class: a #GEnumClass + * @enum_value: a #GEnumValue from @enum_class + * + * Retrieves the translated abbreviation for a given @enum_value. + * + * Return value: the translated abbreviation of the enum value + * + * Since: 2.10 + **/ +const gchar * +gimp_enum_value_get_abbrev (GEnumClass *enum_class, + GEnumValue *enum_value) +{ + GType type = G_TYPE_FROM_CLASS (enum_class); + GimpEnumDesc *enum_desc; + + enum_desc = gimp_enum_get_desc (enum_class, enum_value->value); + + if (enum_desc && + enum_desc[1].value == enum_desc->value && + enum_desc[1].value_desc) + { + return g_dpgettext2 (gimp_type_get_translation_domain (type), + gimp_type_get_translation_context (type), + enum_desc[1].value_desc); + } + + return NULL; +} + +/** + * gimp_flags_get_first_desc: + * @flags_class: a #GFlagsClass + * @value: a value from @flags_class + * + * Retrieves the first #GimpFlagsDesc that matches the given value, or %NULL. + * + * Return value: the value's #GimpFlagsDesc. + * + * Since: 2.2 + **/ +GimpFlagsDesc * +gimp_flags_get_first_desc (GFlagsClass *flags_class, + guint value) +{ + const GimpFlagsDesc *value_desc; + + g_return_val_if_fail (G_IS_FLAGS_CLASS (flags_class), NULL); + + value_desc = + gimp_flags_get_value_descriptions (G_TYPE_FROM_CLASS (flags_class)); + + if (value_desc) + { + while (value_desc->value_desc) + { + if ((value_desc->value & value) == value_desc->value) + return (GimpFlagsDesc *) value_desc; + + value_desc++; + } + } + + return NULL; +} + +/** + * gimp_flags_get_first_value: + * @flags_type: the #GType of registered flags + * @value: an integer value + * @value_name: return location for the value's name (or %NULL) + * @value_nick: return location for the value's nick (or %NULL) + * @value_desc: return location for the value's translated description (or %NULL) + * @value_help: return location for the value's translated help (or %NULL) + * + * Checks if @value is valid for the flags registered as @flags_type. + * If the value exists in that flags, its name, nick and its + * translated description and help are returned (if @value_name, + * @value_nick, @value_desc and @value_help are not %NULL). + * + * Return value: %TRUE if @value is valid for the @flags_type, + * %FALSE otherwise + * + * Since: 2.2 + **/ +gboolean +gimp_flags_get_first_value (GType flags_type, + guint value, + const gchar **value_name, + const gchar **value_nick, + const gchar **value_desc, + const gchar **value_help) +{ + GFlagsClass *flags_class; + GFlagsValue *flags_value; + + g_return_val_if_fail (G_TYPE_IS_FLAGS (flags_type), FALSE); + + flags_class = g_type_class_peek (flags_type); + flags_value = g_flags_get_first_value (flags_class, value); + + if (flags_value) + { + if (value_name) + *value_name = flags_value->value_name; + + if (value_nick) + *value_nick = flags_value->value_nick; + + if (value_desc || value_help) + { + GimpFlagsDesc *flags_desc; + + flags_desc = gimp_flags_get_first_desc (flags_class, value); + + if (value_desc) + *value_desc = ((flags_desc && flags_desc->value_desc) ? + dgettext (gimp_type_get_translation_domain (flags_type), + flags_desc->value_desc) : + NULL); + + if (value_help) + *value_help = ((flags_desc && flags_desc->value_desc) ? + dgettext (gimp_type_get_translation_domain (flags_type), + flags_desc->value_help) : + NULL); + } + + return TRUE; + } + + return FALSE; +} + +/** + * gimp_flags_value_get_desc: + * @flags_class: a #GFlagsClass + * @flags_value: a #GFlagsValue from @flags_class + * + * Retrieves the translated description for a given @flags_value. + * + * Return value: the translated description of the flags value + * + * Since: 2.2 + **/ +const gchar * +gimp_flags_value_get_desc (GFlagsClass *flags_class, + GFlagsValue *flags_value) +{ + GType type = G_TYPE_FROM_CLASS (flags_class); + GimpFlagsDesc *flags_desc; + + flags_desc = gimp_flags_get_first_desc (flags_class, flags_value->value); + + if (flags_desc->value_desc) + { + const gchar *context; + + context = gimp_type_get_translation_context (type); + + if (context) /* the new way, using NC_() */ + return g_dpgettext2 (gimp_type_get_translation_domain (type), + context, + flags_desc->value_desc); + else /* for backward compatibility */ + return g_strip_context (flags_desc->value_desc, + dgettext (gimp_type_get_translation_domain (type), + flags_desc->value_desc)); + } + + return flags_value->value_name; +} + +/** + * gimp_flags_value_get_help: + * @flags_class: a #GFlagsClass + * @flags_value: a #GFlagsValue from @flags_class + * + * Retrieves the translated help for a given @flags_value. + * + * Return value: the translated help of the flags value + * + * Since: 2.2 + **/ +const gchar * +gimp_flags_value_get_help (GFlagsClass *flags_class, + GFlagsValue *flags_value) +{ + GType type = G_TYPE_FROM_CLASS (flags_class); + GimpFlagsDesc *flags_desc; + + flags_desc = gimp_flags_get_first_desc (flags_class, flags_value->value); + + if (flags_desc->value_help) + return dgettext (gimp_type_get_translation_domain (type), + flags_desc->value_help); + + return NULL; +} + +/** + * gimp_flags_value_get_abbrev: + * @flags_class: a #GFlagsClass + * @flags_value: a #GFlagsValue from @flags_class + * + * Retrieves the translated abbreviation for a given @flags_value. + * + * Return value: the translated abbreviation of the flags value + * + * Since: 2.10 + **/ +const gchar * +gimp_flags_value_get_abbrev (GFlagsClass *flags_class, + GFlagsValue *flags_value) +{ + GType type = G_TYPE_FROM_CLASS (flags_class); + GimpFlagsDesc *flags_desc; + + flags_desc = gimp_flags_get_first_desc (flags_class, flags_value->value); + + if (flags_desc && + flags_desc[1].value == flags_desc->value && + flags_desc[1].value_desc) + { + return g_dpgettext2 (gimp_type_get_translation_domain (type), + gimp_type_get_translation_context (type), + flags_desc[1].value_desc); + } + + return NULL; +} + +/** + * gimp_stack_trace_available: + * @optimal: whether we get optimal traces. + * + * Returns #TRUE if we have dependencies to generate backtraces. If + * @optimal is #TRUE, the function will return #TRUE only when we + * are able to generate optimal traces (i.e. with GDB or LLDB); + * otherwise we return #TRUE even if only backtrace() API is available. + * + * On Win32, we return TRUE if Dr. Mingw is built-in, FALSE otherwise. + * + * Note: this function is not crash-safe, i.e. you should not try to use + * it in a callback when the program is already crashing. In such a + * case, call gimp_stack_trace_print() or gimp_stack_trace_query() + * directly. + * + * Since: 2.10 + **/ +gboolean +gimp_stack_trace_available (gboolean optimal) +{ +#ifndef G_OS_WIN32 + gchar *lld_path = NULL; + gboolean has_lldb = FALSE; + + /* Similarly to gdb, we could check for lldb by calling: + * gimp_utils_generic_available ("lldb", major, minor). + * We don't do so on purpose because on macOS, when lldb is absent, it + * triggers a popup asking to install Xcode. So instead, we just + * search for the executable in path. + * This is the reason why this function is not crash-safe, since + * g_find_program_in_path() allocates memory. + * See issue #1999. + */ + lld_path = g_find_program_in_path ("lldb"); + if (lld_path) + { + has_lldb = TRUE; + g_free (lld_path); + } + + if (gimp_utils_gdb_available (7, 0) || has_lldb) + return TRUE; +#ifdef HAVE_EXECINFO_H + if (! optimal) + return TRUE; +#endif +#else /* G_OS_WIN32 */ +#ifdef HAVE_EXCHNDL + return TRUE; +#endif +#endif /* G_OS_WIN32 */ + return FALSE; +} + +/** + * gimp_stack_trace_print: + * @prog_name: the program to attach to. + * @stream: a #FILE * stream. + * @trace: location to store a newly allocated string of the trace. + * + * Attempts to generate a stack trace at current code position in + * @prog_name. @prog_name is mostly a helper and can be set to NULL. + * Nevertheless if set, it has to be the current program name (argv[0]). + * This function is not meant to generate stack trace for third-party + * programs, and will attach the current process id only. + * Internally, this function uses `gdb` or `lldb` if they are available, + * or the stacktrace() API on platforms where it is available. It always + * fails on Win32. + * + * The stack trace, once generated, will either be printed to @stream or + * returned as a newly allocated string in @trace, if not #NULL. + * + * In some error cases (e.g. segmentation fault), trying to allocate + * more memory will trigger more segmentation faults and therefore loop + * our error handling (which is just wrong). Therefore printing to a + * file description is an implementation without any memory allocation. + + * Return value: #TRUE if a stack trace could be generated, #FALSE + * otherwise. + * + * Since: 2.10 + **/ +gboolean +gimp_stack_trace_print (const gchar *prog_name, + gpointer stream, + gchar **trace) +{ + gboolean stack_printed = FALSE; + + /* This works only on UNIX systems. */ +#ifndef G_OS_WIN32 + GString *gtrace = NULL; + gchar gimp_pid[16]; + gchar buffer[256]; + ssize_t read_n; + int sync_fd[2]; + int out_fd[2]; + pid_t fork_pid; + pid_t pid = getpid(); + gint eintr_count = 0; +#if defined(G_OS_WIN32) + DWORD tid = GetCurrentThreadId (); +#elif defined(PLATFORM_OSX) + uint64 tid64; + long tid; + + pthread_threadid_np (NULL, &tid64); + tid = (long) tid64; +#elif defined(SYS_gettid) + long tid = syscall (SYS_gettid); +#elif defined(HAVE_THR_SELF) + long tid = 0; + thr_self (&tid); +#endif + + g_snprintf (gimp_pid, 16, "%u", (guint) pid); + + if (pipe (sync_fd) == -1) + { + return FALSE; + } + + if (pipe (out_fd) == -1) + { + close (sync_fd[0]); + close (sync_fd[1]); + + return FALSE; + } + + fork_pid = fork (); + if (fork_pid == 0) + { + /* Child process. */ + gchar *args[9] = { "gdb", "-batch", + "-ex", "info threads", + "-ex", "thread apply all backtrace full", + (gchar *) prog_name, NULL, NULL }; + + if (prog_name == NULL) + args[6] = "-p"; + + args[7] = gimp_pid; + + /* Wait until the parent enabled us to ptrace it. */ + { + gchar dummy; + + close (sync_fd[1]); + while (read (sync_fd[0], &dummy, 1) < 0 && errno == EINTR); + close (sync_fd[0]); + } + + /* Redirect the debugger output. */ + dup2 (out_fd[1], STDOUT_FILENO); + close (out_fd[0]); + close (out_fd[1]); + + /* Run GDB if version 7.0 or over. Why I do such a check is that + * it turns out older versions may not only fail, but also have + * very undesirable side effects like terminating the debugged + * program, at least on FreeBSD where GDB 6.1 is apparently + * installed by default on the stable release at day of writing. + * See bug 793514. */ + if (! gimp_utils_gdb_available (7, 0) || + execvp (args[0], args) == -1) + { + /* LLDB as alternative if the GDB call failed or if it was in + * a too-old version. */ + gchar *args_lldb[15] = { "lldb", "--attach-pid", NULL, "--batch", + "--one-line", "thread list", + "--one-line", "thread backtrace all", + "--one-line", "bt all", + "--one-line-on-crash", "bt", + "--one-line-on-crash", "quit", NULL }; + + args_lldb[2] = gimp_pid; + + execvp (args_lldb[0], args_lldb); + } + + _exit (0); + } + else if (fork_pid > 0) + { + /* Main process */ + int status; + + /* Allow the child to ptrace us, and signal it to start. */ + close (sync_fd[0]); +#ifdef PR_SET_PTRACER + prctl (PR_SET_PTRACER, fork_pid, 0, 0, 0); +#endif + close (sync_fd[1]); + + /* It is important to close the writing side of the pipe, otherwise + * the read() will wait forever without getting the information that + * writing is finished. + */ + close (out_fd[1]); + + while ((read_n = read (out_fd[0], buffer, 256)) != 0) + { + if (read_n < 0) + { + /* LLDB on macOS seems to trigger a few EINTR error (see + * !13), though read() finally ends up working later. So + * let's not make this error fatal, and instead try again. + * Yet to avoid infinite loop (in case the error really + * happens at every call), we abandon after a few + * consecutive errors. + */ + if (errno == EINTR && eintr_count <= 5) + { + eintr_count++; + continue; + } + break; + } + eintr_count = 0; + if (! stack_printed) + { +#if defined(PLATFORM_OSX) + if (stream) + g_fprintf (stream, + "\n# Stack traces obtained from PID %d - Thread 0x%lx #\n\n", + pid, tid); +#elif defined(G_OS_WIN32) || defined(SYS_gettid) || defined(HAVE_THR_SELF) + if (stream) + g_fprintf (stream, + "\n# Stack traces obtained from PID %d - Thread %lu #\n\n", + pid, tid); +#endif + if (trace) + { + gtrace = g_string_new (NULL); +#if defined(PLATFORM_OSX) + g_string_printf (gtrace, + "\n# Stack traces obtained from PID %d - Thread 0x%lx #\n\n", + pid, tid); +#elif defined(G_OS_WIN32) || defined(SYS_gettid) || defined(HAVE_THR_SELF) + g_string_printf (gtrace, + "\n# Stack traces obtained from PID %d - Thread %lu #\n\n", + pid, tid); +#endif + } + } + /* It's hard to know if the debugger was found since it + * happened in the child. Let's just assume that any output + * means it succeeded. + */ + stack_printed = TRUE; + + buffer[read_n] = '\0'; + if (stream) + g_fprintf (stream, "%s", buffer); + if (trace) + g_string_append (gtrace, (const gchar *) buffer); + } + close (out_fd[0]); + +#ifdef PR_SET_PTRACER + /* Clear ptrace permission set above */ + prctl (PR_SET_PTRACER, 0, 0, 0, 0); +#endif + + waitpid (fork_pid, &status, 0); + } + /* else if (fork_pid == (pid_t) -1) + * Fork failed! + * Just continue, maybe the backtrace() API will succeed. + */ + +#ifdef HAVE_EXECINFO_H + if (! stack_printed) + { + /* As a last resort, try using the backtrace() Linux API. It is a bit + * less fancy than gdb or lldb, which is why it is not given priority. + */ + void *bt_buf[100]; + int n_symbols; + + n_symbols = backtrace (bt_buf, 100); + if (trace && n_symbols) + { + char **symbols; + int i; + + symbols = backtrace_symbols (bt_buf, n_symbols); + if (symbols) + { + for (i = 0; i < n_symbols; i++) + { + if (stream) + g_fprintf (stream, "%s\n", (const gchar *) symbols[i]); + if (trace) + { + if (! gtrace) + gtrace = g_string_new (NULL); + g_string_append (gtrace, + (const gchar *) symbols[i]); + g_string_append_c (gtrace, '\n'); + } + } + free (symbols); + } + } + else if (n_symbols) + { + /* This allows to generate traces without memory allocation. + * In some cases, this is necessary, especially during + * segfault-type crashes. + */ + backtrace_symbols_fd (bt_buf, n_symbols, fileno ((FILE *) stream)); + } + stack_printed = (n_symbols > 0); + } +#endif /* HAVE_EXECINFO_H */ + + if (trace) + { + if (gtrace) + *trace = g_string_free (gtrace, FALSE); + else + *trace = NULL; + } +#endif /* G_OS_WIN32 */ + + return stack_printed; +} + +/** + * gimp_stack_trace_query: + * @prog_name: the program to attach to. + * + * This is mostly the same as g_on_error_query() except that we use our + * own backtrace function, much more complete. + * @prog_name must be the current program name (argv[0]). + * It does nothing on Win32. + * + * Since: 2.10 + **/ +void +gimp_stack_trace_query (const gchar *prog_name) +{ +#ifndef G_OS_WIN32 + gchar buf[16]; + + retry: + + g_fprintf (stdout, + "%s (pid:%u): %s: ", + prog_name, + (guint) getpid (), + "[E]xit, show [S]tack trace or [P]roceed"); + fflush (stdout); + + if (isatty(0) && isatty(1)) + fgets (buf, 8, stdin); + else + strcpy (buf, "E\n"); + + if ((buf[0] == 'E' || buf[0] == 'e') + && buf[1] == '\n') + _exit (0); + else if ((buf[0] == 'P' || buf[0] == 'p') + && buf[1] == '\n') + return; + else if ((buf[0] == 'S' || buf[0] == 's') + && buf[1] == '\n') + { + if (! gimp_stack_trace_print (prog_name, stdout, NULL)) + g_fprintf (stderr, "%s\n", "Stack trace not available on your system."); + goto retry; + } + else + goto retry; +#endif +} + + +/* Private functions. */ + +static gboolean +gimp_utils_generic_available (const gchar *program, + gint major, + gint minor) +{ +#ifndef G_OS_WIN32 + pid_t pid; + int out_fd[2]; + + if (pipe (out_fd) == -1) + { + return FALSE; + } + + /* XXX: I don't use g_spawn_sync() or similar glib functions because + * to read the contents of the stdout, these functions would allocate + * memory dynamically. As we know, when debugging crashes, this is a + * definite blocker. So instead I simply use a buffer on the stack + * with a lower level fork() call. + */ + pid = fork (); + if (pid == 0) + { + /* Child process. */ + gchar *args[3] = { (gchar *) program, "--version", NULL }; + + /* Redirect the debugger output. */ + dup2 (out_fd[1], STDOUT_FILENO); + close (out_fd[0]); + close (out_fd[1]); + + /* Run version check. */ + execvp (args[0], args); + _exit (-1); + } + else if (pid > 0) + { + /* Main process */ + gchar buffer[256]; + ssize_t read_n; + int status; + gint installed_major = 0; + gint installed_minor = 0; + gboolean major_reading = FALSE; + gboolean minor_reading = FALSE; + gint i; + gchar c; + + waitpid (pid, &status, 0); + + if (! WIFEXITED (status) || WEXITSTATUS (status) != 0) + return FALSE; + + /* It is important to close the writing side of the pipe, otherwise + * the read() will wait forever without getting the information that + * writing is finished. + */ + close (out_fd[1]); + + /* I could loop forever until EOL, but I am pretty sure the + * version information is stored on the first line and one call to + * read() with 256 characters should be more than enough. + */ + read_n = read (out_fd[0], buffer, 256); + + /* This is quite a very stupid parser. I only look for the first + * numbers and consider them as version information. This works + * fine for both GDB and LLDB as far as I can see for the output + * of `${program} --version` but this should obviously not be + * considered as a *really* generic version test. + */ + for (i = 0; i < read_n; i++) + { + c = buffer[i]; + if (c >= '0' && c <= '9') + { + if (minor_reading) + { + installed_minor = 10 * installed_minor + (c - '0'); + } + else + { + major_reading = TRUE; + installed_major = 10 * installed_major + (c - '0'); + } + } + else if (c == '.') + { + if (major_reading) + { + minor_reading = TRUE; + major_reading = FALSE; + } + else if (minor_reading) + { + break; + } + } + else if (c == '\n') + { + /* Version information should be in the first line. */ + break; + } + } + close (out_fd[0]); + + return (installed_major > 0 && + (installed_major > major || + (installed_major == major && installed_minor >= minor))); + } +#endif + + /* Fork failed, or Win32. */ + return FALSE; +} + +static gboolean +gimp_utils_gdb_available (gint major, + gint minor) +{ + return gimp_utils_generic_available ("gdb", major, minor); +} diff --git a/libgimpbase/gimputils.h b/libgimpbase/gimputils.h new file mode 100644 index 0000000..ca7b730 --- /dev/null +++ b/libgimpbase/gimputils.h @@ -0,0 +1,87 @@ +/* LIBGIMP - The GIMP Library + * Copyright (C) 1995-1997 Peter Mattis and Spencer Kimball + * + * This library is free software: you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This library 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see + * <https://www.gnu.org/licenses/>. + */ + +#if !defined (__GIMP_BASE_H_INSIDE__) && !defined (GIMP_BASE_COMPILATION) +#error "Only <libgimpbase/gimpbase.h> can be included directly." +#endif + +#ifndef __GIMP_UTILS_H__ +#define __GIMP_UTILS_H__ + +G_BEGIN_DECLS + + +gchar * gimp_utf8_strtrim (const gchar *str, + gint max_chars) G_GNUC_MALLOC; +gchar * gimp_any_to_utf8 (const gchar *str, + gssize len, + const gchar *warning_format, + ...) G_GNUC_PRINTF (3, 4) G_GNUC_MALLOC; +const gchar * gimp_filename_to_utf8 (const gchar *filename); + +const gchar * gimp_file_get_utf8_name (GFile *file); +gboolean gimp_file_has_extension (GFile *file, + const gchar *extension); +gboolean gimp_file_show_in_file_manager (GFile *file, + GError **error); + +gchar * gimp_strip_uline (const gchar *str) G_GNUC_MALLOC; +gchar * gimp_escape_uline (const gchar *str) G_GNUC_MALLOC; + +gchar * gimp_canonicalize_identifier (const gchar *identifier) G_GNUC_MALLOC; + +GimpEnumDesc * gimp_enum_get_desc (GEnumClass *enum_class, + gint value); +gboolean gimp_enum_get_value (GType enum_type, + gint value, + const gchar **value_name, + const gchar **value_nick, + const gchar **value_desc, + const gchar **value_help); +const gchar * gimp_enum_value_get_desc (GEnumClass *enum_class, + GEnumValue *enum_value); +const gchar * gimp_enum_value_get_help (GEnumClass *enum_class, + GEnumValue *enum_value); +const gchar * gimp_enum_value_get_abbrev (GEnumClass *enum_class, + GEnumValue *enum_value); + +GimpFlagsDesc * gimp_flags_get_first_desc (GFlagsClass *flags_class, + guint value); +gboolean gimp_flags_get_first_value (GType flags_type, + guint value, + const gchar **value_name, + const gchar **value_nick, + const gchar **value_desc, + const gchar **value_help); +const gchar * gimp_flags_value_get_desc (GFlagsClass *flags_class, + GFlagsValue *flags_value); +const gchar * gimp_flags_value_get_help (GFlagsClass *flags_class, + GFlagsValue *flags_value); +const gchar * gimp_flags_value_get_abbrev (GFlagsClass *flags_class, + GFlagsValue *flags_value); + +gboolean gimp_stack_trace_available (gboolean optimal); +gboolean gimp_stack_trace_print (const gchar *prog_name, + gpointer stream, + gchar **trace); +void gimp_stack_trace_query (const gchar *prog_name); + + +G_END_DECLS + +#endif /* __GIMP_UTILS_H__ */ diff --git a/libgimpbase/gimpvaluearray.c b/libgimpbase/gimpvaluearray.c new file mode 100644 index 0000000..eb23b82 --- /dev/null +++ b/libgimpbase/gimpvaluearray.c @@ -0,0 +1,589 @@ +/* LIBGIMP - The GIMP Library + * Copyright (C) 1995-1997 Peter Mattis and Spencer Kimball + * + * gimpvaluearray.c ported from GValueArray + * + * This library is free software: you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This library 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see + * <https://www.gnu.org/licenses/>. + */ + +#include "config.h" + +#include <string.h> + +#include <glib-object.h> + +#include "gimpbasetypes.h" + +#include "gimpvaluearray.h" + + +/** + * SECTION:gimpvaluearray + * @short_description: A container structure to maintain an array of + * generic values + * @see_also: #GValue, #GParamSpecValueArray, gimp_param_spec_value_array() + * @title: GimpValueArray + * + * The prime purpose of a #GimpValueArray is for it to be used as an + * object property that holds an array of values. A #GimpValueArray wraps + * an array of #GValue elements in order for it to be used as a boxed + * type through %GIMP_TYPE_VALUE_ARRAY. + */ + + +#define GROUP_N_VALUES (1) /* power of 2 !! */ + + +/** + * GimpValueArray: + * + * A #GimpValueArray contains an array of #GValue elements. + * + * Since: 2.10 + */ +struct _GimpValueArray +{ + gint n_values; + GValue *values; + + gint n_prealloced; + gint ref_count; +}; + + +G_DEFINE_BOXED_TYPE (GimpValueArray, gimp_value_array, + gimp_value_array_ref, gimp_value_array_unref) + + +/** + * gimp_value_array_index: + * @value_array: #GimpValueArray to get a value from + * @index: index of the value of interest + * + * Return a pointer to the value at @index contained in @value_array. + * + * Returns: (transfer none): pointer to a value at @index in @value_array + * + * Since: 2.10 + */ +GValue * +gimp_value_array_index (const GimpValueArray *value_array, + gint index) +{ + g_return_val_if_fail (value_array != NULL, NULL); + g_return_val_if_fail (index < value_array->n_values, NULL); + + return value_array->values + index; +} + +static inline void +value_array_grow (GimpValueArray *value_array, + gint n_values, + gboolean zero_init) +{ + g_return_if_fail ((guint) n_values >= (guint) value_array->n_values); + + value_array->n_values = n_values; + if (value_array->n_values > value_array->n_prealloced) + { + gint i = value_array->n_prealloced; + + value_array->n_prealloced = (value_array->n_values + GROUP_N_VALUES - 1) & ~(GROUP_N_VALUES - 1); + value_array->values = g_renew (GValue, value_array->values, value_array->n_prealloced); + + if (!zero_init) + i = value_array->n_values; + + memset (value_array->values + i, 0, + (value_array->n_prealloced - i) * sizeof (value_array->values[0])); + } +} + +static inline void +value_array_shrink (GimpValueArray *value_array) +{ + if (value_array->n_prealloced >= value_array->n_values + GROUP_N_VALUES) + { + value_array->n_prealloced = (value_array->n_values + GROUP_N_VALUES - 1) & ~(GROUP_N_VALUES - 1); + value_array->values = g_renew (GValue, value_array->values, value_array->n_prealloced); + } +} + +/** + * gimp_value_array_new: + * @n_prealloced: number of values to preallocate space for + * + * Allocate and initialize a new #GimpValueArray, optionally preserve space + * for @n_prealloced elements. New arrays always contain 0 elements, + * regardless of the value of @n_prealloced. + * + * Returns: a newly allocated #GimpValueArray with 0 values + * + * Since: 2.10 + */ +GimpValueArray * +gimp_value_array_new (gint n_prealloced) +{ + GimpValueArray *value_array = g_slice_new (GimpValueArray); + + value_array->n_values = 0; + value_array->n_prealloced = 0; + value_array->values = NULL; + value_array_grow (value_array, n_prealloced, TRUE); + value_array->n_values = 0; + value_array->ref_count = 1; + + return value_array; +} + +/** + * gimp_value_array_ref: + * @value_array: #GimpValueArray to ref + * + * Adds a reference to a #GimpValueArray. + * + * Return value: the same @value_array + * + * Since: 2.10 + */ +GimpValueArray * +gimp_value_array_ref (GimpValueArray *value_array) +{ + g_return_val_if_fail (value_array != NULL, NULL); + + value_array->ref_count++; + + return value_array; +} + +/** + * gimp_value_array_unref: + * @value_array: #GimpValueArray to unref + * + * Unref a #GimpValueArray. If the reference count drops to zero, the + * array including its contents are freed. + * + * Since: 2.10 + */ +void +gimp_value_array_unref (GimpValueArray *value_array) +{ + g_return_if_fail (value_array != NULL); + + value_array->ref_count--; + + if (value_array->ref_count < 1) + { + gint i; + + for (i = 0; i < value_array->n_values; i++) + { + GValue *value = value_array->values + i; + + if (G_VALUE_TYPE (value) != 0) /* we allow unset values in the array */ + g_value_unset (value); + } + + g_free (value_array->values); + g_slice_free (GimpValueArray, value_array); + } +} + +gint +gimp_value_array_length (const GimpValueArray *value_array) +{ + g_return_val_if_fail (value_array != NULL, 0); + + return value_array->n_values; +} + +/** + * gimp_value_array_prepend: + * @value_array: #GimpValueArray to add an element to + * @value: (allow-none): #GValue to copy into #GimpValueArray, or %NULL + * + * Insert a copy of @value as first element of @value_array. If @value is + * %NULL, an uninitialized value is prepended. + * + * Returns: (transfer none): the #GimpValueArray passed in as @value_array + * + * Since: 2.10 + */ +GimpValueArray * +gimp_value_array_prepend (GimpValueArray *value_array, + const GValue *value) +{ + g_return_val_if_fail (value_array != NULL, NULL); + + return gimp_value_array_insert (value_array, 0, value); +} + +/** + * gimp_value_array_append: + * @value_array: #GimpValueArray to add an element to + * @value: (allow-none): #GValue to copy into #GimpValueArray, or %NULL + * + * Insert a copy of @value as last element of @value_array. If @value is + * %NULL, an uninitialized value is appended. + * + * Returns: (transfer none): the #GimpValueArray passed in as @value_array + * + * Since: 2.10 + */ +GimpValueArray * +gimp_value_array_append (GimpValueArray *value_array, + const GValue *value) +{ + g_return_val_if_fail (value_array != NULL, NULL); + + return gimp_value_array_insert (value_array, value_array->n_values, value); +} + +/** + * gimp_value_array_insert: + * @value_array: #GimpValueArray to add an element to + * @index: insertion position, must be <= gimp_value_array_length() + * @value: (allow-none): #GValue to copy into #GimpValueArray, or %NULL + * + * Insert a copy of @value at specified position into @value_array. If @value + * is %NULL, an uninitialized value is inserted. + * + * Returns: (transfer none): the #GimpValueArray passed in as @value_array + * + * Since: 2.10 + */ +GimpValueArray * +gimp_value_array_insert (GimpValueArray *value_array, + gint index, + const GValue *value) +{ + gint i; + + g_return_val_if_fail (value_array != NULL, NULL); + g_return_val_if_fail (index <= value_array->n_values, value_array); + + i = value_array->n_values; + value_array_grow (value_array, value_array->n_values + 1, FALSE); + + if (index + 1 < value_array->n_values) + memmove (value_array->values + index + 1, value_array->values + index, + (i - index) * sizeof (value_array->values[0])); + + memset (value_array->values + index, 0, sizeof (value_array->values[0])); + + if (value) + { + g_value_init (value_array->values + index, G_VALUE_TYPE (value)); + g_value_copy (value, value_array->values + index); + } + + return value_array; +} + +/** + * gimp_value_array_remove: + * @value_array: #GimpValueArray to remove an element from + * @index: position of value to remove, which must be less than + * gimp_value_array_length() + * + * Remove the value at position @index from @value_array. + * + * Returns: (transfer none): the #GimpValueArray passed in as @value_array + * + * Since: 2.10 + */ +GimpValueArray * +gimp_value_array_remove (GimpValueArray *value_array, + gint index) +{ + g_return_val_if_fail (value_array != NULL, NULL); + g_return_val_if_fail (index < value_array->n_values, value_array); + + if (G_VALUE_TYPE (value_array->values + index) != 0) + g_value_unset (value_array->values + index); + + value_array->n_values--; + + if (index < value_array->n_values) + memmove (value_array->values + index, value_array->values + index + 1, + (value_array->n_values - index) * sizeof (value_array->values[0])); + + value_array_shrink (value_array); + + if (value_array->n_prealloced > value_array->n_values) + memset (value_array->values + value_array->n_values, 0, sizeof (value_array->values[0])); + + return value_array; +} + +void +gimp_value_array_truncate (GimpValueArray *value_array, + gint n_values) +{ + gint i; + + g_return_if_fail (value_array != NULL); + g_return_if_fail (n_values > 0 && n_values <= value_array->n_values); + + for (i = value_array->n_values; i > n_values; i--) + gimp_value_array_remove (value_array, i - 1); +} + + +/* + * GIMP_TYPE_PARAM_VALUE_ARRAY + */ + +static void gimp_param_value_array_class_init (GParamSpecClass *klass); +static void gimp_param_value_array_init (GParamSpec *pspec); +static void gimp_param_value_array_finalize (GParamSpec *pspec); +static void gimp_param_value_array_set_default (GParamSpec *pspec, + GValue *value); +static gboolean gimp_param_value_array_validate (GParamSpec *pspec, + GValue *value); +static gint gimp_param_value_array_values_cmp (GParamSpec *pspec, + const GValue *value1, + const GValue *value2); + +GType +gimp_param_value_array_get_type (void) +{ + static GType type = 0; + + if (! type) + { + const GTypeInfo info = + { + sizeof (GParamSpecClass), + NULL, NULL, + (GClassInitFunc) gimp_param_value_array_class_init, + NULL, NULL, + sizeof (GimpParamSpecValueArray), + 0, + (GInstanceInitFunc) gimp_param_value_array_init + }; + + type = g_type_register_static (G_TYPE_PARAM_BOXED, + "GimpParamValueArray", &info, 0); + } + + return type; +} + + +static void +gimp_param_value_array_class_init (GParamSpecClass *klass) +{ + klass->value_type = GIMP_TYPE_VALUE_ARRAY; + klass->finalize = gimp_param_value_array_finalize; + klass->value_set_default = gimp_param_value_array_set_default; + klass->value_validate = gimp_param_value_array_validate; + klass->values_cmp = gimp_param_value_array_values_cmp; +} + +static void +gimp_param_value_array_init (GParamSpec *pspec) +{ + GimpParamSpecValueArray *aspec = GIMP_PARAM_SPEC_VALUE_ARRAY (pspec); + + aspec->element_spec = NULL; + aspec->fixed_n_elements = 0; /* disable */ +} + +static inline guint +gimp_value_array_ensure_size (GimpValueArray *value_array, + guint fixed_n_elements) +{ + guint changed = 0; + + if (fixed_n_elements) + { + while (gimp_value_array_length (value_array) < fixed_n_elements) + { + gimp_value_array_append (value_array, NULL); + changed++; + } + + while (gimp_value_array_length (value_array) > fixed_n_elements) + { + gimp_value_array_remove (value_array, + gimp_value_array_length (value_array) - 1); + changed++; + } + } + + return changed; +} + +static void +gimp_param_value_array_finalize (GParamSpec *pspec) +{ + GimpParamSpecValueArray *aspec = GIMP_PARAM_SPEC_VALUE_ARRAY (pspec); + GParamSpecClass *parent_class; + + parent_class = g_type_class_peek (g_type_parent (GIMP_TYPE_PARAM_VALUE_ARRAY)); + + g_clear_pointer (&aspec->element_spec, g_param_spec_unref); + + parent_class->finalize (pspec); +} + +static void +gimp_param_value_array_set_default (GParamSpec *pspec, + GValue *value) +{ + GimpParamSpecValueArray *aspec = GIMP_PARAM_SPEC_VALUE_ARRAY (pspec); + + if (! value->data[0].v_pointer && aspec->fixed_n_elements) + value->data[0].v_pointer = gimp_value_array_new (aspec->fixed_n_elements); + + if (value->data[0].v_pointer) + { + /* g_value_reset (value); already done */ + gimp_value_array_ensure_size (value->data[0].v_pointer, + aspec->fixed_n_elements); + } +} + +static gboolean +gimp_param_value_array_validate (GParamSpec *pspec, + GValue *value) +{ + GimpParamSpecValueArray *aspec = GIMP_PARAM_SPEC_VALUE_ARRAY (pspec); + GimpValueArray *value_array = value->data[0].v_pointer; + guint changed = 0; + + if (! value->data[0].v_pointer && aspec->fixed_n_elements) + value->data[0].v_pointer = gimp_value_array_new (aspec->fixed_n_elements); + + if (value->data[0].v_pointer) + { + /* ensure array size validity */ + changed += gimp_value_array_ensure_size (value_array, + aspec->fixed_n_elements); + + /* ensure array values validity against a present element spec */ + if (aspec->element_spec) + { + GParamSpec *element_spec = aspec->element_spec; + gint length = gimp_value_array_length (value_array); + gint i; + + for (i = 0; i < length; i++) + { + GValue *element = gimp_value_array_index (value_array, i); + + /* need to fixup value type, or ensure that the array + * value is initialized at all + */ + if (! g_value_type_compatible (G_VALUE_TYPE (element), + G_PARAM_SPEC_VALUE_TYPE (element_spec))) + { + if (G_VALUE_TYPE (element) != 0) + g_value_unset (element); + + g_value_init (element, G_PARAM_SPEC_VALUE_TYPE (element_spec)); + g_param_value_set_default (element_spec, element); + changed++; + } + + /* validate array value against element_spec */ + changed += g_param_value_validate (element_spec, element); + } + } + } + + return changed; +} + +static gint +gimp_param_value_array_values_cmp (GParamSpec *pspec, + const GValue *value1, + const GValue *value2) +{ + GimpParamSpecValueArray *aspec = GIMP_PARAM_SPEC_VALUE_ARRAY (pspec); + GimpValueArray *value_array1 = value1->data[0].v_pointer; + GimpValueArray *value_array2 = value2->data[0].v_pointer; + gint length1; + gint length2; + + if (!value_array1 || !value_array2) + return value_array2 ? -1 : value_array1 != value_array2; + + length1 = gimp_value_array_length (value_array1); + length2 = gimp_value_array_length (value_array2); + + if (length1 != length2) + { + return length1 < length2 ? -1 : 1; + } + else if (! aspec->element_spec) + { + /* we need an element specification for comparisons, so there's + * not much to compare here, try to at least provide stable + * lesser/greater result + */ + return length1 < length2 ? -1 : length1 > length2; + } + else /* length1 == length2 */ + { + guint i; + + for (i = 0; i < length1; i++) + { + GValue *element1 = gimp_value_array_index (value_array1, i); + GValue *element2 = gimp_value_array_index (value_array2, i); + gint cmp; + + /* need corresponding element types, provide stable result + * otherwise + */ + if (G_VALUE_TYPE (element1) != G_VALUE_TYPE (element2)) + return G_VALUE_TYPE (element1) < G_VALUE_TYPE (element2) ? -1 : 1; + + cmp = g_param_values_cmp (aspec->element_spec, element1, element2); + if (cmp) + return cmp; + } + + return 0; + } +} + +GParamSpec * +gimp_param_spec_value_array (const gchar *name, + const gchar *nick, + const gchar *blurb, + GParamSpec *element_spec, + GParamFlags flags) +{ + GimpParamSpecValueArray *aspec; + + if (element_spec) + g_return_val_if_fail (G_IS_PARAM_SPEC (element_spec), NULL); + + aspec = g_param_spec_internal (GIMP_TYPE_PARAM_VALUE_ARRAY, + name, + nick, + blurb, + flags); + if (element_spec) + { + aspec->element_spec = g_param_spec_ref (element_spec); + g_param_spec_sink (element_spec); + } + + return G_PARAM_SPEC (aspec); +} diff --git a/libgimpbase/gimpvaluearray.h b/libgimpbase/gimpvaluearray.h new file mode 100644 index 0000000..d7aefcb --- /dev/null +++ b/libgimpbase/gimpvaluearray.h @@ -0,0 +1,104 @@ +/* LIBGIMP - The GIMP Library + * Copyright (C) 1995-1997 Peter Mattis and Spencer Kimball + * + * gimpvaluearray.h ported from GValueArray + * + * This library is free software: you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This library 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see + * <https://www.gnu.org/licenses/>. + */ + +#if !defined (__GIMP_BASE_H_INSIDE__) && !defined (GIMP_BASE_COMPILATION) +#error "Only <libgimpbase/gimpbase.h> can be included directly." +#endif + +#ifndef __GIMP_VALUE_ARRAY_H__ +#define __GIMP_VALUE_ARRAY_H__ + +G_BEGIN_DECLS + +/** + * GIMP_TYPE_VALUE_ARRAY: + * + * The type ID of the "GimpValueArray" type which is a boxed type, + * used to pass around pointers to GimpValueArrays. + * + * Since: 2.10 + */ +#define GIMP_TYPE_VALUE_ARRAY (gimp_value_array_get_type ()) + + +GType gimp_value_array_get_type (void) G_GNUC_CONST; + +GimpValueArray * gimp_value_array_new (gint n_prealloced); + +GimpValueArray * gimp_value_array_ref (GimpValueArray *value_array); +void gimp_value_array_unref (GimpValueArray *value_array); + +gint gimp_value_array_length (const GimpValueArray *value_array); + +GValue * gimp_value_array_index (const GimpValueArray *value_array, + gint index); + +GimpValueArray * gimp_value_array_prepend (GimpValueArray *value_array, + const GValue *value); +GimpValueArray * gimp_value_array_append (GimpValueArray *value_array, + const GValue *value); +GimpValueArray * gimp_value_array_insert (GimpValueArray *value_array, + gint index, + const GValue *value); + +GimpValueArray * gimp_value_array_remove (GimpValueArray *value_array, + gint index); +void gimp_value_array_truncate (GimpValueArray *value_array, + gint n_values); + + +/* + * GIMP_TYPE_PARAM_VALUE_ARRAY + */ + +#define GIMP_TYPE_PARAM_VALUE_ARRAY (gimp_param_value_array_get_type ()) +#define GIMP_IS_PARAM_SPEC_VALUE_ARRAY(pspec) (G_TYPE_CHECK_INSTANCE_TYPE ((pspec), GIMP_TYPE_PARAM_VALUE_ARRAY)) +#define GIMP_PARAM_SPEC_VALUE_ARRAY(pspec) (G_TYPE_CHECK_INSTANCE_CAST ((pspec), GIMP_TYPE_PARAM_VALUE_ARRAY, GimpParamSpecValueArray)) + +typedef struct _GimpParamSpecValueArray GimpParamSpecValueArray; + +/** + * GimpParamSpecValueArray: + * @parent_instance: private #GParamSpec portion + * @element_spec: the #GParamSpec of the array elements + * @fixed_n_elements: default length of the array + * + * A #GParamSpec derived structure that contains the meta data for + * value array properties. + **/ +struct _GimpParamSpecValueArray +{ + GParamSpec parent_instance; + GParamSpec *element_spec; + gint fixed_n_elements; +}; + +GType gimp_param_value_array_get_type (void) G_GNUC_CONST; + +GParamSpec * gimp_param_spec_value_array (const gchar *name, + const gchar *nick, + const gchar *blurb, + GParamSpec *element_spec, + GParamFlags flags); + + +G_END_DECLS + +#endif /* __GIMP_VALUE_ARRAY_H__ */ diff --git a/libgimpbase/gimpversion.h b/libgimpbase/gimpversion.h new file mode 100644 index 0000000..5d6c163 --- /dev/null +++ b/libgimpbase/gimpversion.h @@ -0,0 +1,70 @@ +/* gimpversion.h + * + * This is a generated file. Please modify 'configure.ac' + */ + +#if !defined (__GIMP_BASE_H_INSIDE__) && !defined (GIMP_BASE_COMPILATION) +#error "Only <libgimpbase/gimpbase.h> can be included directly." +#endif + +#ifndef __GIMP_VERSION_H__ +#define __GIMP_VERSION_H__ + +G_BEGIN_DECLS + + +/** + * SECTION: gimpversion + * @title: gimpversion + * @short_description: Macros and constants useful for determining + * GIMP's version number and capabilities. + * + * Macros and constants useful for determining GIMP's version number and + * capabilities. + **/ + +/** + * GIMP_MAJOR_VERSION: + * + * The major GIMP version number. + **/ +#define GIMP_MAJOR_VERSION (2) + +/** + * GIMP_MINOR_VERSION: + * + * The minor GIMP version number. + **/ +#define GIMP_MINOR_VERSION (10) + +/** + * GIMP_MICRO_VERSION: + * + * The micro GIMP version number. + **/ +#define GIMP_MICRO_VERSION (36) + +/** + * GIMP_VERSION: + * + * The GIMP version as a string. + **/ +#define GIMP_VERSION "2.10.36" + +/** + * GIMP_API_VERSION: + * + * Since: 2.2 + **/ +#define GIMP_API_VERSION "2.0" + +#define GIMP_CHECK_VERSION(major, minor, micro) \ + (GIMP_MAJOR_VERSION > (major) || \ + (GIMP_MAJOR_VERSION == (major) && GIMP_MINOR_VERSION > (minor)) || \ + (GIMP_MAJOR_VERSION == (major) && GIMP_MINOR_VERSION == (minor) && \ + GIMP_MICRO_VERSION >= (micro))) + + +G_END_DECLS + +#endif /* __GIMP_VERSION_H__ */ diff --git a/libgimpbase/gimpwin32-io.h b/libgimpbase/gimpwin32-io.h new file mode 100644 index 0000000..45a3104 --- /dev/null +++ b/libgimpbase/gimpwin32-io.h @@ -0,0 +1,99 @@ +/* LIBGIMP - The GIMP Library + * Copyright (C) 1995-1997 Peter Mattis and Spencer Kimball + * + * gimpwin32-io.h + * Compatibility defines, you mostly need this as unistd.h replacement + * + * This library is free software: you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This library 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see + * <https://www.gnu.org/licenses/>. + */ + +#ifndef __GIMP_WIN32_IO_H__ +#define __GIMP_WIN32_IO_H__ + +#include <io.h> +#include <direct.h> + +G_BEGIN_DECLS + + +#define mkdir(n,a) _mkdir(n) +#define chmod(n,f) _chmod(n,f) +#define access(f,p) _access(f,p) + +#ifndef S_ISREG +#define S_ISREG(m) (((m) & _S_IFMT) == _S_IFREG) +#endif +#ifndef S_ISDIR +#define S_ISDIR(m) (((m) & _S_IFMT) == _S_IFDIR) +#endif + +#ifndef S_IRUSR +#define S_IRUSR _S_IREAD +#endif +#ifndef S_IWUSR +#define S_IWUSR _S_IWRITE +#endif +#ifndef S_IXUSR +#define S_IXUSR _S_IEXEC +#endif + +#ifndef S_IRGRP +#define S_IRGRP _S_IREAD +#endif +#ifndef S_IXGRP +#define S_IXGRP _S_IEXEC +#endif +#ifndef S_IROTH +#define S_IROTH _S_IREAD +#endif +#ifndef S_IXOTH +#define S_IXOTH _S_IEXEC +#endif + +#ifndef _O_BINARY +#define _O_BINARY 0 +#endif +#ifndef _O_TEMPORARY +#define _O_TEMPORARY 0 +#endif + +#ifndef F_OK +#define F_OK 0 +#endif +#ifndef W_OK +#define W_OK 2 +#endif +#ifndef R_OK +#define R_OK 4 +#endif +#ifndef X_OK +#define X_OK 0 /* not really */ +#endif + +/* +2004-09-15 Tor Lillqvist <tml@iki.fi> + + * glib/gwin32.h: Don't define ftruncate as a macro. Was never a + good idea, and it clashes with newest mingw headers, which have a + ftruncate implementation as an inline function. Thanks to Dominik R. + */ +/* needs coorection for msvc though ;( */ +#ifdef _MSC_VER +#define ftruncate(f,s) g_win32_ftruncate(f,s) +#endif + +G_END_DECLS + +#endif /* __GIMP_WIN32_IO_H__ */ diff --git a/libgimpbase/gimpwire.c b/libgimpbase/gimpwire.c new file mode 100644 index 0000000..9382bee --- /dev/null +++ b/libgimpbase/gimpwire.c @@ -0,0 +1,695 @@ +/* LIBGIMP - The GIMP Library + * Copyright (C) 1995-1997 Peter Mattis and Spencer Kimball + * + * This library is free software: you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This library 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see + * <https://www.gnu.org/licenses/>. + */ + +#include "config.h" + +#include <string.h> + +#include <glib-object.h> + +#include <libgimpcolor/gimpcolortypes.h> + +#include "gimpwire.h" + + +typedef struct _GimpWireHandler GimpWireHandler; + +struct _GimpWireHandler +{ + guint32 type; + GimpWireReadFunc read_func; + GimpWireWriteFunc write_func; + GimpWireDestroyFunc destroy_func; +}; + + +static GHashTable *wire_ht = NULL; +static GimpWireIOFunc wire_read_func = NULL; +static GimpWireIOFunc wire_write_func = NULL; +static GimpWireFlushFunc wire_flush_func = NULL; +static gboolean wire_error_val = FALSE; + + +static void gimp_wire_init (void); + + +void +gimp_wire_register (guint32 type, + GimpWireReadFunc read_func, + GimpWireWriteFunc write_func, + GimpWireDestroyFunc destroy_func) +{ + GimpWireHandler *handler; + + if (! wire_ht) + gimp_wire_init (); + + handler = g_hash_table_lookup (wire_ht, &type); + + if (! handler) + handler = g_slice_new0 (GimpWireHandler); + + handler->type = type; + handler->read_func = read_func; + handler->write_func = write_func; + handler->destroy_func = destroy_func; + + g_hash_table_insert (wire_ht, &handler->type, handler); +} + +void +gimp_wire_set_reader (GimpWireIOFunc read_func) +{ + wire_read_func = read_func; +} + +void +gimp_wire_set_writer (GimpWireIOFunc write_func) +{ + wire_write_func = write_func; +} + +void +gimp_wire_set_flusher (GimpWireFlushFunc flush_func) +{ + wire_flush_func = flush_func; +} + +gboolean +gimp_wire_read (GIOChannel *channel, + guint8 *buf, + gsize count, + gpointer user_data) +{ + if (wire_read_func) + { + if (!(* wire_read_func) (channel, buf, count, user_data)) + { + /* Gives a confusing error message most of the time, disable: + g_warning ("%s: gimp_wire_read: error", g_get_prgname ()); + */ + wire_error_val = TRUE; + return FALSE; + } + } + else + { + GIOStatus status; + GError *error = NULL; + gsize bytes; + + while (count > 0) + { + do + { + bytes = 0; + status = g_io_channel_read_chars (channel, + (gchar *) buf, count, + &bytes, + &error); + } + while (G_UNLIKELY (status == G_IO_STATUS_AGAIN)); + + if (G_UNLIKELY (status != G_IO_STATUS_NORMAL)) + { + if (error) + { + g_warning ("%s: gimp_wire_read(): error: %s", + g_get_prgname (), error->message); + g_error_free (error); + } + else + { + g_warning ("%s: gimp_wire_read(): error", + g_get_prgname ()); + } + + wire_error_val = TRUE; + return FALSE; + } + + if (G_UNLIKELY (bytes == 0)) + { + g_warning ("%s: gimp_wire_read(): unexpected EOF", + g_get_prgname ()); + wire_error_val = TRUE; + return FALSE; + } + + count -= bytes; + buf += bytes; + } + } + + return TRUE; +} + +gboolean +gimp_wire_write (GIOChannel *channel, + const guint8 *buf, + gsize count, + gpointer user_data) +{ + if (wire_write_func) + { + if (!(* wire_write_func) (channel, (guint8 *) buf, count, user_data)) + { + g_warning ("%s: gimp_wire_write: error", g_get_prgname ()); + wire_error_val = TRUE; + return FALSE; + } + } + else + { + GIOStatus status; + GError *error = NULL; + gsize bytes; + + while (count > 0) + { + do + { + bytes = 0; + status = g_io_channel_write_chars (channel, + (const gchar *) buf, count, + &bytes, + &error); + } + while (G_UNLIKELY (status == G_IO_STATUS_AGAIN)); + + if (G_UNLIKELY (status != G_IO_STATUS_NORMAL)) + { + if (error) + { + g_warning ("%s: gimp_wire_write(): error: %s", + g_get_prgname (), error->message); + g_error_free (error); + } + else + { + g_warning ("%s: gimp_wire_write(): error", + g_get_prgname ()); + } + + wire_error_val = TRUE; + return FALSE; + } + + count -= bytes; + buf += bytes; + } + } + + return TRUE; +} + +gboolean +gimp_wire_flush (GIOChannel *channel, + gpointer user_data) +{ + if (wire_flush_func) + return (* wire_flush_func) (channel, user_data); + + return FALSE; +} + +gboolean +gimp_wire_error (void) +{ + return wire_error_val; +} + +void +gimp_wire_clear_error (void) +{ + wire_error_val = FALSE; +} + +gboolean +gimp_wire_read_msg (GIOChannel *channel, + GimpWireMessage *msg, + gpointer user_data) +{ + GimpWireHandler *handler; + + if (G_UNLIKELY (! wire_ht)) + g_error ("gimp_wire_read_msg: the wire protocol has not been initialized"); + + if (wire_error_val) + return !wire_error_val; + + if (! _gimp_wire_read_int32 (channel, &msg->type, 1, user_data)) + return FALSE; + + handler = g_hash_table_lookup (wire_ht, &msg->type); + + if (G_UNLIKELY (! handler)) + g_error ("gimp_wire_read_msg: could not find handler for message: %d", + msg->type); + + (* handler->read_func) (channel, msg, user_data); + + return !wire_error_val; +} + +gboolean +gimp_wire_write_msg (GIOChannel *channel, + GimpWireMessage *msg, + gpointer user_data) +{ + GimpWireHandler *handler; + + if (G_UNLIKELY (! wire_ht)) + g_error ("gimp_wire_write_msg: the wire protocol has not been initialized"); + + if (wire_error_val) + return !wire_error_val; + + handler = g_hash_table_lookup (wire_ht, &msg->type); + + if (G_UNLIKELY (! handler)) + g_error ("gimp_wire_write_msg: could not find handler for message: %d", + msg->type); + + if (! _gimp_wire_write_int32 (channel, &msg->type, 1, user_data)) + return FALSE; + + (* handler->write_func) (channel, msg, user_data); + + return !wire_error_val; +} + +void +gimp_wire_destroy (GimpWireMessage *msg) +{ + GimpWireHandler *handler; + + if (G_UNLIKELY (! wire_ht)) + g_error ("gimp_wire_destroy: the wire protocol has not been initialized"); + + handler = g_hash_table_lookup (wire_ht, &msg->type); + + if (G_UNLIKELY (! handler)) + g_error ("gimp_wire_destroy: could not find handler for message: %d\n", + msg->type); + + (* handler->destroy_func) (msg); +} + +gboolean +_gimp_wire_read_int64 (GIOChannel *channel, + guint64 *data, + gint count, + gpointer user_data) +{ + g_return_val_if_fail (count >= 0, FALSE); + + if (count > 0) + { + if (! _gimp_wire_read_int8 (channel, + (guint8 *) data, count * 8, user_data)) + return FALSE; + + while (count--) + { + *data = GUINT64_FROM_BE (*data); + data++; + } + } + + return TRUE; +} + +gboolean +_gimp_wire_read_int32 (GIOChannel *channel, + guint32 *data, + gint count, + gpointer user_data) +{ + g_return_val_if_fail (count >= 0, FALSE); + + if (count > 0) + { + if (! _gimp_wire_read_int8 (channel, + (guint8 *) data, count * 4, user_data)) + return FALSE; + + while (count--) + { + *data = g_ntohl (*data); + data++; + } + } + + return TRUE; +} + +gboolean +_gimp_wire_read_int16 (GIOChannel *channel, + guint16 *data, + gint count, + gpointer user_data) +{ + g_return_val_if_fail (count >= 0, FALSE); + + if (count > 0) + { + if (! _gimp_wire_read_int8 (channel, + (guint8 *) data, count * 2, user_data)) + return FALSE; + + while (count--) + { + *data = g_ntohs (*data); + data++; + } + } + + return TRUE; +} + +gboolean +_gimp_wire_read_int8 (GIOChannel *channel, + guint8 *data, + gint count, + gpointer user_data) +{ + g_return_val_if_fail (count >= 0, FALSE); + + return gimp_wire_read (channel, data, count, user_data); +} + +gboolean +_gimp_wire_read_double (GIOChannel *channel, + gdouble *data, + gint count, + gpointer user_data) +{ + gdouble *t; + guint8 tmp[8]; + gint i; + + g_return_val_if_fail (count >= 0, FALSE); + + t = (gdouble *) tmp; + + for (i = 0; i < count; i++) + { +#if (G_BYTE_ORDER == G_LITTLE_ENDIAN) + gint j; +#endif + + if (! _gimp_wire_read_int8 (channel, tmp, 8, user_data)) + return FALSE; + +#if (G_BYTE_ORDER == G_LITTLE_ENDIAN) + for (j = 0; j < 4; j++) + { + guint8 swap; + + swap = tmp[j]; + tmp[j] = tmp[7 - j]; + tmp[7 - j] = swap; + } +#endif + + data[i] = *t; + } + + return TRUE; +} + +gboolean +_gimp_wire_read_string (GIOChannel *channel, + gchar **data, + gint count, + gpointer user_data) +{ + gint i; + + g_return_val_if_fail (count >= 0, FALSE); + + for (i = 0; i < count; i++) + { + guint32 tmp; + + if (! _gimp_wire_read_int32 (channel, &tmp, 1, user_data)) + return FALSE; + + if (tmp > 0) + { + data[i] = g_try_new (gchar, tmp); + + if (! data[i]) + { + g_printerr ("%s: failed to allocate %u bytes\n", G_STRFUNC, tmp); + return FALSE; + } + + if (! _gimp_wire_read_int8 (channel, + (guint8 *) data[i], tmp, user_data)) + { + g_free (data[i]); + return FALSE; + } + + /* make sure that the string is NULL-terminated */ + data[i][tmp - 1] = '\0'; + } + else + { + data[i] = NULL; + } + } + + return TRUE; +} + +gboolean +_gimp_wire_read_color (GIOChannel *channel, + GimpRGB *data, + gint count, + gpointer user_data) +{ + g_return_val_if_fail (count >= 0, FALSE); + + return _gimp_wire_read_double (channel, + (gdouble *) data, 4 * count, user_data); +} + +gboolean +_gimp_wire_write_int64 (GIOChannel *channel, + const guint64 *data, + gint count, + gpointer user_data) +{ + g_return_val_if_fail (count >= 0, FALSE); + + if (count > 0) + { + gint i; + + for (i = 0; i < count; i++) + { + guint64 tmp = GUINT64_TO_BE (data[i]); + + if (! _gimp_wire_write_int8 (channel, + (const guint8 *) &tmp, 8, user_data)) + return FALSE; + } + } + + return TRUE; +} + +gboolean +_gimp_wire_write_int32 (GIOChannel *channel, + const guint32 *data, + gint count, + gpointer user_data) +{ + g_return_val_if_fail (count >= 0, FALSE); + + if (count > 0) + { + gint i; + + for (i = 0; i < count; i++) + { + guint32 tmp = g_htonl (data[i]); + + if (! _gimp_wire_write_int8 (channel, + (const guint8 *) &tmp, 4, user_data)) + return FALSE; + } + } + + return TRUE; +} + +gboolean +_gimp_wire_write_int16 (GIOChannel *channel, + const guint16 *data, + gint count, + gpointer user_data) +{ + g_return_val_if_fail (count >= 0, FALSE); + + if (count > 0) + { + gint i; + + for (i = 0; i < count; i++) + { + guint16 tmp = g_htons (data[i]); + + if (! _gimp_wire_write_int8 (channel, + (const guint8 *) &tmp, 2, user_data)) + return FALSE; + } + } + + return TRUE; +} + +gboolean +_gimp_wire_write_int8 (GIOChannel *channel, + const guint8 *data, + gint count, + gpointer user_data) +{ + g_return_val_if_fail (count >= 0, FALSE); + + return gimp_wire_write (channel, data, count, user_data); +} + +gboolean +_gimp_wire_write_double (GIOChannel *channel, + const gdouble *data, + gint count, + gpointer user_data) +{ + gdouble *t; + guint8 tmp[8]; + gint i; +#if (G_BYTE_ORDER == G_LITTLE_ENDIAN) + gint j; +#endif + + g_return_val_if_fail (count >= 0, FALSE); + + t = (gdouble *) tmp; + + for (i = 0; i < count; i++) + { + *t = data[i]; + +#if (G_BYTE_ORDER == G_LITTLE_ENDIAN) + for (j = 0; j < 4; j++) + { + guint8 swap; + + swap = tmp[j]; + tmp[j] = tmp[7 - j]; + tmp[7 - j] = swap; + } +#endif + + if (! _gimp_wire_write_int8 (channel, tmp, 8, user_data)) + return FALSE; + +#if 0 + { + gint k; + + g_print ("Wire representation of %f:\t", data[i]); + + for (k = 0; k < 8; k++) + g_print ("%02x ", tmp[k]); + + g_print ("\n"); + } +#endif + } + + return TRUE; +} + +gboolean +_gimp_wire_write_string (GIOChannel *channel, + gchar **data, + gint count, + gpointer user_data) +{ + gint i; + + g_return_val_if_fail (count >= 0, FALSE); + + for (i = 0; i < count; i++) + { + guint32 tmp; + + if (data[i]) + tmp = strlen (data[i]) + 1; + else + tmp = 0; + + if (! _gimp_wire_write_int32 (channel, &tmp, 1, user_data)) + return FALSE; + + if (tmp > 0) + if (! _gimp_wire_write_int8 (channel, + (const guint8 *) data[i], tmp, user_data)) + return FALSE; + } + + return TRUE; +} + +gboolean +_gimp_wire_write_color (GIOChannel *channel, + const GimpRGB *data, + gint count, + gpointer user_data) +{ + g_return_val_if_fail (count >= 0, FALSE); + + return _gimp_wire_write_double (channel, + (gdouble *) data, 4 * count, user_data); +} + +static guint +gimp_wire_hash (const guint32 *key) +{ + return *key; +} + +static gboolean +gimp_wire_compare (const guint32 *a, + const guint32 *b) +{ + return (*a == *b); +} + +static void +gimp_wire_init (void) +{ + if (! wire_ht) + wire_ht = g_hash_table_new ((GHashFunc) gimp_wire_hash, + (GCompareFunc) gimp_wire_compare); +} diff --git a/libgimpbase/gimpwire.h b/libgimpbase/gimpwire.h new file mode 100644 index 0000000..dde69d9 --- /dev/null +++ b/libgimpbase/gimpwire.h @@ -0,0 +1,146 @@ +/* LIBGIMP - The GIMP Library + * Copyright (C) 1995-1997 Peter Mattis and Spencer Kimball + * + * This library is free software: you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see + * <https://www.gnu.org/licenses/>. + */ + +#ifndef __GIMP_WIRE_H__ +#define __GIMP_WIRE_H__ + +G_BEGIN_DECLS + +/* For information look into the C source or the html documentation */ + + +typedef struct _GimpWireMessage GimpWireMessage; + +typedef void (* GimpWireReadFunc) (GIOChannel *channel, + GimpWireMessage *msg, + gpointer user_data); +typedef void (* GimpWireWriteFunc) (GIOChannel *channel, + GimpWireMessage *msg, + gpointer user_data); +typedef void (* GimpWireDestroyFunc) (GimpWireMessage *msg); +typedef gboolean (* GimpWireIOFunc) (GIOChannel *channel, + const guint8 *buf, + gulong count, + gpointer user_data); +typedef gboolean (* GimpWireFlushFunc) (GIOChannel *channel, + gpointer user_data); + + +struct _GimpWireMessage +{ + guint32 type; + gpointer data; +}; + + +void gimp_wire_register (guint32 type, + GimpWireReadFunc read_func, + GimpWireWriteFunc write_func, + GimpWireDestroyFunc destroy_func); + +void gimp_wire_set_reader (GimpWireIOFunc read_func); +void gimp_wire_set_writer (GimpWireIOFunc write_func); +void gimp_wire_set_flusher (GimpWireFlushFunc flush_func); + +gboolean gimp_wire_read (GIOChannel *channel, + guint8 *buf, + gsize count, + gpointer user_data); +gboolean gimp_wire_write (GIOChannel *channel, + const guint8 *buf, + gsize count, + gpointer user_data); +gboolean gimp_wire_flush (GIOChannel *channel, + gpointer user_data); + +gboolean gimp_wire_error (void); +void gimp_wire_clear_error (void); + +gboolean gimp_wire_read_msg (GIOChannel *channel, + GimpWireMessage *msg, + gpointer user_data); +gboolean gimp_wire_write_msg (GIOChannel *channel, + GimpWireMessage *msg, + gpointer user_data); + +void gimp_wire_destroy (GimpWireMessage *msg); + + +/* for internal use in libgimpbase */ + +G_GNUC_INTERNAL gboolean _gimp_wire_read_int64 (GIOChannel *channel, + guint64 *data, + gint count, + gpointer user_data); +G_GNUC_INTERNAL gboolean _gimp_wire_read_int32 (GIOChannel *channel, + guint32 *data, + gint count, + gpointer user_data); +G_GNUC_INTERNAL gboolean _gimp_wire_read_int16 (GIOChannel *channel, + guint16 *data, + gint count, + gpointer user_data); +G_GNUC_INTERNAL gboolean _gimp_wire_read_int8 (GIOChannel *channel, + guint8 *data, + gint count, + gpointer user_data); +G_GNUC_INTERNAL gboolean _gimp_wire_read_double (GIOChannel *channel, + gdouble *data, + gint count, + gpointer user_data); +G_GNUC_INTERNAL gboolean _gimp_wire_read_string (GIOChannel *channel, + gchar **data, + gint count, + gpointer user_data); +G_GNUC_INTERNAL gboolean _gimp_wire_read_color (GIOChannel *channel, + GimpRGB *data, + gint count, + gpointer user_data); +G_GNUC_INTERNAL gboolean _gimp_wire_write_int64 (GIOChannel *channel, + const guint64 *data, + gint count, + gpointer user_data); +G_GNUC_INTERNAL gboolean _gimp_wire_write_int32 (GIOChannel *channel, + const guint32 *data, + gint count, + gpointer user_data); +G_GNUC_INTERNAL gboolean _gimp_wire_write_int16 (GIOChannel *channel, + const guint16 *data, + gint count, + gpointer user_data); +G_GNUC_INTERNAL gboolean _gimp_wire_write_int8 (GIOChannel *channel, + const guint8 *data, + gint count, + gpointer user_data); +G_GNUC_INTERNAL gboolean _gimp_wire_write_double (GIOChannel *channel, + const gdouble *data, + gint count, + gpointer user_data); +G_GNUC_INTERNAL gboolean _gimp_wire_write_string (GIOChannel *channel, + gchar **data, + gint count, + gpointer user_data); +G_GNUC_INTERNAL gboolean _gimp_wire_write_color (GIOChannel *channel, + const GimpRGB *data, + gint count, + gpointer user_data); + + +G_END_DECLS + +#endif /* __GIMP_WIRE_H__ */ diff --git a/libgimpbase/test-cpu-accel.c b/libgimpbase/test-cpu-accel.c new file mode 100644 index 0000000..5c0349f --- /dev/null +++ b/libgimpbase/test-cpu-accel.c @@ -0,0 +1,48 @@ +/* A small test program for the CPU detection code */ + +#include "config.h" + +#include <stdlib.h> + +#include <glib.h> + +#include "gimpcpuaccel.h" + + +static void +cpu_accel_print_results (void) +{ + GimpCpuAccelFlags support; + + g_printerr ("Testing CPU features...\n"); + + support = gimp_cpu_accel_get_support (); + +#ifdef ARCH_X86 + g_printerr (" mmx : %s\n", + (support & GIMP_CPU_ACCEL_X86_MMX) ? "yes" : "no"); + g_printerr (" 3dnow : %s\n", + (support & GIMP_CPU_ACCEL_X86_3DNOW) ? "yes" : "no"); + g_printerr (" mmxext : %s\n", + (support & GIMP_CPU_ACCEL_X86_MMXEXT) ? "yes" : "no"); + g_printerr (" sse : %s\n", + (support & GIMP_CPU_ACCEL_X86_SSE) ? "yes" : "no"); + g_printerr (" sse2 : %s\n", + (support & GIMP_CPU_ACCEL_X86_SSE2) ? "yes" : "no"); + g_printerr (" sse3 : %s\n", + (support & GIMP_CPU_ACCEL_X86_SSE3) ? "yes" : "no"); +#endif +#ifdef ARCH_PPC + g_printerr (" altivec : %s\n", + (support & GIMP_CPU_ACCEL_PPC_ALTIVEC) ? "yes" : "no"); +#endif + g_printerr ("\n"); +} + +int +main (void) +{ + cpu_accel_print_results (); + + return EXIT_SUCCESS; +} |