summaryrefslogtreecommitdiffstats
path: root/plug-ins/twain
diff options
context:
space:
mode:
Diffstat (limited to 'plug-ins/twain')
-rw-r--r--plug-ins/twain/Makefile.am61
-rw-r--r--plug-ins/twain/Makefile.in1026
-rw-r--r--plug-ins/twain/README92
-rw-r--r--plug-ins/twain/gimp-twain.pngbin0 -> 13859 bytes
-rw-r--r--plug-ins/twain/tw_dump.c273
-rw-r--r--plug-ins/twain/tw_dump.h70
-rw-r--r--plug-ins/twain/tw_func.c874
-rw-r--r--plug-ins/twain/tw_func.h243
-rw-r--r--plug-ins/twain/tw_local.h48
-rw-r--r--plug-ins/twain/tw_platform.h37
-rw-r--r--plug-ins/twain/tw_util.c170
-rw-r--r--plug-ins/twain/tw_util.h73
-rw-r--r--plug-ins/twain/tw_win.c452
-rw-r--r--plug-ins/twain/twain.c962
-rw-r--r--plug-ins/twain/twain.h1819
15 files changed, 6200 insertions, 0 deletions
diff --git a/plug-ins/twain/Makefile.am b/plug-ins/twain/Makefile.am
new file mode 100644
index 0000000..4e094a5
--- /dev/null
+++ b/plug-ins/twain/Makefile.am
@@ -0,0 +1,61 @@
+## Process this file with automake to produce Makefile.in
+
+libgimpui = $(top_builddir)/libgimp/libgimpui-$(GIMP_API_VERSION).la
+libgimpconfig = $(top_builddir)/libgimpconfig/libgimpconfig-$(GIMP_API_VERSION).la
+libgimpwidgets = $(top_builddir)/libgimpwidgets/libgimpwidgets-$(GIMP_API_VERSION).la
+libgimp = $(top_builddir)/libgimp/libgimp-$(GIMP_API_VERSION).la
+libgimpcolor = $(top_builddir)/libgimpcolor/libgimpcolor-$(GIMP_API_VERSION).la
+libgimpbase = $(top_builddir)/libgimpbase/libgimpbase-$(GIMP_API_VERSION).la
+libgimpmath = $(top_builddir)/libgimpmath/libgimpmath-$(GIMP_API_VERSION).la
+
+libexecdir = $(gimpplugindir)/plug-ins/twain
+
+libexec_PROGRAMS = twain
+
+
+if OS_WIN32
+twain_LDFLAGS = -mwindows -luser32
+
+twainplatform = tw_win.c
+endif
+
+if HAVE_WINDRES
+include $(top_srcdir)/build/windows/gimprc-plug-ins.rule
+twain_RC = twain.rc.o
+endif
+
+
+twain_SOURCES = \
+ tw_func.c \
+ tw_func.h \
+ tw_util.c \
+ tw_util.h \
+ twain.c \
+ twain.h \
+ tw_local.h \
+ tw_platform.h \
+ $(twainplatform)
+
+EXTRA_DIST = \
+ README \
+ gimp-twain.png \
+ tw_dump.c \
+ tw_dump.h \
+ tw_win.c
+
+AM_CPPFLAGS = \
+ -I$(top_srcdir) \
+ $(GTK_CFLAGS) \
+ $(GEGL_CFLAGS) \
+ -I$(includedir)
+
+LDADD = \
+ $(libgimp) \
+ $(libgimpcolor) \
+ $(libgimpbase) \
+ $(GLIB_LIBS) \
+ $(GEGL_LIBS) \
+ $(RT_LIBS) \
+ $(INTLLIBS) \
+ $(twain_LIBS) \
+ $(twain_RC)
diff --git a/plug-ins/twain/Makefile.in b/plug-ins/twain/Makefile.in
new file mode 100644
index 0000000..efc3380
--- /dev/null
+++ b/plug-ins/twain/Makefile.in
@@ -0,0 +1,1026 @@
+# Makefile.in generated by automake 1.16.2 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@
+
+# Version resources for Microsoft Windows
+
+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@
+libexec_PROGRAMS = twain$(EXEEXT)
+subdir = plug-ins/twain
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/m4macros/gtk-doc.m4 \
+ $(top_srcdir)/m4macros/intltool.m4 \
+ $(top_srcdir)/m4macros/libtool.m4 \
+ $(top_srcdir)/m4macros/ltoptions.m4 \
+ $(top_srcdir)/m4macros/ltsugar.m4 \
+ $(top_srcdir)/m4macros/ltversion.m4 \
+ $(top_srcdir)/m4macros/lt~obsolete.m4 \
+ $(top_srcdir)/acinclude.m4 $(top_srcdir)/m4macros/alsa.m4 \
+ $(top_srcdir)/m4macros/ax_compare_version.m4 \
+ $(top_srcdir)/m4macros/ax_cxx_compile_stdcxx.m4 \
+ $(top_srcdir)/m4macros/ax_gcc_func_attribute.m4 \
+ $(top_srcdir)/m4macros/ax_prog_cc_for_build.m4 \
+ $(top_srcdir)/m4macros/ax_prog_perl_version.m4 \
+ $(top_srcdir)/m4macros/detectcflags.m4 \
+ $(top_srcdir)/m4macros/pythondev.m4 $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+am__installdirs = "$(DESTDIR)$(libexecdir)"
+PROGRAMS = $(libexec_PROGRAMS)
+am__twain_SOURCES_DIST = tw_func.c tw_func.h tw_util.c tw_util.h \
+ twain.c twain.h tw_local.h tw_platform.h tw_win.c
+@OS_WIN32_TRUE@am__objects_1 = tw_win.$(OBJEXT)
+am_twain_OBJECTS = tw_func.$(OBJEXT) tw_util.$(OBJEXT) twain.$(OBJEXT) \
+ $(am__objects_1)
+twain_OBJECTS = $(am_twain_OBJECTS)
+twain_LDADD = $(LDADD)
+am__DEPENDENCIES_1 =
+twain_DEPENDENCIES = $(libgimp) $(libgimpcolor) $(libgimpbase) \
+ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) $(twain_RC)
+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 =
+twain_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(twain_LDFLAGS) $(LDFLAGS) -o $@
+AM_V_P = $(am__v_P_@AM_V@)
+am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
+am__v_P_0 = false
+am__v_P_1 = :
+AM_V_GEN = $(am__v_GEN_@AM_V@)
+am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
+am__v_GEN_0 = @echo " GEN " $@;
+am__v_GEN_1 =
+AM_V_at = $(am__v_at_@AM_V@)
+am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
+am__v_at_0 = @
+am__v_at_1 =
+DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)
+depcomp = $(SHELL) $(top_srcdir)/depcomp
+am__maybe_remake_depfiles = depfiles
+am__depfiles_remade = ./$(DEPDIR)/tw_func.Po ./$(DEPDIR)/tw_util.Po \
+ ./$(DEPDIR)/tw_win.Po ./$(DEPDIR)/twain.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 = $(twain_SOURCES)
+DIST_SOURCES = $(am__twain_SOURCES_DIST)
+am__can_run_installinfo = \
+ case $$AM_UPDATE_INFO_DIR in \
+ n|no|NO) false;; \
+ *) (install-info --version) >/dev/null 2>&1;; \
+ esac
+am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
+# Read a list of newline-separated strings from the standard input,
+# and print each of them once, without duplicates. Input order is
+# *not* preserved.
+am__uniquify_input = $(AWK) '\
+ BEGIN { nonempty = 0; } \
+ { items[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in items) print i; }; } \
+'
+# Make sure the list of sources is unique. This is necessary because,
+# e.g., the same source file might be shared among _SOURCES variables
+# for different programs/libraries.
+am__define_uniq_tagged_files = \
+ list='$(am__tagged_files)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | $(am__uniquify_input)`
+ETAGS = etags
+CTAGS = ctags
+am__DIST_COMMON = $(srcdir)/Makefile.in \
+ $(top_srcdir)/build/windows/gimprc-plug-ins.rule \
+ $(top_srcdir)/depcomp README
+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_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_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@
+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@
+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 = $(gimpplugindir)/plug-ins/twain
+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@
+libgimpui = $(top_builddir)/libgimp/libgimpui-$(GIMP_API_VERSION).la
+libgimpconfig = $(top_builddir)/libgimpconfig/libgimpconfig-$(GIMP_API_VERSION).la
+libgimpwidgets = $(top_builddir)/libgimpwidgets/libgimpwidgets-$(GIMP_API_VERSION).la
+libgimp = $(top_builddir)/libgimp/libgimp-$(GIMP_API_VERSION).la
+libgimpcolor = $(top_builddir)/libgimpcolor/libgimpcolor-$(GIMP_API_VERSION).la
+libgimpbase = $(top_builddir)/libgimpbase/libgimpbase-$(GIMP_API_VERSION).la
+libgimpmath = $(top_builddir)/libgimpmath/libgimpmath-$(GIMP_API_VERSION).la
+@OS_WIN32_TRUE@twain_LDFLAGS = -mwindows -luser32
+@OS_WIN32_TRUE@twainplatform = tw_win.c
+@HAVE_WINDRES_TRUE@GIMPPLUGINRC = $(top_builddir)/build/windows/gimp-plug-ins.rc
+@HAVE_WINDRES_TRUE@twain_RC = twain.rc.o
+twain_SOURCES = \
+ tw_func.c \
+ tw_func.h \
+ tw_util.c \
+ tw_util.h \
+ twain.c \
+ twain.h \
+ tw_local.h \
+ tw_platform.h \
+ $(twainplatform)
+
+EXTRA_DIST = \
+ README \
+ gimp-twain.png \
+ tw_dump.c \
+ tw_dump.h \
+ tw_win.c
+
+AM_CPPFLAGS = \
+ -I$(top_srcdir) \
+ $(GTK_CFLAGS) \
+ $(GEGL_CFLAGS) \
+ -I$(includedir)
+
+LDADD = \
+ $(libgimp) \
+ $(libgimpcolor) \
+ $(libgimpbase) \
+ $(GLIB_LIBS) \
+ $(GEGL_LIBS) \
+ $(RT_LIBS) \
+ $(INTLLIBS) \
+ $(twain_LIBS) \
+ $(twain_RC)
+
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .lo .o .obj
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(top_srcdir)/build/windows/gimprc-plug-ins.rule $(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 plug-ins/twain/Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --gnu plug-ins/twain/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_srcdir)/build/windows/gimprc-plug-ins.rule $(am__empty):
+
+$(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-libexecPROGRAMS: $(libexec_PROGRAMS)
+ @$(NORMAL_INSTALL)
+ @list='$(libexec_PROGRAMS)'; test -n "$(libexecdir)" || list=; \
+ if test -n "$$list"; then \
+ echo " $(MKDIR_P) '$(DESTDIR)$(libexecdir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(libexecdir)" || exit 1; \
+ fi; \
+ for p in $$list; do echo "$$p $$p"; done | \
+ sed 's/$(EXEEXT)$$//' | \
+ while read p p1; do if test -f $$p \
+ || test -f $$p1 \
+ ; then echo "$$p"; echo "$$p"; else :; fi; \
+ done | \
+ sed -e 'p;s,.*/,,;n;h' \
+ -e 's|.*|.|' \
+ -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \
+ sed 'N;N;N;s,\n, ,g' | \
+ $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \
+ { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \
+ if ($$2 == $$4) files[d] = files[d] " " $$1; \
+ else { print "f", $$3 "/" $$4, $$1; } } \
+ END { for (d in files) print "f", d, files[d] }' | \
+ while read type dir files; do \
+ if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \
+ test -z "$$files" || { \
+ echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(libexecdir)$$dir'"; \
+ $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(libexecdir)$$dir" || exit $$?; \
+ } \
+ ; done
+
+uninstall-libexecPROGRAMS:
+ @$(NORMAL_UNINSTALL)
+ @list='$(libexec_PROGRAMS)'; test -n "$(libexecdir)" || list=; \
+ files=`for p in $$list; do echo "$$p"; done | \
+ sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \
+ -e 's/$$/$(EXEEXT)/' \
+ `; \
+ test -n "$$list" || exit 0; \
+ echo " ( cd '$(DESTDIR)$(libexecdir)' && rm -f" $$files ")"; \
+ cd "$(DESTDIR)$(libexecdir)" && rm -f $$files
+
+clean-libexecPROGRAMS:
+ @list='$(libexec_PROGRAMS)'; test -n "$$list" || exit 0; \
+ echo " rm -f" $$list; \
+ rm -f $$list || exit $$?; \
+ test -n "$(EXEEXT)" || exit 0; \
+ list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \
+ echo " rm -f" $$list; \
+ rm -f $$list
+
+twain$(EXEEXT): $(twain_OBJECTS) $(twain_DEPENDENCIES) $(EXTRA_twain_DEPENDENCIES)
+ @rm -f twain$(EXEEXT)
+ $(AM_V_CCLD)$(twain_LINK) $(twain_OBJECTS) $(twain_LDADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tw_func.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tw_util.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tw_win.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/twain.Po@am__quote@ # am--include-marker
+
+$(am__depfiles_remade):
+ @$(MKDIR_P) $(@D)
+ @echo '# dummy' >$@-t && $(am__mv) $@-t $@
+
+am--depfiles: $(am__depfiles_remade)
+
+.c.o:
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $<
+
+.c.obj:
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
+
+.c.lo:
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $<
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+
+ID: $(am__tagged_files)
+ $(am__define_uniq_tagged_files); mkid -fID $$unique
+tags: tags-am
+TAGS: tags
+
+tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+ set x; \
+ here=`pwd`; \
+ $(am__define_uniq_tagged_files); \
+ shift; \
+ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
+ test -n "$$unique" || unique=$$empty_fix; \
+ if test $$# -gt 0; then \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ "$$@" $$unique; \
+ else \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$unique; \
+ fi; \
+ fi
+ctags: ctags-am
+
+CTAGS: ctags
+ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+ $(am__define_uniq_tagged_files); \
+ test -z "$(CTAGS_ARGS)$$unique" \
+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+ $$unique
+
+GTAGS:
+ here=`$(am__cd) $(top_builddir) && pwd` \
+ && $(am__cd) $(top_srcdir) \
+ && gtags -i $(GTAGS_ARGS) "$$here"
+cscopelist: cscopelist-am
+
+cscopelist-am: $(am__tagged_files)
+ list='$(am__tagged_files)'; \
+ case "$(srcdir)" in \
+ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
+ *) sdir=$(subdir)/$(srcdir) ;; \
+ esac; \
+ for i in $$list; do \
+ if test -f "$$i"; then \
+ echo "$(subdir)/$$i"; \
+ else \
+ echo "$$sdir/$$i"; \
+ fi; \
+ done >> $(top_builddir)/cscope.files
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+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
+check: check-am
+all-am: Makefile $(PROGRAMS)
+installdirs:
+ for dir in "$(DESTDIR)$(libexecdir)"; 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:
+
+clean-generic:
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+ -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-generic clean-libexecPROGRAMS clean-libtool \
+ mostlyclean-am
+
+distclean: distclean-am
+ -rm -f ./$(DEPDIR)/tw_func.Po
+ -rm -f ./$(DEPDIR)/tw_util.Po
+ -rm -f ./$(DEPDIR)/tw_win.Po
+ -rm -f ./$(DEPDIR)/twain.Po
+ -rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+ distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+html-am:
+
+info: info-am
+
+info-am:
+
+install-data-am:
+
+install-dvi: install-dvi-am
+
+install-dvi-am:
+
+install-exec-am: install-libexecPROGRAMS
+
+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)/tw_func.Po
+ -rm -f ./$(DEPDIR)/tw_util.Po
+ -rm -f ./$(DEPDIR)/tw_win.Po
+ -rm -f ./$(DEPDIR)/twain.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-libexecPROGRAMS
+
+.MAKE: install-am install-strip
+
+.PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \
+ clean-generic clean-libexecPROGRAMS 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-dvi install-dvi-am \
+ install-exec install-exec-am install-html install-html-am \
+ install-info install-info-am install-libexecPROGRAMS \
+ 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 tags tags-am uninstall \
+ uninstall-am uninstall-libexecPROGRAMS
+
+.PRECIOUS: Makefile
+
+
+# `windres` seems a very stupid tool and it breaks with double shlashes
+# in parameter paths. Strengthen the rule a little.
+@HAVE_WINDRES_TRUE@%.rc.o:
+@HAVE_WINDRES_TRUE@ $(WINDRES) --define ORIGINALFILENAME_STR="$*$(EXEEXT)" \
+@HAVE_WINDRES_TRUE@ --define INTERNALNAME_STR="$*" \
+@HAVE_WINDRES_TRUE@ --define TOP_SRCDIR="`echo $(top_srcdir) | sed 's*//*/*'`" \
+@HAVE_WINDRES_TRUE@ -I"`echo $(top_srcdir)/app | sed 's%/\+%/%'`" \
+@HAVE_WINDRES_TRUE@ -I"`echo $(top_builddir)/app | sed 's%/\+%/%'`"\
+@HAVE_WINDRES_TRUE@ -I"`echo $(top_builddir) | sed 's%/\+%/%'`"\
+@HAVE_WINDRES_TRUE@ $(GIMPPLUGINRC) $@
+
+# 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/plug-ins/twain/README b/plug-ins/twain/README
new file mode 100644
index 0000000..87c1492
--- /dev/null
+++ b/plug-ins/twain/README
@@ -0,0 +1,92 @@
+TWAIN Plug-in
+Copyright (C) 1999 Craig Setera
+Craig Setera <setera@home.com>
+03/31/1999
+
+Updated for Mac OS X support
+Brion Vibber <brion@pobox.com>
+07/22/2004
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 3 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program. If not, see <https://www.gnu.org/licenses/>.
+
+Based on (at least) the following plug-ins:
+Screenshot
+GIF
+Randomize
+
+Any suggestions, bug-reports or patches are welcome.
+
+This plug-in interfaces to the TWAIN support library in order
+to capture images from TWAIN devices directly into GIMP images.
+The plug-in is capable of acquiring the following type of
+images:
+ - B/W (1 bit images translated to grayscale B/W)
+ - Grayscale up to 16 bits per pixel
+ - RGB up to 16 bits per sample (24, 30, 36, etc.)
+ - Paletted images (both Gray and RGB)
+
+Prerequisites:
+ Should compile and run on both Win32 and Mac OS X 10.3 (possibly
+ also on 10.2).
+
+Known problems:
+
+ - Multiple image transfers will hang the plug-in. The current
+ configuration compiles with a maximum of single image transfers.
+ - On Mac OS X, canceling doesn't always close things out fully.
+ - Epson TWAIN driver on Mac OS X crashes the plugin when scanning.
+
+Debugging:
+ There are two different versions of the program included, a standard
+ version and a version built for debugging. The debugging version is
+ a special version capable of capturing the TWAIN datasource data to
+ a file for later processing. This feature can be used to create a data
+ dump that can be sent to me if for some reason the plug-in fails for
+ your TWAIN datasource. The function of the plug-in is controlled by
+ the name of the executable file. The plug-in should be placed in your
+ plug-ins directory and named as follows:
+
+twain.exe - This is the standard (non-debugging) version. This file will
+ not behave differently if renamed. This version is intended to be used
+ unless your TWAIN datasource has some problem.
+
+gtwain.exe - This is the debugging version of the program shipped along.
+ If this program is used as named, it will behave the same as "twain.exe"
+ except that the file C:\twain.log will be written. This file is a text
+ file with very little information available for debugging.
+
+dtwain.exe - Renaming "gtwain.exe" to "dtwain.exe" in your plug-ins directory
+ will change the behavior of the plug-in. The menu option will be registered
+ as "TWAIN Acquire (Dump)..." and will cause the TWAIN acquire operation to
+ be dumped to the file "C:\twaincap.bin". This file contains all of the data
+ necessary to recreate the capture on another system (such as my machine). The
+ image will not be displayed, as it might cause the plug-in to crash making
+ the data useless. Instead, a message will be displayed that the image
+ information was dumped to a file.
+
+rtwain.exe - Renaming "gtwain.exe" to "rtwain.exe" in your plug-ins directory
+ will change the behavior of the plug-in. The menu option will be registered
+ as "TWAIN Acquire (Read)..." and will cause the TWAIN acquire operation to
+ read a previously dumped (using dtwain.exe) TWAIN acquire from
+ "C:\twaincap.bin".
+
+If you find that you are unable to capture data from you datasource (the plug-in
+crashes or the image is wrong), please capture data using the following steps:
+
+1) Copy gtwain.exe to your plug-ins directory as "dtwain.exe".
+2) Run GIMP.
+3) Choose Xtns->TWAIN Acquire (Dump)...
+4) Choose the datasource settings that are causing problems.
+5) Choose a *SMALL* sample image.
+6) Zip up "C:\twaincap.bin" and "C:\twain.log" and send them to me.
diff --git a/plug-ins/twain/gimp-twain.png b/plug-ins/twain/gimp-twain.png
new file mode 100644
index 0000000..25ff3f3
--- /dev/null
+++ b/plug-ins/twain/gimp-twain.png
Binary files differ
diff --git a/plug-ins/twain/tw_dump.c b/plug-ins/twain/tw_dump.c
new file mode 100644
index 0000000..b75bc8c
--- /dev/null
+++ b/plug-ins/twain/tw_dump.c
@@ -0,0 +1,273 @@
+/*
+ * TWAIN Plug-in
+ * Copyright (C) 1999 Craig Setera
+ * Craig Setera <setera@home.com>
+ * 03/31/1999
+ *
+ * Updated for Mac OS X support
+ * Brion Vibber <brion@pobox.com>
+ * 07/22/2004
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ *
+ *
+ * Based on (at least) the following plug-ins:
+ * Screenshot
+ * GIF
+ * Randomize
+ *
+ * Any suggestions, bug-reports or patches are welcome.
+ *
+ * This plug-in interfaces to the TWAIN support library in order
+ * to capture images from TWAIN devices directly into GIMP images.
+ * The plug-in is capable of acquiring the following type of
+ * images:
+ * - B/W (1 bit images translated to grayscale B/W)
+ * - Grayscale up to 16 bits per pixel
+ * - RGB up to 16 bits per sample (24, 30, 36, etc.)
+ * - Paletted images (both Gray and RGB)
+ *
+ * Prerequisites:
+ * Should compile and run on both Win32 and Mac OS X 10.3 (possibly
+ * also on 10.2).
+ *
+ * Known problems:
+ * - Multiple image transfers will hang the plug-in. The current
+ * configuration compiles with a maximum of single image transfers.
+ * - On Mac OS X, canceling doesn't always close things out fully.
+ * - Epson TWAIN driver on Mac OS X crashes the plugin when scanning.
+ */
+
+/*
+ * Revision history
+ * (02/07/99) v0.1 First working version (internal)
+ * (02/09/99) v0.2 First release to anyone other than myself
+ * (02/15/99) v0.3 Added image dump and read support for debugging
+ * (03/31/99) v0.5 Added support for multi-byte samples and paletted
+ * images.
+ * (07/23/04) v0.6 Added Mac OS X support.
+ */
+
+#include "config.h"
+
+#include <string.h>
+
+#include <glib/gstdio.h>
+
+#include "libgimp/gimp.h"
+
+#include "tw_dump.h"
+#include "tw_func.h"
+#include "tw_util.h"
+
+/* File variables */
+static FILE *outputFile = NULL;
+extern pTW_SESSION twSession;
+
+/*
+ * dumpPreTransferCallback
+ *
+ * This callback function is called before any images
+ * are transferred. Set up the one time only stuff.
+ */
+void
+dumpPreTransferCallback(void *clientData)
+{
+ /* Open our output file... Not settable... Always
+ * write to the root directory. Simplistic, but
+ * gets the job done.
+ */
+ outputFile = g_fopen(DUMP_FILE, "wb");
+}
+
+/*
+ * dumpBeginTransferCallback
+ *
+ * The following function is called at the beginning
+ * of each image transfer.
+ */
+int
+dumpBeginTransferCallback(pTW_IMAGEINFO imageInfo, void *clientData)
+{
+ logBegin(imageInfo, clientData);
+
+ /* Dump the image information */
+ fwrite((void *) imageInfo, sizeof(TW_IMAGEINFO), 1, outputFile);
+
+ /* Keep going */
+ return TRUE;
+}
+
+/*
+ * dumpDataTransferCallback
+ *
+ * The following function is called for each memory
+ * block that is transferred from the data source.
+ */
+int
+dumpDataTransferCallback(pTW_IMAGEINFO imageInfo,
+ pTW_IMAGEMEMXFER imageMemXfer,
+ void *clientData)
+{
+ int flag = 1;
+
+ logData(imageInfo, imageMemXfer, clientData);
+
+ /* Write a flag that says that this is a data packet */
+ fwrite((void *) &flag, sizeof(int), 1, outputFile);
+
+ /* Dump the memory information */
+ fwrite((void *) imageMemXfer, sizeof(TW_IMAGEMEMXFER), 1, outputFile);
+ fwrite((void *) imageMemXfer->Memory.TheMem,
+ 1, imageMemXfer->BytesWritten, outputFile);
+
+ /* Keep going */
+ return TRUE;
+}
+
+/*
+ * dumpEndTransferCallback
+ *
+ * The following function is called at the end of the
+ * image transfer. The caller will be handed
+ * the image transfer completion state. The
+ * following values (defined in twain.h) are
+ * possible:
+ *
+ * TWRC_XFERDONE
+ * The transfer completed successfully
+ * TWRC_CANCEL
+ * The transfer was completed by the user
+ * TWRC_FAILURE
+ * The transfer failed.
+ */
+int
+dumpEndTransferCallback(int completionState, int pendingCount, void *clientData)
+{
+ int flag = 0;
+
+ /* Write a flag that says that this is a data packet */
+ fwrite((void *) &flag, sizeof(int), 1, outputFile);
+
+ /* Write the necessary data */
+ fwrite(&completionState, sizeof(int), 1, outputFile);
+ fwrite(&pendingCount, sizeof(int), 1, outputFile);
+
+ /* Only ever transfer a single image */
+ return FALSE;
+}
+
+/*
+ * dumpPostTransferCallback
+ *
+ * This callback function will be called
+ * after all possible images have been
+ * transferred.
+ */
+void
+dumpPostTransferCallback(int pendingCount, void *clientData)
+{
+ char buffer[128];
+
+ /* Shut things down. */
+ if (pendingCount != 0)
+ cancelPendingTransfers(twSession);
+
+ /* This will close the datasource and datasource
+ * manager. Then the message queue will be shut
+ * down and the run() procedure will finally be
+ * able to finish.
+ */
+ disableDS(twSession);
+ closeDS(twSession);
+ closeDSM(twSession);
+
+ /* Close the dump file */
+ fclose(outputFile);
+
+ /* Tell the user */
+ sprintf(buffer, "Image dumped to file %s\n", DUMP_FILE);
+ gimp_message(buffer);
+
+ /* Post a message to close up the application */
+ twainQuitApplication ();
+}
+
+/*
+ * readDumpedImage
+ *
+ * Get a previously dumped image.
+ */
+void readDumpedImage(pTW_SESSION twSession)
+{
+ int moreData;
+ int completionState;
+ int pendingCount;
+
+ TW_IMAGEINFO imageInfo;
+ TW_IMAGEMEMXFER imageMemXfer;
+
+ /* Open our output file... Not settable... Always
+ * write to the root directory. Simplistic, but
+ * gets the job done.
+ */
+ FILE *inputFile = g_fopen(DUMP_FILE, "rb");
+
+ /*
+ * Inform our application that we are getting ready
+ * to transfer images.
+ */
+ (*twSession->transferFunctions->preTxfrCb)(NULL);
+
+ /* Read the image information */
+ fread((void *) &imageInfo, sizeof(TW_IMAGEINFO), 1, inputFile);
+
+ /* Call the begin transfer callback */
+ if (!(*twSession->transferFunctions->txfrBeginCb)(&imageInfo, twSession->clientData))
+ return;
+
+ /* Read all of the data packets */
+ fread((void *) &moreData, sizeof(int), 1, inputFile);
+ while (moreData) {
+ /* Read the memory information */
+ fread((void *) &imageMemXfer, sizeof(TW_IMAGEMEMXFER), 1, inputFile);
+ imageMemXfer.Memory.TheMem = (TW_MEMREF) g_malloc (imageMemXfer.BytesWritten);
+ fread((void *) imageMemXfer.Memory.TheMem,
+ 1, imageMemXfer.BytesWritten, inputFile);
+
+ /* Call the data transfer callback function */
+ if (!(*twSession->transferFunctions->txfrDataCb)
+ (&imageInfo,
+ &imageMemXfer,
+ twSession->clientData))
+ return;
+
+ /* Clean up the memory */
+ g_free (imageMemXfer.Memory.TheMem);
+
+ /* Check for continuation */
+ fread((void *) &moreData, sizeof(int), 1, inputFile);
+ }
+
+ /* Grab the final information */
+ fread(&completionState, sizeof(int), 1, inputFile);
+ fread(&pendingCount, sizeof(int), 1, inputFile);
+
+ if (twSession->transferFunctions->txfrEndCb)
+ (*twSession->transferFunctions->txfrEndCb)(completionState, 0,
+ twSession->clientData);
+
+ /* Post a message to close up the application */
+ twainQuitApplication ();
+}
diff --git a/plug-ins/twain/tw_dump.h b/plug-ins/twain/tw_dump.h
new file mode 100644
index 0000000..5386af7
--- /dev/null
+++ b/plug-ins/twain/tw_dump.h
@@ -0,0 +1,70 @@
+/*
+ * TWAIN Plug-in
+ * Copyright (C) 1999 Craig Setera
+ * Craig Setera <setera@home.com>
+ * 03/31/1999
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ *
+ *
+ * Based on (at least) the following plug-ins:
+ * Screenshot
+ * GIF
+ * Randomize
+ *
+ * Any suggestions, bug-reports or patches are welcome.
+ *
+ * This plug-in interfaces to the TWAIN support library in order
+ * to capture images from TWAIN devices directly into GIMP images.
+ * The plug-in is capable of acquiring the following type of
+ * images:
+ * - B/W (1 bit images translated to grayscale B/W)
+ * - Grayscale up to 16 bits per pixel
+ * - RGB up to 16 bits per sample (24, 30, 36, etc.)
+ * - Paletted images (both Gray and RGB)
+ *
+ * Prerequisites:
+ * This plug-in will not compile on anything other than a Win32
+ * platform. Although the TWAIN documentation implies that there
+ * is TWAIN support available on Macintosh, I neither have a
+ * Macintosh nor the interest in porting this. If anyone else
+ * has an interest, consult www.twain.org for more information on
+ * interfacing to TWAIN.
+ *
+ * Known problems:
+ * - Multiple image transfers will hang the plug-in. The current
+ * configuration compiles with a maximum of single image transfers.
+ */
+
+/*
+ * Revision history
+ * (02/07/99) v0.1 First working version (internal)
+ * (02/09/99) v0.2 First release to anyone other than myself
+ * (02/15/99) v0.3 Added image dump and read support for debugging
+ * (03/31/99) v0.5 Added support for multi-byte samples and paletted
+ * images.
+ */
+
+#include "tw_platform.h"
+#include "tw_func.h"
+
+void dumpPreTransferCallback(void *clientData);
+int dumpBeginTransferCallback(pTW_IMAGEINFO imageInfo, void *clientData);
+int dumpDataTransferCallback(pTW_IMAGEINFO imageInfo,
+ pTW_IMAGEMEMXFER imageMemXfer,
+ void *clientData);
+int dumpEndTransferCallback(int completionState, int pendingCount, void *clientData);
+void dumpPostTransferCallback(int pendingCount, void *clientData);
+void readDumpedImage(pTW_SESSION twSession);
+
diff --git a/plug-ins/twain/tw_func.c b/plug-ins/twain/tw_func.c
new file mode 100644
index 0000000..8baa7b3
--- /dev/null
+++ b/plug-ins/twain/tw_func.c
@@ -0,0 +1,874 @@
+/*
+ * TWAIN Plug-in
+ * Copyright (C) 1999 Craig Setera
+ * Craig Setera <setera@home.com>
+ * 03/31/1999
+ *
+ * Updated for Mac OS X support
+ * Brion Vibber <brion@pobox.com>
+ * 07/22/2004
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ *
+ *
+ * Based on (at least) the following plug-ins:
+ * Screenshot
+ * GIF
+ * Randomize
+ *
+ * Any suggestions, bug-reports or patches are welcome.
+ *
+ * This plug-in interfaces to the TWAIN support library in order
+ * to capture images from TWAIN devices directly into GIMP images.
+ * The plug-in is capable of acquiring the following type of
+ * images:
+ * - B/W (1 bit images translated to grayscale B/W)
+ * - Grayscale up to 16 bits per pixel
+ * - RGB up to 16 bits per sample (24, 30, 36, etc.)
+ * - Paletted images (both Gray and RGB)
+ *
+ * Prerequisites:
+ * Should compile and run on both Win32 and Mac OS X 10.3 (possibly
+ * also on 10.2).
+ *
+ * Known problems:
+ * - Multiple image transfers will hang the plug-in. The current
+ * configuration compiles with a maximum of single image transfers.
+ * - On Mac OS X, canceling doesn't always close things out fully.
+ * - Epson TWAIN driver on Mac OS X crashes the plugin when scanning.
+ */
+
+/*
+ * Revision history
+ * (02/07/99) v0.1 First working version (internal)
+ * (02/09/99) v0.2 First release to anyone other than myself
+ * (02/15/99) v0.3 Added image dump and read support for debugging
+ * (03/31/99) v0.5 Added support for multi-byte samples and paletted
+ * images.
+ * (07/23/04) v0.6 Added Mac OS X support.
+ */
+
+#include "config.h"
+
+#include <glib.h> /* Needed when compiling with gcc */
+
+#include "tw_func.h"
+#include "tw_util.h"
+#include "tw_local.h"
+
+/*
+ * Twain error code to string mappings
+ */
+static int twainErrorCount = 0;
+static char *twainErrors[] = {
+ "No error",
+ "Failure due to unknown causes",
+ "Not enough memory to perform operation",
+ "No Data Source",
+ "DS is connected to max possible apps",
+ "DS or DSM reported error, application shouldn't",
+ "Unknown capability",
+ "Unrecognized MSG DG DAT combination",
+ "Data parameter out of range",
+ "DG DAT MSG out of expected sequence",
+ "Unknown destination App/Src in DSM_Entry",
+ "Capability not supported by source",
+ "Operation not supported by capability",
+ "Capability has dependency on other capability",
+ "File System operation is denied (file is protected)",
+ "Operation failed because file already exists.",
+ "File not found",
+ "Operation failed because directory is not empty",
+ "The feeder is jammed",
+ "The feeder detected multiple pages",
+ "Error writing the file (disk full?)",
+ "The device went offline prior to or during this operation",
+ NULL
+};
+
+/*
+ * FloatToFix32
+ *
+ * Convert a floating point value into a FIX32.
+ */
+TW_FIX32 FloatToFIX32(float floater)
+{
+ TW_FIX32 Fix32_value;
+ TW_INT32 value = (TW_INT32) (floater * 65536.0 + 0.5);
+ Fix32_value.Whole = value >> 16;
+ Fix32_value.Frac = value & 0x0000ffffL;
+ return (Fix32_value);
+}
+
+/*
+ * Fix32ToFloat
+ *
+ * Convert a FIX32 value into a floating point value.
+ */
+float FIX32ToFloat(TW_FIX32 fix32)
+{
+ float floater;
+ floater = (float) fix32.Whole + (float) fix32.Frac / 65536.0;
+ return floater;
+}
+
+/*
+ * twainError
+ *
+ * Return the TWAIN error message associated
+ * with the specified error code.
+ */
+char *
+twainError(int errorCode)
+{
+ /* Check whether we've counted */
+ if (twainErrorCount == 0)
+ while (twainErrors[twainErrorCount++]) {}
+
+ /* Check out of bounds */
+ if (errorCode >= twainErrorCount)
+ return "Unknown TWAIN Error Code";
+ else
+ return twainErrors[errorCode];
+}
+
+/*
+ * currentTwainError
+ *
+ * Return the current TWAIN error message.
+ */
+char *
+currentTwainError(pTW_SESSION twSession)
+{
+ TW_STATUS twStatus;
+
+ /* Get the current status code from the DSM */
+ twSession->twRC = callDSM(APP_IDENTITY(twSession), DS_IDENTITY(twSession),
+ DG_CONTROL, DAT_STATUS, MSG_GET,
+ (TW_MEMREF) &twStatus);
+
+ /* Return the mapped error code */
+ return twainError(twStatus.ConditionCode);
+}
+
+
+/*
+ * getImage
+ *
+ * This is a "high-level" function that can be called in order
+ * to take all of the steps necessary to kick off an image-transfer
+ * from a user-specified TWAIN datasource. The data will be passed
+ * back to the callback function specified in the session structure.
+ */
+int
+getImage(pTW_SESSION twSession)
+{
+ /* Do some sanity checking first and bail
+ * if necessary.
+ */
+
+ if (!twainIsAvailable()) {
+ LogMessage("TWAIN is not available for image capture\n");
+ return FALSE;
+ }
+
+ /* One step at a time */
+ if (!openDSM(twSession)) {
+ LogMessage("Unable to open data source manager\n");
+ return FALSE;
+ }
+
+ if (!selectDS(twSession)) {
+ LogMessage("Data source not selected\n");
+ return FALSE;
+ }
+
+ if (!openDS(twSession)) {
+ LogMessage("Unable to open datasource\n");
+ return FALSE;
+ }
+
+ requestImageAcquire(twSession, TRUE);
+
+ return TRUE;
+}
+
+/*
+ * openDSM
+ *
+ * Open the data source manager
+ */
+int
+openDSM(pTW_SESSION twSession)
+{
+ /* Make sure that we aren't already open */
+ if (DSM_IS_OPEN(twSession))
+ return TRUE;
+
+ /* Open the data source manager */
+ twSession->twRC = callDSM(APP_IDENTITY(twSession), NULL,
+ DG_CONTROL, DAT_PARENT, MSG_OPENDSM,
+ (TW_MEMREF) &(twSession->hwnd));
+
+ /* Check the return code */
+ switch (twSession->twRC) {
+ case TWRC_SUCCESS:
+ /* We are now at state 3 */
+ twSession->twainState = 3;
+ return TRUE;
+ break;
+
+ case TWRC_FAILURE:
+ default:
+ LogMessage("OpenDSM failure\n");
+ break;
+ }
+
+ return FALSE;
+}
+
+/*
+ * selectDS
+ *
+ * Select a datasource using the TWAIN user
+ * interface.
+ */
+int
+selectDS(pTW_SESSION twSession)
+{
+ /* The datasource manager must be open */
+ if (DSM_IS_CLOSED(twSession)) {
+ LogMessage("Can't select data source with closed source manager\n");
+ return FALSE;
+ }
+
+ /* Ask TWAIN to present the source select dialog */
+ twSession->twRC = callDSM(APP_IDENTITY(twSession), NULL,
+ DG_CONTROL, DAT_IDENTITY, MSG_USERSELECT,
+ (TW_MEMREF) DS_IDENTITY(twSession));
+
+ /* Check the return to determine what the user decided
+ * to do.
+ */
+ switch (twSession->twRC) {
+ case TWRC_SUCCESS:
+ LogMessage("Data source %s selected\n", DS_IDENTITY(twSession)->ProductName);
+ return TRUE;
+ break;
+
+ case TWRC_CANCEL:
+ LogMessage("User cancelled TWAIN source selection\n");
+ break;
+
+ case TWRC_FAILURE:
+ default:
+ LogMessage("Error \"%s\" during TWAIN source selection\n",
+ currentTwainError(twSession));
+ break;
+ }
+
+ return FALSE;
+}
+
+/*
+ * selectDefaultDS
+ *
+ * Select the default datasource.
+ */
+int
+selectDefaultDS(pTW_SESSION twSession)
+{
+ /* The datasource manager must be open */
+ if (DSM_IS_CLOSED(twSession)) {
+ LogMessage("Can't select data source with closed source manager\n");
+ return FALSE;
+ }
+
+ /* Ask TWAIN to present the source select dialog */
+ twSession->twRC = callDSM(APP_IDENTITY(twSession), NULL,
+ DG_CONTROL, DAT_IDENTITY, MSG_GETDEFAULT,
+ (TW_MEMREF) DS_IDENTITY(twSession));
+
+ /* Check the return code */
+ return (twSession->twRC == TWRC_SUCCESS);
+}
+
+/*
+ * openDS
+ *
+ * Open a data source using the TWAIN user interface.
+ */
+int
+openDS(pTW_SESSION twSession)
+{
+ TW_IDENTITY *dsIdentity;
+
+ /* The datasource manager must be open */
+ if (DSM_IS_CLOSED(twSession)) {
+ LogMessage("openDS: Cannot open data source... manager closed\n");
+ return FALSE;
+ }
+
+ /* Is the data source already open? */
+ if (DS_IS_OPEN(twSession)) {
+ LogMessage("openDS: Data source already open\n");
+ return TRUE;
+ }
+
+ /* Open the TWAIN datasource */
+ dsIdentity = DS_IDENTITY(twSession);
+ twSession->twRC = callDSM(APP_IDENTITY(twSession), NULL,
+ DG_CONTROL, DAT_IDENTITY, MSG_OPENDS,
+ (TW_MEMREF) dsIdentity);
+
+ /* Check the return to determine what the user decided
+ * to do.
+ */
+ switch (twSession->twRC) {
+ case TWRC_SUCCESS:
+ /* We are now in TWAIN state 4 */
+ twSession->twainState = 4;
+ LogMessage("Data source %s opened\n", DS_IDENTITY(twSession)->ProductName);
+ LogMessage("\tVersion.MajorNum = %d\n", dsIdentity->Version.MajorNum);
+ LogMessage("\tVersion.MinorNum = %d\n", dsIdentity->Version.MinorNum);
+ LogMessage("\tVersion.Info = %s\n", dsIdentity->Version.Info);
+ LogMessage("\tProtocolMajor = %d\n", dsIdentity->ProtocolMajor);
+ LogMessage("\tProtocolMinor = %d\n", dsIdentity->ProtocolMinor);
+ LogMessage("\tManufacturer = %s\n", dsIdentity->Manufacturer);
+ LogMessage("\tProductFamily = %s\n", dsIdentity->ProductFamily);
+ return TRUE;
+ break;
+
+ default:
+ LogMessage("Error \"%s\" opening data source\n", currentTwainError(twSession));
+ break;
+ }
+
+ return FALSE;
+}
+
+/*
+ * setBufferedXfer
+ */
+static int
+setBufferedXfer(pTW_SESSION twSession)
+{
+ TW_CAPABILITY bufXfer;
+ pTW_ONEVALUE pvalOneValue;
+
+ /* Make sure the data source is open first */
+ if (DS_IS_CLOSED(twSession))
+ return FALSE;
+
+ /* Create the capability information */
+ bufXfer.Cap = ICAP_XFERMECH;
+ bufXfer.ConType = TWON_ONEVALUE;
+ bufXfer.hContainer = twainAllocHandle(sizeof(TW_ONEVALUE));
+
+ pvalOneValue = (pTW_ONEVALUE) twainLockHandle(bufXfer.hContainer);
+ pvalOneValue->ItemType = TWTY_UINT16;
+ pvalOneValue->Item = TWSX_MEMORY;
+ twainUnlockHandle(bufXfer.hContainer);
+
+ /* Make the call to the source manager */
+ twSession->twRC = callDSM(APP_IDENTITY(twSession), DS_IDENTITY(twSession),
+ DG_CONTROL, DAT_CAPABILITY, MSG_SET,
+ (TW_MEMREF) &bufXfer);
+
+ /* Free the container */
+ twainFreeHandle(bufXfer.hContainer);
+
+ /* Let the caller know what happened */
+ return (twSession->twRC==TWRC_SUCCESS);
+}
+
+/*
+ * requestImageAcquire
+ *
+ * Request that the acquire user interface
+ * be displayed. This may or may not cause
+ * an image to actually be transferred.
+ */
+int
+requestImageAcquire(pTW_SESSION twSession, gboolean showUI)
+{
+ /* Make sure in the correct state */
+ if (DS_IS_CLOSED(twSession)) {
+ LogMessage("Can't acquire image with closed datasource\n");
+ return FALSE;
+ }
+
+ twainSetupCallback(twSession);
+
+ /* Set the transfer mode */
+ if (setBufferedXfer(twSession)) {
+ TW_USERINTERFACE ui;
+
+ /* Set the UI information */
+ ui.ShowUI = TRUE;
+ ui.ModalUI = TRUE;
+ /* In Windows, the callbacks are sent to the window message handler */
+ ui.hParent = twSession->hwnd;
+
+ /* Make the call to the source manager */
+ twSession->twRC = callDSM(APP_IDENTITY(twSession), DS_IDENTITY(twSession),
+ DG_CONTROL, DAT_USERINTERFACE, MSG_ENABLEDS,
+ (TW_MEMREF) &ui);
+
+ if (twSession->twRC == TWRC_SUCCESS) {
+ /* We are now at a new twain state */
+ twSession->twainState = 5;
+
+ return TRUE;
+ } else {
+ LogMessage("Error during data source enable\n");
+ return FALSE;
+ }
+ } else {
+ LogMessage("Unable to set buffered transfer mode: %s\n",
+ currentTwainError(twSession));
+ return FALSE;
+ }
+}
+
+/*
+ * disableDS
+ *
+ * Disable the datasource associated with twSession.
+ */
+int
+disableDS(pTW_SESSION twSession)
+{
+ TW_USERINTERFACE ui;
+
+ /* Verify the datasource is enabled */
+ if (DS_IS_DISABLED(twSession)) {
+ LogMessage("disableDS: Data source not enabled\n");
+ return TRUE;
+ }
+
+ /* Set the UI information */
+ ui.ShowUI = TRUE;
+ ui.ModalUI = TRUE;
+ ui.hParent = twSession->hwnd;
+
+ /* Make the call to the source manager */
+ twSession->twRC = callDSM(APP_IDENTITY(twSession), DS_IDENTITY(twSession),
+ DG_CONTROL, DAT_USERINTERFACE, MSG_DISABLEDS,
+ (TW_MEMREF) &ui);
+
+ if (twSession->twRC == TWRC_SUCCESS) {
+ /* We are now at a new twain state */
+ twSession->twainState = 4;
+
+ return TRUE;
+ } else {
+ LogMessage("Error during data source disable\n");
+ return FALSE;
+ }
+}
+
+/*
+ * closeDS
+ *
+ * Close the datasource associated with the
+ * specified session.
+ */
+int
+closeDS(pTW_SESSION twSession)
+{
+ /* Can't close a closed data source */
+ if (DS_IS_CLOSED(twSession)) {
+ LogMessage("closeDS: Data source already closed\n");
+ return TRUE;
+ }
+
+ /* Open the TWAIN datasource */
+ twSession->twRC = callDSM(APP_IDENTITY(twSession), NULL,
+ DG_CONTROL, DAT_IDENTITY, MSG_CLOSEDS,
+ (TW_MEMREF) DS_IDENTITY(twSession));
+
+ /* Check the return to determine what the user decided
+ * to do.
+ */
+ switch (twSession->twRC) {
+ case TWRC_SUCCESS:
+ /* We are now in TWAIN state 3 */
+ twSession->twainState = 3;
+ LogMessage("Data source %s closed\n", DS_IDENTITY(twSession)->ProductName);
+ return TRUE;
+ break;
+
+ default:
+ LogMessage("Error \"%s\" closing data source\n", currentTwainError(twSession));
+ break;
+ }
+
+ return FALSE;
+}
+
+/*
+ * closeDSM
+ *
+ * Close the data source manager
+ */
+int
+closeDSM(pTW_SESSION twSession)
+{
+ if (DSM_IS_CLOSED(twSession)) {
+ LogMessage("closeDSM: Source Manager not open\n");
+ return FALSE;
+ } else {
+ if (DS_IS_OPEN(twSession)) {
+ LogMessage("closeDSM: Can't close source manager with open source\n");
+ return FALSE;
+ } else {
+ twSession->twRC = callDSM(APP_IDENTITY(twSession), NULL,
+ DG_CONTROL, DAT_PARENT, MSG_CLOSEDSM,
+ (TW_MEMREF)&(twSession->hwnd));
+
+ if (twSession->twRC != TWRC_SUCCESS) {
+ LogMessage("CloseDSM failure -- %s\n", currentTwainError(twSession));
+ }
+ else {
+
+ /* We are now in state 2 */
+ twSession->twainState = 2;
+ }
+ }
+ }
+
+ /* Let the caller know what happened */
+ return (twSession->twRC==TWRC_SUCCESS);
+}
+
+
+/*
+ * beginImageTransfer
+ *
+ * Begin an image transfer.
+ */
+static int
+beginImageTransfer(pTW_SESSION twSession, pTW_IMAGEINFO imageInfo)
+{
+ /* Clear our structures */
+ memset(imageInfo, 0, sizeof(TW_IMAGEINFO));
+
+ /* Query the image information */
+ twSession->twRC = callDSM(
+ APP_IDENTITY(twSession), DS_IDENTITY(twSession),
+ DG_IMAGE, DAT_IMAGEINFO, MSG_GET,
+ (TW_MEMREF) imageInfo);
+
+ /* Check the return code */
+ if (twSession->twRC != TWRC_SUCCESS) {
+ LogMessage("Get Image Info failure - %s\n", currentTwainError(twSession));
+
+ return FALSE;
+ }
+
+ /* Call the begin transfer callback if registered */
+ if (twSession->transferFunctions->txfrBeginCb)
+ if (!(*twSession->transferFunctions->txfrBeginCb)(imageInfo, twSession->clientData))
+ return FALSE;
+
+ /* We should continue */
+ return TRUE;
+}
+
+/*
+ * transferImage
+ *
+ * The Source indicated it is ready to transfer data. It is
+ * waiting for the application to inquire about the image details,
+ * initiate the actual transfer, and, hence, transition the session
+ * from State 6 to 7. Return the reason for exiting the transfer.
+ */
+static void
+transferImage(pTW_SESSION twSession, pTW_IMAGEINFO imageInfo)
+{
+ TW_SETUPMEMXFER setupMemXfer;
+ TW_IMAGEMEMXFER imageMemXfer;
+ char *buffer;
+
+ /* Clear our structures */
+ memset(&setupMemXfer, 0, sizeof(TW_SETUPMEMXFER));
+ memset(&imageMemXfer, 0, sizeof(TW_IMAGEMEMXFER));
+
+ /* Find out how the source would like to transfer... */
+ twSession->twRC = callDSM(APP_IDENTITY(twSession), DS_IDENTITY(twSession),
+ DG_CONTROL, DAT_SETUPMEMXFER, MSG_GET,
+ (TW_MEMREF) &setupMemXfer);
+
+ /* Allocate the buffer for the transfer */
+ buffer = g_new (char, setupMemXfer.Preferred);
+ imageMemXfer.Memory.Flags = TWMF_APPOWNS | TWMF_POINTER;
+ imageMemXfer.Memory.Length = setupMemXfer.Preferred;
+ imageMemXfer.Memory.TheMem = (TW_MEMREF) buffer;
+
+ /* Get the data */
+ do {
+ /* Setup for the memory transfer */
+ imageMemXfer.Compression = TWON_DONTCARE16;
+ imageMemXfer.BytesPerRow = TWON_DONTCARE32;
+ imageMemXfer.Columns = TWON_DONTCARE32;
+ imageMemXfer.Rows = TWON_DONTCARE32;
+ imageMemXfer.XOffset = TWON_DONTCARE32;
+ imageMemXfer.YOffset = TWON_DONTCARE32;
+ imageMemXfer.BytesWritten = TWON_DONTCARE32;
+
+ /* Get the next block of memory */
+ twSession->twRC = callDSM(APP_IDENTITY(twSession), DS_IDENTITY(twSession),
+ DG_IMAGE, DAT_IMAGEMEMXFER, MSG_GET,
+ (TW_MEMREF) &imageMemXfer);
+
+ if ((twSession->twRC == TWRC_SUCCESS) ||
+ (twSession->twRC == TWRC_XFERDONE)) {
+ /* Call the callback function */
+ if (!(*twSession->transferFunctions->txfrDataCb) (
+ imageInfo,
+ &imageMemXfer,
+ twSession->clientData)) {
+ /* Callback function requested to cancel */
+ twSession->twRC = TWRC_CANCEL;
+ break;
+ }
+ }
+ } while (twSession->twRC == TWRC_SUCCESS);
+
+ /* Free the memory buffer */
+ g_free (imageMemXfer.Memory.TheMem);
+}
+
+/*
+ * endPendingTransfer
+ *
+ * Cancel the currently pending transfer.
+ * Return the count of pending transfers.
+ */
+static int
+endPendingTransfer(pTW_SESSION twSession)
+{
+ TW_PENDINGXFERS pendingXfers;
+
+ twSession->twRC = callDSM(APP_IDENTITY(twSession), DS_IDENTITY(twSession),
+ DG_CONTROL, DAT_PENDINGXFERS, MSG_ENDXFER,
+ (TW_MEMREF) &pendingXfers);
+
+ if (!pendingXfers.Count)
+ twSession->twainState = 5;
+
+ return pendingXfers.Count;
+}
+
+/*
+ * cancelPendingTransfers
+ *
+ * Cancel all pending image transfers.
+ */
+void
+cancelPendingTransfers(pTW_SESSION twSession)
+{
+ TW_PENDINGXFERS pendingXfers;
+
+ twSession->twRC = callDSM(APP_IDENTITY(twSession), DS_IDENTITY(twSession),
+ DG_CONTROL, DAT_PENDINGXFERS, MSG_RESET,
+ (TW_MEMREF) &pendingXfers);
+}
+
+/*
+ * endImageTransfer
+ *
+ * Finish transferring an image. Return the count
+ * of pending images.
+ */
+static int
+endImageTransfer(pTW_SESSION twSession, int *pendingCount)
+{
+ gboolean continueTransfers;
+ int exitCode = twSession->twRC;
+
+ /* Have now exited the transfer for some reason... Figure out
+ * why and what to do about it
+ */
+ switch (twSession->twRC) {
+ case TWRC_XFERDONE:
+ case TWRC_CANCEL:
+ LogMessage("Xfer done received\n");
+ *pendingCount = endPendingTransfer(twSession);
+ break;
+
+ case TWRC_FAILURE:
+ LogMessage("Failure received\n");
+ *pendingCount = endPendingTransfer(twSession);
+ break;
+ }
+
+ /* Call the end transfer callback */
+ if (twSession->transferFunctions->txfrEndCb)
+ continueTransfers =
+ (*twSession->transferFunctions->txfrEndCb)(exitCode,
+ *pendingCount,
+ twSession->clientData);
+
+ return (*pendingCount && continueTransfers);
+}
+
+/*
+ * transferImages
+ *
+ * Transfer all of the images that are available from the
+ * datasource.
+ */
+static void
+transferImages(pTW_SESSION twSession)
+{
+ TW_IMAGEINFO imageInfo;
+ int pendingCount;
+
+ /* Check the image transfer callback function
+ * before even attempting to do the transfer
+ */
+ if (!twSession->transferFunctions || !twSession->transferFunctions->txfrDataCb) {
+ LogMessage("Attempting image transfer without callback function\n");
+ return;
+ }
+
+ /*
+ * Inform our application that we are getting ready
+ * to transfer images.
+ */
+ if (twSession->transferFunctions->preTxfrCb)
+ (*twSession->transferFunctions->preTxfrCb)(twSession->clientData);
+
+ /* Loop through the available images */
+ do {
+ /* Move to the new state */
+ twSession->twainState = 6;
+
+ /* Begin the image transfer */
+ if (!beginImageTransfer(twSession, &imageInfo))
+ continue;
+
+ /* Call the image transfer function */
+ transferImage(twSession, &imageInfo);
+
+ } while (endImageTransfer(twSession, &pendingCount));
+
+ /*
+ * Inform our application that we are done
+ * transferring images.
+ */
+ if (twSession->transferFunctions->postTxfrCb)
+ (*twSession->transferFunctions->postTxfrCb)(pendingCount,
+ twSession->clientData);
+}
+
+void
+processTwainMessage(TW_UINT16 message, pTW_SESSION twSession)
+{
+ switch (message) {
+ case MSG_XFERREADY:
+ LogMessage("Source says that data is ready\n");
+ transferImages(twSession);
+ break;
+
+ case MSG_CLOSEDSREQ:
+ /* Disable the datasource, Close the Data source
+ * and close the data source manager
+ */
+ LogMessage("CloseDSReq\n");
+ disableDS(twSession);
+ closeDS(twSession);
+ closeDSM(twSession);
+ break;
+
+ /* No message from the Source to the App break;
+ * possible new message
+ */
+ case MSG_NULL:
+ default:
+ break;
+ }
+}
+
+/**********************************************************************
+ * Session related functions
+ **********************************************************************/
+
+/*
+ * newSession
+ *
+ * Create a new TWAIN session.
+ */
+pTW_SESSION
+newSession(pTW_IDENTITY appIdentity) {
+ /* Create the structure */
+ pTW_SESSION session = g_new (TW_SESSION, 1);
+
+ /* Set the structure fields */
+ session->hwnd = 0;
+ session->twRC = TWRC_SUCCESS;
+ session->appIdentity = appIdentity;
+ session->dsIdentity = g_new (TW_IDENTITY, 1);
+ session->dsIdentity->Id = 0;
+ session->dsIdentity->ProductName[0] = '\0';
+ session->transferFunctions = NULL;
+
+ if (twainIsAvailable())
+ session->twainState = 2;
+ else
+ session->twainState = 0;
+
+ return session;
+}
+
+/*
+ * registerWindowHandle
+ *
+ * Register the window handle to be used for this
+ * session.
+ */
+void
+registerWindowHandle(pTW_SESSION session, TW_HANDLE hwnd)
+{
+ session->hwnd = hwnd;
+}
+
+/*
+ * registerTransferCallback
+ *
+ * Register the callback to use when transferring
+ * image data.
+ */
+void
+registerTransferCallbacks(pTW_SESSION session,
+ pTXFR_CB_FUNCS txfrFuncs,
+ void *clientData)
+{
+ session->transferFunctions = txfrFuncs;
+ session->clientData = clientData;
+}
+
+/*
+ * setClientData
+ *
+ * Set the client data associated with the specified
+ * TWAIN session.
+ */
+void
+setClientData(pTW_SESSION session, void *clientData)
+{
+ session->clientData = clientData;
+}
diff --git a/plug-ins/twain/tw_func.h b/plug-ins/twain/tw_func.h
new file mode 100644
index 0000000..69d305c
--- /dev/null
+++ b/plug-ins/twain/tw_func.h
@@ -0,0 +1,243 @@
+/*
+ * TWAIN Plug-in
+ * Copyright (C) 1999 Craig Setera
+ * Craig Setera <setera@home.com>
+ * 03/31/1999
+ *
+ * Updated for Mac OS X support
+ * Brion Vibber <brion@pobox.com>
+ * 07/22/2004
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ *
+ *
+ * Based on (at least) the following plug-ins:
+ * Screenshot
+ * GIF
+ * Randomize
+ *
+ * Any suggestions, bug-reports or patches are welcome.
+ *
+ * This plug-in interfaces to the TWAIN support library in order
+ * to capture images from TWAIN devices directly into GIMP images.
+ * The plug-in is capable of acquiring the following type of
+ * images:
+ * - B/W (1 bit images translated to grayscale B/W)
+ * - Grayscale up to 16 bits per pixel
+ * - RGB up to 16 bits per sample (24, 30, 36, etc.)
+ * - Paletted images (both Gray and RGB)
+ *
+ * Prerequisites:
+ * Should compile and run on both Win32 and Mac OS X 10.3 (possibly
+ * also on 10.2).
+ *
+ * Known problems:
+ * - Multiple image transfers will hang the plug-in. The current
+ * configuration compiles with a maximum of single image transfers.
+ * - On Mac OS X, canceling doesn't always close things out fully.
+ * - Epson TWAIN driver on Mac OS X crashes the plugin when scanning.
+ */
+
+/*
+ * Revision history
+ * (02/07/99) v0.1 First working version (internal)
+ * (02/09/99) v0.2 First release to anyone other than myself
+ * (02/15/99) v0.3 Added image dump and read support for debugging
+ * (03/31/99) v0.5 Added support for multi-byte samples and paletted
+ * images.
+ * (07/23/04) v0.6 Added Mac OS X support.
+ */
+
+#ifndef _TW_FUNC_H
+#define _TW_FUNC_H
+
+#include "tw_platform.h"
+
+/*
+ * Pre-image transfer function type
+ *
+ * Sent to the caller before any of the
+ * images are transferred to the application.
+ */
+typedef void (* TW_PRE_TXFR_CB)(void *);
+
+/*
+ * Image transfer begin function type
+ *
+ * Sent to the caller when an image transfer
+ * is about to begin. The caller may return
+ * FALSE if the transfer should not continue.
+ * Otherwise, the function should return a
+ * TRUE value.
+ */
+typedef int (* TW_TXFR_BEGIN_CB)(pTW_IMAGEINFO, void *);
+
+/*
+ * Image transfer callback function type
+ *
+ * Expected to return true if the image transfer
+ * should continue. False if the transfer should
+ * be cancelled.
+ */
+typedef int (* TW_TXFR_DATA_CB)(pTW_IMAGEINFO, pTW_IMAGEMEMXFER, void *);
+
+/*
+ * Image transfer end function type
+ *
+ * Sent to the caller when an image transfer
+ * is completed. The caller will be handed
+ * the image transfer completion state. The
+ * following values (defined in twain.h) are
+ * possible:
+ *
+ * TWRC_XFERDONE
+ * The transfer completed successfully
+ * TWRC_CANCEL
+ * The transfer was completed by the user
+ * TWRC_FAILURE
+ * The transfer failed.
+ */
+typedef int (* TW_TXFR_END_CB)(int, int, void *);
+
+/*
+ * Post-image transfer callback
+ *
+ * This callback function is called after all
+ * of the possible images have been transferred
+ * from the datasource.
+ */
+typedef void (* TW_POST_TXFR_CB)(int, void *);
+
+/*
+ * The following structure defines the
+ * three callback functions that are called
+ * while an image is being transferred.
+ * The types of these functions are defined
+ * above. Any function that is NULL will just
+ * not be called.
+ */
+typedef struct _TXFR_CB_FUNCS {
+ /* Pre-transfer function */
+ TW_PRE_TXFR_CB preTxfrCb;
+
+ /* Begin function */
+ TW_TXFR_BEGIN_CB txfrBeginCb;
+
+ /* Data transfer */
+ TW_TXFR_DATA_CB txfrDataCb;
+
+ /* End function */
+ TW_TXFR_END_CB txfrEndCb;
+
+ /* Post-transfer function */
+ TW_POST_TXFR_CB postTxfrCb;
+} TXFR_CB_FUNCS, *pTXFR_CB_FUNCS;
+
+/*
+ * Data representing a TWAIN
+ * application to data source
+ * session.
+ */
+typedef struct _TWAIN_SESSION {
+ /* The window handle related to the TWAIN application on Win32 */
+ TW_HANDLE hwnd;
+
+ /* The current TWAIN return code */
+ TW_UINT16 twRC;
+
+ /* The application's TWAIN identity */
+ pTW_IDENTITY appIdentity;
+
+ /* The datasource's TWAIN identity */
+ pTW_IDENTITY dsIdentity;
+
+ /* The image data transfer functions */
+ pTXFR_CB_FUNCS transferFunctions;
+
+ /* Client data that is associated with the image
+ * transfer callback
+ */
+ void *clientData;
+
+ /*
+ * The following variable tracks the current state
+ * as related to the TWAIN engine. The states are:
+ *
+ * 1) Pre-session: The DSM has not been loaded
+ * 2) Source Manager Loaded (not opened)
+ * 3) Source Manager Opened
+ * 4) Source Open
+ * 5) Source Enabled
+ * 6) Transfer ready
+ * 7) Transferring
+ */
+ int twainState;
+
+} TW_SESSION, *pTW_SESSION;
+
+/* Session structure access
+ * macros
+ */
+/* #define pAPP_IDENTITY(tw_session) (&(tw_session->appIdentity)) */
+#define APP_IDENTITY(tw_session) (tw_session->appIdentity)
+/* #define pDS_IDENTITY(tw_session) (&(tw_session->dsIdentity)) */
+#define DS_IDENTITY(tw_session) (tw_session->dsIdentity)
+
+/* State macros... Each expects
+ * a Twain Session pointer
+ */
+#define TWAIN_LOADED(tw_session) (tw_session->twainState >= 2)
+#define TWAIN_UNLOADED(tw_session) (tw_session->twainState < 2)
+#define DSM_IS_OPEN(tw_session) (tw_session->twainState >= 3)
+#define DSM_IS_CLOSED(tw_session) (tw_session->twainState < 3)
+#define DS_IS_OPEN(tw_session) (tw_session->twainState >= 4)
+#define DS_IS_CLOSED(tw_session) (tw_session->twainState < 4)
+#define DS_IS_ENABLED(tw_session) (tw_session->twainState >= 5)
+#define DS_IS_DISABLED(tw_session) (tw_session->twainState < 5)
+
+/* Function declarations */
+char *twainError(int);
+char *currentTwainError(pTW_SESSION);
+int getImage(pTW_SESSION);
+int loadTwainLibrary(pTW_SESSION);
+int unloadTwainLibrary(pTW_SESSION twSession);
+int openDSM(pTW_SESSION);
+int selectDS(pTW_SESSION);
+int selectDefaultDS(pTW_SESSION);
+int openDS(pTW_SESSION);
+int requestImageAcquire(pTW_SESSION, gboolean);
+int disableDS(pTW_SESSION);
+int closeDS(pTW_SESSION);
+int closeDSM(pTW_SESSION);
+void cancelPendingTransfers(pTW_SESSION);
+int scanImage (void);
+
+TW_FIX32 FloatToFIX32(float);
+float FIX32ToFloat(TW_FIX32);
+
+void processTwainMessage(TW_UINT16 message, pTW_SESSION twSession);
+
+pTW_SESSION newSession(pTW_IDENTITY);
+void registerWindowHandle(pTW_SESSION, TW_HANDLE);
+void registerTransferCallbacks(pTW_SESSION, pTXFR_CB_FUNCS, void *);
+void setClientData(pTW_SESSION session, void *clientData);
+pTW_SESSION initializeTwain(void);
+
+#ifdef G_OS_WIN32
+void LogLastWinError(void);
+BOOL InitApplication(HINSTANCE hInstance);
+BOOL InitInstance(HINSTANCE hInstance, int nCmdShow, pTW_SESSION twSession);
+#endif
+
+#endif /* _TW_FUNC_H */
diff --git a/plug-ins/twain/tw_local.h b/plug-ins/twain/tw_local.h
new file mode 100644
index 0000000..88348ab
--- /dev/null
+++ b/plug-ins/twain/tw_local.h
@@ -0,0 +1,48 @@
+/*
+ * TWAIN Plug-in
+ * Copyright (C) 1999 Craig Setera
+ * Craig Setera <setera@home.com>
+ * 03/31/1999
+ *
+ * Updated for Mac OS X support
+ * Brion Vibber <brion@pobox.com>
+ * 07/22/2004
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+#ifndef _TW_LOCAL_H
+#define _TW_LOCAL_H
+
+#include "tw_func.h"
+
+/* Functions which the platform-independent code will call */
+
+TW_UINT16 callDSM(pTW_IDENTITY, pTW_IDENTITY,
+ TW_UINT32, TW_UINT16,
+ TW_UINT16, TW_MEMREF);
+
+int twainIsAvailable(void);
+void twainQuitApplication (void);
+gboolean twainSetupCallback (pTW_SESSION twSession);
+
+TW_HANDLE twainAllocHandle(size_t size);
+TW_MEMREF twainLockHandle (TW_HANDLE handle);
+void twainUnlockHandle (TW_HANDLE handle);
+void twainFreeHandle (TW_HANDLE handle);
+
+int twainMain (void);
+int scanImage (void);
+
+#endif
diff --git a/plug-ins/twain/tw_platform.h b/plug-ins/twain/tw_platform.h
new file mode 100644
index 0000000..de0263b
--- /dev/null
+++ b/plug-ins/twain/tw_platform.h
@@ -0,0 +1,37 @@
+/*
+ * TWAIN Plug-in
+ * Copyright (C) 1999 Craig Setera
+ * Craig Setera <setera@home.com>
+ * 03/31/1999
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+#ifndef _TW_PLATFORM_H
+#define _TW_PLATFORM_H
+
+#include <windows.h>
+#include "twain.h"
+
+/* The DLL to be loaded for TWAIN support */
+#define TWAIN_DLL_NAME "TWAIN_32.DLL"
+#define DEBUG_LOGFILE "c:\\twain.log"
+#define DUMP_FILE "C:\\TWAINCAP.BIN"
+#define DUMP_NAME "DTWAIN.EXE"
+#define READDUMP_NAME "RTWAIN.EXE"
+
+/* Windows uses separate entry point */
+#define TWAIN_ALTERNATE_MAIN
+
+#endif
diff --git a/plug-ins/twain/tw_util.c b/plug-ins/twain/tw_util.c
new file mode 100644
index 0000000..f02109b
--- /dev/null
+++ b/plug-ins/twain/tw_util.c
@@ -0,0 +1,170 @@
+/*
+ * TWAIN Plug-in
+ * Copyright (C) 1999 Craig Setera
+ * Craig Setera <setera@home.com>
+ * 03/31/1999
+ *
+ * Updated for Mac OS X support
+ * Brion Vibber <brion@pobox.com>
+ * 07/22/2004
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ *
+ *
+ * Based on (at least) the following plug-ins:
+ * Screenshot
+ * GIF
+ * Randomize
+ *
+ * Any suggestions, bug-reports or patches are welcome.
+ *
+ * This plug-in interfaces to the TWAIN support library in order
+ * to capture images from TWAIN devices directly into GIMP images.
+ * The plug-in is capable of acquiring the following type of
+ * images:
+ * - B/W (1 bit images translated to grayscale B/W)
+ * - Grayscale up to 16 bits per pixel
+ * - RGB up to 16 bits per sample (24, 30, 36, etc.)
+ * - Paletted images (both Gray and RGB)
+ *
+ * Prerequisites:
+ * Should compile and run on both Win32 and Mac OS X 10.3 (possibly
+ * also on 10.2).
+ *
+ * Known problems:
+ * - Multiple image transfers will hang the plug-in. The current
+ * configuration compiles with a maximum of single image transfers.
+ * - On Mac OS X, canceling doesn't always close things out fully.
+ * - Epson TWAIN driver on Mac OS X crashes the plugin when scanning.
+ */
+
+/*
+ * Revision history
+ * (02/07/99) v0.1 First working version (internal)
+ * (02/09/99) v0.2 First release to anyone other than myself
+ * (02/15/99) v0.3 Added image dump and read support for debugging
+ * (03/31/99) v0.5 Added support for multi-byte samples and paletted
+ * images.
+ * (07/23/04) v0.6 Added Mac OS X support.
+ */
+
+#include "config.h"
+
+#include <glib.h> /* Needed when compiling with gcc */
+
+#include <glib/gstdio.h>
+
+#include <stdarg.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+
+#include "tw_util.h"
+#ifdef _DEBUG
+#include "tw_func.h"
+FILE *logFile = NULL;
+#endif
+
+#ifdef _DEBUG
+
+/*
+ * LogMessage
+ */
+void
+LogMessage(char *format, ...)
+{
+ va_list args;
+ time_t time_of_day;
+ char *ctime_string;
+
+ /* Open the log file as necessary */
+ if (!logFile)
+ logFile = g_fopen(DEBUG_LOGFILE, "w");
+
+ time_of_day = time(NULL);
+ ctime_string = ctime(&time_of_day);
+ ctime_string[19] = '\0';
+
+ fprintf(logFile, "[%s] ", (ctime_string + 11));
+ va_start(args, format);
+ vfprintf(logFile, format, args);
+ fflush(logFile);
+ va_end(args);
+}
+
+void
+logBegin(pTW_IMAGEINFO imageInfo, void *clientData)
+{
+ int i;
+ char buffer[256];
+
+ LogMessage("\n");
+ LogMessage("*************************************\n");
+ LogMessage("\n");
+ LogMessage("Image transfer begin:\n");
+ /* LogMessage("\tClient data: %s\n", (char *) clientData); */
+
+ /* Log the image information */
+ LogMessage("Image information:\n");
+ LogMessage("\tXResolution: %f\n", FIX32ToFloat(imageInfo->XResolution));
+ LogMessage("\tYResolution: %f\n", FIX32ToFloat(imageInfo->YResolution));
+ LogMessage("\tImageWidth: %d\n", imageInfo->ImageWidth);
+ LogMessage("\tImageLength: %d\n", imageInfo->ImageLength);
+ LogMessage("\tSamplesPerPixel: %d\n", imageInfo->SamplesPerPixel);
+ sprintf(buffer, "\tBitsPerSample: {");
+ for (i = 0; i < 8; i++) {
+ if (imageInfo->BitsPerSample[i])
+ strcat(buffer, "1");
+ else
+ strcat(buffer, "0");
+
+ if (i != 7)
+ strcat(buffer, ",");
+ }
+ LogMessage("%s}\n", buffer);
+
+ LogMessage("\tBitsPerPixel: %d\n", imageInfo->BitsPerPixel);
+ LogMessage("\tPlanar: %s\n", (imageInfo->Planar ? "TRUE" : "FALSE"));
+ LogMessage("\tPixelType: %d\n", imageInfo->PixelType);
+ /* Compression */
+
+}
+
+void
+logData(pTW_IMAGEINFO imageInfo,
+ pTW_IMAGEMEMXFER imageMemXfer,
+ void *clientData)
+{
+ LogMessage("Image transfer callback called:\n");
+ LogMessage("\tClient data: %s\n", (char *) clientData);
+ LogMessage("Memory block transferred:\n");
+ LogMessage("\tBytesPerRow = %d\n", imageMemXfer->BytesPerRow);
+ LogMessage("\tColumns = %d\n", imageMemXfer->Columns);
+ LogMessage("\tRows = %d\n", imageMemXfer->Rows);
+ LogMessage("\tXOffset = %d\n", imageMemXfer->XOffset);
+ LogMessage("\tYOffset = %d\n", imageMemXfer->YOffset);
+ LogMessage("\tBytesWritten = %d\n", imageMemXfer->BytesWritten);
+}
+
+#else
+
+/*
+ * LogMessage
+ */
+void
+LogMessage(char *format, ...)
+{
+}
+
+#endif /* DEBUG */
diff --git a/plug-ins/twain/tw_util.h b/plug-ins/twain/tw_util.h
new file mode 100644
index 0000000..8fac459
--- /dev/null
+++ b/plug-ins/twain/tw_util.h
@@ -0,0 +1,73 @@
+/*
+ * TWAIN Plug-in
+ * Copyright (C) 1999 Craig Setera
+ * Craig Setera <setera@home.com>
+ * 03/31/1999
+ *
+ * Updated for Mac OS X support
+ * Brion Vibber <brion@pobox.com>
+ * 07/22/2004
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ *
+ *
+ * Based on (at least) the following plug-ins:
+ * Screenshot
+ * GIF
+ * Randomize
+ *
+ * Any suggestions, bug-reports or patches are welcome.
+ *
+ * This plug-in interfaces to the TWAIN support library in order
+ * to capture images from TWAIN devices directly into GIMP images.
+ * The plug-in is capable of acquiring the following type of
+ * images:
+ * - B/W (1 bit images translated to grayscale B/W)
+ * - Grayscale up to 16 bits per pixel
+ * - RGB up to 16 bits per sample (24, 30, 36, etc.)
+ * - Paletted images (both Gray and RGB)
+ *
+ * Prerequisites:
+ * Should compile and run on both Win32 and Mac OS X 10.3 (possibly
+ * also on 10.2).
+ *
+ * Known problems:
+ * - Multiple image transfers will hang the plug-in. The current
+ * configuration compiles with a maximum of single image transfers.
+ * - On Mac OS X, canceling doesn't always close things out fully.
+ * - Epson TWAIN driver on Mac OS X crashes the plugin when scanning.
+ */
+
+/*
+ * Revision history
+ * (02/07/99) v0.1 First working version (internal)
+ * (02/09/99) v0.2 First release to anyone other than myself
+ * (02/15/99) v0.3 Added image dump and read support for debugging
+ * (03/31/99) v0.5 Added support for multi-byte samples and paletted
+ * images.
+ * (07/23/04) v0.6 Added Mac OS X support.
+ */
+#ifndef __TW_UTIL_H
+#define __TW_UTIL_H
+
+#include "tw_platform.h"
+
+void LogMessage(char *, ...);
+
+#ifdef _DEBUG
+void logBegin(pTW_IMAGEINFO, void *);
+void logData(pTW_IMAGEINFO, pTW_IMAGEMEMXFER, void *);
+#endif
+
+#endif /* __TW_UTIL_H */
diff --git a/plug-ins/twain/tw_win.c b/plug-ins/twain/tw_win.c
new file mode 100644
index 0000000..726a45f
--- /dev/null
+++ b/plug-ins/twain/tw_win.c
@@ -0,0 +1,452 @@
+/*
+ * TWAIN Plug-in
+ * Copyright (C) 1999 Craig Setera
+ * Craig Setera <setera@home.com>
+ * 03/31/1999
+ *
+ * Updated for Mac OS X support
+ * Brion Vibber <brion@pobox.com>
+ * 07/22/2004
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+/*
+ * Windows platform-specific code
+ */
+
+#include "config.h"
+
+#include <libgimp/gimp.h>
+
+#include "tw_platform.h"
+#include "tw_func.h"
+#include "tw_util.h"
+#include "tw_local.h"
+
+LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
+
+int twainMessageLoop(pTW_SESSION);
+int TwainProcessMessage(LPMSG lpMsg, pTW_SESSION twSession);
+
+extern GimpPlugInInfo PLUG_IN_INFO;
+extern pTW_SESSION initializeTwain ();
+#ifdef _DEBUG
+extern void setRunMode(char *argv[]);
+#endif
+
+
+#define APP_NAME "TWAIN"
+#define SHOW_WINDOW 0
+#define WM_TRANSFER_IMAGE (WM_USER + 100)
+
+/* main bits */
+static HWND hwnd = NULL;
+static HINSTANCE hInst = NULL;
+
+/* Storage for the DLL handle */
+static HINSTANCE hDLL = NULL;
+
+/* Storage for the entry point into the DSM */
+static DSMENTRYPROC dsmEntryPoint = NULL;
+
+
+/*
+ * callDSM
+ *
+ * Call the specified function on the data source manager.
+ */
+TW_UINT16
+callDSM(pTW_IDENTITY pOrigin,
+ pTW_IDENTITY pDest,
+ TW_UINT32 DG,
+ TW_UINT16 DAT,
+ TW_UINT16 MSG,
+ TW_MEMREF pData)
+{
+ /* Call the function */
+ return (*dsmEntryPoint) (pOrigin, pDest, DG, DAT, MSG, pData);
+}
+
+/*
+ * twainIsAvailable
+ *
+ * Return boolean indicating whether TWAIN is available
+ */
+int
+twainIsAvailable(void)
+{
+ /* Already loaded? */
+ if (dsmEntryPoint) {
+ return TRUE;
+ }
+
+ /* Attempt to load the library */
+ hDLL = LoadLibrary(TWAIN_DLL_NAME);
+ if (hDLL == NULL)
+ return FALSE;
+
+ /* Look up the entry point for use */
+ dsmEntryPoint = (DSMENTRYPROC) GetProcAddress(hDLL, "DSM_Entry");
+ if (dsmEntryPoint == NULL)
+ return FALSE;
+
+ return TRUE;
+}
+
+TW_HANDLE
+twainAllocHandle (size_t size)
+{
+ return GlobalAlloc(GHND, size);
+}
+
+TW_MEMREF
+twainLockHandle (TW_HANDLE handle)
+{
+ return GlobalLock (handle);
+}
+
+void
+twainUnlockHandle (TW_HANDLE handle)
+{
+ GlobalUnlock (handle);
+}
+
+void
+twainFreeHandle (TW_HANDLE handle)
+{
+ GlobalFree (handle);
+}
+
+gboolean
+twainSetupCallback (pTW_SESSION twSession)
+{
+ /* Callbacks go through the window messaging system */
+ return TRUE;
+}
+
+/*
+ * unloadTwainLibrary
+ *
+ * Unload the TWAIN dynamic link library
+ */
+int
+unloadTwainLibrary(pTW_SESSION twSession)
+{
+ /* Explicitly free the SM library */
+ if (hDLL) {
+ FreeLibrary(hDLL);
+ hDLL=NULL;
+ }
+
+ /* the data source id will no longer be valid after
+ * twain is killed. If the id is left around the
+ * data source can not be found or opened
+ */
+ DS_IDENTITY(twSession)->Id = 0;
+
+ /* We are now back at state 1 */
+ twSession->twainState = 1;
+ LogMessage("Source Manager successfully closed\n");
+
+ return TRUE;
+}
+
+/*
+ * TwainProcessMessage
+ *
+ * Returns TRUE if the application should process message as usual.
+ * Returns FALSE if the application should skip processing of this message
+ */
+int
+TwainProcessMessage(LPMSG lpMsg, pTW_SESSION twSession)
+{
+ TW_EVENT twEvent;
+
+ twSession->twRC = TWRC_NOTDSEVENT;
+
+ /* Only ask Source Manager to process event if there is a Source connected. */
+ if (DSM_IS_OPEN(twSession) && DS_IS_OPEN(twSession)) {
+ /*
+ * A Source provides a modeless dialog box as its user interface.
+ * The following call relays Windows messages down to the Source's
+ * UI that were intended for its dialog box. It also retrieves TWAIN
+ * messages sent from the Source to our Application.
+ */
+ twEvent.pEvent = (TW_MEMREF) lpMsg;
+ twSession->twRC = callDSM(APP_IDENTITY(twSession), DS_IDENTITY(twSession),
+ DG_CONTROL, DAT_EVENT, MSG_PROCESSEVENT,
+ (TW_MEMREF) &twEvent);
+
+ /* Check the return code */
+ if (twSession->twRC == TWRC_NOTDSEVENT) {
+ return FALSE;
+ }
+
+ /* Process the message as necessary */
+ processTwainMessage(twEvent.TWMessage, twSession);
+ }
+
+ /* tell the caller what happened */
+ return (twSession->twRC == TWRC_DSEVENT);
+}
+
+/*
+ * twainMessageLoop
+ *
+ * Process Win32 window messages and provide special handling
+ * of TWAIN specific messages. This loop will not exit until
+ * the application exits.
+ */
+int
+twainMessageLoop(pTW_SESSION twSession)
+{
+ MSG msg;
+
+ while (GetMessage(&msg, NULL, 0, 0)) {
+ if (DS_IS_CLOSED(twSession) || !TwainProcessMessage(&msg, twSession)) {
+ TranslateMessage((LPMSG)&msg);
+ DispatchMessage(&msg);
+ }
+ }
+
+ return msg.wParam;
+}
+
+/*
+ * LogLastWinError
+ *
+ * Log the last Windows error as returned by
+ * GetLastError.
+ */
+void
+LogLastWinError(void)
+{
+ LPVOID lpMsgBuf;
+
+ FormatMessage(
+ FORMAT_MESSAGE_ALLOCATE_BUFFER |
+ FORMAT_MESSAGE_FROM_SYSTEM |
+ FORMAT_MESSAGE_IGNORE_INSERTS,
+ NULL,
+ GetLastError(),
+ MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), /* Default language */
+ (LPTSTR) &lpMsgBuf,
+ 0,
+ NULL
+ );
+
+ LogMessage("%s\n", lpMsgBuf);
+
+ /* Free the buffer. */
+ LocalFree( lpMsgBuf );
+}
+
+void twainQuitApplication ()
+{
+ PostQuitMessage (0);
+}
+
+
+/******************************************************************
+ * Win32 entry point and setup...
+ ******************************************************************/
+
+/*
+ * WinMain
+ *
+ * The standard gimp entry point won't quite cut it for
+ * this plug-in. This plug-in requires creation of a
+ * standard Win32 window (hidden) in order to receive
+ * and process window messages on behalf of the TWAIN
+ * datasource.
+ */
+int APIENTRY
+WinMain(HINSTANCE hInstance,
+ HINSTANCE hPrevInstance,
+ LPSTR lpCmdLine,
+ int nCmdShow)
+{
+
+ /*
+ * Normally, we would do all of the Windows-ish set up of
+ * the window classes and stuff here in WinMain. But,
+ * the only time we really need the window and message
+ * queues is during the plug-in run. So, all of that will
+ * be done during run(). This avoids all of the Windows
+ * setup stuff for the query(). Stash the instance handle now
+ * so it is available from the run() procedure.
+ */
+ hInst = hInstance;
+
+#ifdef _DEBUG
+ /* When in debug version, we allow different run modes...
+ * make sure that it is correctly set.
+ */
+ setRunMode(__argv);
+#endif /* _DEBUG */
+
+ /*
+ * Now, call gimp_main... This is what the MAIN() macro
+ * would usually do.
+ */
+ return gimp_main(&PLUG_IN_INFO, __argc, __argv);
+}
+
+/*
+ * main
+ *
+ * allow to build as console app as well
+ */
+int main (int argc, char *argv[])
+{
+#ifdef _DEBUG
+ /* When in debug version, we allow different run modes...
+ * make sure that it is correctly set.
+ */
+ setRunMode(__argv);
+#endif /* _DEBUG */
+
+ /*
+ * Now, call gimp_main... This is what the MAIN() macro
+ * would usually do.
+ */
+ return gimp_main(&PLUG_IN_INFO, __argc, __argv);
+}
+
+/*
+ * InitApplication
+ *
+ * Initialize window data and register the window class
+ */
+BOOL
+InitApplication(HINSTANCE hInstance)
+{
+ WNDCLASS wc;
+ BOOL retValue;
+
+ /*
+ * Fill in window class structure with parameters to describe
+ * the main window.
+ */
+ wc.style = CS_HREDRAW | CS_VREDRAW;
+ wc.lpfnWndProc = (WNDPROC) WndProc;
+ wc.cbClsExtra = 0;
+ wc.cbWndExtra = 0;
+ wc.hInstance = hInstance;
+ wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
+ wc.hCursor = LoadCursor(NULL, IDC_ARROW);
+ wc.hbrBackground = (HBRUSH) (COLOR_WINDOW + 1);
+ wc.lpszClassName = APP_NAME;
+ wc.lpszMenuName = NULL;
+
+ /* Register the window class and stash success/failure code. */
+ retValue = RegisterClass(&wc);
+
+ /* Log error */
+ if (!retValue)
+ LogLastWinError();
+
+ return retValue;
+}
+
+/*
+ * InitInstance
+ *
+ * Create the main window for the application. Used to
+ * interface with the TWAIN datasource.
+ */
+BOOL
+InitInstance(HINSTANCE hInstance, int nCmdShow, pTW_SESSION twSession)
+{
+ /* Create our window */
+ hwnd = CreateWindow(APP_NAME, APP_NAME, WS_OVERLAPPEDWINDOW,
+ CW_USEDEFAULT, 0, CW_USEDEFAULT, 0,
+ NULL, NULL, hInstance, NULL);
+
+ if (!hwnd) {
+ return (FALSE);
+ }
+
+ /* Register our window handle with the TWAIN
+ * support.
+ */
+ registerWindowHandle(twSession, hwnd);
+
+ /* Schedule the image transfer by posting a message */
+ PostMessage(hwnd, WM_TRANSFER_IMAGE, 0, 0);
+
+ ShowWindow(hwnd, nCmdShow);
+ UpdateWindow(hwnd);
+
+ return TRUE;
+}
+
+/*
+ * twainWinMain
+ *
+ * This is the function that represents the code that
+ * would normally reside in WinMain (see above). This
+ * function will get called during run() in order to set
+ * up the windowing environment necessary for TWAIN to
+ * operate.
+ */
+int
+twainMain()
+{
+ /* Initialize the twain information */
+ pTW_SESSION twSession = initializeTwain();
+
+ /* Perform instance initialization */
+ if (!InitApplication(hInst))
+ return (FALSE);
+
+ /* Perform application initialization */
+ if (!InitInstance(hInst, SHOW_WINDOW, twSession))
+ return (FALSE);
+
+ /*
+ * Call the main message processing loop...
+ * This call will not return until the application
+ * exits.
+ */
+ return twainMessageLoop(twSession);
+}
+
+/*
+ * WndProc
+ *
+ * Process window message for the main window.
+ */
+LRESULT CALLBACK
+WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
+{
+ switch (message) {
+
+ case WM_TRANSFER_IMAGE:
+ /* Get an image */
+ scanImage ();
+ break;
+
+ case WM_DESTROY:
+ LogMessage("Exiting application\n");
+ PostQuitMessage(0);
+ break;
+
+ default:
+ return (DefWindowProc(hWnd, message, wParam, lParam));
+ }
+ return 0;
+}
+
diff --git a/plug-ins/twain/twain.c b/plug-ins/twain/twain.c
new file mode 100644
index 0000000..dafb215
--- /dev/null
+++ b/plug-ins/twain/twain.c
@@ -0,0 +1,962 @@
+/*
+ * TWAIN Plug-in
+ * Copyright (C) 1999 Craig Setera
+ * Craig Setera <setera@home.com>
+ * 03/31/1999
+ *
+ * Updated for Mac OS X support
+ * Brion Vibber <brion@pobox.com>
+ * 07/22/2004
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ *
+ *
+ * Based on (at least) the following plug-ins:
+ * Screenshot
+ * GIF
+ * Randomize
+ *
+ * Any suggestions, bug-reports or patches are welcome.
+ *
+ * This plug-in interfaces to the TWAIN support library in order
+ * to capture images from TWAIN devices directly into GIMP images.
+ * The plug-in is capable of acquiring the following type of
+ * images:
+ * - B/W (1 bit images translated to grayscale B/W)
+ * - Grayscale up to 16 bits per pixel
+ * - RGB up to 16 bits per sample (24, 30, 36, etc.)
+ * - Paletted images (both Gray and RGB)
+ *
+ * Prerequisites:
+ * Should compile and run on both Win32 and Mac OS X 10.3 (possibly
+ * also on 10.2).
+ *
+ * Known problems:
+ * - Multiple image transfers will hang the plug-in. The current
+ * configuration compiles with a maximum of single image transfers.
+ * - On Mac OS X, canceling doesn't always close things out fully.
+ * - Epson TWAIN driver on Mac OS X crashes the plugin when scanning.
+ */
+
+/*
+ * Revision history
+ * (02/07/99) v0.1 First working version (internal)
+ * (02/09/99) v0.2 First release to anyone other than myself
+ * (02/15/99) v0.3 Added image dump and read support for debugging
+ * (03/31/99) v0.5 Added support for multi-byte samples and paletted
+ * images.
+ * (07/23/04) v0.6 Added Mac OS X support.
+ */
+#include "config.h"
+
+#include <glib.h> /* Needed when compiling with gcc */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "tw_platform.h"
+#include "tw_local.h"
+
+#include "libgimp/gimp.h"
+#include "libgimp/stdplugins-intl.h"
+
+#include "tw_func.h"
+#include "tw_util.h"
+
+#ifdef _DEBUG
+#include "tw_dump.h"
+#endif /* _DEBUG */
+
+/*
+ * Plug-in Definitions
+ */
+#define PLUG_IN_NAME "twain-acquire"
+#define PLUG_IN_DESCRIPTION N_("Capture an image from a TWAIN datasource")
+#define PLUG_IN_HELP "This plug-in will capture an image from a TWAIN datasource"
+#define PLUG_IN_AUTHOR "Craig Setera (setera@home.com)"
+#define PLUG_IN_COPYRIGHT "Craig Setera"
+#define PLUG_IN_VERSION "v0.6 (07/22/2004)"
+
+#ifdef _DEBUG
+#define PLUG_IN_D_NAME "twain-acquire-dump"
+#define PLUG_IN_R_NAME "twain-acquire-read"
+#endif /* _DEBUG */
+
+/*
+ * Application definitions
+ */
+#define MAX_IMAGES 1
+
+/*
+ * Definition of the run states
+ */
+#define RUN_STANDARD 0
+#define RUN_DUMP 1
+#define RUN_READDUMP 2
+
+/* Global variables */
+pTW_SESSION twSession = NULL;
+
+#ifdef _DEBUG
+static int twain_run_mode = RUN_STANDARD;
+#endif
+
+/* Forward declarations */
+void preTransferCallback (void *clientData);
+int beginTransferCallback (pTW_IMAGEINFO imageInfo,
+ void *clientData);
+int dataTransferCallback (pTW_IMAGEINFO imageInfo,
+ pTW_IMAGEMEMXFER imageMemXfer,
+ void *clientData);
+int endTransferCallback (int completionState,
+ int pendingCount,
+ void *clientData);
+void postTransferCallback (int pendingCount,
+ void *clientData);
+
+static void query (void);
+static void run (const gchar *name,
+ gint nparams,
+ const GimpParam *param,
+ gint *nreturn_vals,
+ GimpParam **return_vals);
+
+
+const GimpPlugInInfo PLUG_IN_INFO =
+{
+ NULL, /* init_proc */
+ NULL, /* quit_proc */
+ query, /* query_proc */
+ run, /* run_proc */
+};
+
+extern void set_gimp_PLUG_IN_INFO_PTR (GimpPlugInInfo *);
+
+/* Data structure holding data between runs */
+/* Currently unused... Eventually may be used
+ * to track dialog data.
+ */
+typedef struct
+{
+ gchar sourceName[34];
+ gfloat xResolution;
+ gfloat yResolution;
+ gint xOffset;
+ gint yOffset;
+ gint width;
+ gint height;
+ gint imageType;
+} TwainValues;
+
+/* Default Twain values */
+static TwainValues twainvals =
+{
+ "",
+ 100.0, 100.0,
+ 0, 0,
+ 0, 0,
+ TWPT_RGB
+};
+
+/* The standard callback functions */
+TXFR_CB_FUNCS standardCbFuncs =
+{
+ preTransferCallback,
+ beginTransferCallback,
+ dataTransferCallback,
+ endTransferCallback,
+ postTransferCallback
+};
+
+/******************************************************************
+ * Dump handling
+ ******************************************************************/
+
+#ifdef _DEBUG
+/* The dumper callback functions */
+TXFR_CB_FUNCS dumperCbFuncs =
+{
+ dumpPreTransferCallback,
+ dumpBeginTransferCallback,
+ dumpDataTransferCallback,
+ dumpEndTransferCallback,
+ dumpPostTransferCallback
+};
+
+void
+setRunMode (char *argv[])
+{
+ char *exeName = strrchr (argv[0], '\\') + 1;
+
+ LogMessage ("Executable name: %s\n", exeName);
+
+ if (!_stricmp (exeName, DUMP_NAME))
+ twain_run_mode = RUN_DUMP;
+
+ if (!_stricmp (exeName, RUNDUMP_NAME))
+ twain_run_mode = RUN_READDUMP;
+}
+#endif /* _DEBUG */
+
+#ifndef TWAIN_ALTERNATE_MAIN
+MAIN ()
+#endif
+
+int
+scanImage (void)
+{
+#ifdef _DEBUG
+ if (twain_run_mode == RUN_READDUMP)
+ return readDumpedImage (twSession);
+ else
+#endif /* _DEBUG */
+ return getImage (twSession);
+}
+
+/*
+ * initTwainAppIdentity
+ *
+ * Initialize and return our application's identity for
+ * the TWAIN runtime.
+ */
+static pTW_IDENTITY
+getAppIdentity (void)
+{
+ pTW_IDENTITY appIdentity = g_new (TW_IDENTITY, 1);
+
+ /* Set up the application identity */
+ appIdentity->Id = 0;
+ appIdentity->Version.MajorNum = 0;
+ appIdentity->Version.MinorNum = 1;
+ appIdentity->Version.Language = TWLG_USA;
+ appIdentity->Version.Country = TWCY_USA;
+ strcpy(appIdentity->Version.Info, "GIMP TWAIN 0.6");
+ appIdentity->ProtocolMajor = TWON_PROTOCOLMAJOR;
+ appIdentity->ProtocolMinor = TWON_PROTOCOLMINOR;
+ appIdentity->SupportedGroups = DG_IMAGE;
+ strcpy(appIdentity->Manufacturer, "Craig Setera");
+ strcpy(appIdentity->ProductFamily, "GIMP");
+ strcpy(appIdentity->ProductName, "GIMP");
+
+ return appIdentity;
+}
+
+/*
+ * initializeTwain
+ *
+ * Do the necessary TWAIN initialization. This sets up
+ * our TWAIN session information. The session stuff is
+ * something built by me on top of the standard TWAIN
+ * datasource manager calls.
+ */
+pTW_SESSION
+initializeTwain (void)
+{
+ pTW_IDENTITY appIdentity;
+
+ /* Get our application's identity */
+ appIdentity = getAppIdentity ();
+
+ /* Create a new session object */
+ twSession = newSession (appIdentity);
+
+ /* Register our image transfer callback functions */
+#ifdef _DEBUG
+ if (twain_run_mode == RUN_DUMP)
+ registerTransferCallbacks (twSession, &dumperCbFuncs, NULL);
+ else
+#endif /* _DEBUG */
+ registerTransferCallbacks (twSession, &standardCbFuncs, NULL);
+
+ return twSession;
+}
+
+/******************************************************************
+ * GIMP Plug-in entry points
+ ******************************************************************/
+
+/*
+ * Plug-in Parameter definitions
+ */
+#define NUMBER_IN_ARGS 1
+#define IN_ARGS { GIMP_PDB_INT32, "run-mode", "The run mode { RUN-INTERACTIVE (0), RUN-NONINTERACTIVE (1) }" }
+#define NUMBER_OUT_ARGS 2
+#define OUT_ARGS \
+ { GIMP_PDB_INT32, "image-count", "Number of acquired images" }, \
+ { GIMP_PDB_INT32ARRAY, "image-ids", "Array of acquired image identifiers" }
+
+
+/*
+ * query
+ *
+ * The plug-in is being queried. Install our procedure for
+ * acquiring.
+ */
+static void
+query (void)
+{
+ static const GimpParamDef args[] = { IN_ARGS };
+ static const GimpParamDef return_vals[] = { OUT_ARGS };
+
+#ifdef _DEBUG
+ if (twain_run_mode == RUN_DUMP)
+ {
+ /* the installation of the plugin */
+ gimp_install_procedure (PLUG_IN_D_NAME,
+ PLUG_IN_DESCRIPTION,
+ PLUG_IN_HELP,
+ PLUG_IN_AUTHOR,
+ PLUG_IN_COPYRIGHT,
+ PLUG_IN_VERSION,
+ "TWAIN (Dump)...",
+ NULL,
+ GIMP_PLUGIN,
+ NUMBER_IN_ARGS,
+ NUMBER_OUT_ARGS,
+ args,
+ return_vals);
+
+ gimp_plugin_menu_register (PLUG_IN_D_NAME, "<Image>/File/Create/Acquire");
+ }
+ else if (twain_run_mode == RUN_READDUMP)
+ {
+ /* the installation of the plugin */
+ gimp_install_procedure (PLUG_IN_R_NAME,
+ PLUG_IN_DESCRIPTION,
+ PLUG_IN_HELP,
+ PLUG_IN_AUTHOR,
+ PLUG_IN_COPYRIGHT,
+ PLUG_IN_VERSION,
+ "TWAIN (Read)...",
+ NULL,
+ GIMP_PLUGIN,
+ NUMBER_IN_ARGS,
+ NUMBER_OUT_ARGS,
+ args,
+ return_vals);
+
+ gimp_plugin_menu_register (PLUG_IN_R_NAME, "<Image>/File/Create/Acquire");
+ }
+ else
+#endif /* _DEBUG */
+ {
+ /* the installation of the plugin */
+ gimp_install_procedure (PLUG_IN_NAME,
+ PLUG_IN_DESCRIPTION,
+ PLUG_IN_HELP,
+ PLUG_IN_AUTHOR,
+ PLUG_IN_COPYRIGHT,
+ PLUG_IN_VERSION,
+ N_("_Scanner/Camera..."),
+ NULL,
+ GIMP_PLUGIN,
+ NUMBER_IN_ARGS,
+ NUMBER_OUT_ARGS,
+ args,
+ return_vals);
+
+ gimp_plugin_menu_register (PLUG_IN_NAME, "<Image>/File/Create/Acquire");
+ }
+}
+
+
+/* Return values storage */
+static GimpParam values[3];
+
+/*
+ * run
+ *
+ * The plug-in is being requested to run.
+ * Capture an image from a TWAIN datasource
+ */
+static void
+run (const gchar *name,
+ gint nparams,
+ const GimpParam *param,
+ gint *nreturn_vals,
+ GimpParam **return_vals)
+{
+ GimpRunMode run_mode = param[0].data.d_int32;
+
+ /* Initialize the return values
+ * Always return at least the status to the caller.
+ */
+ values[0].type = GIMP_PDB_STATUS;
+ values[0].data.d_status = GIMP_PDB_SUCCESS;
+
+ *nreturn_vals = 1;
+ *return_vals = values;
+
+ INIT_I18N ();
+ gegl_init (NULL, NULL);
+
+ /* Before we get any further, verify that we have
+ * TWAIN and that there is actually a datasource
+ * to be used in doing the acquire.
+ */
+ if (! twainIsAvailable ())
+ {
+ values[0].data.d_status = GIMP_PDB_EXECUTION_ERROR;
+ return;
+ }
+
+ /* Set up the rest of the return parameters */
+ values[1].type = GIMP_PDB_INT32;
+ values[1].data.d_int32 = 0;
+ values[2].type = GIMP_PDB_INT32ARRAY;
+ values[2].data.d_int32array = g_new (gint32, MAX_IMAGES);
+
+ /* How are we running today? */
+ switch (run_mode)
+ {
+ case GIMP_RUN_INTERACTIVE:
+ /* Retrieve values from the last run...
+ * Currently ignored
+ */
+ gimp_get_data (PLUG_IN_NAME, &twainvals);
+ break;
+
+ case GIMP_RUN_NONINTERACTIVE:
+ /* Currently, we don't do non-interactive calls.
+ * Bail if someone tries to call us non-interactively
+ */
+ values[0].data.d_status = GIMP_PDB_CALLING_ERROR;
+ return;
+
+ case GIMP_RUN_WITH_LAST_VALS:
+ /* Retrieve values from the last run...
+ * Currently ignored
+ */
+ gimp_get_data (PLUG_IN_NAME, &twainvals);
+ break;
+
+ default:
+ break;
+ }
+
+ /* Have we succeeded so far? */
+ if (values[0].data.d_status == GIMP_PDB_SUCCESS)
+ twainMain ();
+
+ /* Check to make sure we got at least one valid
+ * image.
+ */
+ if (values[1].data.d_int32 > 0)
+ {
+ /* An image was captured from the TWAIN
+ * datasource. Do final Interactive
+ * steps.
+ */
+ if (run_mode == GIMP_RUN_INTERACTIVE)
+ {
+ /* Store variable states for next run */
+ gimp_set_data (PLUG_IN_NAME, &twainvals, sizeof (TwainValues));
+ }
+
+ /* Set return values */
+ *nreturn_vals = 3;
+ }
+ else
+ {
+ values[0].data.d_status = GIMP_PDB_EXECUTION_ERROR;
+ }
+}
+
+/***********************************************************************
+ * Image transfer callback functions
+ ***********************************************************************/
+
+/* Data used to carry data between each of
+ * the callback function calls.
+ */
+typedef struct
+{
+ gint32 image_id;
+ gint32 layer_id;
+ GeglBuffer *buffer;
+ const Babl *format;
+ pTW_PALETTE8 paletteData;
+ int totalPixels;
+ int completedPixels;
+} ClientDataStruct, *pClientDataStruct;
+
+/*
+ * preTransferCallback
+ *
+ * This callback function is called before any images
+ * are transferred. Set up the one time only stuff.
+ */
+void
+preTransferCallback (void *clientData)
+{
+ /* Initialize our progress dialog */
+ gimp_progress_init (_("Transferring data from scanner/camera"));
+}
+
+/*
+ * beginTransferCallback
+ *
+ * The following function is called at the beginning
+ * of each image transfer.
+ */
+int
+beginTransferCallback (pTW_IMAGEINFO imageInfo,
+ void *clientData)
+{
+ pClientDataStruct theClientData = g_new (ClientDataStruct, 1);
+
+ const Babl *format;
+ GimpImageBaseType imageType;
+ GimpImageType layerType;
+ GimpPrecision precision;
+
+ gint bpc = imageInfo->BitsPerPixel /
+ imageInfo->SamplesPerPixel;
+
+
+#ifdef _DEBUG
+ logBegin (imageInfo, clientData);
+#endif
+
+ /* Decide on the image type */
+ switch (imageInfo->PixelType)
+ {
+ case TWPT_BW:
+ /* Set up the image and layer types */
+ imageType = GIMP_GRAY;
+ layerType = GIMP_GRAY_IMAGE;
+ precision = GIMP_PRECISION_U8_GAMMA;
+ format = babl_format ("Y' u8");
+ break;
+
+ case TWPT_GRAY:
+ /* Set up the image and layer types */
+ imageType = GIMP_GRAY;
+ layerType = GIMP_GRAY_IMAGE;
+
+ switch (bpc)
+ {
+ case 8:
+ precision = GIMP_PRECISION_U8_GAMMA;
+ format = babl_format ("Y' u8");
+ break;
+
+ case 16:
+ precision = GIMP_PRECISION_U16_GAMMA;
+ format = babl_format ("Y' u16");
+ break;
+
+ default:
+ return FALSE;
+ }
+ break;
+
+ case TWPT_RGB:
+ /* Set up the image and layer types */
+ imageType = GIMP_RGB;
+ layerType = GIMP_RGB_IMAGE;
+
+ switch (bpc)
+ {
+ case 8:
+ precision = GIMP_PRECISION_U8_GAMMA;
+ format = babl_format ("R'G'B' u8");
+ break;
+
+ case 16:
+ precision = GIMP_PRECISION_U16_GAMMA;
+ format = babl_format ("R'G'B' u16");
+ break;
+
+ default:
+ return FALSE;
+ }
+ break;
+
+ case TWPT_PALETTE:
+ /* Get the palette data */
+ theClientData->paletteData = g_new (TW_PALETTE8, 1);
+ twSession->twRC = callDSM (APP_IDENTITY (twSession),
+ DS_IDENTITY (twSession),
+ DG_IMAGE, DAT_PALETTE8, MSG_GET,
+ (TW_MEMREF) theClientData->paletteData);
+ if (twSession->twRC != TWRC_SUCCESS)
+ return FALSE;
+
+ switch (theClientData->paletteData->PaletteType)
+ {
+ case TWPA_RGB:
+ /* Set up the image and layer types */
+ imageType = GIMP_RGB;
+ layerType = GIMP_RGB_IMAGE;
+ precision = GIMP_PRECISION_U8_GAMMA;
+
+ format = babl_format ("R'G'B' u8");
+ break;
+
+ case TWPA_GRAY:
+ /* Set up the image and layer types */
+ imageType = GIMP_GRAY;
+ layerType = GIMP_GRAY_IMAGE;
+ precision = GIMP_PRECISION_U8_GAMMA;
+
+ format = babl_format ("Y' u8");
+ break;
+
+ default:
+ return FALSE;
+ }
+ break;
+
+ default:
+ /* We don't know how to deal with anything other than
+ * the types listed above. Bail for any other image
+ * type.
+ */
+ return FALSE;
+ }
+
+ /* Create the GIMP image */
+ theClientData->image_id = gimp_image_new_with_precision (
+ imageInfo->ImageWidth,
+ imageInfo->ImageLength,
+ imageType,
+ precision);
+
+ /* Set the actual resolution */
+ gimp_image_set_resolution (theClientData->image_id,
+ FIX32ToFloat (imageInfo->XResolution),
+ FIX32ToFloat (imageInfo->YResolution));
+ gimp_image_set_unit (theClientData->image_id, GIMP_UNIT_INCH);
+
+ /* Create a layer */
+ theClientData->layer_id = gimp_layer_new (theClientData->image_id,
+ _("Background"),
+ imageInfo->ImageWidth,
+ imageInfo->ImageLength,
+ layerType, 100,
+ GIMP_LAYER_MODE_NORMAL);
+
+ /* Add the layer to the image */
+ gimp_image_insert_layer (theClientData->image_id,
+ theClientData->layer_id, -1, 0);
+
+ /* Update the progress dialog */
+ theClientData->totalPixels = imageInfo->ImageWidth * imageInfo->ImageLength;
+ theClientData->completedPixels = 0;
+
+ gimp_progress_update (0.0);
+
+ theClientData->buffer = gimp_drawable_get_buffer (theClientData->layer_id);
+ theClientData->format = format;
+
+ /* Store our client data for the data transfer callbacks */
+ if (clientData)
+ g_free (clientData);
+
+ setClientData (twSession, (void *) theClientData);
+
+ /* Make sure to return TRUE to continue the image
+ * transfer
+ */
+ return TRUE;
+}
+
+/*
+ * bitTransferCallback
+ *
+ * The following function is called for each memory
+ * block that is transferred from the data source if
+ * the image type is Black/White.
+ *
+ * Black and white data is unpacked from bit data
+ * into byte data and written into a gray scale GIMP
+ * image.
+ */
+static char bitMasks[] = { 128, 64, 32, 16, 8, 4, 2, 1 };
+static int
+bitTransferCallback (pTW_IMAGEINFO imageInfo,
+ pTW_IMAGEMEMXFER imageMemXfer,
+ void *clientData)
+{
+ int row, col, offset;
+ char *srcBuf;
+ char *destBuf;
+ int rows = imageMemXfer->Rows;
+ int cols = imageMemXfer->Columns;
+ pClientDataStruct theClientData = (pClientDataStruct) clientData;
+
+ /* Allocate a buffer as necessary */
+ destBuf = gegl_scratch_new (char, rows * cols);
+
+ /* Unpack the image data from bits into bytes */
+ srcBuf = (char *) imageMemXfer->Memory.TheMem;
+ offset = 0;
+ for (row = 0; row < rows; row++)
+ {
+ for (col = 0; col < cols; col++)
+ {
+ char byte = srcBuf[(row * imageMemXfer->BytesPerRow) + (col / 8)];
+ destBuf[offset++] = ((byte & bitMasks[col % 8]) != 0) ? 255 : 0;
+ }
+ }
+
+ /* Update the complete chunk */
+ gegl_buffer_set (theClientData->buffer,
+ GEGL_RECTANGLE (imageMemXfer->XOffset, imageMemXfer->YOffset,
+ cols, rows), 0,
+ theClientData->format, destBuf,
+ GEGL_AUTO_ROWSTRIDE);
+
+ /* Free the buffer */
+ gegl_scratch_free (destBuf);
+
+ /* Update the user on our progress */
+ theClientData->completedPixels += (cols * rows);
+ gimp_progress_update ((double) theClientData->completedPixels /
+ (double) theClientData->totalPixels);
+
+ return TRUE;
+}
+
+/*
+ * directTransferCallback
+ *
+ * The following function is called for each memory
+ * block that is transferred from the data source if
+ * the image type is Grayscale or RGB.
+ */
+static int
+directTransferCallback (pTW_IMAGEINFO imageInfo,
+ pTW_IMAGEMEMXFER imageMemXfer,
+ void *clientData)
+{
+ int rows = imageMemXfer->Rows;
+ int cols = imageMemXfer->Columns;
+ pClientDataStruct theClientData = (pClientDataStruct) clientData;
+
+ /* Update the complete chunk */
+ gegl_buffer_set (theClientData->buffer,
+ GEGL_RECTANGLE (imageMemXfer->XOffset, imageMemXfer->YOffset,
+ cols, rows), 0,
+ theClientData->format, imageMemXfer->Memory.TheMem,
+ imageMemXfer->BytesPerRow);
+
+ /* Update the user on our progress */
+ theClientData->completedPixels += (cols * rows);
+ gimp_progress_update ((double) theClientData->completedPixels /
+ (double) theClientData->totalPixels);
+
+ return TRUE;
+}
+
+/*
+ * palettedTransferCallback
+ *
+ * The following function is called for each memory
+ * block that is transferred from the data source if
+ * the image type is paletted. This does not create
+ * an indexed image type in GIMP because for some
+ * reason it does not allow creation of a specific
+ * palette. This function will create an RGB or Gray
+ * image and use the palette to set the details of
+ * the pixels.
+ */
+static int
+palettedTransferCallback (pTW_IMAGEINFO imageInfo,
+ pTW_IMAGEMEMXFER imageMemXfer,
+ void *clientData)
+{
+ int channelsPerEntry;
+ int row, col;
+ int rows = imageMemXfer->Rows;
+ int cols = imageMemXfer->Columns;
+ char *destBuf;
+ char *destPtr = NULL;
+ char *srcPtr = NULL;
+
+ /* Get the client data */
+ pClientDataStruct theClientData = (pClientDataStruct) clientData;
+
+ /* Look up the palette entry size */
+ channelsPerEntry =
+ (theClientData->paletteData->PaletteType == TWPA_RGB) ? 3 : 1;
+
+ /* Allocate a buffer as necessary */
+ destBuf = gegl_scratch_new (char, rows * cols * channelsPerEntry);
+
+ /* Work through the rows */
+ destPtr = destBuf;
+ for (row = 0; row < rows; row++)
+ {
+ srcPtr = (char *) ((char *) imageMemXfer->Memory.TheMem +
+ (row * imageMemXfer->BytesPerRow));
+
+ /* Work through the columns */
+ for (col = 0; col < cols; col++)
+ {
+ /* Get the palette index */
+ int index = (unsigned char) *srcPtr;
+
+ srcPtr++;
+
+ switch (theClientData->paletteData->PaletteType)
+ {
+ case TWPA_GRAY:
+ *destPtr = theClientData->paletteData->Colors[index].Channel1;
+ destPtr++;
+ break;
+
+ case TWPA_RGB:
+ *destPtr = theClientData->paletteData->Colors[index].Channel1;
+ destPtr++;
+ *destPtr = theClientData->paletteData->Colors[index].Channel2;
+ destPtr++;
+ *destPtr = theClientData->paletteData->Colors[index].Channel3;
+ destPtr++;
+ }
+ }
+ }
+
+ /* Send the complete chunk */
+ gegl_buffer_set (theClientData->buffer,
+ GEGL_RECTANGLE (imageMemXfer->XOffset, imageMemXfer->YOffset,
+ cols, rows), 0,
+ theClientData->format, destBuf,
+ GEGL_AUTO_ROWSTRIDE);
+
+ /* Free the buffer */
+ gegl_scratch_free (destBuf);
+
+ /* Update the user on our progress */
+ theClientData->completedPixels += (cols * rows);
+ gimp_progress_update ((double) theClientData->completedPixels /
+ (double) theClientData->totalPixels);
+
+ return TRUE;
+}
+
+/*
+ * dataTransferCallback
+ *
+ * The following function is called for each memory
+ * block that is transferred from the data source.
+ */
+int
+dataTransferCallback (pTW_IMAGEINFO imageInfo,
+ pTW_IMAGEMEMXFER imageMemXfer,
+ void *clientData)
+{
+#ifdef _DEBUG
+ logData (imageInfo, imageMemXfer, clientData);
+#endif
+
+ /* Choose the appropriate transfer handler */
+ switch (imageInfo->PixelType)
+ {
+ case TWPT_PALETTE:
+ return palettedTransferCallback (imageInfo, imageMemXfer, clientData);
+
+ case TWPT_BW:
+ return bitTransferCallback (imageInfo, imageMemXfer, clientData);
+
+ case TWPT_GRAY:
+ case TWPT_RGB:
+ return directTransferCallback (imageInfo, imageMemXfer, clientData);
+
+ default:
+ return FALSE;
+ }
+}
+
+/*
+ * endTransferCallback
+ *
+ * The following function is called at the end of the
+ * image transfer. The caller will be handed
+ * the image transfer completion state. The
+ * following values (defined in twain.h) are
+ * possible:
+ *
+ * TWRC_XFERDONE
+ * The transfer completed successfully
+ * TWRC_CANCEL
+ * The transfer was completed by the user
+ * TWRC_FAILURE
+ * The transfer failed.
+ */
+int
+endTransferCallback (int completionState,
+ int pendingCount,
+ void *clientData)
+{
+ pClientDataStruct theClientData = (pClientDataStruct) clientData;
+
+ LogMessage ("endTransferCallback: CompState = %d, pending = %d\n",
+ completionState, pendingCount);
+
+ /* Clean up and detach from the drawable */
+ g_object_unref (theClientData->buffer);
+
+ /* Make sure to check our return code */
+ if (completionState == TWRC_XFERDONE)
+ {
+ /* We have a completed image transfer */
+ values[2].type = GIMP_PDB_INT32ARRAY;
+ values[2].data.d_int32array[values[1].data.d_int32++] =
+ theClientData->image_id;
+
+ /* Display the image */
+ LogMessage ("Displaying image %d\n", theClientData->image_id);
+ gimp_display_new (theClientData->image_id);
+ }
+ else
+ {
+ /* The transfer did not complete successfully */
+ LogMessage ("Deleting image\n");
+ gimp_image_delete (theClientData->image_id);
+ }
+
+ /* Shut down if we have received all of the possible images */
+ return (values[1].data.d_int32 < MAX_IMAGES);
+}
+
+/*
+ * postTransferCallback
+ *
+ * This callback function will be called
+ * after all possible images have been
+ * transferred.
+ */
+void
+postTransferCallback (int pendingCount,
+ void *clientData)
+{
+ /* Shut things down. */
+ if (pendingCount != 0)
+ cancelPendingTransfers(twSession);
+
+ /* This will close the datasource and datasource
+ * manager. Then the message queue will be shut
+ * down and the run() procedure will finally be
+ * able to finish.
+ */
+ disableDS (twSession);
+ closeDS (twSession);
+ closeDSM (twSession);
+
+ /* Post a message to close up the application */
+ twainQuitApplication ();
+}
diff --git a/plug-ins/twain/twain.h b/plug-ins/twain/twain.h
new file mode 100644
index 0000000..af00295
--- /dev/null
+++ b/plug-ins/twain/twain.h
@@ -0,0 +1,1819 @@
+/* ======================================================================== *\
+
+ Copyright (C) 1991, 1992 TWAIN Working Group: Aldus, Caere, Eastman-Kodak,
+ Hewlett-Packard and Logitech Corporations. All rights reserved.
+
+ Copyright (C) 1997 TWAIN Working Group: Bell+Howell, Canon, DocuMagix,
+ Fujitsu, Genoa Technology, Hewlett-Packard, Kofax Imaging Products, and
+ Ricoh Corporation. All rights reserved.
+
+ Copyright © 1998 TWAIN Working Group: Adobe Systems Incorporated,
+ Canon Information Systems, Eastman Kodak Company,
+ Fujitsu Computer Products of America, Genoa Technology,
+ Hewlett-Packard Company, Intel Corporation, Kofax Image Products,
+ JFL Peripheral Solutions Inc., Ricoh Corporation, and Xerox Corporation.
+ All rights reserved.
+
+ TWAIN.h - This is the definitive include file for applications and
+ data sources written to the TWAIN specification.
+ It defines constants, data structures, messages etc.
+ for the public interface to TWAIN.
+
+ Revision History:
+ version 1.0, March 6, 1992. TWAIN 1.0.
+ version 1.1, January 1993. Tech Notes 1.1
+ version 1.5, June 1993. Specification Update 1.5
+ Change DC to TW
+ Change filename from DC.H to TWAIN.H
+ version 1.5, July 1993. Remove spaces from country identifiers
+
+ version 1.7, July 1997 Added Capabilities and data structure for
+ document imaging and digital cameras.
+ KHL.
+ version 1.7, July 1997 Inserted Borland compatibile structure packing
+ directives provided by Mentor. JMH
+ version 1.7, Aug 1997 Expanded file tabs to spaces.
+ NOTE: future authors should be sure to have
+ their editors set to automatically expand tabs
+ to spaces (original tab setting was 4 spaces).
+ version 1.7, Sept 1997 Added job control values
+ Added return codes
+ version 1.7, Sept 1997 changed definition of pRGBRESPONSE to
+ pTW_RGBRESPONSE
+ version 1.7 Aug 1998 Added missing TWEI_BARCODEROTATION values
+ TWBCOR_ types JMH
+ version 1.8 August 1998 Added new types and definitions required
+ for 1.8 Specification JMH
+\* ======================================================================== */
+
+#ifndef TWAIN
+#define TWAIN
+
+/* SDH - 02/08/95 - TWUNK */
+/* Force 32-bit twain to use same packing of twain structures as existing */
+/* 16-bit twain. This allows 16/32-bit thunking. */
+#ifdef WIN32
+ #ifdef __BORLANDC__ /* (Mentor June 13, 1996) if using a Borland compiler */
+ #pragma option -a2 /*(Mentor June 13, 1996) switch to word alignment*/
+ #else /*(Mentor June 13, 1996) if we're using some other compiler*/
+ #pragma pack (push, before_twain)
+ #pragma pack (2)
+ #endif /*(Mentor June 13, 1996)*/
+#else /* WIN32 */
+#endif /* WIN32 */
+
+/****************************************************************************
+ * TWAIN Version *
+ ****************************************************************************/
+#define TWON_PROTOCOLMINOR 8 /* Changed for Version 1.8 */
+#define TWON_PROTOCOLMAJOR 1
+
+/****************************************************************************
+ * Platform Dependent Definitions and Typedefs *
+ ****************************************************************************/
+
+/* Define one of the following, depending on the platform */
+/* #define _MAC_ */
+/* #define _UNIX_ */
+#define _MSWIN_
+
+#ifdef _MSWIN_
+ typedef HANDLE TW_HANDLE;
+ typedef LPVOID TW_MEMREF;
+
+ /* SDH - 05/05/95 - TWUNK */
+ /* For common code between 16 and 32 bits. */
+ #ifdef WIN32
+ #define TW_HUGE
+ #else /* WIN32 */
+ #define TW_HUGE huge
+ #endif /* WIN32 */
+ typedef BYTE TW_HUGE * HPBYTE;
+ typedef void TW_HUGE * HPVOID;
+#endif /* _MSWIN_ */
+
+#ifdef _MAC_
+ #define PASCAL pascal
+ #define FAR
+ typedef Handle TW_HANDLE;
+ typedef char *TW_MEMREF;
+#endif /* _MAC_ */
+
+#ifdef _UNIX_
+ #define PASCAL pascal
+ typedef unsigned char *TW_HANDLE;
+ typedef unsigned char *TW_MEMREF;
+#endif /* _UNIX_ */
+
+/****************************************************************************
+ * Type Definitions *
+ ****************************************************************************/
+
+/* String types. These include room for the strings and a NULL char, *
+ * or, on the Mac, a length byte followed by the string. *
+ * TW_STR255 must hold less than 256 chars so length fits in first byte. */
+typedef char TW_STR32[34], FAR *pTW_STR32;
+typedef char TW_STR64[66], FAR *pTW_STR64;
+typedef char TW_STR128[130], FAR *pTW_STR128;
+typedef char TW_STR255[256], FAR *pTW_STR255;
+
+/* Numeric types. */
+typedef char TW_INT8, FAR *pTW_INT8;
+typedef short TW_INT16, FAR *pTW_INT16;
+typedef long TW_INT32, FAR *pTW_INT32;
+typedef unsigned char TW_UINT8, FAR *pTW_UINT8;
+typedef unsigned short TW_UINT16, FAR *pTW_UINT16;
+typedef unsigned long TW_UINT32, FAR *pTW_UINT32;
+typedef unsigned short TW_BOOL, FAR *pTW_BOOL;
+
+/* Fixed point structure type. */
+typedef struct {
+ TW_INT16 Whole; /* maintains the sign */
+ TW_UINT16 Frac;
+} TW_FIX32, FAR *pTW_FIX32;
+
+/****************************************************************************
+ * Structure Definitions *
+ ****************************************************************************/
+
+/* No DAT needed. */
+typedef struct {
+ TW_FIX32 X;
+ TW_FIX32 Y;
+ TW_FIX32 Z;
+} TW_CIEPOINT, FAR * pTW_CIEPOINT;
+
+/* No DAT needed. */
+typedef struct {
+ TW_FIX32 StartIn;
+ TW_FIX32 BreakIn;
+ TW_FIX32 EndIn;
+ TW_FIX32 StartOut;
+ TW_FIX32 BreakOut;
+ TW_FIX32 EndOut;
+ TW_FIX32 Gamma;
+ TW_FIX32 SampleCount; /* if =0 use the gamma */
+} TW_DECODEFUNCTION, FAR * pTW_DECODEFUNCTION;
+
+/* No DAT needed. */
+typedef struct {
+ TW_UINT8 Index; /* Value used to index into the color table. */
+ TW_UINT8 Channel1; /* First tri-stimulus value (e.g Red) */
+ TW_UINT8 Channel2; /* Second tri-stimulus value (e.g Green) */
+ TW_UINT8 Channel3; /* Third tri-stimulus value (e.g Blue) */
+} TW_ELEMENT8, FAR * pTW_ELEMENT8;
+
+/* No DAT. Defines a frame rectangle in ICAP_UNITS coordinates. */
+typedef struct {
+ TW_FIX32 Left;
+ TW_FIX32 Top;
+ TW_FIX32 Right;
+ TW_FIX32 Bottom;
+} TW_FRAME, FAR * pTW_FRAME;
+
+/* No DAT needed. Used to manage memory buffers. */
+typedef struct {
+ TW_UINT32 Flags; /* Any combination of the TWMF_ constants. */
+ TW_UINT32 Length; /* Number of bytes stored in buffer TheMem. */
+ TW_MEMREF TheMem; /* Pointer or handle to the allocated memory buffer. */
+} TW_MEMORY, FAR * pTW_MEMORY;
+
+/* No DAT needed. */
+typedef struct {
+ TW_DECODEFUNCTION Decode[3];
+ TW_FIX32 Mix[3][3];
+} TW_TRANSFORMSTAGE, FAR * pTW_TRANSFORMSTAGE;
+
+/* No DAT needed. Describes version of software currently running. */
+typedef struct {
+ TW_UINT16 MajorNum; /* Major revision number of the software. */
+ TW_UINT16 MinorNum; /* Incremental revision number of the software. */
+ TW_UINT16 Language; /* e.g. TWLG_SWISSFRENCH */
+ TW_UINT16 Country; /* e.g. TWCY_SWITZERLAND */
+ TW_STR32 Info; /* e.g. "1.0b3 Beta release" */
+} TW_VERSION, FAR * pTW_VERSION;
+
+/* TWON_ARRAY. Container for array of values (a simplified TW_ENUMERATION) */
+typedef struct {
+ TW_UINT16 ItemType;
+ TW_UINT32 NumItems; /* How many items in ItemList */
+ TW_UINT8 ItemList[1]; /* Array of ItemType values starts here */
+} TW_ARRAY, FAR * pTW_ARRAY;
+
+/* TWON_ENUMERATION. Container for a collection of values. */
+typedef struct {
+ TW_UINT16 ItemType;
+ TW_UINT32 NumItems; /* How many items in ItemList */
+ TW_UINT32 CurrentIndex; /* Current value is in ItemList[CurrentIndex] */
+ TW_UINT32 DefaultIndex; /* Powerup value is in ItemList[DefaultIndex] */
+ TW_UINT8 ItemList[1]; /* Array of ItemType values starts here */
+} TW_ENUMERATION, FAR * pTW_ENUMERATION;
+
+/* TWON_ONEVALUE. Container for one value. */
+typedef struct {
+ TW_UINT16 ItemType;
+ TW_UINT32 Item;
+} TW_ONEVALUE, FAR * pTW_ONEVALUE;
+
+/* TWON_RANGE. Container for a range of values. */
+typedef struct {
+ TW_UINT16 ItemType;
+ TW_UINT32 MinValue; /* Starting value in the range. */
+ TW_UINT32 MaxValue; /* Final value in the range. */
+ TW_UINT32 StepSize; /* Increment from MinValue to MaxValue. */
+ TW_UINT32 DefaultValue; /* Power-up value. */
+ TW_UINT32 CurrentValue; /* The value that is currently in effect. */
+} TW_RANGE, FAR * pTW_RANGE;
+
+/* DAT_CAPABILITY. Used by application to get/set capability from/in a data source. */
+typedef struct {
+ TW_UINT16 Cap; /* id of capability to set or get, e.g. CAP_BRIGHTNESS */
+ TW_UINT16 ConType; /* TWON_ONEVALUE, _RANGE, _ENUMERATION or _ARRAY */
+ TW_HANDLE hContainer; /* Handle to container of type Dat */
+} TW_CAPABILITY, FAR * pTW_CAPABILITY;
+
+/* DAT_CIECOLOR. */
+typedef struct {
+ TW_UINT16 ColorSpace;
+ TW_INT16 LowEndian;
+ TW_INT16 DeviceDependent;
+ TW_INT32 VersionNumber;
+ TW_TRANSFORMSTAGE StageABC;
+ TW_TRANSFORMSTAGE StageLMN;
+ TW_CIEPOINT WhitePoint;
+ TW_CIEPOINT BlackPoint;
+ TW_CIEPOINT WhitePaper;
+ TW_CIEPOINT BlackInk;
+ TW_FIX32 Samples[1];
+} TW_CIECOLOR, FAR * pTW_CIECOLOR;
+
+/* DAT_EVENT. For passing events down from the application to the DS. */
+typedef struct {
+ TW_MEMREF pEvent; /* Windows pMSG or Mac pEvent. */
+ TW_UINT16 TWMessage; /* TW msg from data source, e.g. MSG_XFERREADY */
+} TW_EVENT, FAR * pTW_EVENT;
+
+/* DAT_GRAYRESPONSE */
+typedef struct {
+ TW_ELEMENT8 Response[1];
+} TW_GRAYRESPONSE, FAR * pTW_GRAYRESPONSE;
+
+/* DAT_IDENTITY. Identifies the program/library/code resource. */
+typedef struct {
+ TW_UINT32 Id; /* Unique number. In Windows, application hWnd */
+ TW_VERSION Version; /* Identifies the piece of code */
+ TW_UINT16 ProtocolMajor; /* Application and DS must set to TWON_PROTOCOLMAJOR */
+ TW_UINT16 ProtocolMinor; /* Application and DS must set to TWON_PROTOCOLMINOR */
+ TW_UINT32 SupportedGroups; /* Bit field OR combination of DG_ constants */
+ TW_STR32 Manufacturer; /* Manufacturer name, e.g. "Hewlett-Packard" */
+ TW_STR32 ProductFamily; /* Product family name, e.g. "ScanJet" */
+ TW_STR32 ProductName; /* Product name, e.g. "ScanJet Plus" */
+} TW_IDENTITY, FAR * pTW_IDENTITY;
+
+/* DAT_IMAGEINFO. Application gets detailed image info from DS with this. */
+typedef struct {
+ TW_FIX32 XResolution; /* Resolution in the horizontal */
+ TW_FIX32 YResolution; /* Resolution in the vertical */
+ TW_INT32 ImageWidth; /* Columns in the image, -1 if unknown by DS*/
+ TW_INT32 ImageLength; /* Rows in the image, -1 if unknown by DS */
+ TW_INT16 SamplesPerPixel; /* Number of samples per pixel, 3 for RGB */
+ TW_INT16 BitsPerSample[8]; /* Number of bits for each sample */
+ TW_INT16 BitsPerPixel; /* Number of bits for each padded pixel */
+ TW_BOOL Planar; /* True if Planar, False if chunky */
+ TW_INT16 PixelType; /* How to interp data; photo interp (TWPT_) */
+ TW_UINT16 Compression; /* How the data is compressed (TWCP_xxxx) */
+} TW_IMAGEINFO, FAR * pTW_IMAGEINFO;
+
+/* DAT_IMAGELAYOUT. Provides image layout information in current units. */
+typedef struct {
+ TW_FRAME Frame; /* Frame coords within larger document */
+ TW_UINT32 DocumentNumber;
+ TW_UINT32 PageNumber; /* Reset when you go to next document */
+ TW_UINT32 FrameNumber; /* Reset when you go to next page */
+} TW_IMAGELAYOUT, FAR * pTW_IMAGELAYOUT;
+
+/* DAT_IMAGEMEMXFER. Used to pass image data (e.g. in strips) from DS to application.*/
+typedef struct {
+ TW_UINT16 Compression; /* How the data is compressed */
+ TW_UINT32 BytesPerRow; /* Number of bytes in a row of data */
+ TW_UINT32 Columns; /* How many columns */
+ TW_UINT32 Rows; /* How many rows */
+ TW_UINT32 XOffset; /* How far from the side of the image */
+ TW_UINT32 YOffset; /* How far from the top of the image */
+ TW_UINT32 BytesWritten; /* How many bytes written in Memory */
+ TW_MEMORY Memory; /* Mem struct used to pass actual image data */
+} TW_IMAGEMEMXFER, FAR * pTW_IMAGEMEMXFER;
+
+/* Changed in 1.1: QuantTable, HuffmanDC, HuffmanAC TW_MEMREF -> TW_MEMORY */
+/* DAT_JPEGCOMPRESSION. Based on JPEG Draft International Std, ver 10918-1. */
+typedef struct {
+ TW_UINT16 ColorSpace; /* One of the TWPT_xxxx values */
+ TW_UINT32 SubSampling; /* Two word "array" for subsampling values */
+ TW_UINT16 NumComponents; /* Number of color components in image */
+ TW_UINT16 RestartFrequency; /* Frequency of restart marker codes in MDU's */
+ TW_UINT16 QuantMap[4]; /* Mapping of components to QuantTables */
+ TW_MEMORY QuantTable[4]; /* Quantization tables */
+ TW_UINT16 HuffmanMap[4]; /* Mapping of components to Huffman tables */
+ TW_MEMORY HuffmanDC[2]; /* DC Huffman tables */
+ TW_MEMORY HuffmanAC[2]; /* AC Huffman tables */
+} TW_JPEGCOMPRESSION, FAR * pTW_JPEGCOMPRESSION;
+
+/* DAT_PALETTE8. Color palette when TWPT_PALETTE pixels xfer'd in mem buf. */
+typedef struct {
+ TW_UINT16 NumColors; /* Number of colors in the color table. */
+ TW_UINT16 PaletteType; /* TWPA_xxxx, specifies type of palette. */
+ TW_ELEMENT8 Colors[256]; /* Array of palette values starts here. */
+} TW_PALETTE8, FAR * pTW_PALETTE8;
+
+/* DAT_PENDINGXFERS. Used with MSG_ENDXFER to indicate additional data. */
+typedef struct {
+ TW_UINT16 Count;
+ union {
+ TW_UINT32 EOJ;
+ TW_UINT32 Reserved;
+ };
+} TW_PENDINGXFERS, FAR *pTW_PENDINGXFERS;
+
+/* DAT_RGBRESPONSE */
+typedef struct {
+ TW_ELEMENT8 Response[1];
+} TW_RGBRESPONSE, FAR * pTW_RGBRESPONSE;
+
+/* DAT_SETUPFILEXFER. Sets up DS to application data transfer via a file. */
+typedef struct {
+ TW_STR255 FileName;
+ TW_UINT16 Format; /* Any TWFF_ constant */
+ TW_INT16 VRefNum; /* Used for Mac only */
+} TW_SETUPFILEXFER, FAR * pTW_SETUPFILEXFER;
+
+/* DAT_SETUPMEMXFER. Sets up DS to application data transfer via a memory buffer. */
+typedef struct {
+ TW_UINT32 MinBufSize;
+ TW_UINT32 MaxBufSize;
+ TW_UINT32 Preferred;
+} TW_SETUPMEMXFER, FAR * pTW_SETUPMEMXFER;
+
+/* DAT_STATUS. Application gets detailed status info from a data source with this. */
+typedef struct {
+ TW_UINT16 ConditionCode; /* Any TWCC_ constant */
+ TW_UINT16 Reserved; /* Future expansion space */
+} TW_STATUS, FAR * pTW_STATUS;
+
+/* DAT_USERINTERFACE. Coordinates UI between application and data source. */
+typedef struct {
+ TW_BOOL ShowUI; /* TRUE if DS should bring up its UI */
+ TW_BOOL ModalUI; /* For Mac only - true if the DS's UI is modal */
+ TW_HANDLE hParent; /* For windows only - Application window handle */
+} TW_USERINTERFACE, FAR * pTW_USERINTERFACE;
+
+/* SDH - 03/21/95 - TWUNK */
+/* DAT_TWUNKIDENTITY. Provides DS identity and 'other' information necessary */
+/* across thunk link. */
+typedef struct {
+ TW_IDENTITY identity; /* Identity of data source. */
+ TW_STR255 dsPath; /* Full path and file name of data source. */
+} TW_TWUNKIDENTITY, FAR * pTW_TWUNKIDENTITY;
+
+/* SDH - 03/21/95 - TWUNK */
+/* Provides DS_Entry parameters over thunk link. */
+typedef struct
+{
+ TW_INT8 destFlag; /* TRUE if dest is not NULL */
+ TW_IDENTITY dest; /* Identity of data source (if used) */
+ TW_INT32 dataGroup; /* DSM_Entry dataGroup parameter */
+ TW_INT16 dataArgType; /* DSM_Entry dataArgType parameter */
+ TW_INT16 message; /* DSM_Entry message parameter */
+ TW_INT32 pDataSize; /* Size of pData (0 if NULL) */
+ /* TW_MEMREF pData; Based on implementation specifics, a */
+ /* pData parameter makes no sense in this */
+ /* structure, but data (if provided) will be*/
+ /* appended in the data block. */
+ } TW_TWUNKDSENTRYPARAMS, FAR * pTW_TWUNKDSENTRYPARAMS;
+
+/* SDH - 03/21/95 - TWUNK */
+/* Provides DS_Entry results over thunk link. */
+typedef struct
+{
+ TW_UINT16 returnCode; /* Thunker DsEntry return code. */
+ TW_UINT16 conditionCode; /* Thunker DsEntry condition code. */
+ TW_INT32 pDataSize; /* Size of pData (0 if NULL) */
+ /* TW_MEMREF pData; Based on implementation specifics, a */
+ /* pData parameter makes no sense in this */
+ /* structure, but data (if provided) will be*/
+ /* appended in the data block. */
+} TW_TWUNKDSENTRYRETURN, FAR * pTW_TWUNKDSENTRYRETURN;
+
+/* WJD - 950818 */
+/* Added for 1.6 Specification */
+/* TWAIN 1.6 CAP_SUPPORTEDCAPSEXT structure */
+typedef struct
+{
+ TW_UINT16 Cap; /* Which CAP/ICAP info is relevant to */
+ TW_UINT16 Properties; /* Messages this CAP/ICAP supports */
+} TW_CAPEXT, FAR * pTW_CAPEXT;
+
+/* ----------------------------------------------------------------------- *\
+
+ Version 1.7: Added Following data structure for Document Imaging
+ July 1997 Enhancement.
+ KHL TW_CUSTOMDSDATA -- For Saving and Restoring Source's
+ state.
+ TW_INFO -- Each attribute for extended image
+ information.
+ TW_EXTIMAGEINFO -- Extended image information structure.
+
+\* ----------------------------------------------------------------------- */
+
+typedef struct {
+ TW_UINT32 InfoLength; /* Length of Information in bytes. */
+ TW_HANDLE hData; /* Place holder for data, DS Allocates */
+}TW_CUSTOMDSDATA, FAR *pTW_CUSTOMDSDATA;
+
+typedef struct {
+ TW_UINT16 InfoID;
+ TW_UINT16 ItemType;
+ TW_UINT16 NumItems;
+ TW_UINT16 CondCode;
+ TW_UINT32 Item;
+}TW_INFO, FAR* pTW_INFO;
+
+typedef struct {
+ TW_UINT32 NumInfos;
+ TW_INFO Info[1];
+}TW_EXTIMAGEINFO, FAR* pTW_EXTIMAGEINFO;
+
+/* Added 1.8 */
+
+/* DAT_AUDIOINFO, information about audio data */
+typedef struct {
+ TW_STR255 Name; /* name of audio data */
+ TW_UINT32 Reserved; /* reserved space */
+} TW_AUDIOINFO, FAR * pTW_AUDIOINFO;
+
+/* DAT_DEVICEEVENT, information about events */
+typedef struct {
+ TW_UINT32 Event; /* One of the TWDE_xxxx values. */
+ TW_STR255 DeviceName; /* The name of the device that generated the event */
+ TW_UINT32 BatteryMinutes; /* Battery Minutes Remaining */
+ TW_INT16 BatteryPercentage; /* Battery Percentage Remaining */
+ TW_INT32 PowerSupply; /* Power Supply */
+ TW_FIX32 XResolution; /* Resolution */
+ TW_FIX32 YResolution; /* Resolution */
+ TW_UINT32 FlashUsed2; /* Flash Used2 */
+ TW_UINT32 AutomaticCapture; /* Automatic Capture */
+ TW_UINT32 TimeBeforeFirstCapture; /* Automatic Capture */
+ TW_UINT32 TimeBetweenCaptures; /* Automatic Capture */
+} TW_DEVICEEVENT, FAR * pTW_DEVICEEVENT;
+
+/* DAT_FILESYSTEM, information about TWAIN file system */
+typedef struct {
+ /* DG_CONTROL / DAT_FILESYSTEM / MSG_xxxx fields */
+ TW_STR255 InputName; /* The name of the input or source file */
+ TW_STR255 OutputName; /* The result of an operation or the name of a destination file */
+ TW_MEMREF Context; /* Source specific data used to remember state information */
+ /* DG_CONTROL / DAT_FILESYSTEM / MSG_DELETE field */
+ int Recursive; /* recursively delete all sub-directories */
+ /* DG_CONTROL / DAT_FILESYSTEM / MSG_GETINFO fields */
+ TW_INT32 FileType; /* One of the TWFT_xxxx values */
+ TW_UINT32 Size; /* Size of current FileType */
+ TW_STR32 CreateTimeDate; /* creation date of the file */
+ TW_STR32 ModifiedTimeDate; /* last date the file was modified */
+ TW_UINT32 FreeSpace; /* bytes of free space on the current device */
+ TW_INT32 NewImageSize; /* estimate of the amount of space a new image would take up */
+ TW_UINT32 NumberOfFiles; /* number of files, depends on FileType */
+ TW_UINT32 NumberOfSnippets; /**/
+ char Reserved[512]; /**/
+} TW_FILESYSTEM, FAR * pTW_FILESYSTEM;
+
+/* DAT_PASSTHRU, device dependent data to pass through Data Source */
+typedef struct {
+ TW_MEMREF pCommand; /* Pointer to Command buffer */
+ TW_UINT32 CommandBytes; /* Number of bytes in Command buffer */
+ TW_INT32 Direction; /* One of the TWDR_xxxx values. Defines the direction of data flow */
+ TW_MEMREF pData; /* Pointer to Data buffer */
+ TW_UINT32 DataBytes; /* Number of bytes in Data buffer */
+ TW_UINT32 DataBytesXfered; /* Number of bytes successfully transferred */
+} TW_PASSTHRU, FAR * pTW_PASSTHRU;
+
+/* DAT_SETUPAUDIOFILEXFER, information required to setup an audio file transfer */
+typedef struct {
+ TW_STR255 FileName; /* full path target file */
+ TW_UINT16 Format; /* one of TWAF_xxxx */
+ TW_INT16 VRefNum;
+} TW_SETUPAUDIOFILEXFER, FAR * pTW_SETUPAUDIOFILEXFER;
+
+/****************************************************************************
+ * Generic Constants *
+ ****************************************************************************/
+
+#define TWON_ARRAY 3 /* indicates TW_ARRAY container */
+#define TWON_ENUMERATION 4 /* indicates TW_ENUMERATION container */
+#define TWON_ONEVALUE 5 /* indicates TW_ONEVALUE container */
+#define TWON_RANGE 6 /* indicates TW_RANGE container */
+
+#define TWON_ICONID 962 /* res Id of icon used in USERSELECT lbox */
+#define TWON_DSMID 461 /* res Id of the DSM version num resource */
+#define TWON_DSMCODEID 63 /* res Id of the Mac SM Code resource */
+
+#define TWON_DONTCARE8 0xff
+#define TWON_DONTCARE16 0xffff
+#define TWON_DONTCARE32 0xffffffff
+
+/* Flags used in TW_MEMORY structure. */
+#define TWMF_APPOWNS 0x1
+#define TWMF_DSMOWNS 0x2
+#define TWMF_DSOWNS 0x4
+#define TWMF_POINTER 0x8
+#define TWMF_HANDLE 0x10
+
+/* Palette types for TW_PALETTE8 */
+#define TWPA_RGB 0
+#define TWPA_GRAY 1
+#define TWPA_CMY 2
+
+/* There are four containers used for capabilities negotiation:
+ * TWON_ONEVALUE, TWON_RANGE, TWON_ENUMERATION, TWON_ARRAY
+ * In each container structure ItemType can be TWTY_INT8, TWTY_INT16, etc.
+ * The kind of data stored in the container can be determined by doing
+ * DCItemSize[ItemType] where the following is defined in TWAIN glue code:
+ * DCItemSize[]= { sizeof(TW_INT8),
+ * sizeof(TW_INT16),
+ * etc.
+ * sizeof(TW_UINT32) };
+ *
+ */
+
+#define TWTY_INT8 0x0000 /* Means Item is a TW_INT8 */
+#define TWTY_INT16 0x0001 /* Means Item is a TW_INT16 */
+#define TWTY_INT32 0x0002 /* Means Item is a TW_INT32 */
+
+#define TWTY_UINT8 0x0003 /* Means Item is a TW_UINT8 */
+#define TWTY_UINT16 0x0004 /* Means Item is a TW_UINT16 */
+#define TWTY_UINT32 0x0005 /* Means Item is a TW_UINT32 */
+
+#define TWTY_BOOL 0x0006 /* Means Item is a TW_BOOL */
+
+#define TWTY_FIX32 0x0007 /* Means Item is a TW_FIX32 */
+
+#define TWTY_FRAME 0x0008 /* Means Item is a TW_FRAME */
+
+#define TWTY_STR32 0x0009 /* Means Item is a TW_STR32 */
+#define TWTY_STR64 0x000a /* Means Item is a TW_STR64 */
+#define TWTY_STR128 0x000b /* Means Item is a TW_STR128 */
+#define TWTY_STR255 0x000c /* Means Item is a TW_STR255 */
+
+/****************************************************************************
+ * Capability Constants *
+ ****************************************************************************/
+
+/* ICAP_BITORDER values (BO_ means Bit Order) */
+#define TWBO_LSBFIRST 0
+#define TWBO_MSBFIRST 1
+
+/* ICAP_COMPRESSION values (CP_ means ComPression ) */
+#define TWCP_NONE 0
+#define TWCP_PACKBITS 1
+#define TWCP_GROUP31D 2 /* Follows CCITT spec (no End Of Line) */
+#define TWCP_GROUP31DEOL 3 /* Follows CCITT spec (has End Of Line) */
+#define TWCP_GROUP32D 4 /* Follows CCITT spec (use cap for K Factor) */
+#define TWCP_GROUP4 5 /* Follows CCITT spec */
+#define TWCP_JPEG 6 /* Use capability for more info */
+#define TWCP_LZW 7 /* Must license from Unisys and IBM to use */
+#define TWCP_JBIG 8 /* For Bitonal images -- Added 1.7 KHL */
+/* Added 1.8 */
+#define TWCP_PNG 9
+#define TWCP_RLE4 10
+#define TWCP_RLE8 11
+#define TWCP_BITFIELDS 12
+
+
+/* ICAP_IMAGEFILEFORMAT values (FF_means File Format) */
+#define TWFF_TIFF 0 /* Tagged Image File Format */
+#define TWFF_PICT 1 /* Macintosh PICT */
+#define TWFF_BMP 2 /* Windows Bitmap */
+#define TWFF_XBM 3 /* X-Windows Bitmap */
+#define TWFF_JFIF 4 /* JPEG File Interchange Format */
+#define TWFF_FPX 5 /* Flash Pix */
+#define TWFF_TIFFMULTI 6 /* Multi-page tiff file */
+#define TWFF_PNG 7
+#define TWFF_SPIFF 8
+#define TWFF_EXIF 9
+
+
+/* ICAP_FILTER values (FT_ means Filter Type) */
+#define TWFT_RED 0
+#define TWFT_GREEN 1
+#define TWFT_BLUE 2
+#define TWFT_NONE 3
+#define TWFT_WHITE 4
+#define TWFT_CYAN 5
+#define TWFT_MAGENTA 6
+#define TWFT_YELLOW 7
+#define TWFT_BLACK 8
+
+/* ICAP_LIGHTPATH values (LP_ means Light Path) */
+#define TWLP_REFLECTIVE 0
+#define TWLP_TRANSMISSIVE 1
+
+/* ICAP_LIGHTSOURCE values (LS_ means Light Source) */
+#define TWLS_RED 0
+#define TWLS_GREEN 1
+#define TWLS_BLUE 2
+#define TWLS_NONE 3
+#define TWLS_WHITE 4
+#define TWLS_UV 5
+#define TWLS_IR 6
+
+/* ICAP_ORIENTATION values (OR_ means ORientation) */
+#define TWOR_ROT0 0
+#define TWOR_ROT90 1
+#define TWOR_ROT180 2
+#define TWOR_ROT270 3
+#define TWOR_PORTRAIT TWOR_ROT0
+#define TWOR_LANDSCAPE TWOR_ROT270
+
+/* ICAP_PLANARCHUNKY values (PC_ means Planar/Chunky ) */
+#define TWPC_CHUNKY 0
+#define TWPC_PLANAR 1
+
+/* ICAP_PIXELFLAVOR values (PF_ means Pixel Flavor) */
+#define TWPF_CHOCOLATE 0 /* zero pixel represents darkest shade */
+#define TWPF_VANILLA 1 /* zero pixel represents lightest shade */
+
+/* ICAP_PIXELTYPE values (PT_ means Pixel Type) */
+#define TWPT_BW 0 /* Black and White */
+#define TWPT_GRAY 1
+#define TWPT_RGB 2
+#define TWPT_PALETTE 3
+#define TWPT_CMY 4
+#define TWPT_CMYK 5
+#define TWPT_YUV 6
+#define TWPT_YUVK 7
+#define TWPT_CIEXYZ 8
+
+/* ICAP_SUPPORTEDSIZES values (SS_ means Supported Sizes) */
+#define TWSS_NONE 0
+#define TWSS_A4LETTER 1
+#define TWSS_B5LETTER 2
+#define TWSS_USLETTER 3
+#define TWSS_USLEGAL 4
+/* Added 1.5 */
+#define TWSS_A5 5
+#define TWSS_B4 6
+#define TWSS_B6 7
+/*#define TWSS_B 8 */
+/* Added 1.7 */
+#define TWSS_USLEDGER 9
+#define TWSS_USEXECUTIVE 10
+#define TWSS_A3 11
+#define TWSS_B3 12
+#define TWSS_A6 13
+#define TWSS_C4 14
+#define TWSS_C5 15
+#define TWSS_C6 16
+/* Added 1.8 */
+#define TWSS_4A0 17
+#define TWSS_2A0 18
+#define TWSS_A0 19
+#define TWSS_A1 20
+#define TWSS_A2 21
+#define TWSS_A4 TWSS_A4LETTER
+#define TWSS_A7 22
+#define TWSS_A8 23
+#define TWSS_A9 24
+#define TWSS_A10 25
+#define TWSS_ISOB0 26
+#define TWSS_ISOB1 27
+#define TWSS_ISOB2 28
+#define TWSS_ISOB3 TWSS_B3
+#define TWSS_ISOB4 TWSS_B4
+#define TWSS_ISOB5 29
+#define TWSS_ISOB6 TWSS_B6
+#define TWSS_ISOB7 30
+#define TWSS_ISOB8 31
+#define TWSS_ISOB9 32
+#define TWSS_ISOB10 33
+#define TWSS_JISB0 34
+#define TWSS_JISB1 35
+#define TWSS_JISB2 36
+#define TWSS_JISB3 37
+#define TWSS_JISB4 38
+#define TWSS_JISB5 TWSS_B5LETTER
+#define TWSS_JISB6 39
+#define TWSS_JISB7 40
+#define TWSS_JISB8 41
+#define TWSS_JISB9 42
+#define TWSS_JISB10 43
+#define TWSS_C0 44
+#define TWSS_C1 45
+#define TWSS_C2 46
+#define TWSS_C3 47
+#define TWSS_C7 48
+#define TWSS_C8 49
+#define TWSS_C9 50
+#define TWSS_C10 51
+#define TWSS_USSTATEMENT 52
+#define TWSS_BUSINESSCARD 53
+
+/* ICAP_XFERMECH values (SX_ means Setup XFer) */
+#define TWSX_NATIVE 0
+#define TWSX_FILE 1
+#define TWSX_MEMORY 2
+
+/* ICAP_UNITS values (UN_ means UNits) */
+#define TWUN_INCHES 0
+#define TWUN_CENTIMETERS 1
+#define TWUN_PICAS 2
+#define TWUN_POINTS 3
+#define TWUN_TWIPS 4
+#define TWUN_PIXELS 5
+
+/* Added 1.5 */
+/* ICAP_BITDEPTHREDUCTION values (BR_ means Bitdepth Reduction) */
+#define TWBR_THRESHOLD 0
+#define TWBR_HALFTONE 1
+#define TWBR_CUSTHALFTONE 2
+#define TWBR_DIFFUSION 3
+
+/* Added 1.7 */
+/* ICAP_DUPLEX values */
+#define TWDX_NONE 0
+#define TWDX_1PASSDUPLEX 1
+#define TWDX_2PASSDUPLEX 2
+
+/* Added 1.7 */
+/* TWEI_BARCODETYPE values */
+#define TWBT_3OF9 0
+#define TWBT_2OF5INTERLEAVED 1
+#define TWBT_2OF5NONINTERLEAVED 2
+#define TWBT_CODE93 3
+#define TWBT_CODE128 4
+#define TWBT_UCC128 5
+#define TWBT_CODABAR 6
+#define TWBT_UPCA 7
+#define TWBT_UPCE 8
+#define TWBT_EAN8 9
+#define TWBT_EAN13 10
+#define TWBT_POSTNET 11
+#define TWBT_PDF417 12
+/* Added 1.8 */
+#define TWBT_2OF5INDUSTRIAL 13
+#define TWBT_2OF5MATRIX 14
+#define TWBT_2OF5DATALOGIC 15
+#define TWBT_2OF5IATA 16
+#define TWBT_3OF9FULLASCII 17
+#define TWBT_CODABARWITHSTARTSTOP 18
+
+
+/* Added 1.7 */
+/* TWEI_DESKEWSTATUS values */
+#define TWDSK_SUCCESS 0
+#define TWDSK_REPORTONLY 1
+#define TWDSK_FAIL 2
+#define TWDSK_DISABLED 3
+
+/* Added 1.7 */
+/* TWEI_PATCHCODE values */
+#define TWPCH_PATCH1 0
+#define TWPCH_PATCH2 1
+#define TWPCH_PATCH3 2
+#define TWPCH_PATCH4 3
+#define TWPCH_PATCH6 4
+#define TWPCH_PATCHT 5
+
+/* Added 1.7 */
+/* CAP_JOBCONTROL values */
+#define TWJC_NONE 0
+#define TWJC_JSIC 1
+#define TWJC_JSIS 2
+#define TWJC_JSXC 3
+#define TWJC_JSXS 4
+
+/* Added 1.7 */
+/* TWEI_BARCODEROTATION values (BCOR_ means barcode rotation) */
+#define TWBCOR_ROT0 0
+#define TWBCOR_ROT90 1
+#define TWBCOR_ROT180 2
+#define TWBCOR_ROT270 3
+#define TWBCOR_ROTX 4
+
+/* Added 1.8 */
+/* ACAP_AUDIOFILEFORMAT values (AF_ means audio format) */
+#define TWAF_WAV 0
+#define TWAF_AIFF 1
+#define TWAF_AU 3
+#define TWAF_SND 4
+
+/* CAP_ALARMS values (AL_ means alarms) */
+#define TWAL_ALARM 0
+#define TWAL_FEEDERERROR 1
+#define TWAL_FEEDERWARNING 2
+#define TWAL_BARCODE 3
+#define TWAL_DOUBLEFEED 4
+#define TWAL_JAM 5
+#define TWAL_PATCHCODE 6
+#define TWAL_POWER 7
+#define TWAL_SKEW 8
+
+/* CAP_CLEARBUFFERS values (CB_ means clear buffers) */
+#define TWCB_AUTO 0
+#define TWCB_CLEAR 1
+#define TWCB_NOCLEAR 2
+
+/* CAP_DEVICEEVENT values (DE_ means device event) */
+#define TWDE_CUSTOMEVENTS 0x8000
+#define TWDE_CHECKAUTOMATICCAPTURE 0
+#define TWDE_CHECKBATTERY 1
+#define TWDE_CHECKDEVICEONLINE 2
+#define TWDE_CHECKFLASH 3
+#define TWDE_CHECKPOWERSUPPLY 4
+#define TWDE_CHECKRESOLUTION 5
+#define TWDE_DEVICEADDED 6
+#define TWDE_DEVICEOFFLINE 7
+#define TWDE_DEVICEREADY 8
+#define TWDE_DEVICEREMOVED 9
+#define TWDE_IMAGECAPTURED 10
+#define TWDE_IMAGEDELETED 11
+#define TWDE_PAPERDOUBLEFEED 12
+#define TWDE_PAPERJAM 13
+#define TWDE_LAMPFAILURE 14
+#define TWDE_POWERSAVE 15
+#define TWDE_POWERSAVENOTIFY 16
+
+/* CAP_FEEDERALIGNMENT values (FA_ means feeder alignment) */
+#define TWFA_NONE 0
+#define TWFA_LEFT 1
+#define TWFA_CENTER 2
+#define TWFA_RIGHT 3
+
+/* CAP_FEEDERORDER values (FO_ means feeder order) */
+#define TWFO_FIRSTPAGEFIRST 0
+#define TWFO_LASTPAGEFIRST 1
+
+/* CAP_FILESYSTEM values (FS_ means file system) */
+#define TWFS_FILESYSTEM 0
+#define TWFS_RECURSIVEDELETE 1
+
+/* CAP_POWERSUPPLY values (PS_ means power supply) */
+#define TWPS_EXTERNAL 0
+#define TWPS_BATTERY 1
+
+/* CAP_PRINTER values (PR_ means printer) */
+#define TWPR_IMPRINTERTOPBEFORE 0
+#define TWPR_IMPRINTERTOPAFTER 1
+#define TWPR_IMPRINTERBOTTOMBEFORE 2
+#define TWPR_IMPRINTERBOTTOMAFTER 3
+#define TWPR_ENDORSERTOPBEFORE 4
+#define TWPR_ENDORSERTOPAFTER 5
+#define TWPR_ENDORSERBOTTOMBEFORE 6
+#define TWPR_ENDORSERBOTTOMAFTER 7
+
+/* CAP_PRINTERMODE values (PM_ means printer mode) */
+#define TWPM_SINGLESTRING 0
+#define TWPM_MULTISTRING 1
+#define TWPM_COMPOUNDSTRING 2
+
+/* ICAP_BARCODESEARCHMODE values (SRCH_ means search) */
+#define SRCH_HORZ 0
+#define SRCH_VERT 1
+#define SRCH_HORZVERT 2
+#define SRCH_VERTHORZ 3
+
+/* ICAP_FLASHUSED2 values (FL_ means flash) */
+#define TWFL_NONE 0
+#define TWFL_OFF 1
+#define TWFL_ON 2
+#define TWFL_AUTO 3
+#define TWFL_REDEYE 4
+
+/* ICAP_FLIPROTATION values (FR_ means flip rotation) */
+#define TWFR_BOOK 0
+#define TWFR_FANFOLD 1
+
+/* ICAP_IMAGEFILTER values (IF_ means image filter) */
+#define TWIF_NONE 0
+#define TWIF_AUTO 1
+#define TWIF_LOWPASS 2
+#define TWIF_BANDPASS 3
+#define TWIF_HIGHPASS 4
+#define TWIF_TEXT TWIF_BANDPASS
+#define TWIF_FINELINE TWIF_HIGHPASS
+
+/* ICAP_NOISEFILTER values (NF_ means noise filter) */
+#define TWNF_NONE 0
+#define TWNF_AUTO 1
+#define TWNF_LONEPIXEL 2
+#define TWNF_MAJORITYRULE 3
+
+/* ICAP_OVERSCAN values (OV_ means overscan) */
+#define TWOV_NONE 0
+#define TWOV_AUTO 1
+#define TWOV_TOPBOTTOM 2
+#define TWOV_LEFTRIGHT 3
+#define TWOV_ALL 4
+
+/* TW_FILESYSTEM.FileType values (FT_ means file type) */
+#define TWFY_CAMERA 0
+#define TWFY_CAMERATOP 1
+#define TWFY_CAMERABOTTOM 2
+#define TWFY_CAMERAPREVIEW 3
+#define TWFY_DOMAIN 4
+#define TWFY_HOST 5
+#define TWFY_DIRECTORY 6
+#define TWFY_IMAGE 7
+#define TWFY_UNKNOWN 8
+
+/****************************************************************************
+ * Country Constants *
+ ****************************************************************************/
+
+#define TWCY_AFGHANISTAN 1001
+#define TWCY_ALGERIA 213
+#define TWCY_AMERICANSAMOA 684
+#define TWCY_ANDORRA 033
+#define TWCY_ANGOLA 1002
+#define TWCY_ANGUILLA 8090
+#define TWCY_ANTIGUA 8091
+#define TWCY_ARGENTINA 54
+#define TWCY_ARUBA 297
+#define TWCY_ASCENSIONI 247
+#define TWCY_AUSTRALIA 61
+#define TWCY_AUSTRIA 43
+#define TWCY_BAHAMAS 8092
+#define TWCY_BAHRAIN 973
+#define TWCY_BANGLADESH 880
+#define TWCY_BARBADOS 8093
+#define TWCY_BELGIUM 32
+#define TWCY_BELIZE 501
+#define TWCY_BENIN 229
+#define TWCY_BERMUDA 8094
+#define TWCY_BHUTAN 1003
+#define TWCY_BOLIVIA 591
+#define TWCY_BOTSWANA 267
+#define TWCY_BRITAIN 6
+#define TWCY_BRITVIRGINIS 8095
+#define TWCY_BRAZIL 55
+#define TWCY_BRUNEI 673
+#define TWCY_BULGARIA 359
+#define TWCY_BURKINAFASO 1004
+#define TWCY_BURMA 1005
+#define TWCY_BURUNDI 1006
+#define TWCY_CAMAROON 237
+#define TWCY_CANADA 2
+#define TWCY_CAPEVERDEIS 238
+#define TWCY_CAYMANIS 8096
+#define TWCY_CENTRALAFREP 1007
+#define TWCY_CHAD 1008
+#define TWCY_CHILE 56
+#define TWCY_CHINA 86
+#define TWCY_CHRISTMASIS 1009
+#define TWCY_COCOSIS 1009
+#define TWCY_COLOMBIA 57
+#define TWCY_COMOROS 1010
+#define TWCY_CONGO 1011
+#define TWCY_COOKIS 1012
+#define TWCY_COSTARICA 506
+#define TWCY_CUBA 005
+#define TWCY_CYPRUS 357
+#define TWCY_CZECHOSLOVAKIA 42
+#define TWCY_DENMARK 45
+#define TWCY_DJIBOUTI 1013
+#define TWCY_DOMINICA 8097
+#define TWCY_DOMINCANREP 8098
+#define TWCY_EASTERIS 1014
+#define TWCY_ECUADOR 593
+#define TWCY_EGYPT 20
+#define TWCY_ELSALVADOR 503
+#define TWCY_EQGUINEA 1015
+#define TWCY_ETHIOPIA 251
+#define TWCY_FALKLANDIS 1016
+#define TWCY_FAEROEIS 298
+#define TWCY_FIJIISLANDS 679
+#define TWCY_FINLAND 358
+#define TWCY_FRANCE 33
+#define TWCY_FRANTILLES 596
+#define TWCY_FRGUIANA 594
+#define TWCY_FRPOLYNEISA 689
+#define TWCY_FUTANAIS 1043
+#define TWCY_GABON 241
+#define TWCY_GAMBIA 220
+#define TWCY_GERMANY 49
+#define TWCY_GHANA 233
+#define TWCY_GIBRALTER 350
+#define TWCY_GREECE 30
+#define TWCY_GREENLAND 299
+#define TWCY_GRENADA 8099
+#define TWCY_GRENEDINES 8015
+#define TWCY_GUADELOUPE 590
+#define TWCY_GUAM 671
+#define TWCY_GUANTANAMOBAY 5399
+#define TWCY_GUATEMALA 502
+#define TWCY_GUINEA 224
+#define TWCY_GUINEABISSAU 1017
+#define TWCY_GUYANA 592
+#define TWCY_HAITI 509
+#define TWCY_HONDURAS 504
+#define TWCY_HONGKONG 852
+#define TWCY_HUNGARY 36
+#define TWCY_ICELAND 354
+#define TWCY_INDIA 91
+#define TWCY_INDONESIA 62
+#define TWCY_IRAN 98
+#define TWCY_IRAQ 964
+#define TWCY_IRELAND 353
+#define TWCY_ISRAEL 972
+#define TWCY_ITALY 39
+#define TWCY_IVORYCOAST 225
+#define TWCY_JAMAICA 8010
+#define TWCY_JAPAN 81
+#define TWCY_JORDAN 962
+#define TWCY_KENYA 254
+#define TWCY_KIRIBATI 1018
+#define TWCY_KOREA 82
+#define TWCY_KUWAIT 965
+#define TWCY_LAOS 1019
+#define TWCY_LEBANON 1020
+#define TWCY_LIBERIA 231
+#define TWCY_LIBYA 218
+#define TWCY_LIECHTENSTEIN 41
+#define TWCY_LUXENBOURG 352
+#define TWCY_MACAO 853
+#define TWCY_MADAGASCAR 1021
+#define TWCY_MALAWI 265
+#define TWCY_MALAYSIA 60
+#define TWCY_MALDIVES 960
+#define TWCY_MALI 1022
+#define TWCY_MALTA 356
+#define TWCY_MARSHALLIS 692
+#define TWCY_MAURITANIA 1023
+#define TWCY_MAURITIUS 230
+#define TWCY_MEXICO 3
+#define TWCY_MICRONESIA 691
+#define TWCY_MIQUELON 508
+#define TWCY_MONACO 33
+#define TWCY_MONGOLIA 1024
+#define TWCY_MONTSERRAT 8011
+#define TWCY_MOROCCO 212
+#define TWCY_MOZAMBIQUE 1025
+#define TWCY_NAMIBIA 264
+#define TWCY_NAURU 1026
+#define TWCY_NEPAL 977
+#define TWCY_NETHERLANDS 31
+#define TWCY_NETHANTILLES 599
+#define TWCY_NEVIS 8012
+#define TWCY_NEWCALEDONIA 687
+#define TWCY_NEWZEALAND 64
+#define TWCY_NICARAGUA 505
+#define TWCY_NIGER 227
+#define TWCY_NIGERIA 234
+#define TWCY_NIUE 1027
+#define TWCY_NORFOLKI 1028
+#define TWCY_NORWAY 47
+#define TWCY_OMAN 968
+#define TWCY_PAKISTAN 92
+#define TWCY_PALAU 1029
+#define TWCY_PANAMA 507
+#define TWCY_PARAGUAY 595
+#define TWCY_PERU 51
+#define TWCY_PHILLIPPINES 63
+#define TWCY_PITCAIRNIS 1030
+#define TWCY_PNEWGUINEA 675
+#define TWCY_POLAND 48
+#define TWCY_PORTUGAL 351
+#define TWCY_QATAR 974
+#define TWCY_REUNIONI 1031
+#define TWCY_ROMANIA 40
+#define TWCY_RWANDA 250
+#define TWCY_SAIPAN 670
+#define TWCY_SANMARINO 39
+#define TWCY_SAOTOME 1033
+#define TWCY_SAUDIARABIA 966
+#define TWCY_SENEGAL 221
+#define TWCY_SEYCHELLESIS 1034
+#define TWCY_SIERRALEONE 1035
+#define TWCY_SINGAPORE 65
+#define TWCY_SOLOMONIS 1036
+#define TWCY_SOMALI 1037
+#define TWCY_SOUTHAFRICA 27
+#define TWCY_SPAIN 34
+#define TWCY_SRILANKA 94
+#define TWCY_STHELENA 1032
+#define TWCY_STKITTS 8013
+#define TWCY_STLUCIA 8014
+#define TWCY_STPIERRE 508
+#define TWCY_STVINCENT 8015
+#define TWCY_SUDAN 1038
+#define TWCY_SURINAME 597
+#define TWCY_SWAZILAND 268
+#define TWCY_SWEDEN 46
+#define TWCY_SWITZERLAND 41
+#define TWCY_SYRIA 1039
+#define TWCY_TAIWAN 886
+#define TWCY_TANZANIA 255
+#define TWCY_THAILAND 66
+#define TWCY_TOBAGO 8016
+#define TWCY_TOGO 228
+#define TWCY_TONGAIS 676
+#define TWCY_TRINIDAD 8016
+#define TWCY_TUNISIA 216
+#define TWCY_TURKEY 90
+#define TWCY_TURKSCAICOS 8017
+#define TWCY_TUVALU 1040
+#define TWCY_UGANDA 256
+#define TWCY_USSR 7
+#define TWCY_UAEMIRATES 971
+#define TWCY_UNITEDKINGDOM 44
+#define TWCY_USA 1
+#define TWCY_URUGUAY 598
+#define TWCY_VANUATU 1041
+#define TWCY_VATICANCITY 39
+#define TWCY_VENEZUELA 58
+#define TWCY_WAKE 1042
+#define TWCY_WALLISIS 1043
+#define TWCY_WESTERNSAHARA 1044
+#define TWCY_WESTERNSAMOA 1045
+#define TWCY_YEMEN 1046
+#define TWCY_YUGOSLAVIA 38
+#define TWCY_ZAIRE 243
+#define TWCY_ZAMBIA 260
+#define TWCY_ZIMBABWE 263
+
+/****************************************************************************
+ * Language Constants *
+ ****************************************************************************/
+
+#define TWLG_DAN 0 /* Danish */
+#define TWLG_DUT 1 /* Dutch */
+#define TWLG_ENG 2 /* International English */
+#define TWLG_FCF 3 /* French Canadian */
+#define TWLG_FIN 4 /* Finnish */
+#define TWLG_FRN 5 /* French */
+#define TWLG_GER 6 /* German */
+#define TWLG_ICE 7 /* Icelandic */
+#define TWLG_ITN 8 /* Italian */
+#define TWLG_NOR 9 /* Norwegian */
+#define TWLG_POR 10 /* Portuguese */
+#define TWLG_SPA 11 /* Spanish */
+#define TWLG_SWE 12 /* Swedish */
+#define TWLG_USA 13 /* U.S. English */
+/* Added for 1.8 */
+#define TWLG_USERLOCALE -1
+#define TWLG_AFRIKAANS 14
+#define TWLG_ALBANIA 15
+#define TWLG_ARABIC 16
+#define TWLG_ARABIC_ALGERIA 17
+#define TWLG_ARABIC_BAHRAIN 18
+#define TWLG_ARABIC_EGYPT 19
+#define TWLG_ARABIC_IRAQ 20
+#define TWLG_ARABIC_JORDAN 21
+#define TWLG_ARABIC_KUWAIT 22
+#define TWLG_ARABIC_LEBANON 23
+#define TWLG_ARABIC_LIBYA 24
+#define TWLG_ARABIC_MOROCCO 25
+#define TWLG_ARABIC_OMAN 26
+#define TWLG_ARABIC_QATAR 27
+#define TWLG_ARABIC_SAUDIARABIA 28
+#define TWLG_ARABIC_SYRIA 29
+#define TWLG_ARABIC_TUNISIA 30
+#define TWLG_ARABIC_UAE 31 /* United Arabic Emirates */
+#define TWLG_ARABIC_YEMEN 32
+#define TWLG_BASQUE 33
+#define TWLG_BYELORUSSIAN 34
+#define TWLG_BULGARIAN 35
+#define TWLG_CATALAN 36
+#define TWLG_CHINESE 37
+#define TWLG_CHINESE_HONGKONG 38
+#define TWLG_CHINESE_PRC 39 /* People's Republic of China */
+#define TWLG_CHINESE_SINGAPORE 40
+#define TWLG_CHINESE_SIMPLIFIED 41
+#define TWLG_CHINESE_TAIWAN 42
+#define TWLG_CHINESE_TRADITIONAL 43
+#define TWLG_CROATIA 44
+#define TWLG_CZECH 45
+#define TWLG_DANISH TWLG_DAN
+#define TWLG_DUTCH TWLG_DUT
+#define TWLG_DUTCH_BELGIAN 46
+#define TWLG_ENGLISH TWLG_ENG
+#define TWLG_ENGLISH_AUSTRALIAN 47
+#define TWLG_ENGLISH_CANADIAN 48
+#define TWLG_ENGLISH_IRELAND 49
+#define TWLG_ENGLISH_NEWZEALAND 50
+#define TWLG_ENGLISH_SOUTHAFRICA 51
+#define TWLG_ENGLISH_UK 52
+#define TWLG_ENGLISH_USA TWLG_USA
+#define TWLG_ESTONIAN 53
+#define TWLG_FAEROESE 54
+#define TWLG_FARSI 55
+#define TWLG_FINNISH TWLG_FIN
+#define TWLG_FRENCH TWLG_FRN
+#define TWLG_FRENCH_BELGIAN 56
+#define TWLG_FRENCH_CANADIAN TWLG_FCF
+#define TWLG_FRENCH_LUXEMBOURG 57
+#define TWLG_FRENCH_SWISS 58
+#define TWLG_GERMAN TWLG_GER
+#define TWLG_GERMAN_AUSTRIAN 59
+#define TWLG_GERMAN_LUXEMBOURG 60
+#define TWLG_GERMAN_LIECHTENSTEIN 61
+#define TWLG_GERMAN_SWISS 62
+#define TWLG_GREEK 63
+#define TWLG_HEBREW 64
+#define TWLG_HUNGARIAN 65
+#define TWLG_ICELANDIC TWLG_ICE
+#define TWLG_INDONESIAN 66
+#define TWLG_ITALIAN TWLG_ITN
+#define TWLG_ITALIAN_SWISS 67
+#define TWLG_JAPANESE 68
+#define TWLG_KOREAN 69
+#define TWLG_KOREAN_JOHAB 70
+#define TWLG_LATVIAN 71
+#define TWLG_LITHUANIAN 72
+#define TWLG_NORWEGIAN TWLG_NOR
+#define TWLG_NORWEGIAN_BOKMAL 73
+#define TWLG_NORWEGIAN_NYNORSK 74
+#define TWLG_POLISH 75
+#define TWLG_PORTUGUESE TWLG_POR
+#define TWLG_PORTUGUESE_BRAZIL 76
+#define TWLG_ROMANIAN 77
+#define TWLG_RUSSIAN 78
+#define TWLG_SERBIAN_LATIN 79
+#define TWLG_SLOVAK 80
+#define TWLG_SLOVENIAN 81
+#define TWLG_SPANISH TWLG_SPA
+#define TWLG_SPANISH_MEXICAN 82
+#define TWLG_SPANISH_MODERN 83
+#define TWLG_SWEDISH TWLG_SWE
+#define TWLG_THAI 84
+#define TWLG_TURKISH 85
+#define TWLG_UKRANIAN 86
+
+/****************************************************************************
+ * Data Groups *
+ ****************************************************************************/
+
+/* More Data Groups may be added in the future.
+ * Possible candidates include text, vector graphics, sound, etc.
+ * NOTE: Data Group constants must be powers of 2 as they are used
+ * as bitflags when Application asks DSM to present a list of DSs.
+ */
+
+#define DG_CONTROL 0x0001L /* data pertaining to control */
+#define DG_IMAGE 0x0002L /* data pertaining to raster images */
+/* Added 1.8 */
+#define DG_AUDIO 0x0004L /* data pertaining to audio */
+
+/****************************************************************************
+ * Data Argument Types *
+ ****************************************************************************/
+
+/* SDH - 03/23/95 - WATCH */
+/* The thunker requires knowledge about size of data being passed in the */
+/* lpData parameter to DS_Entry (which is not readily available due to */
+/* type LPVOID. Thus, we key off the DAT_ argument to determine the size. */
+/* This has a couple implications: */
+/* 1) Any additional DAT_ features require modifications to the thunk code */
+/* for thunker support. */
+/* 2) Any applications which use the custom capabilities are not supported */
+/* under thunking since we have no way of knowing what size data (if */
+/* any) is being passed. */
+
+#define DAT_NULL 0x0000 /* No data or structure. */
+#define DAT_CUSTOMBASE 0x8000 /* Base of custom DATs. */
+
+/* Data Argument Types for the DG_CONTROL Data Group. */
+#define DAT_CAPABILITY 0x0001 /* TW_CAPABILITY */
+#define DAT_EVENT 0x0002 /* TW_EVENT */
+#define DAT_IDENTITY 0x0003 /* TW_IDENTITY */
+#define DAT_PARENT 0x0004 /* TW_HANDLE, application win handle in Windows */
+#define DAT_PENDINGXFERS 0x0005 /* TW_PENDINGXFERS */
+#define DAT_SETUPMEMXFER 0x0006 /* TW_SETUPMEMXFER */
+#define DAT_SETUPFILEXFER 0x0007 /* TW_SETUPFILEXFER */
+#define DAT_STATUS 0x0008 /* TW_STATUS */
+#define DAT_USERINTERFACE 0x0009 /* TW_USERINTERFACE */
+#define DAT_XFERGROUP 0x000a /* TW_UINT32 */
+/* SDH - 03/21/95 - TWUNK */
+/* Additional message required for thunker to request the special */
+/* identity information. */
+#define DAT_TWUNKIDENTITY 0x000b /* TW_TWUNKIDENTITY */
+#define DAT_CUSTOMDSDATA 0x000c /* TW_CUSTOMDSDATA. */
+/* Added 1.8 */
+#define DAT_DEVICEEVENT 0x000d /* TW_DEVICEEVENT */
+#define DAT_FILESYSTEM 0x000e /* TW_FILESYSTEM */
+#define DAT_PASSTHRU 0x000f /* TW_PASSTHRU */
+
+/* Data Argument Types for the DG_IMAGE Data Group. */
+#define DAT_IMAGEINFO 0x0101 /* TW_IMAGEINFO */
+#define DAT_IMAGELAYOUT 0x0102 /* TW_IMAGELAYOUT */
+#define DAT_IMAGEMEMXFER 0x0103 /* TW_IMAGEMEMXFER */
+#define DAT_IMAGENATIVEXFER 0x0104 /* TW_UINT32 loword is hDIB, PICHandle */
+#define DAT_IMAGEFILEXFER 0x0105 /* Null data */
+#define DAT_CIECOLOR 0x0106 /* TW_CIECOLOR */
+#define DAT_GRAYRESPONSE 0x0107 /* TW_GRAYRESPONSE */
+#define DAT_RGBRESPONSE 0x0108 /* TW_RGBRESPONSE */
+#define DAT_JPEGCOMPRESSION 0x0109 /* TW_JPEGCOMPRESSION */
+#define DAT_PALETTE8 0x010a /* TW_PALETTE8 */
+#define DAT_EXTIMAGEINFO 0x010b /* TW_EXTIMAGEINFO -- for 1.7 Spec. */
+
+/* Added 1.8 */
+/* Data Argument Types for the DG_AUDIO Data Group. */
+#define DAT_AUDIOFILEXFER 0x0201 /* Null data */
+#define DAT_AUDIOINFO 0x0202 /* TW_AUDIOINFO */
+#define DAT_AUDIONATIVEXFER 0x0203 /* TW_UINT32 handle to WAV, (AIFF Mac) */
+
+/****************************************************************************
+ * Messages *
+ ****************************************************************************/
+
+/* All message constants are unique.
+ * Messages are grouped according to which DATs they are used with.*/
+
+#define MSG_NULL 0x0000 /* Used in TW_EVENT structure */
+#define MSG_CUSTOMBASE 0x8000 /* Base of custom messages */
+
+/* Generic messages may be used with any of several DATs. */
+#define MSG_GET 0x0001 /* Get one or more values */
+#define MSG_GETCURRENT 0x0002 /* Get current value */
+#define MSG_GETDEFAULT 0x0003 /* Get default (e.g. power up) value */
+#define MSG_GETFIRST 0x0004 /* Get first of a series of items, e.g. DSs */
+#define MSG_GETNEXT 0x0005 /* Iterate through a series of items. */
+#define MSG_SET 0x0006 /* Set one or more values */
+#define MSG_RESET 0x0007 /* Set current value to default value */
+#define MSG_QUERYSUPPORT 0x0008 /* Get supported operations on the cap. */
+
+/* Messages used with DAT_NULL */
+#define MSG_XFERREADY 0x0101 /* The data source has data ready */
+#define MSG_CLOSEDSREQ 0x0102 /* Request for Application. to close DS */
+#define MSG_CLOSEDSOK 0x0103 /* Tell the Application. to save the state. */
+/* Added 1.8 */
+#define MSG_DEVICEEVENT 0X0104 /* Some event has taken place */
+
+/* Messages used with a pointer to a DAT_STATUS structure */
+#define MSG_CHECKSTATUS 0x0201 /* Get status information */
+
+/* Messages used with a pointer to DAT_PARENT data */
+#define MSG_OPENDSM 0x0301 /* Open the DSM */
+#define MSG_CLOSEDSM 0x0302 /* Close the DSM */
+
+/* Messages used with a pointer to a DAT_IDENTITY structure */
+#define MSG_OPENDS 0x0401 /* Open a data source */
+#define MSG_CLOSEDS 0x0402 /* Close a data source */
+#define MSG_USERSELECT 0x0403 /* Put up a dialog of all DS */
+
+/* Messages used with a pointer to a DAT_USERINTERFACE structure */
+#define MSG_DISABLEDS 0x0501 /* Disable data transfer in the DS */
+#define MSG_ENABLEDS 0x0502 /* Enable data transfer in the DS */
+#define MSG_ENABLEDSUIONLY 0x0503 /* Enable for saving DS state only. */
+
+/* Messages used with a pointer to a DAT_EVENT structure */
+#define MSG_PROCESSEVENT 0x0601
+
+/* Messages used with a pointer to a DAT_PENDINGXFERS structure */
+#define MSG_ENDXFER 0x0701
+
+/* Added 1.8 */
+/* Messages used with a pointer to a DAT_FILESYSTEM structure */
+#define MSG_CHANGEDIRECTORY 0x0801
+#define MSG_CREATEDIRECTORY 0x0802
+#define MSG_DELETE 0x0803
+#define MSG_FORMATMEDIA 0x0804
+#define MSG_GETCLOSE 0x0805
+#define MSG_GETFIRSTFILE 0x0806
+#define MSG_GETINFO 0x0807
+#define MSG_GETNEXTFILE 0x0808
+#define MSG_RENAME 0x0809
+
+/* Messages used with a pointer to a DAT_PASSTHRU structure */
+#define MSG_PASSTHRU 0x0901
+
+/****************************************************************************
+ * Capabilities *
+ ****************************************************************************/
+
+#define CAP_CUSTOMBASE 0x8000 /* Base of custom capabilities */
+
+/* all data sources are REQUIRED to support these caps */
+#define CAP_XFERCOUNT 0x0001
+
+/* image data sources are REQUIRED to support these caps */
+#define ICAP_COMPRESSION 0x0100
+#define ICAP_PIXELTYPE 0x0101
+#define ICAP_UNITS 0x0102 /* default is TWUN_INCHES */
+#define ICAP_XFERMECH 0x0103
+
+/* all data sources MAY support these caps */
+#define CAP_AUTHOR 0x1000
+#define CAP_CAPTION 0x1001
+#define CAP_FEEDERENABLED 0x1002
+#define CAP_FEEDERLOADED 0x1003
+#define CAP_TIMEDATE 0x1004
+#define CAP_SUPPORTEDCAPS 0x1005
+#define CAP_EXTENDEDCAPS 0x1006
+#define CAP_AUTOFEED 0x1007
+#define CAP_CLEARPAGE 0x1008
+#define CAP_FEEDPAGE 0x1009
+#define CAP_REWINDPAGE 0x100a
+#define CAP_INDICATORS 0x100b /* Added 1.1 */
+#define CAP_SUPPORTEDCAPSEXT 0x100c /* Added 1.6 */
+#define CAP_PAPERDETECTABLE 0x100d /* Added 1.6 */
+#define CAP_UICONTROLLABLE 0x100e /* Added 1.6 */
+#define CAP_DEVICEONLINE 0x100f /* Added 1.6 */
+#define CAP_AUTOSCAN 0x1010 /* Added 1.6 */
+#define CAP_THUMBNAILSENABLED 0x1011 /* Added 1.7 */
+#define CAP_DUPLEX 0x1012 /* Added 1.7 */
+#define CAP_DUPLEXENABLED 0x1013 /* Added 1.7 */
+#define CAP_ENABLEDSUIONLY 0x1014 /* Added 1.7 */
+#define CAP_CUSTOMDSDATA 0x1015 /* Added 1.7 */
+#define CAP_ENDORSER 0x1016 /* Added 1.7 */
+#define CAP_JOBCONTROL 0x1017 /* Added 1.7 */
+#define CAP_ALARMS 0x1018 /* Added 1.8 */
+#define CAP_ALARMVOLUME 0x1019 /* Added 1.8 */
+#define CAP_AUTOMATICCAPTURE 0x101a /* Added 1.8 */
+#define CAP_TIMEBEFOREFIRSTCAPTURE 0x101b /* Added 1.8 */
+#define CAP_TIMEBETWEENCAPTURES 0x101c /* Added 1.8 */
+#define CAP_CLEARBUFFERS 0x101d /* Added 1.8 */
+#define CAP_MAXBATCHBUFFERS 0x101e /* Added 1.8 */
+#define CAP_DEVICETIMEDATE 0x101f /* Added 1.8 */
+#define CAP_POWERSUPPLY 0x1020 /* Added 1.8 */
+#define CAP_CAMERAPREVIEWUI 0x1021 /* Added 1.8 */
+#define CAP_DEVICEEVENT 0x1022 /* Added 1.8 */
+#define CAP_PAGEMULTIPLEACQUIRE 0x1023 /* Added 1.8 */
+#define CAP_SERIALNUMBER 0x1024 /* Added 1.8 */
+#define CAP_FILESYSTEM 0x1025 /* Added 1.8 */
+#define CAP_PRINTER 0x1026 /* Added 1.8 */
+#define CAP_PRINTERENABLED 0x1027 /* Added 1.8 */
+#define CAP_PRINTERINDEX 0x1028 /* Added 1.8 */
+#define CAP_PRINTERMODE 0x1029 /* Added 1.8 */
+#define CAP_PRINTERSTRING 0x102a /* Added 1.8 */
+#define CAP_PRINTERSUFFIX 0x102b /* Added 1.8 */
+#define CAP_LANGUAGE 0x102c /* Added 1.8 */
+#define CAP_FEEDERALIGNMENT 0x102d /* Added 1.8 */
+#define CAP_FEEDERORDER 0x102e /* Added 1.8 */
+#define CAP_PAPERBINDING 0x102f /* Added 1.8 */
+#define CAP_REACQUIREALLOWED 0x1030 /* Added 1.8 */
+#define CAP_PASSTHRU 0x1031 /* Added 1.8 */
+#define CAP_BATTERYMINUTES 0x1032 /* Added 1.8 */
+#define CAP_BATTERYPERCENTAGE 0x1033 /* Added 1.8 */
+#define CAP_POWERDOWNTIME 0x1034 /* Added 1.8 */
+
+/* image data sources MAY support these caps */
+#define ICAP_AUTOBRIGHT 0x1100
+#define ICAP_BRIGHTNESS 0x1101
+#define ICAP_CONTRAST 0x1103
+#define ICAP_CUSTHALFTONE 0x1104
+#define ICAP_EXPOSURETIME 0x1105
+#define ICAP_FILTER 0x1106
+#define ICAP_FLASHUSED 0x1107
+#define ICAP_GAMMA 0x1108
+#define ICAP_HALFTONES 0x1109
+#define ICAP_HIGHLIGHT 0x110a
+#define ICAP_IMAGEFILEFORMAT 0x110c
+#define ICAP_LAMPSTATE 0x110d
+#define ICAP_LIGHTSOURCE 0x110e
+#define ICAP_ORIENTATION 0x1110
+#define ICAP_PHYSICALWIDTH 0x1111
+#define ICAP_PHYSICALHEIGHT 0x1112
+#define ICAP_SHADOW 0x1113
+#define ICAP_FRAMES 0x1114
+#define ICAP_XNATIVERESOLUTION 0x1116
+#define ICAP_YNATIVERESOLUTION 0x1117
+#define ICAP_XRESOLUTION 0x1118
+#define ICAP_YRESOLUTION 0x1119
+#define ICAP_MAXFRAMES 0x111a
+#define ICAP_TILES 0x111b
+#define ICAP_BITORDER 0x111c
+#define ICAP_CCITTKFACTOR 0x111d
+#define ICAP_LIGHTPATH 0x111e
+#define ICAP_PIXELFLAVOR 0x111f
+#define ICAP_PLANARCHUNKY 0x1120
+#define ICAP_ROTATION 0x1121
+#define ICAP_SUPPORTEDSIZES 0x1122
+#define ICAP_THRESHOLD 0x1123
+#define ICAP_XSCALING 0x1124
+#define ICAP_YSCALING 0x1125
+#define ICAP_BITORDERCODES 0x1126
+#define ICAP_PIXELFLAVORCODES 0x1127
+#define ICAP_JPEGPIXELTYPE 0x1128
+#define ICAP_TIMEFILL 0x112a
+#define ICAP_BITDEPTH 0x112b
+#define ICAP_BITDEPTHREDUCTION 0x112c /* Added 1.5 */
+#define ICAP_UNDEFINEDIMAGESIZE 0x112d /* Added 1.6 */
+#define ICAP_IMAGEDATASET 0x112e /* Added 1.7 */
+#define ICAP_EXTIMAGEINFO 0x112f /* Added 1.7 */
+#define ICAP_MINIMUMHEIGHT 0x1130 /* Added 1.7 */
+#define ICAP_MINIMUMWIDTH 0x1131 /* Added 1.7 */
+#define ICAP_AUTOBORDERDETECTION 0x1132 /* Added 1.8 */
+#define ICAP_AUTODESKEW 0x1133 /* Added 1.8 */
+#define ICAP_AUTODISCARDBLANKPAGES 0x1134 /* Added 1.8 */
+#define ICAP_AUTOROTATE 0x1135 /* Added 1.8 */
+#define ICAP_FLIPROTATION 0x1136 /* Added 1.8 */
+#define ICAP_BARCODEDETECTIONENABLED 0x1137 /* Added 1.8 */
+#define ICAP_SUPPORTEDBARCODETYPES 0x1138 /* Added 1.8 */
+#define ICAP_BARCODEMAXSEARCHPRIORITIES 0x1139 /* Added 1.8 */
+#define ICAP_BARCODESEARCHPRIORITIES 0x113a /* Added 1.8 */
+#define ICAP_BARCODESEARCHMODE 0x113b /* Added 1.8 */
+#define ICAP_BARCODEMAXRETRIES 0x113c /* Added 1.8 */
+#define ICAP_BARCODETIMEOUT 0x113d /* Added 1.8 */
+#define ICAP_ZOOMFACTOR 0x113e /* Added 1.8 */
+#define ICAP_PATCHCODEDETECTIONENABLED 0x113f /* Added 1.8 */
+#define ICAP_SUPPORTEDPATCHCODETYPES 0x1140 /* Added 1.8 */
+#define ICAP_PATCHCODEMAXSEARCHPRIORITIES 0x1141 /* Added 1.8 */
+#define ICAP_PATCHCODESEARCHPRIORITIES 0x1142 /* Added 1.8 */
+#define ICAP_PATCHCODESEARCHMODE 0x1143 /* Added 1.8 */
+#define ICAP_PATCHCODEMAXRETRIES 0x1144 /* Added 1.8 */
+#define ICAP_PATCHCODETIMEOUT 0x1145 /* Added 1.8 */
+#define ICAP_FLASHUSED2 0x1146 /* Added 1.8 */
+#define ICAP_IMAGEFILTER 0x1147 /* Added 1.8 */
+#define ICAP_NOISEFILTER 0x1148 /* Added 1.8 */
+#define ICAP_OVERSCAN 0x1149 /* Added 1.8 */
+#define ICAP_AUTOMATICBORDERDETECTION 0x1150 /* Added 1.8 */
+#define ICAP_AUTOMATICDESKEW 0x1151 /* Added 1.8 */
+#define ICAP_AUTOMATICROTATE 0x1152 /* Added 1.8 */
+
+/* image data sources MAY support these audio caps */
+#define ACAP_AUDIOFILEFORMAT 0x1201 /* Added 1.8 */
+#define ACAP_XFERMECH 0x1202 /* Added 1.8 */
+
+/* ----------------------------------------------------------------------- *\
+
+ Version 1.7: Following is Extended Image Info Attributes.
+ July 1997
+ KHL
+
+\* ----------------------------------------------------------------------- */
+
+#define TWEI_BARCODEX 0x1200
+#define TWEI_BARCODEY 0x1201
+#define TWEI_BARCODETEXT 0x1202
+#define TWEI_BARCODETYPE 0x1203
+#define TWEI_DESHADETOP 0x1204
+#define TWEI_DESHADELEFT 0x1205
+#define TWEI_DESHADEHEIGHT 0x1206
+#define TWEI_DESHADEWIDTH 0x1207
+#define TWEI_DESHADESIZE 0x1208
+#define TWEI_SPECKLESREMOVED 0x1209
+#define TWEI_HORZLINEXCOORD 0x120A
+#define TWEI_HORZLINEYCOORD 0x120B
+#define TWEI_HORZLINELENGTH 0x120C
+#define TWEI_HORZLINETHICKNESS 0x120D
+#define TWEI_VERTLINEXCOORD 0x120E
+#define TWEI_VERTLINEYCOORD 0x120F
+#define TWEI_VERTLINELENGTH 0x1210
+#define TWEI_VERTLINETHICKNESS 0x1211
+#define TWEI_PATCHCODE 0x1212
+#define TWEI_ENDORSEDTEXT 0x1213
+#define TWEI_FORMCONFIDENCE 0x1214
+#define TWEI_FORMTEMPLATEMATCH 0x1215
+#define TWEI_FORMTEMPLATEPAGEMATCH 0x1216
+#define TWEI_FORMHORZDOCOFFSET 0x1217
+#define TWEI_FORMVERTDOCOFFSET 0x1218
+#define TWEI_BARCODECOUNT 0x1219
+#define TWEI_BARCODECONFIDENCE 0x121A
+#define TWEI_BARCODEROTATION 0x121B
+#define TWEI_BARCODETEXTLENGTH 0x121C
+#define TWEI_DESHADECOUNT 0x121D
+#define TWEI_DESHADEBLACKCOUNTOLD 0x121E
+#define TWEI_DESHADEBLACKCOUNTNEW 0x121F
+#define TWEI_DESHADEBLACKRLMIN 0x1220
+#define TWEI_DESHADEBLACKRLMAX 0x1221
+#define TWEI_DESHADEWHITECOUNTOLD 0x1222
+#define TWEI_DESHADEWHITECOUNTNEW 0x1223
+#define TWEI_DESHADEWHITERLMIN 0x1224
+#define TWEI_DESHADEWHITERLAVE 0x1225
+#define TWEI_DESHADEWHITERLMAX 0x1226
+#define TWEI_BLACKSPECKLESREMOVED 0x1227
+#define TWEI_WHITESPECKLESREMOVED 0x1228
+#define TWEI_HORZLINECOUNT 0x1229
+#define TWEI_VERTLINECOUNT 0x122A
+#define TWEI_DESKEWSTATUS 0x122B
+#define TWEI_SKEWORIGINALANGLE 0x122C
+#define TWEI_SKEWFINALANGLE 0x122D
+#define TWEI_SKEWCONFIDENCE 0x122E
+#define TWEI_SKEWWINDOWX1 0x122F
+#define TWEI_SKEWWINDOWY1 0x1230
+#define TWEI_SKEWWINDOWX2 0x1231
+#define TWEI_SKEWWINDOWY2 0x1232
+#define TWEI_SKEWWINDOWX3 0x1233
+#define TWEI_SKEWWINDOWY3 0x1234
+#define TWEI_SKEWWINDOWX4 0x1235
+#define TWEI_SKEWWINDOWY4 0x1236
+
+#define TWEJ_NONE 0x0000
+#define TWEJ_MIDSEPARATOR 0x0001
+#define TWEJ_PATCH1 0x0002
+#define TWEJ_PATCH2 0x0003
+#define TWEJ_PATCH3 0x0004
+#define TWEJ_PATCH4 0x0005
+#define TWEJ_PATCH6 0x0006
+#define TWEJ_PATCHT 0x0007
+
+/***************************************************************************
+ * Return Codes and Condition Codes section *
+ ***************************************************************************/
+
+/* Return Codes: DSM_Entry and DS_Entry may return any one of these values. */
+#define TWRC_CUSTOMBASE 0x8000
+
+#define TWRC_SUCCESS 0
+#define TWRC_FAILURE 1 /* Application may get TW_STATUS for info on failure */
+#define TWRC_CHECKSTATUS 2 /* "tried hard"; get status */
+#define TWRC_CANCEL 3
+#define TWRC_DSEVENT 4
+#define TWRC_NOTDSEVENT 5
+#define TWRC_XFERDONE 6
+#define TWRC_ENDOFLIST 7 /* After MSG_GETNEXT if nothing left */
+#define TWRC_INFONOTSUPPORTED 8
+#define TWRC_DATANOTAVAILABLE 9
+
+/* Condition Codes: Application gets these by doing DG_CONTROL DAT_STATUS MSG_GET. */
+#define TWCC_CUSTOMBASE 0x8000
+
+#define TWCC_SUCCESS 0 /* It worked! */
+#define TWCC_BUMMER 1 /* Failure due to unknown causes */
+#define TWCC_LOWMEMORY 2 /* Not enough memory to perform operation */
+#define TWCC_NODS 3 /* No Data Source */
+#define TWCC_MAXCONNECTIONS 4 /* DS is connected to max possible applications */
+#define TWCC_OPERATIONERROR 5 /* DS or DSM reported error, application shouldn't */
+#define TWCC_BADCAP 6 /* Unknown capability */
+#define TWCC_BADPROTOCOL 9 /* Unrecognized MSG DG DAT combination */
+#define TWCC_BADVALUE 10 /* Data parameter out of range */
+#define TWCC_SEQERROR 11 /* DG DAT MSG out of expected sequence */
+#define TWCC_BADDEST 12 /* Unknown destination Application/Source in DSM_Entry */
+#define TWCC_CAPUNSUPPORTED 13 /* Capability not supported by source */
+#define TWCC_CAPBADOPERATION 14 /* Operation not supported by capability */
+#define TWCC_CAPSEQERROR 15 /* Capability has dependency on other capability */
+/* Added 1.8 */
+#define TWCC_DENIED 16 /* File System operation is denied (file is protected) */
+#define TWCC_FILEEXISTS 17 /* Operation failed because file already exists. */
+#define TWCC_FILENOTFOUND 18 /* File not found */
+#define TWCC_NOTEMPTY 19 /* Operation failed because directory is not empty */
+#define TWCC_PAPERJAM 20 /* The feeder is jammed */
+#define TWCC_PAPERDOUBLEFEED 21 /* The feeder detected multiple pages */
+#define TWCC_FILEWRITEERROR 22 /* Error writing the file (meant for things like disk full conditions) */
+#define TWCC_CHECKDEVICEONLINE 23 /* The device went offline prior to or during this operation */
+
+
+/* bit patterns: for query the operation that are supported by the data source on a capability */
+/* Application gets these through DG_CONTROL/DAT_CAPABILITY/MSG_QUERYSUPPORT */
+/* Added 1.6 */
+#define TWQC_GET 0x0001
+#define TWQC_SET 0x0002
+#define TWQC_GETDEFAULT 0x0004
+#define TWQC_GETCURRENT 0x0008
+#define TWQC_RESET 0x0010
+
+
+/****************************************************************************
+ * Entry Points *
+ ****************************************************************************/
+
+/**********************************************************************
+ * Function: DSM_Entry, the only entry point into the Data Source Manager.
+ *
+ * Parameters:
+ * pOrigin Identifies the source module of the message. This could
+ * identify an Application, a Source, or the Source Manager.
+ *
+ * pDest Identifies the destination module for the message.
+ * This could identify an application or a data source.
+ * If this is NULL, the message goes to the Source Manager.
+ *
+ * DG The Data Group.
+ * Example: DG_IMAGE.
+ *
+ * DAT The Data Attribute Type.
+ * Example: DAT_IMAGEMEMXFER.
+ *
+ * MSG The message. Messages are interpreted by the destination module
+ * with respect to the Data Group and the Data Attribute Type.
+ * Example: MSG_GET.
+ *
+ * pData A pointer to the data structure or variable identified
+ * by the Data Attribute Type.
+ * Example: (TW_MEMREF)&ImageMemXfer
+ * where ImageMemXfer is a TW_IMAGEMEMXFER structure.
+ *
+ * Returns:
+ * ReturnCode
+ * Example: TWRC_SUCCESS.
+ *
+ ********************************************************************/
+
+/* Don't mangle the name "DSM_Entry" if we're compiling in C++! */
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+#ifdef _MSWIN_
+TW_UINT16 FAR PASCAL DSM_Entry( pTW_IDENTITY pOrigin,
+ pTW_IDENTITY pDest,
+ TW_UINT32 DG,
+ TW_UINT16 DAT,
+ TW_UINT16 MSG,
+ TW_MEMREF pData);
+
+typedef TW_UINT16 (FAR PASCAL *DSMENTRYPROC)(pTW_IDENTITY, pTW_IDENTITY,
+ TW_UINT32, TW_UINT16,
+ TW_UINT16, TW_MEMREF);
+#else /* _MSWIN_ */
+
+FAR PASCAL TW_UINT16 DSM_Entry( pTW_IDENTITY pOrigin,
+ pTW_IDENTITY pDest,
+ TW_UINT32 DG,
+ TW_UINT16 DAT,
+ TW_UINT16 MSG,
+ TW_MEMREF pData);
+
+typedef TW_UINT16 (*DSMENTRYPROC)(pTW_IDENTITY, pTW_IDENTITY,
+ TW_UINT32, TW_UINT16,
+ TW_UINT16, TW_MEMREF);
+#endif /* _MSWIN_ */
+
+#ifdef __cplusplus
+}
+#endif /* cplusplus */
+
+
+/**********************************************************************
+ * Function: DS_Entry, the entry point provided by a Data Source.
+ *
+ * Parameters:
+ * pOrigin Identifies the source module of the message. This could
+ * identify an application or the Data Source Manager.
+ *
+ * DG The Data Group.
+ * Example: DG_IMAGE.
+ *
+ * DAT The Data Attribute Type.
+ * Example: DAT_IMAGEMEMXFER.
+ *
+ * MSG The message. Messages are interpreted by the data source
+ * with respect to the Data Group and the Data Attribute Type.
+ * Example: MSG_GET.
+ *
+ * pData A pointer to the data structure or variable identified
+ * by the Data Attribute Type.
+ * Example: (TW_MEMREF)&ImageMemXfer
+ * where ImageMemXfer is a TW_IMAGEMEMXFER structure.
+ *
+ * Returns:
+ * ReturnCode
+ * Example: TWRC_SUCCESS.
+ *
+ * Note:
+ * The DSPROC type is only used by an application when it calls
+ * a Data Source directly, bypassing the Data Source Manager.
+ *
+ ********************************************************************/
+/* Don't mangle the name "DS_Entry" if we're compiling in C++! */
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+#ifdef _MSWIN_
+ #ifdef _WIN32
+ __declspec(dllexport) TW_UINT16 FAR PASCAL DS_Entry (pTW_IDENTITY pOrigin,
+ TW_UINT32 DG,
+ TW_UINT16 DAT,
+ TW_UINT16 MSG,
+ TW_MEMREF pData);
+ #else /* _WIN32 */
+ TW_UINT16 FAR PASCAL DS_Entry (pTW_IDENTITY pOrigin,
+ TW_UINT32 DG,
+ TW_UINT16 DAT,
+ TW_UINT16 MSG,
+ TW_MEMREF pData);
+ #endif /* _WIN32 */
+
+ typedef TW_UINT16 (FAR PASCAL *DSENTRYPROC) (pTW_IDENTITY pOrigin,
+ TW_UINT32 DG,
+ TW_UINT16 DAT,
+ TW_UINT16 MSG,
+ TW_MEMREF pData);
+#else /* _MSWIN_ */
+FAR PASCAL TW_UINT16 DS_Entry( pTW_IDENTITY pOrigin,
+ TW_UINT32 DG,
+ TW_UINT16 DAT,
+ TW_UINT16 MSG,
+ TW_MEMREF pData);
+
+typedef TW_UINT16 (*DSENTRYPROC)(pTW_IDENTITY,
+ TW_UINT32, TW_UINT16,
+ TW_UINT16, TW_MEMREF);
+#endif /* _MSWIN_ */
+
+#ifdef __cplusplus
+}
+#endif /* cplusplus */
+
+/* SDH - 02/08/95 - TWUNK */
+/* Force 32-bit twain to use same packing of twain structures as existing */
+/* 16-bit twain. This allows 16/32-bit thunking. */
+#ifdef WIN32
+ #ifdef __BORLANDC__ /*(Mentor June 13, 1996) if we're using a Borland compiler */
+ #pragma option -a. /*(Mentor October 30, 1996) switch back to original alignment */
+ #else /*(Mentor June 13, 1996) if NOT using a Borland compiler */
+ #pragma pack (pop, before_twain)
+ #endif /*(Mentor June 13, 1996) */
+#else /* WIN32 */
+#endif /* WIN32 */
+
+#endif /* TWAIN */