summaryrefslogtreecommitdiff
path: root/src/gutenprintui2
diff options
context:
space:
mode:
authorRoger Leigh <rleigh@debian.org>2008-10-26 16:11:41 +0000
committerRoger Leigh <rleigh@debian.org>2008-10-26 16:11:41 +0000
commitdfae5860833782af557deb35e286d7e186fe3cf5 (patch)
treee3b4282ae08e120f78cd0c097f7cb3b570e94da2 /src/gutenprintui2
parent3b59bb0a607ec27ea60f07d1cd5d1bbb4483c832 (diff)
Imported Upstream version 4.3.99+cvs20050702
Diffstat (limited to 'src/gutenprintui2')
-rw-r--r--src/gutenprintui2/Makefile.am101
-rw-r--r--src/gutenprintui2/Makefile.in830
-rw-r--r--src/gutenprintui2/curve.c1055
-rw-r--r--src/gutenprintui2/gammacurve.c495
-rw-r--r--src/gutenprintui2/gutenprintui-internal.h240
-rw-r--r--src/gutenprintui2/gutenprintui2.pc.in11
-rw-r--r--src/gutenprintui2/panel.c4962
-rw-r--r--src/gutenprintui2/plist.c1751
-rw-r--r--src/gutenprintui2/print-image-thumbnail.c130
-rw-r--r--src/gutenprintui2/printrc.h44
-rw-r--r--src/gutenprintui2/printrcl.c2106
-rw-r--r--src/gutenprintui2/printrcl.l115
-rw-r--r--src/gutenprintui2/printrcy.c1694
-rw-r--r--src/gutenprintui2/printrcy.h124
-rw-r--r--src/gutenprintui2/printrcy.y398
-rw-r--r--src/gutenprintui2/typebuiltins.c58
-rw-r--r--src/gutenprintui2/ui-utils.c874
17 files changed, 14988 insertions, 0 deletions
diff --git a/src/gutenprintui2/Makefile.am b/src/gutenprintui2/Makefile.am
new file mode 100644
index 0000000..6b93566
--- /dev/null
+++ b/src/gutenprintui2/Makefile.am
@@ -0,0 +1,101 @@
+## $Id: Makefile.am,v 1.5 2005/06/26 10:56:51 rleigh Exp $
+## Copyright (C) 2000 Roger Leigh
+##
+## 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 2, 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, write to the Free Software
+## Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+## Process this file with automake to produce Makefile.in.
+
+AUTOMAKE_OPTIONS = 1.4 gnu
+
+@SET_MAKE@
+
+MAINT_CHARSET = latin1
+
+include $(top_srcdir)/scripts/global.mk
+
+
+## Variables
+
+m4datadir = $(datadir)/aclocal
+pkgconfigdatadir = $(libdir)/pkgconfig
+
+
+## Programs
+
+if BUILD_LIBGUTENPRINTUI2
+lib_LTLIBRARIES = libgutenprintui2.la
+endif
+
+libgutenprintui2_la_SOURCES = \
+ printrcy.y \
+ printrcl.l \
+ printrc.h \
+ panel.c \
+ plist.c \
+ ui-utils.c \
+ print-image-thumbnail.c \
+ curve.c \
+ gammacurve.c \
+ typebuiltins.c \
+ gutenprintui-internal.h
+
+libgutenprintui2_la_LIBADD = $(GUTENPRINTUI2_LIBDEPS)
+# Uncommment to build an unversioned library (version in soname)
+libgutenprintui2_la_CFLAGS = $(AM_CFLAGS) $(CFLAGS) $(GUTENPRINT_CFLAGS) $(GTK2_CFLAGS)
+#libgutenprintui2_la_LDFLAGS = -release $(GUTENPRINT_VERSION) \
+# -rpath $(libdir) -no-undefined
+# Uncomment to build a versioned library
+libgutenprintui2_la_LDFLAGS = \
+ -version-info $(GUTENPRINTUI2_CURRENT_INTERFACE):$(GUTENPRINTUI2_INTERFACE_AGE):$(GUTENPRINTUI2_BINARY_AGE) \
+ -rpath $(libdir) -no-undefined
+
+AM_LFLAGS = -i
+AM_YFLAGS = -d
+
+printrcl.o: printrcy.o
+plist.o: printrcy.o
+
+## Data
+
+pkgconfigdata_DATA = gutenprintui2.pc
+
+
+## Rules
+
+# Copied from include/gutenprintui2/Makefile.am
+# This duplication needs fixing somehow
+stpui_public_h_sources = \
+ ../../include/gutenprintui2/gutenprintui.h \
+ ../../include/gutenprintui2/curve.h \
+ ../../include/gutenprintui2/gammacurve.h
+
+if MAINTAINER_MODE
+typebuiltins_extra_deps = Makefile
+endif
+
+# Really need to depend upon $(stpui_public_h_sources) here...
+$(srcdir)/typebuiltins.c: $(typebuiltins_extra_deps)
+ ( cd $(srcdir) && $(GLIB_MKENUMS) \
+ --fhead "#include <gutenprintui2/gutenprintui.h>" \
+ --fprod "\n/* enumerations from \"@filename@\" */" \
+ --vhead "GType\n@enum_name@_get_type (void)\n{\n static GType etype = 0;\n if (etype == 0) {\n static const G@Type@Value values[] = {" \
+ --vprod " { @VALUENAME@, \"@VALUENAME@\", \"@valuenick@\" }," \
+ --vtail " { 0, NULL, NULL }\n };\n etype = g_@type@_register_static (\"@EnumName@\", values);\n }\n return etype;\n}\n" \
+ $(stpui_public_h_sources) ) > $@
+
+
+## Clean
+
+MAINTAINERCLEANFILES = Makefile.in typebuiltins.c printrcl.c printrcy.c printrcy.h
diff --git a/src/gutenprintui2/Makefile.in b/src/gutenprintui2/Makefile.in
new file mode 100644
index 0000000..8c3e85c
--- /dev/null
+++ b/src/gutenprintui2/Makefile.in
@@ -0,0 +1,830 @@
+# Makefile.in generated by automake 1.9.5 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004, 2005 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@
+
+# Variables
+
+
+SOURCES = $(libgutenprintui2_la_SOURCES)
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+pkgdatadir = $(datadir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+top_builddir = ../..
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+INSTALL = @INSTALL@
+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@
+DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in \
+ $(srcdir)/gutenprintui2.pc.in $(top_srcdir)/scripts/global.mk \
+ printrcl.c printrcy.c printrcy.h
+subdir = src/gutenprintui2
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/m4/gettext.m4 \
+ $(top_srcdir)/m4/gimp.m4 $(top_srcdir)/m4/iconv.m4 \
+ $(top_srcdir)/m4/lib-ld.m4 $(top_srcdir)/m4/lib-link.m4 \
+ $(top_srcdir)/m4/lib-prefix.m4 $(top_srcdir)/m4/progtest.m4 \
+ $(top_srcdir)/m4/stp.m4 $(top_srcdir)/m4/stp_cups.m4 \
+ $(top_srcdir)/m4/stp_gimp.m4 $(top_srcdir)/m4/stp_option.m4 \
+ $(top_srcdir)/m4/stp_release.m4 $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+mkinstalldirs = $(SHELL) $(top_srcdir)/scripts/mkinstalldirs
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES = gutenprintui2.pc
+am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
+am__vpath_adj = case $$p in \
+ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
+ *) f=$$p;; \
+ esac;
+am__strip_dir = `echo $$p | sed -e 's|^.*/||'`;
+am__installdirs = "$(DESTDIR)$(libdir)" \
+ "$(DESTDIR)$(pkgconfigdatadir)"
+libLTLIBRARIES_INSTALL = $(INSTALL)
+LTLIBRARIES = $(lib_LTLIBRARIES)
+am__DEPENDENCIES_1 =
+libgutenprintui2_la_DEPENDENCIES = $(am__DEPENDENCIES_1)
+am_libgutenprintui2_la_OBJECTS = libgutenprintui2_la-printrcy.lo \
+ libgutenprintui2_la-printrcl.lo libgutenprintui2_la-panel.lo \
+ libgutenprintui2_la-plist.lo libgutenprintui2_la-ui-utils.lo \
+ libgutenprintui2_la-print-image-thumbnail.lo \
+ libgutenprintui2_la-curve.lo libgutenprintui2_la-gammacurve.lo \
+ libgutenprintui2_la-typebuiltins.lo
+libgutenprintui2_la_OBJECTS = $(am_libgutenprintui2_la_OBJECTS)
+@BUILD_LIBGUTENPRINTUI2_TRUE@am_libgutenprintui2_la_rpath = -rpath \
+@BUILD_LIBGUTENPRINTUI2_TRUE@ $(libdir)
+DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir)
+depcomp = $(SHELL) $(top_srcdir)/scripts/depcomp
+am__depfiles_maybe = depfiles
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) \
+ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
+ $(AM_CFLAGS) $(CFLAGS)
+CCLD = $(CC)
+LINK = $(LIBTOOL) --tag=CC --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(AM_LDFLAGS) $(LDFLAGS) -o $@
+LEXCOMPILE = $(LEX) $(LFLAGS) $(AM_LFLAGS)
+LTLEXCOMPILE = $(LIBTOOL) --mode=compile $(LEX) $(LFLAGS) $(AM_LFLAGS)
+YACCCOMPILE = $(YACC) $(YFLAGS) $(AM_YFLAGS)
+LTYACCCOMPILE = $(LIBTOOL) --mode=compile $(YACC) $(YFLAGS) \
+ $(AM_YFLAGS)
+SOURCES = $(libgutenprintui2_la_SOURCES)
+DIST_SOURCES = $(libgutenprintui2_la_SOURCES)
+pkgconfigdataDATA_INSTALL = $(INSTALL_DATA)
+DATA = $(pkgconfigdata_DATA)
+ETAGS = etags
+CTAGS = ctags
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+ALL_LINGUAS = @ALL_LINGUAS@
+AMDEP_FALSE = @AMDEP_FALSE@
+AMDEP_TRUE = @AMDEP_TRUE@
+AMTAR = @AMTAR@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+BUILD_CUPS_FALSE = @BUILD_CUPS_FALSE@
+BUILD_CUPS_PPDS_FALSE = @BUILD_CUPS_PPDS_FALSE@
+BUILD_CUPS_PPDS_TRUE = @BUILD_CUPS_PPDS_TRUE@
+BUILD_CUPS_TRUE = @BUILD_CUPS_TRUE@
+BUILD_ESCPUTIL_FALSE = @BUILD_ESCPUTIL_FALSE@
+BUILD_ESCPUTIL_TRUE = @BUILD_ESCPUTIL_TRUE@
+BUILD_FOOMATIC_3_FALSE = @BUILD_FOOMATIC_3_FALSE@
+BUILD_FOOMATIC_3_TRUE = @BUILD_FOOMATIC_3_TRUE@
+BUILD_FOOMATIC_FALSE = @BUILD_FOOMATIC_FALSE@
+BUILD_FOOMATIC_TRUE = @BUILD_FOOMATIC_TRUE@
+BUILD_GENPPD_STATIC_FALSE = @BUILD_GENPPD_STATIC_FALSE@
+BUILD_GENPPD_STATIC_TRUE = @BUILD_GENPPD_STATIC_TRUE@
+BUILD_GHOSTSCRIPT_FALSE = @BUILD_GHOSTSCRIPT_FALSE@
+BUILD_GHOSTSCRIPT_TRUE = @BUILD_GHOSTSCRIPT_TRUE@
+BUILD_GIMP2_FALSE = @BUILD_GIMP2_FALSE@
+BUILD_GIMP2_TRUE = @BUILD_GIMP2_TRUE@
+BUILD_GIMP_FALSE = @BUILD_GIMP_FALSE@
+BUILD_GIMP_TRUE = @BUILD_GIMP_TRUE@
+BUILD_LIBGUTENPRINTUI2_FALSE = @BUILD_LIBGUTENPRINTUI2_FALSE@
+BUILD_LIBGUTENPRINTUI2_TRUE = @BUILD_LIBGUTENPRINTUI2_TRUE@
+BUILD_LIBGUTENPRINTUI_FALSE = @BUILD_LIBGUTENPRINTUI_FALSE@
+BUILD_LIBGUTENPRINTUI_TRUE = @BUILD_LIBGUTENPRINTUI_TRUE@
+BUILD_MODULES_FALSE = @BUILD_MODULES_FALSE@
+BUILD_MODULES_TRUE = @BUILD_MODULES_TRUE@
+BUILD_TESTPATTERN_FALSE = @BUILD_TESTPATTERN_FALSE@
+BUILD_TESTPATTERN_TRUE = @BUILD_TESTPATTERN_TRUE@
+BUILD_TEST_FALSE = @BUILD_TEST_FALSE@
+BUILD_TEST_TRUE = @BUILD_TEST_TRUE@
+BUILD_TRANSLATED_CUPS_PPDS_FALSE = @BUILD_TRANSLATED_CUPS_PPDS_FALSE@
+BUILD_TRANSLATED_CUPS_PPDS_TRUE = @BUILD_TRANSLATED_CUPS_PPDS_TRUE@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CONVERT = @CONVERT@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CUPS_CFLAGS = @CUPS_CFLAGS@
+CUPS_CONFIG = @CUPS_CONFIG@
+CUPS_LIBS = @CUPS_LIBS@
+CUPS_PPDS_AT_TOP_LEVEL_FALSE = @CUPS_PPDS_AT_TOP_LEVEL_FALSE@
+CUPS_PPDS_AT_TOP_LEVEL_TRUE = @CUPS_PPDS_AT_TOP_LEVEL_TRUE@
+CUPS_PPD_PS_LEVEL = @CUPS_PPD_PS_LEVEL@
+CXX = @CXX@
+CXXCPP = @CXXCPP@
+CXXDEPMODE = @CXXDEPMODE@
+CXXFLAGS = @CXXFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DB2HTML = @DB2HTML@
+DB2PDF = @DB2PDF@
+DB2PS = @DB2PS@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DIALOG = @DIALOG@
+DOXYGEN = @DOXYGEN@
+DVIPDF = @DVIPDF@
+DVIPS = @DVIPS@
+ECHO = @ECHO@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+F77 = @F77@
+FFLAGS = @FFLAGS@
+FIND = @FIND@
+FOOMATIC_CONFIGURE = @FOOMATIC_CONFIGURE@
+FOOMATIC_KITLOAD = @FOOMATIC_KITLOAD@
+FOOMATIC_PPDFILE = @FOOMATIC_PPDFILE@
+GENPPD_LIBS = @GENPPD_LIBS@
+GIMP2_CFLAGS = @GIMP2_CFLAGS@
+GIMP2_LIBS = @GIMP2_LIBS@
+GIMPTOOL = @GIMPTOOL@
+GIMPTOOL2_CHECK = @GIMPTOOL2_CHECK@
+GIMPTOOL_CHECK = @GIMPTOOL_CHECK@
+GIMP_CFLAGS = @GIMP_CFLAGS@
+GIMP_CFLAGS_NOUI = @GIMP_CFLAGS_NOUI@
+GIMP_DATA_DIR = @GIMP_DATA_DIR@
+GIMP_LIBS = @GIMP_LIBS@
+GIMP_LIBS_NOUI = @GIMP_LIBS_NOUI@
+GIMP_PLUGIN_DIR = @GIMP_PLUGIN_DIR@
+GLIB_CFLAGS = @GLIB_CFLAGS@
+GLIB_CONFIG = @GLIB_CONFIG@
+GLIB_LIBS = @GLIB_LIBS@
+GLIB_MKENUMS = @GLIB_MKENUMS@
+GMSGFMT = @GMSGFMT@
+GNUCFLAGS = @GNUCFLAGS@
+GTK2_CFLAGS = @GTK2_CFLAGS@
+GTK2_LIBS = @GTK2_LIBS@
+GTK_CFLAGS = @GTK_CFLAGS@
+GTK_CONFIG = @GTK_CONFIG@
+GTK_LIBS = @GTK_LIBS@
+GUTENPRINTUI2_BINARY_AGE = @GUTENPRINTUI2_BINARY_AGE@
+GUTENPRINTUI2_CFLAGS = @GUTENPRINTUI2_CFLAGS@
+GUTENPRINTUI2_CURRENT_INTERFACE = @GUTENPRINTUI2_CURRENT_INTERFACE@
+GUTENPRINTUI2_INTERFACE_AGE = @GUTENPRINTUI2_INTERFACE_AGE@
+GUTENPRINTUI2_LIBDEPS = @GUTENPRINTUI2_LIBDEPS@
+GUTENPRINTUI2_LIBS = $(top_builddir)/src/gutenprintui2/libgutenprintui2.la
+GUTENPRINTUI2_VERSION = @GUTENPRINTUI2_VERSION@
+GUTENPRINTUI_BINARY_AGE = @GUTENPRINTUI_BINARY_AGE@
+GUTENPRINTUI_CFLAGS = @GUTENPRINTUI_CFLAGS@
+GUTENPRINTUI_CURRENT_INTERFACE = @GUTENPRINTUI_CURRENT_INTERFACE@
+GUTENPRINTUI_INTERFACE_AGE = @GUTENPRINTUI_INTERFACE_AGE@
+GUTENPRINTUI_LIBDEPS = @GUTENPRINTUI_LIBDEPS@
+GUTENPRINTUI_LIBS = $(top_builddir)/src/gutenprintui/libgutenprintui.la
+GUTENPRINTUI_VERSION = @GUTENPRINTUI_VERSION@
+GUTENPRINT_BINARY_AGE = @GUTENPRINT_BINARY_AGE@
+GUTENPRINT_CFLAGS = @GUTENPRINT_CFLAGS@
+GUTENPRINT_CURRENT_INTERFACE = @GUTENPRINT_CURRENT_INTERFACE@
+GUTENPRINT_INTERFACE_AGE = @GUTENPRINT_INTERFACE_AGE@
+GUTENPRINT_LIBDEPS = @GUTENPRINT_LIBDEPS@
+
+# Libraries
+GUTENPRINT_LIBS = $(top_builddir)/src/main/libgutenprint.la
+GUTENPRINT_MAJOR_VERSION = @GUTENPRINT_MAJOR_VERSION@
+GUTENPRINT_MICRO_VERSION = @GUTENPRINT_MICRO_VERSION@
+GUTENPRINT_MINOR_VERSION = @GUTENPRINT_MINOR_VERSION@
+GUTENPRINT_VERSION = @GUTENPRINT_VERSION@
+IJS_CFLAGS = @IJS_CFLAGS@
+IJS_CONFIG = @IJS_CONFIG@
+IJS_LIBS = @IJS_LIBS@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SAMPLES_FALSE = @INSTALL_SAMPLES_FALSE@
+INSTALL_SAMPLES_TRUE = @INSTALL_SAMPLES_TRUE@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+INSTALL_USER_GUIDE_FALSE = @INSTALL_USER_GUIDE_FALSE@
+INSTALL_USER_GUIDE_TRUE = @INSTALL_USER_GUIDE_TRUE@
+INTLLIBS = @INTLLIBS@
+LDFLAGS = @LDFLAGS@
+LEX = @LEX@
+LEXLIB = @LEXLIB@
+LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@
+LIBICONV = @LIBICONV@
+LIBINTL = @LIBINTL@
+LIBOBJS = @LIBOBJS@
+LIBREADLINE_DEPS = @LIBREADLINE_DEPS@
+LIBS = $(INTLLIBS) @LIBS@
+LIBTOOL = @LIBTOOL@
+LIBTOOL_DEPS = @LIBTOOL_DEPS@
+LN_S = @LN_S@
+LTALLOCA = @LTALLOCA@
+LTLIBICONV = @LTLIBICONV@
+LTLIBINTL = @LTLIBINTL@
+LTLIBOBJS = @LTLIBOBJS@
+MAINT = @MAINT@
+MAINTAINER_CFLAGS = @MAINTAINER_CFLAGS@
+MAINTAINER_MODE_FALSE = @MAINTAINER_MODE_FALSE@
+MAINTAINER_MODE_TRUE = @MAINTAINER_MODE_TRUE@
+MAKEINFO = @MAKEINFO@
+MKINSTALLDIRS = @MKINSTALLDIRS@
+MSGFMT = @MSGFMT@
+MSGMERGE = @MSGMERGE@
+OBJEXT = @OBJEXT@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PERL = @PERL@
+PKG_CONFIG = @PKG_CONFIG@
+PLUG_IN_PATH = @PLUG_IN_PATH@
+POSUB = @POSUB@
+RANLIB = @RANLIB@
+RELEASE_DATE = @RELEASE_DATE@
+RM = @RM@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRIP = @STRIP@
+TEXI2HTML = @TEXI2HTML@
+USE_LEVEL3_PS_FALSE = @USE_LEVEL3_PS_FALSE@
+USE_LEVEL3_PS_TRUE = @USE_LEVEL3_PS_TRUE@
+USE_NLS = @USE_NLS@
+USE_NLS_FALSE = @USE_NLS_FALSE@
+USE_NLS_TRUE = @USE_NLS_TRUE@
+VERSION = @VERSION@
+XGETTEXT = @XGETTEXT@
+YACC = @YACC@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_CXX = @ac_ct_CXX@
+ac_ct_F77 = @ac_ct_F77@
+ac_ct_RANLIB = @ac_ct_RANLIB@
+ac_ct_STRIP = @ac_ct_STRIP@
+ac_pt_PKG_CONFIG = @ac_pt_PKG_CONFIG@
+am__fastdepCC_FALSE = @am__fastdepCC_FALSE@
+am__fastdepCC_TRUE = @am__fastdepCC_TRUE@
+am__fastdepCXX_FALSE = @am__fastdepCXX_FALSE@
+am__fastdepCXX_TRUE = @am__fastdepCXX_TRUE@
+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@
+cups_bindir = @cups_bindir@
+cups_conf_datadir = @cups_conf_datadir@
+cups_conf_serverbin = @cups_conf_serverbin@
+cups_conf_serverroot = @cups_conf_serverroot@
+cups_exec_prefix = @cups_exec_prefix@
+cups_prefix = @cups_prefix@
+cups_sbindir = @cups_sbindir@
+datadir = @datadir@
+exec_prefix = @exec_prefix@
+gimp2_plug_indir = @gimp2_plug_indir@
+gimp_plug_indir = @gimp_plug_indir@
+gutenprint_cflags = @gutenprint_cflags@
+gutenprint_libs = @gutenprint_libs@
+gutenprintui2_cflags = @gutenprintui2_cflags@
+gutenprintui2_libs = @gutenprintui2_libs@
+gutenprintui_cflags = @gutenprintui_cflags@
+gutenprintui_libs = @gutenprintui_libs@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+AUTOMAKE_OPTIONS = 1.4 gnu
+MAINT_CHARSET = latin1
+AM_CPPFLAGS = -I$(top_srcdir)/include -I$(top_builddir)/include $(LOCAL_CPPFLAGS) $(GNUCFLAGS)
+m4datadir = $(datadir)/aclocal
+pkgconfigdatadir = $(libdir)/pkgconfig
+@BUILD_LIBGUTENPRINTUI2_TRUE@lib_LTLIBRARIES = libgutenprintui2.la
+libgutenprintui2_la_SOURCES = \
+ printrcy.y \
+ printrcl.l \
+ printrc.h \
+ panel.c \
+ plist.c \
+ ui-utils.c \
+ print-image-thumbnail.c \
+ curve.c \
+ gammacurve.c \
+ typebuiltins.c \
+ gutenprintui-internal.h
+
+libgutenprintui2_la_LIBADD = $(GUTENPRINTUI2_LIBDEPS)
+# Uncommment to build an unversioned library (version in soname)
+libgutenprintui2_la_CFLAGS = $(AM_CFLAGS) $(CFLAGS) $(GUTENPRINT_CFLAGS) $(GTK2_CFLAGS)
+#libgutenprintui2_la_LDFLAGS = -release $(GUTENPRINT_VERSION) \
+# -rpath $(libdir) -no-undefined
+# Uncomment to build a versioned library
+libgutenprintui2_la_LDFLAGS = \
+ -version-info $(GUTENPRINTUI2_CURRENT_INTERFACE):$(GUTENPRINTUI2_INTERFACE_AGE):$(GUTENPRINTUI2_BINARY_AGE) \
+ -rpath $(libdir) -no-undefined
+
+AM_LFLAGS = -i
+AM_YFLAGS = -d
+pkgconfigdata_DATA = gutenprintui2.pc
+
+# Copied from include/gutenprintui2/Makefile.am
+# This duplication needs fixing somehow
+stpui_public_h_sources = \
+ ../../include/gutenprintui2/gutenprintui.h \
+ ../../include/gutenprintui2/curve.h \
+ ../../include/gutenprintui2/gammacurve.h
+
+@MAINTAINER_MODE_TRUE@typebuiltins_extra_deps = Makefile
+MAINTAINERCLEANFILES = Makefile.in typebuiltins.c printrcl.c printrcy.c printrcy.h
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .l .lo .o .obj .y
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(top_srcdir)/scripts/global.mk $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
+ && exit 0; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/gutenprintui2/Makefile'; \
+ cd $(top_srcdir) && \
+ $(AUTOMAKE) --gnu src/gutenprintui2/Makefile
+.PRECIOUS: 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__depfiles_maybe)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+gutenprintui2.pc: $(top_builddir)/config.status $(srcdir)/gutenprintui2.pc.in
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@
+install-libLTLIBRARIES: $(lib_LTLIBRARIES)
+ @$(NORMAL_INSTALL)
+ test -z "$(libdir)" || $(mkdir_p) "$(DESTDIR)$(libdir)"
+ @list='$(lib_LTLIBRARIES)'; for p in $$list; do \
+ if test -f $$p; then \
+ f=$(am__strip_dir) \
+ echo " $(LIBTOOL) --mode=install $(libLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) '$$p' '$(DESTDIR)$(libdir)/$$f'"; \
+ $(LIBTOOL) --mode=install $(libLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) "$$p" "$(DESTDIR)$(libdir)/$$f"; \
+ else :; fi; \
+ done
+
+uninstall-libLTLIBRARIES:
+ @$(NORMAL_UNINSTALL)
+ @set -x; list='$(lib_LTLIBRARIES)'; for p in $$list; do \
+ p=$(am__strip_dir) \
+ echo " $(LIBTOOL) --mode=uninstall rm -f '$(DESTDIR)$(libdir)/$$p'"; \
+ $(LIBTOOL) --mode=uninstall rm -f "$(DESTDIR)$(libdir)/$$p"; \
+ done
+
+clean-libLTLIBRARIES:
+ -test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES)
+ @list='$(lib_LTLIBRARIES)'; for p in $$list; do \
+ dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \
+ test "$$dir" != "$$p" || dir=.; \
+ echo "rm -f \"$${dir}/so_locations\""; \
+ rm -f "$${dir}/so_locations"; \
+ done
+printrcy.h: printrcy.c
+ @if test ! -f $@; then \
+ rm -f printrcy.c; \
+ $(MAKE) printrcy.c; \
+ else :; fi
+libgutenprintui2.la: $(libgutenprintui2_la_OBJECTS) $(libgutenprintui2_la_DEPENDENCIES)
+ $(LINK) $(am_libgutenprintui2_la_rpath) $(libgutenprintui2_la_LDFLAGS) $(libgutenprintui2_la_OBJECTS) $(libgutenprintui2_la_LIBADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgutenprintui2_la-curve.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgutenprintui2_la-gammacurve.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgutenprintui2_la-panel.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgutenprintui2_la-plist.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgutenprintui2_la-print-image-thumbnail.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgutenprintui2_la-printrcl.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgutenprintui2_la-printrcy.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgutenprintui2_la-typebuiltins.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgutenprintui2_la-ui-utils.Plo@am__quote@
+
+.c.o:
+@am__fastdepCC_TRUE@ if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(COMPILE) -c $<
+
+.c.obj:
+@am__fastdepCC_TRUE@ if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ `$(CYGPATH_W) '$<'`; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'`
+
+.c.lo:
+@am__fastdepCC_TRUE@ if $(LTCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Plo"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $<
+
+libgutenprintui2_la-printrcy.lo: printrcy.c
+@am__fastdepCC_TRUE@ if $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgutenprintui2_la_CFLAGS) $(CFLAGS) -MT libgutenprintui2_la-printrcy.lo -MD -MP -MF "$(DEPDIR)/libgutenprintui2_la-printrcy.Tpo" -c -o libgutenprintui2_la-printrcy.lo `test -f 'printrcy.c' || echo '$(srcdir)/'`printrcy.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/libgutenprintui2_la-printrcy.Tpo" "$(DEPDIR)/libgutenprintui2_la-printrcy.Plo"; else rm -f "$(DEPDIR)/libgutenprintui2_la-printrcy.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='printrcy.c' object='libgutenprintui2_la-printrcy.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgutenprintui2_la_CFLAGS) $(CFLAGS) -c -o libgutenprintui2_la-printrcy.lo `test -f 'printrcy.c' || echo '$(srcdir)/'`printrcy.c
+
+libgutenprintui2_la-printrcl.lo: printrcl.c
+@am__fastdepCC_TRUE@ if $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgutenprintui2_la_CFLAGS) $(CFLAGS) -MT libgutenprintui2_la-printrcl.lo -MD -MP -MF "$(DEPDIR)/libgutenprintui2_la-printrcl.Tpo" -c -o libgutenprintui2_la-printrcl.lo `test -f 'printrcl.c' || echo '$(srcdir)/'`printrcl.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/libgutenprintui2_la-printrcl.Tpo" "$(DEPDIR)/libgutenprintui2_la-printrcl.Plo"; else rm -f "$(DEPDIR)/libgutenprintui2_la-printrcl.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='printrcl.c' object='libgutenprintui2_la-printrcl.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgutenprintui2_la_CFLAGS) $(CFLAGS) -c -o libgutenprintui2_la-printrcl.lo `test -f 'printrcl.c' || echo '$(srcdir)/'`printrcl.c
+
+libgutenprintui2_la-panel.lo: panel.c
+@am__fastdepCC_TRUE@ if $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgutenprintui2_la_CFLAGS) $(CFLAGS) -MT libgutenprintui2_la-panel.lo -MD -MP -MF "$(DEPDIR)/libgutenprintui2_la-panel.Tpo" -c -o libgutenprintui2_la-panel.lo `test -f 'panel.c' || echo '$(srcdir)/'`panel.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/libgutenprintui2_la-panel.Tpo" "$(DEPDIR)/libgutenprintui2_la-panel.Plo"; else rm -f "$(DEPDIR)/libgutenprintui2_la-panel.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='panel.c' object='libgutenprintui2_la-panel.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgutenprintui2_la_CFLAGS) $(CFLAGS) -c -o libgutenprintui2_la-panel.lo `test -f 'panel.c' || echo '$(srcdir)/'`panel.c
+
+libgutenprintui2_la-plist.lo: plist.c
+@am__fastdepCC_TRUE@ if $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgutenprintui2_la_CFLAGS) $(CFLAGS) -MT libgutenprintui2_la-plist.lo -MD -MP -MF "$(DEPDIR)/libgutenprintui2_la-plist.Tpo" -c -o libgutenprintui2_la-plist.lo `test -f 'plist.c' || echo '$(srcdir)/'`plist.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/libgutenprintui2_la-plist.Tpo" "$(DEPDIR)/libgutenprintui2_la-plist.Plo"; else rm -f "$(DEPDIR)/libgutenprintui2_la-plist.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='plist.c' object='libgutenprintui2_la-plist.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgutenprintui2_la_CFLAGS) $(CFLAGS) -c -o libgutenprintui2_la-plist.lo `test -f 'plist.c' || echo '$(srcdir)/'`plist.c
+
+libgutenprintui2_la-ui-utils.lo: ui-utils.c
+@am__fastdepCC_TRUE@ if $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgutenprintui2_la_CFLAGS) $(CFLAGS) -MT libgutenprintui2_la-ui-utils.lo -MD -MP -MF "$(DEPDIR)/libgutenprintui2_la-ui-utils.Tpo" -c -o libgutenprintui2_la-ui-utils.lo `test -f 'ui-utils.c' || echo '$(srcdir)/'`ui-utils.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/libgutenprintui2_la-ui-utils.Tpo" "$(DEPDIR)/libgutenprintui2_la-ui-utils.Plo"; else rm -f "$(DEPDIR)/libgutenprintui2_la-ui-utils.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='ui-utils.c' object='libgutenprintui2_la-ui-utils.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgutenprintui2_la_CFLAGS) $(CFLAGS) -c -o libgutenprintui2_la-ui-utils.lo `test -f 'ui-utils.c' || echo '$(srcdir)/'`ui-utils.c
+
+libgutenprintui2_la-print-image-thumbnail.lo: print-image-thumbnail.c
+@am__fastdepCC_TRUE@ if $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgutenprintui2_la_CFLAGS) $(CFLAGS) -MT libgutenprintui2_la-print-image-thumbnail.lo -MD -MP -MF "$(DEPDIR)/libgutenprintui2_la-print-image-thumbnail.Tpo" -c -o libgutenprintui2_la-print-image-thumbnail.lo `test -f 'print-image-thumbnail.c' || echo '$(srcdir)/'`print-image-thumbnail.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/libgutenprintui2_la-print-image-thumbnail.Tpo" "$(DEPDIR)/libgutenprintui2_la-print-image-thumbnail.Plo"; else rm -f "$(DEPDIR)/libgutenprintui2_la-print-image-thumbnail.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='print-image-thumbnail.c' object='libgutenprintui2_la-print-image-thumbnail.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgutenprintui2_la_CFLAGS) $(CFLAGS) -c -o libgutenprintui2_la-print-image-thumbnail.lo `test -f 'print-image-thumbnail.c' || echo '$(srcdir)/'`print-image-thumbnail.c
+
+libgutenprintui2_la-curve.lo: curve.c
+@am__fastdepCC_TRUE@ if $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgutenprintui2_la_CFLAGS) $(CFLAGS) -MT libgutenprintui2_la-curve.lo -MD -MP -MF "$(DEPDIR)/libgutenprintui2_la-curve.Tpo" -c -o libgutenprintui2_la-curve.lo `test -f 'curve.c' || echo '$(srcdir)/'`curve.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/libgutenprintui2_la-curve.Tpo" "$(DEPDIR)/libgutenprintui2_la-curve.Plo"; else rm -f "$(DEPDIR)/libgutenprintui2_la-curve.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='curve.c' object='libgutenprintui2_la-curve.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgutenprintui2_la_CFLAGS) $(CFLAGS) -c -o libgutenprintui2_la-curve.lo `test -f 'curve.c' || echo '$(srcdir)/'`curve.c
+
+libgutenprintui2_la-gammacurve.lo: gammacurve.c
+@am__fastdepCC_TRUE@ if $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgutenprintui2_la_CFLAGS) $(CFLAGS) -MT libgutenprintui2_la-gammacurve.lo -MD -MP -MF "$(DEPDIR)/libgutenprintui2_la-gammacurve.Tpo" -c -o libgutenprintui2_la-gammacurve.lo `test -f 'gammacurve.c' || echo '$(srcdir)/'`gammacurve.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/libgutenprintui2_la-gammacurve.Tpo" "$(DEPDIR)/libgutenprintui2_la-gammacurve.Plo"; else rm -f "$(DEPDIR)/libgutenprintui2_la-gammacurve.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='gammacurve.c' object='libgutenprintui2_la-gammacurve.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgutenprintui2_la_CFLAGS) $(CFLAGS) -c -o libgutenprintui2_la-gammacurve.lo `test -f 'gammacurve.c' || echo '$(srcdir)/'`gammacurve.c
+
+libgutenprintui2_la-typebuiltins.lo: typebuiltins.c
+@am__fastdepCC_TRUE@ if $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgutenprintui2_la_CFLAGS) $(CFLAGS) -MT libgutenprintui2_la-typebuiltins.lo -MD -MP -MF "$(DEPDIR)/libgutenprintui2_la-typebuiltins.Tpo" -c -o libgutenprintui2_la-typebuiltins.lo `test -f 'typebuiltins.c' || echo '$(srcdir)/'`typebuiltins.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/libgutenprintui2_la-typebuiltins.Tpo" "$(DEPDIR)/libgutenprintui2_la-typebuiltins.Plo"; else rm -f "$(DEPDIR)/libgutenprintui2_la-typebuiltins.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='typebuiltins.c' object='libgutenprintui2_la-typebuiltins.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgutenprintui2_la_CFLAGS) $(CFLAGS) -c -o libgutenprintui2_la-typebuiltins.lo `test -f 'typebuiltins.c' || echo '$(srcdir)/'`typebuiltins.c
+
+.l.c:
+ $(LEXCOMPILE) $<
+ sed '/^#/ s|$(LEX_OUTPUT_ROOT)\.c|$@|' $(LEX_OUTPUT_ROOT).c >$@
+ rm -f $(LEX_OUTPUT_ROOT).c
+
+.y.c:
+ $(YACCCOMPILE) $<
+ if test -f y.tab.h; then \
+ to=`echo "$*_H" | sed \
+ -e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/' \
+ -e 's/[^ABCDEFGHIJKLMNOPQRSTUVWXYZ]/_/g'`; \
+ sed -e "/^#/!b" -e "s/Y_TAB_H/$$to/g" -e "s|y\.tab\.h|$*.h|" \
+ y.tab.h >$*.ht; \
+ rm -f y.tab.h; \
+ if cmp -s $*.ht $*.h; then \
+ rm -f $*.ht ;\
+ else \
+ mv $*.ht $*.h; \
+ fi; \
+ fi
+ if test -f y.output; then \
+ mv y.output $*.output; \
+ fi
+ sed '/^#/ s|y\.tab\.c|$@|' y.tab.c >$@t && mv $@t $@
+ rm -f y.tab.c
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+
+distclean-libtool:
+ -rm -f libtool
+uninstall-info-am:
+install-pkgconfigdataDATA: $(pkgconfigdata_DATA)
+ @$(NORMAL_INSTALL)
+ test -z "$(pkgconfigdatadir)" || $(mkdir_p) "$(DESTDIR)$(pkgconfigdatadir)"
+ @list='$(pkgconfigdata_DATA)'; for p in $$list; do \
+ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+ f=$(am__strip_dir) \
+ echo " $(pkgconfigdataDATA_INSTALL) '$$d$$p' '$(DESTDIR)$(pkgconfigdatadir)/$$f'"; \
+ $(pkgconfigdataDATA_INSTALL) "$$d$$p" "$(DESTDIR)$(pkgconfigdatadir)/$$f"; \
+ done
+
+uninstall-pkgconfigdataDATA:
+ @$(NORMAL_UNINSTALL)
+ @list='$(pkgconfigdata_DATA)'; for p in $$list; do \
+ f=$(am__strip_dir) \
+ echo " rm -f '$(DESTDIR)$(pkgconfigdatadir)/$$f'"; \
+ rm -f "$(DESTDIR)$(pkgconfigdatadir)/$$f"; \
+ done
+
+ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ mkid -fID $$unique
+tags: TAGS
+
+TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ tags=; \
+ here=`pwd`; \
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \
+ test -n "$$unique" || unique=$$empty_fix; \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$tags $$unique; \
+ fi
+ctags: CTAGS
+CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ tags=; \
+ here=`pwd`; \
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ test -z "$(CTAGS_ARGS)$$tags$$unique" \
+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+ $$tags $$unique
+
+GTAGS:
+ here=`$(am__cd) $(top_builddir) && pwd` \
+ && cd $(top_srcdir) \
+ && gtags -i $(GTAGS_ARGS) $$here
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+distdir: $(DISTFILES)
+ $(mkdir_p) $(distdir)/../../scripts
+ @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \
+ list='$(DISTFILES)'; for file in $$list; do \
+ case $$file in \
+ $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \
+ $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \
+ esac; \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test "$$dir" != "$$file" && test "$$dir" != "."; then \
+ dir="/$$dir"; \
+ $(mkdir_p) "$(distdir)$$dir"; \
+ else \
+ dir=''; \
+ fi; \
+ if test -d $$d/$$file; then \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
+ fi; \
+ cp -pR $$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 $(LTLIBRARIES) $(DATA)
+installdirs:
+ for dir in "$(DESTDIR)$(libdir)" "$(DESTDIR)$(pkgconfigdatadir)"; 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:
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ `test -z '$(STRIP)' || \
+ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+ -rm -f printrcl.c
+ -rm -f printrcy.c
+ -rm -f printrcy.h
+ -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES)
+clean: clean-am
+
+clean-am: clean-generic clean-libLTLIBRARIES clean-libtool \
+ mostlyclean-am
+
+distclean: distclean-am
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+ distclean-libtool distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+info: info-am
+
+info-am:
+
+install-data-am: install-pkgconfigdataDATA
+
+install-exec-am: install-libLTLIBRARIES
+
+install-info: install-info-am
+
+install-man:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+ -rm -rf ./$(DEPDIR)
+ -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-info-am uninstall-libLTLIBRARIES \
+ uninstall-pkgconfigdataDATA
+
+.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
+ clean-libLTLIBRARIES clean-libtool ctags 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-exec \
+ install-exec-am install-info install-info-am \
+ install-libLTLIBRARIES install-man install-pkgconfigdataDATA \
+ 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 uninstall uninstall-am \
+ uninstall-info-am uninstall-libLTLIBRARIES \
+ uninstall-pkgconfigdataDATA
+
+
+@SET_MAKE@
+
+export STP_MODULE_PATH = $(top_builddir)/src/main/.libs:$(top_builddir)/src/main
+export STP_DATA_PATH = $(top_srcdir)/src/main
+
+# Rules
+
+$(top_builddir)/src/main/libgutenprint.la:
+ cd $(top_builddir)/src/main; \
+ $(MAKE)
+
+$(top_builddir)/src/gutenprintui/libgutenprintui.la:
+ cd $(top_builddir)/src/gutenprintui; \
+ $(MAKE)
+
+$(top_builddir)/src/gutenprintui2/libgutenprintui2.la:
+ cd $(top_builddir)/src/gutenprintui2; \
+ $(MAKE)
+
+printrcl.o: printrcy.o
+plist.o: printrcy.o
+
+# Really need to depend upon $(stpui_public_h_sources) here...
+$(srcdir)/typebuiltins.c: $(typebuiltins_extra_deps)
+ ( cd $(srcdir) && $(GLIB_MKENUMS) \
+ --fhead "#include <gutenprintui2/gutenprintui.h>" \
+ --fprod "\n/* enumerations from \"@filename@\" */" \
+ --vhead "GType\n@enum_name@_get_type (void)\n{\n static GType etype = 0;\n if (etype == 0) {\n static const G@Type@Value values[] = {" \
+ --vprod " { @VALUENAME@, \"@VALUENAME@\", \"@valuenick@\" }," \
+ --vtail " { 0, NULL, NULL }\n };\n etype = g_@type@_register_static (\"@EnumName@\", values);\n }\n return etype;\n}\n" \
+ $(stpui_public_h_sources) ) > $@
+# 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/src/gutenprintui2/curve.c b/src/gutenprintui2/curve.c
new file mode 100644
index 0000000..6f89a53
--- /dev/null
+++ b/src/gutenprintui2/curve.c
@@ -0,0 +1,1055 @@
+/* GTK - The GIMP Toolkit
+ * Copyright (C) 1997 David Mosberger
+ * 2004 Roger Leigh
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+/*
+ * Modified by the GTK+ Team and others 1997-2000. See the AUTHORS
+ * file for a list of people on the GTK+ Team. See the ChangeLog
+ * files for a list of changes. These files are distributed with
+ * GTK+ at ftp://ftp.gtk.org/pub/gtk/.
+ */
+
+/*
+ * Incorporated into Gutenprint by Roger Leigh in 2004. Subsequent
+ * changes are by the Gutenprint team.
+ */
+
+#include <config.h>
+#include <stdlib.h>
+#include <string.h>
+#include <math.h>
+
+#include <gtk/gtkmain.h>
+#include <gtk/gtkradiobutton.h>
+#include <gtk/gtktable.h>
+
+#include <gutenprint/gutenprint-intl-internal.h>
+
+#include <gutenprintui2/curve.h>
+#include <gutenprintui2/typebuiltins.h>
+
+#define RADIUS 3 /* radius of the control points */
+#define MIN_DISTANCE 8 /* min distance between control points */
+
+#define GRAPH_MASK (GDK_EXPOSURE_MASK | \
+ GDK_POINTER_MOTION_MASK | \
+ GDK_POINTER_MOTION_HINT_MASK | \
+ GDK_ENTER_NOTIFY_MASK | \
+ GDK_BUTTON_PRESS_MASK | \
+ GDK_BUTTON_RELEASE_MASK | \
+ GDK_BUTTON1_MOTION_MASK)
+
+enum {
+ PROP_0,
+ PROP_CURVE_TYPE,
+ PROP_MIN_X,
+ PROP_MAX_X,
+ PROP_MIN_Y,
+ PROP_MAX_Y
+};
+
+static GtkDrawingAreaClass *parent_class = NULL;
+static guint curve_type_changed_signal = 0;
+
+
+/* forward declarations: */
+static void stpui_curve_class_init (StpuiCurveClass *class);
+static void stpui_curve_init (StpuiCurve *curve);
+static void stpui_curve_get_property (GObject *object,
+ guint param_id,
+ GValue *value,
+ GParamSpec *pspec);
+static void stpui_curve_set_property (GObject *object,
+ guint param_id,
+ const GValue *value,
+ GParamSpec *pspec);
+static void stpui_curve_finalize (GObject *object);
+static gint stpui_curve_graph_events (GtkWidget *widget,
+ GdkEvent *event,
+ StpuiCurve *c);
+static void stpui_curve_size_graph (StpuiCurve *curve);
+
+GType
+stpui_curve_get_type (void)
+{
+ static GType curve_type = 0;
+
+ if (!curve_type)
+ {
+ static const GTypeInfo curve_info =
+ {
+ sizeof (StpuiCurveClass),
+ NULL, /* base_init */
+ NULL, /* base_finalize */
+ (GClassInitFunc) stpui_curve_class_init,
+ NULL, /* class_finalize */
+ NULL, /* class_data */
+ sizeof (StpuiCurve),
+ 0, /* n_preallocs */
+ (GInstanceInitFunc) stpui_curve_init,
+ };
+
+ curve_type = g_type_register_static (GTK_TYPE_DRAWING_AREA,
+ "StpuiCurve",
+ &curve_info, 0);
+ }
+ return curve_type;
+}
+
+static void
+stpui_curve_class_init (StpuiCurveClass *class)
+{
+ GObjectClass *gobject_class = G_OBJECT_CLASS (class);
+
+ parent_class = g_type_class_peek_parent (class);
+
+ gobject_class->finalize = stpui_curve_finalize;
+
+ gobject_class->set_property = stpui_curve_set_property;
+ gobject_class->get_property = stpui_curve_get_property;
+
+ g_object_class_install_property (gobject_class,
+ PROP_CURVE_TYPE,
+ g_param_spec_enum ("curve_type",
+ _("Curve type"),
+ _("Is this curve linear, spline interpolated, or free-form"),
+ STPUI_TYPE_CURVE_TYPE,
+ STPUI_CURVE_TYPE_LINEAR,
+ G_PARAM_READABLE |
+ G_PARAM_WRITABLE));
+ g_object_class_install_property (gobject_class,
+ PROP_MIN_X,
+ g_param_spec_float ("min_x",
+ _("Minimum X"),
+ _("Minimum possible value for X"),
+ -G_MAXFLOAT,
+ G_MAXFLOAT,
+ 0.0,
+ G_PARAM_READABLE |
+ G_PARAM_WRITABLE));
+ g_object_class_install_property (gobject_class,
+ PROP_MAX_X,
+ g_param_spec_float ("max_x",
+ _("Maximum X"),
+ _("Maximum possible X value"),
+ -G_MAXFLOAT,
+ G_MAXFLOAT,
+ 1.0,
+ G_PARAM_READABLE |
+ G_PARAM_WRITABLE));
+ g_object_class_install_property (gobject_class,
+ PROP_MIN_Y,
+ g_param_spec_float ("min_y",
+ _("Minimum Y"),
+ _("Minimum possible value for Y"),
+ -G_MAXFLOAT,
+ G_MAXFLOAT,
+ 0.0,
+ G_PARAM_READABLE |
+ G_PARAM_WRITABLE));
+ g_object_class_install_property (gobject_class,
+ PROP_MAX_Y,
+ g_param_spec_float ("max_y",
+ _("Maximum Y"),
+ _("Maximum possible value for Y"),
+ -G_MAXFLOAT,
+ G_MAXFLOAT,
+ 1.0,
+ G_PARAM_READABLE |
+ G_PARAM_WRITABLE));
+
+ curve_type_changed_signal =
+ g_signal_new ("curve_type_changed",
+ G_OBJECT_CLASS_TYPE (gobject_class),
+ G_SIGNAL_RUN_FIRST,
+ G_STRUCT_OFFSET (StpuiCurveClass, curve_type_changed),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+}
+
+static void
+stpui_curve_init (StpuiCurve *curve)
+{
+ gint old_mask;
+
+ curve->cursor_type = GDK_TOP_LEFT_ARROW;
+ curve->pixmap = NULL;
+ curve->curve_type = STPUI_CURVE_TYPE_SPLINE;
+ curve->height = 0;
+ curve->grab_point = -1;
+
+ curve->num_points = 0;
+ curve->point = 0;
+
+ curve->num_ctlpoints = 0;
+ curve->ctlpoint = NULL;
+
+ curve->min_x = 0.0;
+ curve->max_x = 1.0;
+ curve->min_y = 0.0;
+ curve->max_y = 1.0;
+
+ old_mask = gtk_widget_get_events (GTK_WIDGET (curve));
+ gtk_widget_set_events (GTK_WIDGET (curve), old_mask | GRAPH_MASK);
+ g_signal_connect (curve, "event",
+ G_CALLBACK (stpui_curve_graph_events), curve);
+ stpui_curve_size_graph (curve);
+}
+
+static void
+stpui_curve_set_property (GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ StpuiCurve *curve = STPUI_CURVE (object);
+
+ switch (prop_id)
+ {
+ case PROP_CURVE_TYPE:
+ stpui_curve_set_curve_type (curve, g_value_get_enum (value));
+ break;
+ case PROP_MIN_X:
+ stpui_curve_set_range (curve, g_value_get_float (value), curve->max_x,
+ curve->min_y, curve->max_y);
+ break;
+ case PROP_MAX_X:
+ stpui_curve_set_range (curve, curve->min_x, g_value_get_float (value),
+ curve->min_y, curve->max_y);
+ break;
+ case PROP_MIN_Y:
+ stpui_curve_set_range (curve, curve->min_x, curve->max_x,
+ g_value_get_float (value), curve->max_y);
+ break;
+ case PROP_MAX_Y:
+ stpui_curve_set_range (curve, curve->min_x, curve->max_x,
+ curve->min_y, g_value_get_float (value));
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+stpui_curve_get_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ StpuiCurve *curve = STPUI_CURVE (object);
+
+ switch (prop_id)
+ {
+ case PROP_CURVE_TYPE:
+ g_value_set_enum (value, curve->curve_type);
+ break;
+ case PROP_MIN_X:
+ g_value_set_float (value, curve->min_x);
+ break;
+ case PROP_MAX_X:
+ g_value_set_float (value, curve->max_x);
+ break;
+ case PROP_MIN_Y:
+ g_value_set_float (value, curve->min_y);
+ break;
+ case PROP_MAX_Y:
+ g_value_set_float (value, curve->max_y);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+static int
+project (gfloat value, gfloat min, gfloat max, int norm)
+{
+ return (norm - 1) * ((value - min) / (max - min)) + 0.5;
+}
+
+static gfloat
+unproject (gint value, gfloat min, gfloat max, int norm)
+{
+ return value / (gfloat) (norm - 1) * (max - min) + min;
+}
+
+/* Solve the tridiagonal equation system that determines the second
+ derivatives for the interpolation points. (Based on Numerical
+ Recipies 2nd Edition.) */
+static void
+spline_solve (int n, gfloat x[], gfloat y[], gfloat y2[])
+{
+ gfloat p, sig, *u;
+ gint i, k;
+
+ u = g_malloc ((n - 1) * sizeof (u[0]));
+
+ y2[0] = u[0] = 0.0; /* set lower boundary condition to "natural" */
+
+ for (i = 1; i < n - 1; ++i)
+ {
+ sig = (x[i] - x[i - 1]) / (x[i + 1] - x[i - 1]);
+ p = sig * y2[i - 1] + 2.0;
+ y2[i] = (sig - 1.0) / p;
+ u[i] = ((y[i + 1] - y[i])
+ / (x[i + 1] - x[i]) - (y[i] - y[i - 1]) / (x[i] - x[i - 1]));
+ u[i] = (6.0 * u[i] / (x[i + 1] - x[i - 1]) - sig * u[i - 1]) / p;
+ }
+
+ y2[n - 1] = 0.0;
+ for (k = n - 2; k >= 0; --k)
+ y2[k] = y2[k] * y2[k + 1] + u[k];
+
+ g_free (u);
+}
+
+static gfloat
+spline_eval (int n, gfloat x[], gfloat y[], gfloat y2[], gfloat val)
+{
+ gint k_lo, k_hi, k;
+ gfloat h, b, a;
+
+ /* do a binary search for the right interval: */
+ k_lo = 0; k_hi = n - 1;
+ while (k_hi - k_lo > 1)
+ {
+ k = (k_hi + k_lo) / 2;
+ if (x[k] > val)
+ k_hi = k;
+ else
+ k_lo = k;
+ }
+
+ h = x[k_hi] - x[k_lo];
+ g_assert (h > 0.0);
+
+ a = (x[k_hi] - val) / h;
+ b = (val - x[k_lo]) / h;
+ return a*y[k_lo] + b*y[k_hi] +
+ ((a*a*a - a)*y2[k_lo] + (b*b*b - b)*y2[k_hi]) * (h*h)/6.0;
+}
+
+static void
+stpui_curve_interpolate (StpuiCurve *c, gint width, gint height)
+{
+ gfloat *vector;
+ int i;
+
+ vector = g_malloc (width * sizeof (vector[0]));
+
+ stpui_curve_get_vector (c, width, vector);
+
+ c->height = height;
+ if (c->num_points != width)
+ {
+ c->num_points = width;
+ if (c->point)
+ g_free (c->point);
+ c->point = g_malloc (c->num_points * sizeof (c->point[0]));
+ }
+
+ for (i = 0; i < width; ++i)
+ {
+ c->point[i].x = RADIUS + i;
+ c->point[i].y = RADIUS + height
+ - project (vector[i], c->min_y, c->max_y, height);
+ }
+
+ g_free (vector);
+}
+
+static void
+stpui_curve_draw (StpuiCurve *c, gint width, gint height)
+{
+ GtkStateType state;
+ GtkStyle *style;
+ gint i;
+
+ if (!c->pixmap)
+ return;
+
+ if (c->height != height || c->num_points != width)
+ stpui_curve_interpolate (c, width, height);
+
+ state = GTK_STATE_NORMAL;
+ if (!GTK_WIDGET_IS_SENSITIVE (GTK_WIDGET (c)))
+ state = GTK_STATE_INSENSITIVE;
+
+ style = GTK_WIDGET (c)->style;
+
+ /* clear the pixmap: */
+ gtk_paint_flat_box (style, c->pixmap, GTK_STATE_NORMAL, GTK_SHADOW_NONE,
+ NULL, GTK_WIDGET (c), "curve_bg",
+ 0, 0, width + RADIUS * 2, height + RADIUS * 2);
+ /* draw the grid lines: (XXX make more meaningful) */
+ for (i = 0; i < 5; i++)
+ {
+ gdk_draw_line (c->pixmap, style->dark_gc[state],
+ RADIUS, i * (height / 4.0) + RADIUS,
+ width + RADIUS, i * (height / 4.0) + RADIUS);
+ gdk_draw_line (c->pixmap, style->dark_gc[state],
+ i * (width / 4.0) + RADIUS, RADIUS,
+ i * (width / 4.0) + RADIUS, height + RADIUS);
+ }
+
+ gdk_draw_points (c->pixmap, style->fg_gc[state], c->point, c->num_points);
+ if (c->curve_type != STPUI_CURVE_TYPE_FREE)
+ for (i = 0; i < c->num_ctlpoints; ++i)
+ {
+ gint x, y;
+
+ if (c->ctlpoint[i][0] < c->min_x)
+ continue;
+
+ x = project (c->ctlpoint[i][0], c->min_x, c->max_x,
+ width);
+ y = height -
+ project (c->ctlpoint[i][1], c->min_y, c->max_y,
+ height);
+
+ /* draw a bullet: */
+ gdk_draw_arc (c->pixmap, style->fg_gc[state], TRUE, x, y,
+ RADIUS * 2, RADIUS*2, 0, 360*64);
+ }
+ gdk_draw_drawable (GTK_WIDGET (c)->window, style->fg_gc[state], c->pixmap,
+ 0, 0, 0, 0, width + RADIUS * 2, height + RADIUS * 2);
+}
+
+static gint
+stpui_curve_graph_events (GtkWidget *widget,
+ GdkEvent *event,
+ StpuiCurve *c)
+{
+ GdkCursorType new_type = c->cursor_type;
+ gint i, src, dst, leftbound, rightbound;
+ GdkEventButton *bevent;
+ GdkEventMotion *mevent;
+ GtkWidget *w;
+ gint tx, ty;
+ gint cx, x, y, width, height;
+ gint closest_point = 0;
+ gfloat rx, ry, min_x;
+ guint distance;
+ gint x1, x2, y1, y2;
+ gint retval = FALSE;
+
+ w = GTK_WIDGET (c);
+ width = w->allocation.width - RADIUS * 2;
+ height = w->allocation.height - RADIUS * 2;
+
+ if ((width < 0) || (height < 0))
+ return FALSE;
+
+ /* get the pointer position */
+ gdk_window_get_pointer (w->window, &tx, &ty, NULL);
+ x = CLAMP ((tx - RADIUS), 0, width-1);
+ y = CLAMP ((ty - RADIUS), 0, height-1);
+
+ min_x = c->min_x;
+
+ distance = ~0U;
+ for (i = 0; i < c->num_ctlpoints; ++i)
+ {
+ cx = project (c->ctlpoint[i][0], min_x, c->max_x, width);
+ if ((guint) abs (x - cx) < distance)
+ {
+ distance = abs (x - cx);
+ closest_point = i;
+ }
+ }
+
+ switch (event->type)
+ {
+ case GDK_CONFIGURE:
+ if (c->pixmap)
+ g_object_unref (c->pixmap);
+ c->pixmap = NULL;
+ /* fall through */
+ case GDK_EXPOSE:
+ if (!c->pixmap)
+ c->pixmap = gdk_pixmap_new (w->window,
+ w->allocation.width,
+ w->allocation.height, -1);
+ stpui_curve_draw (c, width, height);
+ break;
+
+ case GDK_BUTTON_PRESS:
+ gtk_grab_add (widget);
+
+ bevent = (GdkEventButton *) event;
+ new_type = GDK_TCROSS;
+
+ switch (c->curve_type)
+ {
+ case STPUI_CURVE_TYPE_LINEAR:
+ case STPUI_CURVE_TYPE_SPLINE:
+ if (distance > MIN_DISTANCE)
+ {
+ /* insert a new control point */
+ if (c->num_ctlpoints > 0)
+ {
+ cx = project (c->ctlpoint[closest_point][0], min_x,
+ c->max_x, width);
+ if (x > cx)
+ ++closest_point;
+ }
+ ++c->num_ctlpoints;
+ c->ctlpoint =
+ g_realloc (c->ctlpoint,
+ c->num_ctlpoints * sizeof (*c->ctlpoint));
+ for (i = c->num_ctlpoints - 1; i > closest_point; --i)
+ memcpy (c->ctlpoint + i, c->ctlpoint + i - 1,
+ sizeof (*c->ctlpoint));
+ }
+ c->grab_point = closest_point;
+ c->ctlpoint[c->grab_point][0] =
+ unproject (x, min_x, c->max_x, width);
+ c->ctlpoint[c->grab_point][1] =
+ unproject (height - y, c->min_y, c->max_y, height);
+
+ stpui_curve_interpolate (c, width, height);
+ break;
+
+ case STPUI_CURVE_TYPE_FREE:
+ c->point[x].x = RADIUS + x;
+ c->point[x].y = RADIUS + y;
+ c->grab_point = x;
+ c->last = y;
+ break;
+ }
+ stpui_curve_draw (c, width, height);
+ retval = TRUE;
+ break;
+
+ case GDK_BUTTON_RELEASE:
+ gtk_grab_remove (widget);
+
+ /* delete inactive points: */
+ if (c->curve_type != STPUI_CURVE_TYPE_FREE)
+ {
+ for (src = dst = 0; src < c->num_ctlpoints; ++src)
+ {
+ if (c->ctlpoint[src][0] >= min_x)
+ {
+ memcpy (c->ctlpoint + dst, c->ctlpoint + src,
+ sizeof (*c->ctlpoint));
+ ++dst;
+ }
+ }
+ if (dst < src)
+ {
+ c->num_ctlpoints -= (src - dst);
+ if (c->num_ctlpoints <= 0)
+ {
+ c->num_ctlpoints = 1;
+ c->ctlpoint[0][0] = min_x;
+ c->ctlpoint[0][1] = c->min_y;
+ stpui_curve_interpolate (c, width, height);
+ stpui_curve_draw (c, width, height);
+ }
+ c->ctlpoint =
+ g_realloc (c->ctlpoint,
+ c->num_ctlpoints * sizeof (*c->ctlpoint));
+ }
+ }
+ new_type = GDK_FLEUR;
+ c->grab_point = -1;
+ retval = TRUE;
+ break;
+
+ case GDK_MOTION_NOTIFY:
+ mevent = (GdkEventMotion *) event;
+
+ switch (c->curve_type)
+ {
+ case STPUI_CURVE_TYPE_LINEAR:
+ case STPUI_CURVE_TYPE_SPLINE:
+ if (c->grab_point == -1)
+ {
+ /* if no point is grabbed... */
+ if (distance <= MIN_DISTANCE)
+ new_type = GDK_FLEUR;
+ else
+ new_type = GDK_TCROSS;
+ }
+ else
+ {
+ /* drag the grabbed point */
+ new_type = GDK_TCROSS;
+
+ leftbound = -MIN_DISTANCE;
+ if (c->grab_point > 0)
+ leftbound = project (c->ctlpoint[c->grab_point - 1][0],
+ min_x, c->max_x, width);
+
+ rightbound = width + RADIUS * 2 + MIN_DISTANCE;
+ if (c->grab_point + 1 < c->num_ctlpoints)
+ rightbound = project (c->ctlpoint[c->grab_point + 1][0],
+ min_x, c->max_x, width);
+
+ if (tx <= leftbound || tx >= rightbound
+ || ty > height + RADIUS * 2 + MIN_DISTANCE
+ || ty < -MIN_DISTANCE)
+ c->ctlpoint[c->grab_point][0] = min_x - 1.0;
+ else
+ {
+ rx = unproject (x, min_x, c->max_x, width);
+ ry = unproject (height - y, c->min_y, c->max_y, height);
+ c->ctlpoint[c->grab_point][0] = rx;
+ c->ctlpoint[c->grab_point][1] = ry;
+ }
+ stpui_curve_interpolate (c, width, height);
+ stpui_curve_draw (c, width, height);
+ }
+ break;
+
+ case STPUI_CURVE_TYPE_FREE:
+ if (c->grab_point != -1)
+ {
+ if (c->grab_point > x)
+ {
+ x1 = x;
+ x2 = c->grab_point;
+ y1 = y;
+ y2 = c->last;
+ }
+ else
+ {
+ x1 = c->grab_point;
+ x2 = x;
+ y1 = c->last;
+ y2 = y;
+ }
+
+ if (x2 != x1)
+ for (i = x1; i <= x2; i++)
+ {
+ c->point[i].x = RADIUS + i;
+ c->point[i].y = RADIUS +
+ (y1 + ((y2 - y1) * (i - x1)) / (x2 - x1));
+ }
+ else
+ {
+ c->point[x].x = RADIUS + x;
+ c->point[x].y = RADIUS + y;
+ }
+ c->grab_point = x;
+ c->last = y;
+ stpui_curve_draw (c, width, height);
+ }
+ if (mevent->state & GDK_BUTTON1_MASK)
+ new_type = GDK_TCROSS;
+ else
+ new_type = GDK_PENCIL;
+ break;
+ }
+ if (new_type != (GdkCursorType) c->cursor_type)
+ {
+ GdkCursor *cursor;
+
+ c->cursor_type = new_type;
+
+ cursor = gdk_cursor_new_for_display (gtk_widget_get_display (w),
+ c->cursor_type);
+ gdk_window_set_cursor (w->window, cursor);
+ gdk_cursor_unref (cursor);
+ }
+ retval = TRUE;
+ break;
+
+ default:
+ break;
+ }
+
+ return retval;
+}
+
+void
+stpui_curve_set_curve_type (StpuiCurve *c, StpuiCurveType new_type)
+{
+ gfloat rx, dx;
+ gint x, i;
+
+ if (new_type != c->curve_type)
+ {
+ gint width, height;
+
+ width = GTK_WIDGET (c)->allocation.width - RADIUS * 2;
+ height = GTK_WIDGET (c)->allocation.height - RADIUS * 2;
+
+ if (new_type == STPUI_CURVE_TYPE_FREE)
+ {
+ stpui_curve_interpolate (c, width, height);
+ c->curve_type = new_type;
+ }
+ else if (c->curve_type == STPUI_CURVE_TYPE_FREE)
+ {
+ if (c->ctlpoint)
+ g_free (c->ctlpoint);
+ c->num_ctlpoints = 9;
+ c->ctlpoint = g_malloc (c->num_ctlpoints * sizeof (*c->ctlpoint));
+
+ rx = 0.0;
+ dx = (width - 1) / (gfloat) (c->num_ctlpoints - 1);
+
+ for (i = 0; i < c->num_ctlpoints; ++i, rx += dx)
+ {
+ x = (int) (rx + 0.5);
+ c->ctlpoint[i][0] =
+ unproject (x, c->min_x, c->max_x, width);
+ c->ctlpoint[i][1] =
+ unproject (RADIUS + height - c->point[x].y,
+ c->min_y, c->max_y, height);
+ }
+ c->curve_type = new_type;
+ stpui_curve_interpolate (c, width, height);
+ }
+ else
+ {
+ c->curve_type = new_type;
+ stpui_curve_interpolate (c, width, height);
+ }
+ g_signal_emit (c, curve_type_changed_signal, 0);
+ g_object_notify (G_OBJECT (c), "curve_type");
+ stpui_curve_draw (c, width, height);
+ }
+}
+
+static void
+stpui_curve_size_graph (StpuiCurve *curve)
+{
+ gint width, height;
+ gfloat aspect;
+ GdkScreen *screen = gtk_widget_get_screen (GTK_WIDGET (curve));
+
+ width = (curve->max_x - curve->min_x) + 1;
+ height = (curve->max_y - curve->min_y) + 1;
+ aspect = width / (gfloat) height;
+ if (width > gdk_screen_get_width (screen) / 4)
+ width = gdk_screen_get_width (screen) / 4;
+ if (height > gdk_screen_get_height (screen) / 4)
+ height = gdk_screen_get_height (screen) / 4;
+
+ if (aspect < 1.0)
+ width = height * aspect;
+ else
+ height = width / aspect;
+
+ gtk_widget_set_size_request (GTK_WIDGET (curve),
+ width + RADIUS * 2,
+ height + RADIUS * 2);
+}
+
+static void
+stpui_curve_reset_vector (StpuiCurve *curve)
+{
+ if (curve->ctlpoint)
+ g_free (curve->ctlpoint);
+
+ curve->num_ctlpoints = 2;
+ curve->ctlpoint = g_malloc (2 * sizeof (curve->ctlpoint[0]));
+ curve->ctlpoint[0][0] = curve->min_x;
+ curve->ctlpoint[0][1] = curve->min_y;
+ curve->ctlpoint[1][0] = curve->max_x;
+ curve->ctlpoint[1][1] = curve->max_y;
+
+ if (curve->pixmap)
+ {
+ gint width, height;
+
+ width = GTK_WIDGET (curve)->allocation.width - RADIUS * 2;
+ height = GTK_WIDGET (curve)->allocation.height - RADIUS * 2;
+
+ if (curve->curve_type == STPUI_CURVE_TYPE_FREE)
+ {
+ curve->curve_type = STPUI_CURVE_TYPE_LINEAR;
+ stpui_curve_interpolate (curve, width, height);
+ curve->curve_type = STPUI_CURVE_TYPE_FREE;
+ }
+ else
+ stpui_curve_interpolate (curve, width, height);
+ stpui_curve_draw (curve, width, height);
+ }
+}
+
+void
+stpui_curve_reset (StpuiCurve *c)
+{
+ StpuiCurveType old_type;
+
+ old_type = c->curve_type;
+ c->curve_type = STPUI_CURVE_TYPE_SPLINE;
+ stpui_curve_reset_vector (c);
+
+ if (old_type != STPUI_CURVE_TYPE_SPLINE)
+ {
+ g_signal_emit (c, curve_type_changed_signal, 0);
+ g_object_notify (G_OBJECT (c), "curve_type");
+ }
+}
+
+void
+stpui_curve_set_gamma (StpuiCurve *c, gfloat gamma)
+{
+ gfloat x, one_over_gamma, height, one_over_width;
+ StpuiCurveType old_type;
+ gint i;
+
+ if (c->num_points < 2)
+ return;
+
+ old_type = c->curve_type;
+ c->curve_type = STPUI_CURVE_TYPE_FREE;
+
+ if (gamma <= 0)
+ one_over_gamma = 1.0;
+ else
+ one_over_gamma = 1.0 / gamma;
+ one_over_width = 1.0 / (c->num_points - 1);
+ height = c->height;
+ for (i = 0; i < c->num_points; ++i)
+ {
+ x = (gfloat) i / (c->num_points - 1);
+ c->point[i].x = RADIUS + i;
+ c->point[i].y =
+ RADIUS + (height * (1.0 - pow (x, one_over_gamma)) + 0.5);
+ }
+
+ if (old_type != STPUI_CURVE_TYPE_FREE)
+ g_signal_emit (c, curve_type_changed_signal, 0);
+
+ stpui_curve_draw (c, c->num_points, c->height);
+}
+
+void
+stpui_curve_set_range (StpuiCurve *curve,
+ gfloat min_x,
+ gfloat max_x,
+ gfloat min_y,
+ gfloat max_y)
+{
+ g_object_freeze_notify (G_OBJECT (curve));
+ if (curve->min_x != min_x) {
+ curve->min_x = min_x;
+ g_object_notify (G_OBJECT (curve), "min_x");
+ }
+ if (curve->max_x != max_x) {
+ curve->max_x = max_x;
+ g_object_notify (G_OBJECT (curve), "max_x");
+ }
+ if (curve->min_y != min_y) {
+ curve->min_y = min_y;
+ g_object_notify (G_OBJECT (curve), "min_y");
+ }
+ if (curve->max_y != max_y) {
+ curve->max_y = max_y;
+ g_object_notify (G_OBJECT (curve), "max_y");
+ }
+ g_object_thaw_notify (G_OBJECT (curve));
+
+ stpui_curve_size_graph (curve);
+ stpui_curve_reset_vector (curve);
+}
+
+void
+stpui_curve_set_vector (StpuiCurve *c, int veclen, const gfloat vector[])
+{
+ StpuiCurveType old_type;
+ gfloat rx, dx, ry;
+ gint i, height;
+ GdkScreen *screen = gtk_widget_get_screen (GTK_WIDGET (c));
+
+ old_type = c->curve_type;
+ c->curve_type = STPUI_CURVE_TYPE_FREE;
+
+ if (c->point)
+ height = GTK_WIDGET (c)->allocation.height - RADIUS * 2;
+ else
+ {
+ height = (c->max_y - c->min_y);
+ if (height > gdk_screen_get_height (screen) / 4)
+ height = gdk_screen_get_height (screen) / 4;
+
+ c->height = height;
+ c->num_points = veclen;
+ c->point = g_malloc (c->num_points * sizeof (c->point[0]));
+ }
+ rx = 0;
+ dx = (veclen - 1.0) / (c->num_points - 1.0);
+
+ for (i = 0; i < c->num_points; ++i, rx += dx)
+ {
+ ry = vector[(int) (rx + 0.5)];
+ if (ry > c->max_y) ry = c->max_y;
+ if (ry < c->min_y) ry = c->min_y;
+ c->point[i].x = RADIUS + i;
+ c->point[i].y =
+ RADIUS + height - project (ry, c->min_y, c->max_y, height);
+ }
+ if (old_type != STPUI_CURVE_TYPE_FREE)
+ {
+ g_signal_emit (c, curve_type_changed_signal, 0);
+ g_object_notify (G_OBJECT (c), "curve_type");
+ }
+
+ stpui_curve_draw (c, c->num_points, height);
+}
+
+void
+stpui_curve_get_vector (StpuiCurve *c, int veclen, gfloat vector[])
+{
+ gfloat rx, ry, dx, dy, min_x, delta_x, *mem, *xv, *yv, *y2v, prev;
+ gint dst, i, x, next, num_active_ctlpoints = 0, first_active = -1;
+
+ min_x = c->min_x;
+
+ if (c->curve_type != STPUI_CURVE_TYPE_FREE)
+ {
+ /* count active points: */
+ prev = min_x - 1.0;
+ for (i = num_active_ctlpoints = 0; i < c->num_ctlpoints; ++i)
+ if (c->ctlpoint[i][0] > prev)
+ {
+ if (first_active < 0)
+ first_active = i;
+ prev = c->ctlpoint[i][0];
+ ++num_active_ctlpoints;
+ }
+
+ /* handle degenerate case: */
+ if (num_active_ctlpoints < 2)
+ {
+ if (num_active_ctlpoints > 0)
+ ry = c->ctlpoint[first_active][1];
+ else
+ ry = c->min_y;
+ if (ry < c->min_y) ry = c->min_y;
+ if (ry > c->max_y) ry = c->max_y;
+ for (x = 0; x < veclen; ++x)
+ vector[x] = ry;
+ return;
+ }
+ }
+
+ switch (c->curve_type)
+ {
+ case STPUI_CURVE_TYPE_SPLINE:
+ mem = g_malloc (3 * num_active_ctlpoints * sizeof (gfloat));
+ xv = mem;
+ yv = mem + num_active_ctlpoints;
+ y2v = mem + 2*num_active_ctlpoints;
+
+ prev = min_x - 1.0;
+ for (i = dst = 0; i < c->num_ctlpoints; ++i)
+ if (c->ctlpoint[i][0] > prev)
+ {
+ prev = c->ctlpoint[i][0];
+ xv[dst] = c->ctlpoint[i][0];
+ yv[dst] = c->ctlpoint[i][1];
+ ++dst;
+ }
+
+ spline_solve (num_active_ctlpoints, xv, yv, y2v);
+
+ rx = min_x;
+ dx = (c->max_x - min_x) / (veclen - 1);
+ for (x = 0; x < veclen; ++x, rx += dx)
+ {
+ ry = spline_eval (num_active_ctlpoints, xv, yv, y2v, rx);
+ if (ry < c->min_y) ry = c->min_y;
+ if (ry > c->max_y) ry = c->max_y;
+ vector[x] = ry;
+ }
+
+ g_free (mem);
+ break;
+
+ case STPUI_CURVE_TYPE_LINEAR:
+ dx = (c->max_x - min_x) / (veclen - 1);
+ rx = min_x;
+ ry = c->min_y;
+ dy = 0.0;
+ i = first_active;
+ for (x = 0; x < veclen; ++x, rx += dx)
+ {
+ if (rx >= c->ctlpoint[i][0])
+ {
+ if (rx > c->ctlpoint[i][0])
+ ry = c->min_y;
+ dy = 0.0;
+ next = i + 1;
+ while (next < c->num_ctlpoints
+ && c->ctlpoint[next][0] <= c->ctlpoint[i][0])
+ ++next;
+ if (next < c->num_ctlpoints)
+ {
+ delta_x = c->ctlpoint[next][0] - c->ctlpoint[i][0];
+ dy = ((c->ctlpoint[next][1] - c->ctlpoint[i][1])
+ / delta_x);
+ dy *= dx;
+ ry = c->ctlpoint[i][1];
+ i = next;
+ }
+ }
+ vector[x] = ry;
+ ry += dy;
+ }
+ break;
+
+ case STPUI_CURVE_TYPE_FREE:
+ if (c->point)
+ {
+ rx = 0.0;
+ dx = c->num_points / (double) veclen;
+ for (x = 0; x < veclen; ++x, rx += dx)
+ vector[x] = unproject (RADIUS + c->height - c->point[(int) rx].y,
+ c->min_y, c->max_y,
+ c->height);
+ }
+ else
+ memset (vector, 0, veclen * sizeof (vector[0]));
+ break;
+ }
+}
+
+GtkWidget*
+stpui_curve_new (void)
+{
+ return g_object_new (STPUI_TYPE_CURVE, NULL);
+}
+
+static void
+stpui_curve_finalize (GObject *object)
+{
+ StpuiCurve *curve;
+
+ g_return_if_fail (STPUI_IS_CURVE (object));
+
+ curve = STPUI_CURVE (object);
+ if (curve->pixmap)
+ g_object_unref (curve->pixmap);
+ if (curve->point)
+ g_free (curve->point);
+ if (curve->ctlpoint)
+ g_free (curve->ctlpoint);
+
+ G_OBJECT_CLASS (parent_class)->finalize (object);
+}
diff --git a/src/gutenprintui2/gammacurve.c b/src/gutenprintui2/gammacurve.c
new file mode 100644
index 0000000..c195b7d
--- /dev/null
+++ b/src/gutenprintui2/gammacurve.c
@@ -0,0 +1,495 @@
+/* GTK - The GIMP Toolkit
+ * Copyright (C) 1997 David Mosberger
+ * 2004 Roger Leigh
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+/*
+ * Modified by the GTK+ Team and others 1997-2000. See the AUTHORS
+ * file for a list of people on the GTK+ Team. See the ChangeLog
+ * files for a list of changes. These files are distributed with
+ * GTK+ at ftp://ftp.gtk.org/pub/gtk/.
+ */
+
+/*
+ * Incorporated into Gutenprint by Roger Leigh in 2004. Subsequent
+ * changes are by the Gutenprint team.
+ */
+
+#include <config.h>
+#include <string.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+#include <gtk/gtkdialog.h>
+#include <gtk/gtkdrawingarea.h>
+#include <gtk/gtkentry.h>
+#include <gtk/gtkhbox.h>
+#include <gtk/gtkimage.h>
+#include <gtk/gtklabel.h>
+#include <gtk/gtkmain.h>
+#include <gtk/gtkradiobutton.h>
+#include <gtk/gtkstock.h>
+#include <gtk/gtktable.h>
+#include <gtk/gtkvbox.h>
+#include <gtk/gtkwindow.h>
+
+#include <gutenprint/gutenprint-intl-internal.h>
+
+#include <gutenprintui2/curve.h>
+#include <gutenprintui2/gammacurve.h>
+
+static GtkVBoxClass *parent_class = NULL;
+
+
+/* forward declarations: */
+static void stpui_gamma_curve_class_init (StpuiGammaCurveClass *class);
+static void stpui_gamma_curve_init (StpuiGammaCurve *curve);
+static void stpui_gamma_curve_destroy (GtkObject *object);
+
+static void curve_type_changed_callback (GtkWidget *w, gpointer data);
+static void button_realize_callback (GtkWidget *w);
+static void button_toggled_callback (GtkWidget *w, gpointer data);
+static void button_clicked_callback (GtkWidget *w, gpointer data);
+
+enum
+ {
+ LINEAR = 0,
+ SPLINE,
+ FREE,
+ GAMMA,
+ RESET,
+ NUM_XPMS
+ };
+
+static const char *xpm[][27] =
+ {
+ /* spline: */
+ {
+ /* width height ncolors chars_per_pixel */
+ "16 16 4 1",
+ /* colors */
+ ". c None",
+ "B c #000000",
+ "+ c #BC2D2D",
+ "r c #FF0000",
+ /* pixels */
+ "..............BB",
+ ".........rrrrrrB",
+ ".......rr.......",
+ ".....B+.........",
+ "....BBB.........",
+ "....+B..........",
+ "....r...........",
+ "...r............",
+ "...r............",
+ "..r.............",
+ "..r.............",
+ ".r..............",
+ ".r..............",
+ ".r..............",
+ "B+..............",
+ "BB.............."
+ },
+ /* linear: */
+ {
+ /* width height ncolors chars_per_pixel */
+ "16 16 5 1",
+ /* colors */
+ ". c None", /* transparent */
+ "B c #000000",
+ "' c #7F7F7F",
+ "+ c #824141",
+ "r c #FF0000",
+ /* pixels */
+ "..............BB",
+ "..............+B",
+ "..............r.",
+ ".............r..",
+ ".............r..",
+ "....'B'.....r...",
+ "....BBB.....r...",
+ "....+B+....r....",
+ "....r.r....r....",
+ "...r...r..r.....",
+ "...r...r..r.....",
+ "..r.....rB+.....",
+ "..r.....BBB.....",
+ ".r......'B'.....",
+ "B+..............",
+ "BB.............."
+ },
+ /* free: */
+ {
+ /* width height ncolors chars_per_pixel */
+ "16 16 2 1",
+ /* colors */
+ ". c None",
+ "r c #FF0000",
+ /* pixels */
+ "................",
+ "................",
+ "......r.........",
+ "......r.........",
+ ".......r........",
+ ".......r........",
+ ".......r........",
+ "........r.......",
+ "........r.......",
+ "........r.......",
+ ".....r...r.rrrrr",
+ "....r....r......",
+ "...r.....r......",
+ "..r.......r.....",
+ ".r........r.....",
+ "r..............."
+ },
+ /* gamma: */
+ {
+ /* width height ncolors chars_per_pixel */
+ "16 16 10 1",
+ /* colors */
+ ". c None",
+ "B c #000000",
+ "& c #171717",
+ "# c #2F2F2F",
+ "X c #464646",
+ "= c #5E5E5E",
+ "/ c #757575",
+ "+ c #8C8C8C",
+ "- c #A4A4A4",
+ "` c #BBBBBB",
+ /* pixels */
+ "................",
+ "................",
+ "................",
+ "....B=..+B+.....",
+ "....X&`./&-.....",
+ "...../+.XX......",
+ "......B.B+......",
+ "......X.X.......",
+ "......X&+.......",
+ "......-B........",
+ "....../=........",
+ "......#B........",
+ "......BB........",
+ "......B#........",
+ "................",
+ "................"
+ },
+ /* reset: */
+ {
+ /* width height ncolors chars_per_pixel */
+ "16 16 4 1",
+ /* colors */
+ ". c None",
+ "B c #000000",
+ "+ c #824141",
+ "r c #FF0000",
+ /* pixels */
+ "..............BB",
+ "..............+B",
+ ".............r..",
+ "............r...",
+ "...........r....",
+ "..........r.....",
+ ".........r......",
+ "........r.......",
+ ".......r........",
+ "......r.........",
+ ".....r..........",
+ "....r...........",
+ "...r............",
+ "..r.............",
+ "B+..............",
+ "BB.............."
+ }
+ };
+
+GType
+stpui_gamma_curve_get_type (void)
+{
+ static GType gamma_curve_type = 0;
+
+ if (!gamma_curve_type)
+ {
+ static const GTypeInfo gamma_curve_info =
+ {
+ sizeof (StpuiGammaCurveClass),
+ NULL, /* base_init */
+ NULL, /* base_finalize */
+ (GClassInitFunc) stpui_gamma_curve_class_init,
+ NULL, /* class_finalize */
+ NULL, /* class_data */
+ sizeof (StpuiGammaCurve),
+ 0, /* n_preallocs */
+ (GInstanceInitFunc) stpui_gamma_curve_init,
+ };
+
+ gamma_curve_type = g_type_register_static (GTK_TYPE_VBOX, "StpuiGammaCurve",
+ &gamma_curve_info, 0);
+ }
+ return gamma_curve_type;
+}
+
+static void
+stpui_gamma_curve_class_init (StpuiGammaCurveClass *class)
+{
+ GtkObjectClass *object_class;
+
+ parent_class = g_type_class_peek_parent (class);
+
+ object_class = (GtkObjectClass *) class;
+ object_class->destroy = stpui_gamma_curve_destroy;
+}
+
+static void
+stpui_gamma_curve_init (StpuiGammaCurve *curve)
+{
+ GtkWidget *vbox;
+ int i;
+
+ curve->gamma = 1.0;
+
+ curve->table = gtk_table_new (1, 2, FALSE);
+ gtk_table_set_col_spacings (GTK_TABLE (curve->table), 3);
+ gtk_container_add (GTK_CONTAINER (curve), curve->table);
+
+ curve->curve = stpui_curve_new ();
+ g_signal_connect (curve->curve, "curve_type_changed",
+ G_CALLBACK (curve_type_changed_callback), curve);
+ gtk_table_attach_defaults (GTK_TABLE (curve->table), curve->curve, 0, 1, 0, 1);
+
+ vbox = gtk_vbox_new (/* homogeneous */ FALSE, /* spacing */ 3);
+ gtk_table_attach (GTK_TABLE (curve->table), vbox, 1, 2, 0, 1, 0, 0, 0, 0);
+
+ /* toggle buttons: */
+ for (i = 0; i < 3; ++i)
+ {
+ curve->button[i] = gtk_toggle_button_new ();
+ g_object_set_data (G_OBJECT (curve->button[i]), "_StpuiGammaCurveIndex",
+ GINT_TO_POINTER (i));
+ gtk_container_add (GTK_CONTAINER (vbox), curve->button[i]);
+ g_signal_connect (curve->button[i], "realize",
+ G_CALLBACK (button_realize_callback), NULL);
+ g_signal_connect (curve->button[i], "toggled",
+ G_CALLBACK (button_toggled_callback), curve);
+ gtk_widget_show (curve->button[i]);
+ }
+
+ /* push buttons: */
+ for (i = 3; i < 5; ++i)
+ {
+ curve->button[i] = gtk_button_new ();
+ g_object_set_data (G_OBJECT (curve->button[i]), "_StpuiGammaCurveIndex",
+ GINT_TO_POINTER (i));
+ gtk_container_add (GTK_CONTAINER (vbox), curve->button[i]);
+ g_signal_connect (curve->button[i], "realize",
+ G_CALLBACK (button_realize_callback), NULL);
+ g_signal_connect (curve->button[i], "clicked",
+ G_CALLBACK (button_clicked_callback), curve);
+ gtk_widget_show (curve->button[i]);
+ }
+
+ gtk_widget_show (vbox);
+ gtk_widget_show (curve->table);
+ gtk_widget_show (curve->curve);
+}
+
+static void
+button_realize_callback (GtkWidget *w)
+{
+ GtkWidget *pixmap;
+ GdkBitmap *mask;
+ GdkPixmap *pm;
+ int i;
+
+ i = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (w), "_StpuiGammaCurveIndex"));
+ pm = gdk_pixmap_create_from_xpm_d (w->window, &mask,
+ &w->style->bg[GTK_STATE_NORMAL], (gchar **)xpm[i]);
+
+ pixmap = gtk_image_new_from_pixmap (pm, mask);
+ gtk_container_add (GTK_CONTAINER (w), pixmap);
+ gtk_widget_show (pixmap);
+
+ g_object_unref (pm);
+ g_object_unref (mask);
+}
+
+static void
+button_toggled_callback (GtkWidget *w, gpointer data)
+{
+ StpuiGammaCurve *c = data;
+ StpuiCurveType type;
+ int active, i;
+
+ if (!GTK_TOGGLE_BUTTON (w)->active)
+ return;
+
+ active = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (w), "_StpuiGammaCurveIndex"));
+
+ for (i = 0; i < 3; ++i)
+ if ((i != active) && GTK_TOGGLE_BUTTON (c->button[i])->active)
+ break;
+
+ if (i < 3)
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (c->button[i]), FALSE);
+
+ switch (active)
+ {
+ case 0: type = STPUI_CURVE_TYPE_SPLINE; break;
+ case 1: type = STPUI_CURVE_TYPE_LINEAR; break;
+ default: type = STPUI_CURVE_TYPE_FREE; break;
+ }
+ stpui_curve_set_curve_type (STPUI_CURVE (c->curve), type);
+}
+
+static void
+gamma_cancel_callback (GtkWidget *w, gpointer data)
+{
+ StpuiGammaCurve *c = data;
+
+ gtk_widget_destroy (c->gamma_dialog);
+}
+
+static void
+gamma_ok_callback (GtkWidget *w, gpointer data)
+{
+ StpuiGammaCurve *c = data;
+ const gchar *start;
+ gchar *end;
+ gfloat v;
+
+ start = gtk_entry_get_text (GTK_ENTRY (c->gamma_text));
+ if (start)
+ {
+ v = g_strtod (start, &end);
+ if (end > start && v > 0.0)
+ c->gamma = v;
+ }
+ stpui_curve_set_gamma (STPUI_CURVE (c->curve), c->gamma);
+ gamma_cancel_callback (w, data);
+}
+
+static void
+button_clicked_callback (GtkWidget *w, gpointer data)
+{
+ StpuiGammaCurve *c = data;
+ int active;
+
+ active = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (w), "_StpuiGammaCurveIndex"));
+ if (active == 3)
+ {
+ /* set gamma */
+ if (c->gamma_dialog)
+ return;
+ else
+ {
+ GtkWidget *vbox, *hbox, *label, *button;
+ gchar buf[64];
+
+ c->gamma_dialog = gtk_dialog_new ();
+ gtk_window_set_screen (GTK_WINDOW (c->gamma_dialog),
+ gtk_widget_get_screen (w));
+ gtk_window_set_title (GTK_WINDOW (c->gamma_dialog), _("Gamma"));
+ g_object_add_weak_pointer (G_OBJECT (c->gamma_dialog),
+ (gpointer *)&c->gamma_dialog);
+
+ vbox = GTK_DIALOG (c->gamma_dialog)->vbox;
+
+ hbox = gtk_hbox_new (/* homogeneous */ FALSE, 0);
+ gtk_box_pack_start (GTK_BOX (vbox), hbox, TRUE, TRUE, 2);
+ gtk_widget_show (hbox);
+
+ label = gtk_label_new_with_mnemonic (_("_Gamma value"));
+ gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 2);
+ gtk_widget_show (label);
+
+ sprintf (buf, "%g", c->gamma);
+ c->gamma_text = gtk_entry_new ();
+ gtk_label_set_mnemonic_widget (GTK_LABEL (label), c->gamma_text);
+ gtk_entry_set_text (GTK_ENTRY (c->gamma_text), buf);
+ gtk_box_pack_start (GTK_BOX (hbox), c->gamma_text, TRUE, TRUE, 2);
+ gtk_widget_show (c->gamma_text);
+
+ /* fill in action area: */
+ hbox = GTK_DIALOG (c->gamma_dialog)->action_area;
+
+ button = gtk_button_new_from_stock (GTK_STOCK_CANCEL);
+ g_signal_connect (button, "clicked",
+ G_CALLBACK (gamma_cancel_callback), c);
+ gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 0);
+ gtk_widget_show (button);
+
+ button = gtk_button_new_from_stock (GTK_STOCK_OK);
+ GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
+ g_signal_connect (button, "clicked",
+ G_CALLBACK (gamma_ok_callback), c);
+ gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 0);
+ gtk_widget_grab_default (button);
+ gtk_widget_show (button);
+
+ gtk_widget_show (c->gamma_dialog);
+ }
+ }
+ else
+ {
+ /* reset */
+ stpui_curve_reset (STPUI_CURVE (c->curve));
+ }
+}
+
+static void
+curve_type_changed_callback (GtkWidget *w, gpointer data)
+{
+ StpuiGammaCurve *c = data;
+ StpuiCurveType new_type;
+ int active;
+
+ new_type = STPUI_CURVE (w)->curve_type;
+ switch (new_type)
+ {
+ case STPUI_CURVE_TYPE_SPLINE: active = 0; break;
+ case STPUI_CURVE_TYPE_LINEAR: active = 1; break;
+ default: active = 2; break;
+ }
+ if (!GTK_TOGGLE_BUTTON (c->button[active])->active)
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (c->button[active]), TRUE);
+}
+
+GtkWidget*
+stpui_gamma_curve_new (void)
+{
+ return g_object_new (STPUI_TYPE_GAMMA_CURVE, NULL);
+}
+
+static void
+stpui_gamma_curve_destroy (GtkObject *object)
+{
+ StpuiGammaCurve *c;
+
+ g_return_if_fail (STPUI_IS_GAMMA_CURVE (object));
+
+ c = STPUI_GAMMA_CURVE (object);
+
+ if (c->gamma_dialog)
+ gtk_widget_destroy (c->gamma_dialog);
+
+ if (GTK_OBJECT_CLASS (parent_class)->destroy)
+ (* GTK_OBJECT_CLASS (parent_class)->destroy) (object);
+}
+
diff --git a/src/gutenprintui2/gutenprintui-internal.h b/src/gutenprintui2/gutenprintui-internal.h
new file mode 100644
index 0000000..1ff37de
--- /dev/null
+++ b/src/gutenprintui2/gutenprintui-internal.h
@@ -0,0 +1,240 @@
+/*
+ * "$Id: gutenprintui-internal.h,v 1.2 2005/04/09 14:52:34 rlk Exp $"
+ *
+ * Print plug-in for the GIMP.
+ *
+ * Copyright 1997-2000 Michael Sweet (mike@easysw.com),
+ * Robert Krawitz (rlk@alum.mit.edu). and Steve Miller (smiller@rni.net
+ *
+ * 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 2 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ *
+ * Revision History:
+ *
+ * See ChangeLog
+ */
+
+#ifndef GUTENPRINTUI_INTERNAL_H
+#define GUTENPRINTUI_INTERNAL_H
+
+#ifdef __GNUC__
+#define inline __inline__
+#endif
+
+#include <sys/types.h>
+#include <gtk/gtk.h>
+
+#include <gutenprint/gutenprint.h>
+
+typedef struct
+{
+ GtkWidget *checkbox;
+ int current;
+ int deflt;
+} boolean_option_t;
+
+typedef struct
+{
+ gint callback_id;
+ char *default_val;
+ stp_string_list_t *params;
+ GtkWidget *combo;
+ GtkWidget *label;
+} list_option_t;
+
+typedef struct
+{
+ GtkObject *adjustment;
+ gfloat upper;
+ gfloat lower;
+ gfloat deflt;
+ gfloat scale;
+} float_option_t;
+
+typedef struct
+{
+ GtkWidget *label;
+ GtkWidget *button;
+ GtkWidget *dialog;
+ GtkWidget *gamma_curve;
+ const char *help_text;
+ stp_curve_t *current;
+ const stp_curve_t *deflt;
+ gboolean is_visible;
+} curve_option_t;
+
+typedef struct
+{
+ const stp_parameter_t *fast_desc;
+ int is_active;
+ int is_enabled;
+ GtkWidget *checkbox;
+ union {
+ list_option_t list;
+ float_option_t flt;
+ curve_option_t curve;
+ boolean_option_t bool;
+ } info;
+} option_t;
+
+typedef struct
+{
+ const char *name;
+ const char *help;
+ gdouble scale;
+ GtkWidget *checkbox;
+ const char *format;
+} unit_t;
+
+typedef struct
+{
+ const char *name;
+ const char *help;
+ const char *value;
+ GtkWidget *button;
+} radio_group_t;
+
+typedef struct
+{
+ unsigned char *base_addr;
+ int bpp;
+ off_t offset;
+ off_t limit;
+} priv_t;
+
+#define PLUG_IN_VERSION VERSION " - " RELEASE_DATE
+#define PLUG_IN_NAME "Print"
+
+#define INVALID_TOP 1
+#define INVALID_LEFT 2
+
+#define SCALE_ENTRY_LABEL(adj) \
+ GTK_LABEL (gtk_object_get_data (GTK_OBJECT(adj), "label"))
+
+#define SCALE_ENTRY_SCALE(adj) \
+ GTK_HSCALE (gtk_object_get_data (GTK_OBJECT(adj), "scale"))
+#define SCALE_ENTRY_SCALE_ADJ(adj) \
+ gtk_range_get_adjustment \
+ (GTK_RANGE (gtk_object_get_data (GTK_OBJECT (adj), "scale")))
+
+#define SCALE_ENTRY_SPINBUTTON(adj) \
+ GTK_SPIN_BUTTON (gtk_object_get_data (GTK_OBJECT (adj), "spinbutton"))
+#define SCALE_ENTRY_SPINBUTTON_ADJ(adj) \
+ gtk_spin_button_get_adjustment \
+ (GTK_SPIN_BUTTON (gtk_object_get_data (GTK_OBJECT (adj), "spinbutton")))
+
+extern gint stpui_plist_count; /* Number of system printers */
+extern gint stpui_plist_current; /* Current system printer */
+extern stpui_plist_t *stpui_plist; /* System printers */
+extern char *stpui_printrc_current_printer;
+extern int stpui_show_all_paper_sizes;
+extern stp_string_list_t *stpui_system_print_queues;
+
+/*
+ * Function prototypes
+ */
+
+extern stpui_plist_t *stpui_plist_create(const char *name, const char *driver);
+extern const char *stpui_combo_get_name(GtkWidget *combo,
+ const stp_string_list_t *options);
+extern void stpui_table_attach_aligned(GtkTable *table, gint column,
+ gint row, const gchar *label_text,
+ gfloat xalign, gfloat yalign,
+ GtkWidget *widget, gint colspan,
+ gboolean left_align);
+
+extern GtkWidget *stpui_create_entry(GtkWidget *table, int hpos, int vpos,
+ const char *text, const char *help,
+ GCallback callback);
+extern GSList *stpui_create_radio_button(radio_group_t *radio, GSList *group,
+ GtkWidget *table, int hpos, int vpos,
+ GCallback callback);
+extern void stpui_set_adjustment_tooltip (GtkObject *adj, const gchar *tip);
+extern void stpui_create_new_combo(option_t *option, GtkWidget *table,
+ int hpos, int vpos, gboolean is_optional);
+extern void stpui_help_init (void);
+extern void stpui_help_free (void);
+extern void stpui_enable_help (void);
+extern void stpui_disable_help (void);
+extern void stpui_set_help_data (GtkWidget *widget, const gchar *tooltip);
+
+extern GtkWidget *stpui_dialog_new(const gchar *title,
+ GtkWindowPosition position,
+ gboolean resizable,
+ /* specify action area buttons as va_list:
+ * const gchar *label,
+ * GtkSignalFunc callback,
+ * gpointer data,
+ * GtkObject *slot_object,
+ * GtkWidget **widget_ptr,
+ * gboolean default_action,
+ * gboolean connect_delete,
+ */
+ ...);
+
+extern GtkWidget *stpui_option_menu_new(gboolean menu_only,
+ /* specify menu items as va_list:
+ * const gchar *label,
+ * GtkSignalFunc callback,
+ * gpointer data,
+ * gpointer user_data,
+ * GtkWidget **widget_ptr,
+ * gboolean active
+ */
+ ...);
+
+extern GtkObject *stpui_scale_entry_new(GtkTable *table,
+ gint column,
+ gint row,
+ const gchar *text,
+ gint scale_usize,
+ gint spinbutton_usize,
+ gfloat value,
+ gfloat lower,
+ gfloat upper,
+ gfloat step_increment,
+ gfloat page_increment,
+ guint digits,
+ gboolean constrain,
+ gfloat unconstrained_lower,
+ gfloat unconstrained_upper,
+ const gchar *tooltip);
+
+extern void stpui_create_scale_entry(option_t *option,
+ GtkTable *table,
+ gint column,
+ gint row,
+ const gchar *text,
+ gint scale_usize,
+ gint spinbutton_usize,
+ gfloat value,
+ gfloat lower,
+ gfloat upper,
+ gfloat step_increment,
+ gfloat page_increment,
+ guint digits,
+ gboolean constrain,
+ gfloat unconstrained_lower,
+ gfloat unconstrained_upper,
+ const gchar *tooltip,
+ gboolean is_optional);
+
+
+/* Thumbnails -- keep it simple! */
+
+stp_image_t *stpui_image_thumbnail_new(const guchar *data, gint w, gint h,
+ gint bpp);
+
+#endif /* GUTENPRINTUI_INTERNAL_H */
diff --git a/src/gutenprintui2/gutenprintui2.pc.in b/src/gutenprintui2/gutenprintui2.pc.in
new file mode 100644
index 0000000..803aaae
--- /dev/null
+++ b/src/gutenprintui2/gutenprintui2.pc.in
@@ -0,0 +1,11 @@
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+libdir=@libdir@
+includedir=@includedir@
+
+Name: Gutenprint UI (GTK+-2.0 version)
+Description: Gutenprint Top Quality Printer Drivers - GTK+-2.0 User Interface
+Requires: gutenprint gtk+-2.0
+Version: @VERSION@
+Libs: -L${libdir} @gutenprintui2_libs@
+Cflags: -I${includedir} @gutenprintui2_cflags@
diff --git a/src/gutenprintui2/panel.c b/src/gutenprintui2/panel.c
new file mode 100644
index 0000000..c8a2ab9
--- /dev/null
+++ b/src/gutenprintui2/panel.c
@@ -0,0 +1,4962 @@
+/*
+ * "$Id: panel.c,v 1.4 2005/06/30 01:42:56 rlk Exp $"
+ *
+ * Main window code for Print plug-in for the GIMP.
+ *
+ * Copyright 1997-2003 Michael Sweet (mike@easysw.com),
+ * Robert Krawitz (rlk@alum.mit.edu), Steve Miller (smiller@rni.net)
+ * and Michael Natterer (mitch@gimp.org)
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#define MAX_PREVIEW_PPI (400)
+#define INCH 72
+#define FINCH ((gdouble) INCH)
+#define ROUNDUP(x, y) (((x) + ((y) - 1)) / (y))
+#define SCALE(x, y) (((x) + (1.0 / (2.0 * (y)))) * (y))
+
+#include <gutenprint/gutenprint-intl-internal.h>
+#include <gutenprintui2/gutenprintui.h>
+#include "gutenprintui-internal.h"
+
+#include <string.h>
+#include <stdio.h>
+
+#define MAXIMUM_PARAMETER_LEVEL STP_PARAMETER_LEVEL_ADVANCED4
+
+/*
+ * Constants for GUI.
+ */
+static int preview_size_vert = 360;
+static int preview_size_horiz = 300;
+static const int minimum_image_percent = 5.0;
+static const int thumbnail_hintw = 128;
+static const int thumbnail_hinth = 128;
+
+#define MOVE_CONSTRAIN 0
+#define MOVE_HORIZONTAL 1
+#define MOVE_VERTICAL 2
+#define MOVE_ANY (MOVE_HORIZONTAL | MOVE_VERTICAL)
+#define MOVE_GRID 4
+
+/*
+ * Main window widgets
+ */
+
+static GtkWidget *main_vbox;
+static GtkWidget *main_hbox;
+static GtkWidget *right_vbox;
+static GtkWidget *notebook;
+
+static GtkWidget *output_color_vbox;
+static GtkWidget *cyan_button;
+static GtkWidget *magenta_button;
+static GtkWidget *yellow_button;
+static GtkWidget *black_button;
+
+static GtkWidget *print_dialog; /* Print dialog window */
+
+static GtkWidget *recenter_button;
+static GtkWidget *recenter_vertical_button;
+static GtkWidget *recenter_horizontal_button;
+
+static GtkWidget *left_entry;
+/*
+static GtkWidget *right_entry;
+*/
+static GtkWidget *right_border_entry;
+static GtkWidget *top_entry;
+/*
+static GtkWidget *bottom_entry;
+*/
+static GtkWidget *bottom_border_entry;
+static GtkWidget *width_entry;
+static GtkWidget *height_entry;
+static GtkWidget *units_hbox;
+static GtkWidget *units_label;
+
+static GtkWidget *custom_size_width;
+static GtkWidget *custom_size_height;
+static GtkWidget *show_all_paper_sizes_button;
+static GtkWidget *auto_paper_size_button;
+
+static GtkWidget *orientation_menu; /* Orientation menu */
+
+static GtkWidget *scaling_percent; /* Scale by percent */
+static GtkWidget *scaling_ppi; /* Scale by pixels-per-inch */
+static GtkWidget *scaling_image; /* Scale to the image */
+static GtkObject *scaling_adjustment; /* Adjustment object for scaling */
+
+static GtkWidget *setup_dialog; /* Setup dialog window */
+static GtkWidget *printer_driver; /* Printer driver widget */
+static GtkWidget *printer_model_label; /* Printer model name */
+static GtkWidget *printer_crawler; /* Scrolled Window for menu */
+static GtkWidget *printer_combo; /* Combo for menu */
+static GtkWidget *manufacturer_clist; /* Manufacturer widget */
+static GtkWidget *manufacturer_crawler; /* Scrolled Window for menu */
+static gint plist_callback_id = -1;
+static GtkWidget *ppd_file; /* PPD file entry */
+static GtkWidget *ppd_box;
+static GtkWidget *ppd_label; /* PPD file entry */
+static GtkWidget *ppd_button; /* PPD file browse button */
+static GtkWidget *ppd_browser; /* File selection dialog for PPDs */
+static GtkWidget *new_printer_dialog; /* New printer dialog window */
+static GtkWidget *new_printer_entry; /* New printer text entry */
+static GtkWidget *file_button; /* PPD file browse button */
+static GtkWidget *file_entry; /* FSD for print files */
+static GtkWidget *file_browser; /* FSD for print files */
+static GtkWidget *standard_cmd_entry; /* FSD for print files */
+static GtkWidget *custom_command_entry; /* FSD for print files */
+static GtkWidget *queue_combo; /* FSD for print files */
+static gint queue_callback_id = -1;
+
+static GtkWidget *adjust_color_button;
+static GtkWidget *about_dialog;
+
+static GtkWidget *page_size_table;
+static GtkWidget *printer_features_table;
+static GtkWidget *color_adjustment_table;
+
+static GtkWidget *copy_count_spin_button;
+
+static gboolean preview_valid = FALSE;
+static gboolean frame_valid = FALSE;
+static gboolean need_exposure = FALSE;
+static gboolean suppress_scaling_adjustment = FALSE;
+static gboolean suppress_scaling_callback = FALSE;
+static gboolean thumbnail_update_pending = FALSE;
+/*
+ * These are semaphores, not true booleans.
+ */
+static gint suppress_preview_update = 0;
+static gint suppress_preview_reset = 0;
+
+static GtkDrawingArea *preview = NULL; /* Preview drawing area widget */
+static GtkDrawingArea *swatch = NULL;
+static gint mouse_x, mouse_y; /* Last mouse position */
+static gint orig_top, orig_left; /* Original mouse position at start */
+static gint buttons_pressed = 0;
+static gint preview_active = 0;
+static gint buttons_mask = 0;
+static gint move_constraint = 0;
+static gint mouse_button = -1; /* Button being dragged with */
+static gint preview_thumbnail_w, preview_thumbnail_h;
+static gint preview_x, preview_y, preview_w, preview_h;
+
+static gint physical_orientation = -2; /* Actual orientation */
+
+static gint paper_width, paper_height; /* Physical width */
+static gint printable_width, printable_height; /* Size of printable area */
+static gint print_width, print_height; /* Printed area of image */
+static gint left, right, top, bottom; /* Imageable region */
+static gint image_width, image_height; /* Image size (possibly rotated) */
+static gint image_true_width, image_true_height; /* Original image */
+static gdouble image_xres, image_yres; /* Original image resolution */
+static gint do_update_thumbnail = 0;
+static gint saveme = 0; /* True if printrc should be saved */
+static gint runme = 0; /* True if print should proceed */
+static gint exit_after_file_ok = 0; /* True if we should exit after file browser complete */
+static gint auto_paper_size = 0; /* True if we're using auto paper size now */
+
+
+
+static void scaling_update (GtkAdjustment *adjustment);
+static void scaling_callback (GtkWidget *widget);
+static void plist_callback (GtkWidget *widget, gpointer data);
+static void queue_callback (GtkWidget *widget, gpointer data);
+static void custom_media_size_callback(GtkWidget *widget, gpointer data);
+static void show_all_paper_sizes_callback(GtkWidget *widget, gpointer data);
+static void auto_paper_size_callback(GtkWidget *widget, gpointer data);
+static void combo_callback (GtkWidget *widget, gpointer data);
+static void output_type_callback (GtkWidget *widget, gpointer data);
+static void unit_callback (GtkWidget *widget, gpointer data);
+static void orientation_callback (GtkWidget *widget, gpointer data);
+static void printandsave_callback (void);
+static void about_callback (void);
+static void print_callback (void);
+static void save_callback (void);
+static void setup_callback (GtkWidget *widget);
+
+static void setup_update (void);
+static void setup_open_callback (void);
+static void setup_ok_callback (void);
+static void setup_cancel_callback (void);
+static void new_printer_open_callback (void);
+static void new_printer_ok_callback (void);
+static void ppd_browse_callback (void);
+static void ppd_ok_callback (void);
+static void file_browse_callback (void);
+static void file_ok_callback (void);
+static void file_cancel_callback (void);
+static void build_printer_driver_clist(void);
+static void print_driver_callback (GtkWidget *widget,
+ gint row,
+ gint column,
+ GdkEventButton *event,
+ gpointer data);
+static void manufacturer_callback (GtkWidget *widget,
+ gint row,
+ gint column,
+ GdkEventButton *event,
+ gpointer data);
+static void command_type_callback (GtkWidget *widget, gpointer data);
+
+static void do_preview_thumbnail (void);
+static void invalidate_preview_thumbnail (void);
+static void invalidate_frame (void);
+
+static GtkWidget *color_adjust_dialog;
+
+static void preview_update (void);
+static void preview_expose (void);
+static void preview_button_callback (GtkWidget *widget,
+ GdkEventButton *bevent,
+ gpointer data);
+static void preview_motion_callback (GtkWidget *widget,
+ GdkEventMotion *mevent,
+ gpointer data);
+static void position_callback (GtkWidget *widget);
+static void position_button_callback (GtkWidget *widget,
+ gpointer data);
+static void copy_count_callback (GtkAdjustment *widget,
+ gpointer data);
+static void plist_build_combo(GtkWidget *combo,
+ GtkWidget *label,
+ stp_string_list_t *items,
+ int active,
+ const gchar *cur_item,
+ const gchar *def_value,
+ GCallback callback,
+ gint *callback_id,
+ int (*check_func)(const char *string),
+ gpointer data);
+static void initialize_thumbnail(void);
+static void set_color_defaults (void);
+static void redraw_color_swatch (void);
+static void color_update (GtkAdjustment *adjustment);
+static void dimension_update (GtkAdjustment *adjustment);
+static void set_controls_active (GtkObject *checkbutton, gpointer optno);
+static void update_adjusted_thumbnail (void);
+
+static void set_media_size(const gchar *new_media_size);
+static const stp_printer_t *tmp_printer = NULL;
+
+static option_t *current_options = NULL;
+static int current_option_count = 0;
+
+static unit_t units[] =
+ {
+ { N_("Inch"), N_("Set the base unit of measurement to inches"),
+ 72.0, NULL, "%.2f" },
+ { N_("cm"), N_("Set the base unit of measurement to centimetres"),
+ 72.0 / 2.54, NULL, "%.2f" },
+ { N_("Points"), N_("Set the base unit of measurement to points (1/72\")"),
+ 1.0, NULL, "%.0f" },
+ { N_("mm"), N_("Set the base unit of measurement to millimetres"),
+ 72.0 / 25.4, NULL, "%.1f" },
+ { N_("Pica"), N_("Set the base unit of measurement to picas (1/12\")"),
+ 72.0 / 12.0, NULL, "%.1f" },
+ };
+static const gint unit_count = sizeof(units) / sizeof(unit_t);
+
+static radio_group_t output_types[] =
+ {
+ { N_("Color"), N_("Color output"), "Color", NULL },
+ { N_("Grayscale"),
+ N_("Print in shades of gray using black ink"), "BW", NULL }
+ };
+
+static const gint output_type_count = (sizeof(output_types) /
+ sizeof(radio_group_t));
+
+/*
+ * The order of these entries must match the order in command_t in
+ * gutenprintui.h
+ */
+static radio_group_t command_options[] =
+ {
+ { N_("Standard Command"), N_("Use standard print command"), "Standard", NULL },
+ { N_("Custom Command"), N_("Use custom print command"), "Custom", NULL },
+ { N_("File"), N_("Print to a file"), "File", NULL }
+ };
+
+static const gint command_options_count = (sizeof(command_options) /
+ sizeof(radio_group_t));
+
+static gdouble preview_ppi = 10;
+
+static stp_string_list_t *printer_list = 0;
+static stpui_plist_t *pv;
+static const char *manufacturer = 0;
+
+static gint thumbnail_w, thumbnail_h, thumbnail_bpp;
+static guchar *thumbnail_data;
+static guchar *adjusted_thumbnail_data;
+static guchar *preview_thumbnail_data;
+
+static void
+set_stpui_curve_values(GtkWidget *gcurve, const stp_curve_t *seed)
+{
+ if (stp_curve_get_gamma(seed))
+ {
+ stpui_curve_set_gamma(STPUI_CURVE(gcurve), stp_curve_get_gamma(seed));
+ }
+ else
+ {
+ stp_curve_t *copy = stp_curve_create_copy(seed);
+ const float *fdata;
+ size_t count;
+ stp_curve_resample(copy, 256);
+ fdata = stp_curve_get_float_data(copy, &count);
+ stpui_curve_set_vector(STPUI_CURVE(gcurve), count, fdata);
+ stp_curve_destroy(copy);
+ }
+}
+
+static void
+set_stp_curve_values(GtkWidget *widget, option_t *opt)
+{
+ int i;
+ double lo, hi;
+ gfloat vector[256];
+ GtkWidget *gcurve = GTK_WIDGET(widget);
+ stp_curve_t *curve = stp_curve_create_copy(opt->info.curve.deflt);
+ stpui_curve_get_vector(STPUI_CURVE(gcurve), 256, vector);
+ stp_curve_get_bounds(opt->info.curve.deflt, &lo, &hi);
+ for (i = 0; i < 256; i++)
+ {
+ if (vector[i] > hi)
+ vector[i] = hi;
+ else if (vector[i] < lo)
+ vector[i] = lo;
+ }
+ switch (STPUI_CURVE(gcurve)->curve_type)
+ {
+ case STPUI_CURVE_TYPE_SPLINE:
+ stp_curve_set_interpolation_type(curve, STP_CURVE_TYPE_SPLINE);
+ break;
+ default:
+ stp_curve_set_interpolation_type(curve, STP_CURVE_TYPE_LINEAR);
+ break;
+ }
+ stp_curve_set_float_data(curve, 256, vector);
+ stp_set_curve_parameter(pv->v, opt->fast_desc->name, curve);
+ stp_curve_destroy(curve);
+}
+
+static int
+open_curve_editor(GtkObject *button, gpointer xopt)
+{
+ option_t *opt = (option_t *)xopt;
+ if (opt->info.curve.is_visible == FALSE)
+ {
+ GtkWidget *gcurve =
+ GTK_WIDGET(STPUI_GAMMA_CURVE(opt->info.curve.gamma_curve)->curve);
+ const stp_curve_t *seed =
+ stp_get_curve_parameter(pv->v, opt->fast_desc->name);
+ stp_curve_t *nseed = NULL;
+ if (!seed)
+ seed = opt->info.curve.deflt;
+ if (seed)
+ nseed = stp_curve_create_copy(seed);
+ gtk_widget_set_sensitive(GTK_WIDGET(opt->checkbox), FALSE);
+ gtk_widget_show(GTK_WIDGET(opt->info.curve.dialog));
+ set_stpui_curve_values(gcurve, seed);
+ opt->info.curve.is_visible = TRUE;
+ if (opt->info.curve.current)
+ stp_curve_destroy(opt->info.curve.current);
+ opt->info.curve.current = nseed;
+ invalidate_preview_thumbnail();
+ update_adjusted_thumbnail();
+ }
+/* gtk_window_activate_focus(GTK_WINDOW(opt->info.curve.dialog)); */
+ return 1;
+}
+
+static int
+set_default_curve_callback(GtkObject *button, gpointer xopt)
+{
+ option_t *opt = (option_t *)xopt;
+ GtkWidget *gcurve =
+ GTK_WIDGET(STPUI_GAMMA_CURVE(opt->info.curve.gamma_curve)->curve);
+ const stp_curve_t *seed = opt->info.curve.deflt;
+ set_stpui_curve_values(gcurve, seed);
+ set_stp_curve_values(gcurve, opt);
+ invalidate_preview_thumbnail();
+ update_adjusted_thumbnail();
+ return 1;
+}
+
+static int
+set_previous_curve_callback(GtkObject *button, gpointer xopt)
+{
+ option_t *opt = (option_t *)xopt;
+ GtkWidget *gcurve =
+ GTK_WIDGET(STPUI_GAMMA_CURVE(opt->info.curve.gamma_curve)->curve);
+ const stp_curve_t *seed = opt->info.curve.current;
+ if (!seed)
+ seed = opt->info.curve.deflt;
+ set_stpui_curve_values(gcurve, seed);
+ set_stp_curve_values(gcurve, opt);
+ invalidate_preview_thumbnail();
+ update_adjusted_thumbnail();
+ return 1;
+}
+
+static int
+set_curve_callback(GtkObject *button, gpointer xopt)
+{
+ option_t *opt = (option_t *)xopt;
+ GtkWidget *gcurve =
+ GTK_WIDGET(STPUI_GAMMA_CURVE(opt->info.curve.gamma_curve)->curve);
+ gtk_widget_hide(opt->info.curve.dialog);
+ gtk_widget_set_sensitive(GTK_WIDGET(opt->checkbox), TRUE);
+ opt->info.curve.is_visible = FALSE;
+ set_stp_curve_values(gcurve, opt);
+ if (opt->info.curve.current)
+ stp_curve_destroy(opt->info.curve.current);
+ opt->info.curve.current = NULL;
+ invalidate_preview_thumbnail();
+ update_adjusted_thumbnail();
+ return 1;
+}
+
+static gint
+curve_draw_callback(GtkWidget *widget, GdkEvent *event, gpointer xopt)
+{
+ option_t *opt = (option_t *)xopt;
+ switch (event->type)
+ {
+ case GDK_BUTTON_RELEASE:
+ set_stp_curve_values(widget, opt);
+ invalidate_preview_thumbnail();
+ update_adjusted_thumbnail();
+ break;
+ default:
+ break;
+ }
+ return 1;
+}
+
+static gint
+curve_type_changed(GtkWidget *widget, gpointer xopt)
+{
+ option_t *opt = (option_t *)xopt;
+ set_stp_curve_values(widget, opt);
+ invalidate_preview_thumbnail();
+ update_adjusted_thumbnail();
+ return 1;
+}
+
+static int
+cancel_curve_callback(GtkObject *button, gpointer xopt)
+{
+ option_t *opt = (option_t *)xopt;
+ if (opt->info.curve.is_visible)
+ {
+ stp_set_curve_parameter(pv->v, opt->fast_desc->name,
+ opt->info.curve.current);
+ stp_curve_destroy(opt->info.curve.current);
+ opt->info.curve.current = NULL;
+ gtk_widget_hide(opt->info.curve.dialog);
+ gtk_widget_set_sensitive(GTK_WIDGET(opt->checkbox), TRUE);
+ opt->info.curve.is_visible = FALSE;
+ invalidate_preview_thumbnail();
+ update_adjusted_thumbnail();
+ }
+ return 1;
+}
+
+static void
+stpui_create_curve(option_t *opt,
+ GtkTable *table,
+ gint column,
+ gint row,
+ const gchar *text,
+ const stp_curve_t *deflt,
+ gboolean is_optional)
+{
+ double lower, upper;
+ opt->checkbox = gtk_check_button_new();
+ gtk_table_attach(GTK_TABLE(table), opt->checkbox,
+ column, column + 1, row, row + 1,
+ GTK_EXPAND|GTK_FILL, GTK_FILL, 0, 0);
+ if (is_optional)
+ gtk_widget_show(opt->checkbox);
+ else
+ gtk_widget_hide(opt->checkbox);
+
+ opt->info.curve.label = gtk_label_new(text);
+ gtk_misc_set_alignment (GTK_MISC (opt->info.curve.label), 0.0, 0.5);
+ gtk_table_attach (GTK_TABLE (table), opt->info.curve.label,
+ column + 1, column + 2, row, row + 1,
+ GTK_FILL, GTK_FILL, 0, 0);
+ gtk_widget_show (opt->info.curve.label);
+
+ opt->info.curve.button = gtk_button_new_with_label(_("Edit Curve..."));
+ g_signal_connect(G_OBJECT(opt->info.curve.button), "clicked",
+ G_CALLBACK(open_curve_editor), opt);
+ gtk_table_attach (GTK_TABLE (table), opt->info.curve.button,
+ column + 2, column + 3, row, row + 1,
+ GTK_FILL, GTK_FILL, 0, 0);
+ gtk_widget_show(opt->info.curve.button);
+
+ opt->info.curve.dialog =
+ stpui_dialog_new(_(opt->fast_desc->text),
+ GTK_WIN_POS_MOUSE, TRUE,
+ _("Set Default"), set_default_curve_callback,
+ opt, NULL, NULL, FALSE, FALSE,
+ _("Restore Previous"), set_previous_curve_callback,
+ opt, NULL, NULL, FALSE, FALSE,
+ _("OK"), set_curve_callback,
+ opt, NULL, NULL, FALSE, FALSE,
+ _("Cancel"), cancel_curve_callback,
+ opt, NULL, NULL, FALSE, FALSE,
+ NULL);
+ opt->info.curve.gamma_curve = stpui_gamma_curve_new();
+ gtk_box_pack_start(GTK_BOX(GTK_DIALOG(opt->info.curve.dialog)->vbox),
+ opt->info.curve.gamma_curve, TRUE, TRUE, 0);
+ stp_curve_get_bounds(opt->info.curve.deflt, &lower, &upper);
+ stpui_curve_set_range
+ (STPUI_CURVE (STPUI_GAMMA_CURVE(opt->info.curve.gamma_curve)->curve),
+ 0.0, 1.0, lower, upper);
+ gtk_widget_set_usize
+ (GTK_WIDGET(STPUI_GAMMA_CURVE(opt->info.curve.gamma_curve)->curve), 256, 256);
+ gtk_widget_show(opt->info.curve.gamma_curve);
+
+ g_signal_connect
+ (G_OBJECT(STPUI_GAMMA_CURVE(opt->info.curve.gamma_curve)->curve),
+ "curve-type-changed", G_CALLBACK(curve_type_changed), opt);
+ g_signal_connect
+ (G_OBJECT(STPUI_GAMMA_CURVE(opt->info.curve.gamma_curve)->curve),
+ "event", G_CALLBACK(curve_draw_callback), opt);
+
+ if (opt->fast_desc->help)
+ {
+ stpui_set_help_data (opt->info.curve.label, opt->fast_desc->help);
+ stpui_set_help_data (opt->info.curve.button, opt->fast_desc->help);
+ stpui_set_help_data (opt->info.curve.gamma_curve, opt->fast_desc->help);
+ }
+}
+
+static int
+checkbox_callback(GtkObject *button, gpointer xopt)
+{
+ option_t *opt = (option_t *)xopt;
+ GtkWidget *checkbox = GTK_WIDGET(opt->info.bool.checkbox);
+ opt->info.bool.current =
+ gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(checkbox));
+ stp_set_boolean_parameter(pv->v, opt->fast_desc->name,
+ opt->info.bool.current);
+ invalidate_frame();
+ invalidate_preview_thumbnail();
+ if (opt->fast_desc->p_class == STP_PARAMETER_CLASS_OUTPUT)
+ update_adjusted_thumbnail();
+ preview_update();
+ return 1;
+}
+
+static int
+print_mode_is_color(const stp_vars_t *v)
+{
+ const char *printing_mode = stp_get_string_parameter(v, "PrintingMode");
+ if (!printing_mode)
+ {
+ int answer = 1;
+ stp_parameter_t desc;
+ stp_describe_parameter(v, "PrintingMode", &desc);
+ if (desc.p_type == STP_PARAMETER_TYPE_STRING_LIST &&
+ strcmp(desc.deflt.str, "BW") == 0)
+ answer = 0;
+ stp_parameter_description_destroy(&desc);
+ return answer;
+ }
+ if (strcmp(printing_mode, "BW") == 0)
+ return 0;
+ else
+ return 1;
+}
+
+static void
+set_current_printer(void)
+{
+ pv = &(stpui_plist[stpui_plist_current]);
+ if (print_mode_is_color(pv->v))
+ stp_set_string_parameter(pv->v, "PrintingMode", "Color");
+ else
+ stp_set_string_parameter(pv->v, "PrintingMode", "BW");
+}
+
+
+static void
+stpui_create_boolean(option_t *opt,
+ GtkTable *table,
+ gint column,
+ gint row,
+ const gchar *text,
+ int deflt,
+ gboolean is_optional)
+{
+ opt->checkbox = gtk_check_button_new();
+ gtk_table_attach(GTK_TABLE(table), opt->checkbox,
+ column, column + 1, row, row + 1,
+ GTK_EXPAND|GTK_FILL, GTK_FILL, 0, 0);
+ if (is_optional)
+ gtk_widget_show(opt->checkbox);
+ else
+ gtk_widget_hide(opt->checkbox);
+
+ opt->info.bool.checkbox =
+ gtk_toggle_button_new_with_label(_(opt->fast_desc->text));
+ gtk_table_attach(GTK_TABLE(table), opt->info.bool.checkbox,
+ column + 1, column + 3, row, row + 1,
+ GTK_EXPAND|GTK_FILL, GTK_FILL, 0, 0);
+ gtk_widget_show(opt->info.bool.checkbox);
+ gtk_toggle_button_set_active
+ (GTK_TOGGLE_BUTTON(opt->info.bool.checkbox),
+ stp_get_boolean_parameter(pv->v, opt->fast_desc->name));
+ g_signal_connect(G_OBJECT(opt->info.bool.checkbox), "toggled",
+ G_CALLBACK(checkbox_callback), opt);
+}
+
+static void
+build_queue_combo(void)
+{
+ plist_build_combo(queue_combo,
+ NULL,
+ stpui_system_print_queues,
+ 1,
+ stpui_plist_get_queue_name(pv),
+ NULL,
+ G_CALLBACK(queue_callback),
+ &queue_callback_id,
+ NULL,
+ NULL);
+}
+
+static void
+build_printer_combo(void)
+{
+ int i;
+ if (printer_list)
+ stp_string_list_destroy(printer_list);
+ printer_list = stp_string_list_create();
+ for (i = 0; i < stpui_plist_count; i++)
+ stp_string_list_add_string(printer_list,
+ stpui_plist[i].name, stpui_plist[i].name);
+ plist_build_combo(printer_combo,
+ NULL,
+ printer_list,
+ 1,
+ stp_string_list_param(printer_list, stpui_plist_current)->name,
+ NULL,
+ G_CALLBACK(plist_callback),
+ &plist_callback_id,
+ NULL,
+ NULL);
+}
+
+static int
+check_page_size(const char *paper_size)
+{
+ const stp_papersize_t *ps = stp_get_papersize_by_name(paper_size);
+ if (ps && (ps->paper_unit == PAPERSIZE_ENGLISH_STANDARD ||
+ ps->paper_unit == PAPERSIZE_METRIC_STANDARD))
+ return 1;
+ else
+ return 0;
+}
+
+static void
+build_page_size_combo(option_t *option)
+{
+ /*
+ * Some printers don't support any "standard" page sizes. If the number
+ * of page sizes is small, just display all of them.
+ */
+ if (stpui_show_all_paper_sizes ||
+ stp_string_list_count(option->info.list.params) < 10)
+ plist_build_combo(option->info.list.combo, option->info.list.label,
+ option->info.list.params, option->is_active,
+ stp_get_string_parameter(pv->v, option->fast_desc->name),
+ option->info.list.default_val,G_CALLBACK(combo_callback),
+ &(option->info.list.callback_id), NULL, option);
+ else
+ plist_build_combo(option->info.list.combo, option->info.list.label,
+ option->info.list.params, option->is_active,
+ stp_get_string_parameter(pv->v, option->fast_desc->name),
+ option->info.list.default_val,G_CALLBACK(combo_callback),
+ &(option->info.list.callback_id),
+ check_page_size, option);
+}
+
+static void
+build_a_combo(option_t *option)
+{
+ const gchar *new_value;
+ stp_parameter_activity_t active;
+ if (option->fast_desc &&
+ option->fast_desc->p_type == STP_PARAMETER_TYPE_STRING_LIST)
+ {
+ const gchar *val = stp_get_string_parameter(pv->v,
+ option->fast_desc->name);
+ if (option->info.list.params == NULL || ! option->is_active ||
+ stp_string_list_count(option->info.list.params) == 0)
+ stp_set_string_parameter(pv->v, option->fast_desc->name, NULL);
+ else if (!val || strlen(val) == 0 ||
+ ! stp_string_list_is_present(option->info.list.params, val))
+ stp_set_string_parameter(pv->v, option->fast_desc->name,
+ option->info.list.default_val);
+ if (strcmp(option->fast_desc->name, "PageSize") == 0)
+ build_page_size_combo(option);
+ else
+ plist_build_combo(option->info.list.combo, option->info.list.label,
+ option->info.list.params,
+ option->is_active,
+ stp_get_string_parameter(pv->v,
+ option->fast_desc->name),
+ option->info.list.default_val, G_CALLBACK(combo_callback),
+ &(option->info.list.callback_id), NULL, option);
+ if (strcmp(option->fast_desc->name, "PageSize") == 0)
+ set_media_size
+ (stp_get_string_parameter(pv->v, option->fast_desc->name));
+ }
+ else
+ plist_build_combo(option->info.list.combo, option->info.list.label,
+ NULL, 0, "", "", G_CALLBACK(combo_callback),
+ &(option->info.list.callback_id), NULL, option);
+ new_value =
+ stpui_combo_get_name(option->info.list.combo, option->info.list.params);
+ active = stp_get_string_parameter_active(pv->v, option->fast_desc->name);
+ stp_set_string_parameter(pv->v, option->fast_desc->name, new_value);
+ stp_set_string_parameter_active(pv->v, option->fast_desc->name, active);
+}
+
+static void
+populate_options(const stp_vars_t *v)
+{
+ stp_parameter_list_t params = stp_get_parameter_list(v);
+ int i;
+ int idx;
+ if (current_options)
+ {
+ for (i = 0; i < current_option_count; i++)
+ {
+ option_t *opt = &(current_options[i]);
+ switch (opt->fast_desc->p_type)
+ {
+ case STP_PARAMETER_TYPE_STRING_LIST:
+ if (opt->info.list.combo)
+ {
+ gtk_widget_destroy(opt->info.list.combo);
+ gtk_widget_destroy(opt->info.list.label);
+ if (opt->info.list.params)
+ stp_string_list_destroy(opt->info.list.params);
+ g_free(opt->info.list.default_val);
+ }
+ break;
+ case STP_PARAMETER_TYPE_DOUBLE:
+ case STP_PARAMETER_TYPE_DIMENSION:
+ if (opt->info.flt.adjustment)
+ {
+ gtk_widget_destroy
+ (GTK_WIDGET
+ (SCALE_ENTRY_SCALE(opt->info.flt.adjustment)));
+ gtk_widget_destroy
+ (GTK_WIDGET
+ (SCALE_ENTRY_LABEL(opt->info.flt.adjustment)));
+ gtk_widget_destroy
+ (GTK_WIDGET
+ (SCALE_ENTRY_SPINBUTTON(opt->info.flt.adjustment)));
+ }
+ break;
+ case STP_PARAMETER_TYPE_CURVE:
+ gtk_widget_destroy(GTK_WIDGET(opt->info.curve.label));
+ gtk_widget_destroy(GTK_WIDGET(opt->info.curve.button));
+ gtk_widget_destroy(GTK_WIDGET(opt->info.curve.dialog));
+ if (opt->info.curve.current)
+ stp_curve_destroy(opt->info.curve.current);
+ break;
+ case STP_PARAMETER_TYPE_BOOLEAN:
+ gtk_widget_destroy(GTK_WIDGET(opt->info.bool.checkbox));
+ break;
+ default:
+ break;
+ }
+ if (opt->checkbox)
+ gtk_widget_destroy(GTK_WIDGET(opt->checkbox));
+ }
+ g_free(current_options);
+ }
+ current_option_count = stp_parameter_list_count(params);
+ current_options = g_malloc(sizeof(option_t) * current_option_count);
+
+ for (idx = 0, i = 0; i < current_option_count; i++)
+ {
+ stp_parameter_t desc;
+ const stp_parameter_t *param = stp_parameter_list_param(params, i);
+ if (!param->read_only &&
+ (param->p_class == STP_PARAMETER_CLASS_OUTPUT ||
+ param->p_class == STP_PARAMETER_CLASS_FEATURE ||
+ (param->p_class == STP_PARAMETER_CLASS_CORE &&
+ strcmp(param->name, "PageSize") == 0)))
+ {
+ option_t *opt = &(current_options[idx]);
+ opt->fast_desc = stp_parameter_list_param(params, i);
+ stp_describe_parameter(v, opt->fast_desc->name, &desc);
+ opt->checkbox = NULL;
+ opt->is_active = 0;
+ opt->is_enabled = 0;
+ switch (opt->fast_desc->p_type)
+ {
+ case STP_PARAMETER_TYPE_STRING_LIST:
+ opt->info.list.callback_id = -1;
+ opt->info.list.default_val = g_strdup(desc.deflt.str);
+ if (desc.bounds.str)
+ opt->info.list.params =
+ stp_string_list_create_copy(desc.bounds.str);
+ else
+ opt->info.list.params = NULL;
+ opt->info.list.combo = NULL;
+ opt->info.list.label = NULL;
+ opt->is_active = desc.is_active;
+ break;
+ case STP_PARAMETER_TYPE_DOUBLE:
+ opt->info.flt.adjustment = NULL;
+ opt->info.flt.upper = desc.bounds.dbl.upper;
+ opt->info.flt.lower = desc.bounds.dbl.lower;
+ opt->info.flt.deflt = desc.deflt.dbl;
+ opt->info.flt.scale = 1.0;
+ opt->is_active = desc.is_active;
+ break;
+ case STP_PARAMETER_TYPE_DIMENSION:
+ opt->info.flt.adjustment = NULL;
+ opt->info.flt.upper = desc.bounds.dimension.upper;
+ opt->info.flt.lower = desc.bounds.dimension.lower;
+ opt->info.flt.deflt = desc.deflt.dimension;
+ opt->info.flt.scale = 1.0;
+ opt->is_active = desc.is_active;
+ break;
+ case STP_PARAMETER_TYPE_CURVE:
+ opt->info.curve.label = NULL;
+ opt->info.curve.button = NULL;
+ opt->info.curve.dialog = NULL;
+ opt->info.curve.gamma_curve = NULL;
+ opt->info.curve.current = NULL;
+ opt->info.curve.deflt = desc.deflt.curve;
+ opt->info.curve.is_visible = FALSE;
+ opt->is_active = desc.is_active;
+ break;
+ case STP_PARAMETER_TYPE_BOOLEAN:
+ opt->info.bool.checkbox = NULL;
+ opt->info.bool.current = 0;
+ opt->info.bool.deflt = desc.deflt.boolean;
+ opt->is_active = desc.is_active;
+ default:
+ break;
+ }
+ idx++;
+ stp_parameter_description_destroy(&desc);
+ }
+ }
+ current_option_count = idx;
+ stp_parameter_list_destroy(params);
+}
+
+static void
+populate_option_table(GtkWidget *table, int p_class)
+{
+ int i, j;
+ int current_pos = 0;
+ int counts[STP_PARAMETER_LEVEL_INVALID][STP_PARAMETER_TYPE_INVALID];
+ int vpos[STP_PARAMETER_LEVEL_INVALID][STP_PARAMETER_TYPE_INVALID];
+ for (i = 0; i < STP_PARAMETER_LEVEL_INVALID; i++)
+ for (j = 0; j < STP_PARAMETER_TYPE_INVALID; j++)
+ {
+ vpos[i][j] = 0;
+ counts[i][j] = 0;
+ }
+
+
+ /* First scan the options to figure out where to start */
+ for (i = 0; i < current_option_count; i++)
+ {
+ const stp_parameter_t *desc = current_options[i].fast_desc;
+ /*
+ * Specialize the core parameters (page size is the only one we want)
+ * Yuck.
+ */
+ if (!desc->read_only && desc->p_class == p_class &&
+ (desc->p_class != STP_PARAMETER_CLASS_CORE ||
+ strcmp(desc->name, "PageSize") == 0))
+ {
+ switch (desc->p_type)
+ {
+ case STP_PARAMETER_TYPE_STRING_LIST:
+ case STP_PARAMETER_TYPE_DIMENSION:
+ case STP_PARAMETER_TYPE_DOUBLE:
+ case STP_PARAMETER_TYPE_CURVE:
+ case STP_PARAMETER_TYPE_BOOLEAN:
+ counts[desc->p_level][desc->p_type]++;
+ break;
+ default:
+ break;
+ }
+ }
+ }
+
+ /* Now, figure out where we're going to put the options */
+ for (i = 0; i < STP_PARAMETER_LEVEL_INVALID; i++)
+ {
+ int level_count = 0;
+ for (j = 0; j < STP_PARAMETER_TYPE_INVALID; j++)
+ level_count += counts[i][j];
+ if (level_count > 0 && current_pos > 0)
+ {
+ GtkWidget *sep = gtk_hseparator_new();
+ gtk_table_attach (GTK_TABLE(table), sep, 0, 4,
+ current_pos, current_pos + 1,
+ GTK_EXPAND|GTK_FILL, GTK_FILL, 0, 0);
+ if (i <= MAXIMUM_PARAMETER_LEVEL)
+ gtk_widget_show(sep);
+ current_pos++;
+ }
+ for (j = 0; j < STP_PARAMETER_TYPE_INVALID; j++)
+ {
+ vpos[i][j] = current_pos;
+ current_pos += counts[i][j];
+ }
+ }
+
+ for (i = 0; i < current_option_count; i++)
+ {
+ option_t *opt = &(current_options[i]);
+ const stp_curve_t *xcurve;
+ const stp_parameter_t *desc = opt->fast_desc;
+ if (!desc->read_only && desc->p_class == p_class &&
+ (desc->p_class != STP_PARAMETER_CLASS_CORE ||
+ strcmp(desc->name, "PageSize") == 0))
+ {
+ gdouble unit_scaler;
+ gdouble minor_increment;
+ gint digits;
+ switch (desc->p_type)
+ {
+ case STP_PARAMETER_TYPE_STRING_LIST:
+ stpui_create_new_combo(opt, table, 0,
+ vpos[desc->p_level][desc->p_type]++,
+ !(desc->is_mandatory));
+ if (desc->p_level > MAXIMUM_PARAMETER_LEVEL)
+ stp_set_string_parameter_active(pv->v, desc->name,
+ STP_PARAMETER_INACTIVE);
+ break;
+ case STP_PARAMETER_TYPE_DOUBLE:
+ stpui_create_scale_entry(opt, GTK_TABLE(table), 0,
+ vpos[desc->p_level][desc->p_type]++,
+ _(desc->text), 200, 0,
+ opt->info.flt.deflt,
+ opt->info.flt.lower,
+ opt->info.flt.upper,
+ .001, .01, 3, TRUE, 0, 0, NULL,
+ !(desc->is_mandatory));
+ stpui_set_adjustment_tooltip(opt->info.flt.adjustment,
+ _(desc->help));
+ g_signal_connect(G_OBJECT(opt->info.flt.adjustment),
+ "value_changed",
+ G_CALLBACK(color_update), opt);
+ if (desc->p_level > MAXIMUM_PARAMETER_LEVEL)
+ stp_set_float_parameter_active(pv->v, desc->name,
+ STP_PARAMETER_INACTIVE);
+ break;
+ case STP_PARAMETER_TYPE_DIMENSION:
+ unit_scaler = units[pv->unit].scale;
+ if (unit_scaler > 100)
+ {
+ digits = 3;
+ minor_increment = .001;
+ }
+ else if (unit_scaler > 10)
+ {
+ digits = 2;
+ minor_increment = .01;
+ }
+ else if (unit_scaler > 1)
+ {
+ digits = 1;
+ minor_increment = .1;
+ }
+ else
+ {
+ digits = 0;
+ minor_increment = 1;
+ }
+ stpui_create_scale_entry(opt, GTK_TABLE(table), 0,
+ vpos[desc->p_level][desc->p_type]++,
+ _(desc->text), 200, 0,
+ opt->info.flt.deflt / unit_scaler,
+ opt->info.flt.lower / unit_scaler,
+ opt->info.flt.upper / unit_scaler,
+ minor_increment, minor_increment * 10,
+ digits, TRUE, 0, 0, NULL,
+ !(desc->is_mandatory));
+ stpui_set_adjustment_tooltip(opt->info.flt.adjustment,
+ _(desc->help));
+ g_signal_connect(G_OBJECT(opt->info.flt.adjustment),
+ "value_changed",
+ G_CALLBACK(dimension_update), opt);
+ if (desc->p_level > MAXIMUM_PARAMETER_LEVEL)
+ stp_set_dimension_parameter_active(pv->v, desc->name,
+ STP_PARAMETER_INACTIVE);
+ break;
+ case STP_PARAMETER_TYPE_CURVE:
+ xcurve = stp_get_curve_parameter(pv->v, opt->fast_desc->name);
+ if (xcurve)
+ opt->info.curve.current = stp_curve_create_copy(xcurve);
+ else
+ opt->info.curve.current = NULL;
+ stpui_create_curve(opt, GTK_TABLE(table), 0,
+ vpos[desc->p_level][desc->p_type]++,
+ _(desc->text), opt->info.curve.deflt,
+ !(desc->is_mandatory));
+ if (desc->p_level > MAXIMUM_PARAMETER_LEVEL)
+ stp_set_curve_parameter_active(pv->v, desc->name,
+ STP_PARAMETER_INACTIVE);
+ break;
+ case STP_PARAMETER_TYPE_BOOLEAN:
+ opt->info.bool.current =
+ stp_get_boolean_parameter(pv->v, opt->fast_desc->name);
+ stpui_create_boolean(opt, GTK_TABLE(table), 0,
+ vpos[desc->p_level][desc->p_type]++,
+ _(desc->text), opt->info.bool.deflt,
+ !(desc->is_mandatory));
+ if (desc->p_level > MAXIMUM_PARAMETER_LEVEL)
+ stp_set_boolean_parameter_active(pv->v, desc->name,
+ STP_PARAMETER_INACTIVE);
+ break;
+ case STP_PARAMETER_TYPE_INT:
+ stp_set_int_parameter_active(pv->v, opt->fast_desc->name,
+ STP_PARAMETER_INACTIVE);
+ break;
+ case STP_PARAMETER_TYPE_RAW:
+ stp_set_raw_parameter_active(pv->v, opt->fast_desc->name,
+ STP_PARAMETER_INACTIVE);
+ break;
+ case STP_PARAMETER_TYPE_FILE:
+ if (strcmp(opt->fast_desc->name, "PPDFile") != 0)
+ stp_set_file_parameter_active(pv->v, opt->fast_desc->name,
+ STP_PARAMETER_INACTIVE);
+ break;
+ default:
+ break;
+ }
+ if (opt->checkbox)
+ g_signal_connect
+ (G_OBJECT(opt->checkbox), "toggled",
+ G_CALLBACK(set_controls_active), opt);
+ }
+ }
+}
+
+static void
+set_options_active(const char *omit)
+{
+ int i;
+ for (i = 0; i < current_option_count; i++)
+ {
+ option_t *opt = &(current_options[i]);
+ const stp_parameter_t *desc = opt->fast_desc;
+ GtkObject *adj;
+ if (omit && strcmp(omit, opt->fast_desc->name) == 0)
+ continue;
+ switch (desc->p_type)
+ {
+ case STP_PARAMETER_TYPE_STRING_LIST:
+ build_a_combo(opt);
+ break;
+ case STP_PARAMETER_TYPE_DOUBLE:
+ case STP_PARAMETER_TYPE_DIMENSION:
+ adj = opt->info.flt.adjustment;
+ if (adj)
+ {
+ if (opt->is_active && desc->p_level <= MAXIMUM_PARAMETER_LEVEL)
+ {
+ gtk_widget_show(GTK_WIDGET(SCALE_ENTRY_LABEL(adj)));
+ gtk_widget_show(GTK_WIDGET(SCALE_ENTRY_SCALE(adj)));
+ gtk_widget_show(GTK_WIDGET(SCALE_ENTRY_SPINBUTTON(adj)));
+ }
+ else
+ {
+ gtk_widget_hide(GTK_WIDGET(SCALE_ENTRY_LABEL(adj)));
+ gtk_widget_hide(GTK_WIDGET(SCALE_ENTRY_SCALE(adj)));
+ gtk_widget_hide(GTK_WIDGET(SCALE_ENTRY_SPINBUTTON(adj)));
+ }
+ }
+ break;
+ case STP_PARAMETER_TYPE_CURVE:
+ if (opt->is_active && desc->p_level <= MAXIMUM_PARAMETER_LEVEL)
+ {
+ gtk_widget_show(GTK_WIDGET(opt->info.curve.label));
+ gtk_widget_show(GTK_WIDGET(opt->info.curve.button));
+ }
+ else
+ {
+ gtk_widget_hide(GTK_WIDGET(opt->info.curve.label));
+ gtk_widget_hide(GTK_WIDGET(opt->info.curve.button));
+ gtk_widget_hide(GTK_WIDGET(opt->info.curve.dialog));
+ }
+ case STP_PARAMETER_TYPE_BOOLEAN:
+ if (opt->is_active && desc->p_level <= MAXIMUM_PARAMETER_LEVEL)
+ {
+ gtk_widget_show(GTK_WIDGET(opt->info.bool.checkbox));
+ }
+ else
+ {
+ gtk_widget_hide(GTK_WIDGET(opt->info.bool.checkbox));
+ }
+ break;
+ default:
+ break;
+ }
+ if (opt->checkbox)
+ {
+ if (!(opt->is_active) || desc->p_level > MAXIMUM_PARAMETER_LEVEL)
+ gtk_widget_hide(GTK_WIDGET(opt->checkbox));
+ else if (!(desc->is_mandatory))
+ gtk_widget_show(GTK_WIDGET(opt->checkbox));
+ }
+ }
+}
+
+static void
+color_button_callback(GtkWidget *widget, gpointer data)
+{
+ invalidate_preview_thumbnail();
+ update_adjusted_thumbnail();
+}
+
+static void
+create_top_level_structure(void)
+{
+ gchar *plug_in_name;
+ /*
+ * Create the main dialog
+ */
+
+ plug_in_name = g_strdup_printf (_("%s -- Print v%s"),
+ stpui_get_image_filename(),
+ VERSION " - " RELEASE_DATE);
+
+ print_dialog =
+ stpui_dialog_new (plug_in_name,
+ GTK_WIN_POS_MOUSE,
+ TRUE,
+
+ _("About"), about_callback,
+ NULL, NULL, NULL, FALSE, FALSE,
+ _("Print and\nSave Settings"), printandsave_callback,
+ NULL, NULL, NULL, FALSE, FALSE,
+ _("Save\nSettings"), save_callback,
+ NULL, NULL, NULL, FALSE, FALSE,
+ _("Print"), print_callback,
+ NULL, NULL, NULL, FALSE, FALSE,
+ _("Cancel"), gtk_widget_destroy,
+ NULL, (GObject *) 1, NULL, FALSE, TRUE,
+
+ NULL);
+
+ g_free (plug_in_name);
+
+ g_signal_connect (G_OBJECT (print_dialog), "destroy",
+ G_CALLBACK (gtk_main_quit), NULL);
+
+ /*
+ * Top-level containers
+ */
+
+ main_vbox = gtk_vbox_new (FALSE, 2);
+ gtk_container_set_border_width (GTK_CONTAINER (main_vbox), 6);
+ gtk_box_pack_start (GTK_BOX (GTK_DIALOG (print_dialog)->vbox), main_vbox,
+ TRUE, TRUE, 0);
+ gtk_widget_show (main_vbox);
+
+ main_hbox = gtk_hbox_new (FALSE, 4);
+ gtk_box_pack_start (GTK_BOX (main_vbox), main_hbox, TRUE, TRUE, 0);
+ gtk_widget_show (main_hbox);
+
+ right_vbox = gtk_vbox_new (FALSE, 2);
+ gtk_box_pack_end (GTK_BOX (main_hbox), right_vbox, FALSE, FALSE, 0);
+ gtk_widget_show (right_vbox);
+
+ notebook = gtk_notebook_new ();
+ gtk_box_pack_start (GTK_BOX (right_vbox), notebook, TRUE, TRUE, 0);
+ gtk_widget_show (notebook);
+}
+
+static gint
+drawing_area_resize_callback(GtkWidget *widget, GdkEventConfigure *event)
+{
+ preview_size_vert = event->height - 1;
+ preview_size_horiz = event->width - 1;
+ invalidate_preview_thumbnail();
+ invalidate_frame();
+ preview_update();
+ return 1;
+}
+
+static void
+create_preview (void)
+{
+ GtkWidget *frame;
+ GtkWidget *event_box;
+
+ frame = gtk_frame_new (_("Preview"));
+ gtk_box_pack_start (GTK_BOX (main_hbox), frame, TRUE, TRUE, 0);
+ gtk_widget_show (frame);
+
+ preview = (GtkDrawingArea *) gtk_drawing_area_new ();
+ gtk_drawing_area_size(preview, preview_size_horiz + 1, preview_size_vert +1);
+ g_signal_connect(G_OBJECT(preview), "configure_event",
+ G_CALLBACK(drawing_area_resize_callback), NULL);
+ event_box = gtk_event_box_new ();
+ gtk_container_add (GTK_CONTAINER (event_box), GTK_WIDGET (preview));
+ gtk_container_add (GTK_CONTAINER (frame), event_box);
+ gtk_widget_show (event_box);
+
+ g_signal_connect (G_OBJECT (preview), "expose_event",
+ G_CALLBACK (preview_expose), NULL);
+ g_signal_connect (G_OBJECT (preview), "button_press_event",
+ G_CALLBACK (preview_button_callback), NULL);
+ g_signal_connect (G_OBJECT (preview), "button_release_event",
+ G_CALLBACK (preview_button_callback), NULL);
+ g_signal_connect (G_OBJECT (preview), "motion_notify_event",
+ G_CALLBACK (preview_motion_callback), NULL);
+ gtk_widget_show (GTK_WIDGET (preview));
+
+ stpui_set_help_data
+ (event_box,
+ _("Position the image on the page.\n"
+ "Click and drag with the primary button to position the image.\n"
+ "Click and drag with the second button to move the image with finer precision; "
+ "each unit of motion moves the image one point (1/72\")\n"
+ "Click and drag with the third (middle) button to move the image in units of "
+ "the image size.\n"
+ "Holding down the shift key while clicking and dragging constrains the image to "
+ "only horizontal or vertical motion.\n"
+ "If you click another button while dragging the mouse, the image will return "
+ "to its original position."));
+
+ gtk_widget_set_events (GTK_WIDGET (preview),
+ GDK_EXPOSURE_MASK | GDK_BUTTON_MOTION_MASK |
+ GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK);
+}
+
+static GtkWidget *
+create_positioning_entry(GtkWidget *table, int hpos, int vpos,
+ const char *text, const char *help)
+{
+ return stpui_create_entry
+ (table, hpos, vpos, text, help, G_CALLBACK(position_callback));
+}
+
+static GtkWidget *
+create_positioning_button(GtkWidget *box, int invalid,
+ const char *text, const char *help)
+{
+ GtkWidget *button = gtk_button_new_with_label(_(text));
+ gtk_box_pack_start(GTK_BOX(box), button, FALSE, TRUE, 0);
+ gtk_widget_show(button);
+ stpui_set_help_data(button, help);
+ g_signal_connect(G_OBJECT(button), "clicked",
+ G_CALLBACK(position_button_callback),
+ (gpointer) invalid);
+ return button;
+}
+
+static void
+create_paper_size_frame(void)
+{
+ GtkWidget *frame;
+ GtkWidget *vbox;
+ GtkWidget *media_size_table;
+ GtkWidget *table;
+ int vpos = 0;
+
+ frame = gtk_frame_new (_("Paper Size"));
+ gtk_box_pack_start (GTK_BOX (right_vbox), frame, FALSE, TRUE, 0);
+ gtk_widget_show (frame);
+
+ vbox = gtk_vbox_new (FALSE, 2);
+ gtk_container_set_border_width (GTK_CONTAINER (vbox), 4);
+ gtk_container_add (GTK_CONTAINER (frame), vbox);
+ gtk_widget_show (vbox);
+
+ table = gtk_table_new (1, 1, FALSE);
+ gtk_container_add (GTK_CONTAINER (vbox), table);
+ gtk_widget_show (table);
+
+ /*
+ * Media size combo box.
+ */
+
+ page_size_table = gtk_table_new(1, 1, FALSE);
+ gtk_widget_show (page_size_table);
+ gtk_table_attach_defaults(GTK_TABLE(table), page_size_table,
+ 0, 2, vpos, vpos + 1);
+ vpos++;
+ show_all_paper_sizes_button =
+ gtk_check_button_new_with_label(_("Show All Paper Sizes"));
+ gtk_table_attach_defaults
+ (GTK_TABLE(table), show_all_paper_sizes_button, 0, 2, vpos, vpos + 1);
+ gtk_toggle_button_set_active
+ (GTK_TOGGLE_BUTTON(show_all_paper_sizes_button),
+ stpui_show_all_paper_sizes);
+ g_signal_connect(G_OBJECT(show_all_paper_sizes_button), "toggled",
+ G_CALLBACK(show_all_paper_sizes_callback), NULL);
+ gtk_widget_show(show_all_paper_sizes_button);
+ vpos++;
+
+ /*
+ * Custom media size entries
+ */
+
+ media_size_table = gtk_table_new (1, 1, FALSE);
+ stpui_table_attach_aligned(GTK_TABLE (table), 0, vpos++, _("Dimensions:"),
+ 0.0, 0.5, media_size_table, 1, TRUE);
+ gtk_table_set_col_spacings (GTK_TABLE (media_size_table), 4);
+
+ custom_size_width = stpui_create_entry
+ (media_size_table, 0, 3, _("Width:"),
+ _("Width of the paper that you wish to print to"),
+ G_CALLBACK(custom_media_size_callback));
+
+ custom_size_height = stpui_create_entry
+ (media_size_table, 2, 3, _("Height:"),
+ _("Height of the paper that you wish to print to"),
+ G_CALLBACK(custom_media_size_callback));
+
+ vpos++;
+ auto_paper_size_button =
+ gtk_check_button_new_with_label(_("Automatic Paper Size"));
+ gtk_table_attach_defaults
+ (GTK_TABLE(table), auto_paper_size_button, 0, 2, vpos, vpos + 1);
+ gtk_toggle_button_set_active
+ (GTK_TOGGLE_BUTTON(auto_paper_size_button), FALSE);
+ g_signal_connect(G_OBJECT(auto_paper_size_button), "toggled",
+ G_CALLBACK(auto_paper_size_callback), NULL);
+}
+
+static void
+create_copy_number_frame(void)
+{
+ GtkWidget *frame;
+ GtkWidget *vbox;
+ GtkWidget *event_box;
+ GtkAdjustment *adj;
+
+ frame = gtk_frame_new (_("Number of Copies"));
+ gtk_box_pack_start (GTK_BOX (right_vbox), frame, FALSE, TRUE, 0);
+ gtk_widget_show (frame);
+
+ vbox = gtk_hbox_new (FALSE, 2);
+ gtk_container_set_border_width (GTK_CONTAINER (vbox), 4);
+ gtk_container_add (GTK_CONTAINER (frame), vbox);
+ gtk_widget_show (vbox);
+
+ event_box = gtk_event_box_new ();
+ gtk_container_add (GTK_CONTAINER (vbox), event_box);
+ stpui_set_help_data(event_box,
+ _("Select the number of copies to print; "
+ "a value between 1 and 100"));
+ gtk_widget_show (event_box);
+
+ /*
+ * Number of Copies Spin Button
+ */
+
+ adj = (GtkAdjustment *) gtk_adjustment_new (1.0f, 1.0f, 100.0f,
+ 1.0f, 5.0f, 0.0f);
+ copy_count_spin_button = gtk_spin_button_new (adj, 0, 0);
+ gtk_spin_button_set_wrap (GTK_SPIN_BUTTON (copy_count_spin_button), FALSE);
+ gtk_spin_button_set_numeric (GTK_SPIN_BUTTON (copy_count_spin_button), TRUE);
+ gtk_spin_button_set_update_policy (GTK_SPIN_BUTTON (copy_count_spin_button),
+ GTK_UPDATE_IF_VALID);
+
+ g_signal_connect(G_OBJECT (adj), "value_changed",
+ G_CALLBACK (copy_count_callback),
+ NULL);
+
+ gtk_container_add (GTK_CONTAINER (event_box), copy_count_spin_button);
+ gtk_widget_show(copy_count_spin_button);
+}
+
+static void
+create_positioning_frame (void)
+{
+ GtkWidget *frame;
+ GtkWidget *table;
+ GtkWidget *box;
+ GtkWidget *sep;
+
+ frame = gtk_frame_new (_("Image Position"));
+ gtk_box_pack_start (GTK_BOX (right_vbox), frame, FALSE, TRUE, 0);
+ gtk_widget_show (frame);
+
+ table = gtk_table_new (1, 1, FALSE);
+ gtk_table_set_col_spacings (GTK_TABLE (table), 2);
+ gtk_table_set_row_spacings (GTK_TABLE (table), 2);
+ gtk_container_set_border_width (GTK_CONTAINER (table), 4);
+ gtk_container_add (GTK_CONTAINER (frame), table);
+ gtk_widget_show (table);
+
+ /*
+ * Orientation option menu.
+ */
+
+ orientation_menu =
+ stpui_option_menu_new (FALSE,
+ _("Auto"), orientation_callback,
+ (gpointer) ORIENT_AUTO, NULL, NULL, 0,
+ _("Portrait"), orientation_callback,
+ (gpointer) ORIENT_PORTRAIT, NULL, NULL, 0,
+ _("Landscape"), orientation_callback,
+ (gpointer) ORIENT_LANDSCAPE, NULL, NULL, 0,
+ _("Upside down"), orientation_callback,
+ (gpointer) ORIENT_UPSIDEDOWN, NULL, NULL, 0,
+ _("Seascape"), orientation_callback,
+ (gpointer) ORIENT_SEASCAPE, NULL, NULL, 0,
+ NULL);
+ stpui_set_help_data (orientation_menu,
+ _("Select the orientation: portrait, landscape, "
+ "upside down, or seascape (upside down landscape)"));
+ stpui_table_attach_aligned (GTK_TABLE (table), 0, 0, _("Orientation:"),
+ 1.0, 0.5, orientation_menu, 4, TRUE);
+ sep = gtk_hseparator_new ();
+ gtk_table_attach_defaults (GTK_TABLE (table), sep, 0, 6, 1, 2);
+ gtk_widget_show (sep);
+
+ /*
+ * Position entries
+ */
+
+ left_entry = create_positioning_entry
+ (table, 0, 2, _("Left:"),
+ _("Distance from the left of the paper to the image"));
+#if 0
+ right_entry = create_positioning_entry
+ (table, 0, 3, _("Right:"),
+ _("Distance from the left of the paper to the right of the image"));
+#endif
+ right_border_entry = create_positioning_entry
+ (table, 0, 4, _("Right:"),
+ _("Distance from the right of the paper to the image"));
+ top_entry = create_positioning_entry
+ (table, 3, 2, _("Top:"),
+ _("Distance from the top of the paper to the image"));
+#if 0
+ bottom_entry = create_positioning_entry
+ (table, 3, 3, _("Bottom:"),
+ _("Distance from the top of the paper to bottom of the image"));
+#endif
+ bottom_border_entry = create_positioning_entry
+ (table, 3, 4, _("Bottom:"),
+ _("Distance from the bottom of the paper to the image"));
+ /*
+ * Center options
+ */
+
+ sep = gtk_hseparator_new ();
+ gtk_table_attach_defaults (GTK_TABLE (table), sep, 0, 6, 5, 6);
+ gtk_widget_show (sep);
+
+ box = gtk_hbox_new (TRUE, 4);
+ stpui_table_attach_aligned (GTK_TABLE (table), 0, 7, _("Center:"), 0.5, 0.5,
+ box, 5, TRUE);
+ recenter_horizontal_button = create_positioning_button
+ (box, INVALID_LEFT, _("Horizontal"),
+ _("Center the image horizontally on the paper"));
+ recenter_button = create_positioning_button
+ (box, INVALID_LEFT | INVALID_TOP, _("Both"),
+ _("Center the image on the paper"));
+ recenter_vertical_button = create_positioning_button
+ (box, INVALID_TOP, _("Vertical"),
+ _("Center the image vertically on the paper"));
+}
+
+static void
+create_printer_dialog (void)
+{
+ GtkWidget *table;
+ GtkWidget *label;
+ GtkWidget *event_box;
+ GSList *group;
+ gint i;
+ stp_string_list_t *manufacturer_list = stp_string_list_create();
+
+ setup_dialog = stpui_dialog_new(_("Setup Printer"),
+ GTK_WIN_POS_MOUSE, TRUE,
+ _("OK"), setup_ok_callback,
+ NULL, NULL, NULL, TRUE, FALSE,
+ _("Cancel"), setup_cancel_callback,
+ NULL, (GObject *) 1, NULL, FALSE, TRUE,
+ NULL);
+
+ /*
+ * Top-level table for dialog.
+ */
+
+ table = gtk_table_new (4, 4, FALSE);
+ gtk_container_set_border_width (GTK_CONTAINER (table), 6);
+ gtk_table_set_col_spacings (GTK_TABLE (table), 4);
+ gtk_table_set_row_spacing (GTK_TABLE (table), 0, 150);
+ gtk_box_pack_start (GTK_BOX (GTK_DIALOG (setup_dialog)->vbox), table,
+ TRUE, TRUE, 0);
+ gtk_widget_show (table);
+
+ /*
+ * Printer driver option menu.
+ */
+
+ label = gtk_label_new (_("Printer Make:"));
+ gtk_misc_set_alignment (GTK_MISC (label), 1.0, 0.5);
+ gtk_table_attach (GTK_TABLE (table), label, 1, 2, 0, 2,
+ GTK_FILL, GTK_FILL, 0, 0);
+ gtk_widget_show (label);
+
+ event_box = gtk_event_box_new ();
+ gtk_table_attach (GTK_TABLE (table), event_box, 2, 4, 0, 2,
+ GTK_FILL | GTK_EXPAND, GTK_FILL | GTK_EXPAND, 0, 0);
+ gtk_widget_show (event_box);
+
+ stpui_set_help_data (event_box, _("Select the make of your printer"));
+
+ manufacturer_crawler = gtk_scrolled_window_new (NULL, NULL);
+ gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (manufacturer_crawler),
+ GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
+ gtk_container_add (GTK_CONTAINER (event_box), manufacturer_crawler);
+ gtk_widget_show (manufacturer_crawler);
+
+ manufacturer_clist = gtk_clist_new (1);
+ gtk_widget_set_usize (manufacturer_clist, 200, 0);
+ gtk_clist_set_selection_mode(GTK_CLIST(manufacturer_clist),GTK_SELECTION_SINGLE);
+ gtk_container_add (GTK_CONTAINER (manufacturer_crawler), manufacturer_clist);
+ gtk_widget_show (manufacturer_clist);
+
+ g_signal_connect (G_OBJECT (manufacturer_clist), "select_row",
+ G_CALLBACK (manufacturer_callback), NULL);
+
+
+ label = gtk_label_new (_("Printer Model:"));
+ gtk_misc_set_alignment (GTK_MISC (label), 1.0, 0.5);
+ gtk_table_attach (GTK_TABLE (table), label, 4, 5, 0, 2,
+ GTK_FILL, GTK_FILL, 0, 0);
+ gtk_widget_show (label);
+
+ event_box = gtk_event_box_new ();
+ gtk_table_attach (GTK_TABLE (table), event_box, 5, 7, 0, 2,
+ GTK_FILL | GTK_EXPAND, GTK_FILL | GTK_EXPAND, 0, 0);
+ gtk_widget_show (event_box);
+
+ stpui_set_help_data (event_box, _("Select your printer model"));
+
+ printer_crawler = gtk_scrolled_window_new (NULL, NULL);
+ gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (printer_crawler),
+ GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
+ gtk_container_add (GTK_CONTAINER (event_box), printer_crawler);
+ gtk_widget_show (printer_crawler);
+
+ printer_driver = gtk_clist_new (1);
+ gtk_widget_set_usize (printer_driver, 200, 0);
+ gtk_clist_set_selection_mode(GTK_CLIST(printer_driver),GTK_SELECTION_SINGLE);
+ gtk_container_add (GTK_CONTAINER (printer_crawler), printer_driver);
+ gtk_widget_show (printer_driver);
+
+ g_signal_connect (G_OBJECT (printer_driver), "select_row",
+ G_CALLBACK (print_driver_callback), NULL);
+
+
+ for (i = 0; i < stp_printer_model_count (); i ++)
+ {
+ const stp_printer_t *the_printer = stp_get_printer_by_index (i);
+
+ if (strcmp(stp_printer_get_long_name (the_printer), "") != 0 &&
+ strcmp(stp_printer_get_family(the_printer), "raw") != 0)
+ {
+ const gchar *make = stp_printer_get_manufacturer(the_printer);
+ if (! stp_string_list_is_present(manufacturer_list, make))
+ stp_string_list_add_string(manufacturer_list, make, make);
+ }
+ }
+
+ for (i = 0; i < stp_string_list_count(manufacturer_list); i++)
+ {
+ const stp_param_string_t *param =
+ stp_string_list_param(manufacturer_list, i);
+ gchar *xname = g_strdup(param->name);
+ gtk_clist_insert(GTK_CLIST(manufacturer_clist), i, &xname);
+ gtk_clist_set_row_data_full(GTK_CLIST(manufacturer_clist), i, xname,
+ g_free);
+ }
+ stp_string_list_destroy(manufacturer_list);
+ gtk_clist_sort(GTK_CLIST(manufacturer_clist));
+ build_printer_driver_clist();
+
+ /*
+ * PPD file.
+ */
+
+ ppd_label = gtk_label_new (_("PPD File:"));
+ gtk_misc_set_alignment (GTK_MISC (ppd_label), 1.0, 0.5);
+ gtk_table_attach (GTK_TABLE (table), ppd_label, 1, 2, 3, 4,
+ GTK_FILL, GTK_FILL, 0, 0);
+ gtk_widget_show (ppd_label);
+
+ ppd_box = gtk_hbox_new (FALSE, 8);
+ gtk_table_attach (GTK_TABLE (table), ppd_box, 2, 7, 3, 4,
+ GTK_FILL, GTK_FILL, 0, 0);
+
+ ppd_file = gtk_entry_new ();
+ gtk_box_pack_start (GTK_BOX (ppd_box), ppd_file, TRUE, TRUE, 0);
+ gtk_widget_show (ppd_file);
+
+ stpui_set_help_data(ppd_file,_("Enter the correct PPD filename for your printer"));
+
+ ppd_button = gtk_button_new_with_label (_("Browse"));
+ gtk_misc_set_padding (GTK_MISC (GTK_BIN (ppd_button)->child), 2, 0);
+ gtk_box_pack_start (GTK_BOX (ppd_box), ppd_button, FALSE, FALSE, 0);
+ gtk_widget_show (ppd_button);
+ gtk_widget_show (ppd_box);
+
+ stpui_set_help_data(ppd_button,
+ _("Choose the correct PPD filename for your printer"));
+ g_signal_connect (G_OBJECT (ppd_button), "clicked",
+ G_CALLBACK (ppd_browse_callback), NULL);
+
+ /*
+ * Print command.
+ */
+
+ group = NULL;
+ for (i = 0; i < command_options_count; i++)
+ group = stpui_create_radio_button(&(command_options[i]), group, table,
+ 0, i > 0 ? i + 5 : i + 4,
+ G_CALLBACK(command_type_callback));
+
+ standard_cmd_entry = gtk_entry_new();
+ gtk_table_attach (GTK_TABLE (table), standard_cmd_entry, 2, 7, 5, 6,
+ GTK_FILL, GTK_FILL, 0, 0);
+ gtk_entry_set_editable(GTK_ENTRY(standard_cmd_entry), FALSE);
+ gtk_widget_set_sensitive(standard_cmd_entry, FALSE);
+ gtk_widget_show (standard_cmd_entry);
+
+ queue_combo = gtk_combo_new ();
+ event_box = gtk_event_box_new ();
+ gtk_container_add (GTK_CONTAINER (event_box), queue_combo);
+ gtk_widget_show (queue_combo);
+ gtk_widget_show (event_box);
+ build_queue_combo();
+
+ stpui_set_help_data(event_box,
+ _("Select the name of the output queue (not the type, "
+ "or model, of printer) that you wish to print to"));
+ label = gtk_label_new(_("Printer Queue:"));
+ gtk_widget_show(label);
+ gtk_table_attach (GTK_TABLE (table), label, 2, 3, 4, 5,
+ GTK_FILL, GTK_FILL, 0, 0);
+ gtk_table_attach (GTK_TABLE (table), event_box, 3, 7, 4, 5,
+ GTK_FILL, GTK_FILL, 0, 0);
+
+ custom_command_entry = gtk_entry_new ();
+ gtk_table_attach (GTK_TABLE (table), custom_command_entry, 2, 7, 6, 7,
+ GTK_FILL, GTK_FILL, 0, 0);
+ g_signal_connect(G_OBJECT(custom_command_entry), "activate",
+ G_CALLBACK(setup_callback), NULL);
+ gtk_widget_set_sensitive(custom_command_entry, FALSE);
+ gtk_widget_show (custom_command_entry);
+
+ stpui_set_help_data
+ (custom_command_entry, _("Enter the correct command to print to your printer. "));
+
+ file_entry = gtk_entry_new ();
+ gtk_table_attach (GTK_TABLE (table), file_entry, 2, 6, 7, 8,
+ GTK_FILL, GTK_FILL, 0, 0);
+ g_signal_connect(G_OBJECT(file_entry), "activate",
+ G_CALLBACK(setup_callback), NULL);
+ gtk_widget_show (file_entry);
+
+ gtk_widget_set_sensitive(file_entry, FALSE);
+ stpui_set_help_data
+ (file_entry, _("Enter the file to print to. "));
+
+ file_button = gtk_button_new_with_label (_("Browse"));
+
+ gtk_table_attach (GTK_TABLE (table), file_button, 6, 7, 7, 8,
+ GTK_FILL, GTK_FILL, 0, 0);
+ gtk_widget_show (file_button);
+
+ stpui_set_help_data(file_button, _("File to print to"));
+ g_signal_connect (G_OBJECT (file_button), "clicked",
+ G_CALLBACK (file_browse_callback), NULL);
+
+ /*
+ * Output file selection dialog.
+ */
+
+ file_browser = gtk_file_selection_new (_("Print To File"));
+
+ g_signal_connect
+ (G_OBJECT (GTK_FILE_SELECTION (file_browser)->ok_button), "clicked",
+ G_CALLBACK (file_ok_callback), NULL);
+ g_signal_connect
+ (G_OBJECT (GTK_FILE_SELECTION (file_browser)->cancel_button), "clicked",
+ G_CALLBACK (file_cancel_callback), NULL);
+
+ /*
+ * PPD file selection dialog.
+ */
+
+ ppd_browser = gtk_file_selection_new (_("PPD File"));
+ gtk_file_selection_hide_fileop_buttons (GTK_FILE_SELECTION (ppd_browser));
+
+ g_signal_connect
+ (G_OBJECT (GTK_FILE_SELECTION (ppd_browser)->ok_button), "clicked",
+ G_CALLBACK (ppd_ok_callback), NULL);
+ g_signal_connect_object
+ (G_OBJECT (GTK_FILE_SELECTION (ppd_browser)->cancel_button), "clicked",
+ G_CALLBACK (gtk_widget_hide), G_OBJECT (ppd_browser), G_CONNECT_SWAPPED);
+}
+
+static void
+create_new_printer_dialog (void)
+{
+ GtkWidget *table;
+
+ new_printer_dialog =
+ stpui_dialog_new (_("Define New Printer"),
+ GTK_WIN_POS_MOUSE, FALSE,
+ _("OK"), new_printer_ok_callback,
+ NULL, NULL, NULL, TRUE, FALSE,
+ _("Cancel"), gtk_widget_hide,
+ NULL, (GObject *) 1, NULL, FALSE, TRUE,
+ NULL);
+
+ table = gtk_table_new (1, 1, FALSE);
+ gtk_container_set_border_width (GTK_CONTAINER (table), 6);
+ gtk_table_set_col_spacings (GTK_TABLE (table), 4);
+ gtk_table_set_row_spacings (GTK_TABLE (table), 8);
+ gtk_box_pack_start (GTK_BOX (GTK_DIALOG (new_printer_dialog)->vbox), table,
+ FALSE, FALSE, 0);
+ gtk_widget_show (table);
+
+ new_printer_entry = gtk_entry_new ();
+ gtk_entry_set_max_length (GTK_ENTRY (new_printer_entry), 127);
+ stpui_table_attach_aligned(GTK_TABLE (table), 0, 0, _("Printer Name:"), 1.0,
+ 0.5, new_printer_entry, 1, TRUE);
+
+ stpui_set_help_data(new_printer_entry,
+ _("Enter the name you wish to give this logical printer"));
+ g_signal_connect (G_OBJECT (new_printer_entry), "activate",
+ G_CALLBACK (new_printer_ok_callback), NULL);
+}
+
+static void
+create_about_dialog (void)
+{
+ GtkWidget *label;
+ about_dialog =
+ stpui_dialog_new (_("About Gutenprint " PLUG_IN_VERSION),
+ GTK_WIN_POS_MOUSE, FALSE,
+ _("OK"), gtk_widget_hide,
+ NULL, (GObject *) 1, NULL, TRUE, TRUE,
+ NULL);
+
+ label = gtk_label_new
+ (_("Gutenprint Version " PLUG_IN_VERSION "\n"
+ "\n"
+ "Copyright (C) 1997-2003 Michael Sweet, Robert Krawitz,\n"
+ "and the rest of the Gutenprint Development Team.\n"
+ "\n"
+ "Please visit our web site at http://gimp-print.sourceforge.net.\n"
+ "\n"
+ "This program is free software; you can redistribute it and/or modify\n"
+ "it under the terms of the GNU General Public License as published by\n"
+ "the Free Software Foundation; either version 2 of the License, or\n"
+ "(at your option) any later version.\n"
+ "\n"
+ "This program is distributed in the hope that it will be useful,\n"
+ "but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
+ "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n"
+ "GNU General Public License for more details.\n"
+ "\n"
+ "You should have received a copy of the GNU General Public License\n"
+ "along with this program; if not, write to the Free Software\n"
+ "Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 "
+ "USA\n"));
+
+ gtk_misc_set_padding (GTK_MISC (label), 12, 4);
+ gtk_box_pack_start (GTK_BOX (GTK_DIALOG (about_dialog)->vbox), label,
+ FALSE, FALSE, 0);
+ gtk_widget_show (label);
+}
+
+static void
+create_printer_settings_frame (void)
+{
+ GtkWidget *table;
+ GtkWidget *sep;
+ GtkWidget *printer_hbox;
+ GtkWidget *button;
+ GtkWidget *event_box;
+ GtkWidget *scrolled_window;
+ gint vpos = 0;
+
+ create_printer_dialog ();
+ create_about_dialog ();
+ create_new_printer_dialog ();
+
+ table = gtk_table_new (1, 1, FALSE);
+ gtk_table_set_col_spacings (GTK_TABLE (table), 2);
+ gtk_table_set_row_spacings (GTK_TABLE (table), 2);
+ gtk_container_set_border_width (GTK_CONTAINER (table), 4);
+ gtk_notebook_append_page (GTK_NOTEBOOK (notebook), table,
+ gtk_label_new (_("Printer Settings")));
+ gtk_widget_show (table);
+
+ /*
+ * Printer option menu.
+ */
+
+ printer_combo = gtk_combo_new ();
+ event_box = gtk_event_box_new ();
+ gtk_container_add (GTK_CONTAINER (event_box), printer_combo);
+ gtk_widget_show (printer_combo);
+
+ stpui_set_help_data(event_box,
+ _("Select the name of the printer (not the type, "
+ "or model, of printer) that you wish to print to"));
+ stpui_table_attach_aligned(GTK_TABLE (table), 0, vpos++, _("Printer Name:"),
+ 0.0, 0.5, event_box, 1, TRUE);
+ printer_model_label = gtk_label_new ("");
+ stpui_table_attach_aligned(GTK_TABLE (table), 0, vpos++, _("Printer Model:"),
+ 0.0, 0.0, printer_model_label, 1, TRUE);
+ printer_hbox = gtk_hbox_new (TRUE, 4);
+ gtk_table_attach (GTK_TABLE (table), printer_hbox,
+ 1, 4, vpos, vpos + 1, GTK_EXPAND|GTK_FILL, GTK_FILL, 0, 0);
+ vpos += 2;
+ gtk_widget_show (printer_hbox);
+
+ /*
+ * Setup printer button
+ */
+
+ button = gtk_button_new_with_label (_("Setup Printer..."));
+ stpui_set_help_data(button,
+ _("Choose the printer model, PPD file, and command "
+ "that is used to print to this printer"));
+ gtk_misc_set_padding (GTK_MISC (GTK_BIN (button)->child), 2, 0);
+ gtk_box_pack_start (GTK_BOX (printer_hbox), button, FALSE, TRUE, 0);
+ gtk_widget_show (button);
+
+ g_signal_connect (G_OBJECT (button), "clicked",
+ G_CALLBACK (setup_open_callback), NULL);
+
+ /*
+ * New printer button
+ */
+
+ button = gtk_button_new_with_label (_("New Printer..."));
+ stpui_set_help_data (button, _("Define a new logical printer. This can be used to "
+ "name a collection of settings that you wish to "
+ "remember for future use."));
+ gtk_box_pack_start (GTK_BOX (printer_hbox), button, FALSE, TRUE, 0);
+ gtk_widget_show (button);
+
+ g_signal_connect (G_OBJECT (button), "clicked",
+ G_CALLBACK (new_printer_open_callback), NULL);
+
+ sep = gtk_hseparator_new ();
+ gtk_table_attach (GTK_TABLE (table), sep, 0, 5, vpos, vpos + 1,
+ GTK_EXPAND|GTK_FILL, GTK_FILL, 0, 0);
+ gtk_widget_show (sep);
+ vpos++;
+
+ printer_features_table = gtk_table_new(1, 1, FALSE);
+ gtk_table_set_col_spacings (GTK_TABLE (printer_features_table), 2);
+ gtk_table_set_row_spacings (GTK_TABLE (printer_features_table), 0);
+ gtk_widget_show (printer_features_table);
+
+ scrolled_window = gtk_scrolled_window_new(NULL, NULL);
+ gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolled_window),
+ GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
+ gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(scrolled_window),
+ printer_features_table);
+ gtk_table_attach_defaults(GTK_TABLE(table), scrolled_window,
+ 0, 6, vpos, vpos + 1);
+ gtk_widget_show(scrolled_window);
+}
+
+static void
+create_scaling_frame (void)
+{
+ GtkWidget *frame;
+ GtkWidget *vbox;
+ GtkWidget *hbox;
+ GtkWidget *table;
+ GtkWidget *box;
+ GtkWidget *label;
+ GtkWidget *event_box;
+ GtkWidget *sep;
+ GSList *group;
+
+ frame = gtk_frame_new (_("Image Size"));
+ gtk_box_pack_start (GTK_BOX (main_vbox), frame, FALSE, FALSE, 0);
+ gtk_widget_show (frame);
+
+ hbox = gtk_hbox_new (FALSE, 2);
+ gtk_container_set_border_width (GTK_CONTAINER (hbox), 4);
+ gtk_container_add (GTK_CONTAINER (frame), hbox);
+ gtk_widget_show (hbox);
+
+ vbox = gtk_vbox_new (FALSE, 2);
+/* gtk_container_set_border_width (GTK_CONTAINER (vbox), 4); */
+ gtk_container_add (GTK_CONTAINER (hbox), vbox);
+ gtk_widget_show (vbox);
+
+ table = gtk_table_new (1, 1, FALSE);
+ gtk_table_set_col_spacings (GTK_TABLE (table), 4);
+ gtk_box_pack_start (GTK_BOX (vbox), table, FALSE, FALSE, 0);
+ gtk_widget_show (table);
+
+ /*
+ * Create the scaling adjustment using percent. It doesn't really matter,
+ * since as soon as we call plist_callback at the end of initialization
+ * everything will be put right.
+ */
+ scaling_adjustment =
+ stpui_scale_entry_new (GTK_TABLE (table), 0, 0, _("Scaling:"), 100, 75,
+ 100.0, minimum_image_percent, 100.0,
+ 1.0, 10.0, 1, TRUE, 0, 0, NULL);
+ stpui_set_adjustment_tooltip(scaling_adjustment,
+ _("Set the scale (size) of the image"));
+ g_signal_connect (G_OBJECT (scaling_adjustment), "value_changed",
+ G_CALLBACK (scaling_update), NULL);
+
+ box = gtk_hbox_new (FALSE, 4);
+ gtk_box_pack_start (GTK_BOX (vbox), box, TRUE, TRUE, 0);
+ gtk_widget_show (box);
+
+ /*
+ * The scale by percent/ppi toggles
+ */
+
+ table = gtk_table_new (1, 1, FALSE);
+ gtk_table_set_col_spacings (GTK_TABLE (table), 4);
+ gtk_box_pack_start (GTK_BOX (box), table, FALSE, FALSE, 0);
+ gtk_widget_show (table);
+
+ event_box = gtk_event_box_new ();
+ gtk_table_attach (GTK_TABLE (table), event_box, 0, 1, 0, 1,
+ GTK_FILL, GTK_FILL, 0, 0);
+ gtk_widget_show (event_box);
+
+ label = gtk_label_new (_("Scale by:"));
+ gtk_container_add (GTK_CONTAINER (event_box), label);
+ gtk_widget_show (label);
+
+ stpui_set_help_data(event_box,
+ _("Select whether scaling is measured as percent of "
+ "available page size or number of output dots per inch"));
+
+ scaling_percent = gtk_radio_button_new_with_label (NULL, _("Percent"));
+ group = gtk_radio_button_group (GTK_RADIO_BUTTON (scaling_percent));
+ stpui_table_attach_aligned(GTK_TABLE (table), 0, 0, NULL, 0.5, 0.5,
+ scaling_percent, 2, TRUE);
+
+ stpui_set_help_data(scaling_percent, _("Scale the print to the size of the page"));
+ g_signal_connect (G_OBJECT (scaling_percent), "toggled",
+ G_CALLBACK (scaling_callback), NULL);
+
+ scaling_ppi = gtk_radio_button_new_with_label (group, _("PPI"));
+ stpui_table_attach_aligned(GTK_TABLE (table), 2, 0, NULL, 0.5, 0.5,
+ scaling_ppi, 1, TRUE);
+
+ stpui_set_help_data(scaling_ppi,
+ _("Scale the print to the number of dots per inch"));
+ g_signal_connect (G_OBJECT (scaling_ppi), "toggled",
+ G_CALLBACK (scaling_callback), NULL);
+
+ sep = gtk_vseparator_new ();
+ gtk_box_pack_start (GTK_BOX (hbox), sep, FALSE, FALSE, 8);
+ gtk_widget_show (sep);
+
+ /*
+ * The width/height enries
+ */
+
+ table = gtk_table_new (1, 1, FALSE);
+ gtk_table_set_col_spacings (GTK_TABLE (table), 2);
+ gtk_box_pack_start (GTK_BOX (hbox), table, FALSE, FALSE, 0);
+ gtk_widget_show (table);
+
+ width_entry = create_positioning_entry
+ (table, 0, 0, _("Width:"), _("Set the width of the print"));
+ height_entry = create_positioning_entry
+ (table, 0, 1, _("Height:"), _("Set the height of the print"));
+
+ /*
+ * The "image size" button
+ */
+
+ scaling_image = gtk_button_new_with_label (_("Use Original\nImage Size"));
+ gtk_misc_set_padding (GTK_MISC (GTK_BIN (scaling_image)->child), 2, 2);
+ gtk_box_pack_end (GTK_BOX (hbox), scaling_image, FALSE, FALSE, 0);
+ gtk_widget_show (scaling_image);
+
+ stpui_set_help_data(scaling_image,
+ _("Set the print size to the size of the image"));
+ g_signal_connect (G_OBJECT (scaling_image), "clicked",
+ G_CALLBACK (scaling_callback), NULL);
+}
+
+/*
+ * create_color_adjust_window (void)
+ *
+ * NOTES:
+ * creates the color adjuster popup, allowing the user to adjust brightness,
+ * contrast, saturation, etc.
+ */
+static void
+create_color_adjust_window (void)
+{
+ GtkWidget *table;
+ GtkWidget *label;
+ GtkWidget *event_box;
+ GtkWidget *scrolled_window;
+ gint x, y; /* Window dimensions */
+
+ initialize_thumbnail();
+
+ color_adjust_dialog =
+ stpui_dialog_new(_("Print Color Adjust"),
+ GTK_WIN_POS_MOUSE, TRUE,
+
+ _("Set Defaults"), set_color_defaults,
+ NULL, NULL, NULL, FALSE, FALSE,
+ _("Close"), gtk_widget_hide,
+ NULL, (GObject *) 1, NULL, TRUE, TRUE,
+ NULL);
+
+ table = gtk_table_new (1, 1, FALSE);
+ gtk_container_set_border_width (GTK_CONTAINER (table), 6);
+ gtk_table_set_col_spacings (GTK_TABLE (table), 4);
+ gtk_table_set_row_spacings (GTK_TABLE (table), 0);
+/* gtk_table_set_row_spacing (GTK_TABLE (table), 8, 6); */
+
+ gtk_box_pack_start (GTK_BOX (GTK_DIALOG (color_adjust_dialog)->vbox),
+ table, TRUE, TRUE, 0);
+ gtk_widget_show (table);
+
+ /*
+ * Drawing area for color swatch feedback display...
+ */
+
+ event_box = gtk_event_box_new ();
+ gtk_widget_show (GTK_WIDGET (event_box));
+ gtk_table_attach (GTK_TABLE (table), GTK_WIDGET (event_box),
+ 0, 1, 0, 1, 0, 0, 0, 0);
+
+ swatch = (GtkDrawingArea *) gtk_drawing_area_new ();
+ gtk_widget_set_events (GTK_WIDGET (swatch), GDK_EXPOSURE_MASK);
+ gtk_drawing_area_size (swatch, thumbnail_w, thumbnail_h);
+ gtk_container_add (GTK_CONTAINER (event_box), GTK_WIDGET (swatch));
+ gtk_widget_show (GTK_WIDGET (swatch));
+
+ stpui_set_help_data (GTK_WIDGET (event_box), _("Image preview"));
+ g_signal_connect (G_OBJECT (swatch), "expose_event",
+ G_CALLBACK (redraw_color_swatch),
+ NULL);
+
+ event_box = gtk_event_box_new ();
+ gtk_widget_show (GTK_WIDGET (event_box));
+ gtk_table_attach (GTK_TABLE (table), GTK_WIDGET (event_box),
+ 1, 2, 0, 1, 0, 0, 0, 0);
+
+ output_color_vbox = gtk_vbox_new(TRUE, 0);
+ gtk_container_add(GTK_CONTAINER(event_box), output_color_vbox);
+ gtk_widget_show(GTK_WIDGET(output_color_vbox));
+
+ label = gtk_label_new(_("View Output Channels:"));
+ gtk_box_pack_start(GTK_BOX(output_color_vbox), label, TRUE, TRUE, 0);
+ gtk_widget_show(GTK_WIDGET(label));
+
+ cyan_button = gtk_toggle_button_new_with_label(_("Cyan"));
+ gtk_box_pack_start(GTK_BOX(output_color_vbox), cyan_button, TRUE, TRUE, 0);
+ gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(cyan_button), TRUE);
+ gtk_widget_show(GTK_WIDGET(cyan_button));
+ g_signal_connect (G_OBJECT (cyan_button), "toggled",
+ G_CALLBACK (color_button_callback), NULL);
+
+ magenta_button = gtk_toggle_button_new_with_label(_("Magenta"));
+ gtk_box_pack_start(GTK_BOX(output_color_vbox), magenta_button, TRUE, TRUE,0);
+ gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(magenta_button), TRUE);
+ gtk_widget_show(GTK_WIDGET(magenta_button));
+ g_signal_connect (G_OBJECT (magenta_button), "toggled",
+ G_CALLBACK (color_button_callback), NULL);
+
+ yellow_button = gtk_toggle_button_new_with_label(_("Yellow"));
+ gtk_box_pack_start(GTK_BOX(output_color_vbox), yellow_button, TRUE, TRUE, 0);
+ gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(yellow_button), TRUE);
+ gtk_widget_show(GTK_WIDGET(yellow_button));
+ g_signal_connect (G_OBJECT (yellow_button), "toggled",
+ G_CALLBACK (color_button_callback), NULL);
+
+ black_button = gtk_toggle_button_new_with_label(_("Black"));
+ gtk_box_pack_start(GTK_BOX(output_color_vbox), black_button, TRUE, TRUE, 0);
+ gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(black_button), TRUE);
+ gtk_widget_show(GTK_WIDGET(black_button));
+ g_signal_connect (G_OBJECT (black_button), "toggled",
+ G_CALLBACK (color_button_callback), NULL);
+
+ color_adjustment_table = gtk_table_new(1, 1, FALSE);
+ gtk_table_set_col_spacings (GTK_TABLE (color_adjustment_table), 2);
+ gtk_table_set_row_spacings (GTK_TABLE (color_adjustment_table), 0);
+ gtk_container_set_border_width (GTK_CONTAINER (color_adjustment_table), 4);
+ gtk_widget_show (color_adjustment_table);
+
+ scrolled_window = gtk_scrolled_window_new(NULL, NULL);
+ gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolled_window),
+ GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
+ gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(scrolled_window),
+ color_adjustment_table);
+ gtk_table_attach_defaults(GTK_TABLE(table), scrolled_window,
+ 0, 2, 1, 2);
+ gtk_widget_show(scrolled_window);
+
+ /* The initial size request does not account for the
+ GtkScrolledWindow. */
+ gtk_window_get_size(GTK_WINDOW(color_adjust_dialog), &x, &y);
+ gtk_window_set_default_size(GTK_WINDOW(color_adjust_dialog), x, y+300);
+}
+
+static void
+create_image_settings_frame (void)
+{
+ GtkWidget *vbox;
+ GtkWidget *hbox;
+ GtkWidget *table;
+ GtkWidget *label;
+ GtkWidget *event_box;
+ GtkWidget *sep;
+ GSList *group;
+ gint i;
+
+ create_color_adjust_window ();
+
+ vbox = gtk_vbox_new (FALSE, 4);
+ gtk_container_set_border_width (GTK_CONTAINER (vbox), 4);
+ gtk_notebook_append_page (GTK_NOTEBOOK (notebook), vbox,
+ gtk_label_new (_("Output")));
+ gtk_widget_show (vbox);
+
+ table = gtk_table_new (1, 1, FALSE);
+ gtk_table_set_col_spacings (GTK_TABLE (table), 4);
+ gtk_box_pack_start (GTK_BOX (vbox), table, FALSE, FALSE, 0);
+ gtk_widget_show (table);
+
+ event_box = gtk_event_box_new ();
+ gtk_table_attach (GTK_TABLE (table), event_box, 0, 1, 0, 1,
+ GTK_FILL, GTK_FILL, 0, 0);
+ gtk_widget_show (event_box);
+
+ /*
+ * Output type toggles.
+ */
+
+ table = gtk_table_new (1, 1, FALSE);
+ gtk_table_set_col_spacings (GTK_TABLE (table), 4);
+/* gtk_table_set_row_spacing (GTK_TABLE (table), 2, 4); */
+ gtk_box_pack_start (GTK_BOX (vbox), table, FALSE, FALSE, 0);
+ gtk_widget_show (table);
+
+ event_box = gtk_event_box_new ();
+ gtk_table_attach (GTK_TABLE (table), event_box, 0, 1, 0, 1,
+ GTK_FILL, GTK_FILL, 0, 0);
+ gtk_widget_show (event_box);
+
+ label = gtk_label_new (_("Output Type:"));
+ gtk_container_add (GTK_CONTAINER (event_box), label);
+ gtk_widget_show (label);
+
+ stpui_set_help_data(event_box, _("Select the desired output type"));
+
+ group = NULL;
+ for (i = 0; i < output_type_count; i++)
+ group = stpui_create_radio_button(&(output_types[i]), group, table, 0, i,
+ G_CALLBACK(output_type_callback));
+
+ sep = gtk_hseparator_new ();
+ gtk_box_pack_start (GTK_BOX (vbox), sep, FALSE, FALSE, 0);
+ gtk_widget_show (sep);
+
+ /*
+ * Color adjust button
+ */
+ hbox = gtk_hbox_new (FALSE, 4);
+ gtk_box_pack_start (GTK_BOX (vbox), hbox, TRUE, TRUE, 0);
+ gtk_widget_show(hbox);
+ label = gtk_label_new("");
+ gtk_box_pack_start(GTK_BOX(hbox), label, TRUE, TRUE, 0);
+ gtk_widget_show(label);
+
+ adjust_color_button = gtk_button_new_with_label (_("Adjust Output..."));
+ gtk_misc_set_padding (GTK_MISC (GTK_BIN (adjust_color_button)->child), 4, 0);
+ gtk_box_pack_start (GTK_BOX (hbox), adjust_color_button, FALSE, FALSE, 0);
+ gtk_widget_show(adjust_color_button);
+ label = gtk_label_new("");
+ gtk_box_pack_end(GTK_BOX(hbox), label, TRUE, TRUE, 0);
+ gtk_widget_show(label);
+
+ stpui_set_help_data(adjust_color_button,
+ _("Adjust color balance, brightness, contrast, "
+ "saturation, and dither algorithm"));
+ g_signal_connect_object (G_OBJECT (adjust_color_button), "clicked",
+ G_CALLBACK (gtk_widget_show),
+ G_OBJECT (color_adjust_dialog),
+ G_CONNECT_SWAPPED);
+}
+
+static void
+create_units_frame (void)
+{
+ GtkWidget *vbox;
+ GtkWidget *table;
+ GtkWidget *label;
+ GtkWidget *event_box;
+ GSList *group;
+ gint i;
+
+ units_hbox = gtk_hbox_new(FALSE, 0);
+ label = gtk_label_new(_("Size Units:"));
+ gtk_widget_show(label);
+ gtk_box_pack_start(GTK_BOX(units_hbox), label, TRUE, TRUE, 0);
+ units_label = gtk_label_new(_(" "));
+ gtk_widget_show(units_label);
+ gtk_box_pack_start(GTK_BOX(units_hbox), units_label, TRUE, TRUE, 0);
+ gtk_widget_show(units_hbox);
+
+ vbox = gtk_vbox_new (FALSE, 4);
+ gtk_container_set_border_width (GTK_CONTAINER (vbox), 4);
+ gtk_notebook_append_page (GTK_NOTEBOOK (notebook), vbox, units_hbox);
+ gtk_widget_show (vbox);
+
+ /*
+ * The units toggles
+ */
+
+ table = gtk_table_new (1, 1, FALSE);
+ gtk_table_set_col_spacings (GTK_TABLE (table), 4);
+ gtk_box_pack_start (GTK_BOX (vbox), table, FALSE, FALSE, 0);
+ gtk_widget_show (table);
+
+ event_box = gtk_event_box_new ();
+ gtk_table_attach (GTK_TABLE (table), event_box, 0, 1, 0, 1,
+ GTK_SHRINK | GTK_FILL, GTK_SHRINK | GTK_FILL, 0, 0);
+ gtk_widget_show (event_box);
+
+ label = gtk_label_new (_("Units:"));
+ gtk_container_add (GTK_CONTAINER (event_box), label);
+ gtk_widget_show (label);
+
+ stpui_set_help_data(event_box,
+ _("Select the base unit of measurement for printing"));
+
+ group = NULL;
+ for (i = 0; i < unit_count; i++)
+ {
+ unit_t *unit = &(units[i]);
+ unit->checkbox = gtk_radio_button_new_with_label(group, _(unit->name));
+ group = gtk_radio_button_group(GTK_RADIO_BUTTON(unit->checkbox));
+ stpui_table_attach_aligned(GTK_TABLE(table), i / 2, i % 2, NULL, 0.5,
+ 0.5, unit->checkbox, 1, TRUE);
+ stpui_set_help_data(unit->checkbox, _(unit->help));
+ g_signal_connect(G_OBJECT(unit->checkbox), "toggled",
+ G_CALLBACK(unit_callback), (gpointer) i);
+ }
+}
+
+/*
+ * create_main_window()
+ */
+static void
+create_main_window (void)
+{
+ gint x, y; /* Window dimensions */
+
+ set_current_printer();
+ manufacturer = stp_printer_get_manufacturer(stp_get_printer(pv->v));
+ /*
+ * Create the various dialog components. Note that we're not
+ * actually initializing the values at this point; that will be done after
+ * the UI is fully created.
+ */
+
+ stpui_help_init();
+
+ create_top_level_structure ();
+
+ create_preview ();
+ create_printer_settings_frame ();
+ create_units_frame();
+ create_paper_size_frame();
+ create_copy_number_frame();
+ create_positioning_frame ();
+ create_scaling_frame ();
+ create_image_settings_frame ();
+
+ /*
+ * Now actually set up the correct values in the dialog
+ */
+
+ do_update_thumbnail = 1;
+ build_printer_combo ();
+ plist_callback (NULL, (gpointer) stpui_plist_current);
+ update_adjusted_thumbnail ();
+
+ /* The initial size request does not account for the
+ GtkScrolledWindow. */
+ gtk_window_get_size(GTK_WINDOW(print_dialog), &x, &y);
+ gtk_window_set_default_size(GTK_WINDOW(print_dialog), x, y+80);
+
+ gtk_widget_show (print_dialog);
+}
+
+static void
+set_entry_value(GtkWidget *entry, double value, int block)
+{
+ gchar s[255];
+ gdouble unit_scaler = units[pv->unit].scale;
+ const gchar *format = units[pv->unit].format;
+
+ g_snprintf(s, sizeof(s), format, value / unit_scaler);
+ if (block)
+ g_signal_handlers_block_matched (G_OBJECT (entry),
+ G_SIGNAL_MATCH_DATA,
+ 0,
+ 0,
+ NULL,
+ NULL,
+ NULL);
+
+ gtk_entry_set_text (GTK_ENTRY (entry), s);
+ if (block)
+ g_signal_handlers_unblock_matched (G_OBJECT (entry),
+ G_SIGNAL_MATCH_DATA,
+ 0,
+ 0,
+ NULL,
+ NULL,
+ NULL);
+}
+
+static void
+reset_preview(void)
+{
+ if (!suppress_preview_reset)
+ {
+ stpui_enable_help();
+ buttons_pressed = preview_active = 0;
+ }
+}
+
+static void
+invalidate_preview_thumbnail (void)
+{
+ preview_valid = FALSE;
+}
+
+static void
+invalidate_frame (void)
+{
+ frame_valid = FALSE;
+}
+
+static void
+compute_scaling_limits(gdouble *min_ppi_scaling, gdouble *max_ppi_scaling)
+{
+ if (auto_paper_size)
+ {
+ *min_ppi_scaling =
+ FINCH * (gdouble) image_width / (gdouble) printable_width;
+ }
+ else
+ {
+ gdouble min_ppi_scaling1 =
+ FINCH * (gdouble) image_width / (gdouble) printable_width;
+ gdouble min_ppi_scaling2 =
+ FINCH * (gdouble) image_height / (gdouble) printable_height;
+
+ if (min_ppi_scaling1 > min_ppi_scaling2)
+ *min_ppi_scaling = min_ppi_scaling1;
+ else
+ *min_ppi_scaling = min_ppi_scaling2;
+ }
+
+ *max_ppi_scaling = *min_ppi_scaling * 100 / minimum_image_percent;
+}
+
+/*
+ * scaling_update() - Update the scaling scale using the slider.
+ */
+static void
+scaling_update (GtkAdjustment *adjustment)
+{
+ reset_preview ();
+
+ if (pv->scaling != adjustment->value)
+ {
+ invalidate_preview_thumbnail ();
+ if (GTK_TOGGLE_BUTTON (scaling_ppi)->active)
+ pv->scaling = -adjustment->value;
+ else
+ pv->scaling = adjustment->value;
+
+ suppress_scaling_adjustment = TRUE;
+ preview_update ();
+ suppress_scaling_adjustment = FALSE;
+ }
+}
+
+/*
+ * scaling_callback() - Update the scaling scale using radio buttons.
+ */
+static void
+scaling_callback (GtkWidget *widget)
+{
+ gdouble max_ppi_scaling;
+ gdouble min_ppi_scaling;
+ gdouble current_scale;
+
+ reset_preview ();
+
+ if (suppress_scaling_callback)
+ return;
+
+ compute_scaling_limits(&min_ppi_scaling, &max_ppi_scaling);
+
+ if (widget == scaling_ppi)
+ {
+ if (! GTK_TOGGLE_BUTTON (scaling_ppi)->active)
+ return;
+
+ GTK_ADJUSTMENT (scaling_adjustment)->lower = min_ppi_scaling;
+ GTK_ADJUSTMENT (scaling_adjustment)->upper = max_ppi_scaling;
+
+ /*
+ * Compute the correct PPI to create an image of the same size
+ * as the one measured in percent
+ */
+ current_scale = GTK_ADJUSTMENT (scaling_adjustment)->value;
+ GTK_ADJUSTMENT (scaling_adjustment)->value =
+ min_ppi_scaling / (current_scale / 100);
+ pv->scaling = 0.0;
+ }
+ else if (widget == scaling_percent)
+ {
+ gdouble new_percent;
+
+ if (! GTK_TOGGLE_BUTTON (scaling_percent)->active)
+ return;
+
+ current_scale = GTK_ADJUSTMENT (scaling_adjustment)->value;
+ GTK_ADJUSTMENT (scaling_adjustment)->lower = minimum_image_percent;
+ GTK_ADJUSTMENT (scaling_adjustment)->upper = 100.0;
+
+ new_percent = 100 * min_ppi_scaling / current_scale;
+
+ if (new_percent > 100)
+ new_percent = 100;
+ if (new_percent < minimum_image_percent)
+ new_percent = minimum_image_percent;
+
+ GTK_ADJUSTMENT (scaling_adjustment)->value = new_percent;
+ pv->scaling = 0.0;
+ }
+ else if (widget == scaling_image)
+ {
+ gdouble yres = image_yres;
+
+ invalidate_preview_thumbnail ();
+
+ GTK_ADJUSTMENT (scaling_adjustment)->lower = min_ppi_scaling;
+ GTK_ADJUSTMENT (scaling_adjustment)->upper = max_ppi_scaling;
+
+ if (yres < min_ppi_scaling)
+ yres = min_ppi_scaling;
+ if (yres > max_ppi_scaling)
+ yres = max_ppi_scaling;
+
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (scaling_ppi), TRUE);
+ GTK_ADJUSTMENT (scaling_adjustment)->value = yres;
+ pv->scaling = 0.0;
+ }
+
+ if (widget == scaling_ppi || widget == scaling_percent)
+ suppress_preview_update++;
+ gtk_adjustment_changed (GTK_ADJUSTMENT (scaling_adjustment));
+ gtk_adjustment_value_changed (GTK_ADJUSTMENT (scaling_adjustment));
+ if (auto_paper_size)
+ set_media_size(stp_get_string_parameter(pv->v, "PageSize"));
+ if (widget == scaling_ppi || widget == scaling_percent)
+ suppress_preview_update--;
+}
+
+/****************************************************************************
+ *
+ * plist_build_combo
+ *
+ ****************************************************************************/
+static void
+plist_build_combo (GtkWidget *combo, /* I - Combo widget */
+ GtkWidget *label,
+ stp_string_list_t *items, /* I - Menu items */
+ int active,
+ const gchar *cur_item, /* I - Current item */
+ const gchar *def_value, /* I - default item */
+ GCallback callback, /* I - Callback */
+ gint *callback_id, /* IO - Callback ID (init to -1) */
+ int (*check_func)(const char *string),
+ gpointer data)
+{
+ gint i; /* Looping var */
+ GList *list = 0;
+ gint num_items = 0;
+ GtkEntry *entry = GTK_ENTRY (GTK_COMBO (combo)->entry);
+
+ if (check_func && items)
+ {
+ stp_string_list_t *new_items = stp_string_list_create();
+ num_items = stp_string_list_count(items);
+ for (i = 0; i < num_items; i++)
+ {
+ stp_param_string_t *param = stp_string_list_param(items, i);
+ if ((*check_func)(param->name))
+ stp_string_list_add_string(new_items, param->name, param->text);
+ }
+ items = new_items;
+ }
+
+ if (items)
+ num_items = stp_string_list_count(items);
+
+ if (*callback_id != -1)
+ g_signal_handler_disconnect (G_OBJECT (entry), *callback_id);
+ gtk_entry_set_editable (entry, FALSE);
+
+ if (!active || num_items == 0)
+ {
+ list = g_list_append (list, _("Standard"));
+ gtk_combo_set_popdown_strings (GTK_COMBO (combo), list);
+ *callback_id = -1;
+ gtk_widget_set_sensitive (combo, FALSE);
+ gtk_widget_hide (combo);
+ if (label)
+ gtk_widget_hide(label);
+ if (check_func && items)
+ stp_string_list_destroy(items);
+ return;
+ }
+
+ for (i = 0; i < num_items; i ++)
+ list = g_list_append(list, g_strdup(stp_string_list_param(items, i)->text));
+
+ gtk_combo_set_popdown_strings (GTK_COMBO (combo), list);
+
+ for (i = 0; i < num_items; i ++)
+ if (strcmp(stp_string_list_param(items, i)->name, cur_item) == 0)
+ break;
+
+ if (i >= num_items && def_value)
+ for (i = 0; i < num_items; i ++)
+ if (strcmp(stp_string_list_param(items, i)->name, def_value) == 0)
+ break;
+
+ if (i >= num_items)
+ i = 0;
+
+ gtk_entry_set_text (entry, stp_string_list_param(items, i)->text);
+
+ gtk_combo_set_value_in_list (GTK_COMBO (combo), TRUE, FALSE);
+ gtk_widget_set_sensitive (combo, TRUE);
+ gtk_widget_show (combo);
+ if (label)
+ gtk_widget_show(label);
+
+ *callback_id = g_signal_connect (G_OBJECT (entry), "changed", callback,
+ data);
+ if (check_func && items)
+ stp_string_list_destroy(items);
+}
+
+void
+stpui_set_image_dimensions(gint width, gint height)
+{
+ image_true_width = width;
+ image_true_height = height;
+}
+
+void
+stpui_set_image_resolution(gdouble xres, gdouble yres)
+{
+ image_xres = xres;
+ image_yres = yres;
+}
+
+gint
+stpui_compute_orientation(void)
+{
+ if (auto_paper_size ||
+ (printable_width >= printable_height &&
+ image_true_width >= image_true_height) ||
+ (printable_height >= printable_width &&
+ image_true_height >= image_true_width))
+ return ORIENT_PORTRAIT;
+ else
+ return ORIENT_LANDSCAPE;
+}
+
+static void
+set_orientation(int orientation)
+{
+ pv->orientation = orientation;
+ if (orientation == ORIENT_AUTO)
+ orientation = stpui_compute_orientation();
+ physical_orientation = orientation;
+ switch (orientation)
+ {
+ case ORIENT_PORTRAIT:
+ case ORIENT_UPSIDEDOWN:
+ image_height = image_true_height;
+ image_width = image_true_width;
+ preview_thumbnail_h = thumbnail_h;
+ preview_thumbnail_w = thumbnail_w;
+ break;
+ case ORIENT_LANDSCAPE:
+ case ORIENT_SEASCAPE:
+ image_height = image_true_width;
+ image_width = image_true_height;
+ preview_thumbnail_h = thumbnail_w;
+ preview_thumbnail_w = thumbnail_h;
+ break;
+ }
+ update_adjusted_thumbnail();
+}
+
+static void
+position_button_callback(GtkWidget *widget, gpointer data)
+{
+ reset_preview();
+ pv->invalid_mask |= (gint) data;
+ preview_update ();
+}
+
+/*
+ * position_callback() - callback for position entry widgets
+ */
+static void
+position_callback (GtkWidget *widget)
+{
+ gdouble new_printed_value = atof (gtk_entry_get_text (GTK_ENTRY (widget)));
+ gint new_value = SCALE(new_printed_value, units[pv->unit].scale);
+
+ reset_preview ();
+ suppress_preview_update++;
+
+ if (widget == top_entry)
+ stp_set_top(pv->v, new_value);
+/*
+ else if (widget == bottom_entry)
+ stp_set_top(pv->v, new_value - print_height);
+*/
+ else if (widget == bottom_border_entry)
+ stp_set_top (pv->v, paper_height - print_height - new_value);
+ else if (widget == left_entry)
+ stp_set_left (pv->v, new_value);
+/*
+ else if (widget == right_entry)
+ stp_set_left(pv->v, new_value - print_width);
+*/
+ else if (widget == right_border_entry)
+ stp_set_left (pv->v, paper_width - print_width - new_value);
+ else if (widget == width_entry || widget == height_entry)
+ {
+ gboolean was_percent = (pv->scaling >= 0);
+ if (pv->scaling >= 0)
+ {
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (scaling_ppi), TRUE);
+ scaling_callback (scaling_ppi);
+ }
+ if (widget == width_entry)
+ GTK_ADJUSTMENT (scaling_adjustment)->value =
+ ((gdouble) image_width) / (new_value / FINCH);
+ else
+ GTK_ADJUSTMENT (scaling_adjustment)->value =
+ ((gdouble) image_height) / (new_value / FINCH);
+ gtk_adjustment_value_changed (GTK_ADJUSTMENT (scaling_adjustment));
+ if (was_percent)
+ {
+ gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(scaling_percent),TRUE);
+ gtk_adjustment_value_changed(GTK_ADJUSTMENT (scaling_adjustment));
+ }
+ }
+
+ suppress_preview_update--;
+ preview_update ();
+}
+
+static void
+set_adjustment_active(option_t *opt, gboolean active, gboolean do_toggle)
+{
+ GtkObject *adj = opt->info.flt.adjustment;
+ if (do_toggle)
+ gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(opt->checkbox), active);
+ gtk_widget_set_sensitive
+ (GTK_WIDGET (SCALE_ENTRY_LABEL (adj)), active);
+ gtk_widget_set_sensitive
+ (GTK_WIDGET (SCALE_ENTRY_SCALE (adj)), active);
+ gtk_widget_set_sensitive
+ (GTK_WIDGET (SCALE_ENTRY_SPINBUTTON (adj)), active);
+}
+
+static void
+set_combo_active(option_t *opt, gboolean active, gboolean do_toggle)
+{
+ if (do_toggle)
+ gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(opt->checkbox), active);
+ gtk_widget_set_sensitive(GTK_WIDGET(opt->info.list.combo), active);
+ gtk_widget_set_sensitive(GTK_WIDGET(opt->info.list.label), active);
+}
+
+static void
+set_curve_active(option_t *opt, gboolean active, gboolean do_toggle)
+{
+ if (do_toggle)
+ gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(opt->checkbox), active);
+ gtk_widget_set_sensitive(GTK_WIDGET(opt->info.curve.button), active);
+ gtk_widget_set_sensitive(GTK_WIDGET(opt->info.curve.label), active);
+ if (active)
+ {
+ if (opt->info.curve.is_visible)
+ gtk_widget_show(GTK_WIDGET(opt->info.curve.dialog));
+ }
+ else
+ gtk_widget_hide(GTK_WIDGET(opt->info.curve.dialog));
+}
+
+static void
+set_bool_active(option_t *opt, gboolean active, gboolean do_toggle)
+{
+ if (do_toggle)
+ gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(opt->checkbox), active);
+ gtk_widget_set_sensitive(GTK_WIDGET(opt->info.bool.checkbox), active);
+}
+
+static void
+do_color_updates (void)
+{
+ int i;
+ for (i = 0; i < current_option_count; i++)
+ {
+ option_t *opt = &(current_options[i]);
+ if (opt->fast_desc->p_level <= MAXIMUM_PARAMETER_LEVEL)
+ {
+ switch (opt->fast_desc->p_type)
+ {
+ case STP_PARAMETER_TYPE_DOUBLE:
+ if (stp_check_float_parameter(pv->v, opt->fast_desc->name,
+ STP_PARAMETER_INACTIVE))
+ gtk_adjustment_set_value
+ (GTK_ADJUSTMENT(opt->info.flt.adjustment),
+ stp_get_float_parameter(pv->v, opt->fast_desc->name));
+ if (stp_check_float_parameter(pv->v, opt->fast_desc->name,
+ STP_PARAMETER_ACTIVE) ||
+ opt->fast_desc->is_mandatory)
+ set_adjustment_active(opt, TRUE, TRUE);
+ else
+ set_adjustment_active(opt, FALSE, TRUE);
+ break;
+ case STP_PARAMETER_TYPE_DIMENSION:
+ if (stp_check_dimension_parameter(pv->v, opt->fast_desc->name,
+ STP_PARAMETER_INACTIVE))
+ {
+ gdouble unit_scaler = units[pv->unit].scale;
+ gtk_adjustment_set_value
+ (GTK_ADJUSTMENT(opt->info.flt.adjustment),
+ (stp_get_dimension_parameter(pv->v, opt->fast_desc->name) /
+ unit_scaler));
+ }
+ if (stp_check_dimension_parameter(pv->v, opt->fast_desc->name,
+ STP_PARAMETER_ACTIVE) ||
+ opt->fast_desc->is_mandatory)
+ set_adjustment_active(opt, TRUE, TRUE);
+ else
+ set_adjustment_active(opt, FALSE, TRUE);
+ break;
+ case STP_PARAMETER_TYPE_CURVE:
+ if (stp_check_curve_parameter(pv->v, opt->fast_desc->name,
+ STP_PARAMETER_ACTIVE) ||
+ opt->fast_desc->is_mandatory)
+ set_curve_active(opt, TRUE, TRUE);
+ else
+ set_curve_active(opt, FALSE, TRUE);
+ break;
+ case STP_PARAMETER_TYPE_STRING_LIST:
+ if (strcmp(opt->fast_desc->name, "PageSize") == 0)
+ build_page_size_combo(opt);
+ else if (stp_check_string_parameter(pv->v, opt->fast_desc->name,
+ STP_PARAMETER_INACTIVE))
+ plist_build_combo(opt->info.list.combo, opt->info.list.label,
+ opt->info.list.params, opt->is_active,
+ (stp_get_string_parameter
+ (pv->v, opt->fast_desc->name)),
+ opt->info.list.default_val,
+ G_CALLBACK(combo_callback),
+ &(opt->info.list.callback_id),
+ NULL, opt);
+ if (stp_check_string_parameter(pv->v, opt->fast_desc->name,
+ STP_PARAMETER_ACTIVE) ||
+ opt->fast_desc->is_mandatory)
+ set_combo_active(opt, TRUE, TRUE);
+ else
+ set_combo_active(opt, FALSE, TRUE);
+ break;
+ case STP_PARAMETER_TYPE_BOOLEAN:
+ if (stp_check_boolean_parameter(pv->v, opt->fast_desc->name,
+ STP_PARAMETER_INACTIVE))
+ gtk_toggle_button_set_active
+ (GTK_TOGGLE_BUTTON(opt->info.bool.checkbox),
+ stp_get_boolean_parameter(pv->v, opt->fast_desc->name));
+ if (stp_check_boolean_parameter(pv->v, opt->fast_desc->name,
+ STP_PARAMETER_ACTIVE) ||
+ opt->fast_desc->is_mandatory)
+ set_bool_active(opt, TRUE, TRUE);
+ else
+ set_bool_active(opt, FALSE, TRUE);
+ break;
+ default:
+ break;
+ }
+ }
+ }
+ update_adjusted_thumbnail ();
+}
+
+static void
+update_options(void)
+{
+ gtk_widget_hide(page_size_table);
+ gtk_widget_hide(printer_features_table);
+ gtk_widget_hide(color_adjustment_table);
+ populate_options(pv->v);
+ populate_option_table(page_size_table, STP_PARAMETER_CLASS_CORE);
+ populate_option_table(printer_features_table, STP_PARAMETER_CLASS_FEATURE);
+ populate_option_table(color_adjustment_table, STP_PARAMETER_CLASS_OUTPUT);
+ gtk_widget_show(page_size_table);
+ gtk_widget_show(printer_features_table);
+ gtk_widget_show(color_adjustment_table);
+ set_options_active(NULL);
+}
+
+static void
+update_standard_print_command(void)
+{
+ char *label_text =
+ stpui_build_standard_print_command(pv, stp_get_printer(pv->v));
+ gtk_entry_set_text(GTK_ENTRY(standard_cmd_entry), label_text);
+ g_free(label_text);
+}
+
+static void
+do_all_updates(void)
+{
+ gint i;
+ suppress_preview_update++;
+ set_orientation(pv->orientation);
+ invalidate_preview_thumbnail ();
+ preview_update ();
+ update_standard_print_command();
+
+ if (pv->scaling < 0)
+ {
+ gdouble tmp = -pv->scaling;
+ gdouble max_ppi_scaling;
+ gdouble min_ppi_scaling;
+
+ compute_scaling_limits(&min_ppi_scaling, &max_ppi_scaling);
+
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (scaling_ppi), TRUE);
+ GTK_ADJUSTMENT (scaling_adjustment)->lower = min_ppi_scaling;
+ GTK_ADJUSTMENT (scaling_adjustment)->upper = max_ppi_scaling;
+ GTK_ADJUSTMENT (scaling_adjustment)->value = tmp;
+ gtk_adjustment_changed (GTK_ADJUSTMENT (scaling_adjustment));
+ gtk_adjustment_value_changed (GTK_ADJUSTMENT (scaling_adjustment));
+ }
+ else
+ {
+ gdouble tmp = pv->scaling;
+
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (scaling_percent), TRUE);
+ GTK_ADJUSTMENT (scaling_adjustment)->lower = minimum_image_percent;
+ GTK_ADJUSTMENT (scaling_adjustment)->upper = 100.0;
+ GTK_ADJUSTMENT (scaling_adjustment)->value = tmp;
+ g_signal_emit_by_name (G_OBJECT(scaling_adjustment), "changed");
+ g_signal_emit_by_name (G_OBJECT(scaling_adjustment), "value_changed");
+ }
+
+ for (i = 0; i < output_type_count; i++)
+ {
+ if (stp_get_string_parameter(pv->v, "PrintingMode") &&
+ strcmp(output_types[i].value,
+ stp_get_string_parameter(pv->v, "PrintingMode")) == 0)
+ gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(output_types[i].button),
+ TRUE);
+ }
+
+ /*
+ * Now get option parameters.
+ */
+
+ update_options();
+ do_color_updates ();
+
+ gtk_option_menu_set_history (GTK_OPTION_MENU (orientation_menu),
+ pv->orientation + 1);
+
+ gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(units[pv->unit].checkbox),
+ TRUE);
+ gtk_label_set_text(GTK_LABEL(units_label), units[pv->unit].name);
+ suppress_preview_update--;
+ preview_update ();
+}
+
+static void
+copy_count_callback(GtkAdjustment *adjustment, gpointer data)
+{
+ gint copy_count = (gint) adjustment->value;
+ stpui_plist_set_copy_count(pv, copy_count);
+ update_standard_print_command();
+}
+
+static void
+auto_paper_size_callback(GtkWidget *widget, gpointer data)
+{
+ auto_paper_size =
+ gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(auto_paper_size_button));
+ pv->auto_size_roll_feed_paper = auto_paper_size;
+ set_orientation(pv->orientation);
+ do_all_updates();
+}
+
+static void
+setup_auto_paper_size(void)
+{
+ const stp_papersize_t *ps =
+ stp_get_papersize_by_name(stp_get_string_parameter(pv->v, "PageSize"));
+ if (ps->height == 0 && ps->width != 0) /* Implies roll feed */
+ {
+ g_signal_handlers_block_matched (G_OBJECT(auto_paper_size_button),
+ G_SIGNAL_MATCH_DATA,
+ 0,
+ 0,
+ NULL,
+ NULL,
+ NULL);
+
+ gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(auto_paper_size_button),
+ pv->auto_size_roll_feed_paper);
+ gtk_widget_show(auto_paper_size_button);
+ g_signal_handlers_unblock_matched (G_OBJECT(auto_paper_size_button),
+ G_SIGNAL_MATCH_DATA,
+ 0,
+ 0,
+ NULL,
+ NULL,
+ NULL);
+ }
+ else
+ {
+ gtk_widget_hide(auto_paper_size_button);
+ auto_paper_size = 0;
+ }
+}
+
+static void
+queue_callback (GtkWidget *widget,
+ gpointer data)
+{
+ int i;
+ int count = stp_string_list_count(stpui_system_print_queues);
+ const gchar *result =
+ gtk_entry_get_text(GTK_ENTRY(GTK_COMBO(queue_combo)->entry));
+ for (i = 0; i < count; i++)
+ {
+ const stp_param_string_t *s =
+ stp_string_list_param(stpui_system_print_queues, i);
+ if (!strcmp(result, s->text))
+ {
+ stpui_plist_set_queue_name(pv, s->name);
+ do_all_updates();
+ return;
+ }
+ }
+}
+
+static void
+setup_callback (GtkWidget *widget)
+{
+ const gchar *new_value = gtk_entry_get_text (GTK_ENTRY (widget));
+
+ if (widget == custom_command_entry)
+ stpui_plist_set_custom_command(pv, new_value);
+ else if (widget == file_entry)
+ {
+ stpui_plist_set_output_filename(pv, new_value);
+ gtk_file_selection_set_filename
+ (GTK_FILE_SELECTION (file_browser),
+ gtk_entry_get_text (GTK_ENTRY (file_entry)));
+ }
+}
+
+/*
+ * plist_callback() - Update the current system printer.
+ */
+static void
+plist_callback (GtkWidget *widget,
+ gpointer data)
+{
+ gint i;
+ char *tmp;
+ stp_parameter_t desc;
+
+ suppress_preview_update++;
+ invalidate_frame ();
+ invalidate_preview_thumbnail ();
+ reset_preview ();
+
+ if (widget)
+ {
+ const gchar *result =
+ gtk_entry_get_text(GTK_ENTRY(GTK_COMBO(printer_combo)->entry));
+
+ for (i = 0; i < stpui_plist_count; i++)
+ {
+ if (! strcmp (result, stp_string_list_param(printer_list, i)->text))
+ {
+ stpui_plist_current = i;
+ break;
+ }
+ }
+ }
+ else
+ {
+ stpui_plist_current = (gint) data;
+ }
+
+ set_current_printer();
+ build_queue_combo();
+ manufacturer = stp_printer_get_manufacturer(stp_get_printer(pv->v));
+ build_printer_driver_clist();
+
+ if (strcmp(stp_get_driver(pv->v), "") != 0)
+ tmp_printer = stp_get_printer(pv->v);
+
+ stp_describe_parameter(pv->v, "PrintingMode", &desc);
+ if (desc.p_type == STP_PARAMETER_TYPE_STRING_LIST)
+ {
+ if (!stp_string_list_is_present(desc.bounds.str, "Color"))
+ {
+ gtk_widget_set_sensitive (output_types[1].button, TRUE);
+ if (gtk_toggle_button_get_active
+ (GTK_TOGGLE_BUTTON (output_types[0].button)) == TRUE)
+ gtk_toggle_button_set_active
+ (GTK_TOGGLE_BUTTON (output_types[1].button), TRUE);
+ gtk_widget_set_sensitive (output_types[0].button, FALSE);
+ }
+ else if (!stp_string_list_is_present(desc.bounds.str, "BW"))
+ {
+ gtk_widget_set_sensitive (output_types[0].button, TRUE);
+ if (gtk_toggle_button_get_active
+ (GTK_TOGGLE_BUTTON (output_types[1].button)) == TRUE)
+ gtk_toggle_button_set_active
+ (GTK_TOGGLE_BUTTON (output_types[0].button), TRUE);
+ gtk_widget_set_sensitive (output_types[1].button, FALSE);
+ }
+ else
+ {
+ gtk_widget_set_sensitive (output_types[0].button, TRUE);
+ gtk_widget_set_sensitive (output_types[1].button, TRUE);
+ }
+ }
+ stp_parameter_description_destroy(&desc);
+ gtk_entry_set_text(GTK_ENTRY(file_entry),
+ stpui_plist_get_output_filename(pv));
+ tmp = stpui_build_standard_print_command(pv, stp_get_printer(pv->v));
+ gtk_entry_set_text(GTK_ENTRY(standard_cmd_entry), tmp);
+ stp_free(tmp);
+ gtk_entry_set_text(GTK_ENTRY(custom_command_entry),
+ stpui_plist_get_custom_command(pv));
+ gtk_spin_button_set_value(GTK_SPIN_BUTTON(copy_count_spin_button),
+ (gfloat) stpui_plist_get_copy_count(pv));
+ do_all_updates();
+
+ setup_update ();
+ do_all_updates();
+ suppress_preview_update--;
+ update_adjusted_thumbnail();
+ preview_update ();
+}
+
+static void
+show_all_paper_sizes_callback(GtkWidget *widget, gpointer data)
+{
+ int i;
+ stpui_show_all_paper_sizes =
+ gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
+ for (i = 0; i < current_option_count; i++)
+ {
+ option_t *option = &(current_options[i]);
+ if (option->fast_desc &&
+ strcmp(option->fast_desc->name, "PageSize") == 0)
+ {
+ build_a_combo(option);
+ break;
+ }
+ }
+}
+
+static void
+custom_media_size_callback(GtkWidget *widget,
+ gpointer data)
+{
+ gint width_limit, height_limit;
+ gint min_width_limit, min_height_limit;
+ gdouble new_printed_value = atof(gtk_entry_get_text(GTK_ENTRY(widget)));
+ gint new_value = SCALE(new_printed_value, units[pv->unit].scale);
+ invalidate_frame ();
+ invalidate_preview_thumbnail ();
+ reset_preview ();
+
+ stp_get_size_limit(pv->v, &width_limit, &height_limit,
+ &min_width_limit, &min_height_limit);
+ if (widget == custom_size_width)
+ {
+ if (new_value < min_width_limit)
+ new_value = min_width_limit;
+ else if (new_value > width_limit)
+ new_value = width_limit;
+ stp_set_page_width (pv->v, new_value);
+ }
+ else
+ {
+ if (new_value < min_height_limit)
+ new_value = min_height_limit;
+ else if (new_value > height_limit)
+ new_value = height_limit;
+ stp_set_page_height (pv->v, new_value);
+ }
+ set_entry_value (widget, new_value, 0);
+ preview_update ();
+}
+
+
+/*
+ * media_size_callback() - Update the current media size.
+ */
+static void
+set_media_size(const gchar *new_media_size)
+{
+ static int setting_media_size = 0;
+ const stp_papersize_t *pap = stp_get_papersize_by_name (new_media_size);
+
+ if (setting_media_size)
+ return;
+ setting_media_size++;
+
+ if (pap)
+ {
+ gint size;
+ int old_width = stp_get_page_width(pv->v);
+ int old_height = stp_get_page_height(pv->v);
+ int need_preview_update = 0;
+
+ if (! stpui_show_all_paper_sizes &&
+ (pap->paper_unit == PAPERSIZE_METRIC_EXTENDED ||
+ pap->paper_unit == PAPERSIZE_ENGLISH_EXTENDED))
+ {
+ int i;
+ stp_parameter_t desc;
+ stp_describe_parameter(pv->v, "PageSize", &desc);
+ stp_set_string_parameter(pv->v, "PageSize", desc.deflt.str);
+ pap = stp_get_papersize_by_name(desc.deflt.str);
+ stp_parameter_description_destroy(&desc);
+ for (i = 0; i < current_option_count; i++)
+ {
+ option_t *option = &(current_options[i]);
+ if (option->fast_desc &&
+ strcmp(option->fast_desc->name, "PageSize") == 0)
+ {
+ build_a_combo(option);
+ break;
+ }
+ }
+ }
+
+ if (pap->width == 0)
+ {
+ int max_w, max_h, min_w, min_h;
+ stp_get_size_limit(pv->v, &max_w, &max_h, &min_w, &min_h);
+ size = old_width;
+ if (size < min_w)
+ size = min_w;
+ else if (size > max_w)
+ size = max_w;
+ gtk_widget_set_sensitive (GTK_WIDGET (custom_size_width), TRUE);
+ gtk_entry_set_editable (GTK_ENTRY (custom_size_width), TRUE);
+ }
+ else
+ {
+ size = pap->width;
+ gtk_widget_set_sensitive (GTK_WIDGET (custom_size_width), FALSE);
+ gtk_entry_set_editable (GTK_ENTRY (custom_size_width), FALSE);
+ }
+ if (size != old_width)
+ {
+ need_preview_update = 1;
+ set_entry_value (custom_size_width, size, 0);
+ stp_set_page_width (pv->v, size);
+ }
+
+ setup_auto_paper_size();
+ if (pap->height == 0)
+ {
+ int max_w, max_h, min_w, min_h;
+ stp_get_size_limit(pv->v, &max_w, &max_h, &min_w, &min_h);
+ if (auto_paper_size)
+ {
+ int l, r, b, t;
+ stp_set_page_height(pv->v, 0);
+ old_height = 0;
+ stp_get_imageable_area(pv->v, &l, &r, &b, &t);
+ gtk_widget_set_sensitive(GTK_WIDGET(custom_size_height), FALSE);
+ gtk_entry_set_editable(GTK_ENTRY(custom_size_height), FALSE);
+ size = print_height;
+ }
+ else
+ {
+ gtk_widget_set_sensitive (GTK_WIDGET (custom_size_height), TRUE);
+ gtk_entry_set_editable (GTK_ENTRY (custom_size_height), TRUE);
+ size = old_height;
+ }
+ if (size < min_h)
+ size = min_h;
+ else if (size > max_h)
+ size = max_h;
+ }
+ else
+ {
+ size = pap->height;
+ gtk_widget_set_sensitive(GTK_WIDGET (custom_size_height), FALSE);
+ gtk_entry_set_editable (GTK_ENTRY (custom_size_height), FALSE);
+ }
+ if (size != old_height)
+ {
+ need_preview_update = 1;
+ set_entry_value (custom_size_height, size, 0);
+ stp_set_page_height (pv->v, size);
+ }
+ if (need_preview_update)
+ {
+ invalidate_preview_thumbnail();
+ invalidate_frame();
+ preview_update();
+ }
+ }
+ setting_media_size--;
+}
+
+static gboolean
+refresh_all_options(gpointer data)
+{
+ do_all_updates();
+ do_all_updates(); /* Update twice to pick up cascading changes */
+ return FALSE;
+}
+
+static void
+combo_callback(GtkWidget *widget, gpointer data)
+{
+ option_t *option = (option_t *)data;
+ const gchar *new_value =
+ stpui_combo_get_name(option->info.list.combo, option->info.list.params);
+ const gchar *value =
+ stp_get_string_parameter(pv->v, option->fast_desc->name);
+ if (value && new_value)
+ {
+ reset_preview();
+ if (!value || strcmp(value, new_value) != 0)
+ {
+ invalidate_frame();
+ invalidate_preview_thumbnail();
+ stp_set_string_parameter(pv->v, option->fast_desc->name, new_value);
+ if (strcmp(option->fast_desc->name, "PageSize") == 0)
+ set_media_size(new_value);
+ g_idle_add(refresh_all_options, NULL);
+ if (option->fast_desc->p_class == STP_PARAMETER_CLASS_OUTPUT)
+ update_adjusted_thumbnail();
+ preview_update();
+ }
+ }
+}
+
+/*
+ * orientation_callback() - Update the current media size.
+ */
+static void
+orientation_callback (GtkWidget *widget,
+ gpointer data)
+{
+ reset_preview ();
+
+ if (pv->orientation != (gint) data)
+ {
+ invalidate_preview_thumbnail ();
+ set_orientation((gint) data);
+ preview_update ();
+ }
+}
+
+/*
+ * output_type_callback() - Update the current output type.
+ */
+static void
+output_type_callback (GtkWidget *widget,
+ gpointer data)
+{
+ reset_preview ();
+
+ if (GTK_TOGGLE_BUTTON (widget)->active)
+ {
+ if (strcmp((const char *) data, "BW") == 0)
+ gtk_widget_hide(output_color_vbox);
+ else
+ gtk_widget_show(output_color_vbox);
+ stp_set_string_parameter(pv->v, "PrintingMode", (const char *) data);
+ invalidate_preview_thumbnail ();
+ update_adjusted_thumbnail ();
+ set_options_active(NULL);
+ preview_update ();
+ do_all_updates();
+ }
+}
+
+static void
+command_type_callback(GtkWidget *widget, gpointer data)
+{
+ if (strcmp((const char *) data, "Standard") == 0)
+ {
+ gtk_widget_set_sensitive(standard_cmd_entry, TRUE);
+ gtk_widget_set_sensitive(queue_combo, TRUE);
+ gtk_widget_set_sensitive(file_entry, FALSE);
+ gtk_entry_set_editable(GTK_ENTRY(file_entry), FALSE);
+ gtk_widget_set_sensitive(custom_command_entry, FALSE);
+ gtk_entry_set_editable(GTK_ENTRY(custom_command_entry), FALSE);
+ gtk_widget_hide(GTK_WIDGET(file_browser));
+ gtk_widget_set_sensitive(file_button, FALSE);
+ gtk_widget_set_sensitive(copy_count_spin_button, TRUE);
+ stpui_plist_set_command_type(pv, COMMAND_TYPE_DEFAULT);
+ }
+ else if (strcmp((const char *) data, "Custom") == 0)
+ {
+ gtk_widget_set_sensitive(standard_cmd_entry, FALSE);
+ gtk_widget_set_sensitive(queue_combo, FALSE);
+ gtk_widget_set_sensitive(file_entry, FALSE);
+ gtk_entry_set_editable(GTK_ENTRY(file_entry), FALSE);
+ gtk_widget_set_sensitive(custom_command_entry, TRUE);
+ gtk_entry_set_editable(GTK_ENTRY(custom_command_entry), TRUE);
+ gtk_widget_hide(GTK_WIDGET(file_browser));
+ gtk_widget_set_sensitive(file_button, FALSE);
+ gtk_widget_set_sensitive(copy_count_spin_button, FALSE);
+ stpui_plist_set_command_type(pv, COMMAND_TYPE_CUSTOM);
+ }
+ else if (strcmp((const char *) data, "File") == 0)
+ {
+ gtk_widget_set_sensitive(standard_cmd_entry, FALSE);
+ gtk_widget_set_sensitive(queue_combo, FALSE);
+ gtk_widget_set_sensitive(file_entry, TRUE);
+ gtk_entry_set_editable(GTK_ENTRY(file_entry), TRUE);
+ gtk_widget_set_sensitive(custom_command_entry, FALSE);
+ gtk_entry_set_editable(GTK_ENTRY(custom_command_entry), FALSE);
+ gtk_widget_set_sensitive(file_button, TRUE);
+ gtk_widget_set_sensitive(copy_count_spin_button, FALSE);
+ stpui_plist_set_command_type(pv, COMMAND_TYPE_FILE);
+ }
+}
+
+static void
+set_all_entry_values(void)
+{
+ set_entry_value (top_entry, (stp_get_top (pv->v)), 1);
+ set_entry_value (left_entry, (stp_get_left (pv->v)), 1);
+/*
+ set_entry_value (bottom_entry, (top + stp_get_top(pv->v) + print_height), 1);
+*/
+ set_entry_value (bottom_border_entry,
+ (paper_height - (stp_get_top (pv->v) + print_height)), 1);
+/*
+ set_entry_value (right_entry, (stp_get_left(pv->v) + print_width), 1);
+*/
+ set_entry_value (right_border_entry,
+ (paper_width - (stp_get_left (pv->v) + print_width)), 1);
+ set_entry_value (width_entry, print_width, 1);
+ set_entry_value (height_entry, print_height, 1);
+ set_entry_value (custom_size_width, stp_get_page_width (pv->v), 1);
+ set_entry_value (custom_size_height, stp_get_page_height (pv->v), 1);
+}
+
+/*
+ * unit_callback() - Update the current unit.
+ */
+static void
+unit_callback (GtkWidget *widget,
+ gpointer data)
+{
+ reset_preview ();
+
+ if (GTK_TOGGLE_BUTTON (widget)->active)
+ {
+ pv->unit = (gint) data;
+ gtk_label_set_text(GTK_LABEL(units_label), units[pv->unit].name);
+ set_all_entry_values();
+ update_options();
+ do_color_updates();
+ }
+}
+
+static void
+destroy_dialogs (void)
+{
+ int i;
+ gtk_widget_destroy (color_adjust_dialog);
+ gtk_widget_destroy (setup_dialog);
+ gtk_widget_destroy (print_dialog);
+ gtk_widget_destroy (new_printer_dialog);
+ gtk_widget_destroy (about_dialog);
+ for (i = 0; i < current_option_count; i++)
+ {
+ if (current_options[i].fast_desc->p_type == STP_PARAMETER_TYPE_CURVE &&
+ current_options[i].info.curve.dialog)
+ gtk_widget_destroy(current_options[i].info.curve.dialog);
+ }
+}
+
+static void
+dialogs_set_sensitive (gboolean sensitive)
+{
+ int i;
+ gtk_widget_set_sensitive (color_adjust_dialog, sensitive);
+ gtk_widget_set_sensitive (setup_dialog, sensitive);
+ gtk_widget_set_sensitive (print_dialog, sensitive);
+ gtk_widget_set_sensitive (new_printer_dialog, sensitive);
+ gtk_widget_set_sensitive (about_dialog, sensitive);
+ for (i = 0; i < current_option_count; i++)
+ {
+ if (current_options[i].fast_desc->p_type == STP_PARAMETER_TYPE_CURVE &&
+ current_options[i].info.curve.dialog)
+ gtk_widget_set_sensitive(current_options[i].info.curve.dialog,
+ sensitive);
+ }
+}
+
+/*
+ * 'print_callback()' - Start the print.
+ */
+static void
+print_callback (void)
+{
+ if (stpui_plist_get_command_type(pv) == COMMAND_TYPE_FILE &&
+ strlen(stpui_plist_get_output_filename(pv)) == 0)
+ {
+ dialogs_set_sensitive (FALSE);
+ exit_after_file_ok = 1;
+ gtk_widget_show (file_browser);
+ }
+ else
+ {
+ runme = TRUE;
+ destroy_dialogs ();
+ }
+}
+
+/*
+ * printandsave_callback() -
+ */
+static void
+printandsave_callback (void)
+{
+ saveme = TRUE;
+ print_callback();
+}
+
+static void
+about_callback (void)
+{
+ gtk_widget_show (about_dialog);
+}
+
+/*
+ * save_callback() - save settings, don't destroy dialog
+ */
+static void
+save_callback (void)
+{
+ reset_preview ();
+ stpui_printrc_save ();
+}
+
+/*
+ * setup_update() - update widgets in the setup dialog
+ */
+static void
+setup_update (void)
+{
+ GtkAdjustment *adjustment;
+ gint idx = 0;
+ gint i;
+ gchar *tmp;
+ const char *ppd_file_name = stp_get_file_parameter(pv->v, "PPDFile");
+
+ for (i = 0; i < GTK_CLIST(manufacturer_clist)->rows; i++)
+ {
+ (void) gtk_clist_get_text(GTK_CLIST(manufacturer_clist), i, 0, &tmp);
+ if (tmp && strcmp(manufacturer, tmp) == 0)
+ {
+ idx = i;
+ break;
+ }
+ }
+ gtk_clist_select_row(GTK_CLIST(manufacturer_clist), idx, 0);
+
+ idx = stp_get_printer_index_by_driver (stp_get_driver (pv->v));
+
+ idx = gtk_clist_find_row_from_data(GTK_CLIST(printer_driver),
+ (gpointer) idx);
+/*
+ if (idx >= 0)
+ idx = 0;
+*/
+ gtk_clist_select_row (GTK_CLIST (printer_driver), idx, 0);
+ gtk_label_set_text (GTK_LABEL (printer_model_label),
+ gettext (stp_printer_get_long_name (tmp_printer)));
+
+ if (ppd_file_name)
+ gtk_entry_set_text (GTK_ENTRY (ppd_file), ppd_file_name);
+ else
+ gtk_entry_set_text (GTK_ENTRY (ppd_file), "");
+
+ if (stp_parameter_find_in_settings(pv->v, "PPDFile"))
+ {
+ gtk_widget_show (ppd_box);
+ gtk_widget_show (ppd_label);
+ }
+ else
+ {
+ gtk_widget_hide (ppd_box);
+ gtk_widget_hide (ppd_label);
+ }
+ gtk_entry_set_text (GTK_ENTRY (custom_command_entry),
+ stpui_plist_get_custom_command (pv));
+
+ adjustment = GTK_CLIST (printer_driver)->vadjustment;
+ gtk_adjustment_set_value
+ (adjustment,
+ adjustment->lower + idx * (adjustment->upper - adjustment->lower) /
+ GTK_CLIST (printer_driver)->rows);
+
+ i = stpui_plist_get_command_type(pv);
+ if (i >= 0 && i < command_options_count)
+ gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(command_options[i].button),
+ TRUE);
+}
+
+/*
+ * setup_open_callback() -
+ */
+static void
+setup_open_callback (void)
+{
+ static gboolean first_time = TRUE;
+ manufacturer = stp_printer_get_manufacturer(stp_get_printer(pv->v));
+ build_printer_driver_clist();
+
+ reset_preview ();
+ setup_update ();
+
+/* gtk_widget_set_sensitive(GTK_DIALOG(print_dialog)->action_area, FALSE); */
+ gtk_widget_show (setup_dialog);
+
+ if (first_time)
+ {
+ /* Make sure the driver scroller gets positioned correctly. */
+ setup_update ();
+ first_time = FALSE;
+ }
+}
+
+/*
+ * new_printer_open_callback() -
+ */
+static void
+new_printer_open_callback (void)
+{
+ reset_preview ();
+ gtk_entry_set_text (GTK_ENTRY (new_printer_entry), "");
+ gtk_widget_show (new_printer_dialog);
+}
+
+static void
+set_printer(void)
+{
+ manufacturer = stp_printer_get_manufacturer(tmp_printer);
+ build_printer_driver_clist();
+ build_queue_combo();
+ stp_set_driver (pv->v, stp_printer_get_driver (tmp_printer));
+ stpui_plist_set_custom_command
+ (pv, gtk_entry_get_text (GTK_ENTRY (custom_command_entry)));
+ stpui_plist_set_output_filename
+ (pv, gtk_entry_get_text (GTK_ENTRY (file_entry)));
+ stp_set_file_parameter (pv->v, "PPDFile",
+ gtk_entry_get_text (GTK_ENTRY (ppd_file)));
+ gtk_label_set_text (GTK_LABEL (printer_model_label),
+ gettext (stp_printer_get_long_name (tmp_printer)));
+
+ plist_callback (NULL, (gpointer) stpui_plist_current);
+}
+
+/*
+ * setup_ok_callback() -
+ */
+static void
+setup_ok_callback (void)
+{
+ gtk_widget_hide(ppd_browser);
+ gtk_widget_hide(file_browser);
+ gtk_widget_hide(setup_dialog);
+ set_printer();
+ gtk_widget_set_sensitive(GTK_DIALOG(print_dialog)->action_area, TRUE);
+}
+
+/*
+ * setup_cancel_callback() -
+ */
+static void
+setup_cancel_callback (void)
+{
+ gtk_widget_hide(ppd_browser);
+ gtk_widget_hide(file_browser);
+ gtk_widget_hide(setup_dialog);
+ manufacturer = stp_printer_get_manufacturer(stp_get_printer(pv->v));
+ build_printer_driver_clist();
+ setup_update();
+ gtk_widget_set_sensitive(GTK_DIALOG(print_dialog)->action_area, TRUE);
+}
+
+/*
+ * setup_ok_callback() -
+ */
+static void
+new_printer_ok_callback (void)
+{
+ const gchar *data = gtk_entry_get_text (GTK_ENTRY (new_printer_entry));
+ stpui_plist_t key;
+
+ if (strlen(data))
+ {
+ memset(&key, 0, sizeof(key));
+ stpui_printer_initialize (&key);
+ stpui_plist_copy(&key, pv);
+ stpui_plist_set_name(&key, data);
+
+ if (stpui_plist_add (&key, 1))
+ {
+ stp_vars_destroy(key.v);
+ g_free(key.name);
+ stpui_plist_current = stpui_plist_count - 1;
+ set_current_printer();
+ build_printer_combo ();
+ set_printer();
+ }
+ }
+
+ gtk_widget_hide (new_printer_dialog);
+}
+
+static void
+pop_ppd_box(void)
+{
+ const stp_vars_t *v = stp_printer_get_defaults(tmp_printer);
+ if (stp_parameter_find_in_settings(v, "PPDFile"))
+ {
+ gtk_widget_show (ppd_label);
+ gtk_widget_show (ppd_box);
+ }
+ else
+ {
+ gtk_widget_hide (ppd_label);
+ gtk_widget_hide (ppd_box);
+ }
+}
+
+static void
+build_printer_driver_clist(void)
+{
+ int i;
+ int current_idx = 0;
+ gtk_clist_clear(GTK_CLIST(printer_driver));
+ for (i = 0; i < stp_printer_model_count (); i ++)
+ {
+ const stp_printer_t *the_printer = stp_get_printer_by_index (i);
+
+ if (strcmp(manufacturer, stp_printer_get_manufacturer(the_printer)) == 0)
+ {
+ gchar *tmp=g_strdup(gettext(stp_printer_get_long_name(the_printer)));
+ /*
+ * FIXME Somehow if the raw printer comes before any of the
+ * "real" printers in the list of printers created in module.c,
+ * this code barfs on any of those printers added later. For
+ * example, try listing olympus_LTX_stpi_module_data after
+ * raw_LTX_stpi_module_data.
+ */
+
+ gtk_clist_insert (GTK_CLIST (printer_driver), current_idx, &tmp);
+ gtk_clist_set_row_data (GTK_CLIST (printer_driver), current_idx,
+ (gpointer) i);
+ g_free(tmp);
+ current_idx++;
+ }
+ }
+}
+
+static void
+manufacturer_callback(GtkWidget *widget, /* I - Driver list */
+ gint row,
+ gint column,
+ GdkEventButton *event,
+ gpointer data)
+{
+ static int calling_manufacturer_callback = 0;
+ gchar *text;
+ if (calling_manufacturer_callback)
+ return;
+ calling_manufacturer_callback++;
+ if (gtk_clist_get_text(GTK_CLIST(widget), row, column, &text))
+ manufacturer = text;
+ build_printer_driver_clist();
+ setup_update();
+ calling_manufacturer_callback--;
+}
+
+/*
+ * print_driver_callback() - Update the current printer driver.
+ */
+static void
+print_driver_callback (GtkWidget *widget, /* I - Driver list */
+ gint row,
+ gint column,
+ GdkEventButton *event,
+ gpointer data) /* I - Data */
+{
+ char *tmp;
+ static int calling_print_driver_callback = 0;
+ if (calling_print_driver_callback)
+ return;
+ calling_print_driver_callback++;
+ invalidate_frame ();
+ invalidate_preview_thumbnail ();
+ reset_preview ();
+ data = gtk_clist_get_row_data (GTK_CLIST (widget), row);
+ tmp_printer = stp_get_printer_by_index ((gint) data);
+ tmp = stpui_build_standard_print_command(pv, tmp_printer);
+ gtk_entry_set_text(GTK_ENTRY(standard_cmd_entry), tmp);
+ g_free(tmp);
+
+ pop_ppd_box();
+ calling_print_driver_callback--;
+}
+
+/*
+ * ppd_browse_callback() -
+ */
+static void
+ppd_browse_callback (void)
+{
+ reset_preview ();
+ gtk_file_selection_set_filename (GTK_FILE_SELECTION (ppd_browser),
+ gtk_entry_get_text (GTK_ENTRY (ppd_file)));
+ gtk_widget_show (ppd_browser);
+}
+
+/*
+ * ppd_ok_callback() -
+ */
+static void
+ppd_ok_callback (void)
+{
+ reset_preview ();
+ gtk_widget_hide (ppd_browser);
+ gtk_entry_set_text
+ (GTK_ENTRY (ppd_file),
+ gtk_file_selection_get_filename (GTK_FILE_SELECTION (ppd_browser)));
+}
+
+/*
+ * ppd_browse_callback() -
+ */
+static void
+file_browse_callback (void)
+{
+ reset_preview ();
+ gtk_file_selection_set_filename (GTK_FILE_SELECTION (file_browser),
+ gtk_entry_get_text (GTK_ENTRY (file_entry)));
+ gtk_widget_show (file_browser);
+}
+
+/*
+ * file_ok_callback() - print to file and go away
+ */
+static void
+file_ok_callback (void)
+{
+ const char *filename =
+ gtk_file_selection_get_filename(GTK_FILE_SELECTION(file_browser));
+ gtk_widget_hide (file_browser);
+ gtk_entry_set_text(GTK_ENTRY(file_entry), filename);
+ stpui_plist_set_output_filename(pv, filename);
+ if (exit_after_file_ok)
+ {
+ runme = TRUE;
+ destroy_dialogs ();
+ }
+}
+
+/*
+ * file_cancel_callback() -
+ */
+static void
+file_cancel_callback (void)
+{
+ exit_after_file_ok = 0;
+ gtk_widget_hide (file_browser);
+ dialogs_set_sensitive (TRUE);
+}
+
+static void
+fill_buffer_writefunc(void *priv, const char *buffer, size_t bytes)
+{
+ int mask = 0;
+ int i;
+ int pixels = bytes / 4;
+ priv_t *p = (priv_t *) priv;
+ unsigned char *where = p->base_addr + p->offset;
+ const unsigned char *xbuffer = (const unsigned char *)buffer;
+
+ if (p->bpp == 1)
+ {
+ memcpy(where, buffer, bytes);
+ p->offset += bytes;
+ }
+ else
+ {
+ if (bytes + p->offset > p->limit)
+ bytes = p->limit - p->offset;
+ if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(cyan_button)))
+ mask |= 1;
+ if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(magenta_button)))
+ mask |= 2;
+ if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(yellow_button)))
+ mask |= 4;
+ if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(black_button)))
+ mask |= 8;
+
+ memset(where, 0xff, pixels * 3);
+ for (i = 0; i < pixels; i++)
+ {
+ if (mask & 8)
+ {
+ where[0] -= xbuffer[3];
+ where[1] -= xbuffer[3];
+ where[2] -= xbuffer[3];
+ }
+ if (mask & 1)
+ {
+ if (where[0] < xbuffer[0])
+ where[0] = 0;
+ else
+ where[0] -= xbuffer[0];
+ }
+ if (mask & 2)
+ {
+ if (where[1] < xbuffer[1])
+ where[1] = 0;
+ else
+ where[1] -= xbuffer[1];
+ }
+ if (mask & 4)
+ {
+ if (where[2] < xbuffer[2])
+ where[2] = 0;
+ else
+ where[2] -= xbuffer[2];
+ }
+ where += 3;
+ xbuffer += 4;
+ }
+ p->offset += pixels * 3;
+ }
+}
+
+/*
+ * update_adjusted_thumbnail()
+ */
+
+static void
+redraw_color_swatch (void)
+{
+ static GdkGC *gc = NULL;
+ static GdkColormap *cmap;
+
+ if (adjusted_thumbnail_data && swatch && swatch->widget.window)
+ {
+ if (gc == NULL)
+ {
+ gc = gdk_gc_new (swatch->widget.window);
+ cmap = gtk_widget_get_colormap (GTK_WIDGET(swatch));
+ }
+
+ if (!print_mode_is_color(pv->v))
+ gdk_draw_gray_image(swatch->widget.window, gc, 0, 0,
+ thumbnail_w, thumbnail_h, GDK_RGB_DITHER_NORMAL,
+ adjusted_thumbnail_data, thumbnail_w);
+ else
+ gdk_draw_rgb_image(swatch->widget.window, gc, 0, 0,
+ thumbnail_w, thumbnail_h, GDK_RGB_DITHER_NORMAL,
+ adjusted_thumbnail_data, 3 * thumbnail_w);
+ }
+}
+
+static void
+initialize_thumbnail(void)
+{
+ int i;
+ if (stpui_get_thumbnail_func())
+ {
+ const guchar *internal_thumbnail_data;
+ /*
+ * Fetch a thumbnail of the image we're to print from the Gimp.
+ */
+
+ thumbnail_w = thumbnail_hintw;
+ thumbnail_h = thumbnail_hinth;
+ internal_thumbnail_data =
+ (stpui_get_thumbnail_func()) (stpui_get_thumbnail_data(), &thumbnail_w,
+ &thumbnail_h, &thumbnail_bpp, 0);
+ if (adjusted_thumbnail_data)
+ g_free(adjusted_thumbnail_data);
+ if (preview_thumbnail_data)
+ g_free(preview_thumbnail_data);
+ if (thumbnail_data)
+ g_free(thumbnail_data);
+
+ if (internal_thumbnail_data)
+ {
+ /*
+ * thumbnail_w and thumbnail_h have now been adjusted to the actual
+ * thumbnail dimensions. Now initialize a color-adjusted version of
+ * the thumbnail.
+ */
+
+ adjusted_thumbnail_data = g_malloc (3 * thumbnail_w * thumbnail_h);
+ preview_thumbnail_data = g_malloc (3 * thumbnail_w * thumbnail_h);
+ thumbnail_data = g_malloc (3 * thumbnail_w * thumbnail_h);
+
+ switch (thumbnail_bpp)
+ {
+ case 1:
+ for (i = 0; i < thumbnail_w * thumbnail_h; i++)
+ {
+ gint val = internal_thumbnail_data[i];
+ thumbnail_data[(3 * i) + 0] = val;
+ thumbnail_data[(3 * i) + 1] = val;
+ thumbnail_data[(3 * i) + 2] = val;
+ }
+ break;
+ case 3:
+ memcpy(thumbnail_data, internal_thumbnail_data,
+ 3 * thumbnail_w * thumbnail_h);
+ break;
+ case 2:
+ for (i = 0; i < thumbnail_w * thumbnail_h; i++)
+ {
+ gint val = internal_thumbnail_data[2 * i];
+ gint alpha = internal_thumbnail_data[(2 * i) + 1];
+ thumbnail_data[(3 * i) +0] = val * alpha / 255 + 255 - alpha;
+ thumbnail_data[(3 * i) +1] = val * alpha / 255 + 255 - alpha;
+ thumbnail_data[(3 * i) +2] = val * alpha / 255 + 255 - alpha;
+ }
+ break;
+ case 4:
+ for (i = 0; i < thumbnail_w * thumbnail_h; i++)
+ {
+ gint r = internal_thumbnail_data[(4 * i)];
+ gint g = internal_thumbnail_data[(4 * i) + 1];
+ gint b = internal_thumbnail_data[(4 * i) + 2];
+ gint alpha = internal_thumbnail_data[(4 * i) + 3];
+ thumbnail_data[(3 * i) + 0] = r * alpha / 255 + 255 - alpha;
+ thumbnail_data[(3 * i) + 1] = g * alpha / 255 + 255 - alpha;
+ thumbnail_data[(3 * i) + 2] = b * alpha / 255 + 255 - alpha;
+ }
+ break;
+ default:
+ break;
+ /* Whatever */
+ }
+ thumbnail_bpp = 3;
+ }
+ else
+ {
+ thumbnail_h = 0;
+ thumbnail_w = 0;
+ }
+ }
+ else
+ {
+ thumbnail_h = 0;
+ thumbnail_w = 0;
+ }
+}
+
+static int
+compute_thumbnail(const stp_vars_t *v)
+{
+ priv_t priv;
+ int answer = 1;
+ stp_image_t *im = stpui_image_thumbnail_new(thumbnail_data, thumbnail_w,
+ thumbnail_h, thumbnail_bpp);
+ stp_vars_t *nv = stp_vars_create_copy(v);
+ stp_set_driver(nv, "raw-data-8");
+ stp_set_top(nv, 0);
+ stp_set_left(nv, 0);
+ stp_set_width(nv, thumbnail_w);
+ stp_set_height(nv, thumbnail_h);
+ stp_set_outfunc(nv, fill_buffer_writefunc);
+ stp_set_outdata(nv, &priv);
+ stp_set_errfunc(nv, stpui_get_errfunc());
+ stp_set_errdata(nv, stpui_get_errdata());
+ if (!print_mode_is_color(nv))
+ {
+ priv.bpp = 1;
+ stp_set_string_parameter(nv, "InkType", "RGBGray");
+ }
+ else
+ {
+ priv.bpp = 4;
+ stp_set_string_parameter(nv, "InkType", "CMYK");
+ }
+ stp_set_page_height(nv, thumbnail_h);
+ stp_set_page_width(nv, thumbnail_w);
+ stp_set_float_parameter(nv, "Density", 1.0);
+ stp_set_float_parameter(nv, "InkLimit", 0);
+ stp_set_string_parameter(nv, "InputImageType", "RGB");
+
+ priv.base_addr = adjusted_thumbnail_data;
+ priv.offset = 0;
+ priv.limit = thumbnail_bpp * thumbnail_h * thumbnail_w;
+
+ if (stp_verify(nv) != 1 || stp_print(nv, im) != 1)
+ {
+ answer = 0;
+ fprintf(stderr, "Could not print thumbnail!\n");
+ }
+ stp_vars_destroy(nv);
+ return answer;
+}
+
+static void
+set_thumbnail_orientation(void)
+{
+ gint x, y;
+ gint preview_limit = (thumbnail_h * thumbnail_w) - 1;
+ gint bpp;
+ if (!print_mode_is_color(pv->v))
+ bpp = 1;
+ else
+ bpp = 3;
+ switch (physical_orientation)
+ {
+ case ORIENT_PORTRAIT:
+ memcpy(preview_thumbnail_data, adjusted_thumbnail_data,
+ bpp * thumbnail_h * thumbnail_w);
+ break;
+ case ORIENT_SEASCAPE:
+ for (x = 0; x < thumbnail_w; x++)
+ for (y = 0; y < thumbnail_h; y++)
+ memcpy((preview_thumbnail_data +
+ bpp * (preview_limit - (x * thumbnail_h + y))),
+ (adjusted_thumbnail_data +
+ bpp * ((thumbnail_h - y - 1) * thumbnail_w + x)), bpp);
+ break;
+
+ case ORIENT_UPSIDEDOWN:
+ for (x = 0; x < thumbnail_h * thumbnail_w; x++)
+ memcpy((preview_thumbnail_data + bpp * (preview_limit - x)),
+ adjusted_thumbnail_data + bpp * x, bpp);
+ break;
+ case ORIENT_LANDSCAPE:
+ for (x = 0; x < thumbnail_w; x++)
+ for (y = 0; y < thumbnail_h; y++)
+ memcpy((preview_thumbnail_data + bpp * (x * thumbnail_h + y)),
+ (adjusted_thumbnail_data +
+ bpp * ((thumbnail_h - y - 1) * thumbnail_w + x)), bpp);
+ break;
+ }
+}
+
+static void
+update_adjusted_thumbnail (void)
+{
+ if (thumbnail_data && adjusted_thumbnail_data && do_update_thumbnail &&
+ suppress_preview_update == 0)
+ {
+ if (compute_thumbnail(pv->v))
+ {
+ set_thumbnail_orientation();
+ redraw_color_swatch ();
+ preview_update ();
+ }
+ }
+}
+
+static void
+draw_arrow (GdkWindow *w,
+ GdkGC *gc,
+ gint paper_left,
+ gint paper_top)
+{
+ gint u = preview_ppi/2;
+ gint ox = paper_left + preview_ppi * paper_width / INCH / 2;
+ gint oy = paper_top + preview_ppi * paper_height / INCH / 2;
+
+ oy -= preview_ppi * paper_height / INCH / 4;
+ if (oy < paper_top + u)
+ oy = paper_top + u;
+ gdk_draw_line (w, gc, ox, oy - u, ox - u, oy);
+ gdk_draw_line (w, gc, ox, oy - u, ox + u, oy);
+ gdk_draw_line (w, gc, ox, oy - u, ox, oy + u);
+}
+
+static void
+create_valid_preview(guchar **preview_data)
+{
+ if (adjusted_thumbnail_data)
+ {
+ gint bpp = (print_mode_is_color(pv->v)) ? 3 : 1;
+ gint v_denominator = preview_h > 1 ? preview_h - 1 : 1;
+ gint v_numerator = (preview_thumbnail_h - 1) % v_denominator;
+ gint v_whole = (preview_thumbnail_h - 1) / v_denominator;
+ gint h_denominator = preview_w > 1 ? preview_w - 1 : 1;
+ gint h_numerator = (preview_thumbnail_w - 1) % h_denominator;
+ gint h_whole = (preview_thumbnail_w - 1) / h_denominator;
+ gint adjusted_preview_width = bpp * preview_w;
+ gint adjusted_thumbnail_width = bpp * preview_thumbnail_w;
+ gint v_cur = 0;
+ gint v_last = -1;
+ gint v_error = v_denominator / 2;
+ gint y;
+ gint i;
+
+ if (*preview_data)
+ g_free (*preview_data);
+ *preview_data = g_malloc (bpp * preview_h * preview_w);
+
+ for (y = 0; y < preview_h; y++)
+ {
+ guchar *outbuf = *preview_data + adjusted_preview_width * y;
+
+ if (v_cur == v_last)
+ memcpy (outbuf, outbuf-adjusted_preview_width,
+ adjusted_preview_width);
+ else
+ {
+ guchar *inbuf = preview_thumbnail_data - bpp
+ + adjusted_thumbnail_width * v_cur;
+
+ gint h_cur = 0;
+ gint h_last = -1;
+ gint h_error = h_denominator / 2;
+ gint x;
+
+ v_last = v_cur;
+ for (x = 0; x < preview_w; x++)
+ {
+ if (h_cur == h_last)
+ {
+ for (i = 0; i < bpp; i++)
+ outbuf[i] = outbuf[i - bpp];
+ }
+ else
+ {
+ inbuf += bpp * (h_cur - h_last);
+ h_last = h_cur;
+ for (i = 0; i < bpp; i++)
+ outbuf[i] = inbuf[i];
+ }
+ outbuf += bpp;
+ h_cur += h_whole;
+ h_error += h_numerator;
+ if (h_error >= h_denominator)
+ {
+ h_error -= h_denominator;
+ h_cur++;
+ }
+ }
+ }
+ v_cur += v_whole;
+ v_error += v_numerator;
+ if (v_error >= v_denominator)
+ {
+ v_error -= v_denominator;
+ v_cur++;
+ }
+ }
+ preview_valid = TRUE;
+ }
+}
+
+/*
+ * preview_update_callback() -
+ */
+static void
+do_preview_thumbnail (void)
+{
+ static GdkGC *gc = NULL;
+ static GdkGC *gcinv = NULL;
+ static GdkGC *gcset = NULL;
+ static guchar *preview_data = NULL;
+ gint opx = preview_x;
+ gint opy = preview_y;
+ gint oph = preview_h;
+ gint opw = preview_w;
+ gint paper_display_left, paper_display_top;
+ gint printable_display_left, printable_display_top;
+ gint paper_display_width, paper_display_height;
+ gint printable_display_width, printable_display_height;
+ int l_bottom = stp_get_top(pv->v) + stp_get_height(pv->v);
+ int l_right = stp_get_left(pv->v) + stp_get_width(pv->v);
+
+ preview_ppi = preview_size_horiz * FINCH / (gdouble) paper_width;
+
+ if (preview_ppi > preview_size_vert * FINCH / (gdouble) paper_height)
+ preview_ppi = preview_size_vert * FINCH / (gdouble) paper_height;
+ if (preview_ppi > MAX_PREVIEW_PPI)
+ preview_ppi = MAX_PREVIEW_PPI;
+
+ if (preview == NULL || preview->widget.window == NULL)
+ return;
+ /*
+ * Center the page on the preview
+ */
+ paper_display_width = MAX(3, ROUNDUP(preview_ppi * paper_width, INCH));
+ paper_display_height = MAX(3, ROUNDUP(preview_ppi * paper_height, INCH));
+
+ paper_display_left = (preview_size_horiz - paper_display_width) / 2;
+ paper_display_top = (preview_size_vert - paper_display_height) / 2;
+
+ printable_display_width =
+ MAX(3, ROUNDUP(preview_ppi * printable_width, INCH));
+ printable_display_height =
+ MAX(3, ROUNDUP(preview_ppi * printable_height, INCH));
+
+ printable_display_left = paper_display_left + preview_ppi * left / INCH;
+ printable_display_top = paper_display_top + preview_ppi * top / INCH ;
+
+ preview_x =
+ 1 + paper_display_left + preview_ppi * stp_get_left (pv->v) / INCH;
+ preview_y =
+ 1 + paper_display_top + preview_ppi * stp_get_top (pv->v) / INCH;
+
+ if (!preview_valid)
+ {
+ gint preview_r = 1 + paper_display_left + preview_ppi * l_right / INCH;
+ gint preview_b = 1 + paper_display_top + preview_ppi * l_bottom / INCH;
+ preview_w = preview_r - preview_x;
+ preview_h = preview_b - preview_y;
+ if (preview_w >= printable_display_width)
+ preview_w = printable_display_width - 1;
+ if (preview_h >= printable_display_height)
+ preview_h = printable_display_height - 1;
+ }
+
+ if (preview_w + preview_x > printable_display_left + printable_display_width)
+ preview_x--;
+ if (preview_h + preview_y > printable_display_top + printable_display_height)
+ preview_y--;
+
+ if (gc == NULL)
+ {
+ gc = gdk_gc_new (preview->widget.window);
+ gcinv = gdk_gc_new (preview->widget.window);
+ gdk_gc_set_function (gcinv, GDK_INVERT);
+ gcset = gdk_gc_new (preview->widget.window);
+ gdk_gc_set_function (gcset, GDK_SET);
+ }
+
+ if (!preview_valid)
+ create_valid_preview(&preview_data);
+
+ if (printable_display_left < paper_display_left)
+ printable_display_left = paper_display_left;
+ if (printable_display_top < paper_display_top)
+ printable_display_top = paper_display_top;
+ if (printable_display_left + printable_display_width >
+ paper_display_left + paper_display_width)
+ printable_display_width =
+ paper_display_width - (paper_display_left - printable_display_left);
+ if (printable_display_top + printable_display_height >
+ paper_display_top + paper_display_height)
+ printable_display_height =
+ paper_display_height - (paper_display_top - printable_display_top);
+ if (need_exposure)
+ {
+ if (!frame_valid)
+ {
+ gdk_window_clear (preview->widget.window);
+ frame_valid = TRUE;
+ }
+ /* draw paper frame */
+ gdk_draw_rectangle (preview->widget.window, gc, 0,
+ paper_display_left, paper_display_top,
+ paper_display_width, paper_display_height);
+
+ /* draw printable frame */
+ gdk_draw_rectangle (preview->widget.window, gc, 0,
+ printable_display_left, printable_display_top,
+ printable_display_width, printable_display_height);
+ need_exposure = FALSE;
+ }
+ else if (!frame_valid)
+ {
+ gdk_window_clear (preview->widget.window);
+ /* draw paper frame */
+ gdk_draw_rectangle (preview->widget.window, gc, 0,
+ paper_display_left, paper_display_top,
+ paper_display_width, paper_display_height);
+
+ /* draw printable frame */
+ gdk_draw_rectangle (preview->widget.window, gc, 0,
+ printable_display_left, printable_display_top,
+ printable_display_width, printable_display_height);
+ frame_valid = TRUE;
+ }
+ else
+ {
+ if (opx + opw <= preview_x || opy + oph <= preview_y ||
+ preview_x + preview_w <= opx || preview_y + preview_h <= opy)
+ {
+ gdk_window_clear_area (preview->widget.window, opx, opy, opw, oph);
+ }
+ else
+ {
+ if (opx < preview_x)
+ gdk_window_clear_area (preview->widget.window,
+ opx, opy, preview_x - opx, oph);
+ if (opy < preview_y)
+ gdk_window_clear_area (preview->widget.window,
+ opx, opy, opw, preview_y - opy);
+ if (opx + opw > preview_x + preview_w)
+ gdk_window_clear_area (preview->widget.window,
+ preview_x + preview_w, opy,
+ (opx + opw) - (preview_x + preview_w), oph);
+ if (opy + oph > preview_y + preview_h)
+ gdk_window_clear_area (preview->widget.window,
+ opx, preview_y + preview_h,
+ opw, (opy + oph) - (preview_y + preview_h));
+ }
+ }
+
+ draw_arrow (preview->widget.window, gcset, paper_display_left,
+ paper_display_top);
+
+ if (!preview_valid)
+ gdk_draw_rectangle (preview->widget.window, gc, 1,
+ preview_x, preview_y, preview_w, preview_h);
+ else if (!print_mode_is_color(pv->v))
+ gdk_draw_gray_image (preview->widget.window, gc,
+ preview_x, preview_y, preview_w, preview_h,
+ GDK_RGB_DITHER_NORMAL, preview_data, preview_w);
+ else
+ gdk_draw_rgb_image (preview->widget.window, gc,
+ preview_x, preview_y, preview_w, preview_h,
+ GDK_RGB_DITHER_NORMAL, preview_data, 3 * preview_w);
+
+ /* If we're printing full bleed, redisplay the paper frame */
+ if (preview_x <= paper_display_left || opx <= paper_display_left ||
+ preview_y <= paper_display_top || opy <= paper_display_top ||
+ preview_x + preview_w >= paper_display_left + paper_display_width ||
+ opx + opw >= paper_display_left + paper_display_width ||
+ preview_y + preview_h >= paper_display_top + paper_display_height ||
+ opy + oph >= paper_display_top + paper_display_height)
+ gdk_draw_rectangle (preview->widget.window, gc, 0,
+ paper_display_left, paper_display_top,
+ paper_display_width, paper_display_height);
+
+
+ /* draw orientation arrow pointing to top-of-paper */
+ draw_arrow (preview->widget.window, gcinv, paper_display_left,
+ paper_display_top);
+ gdk_flush();
+}
+
+static gboolean
+idle_preview_thumbnail(gpointer data)
+{
+ set_orientation(pv->orientation);
+ do_preview_thumbnail();
+ thumbnail_update_pending = FALSE;
+ return FALSE;
+}
+
+static void
+preview_expose (void)
+{
+ need_exposure = TRUE;
+ preview_update ();
+}
+
+static void
+preview_update (void)
+{
+ gdouble max_ppi_scaling; /* Maximum PPI for current page size */
+ gdouble min_ppi_scaling; /* Minimum PPI for current page size */
+
+ suppress_preview_update++;
+ stp_get_media_size(pv->v, &paper_width, &paper_height);
+
+ stp_get_imageable_area(pv->v, &left, &right, &bottom, &top);
+
+ printable_width = right - left;
+ printable_height = bottom - top;
+
+ if (pv->scaling < 0)
+ {
+ gdouble twidth;
+
+ compute_scaling_limits(&min_ppi_scaling, &max_ppi_scaling);
+
+ if (pv->scaling < 0 && pv->scaling > -min_ppi_scaling)
+ pv->scaling = -min_ppi_scaling;
+
+ twidth = (FINCH * (gdouble) image_width / -pv->scaling);
+ print_width = twidth + .5;
+ print_height = (twidth * (gdouble) image_height / image_width) + .5;
+ GTK_ADJUSTMENT (scaling_adjustment)->lower = min_ppi_scaling;
+ GTK_ADJUSTMENT (scaling_adjustment)->upper = max_ppi_scaling;
+ GTK_ADJUSTMENT (scaling_adjustment)->value = -pv->scaling;
+
+ if (!suppress_scaling_adjustment)
+ {
+ suppress_preview_reset++;
+ gtk_adjustment_changed (GTK_ADJUSTMENT (scaling_adjustment));
+ suppress_scaling_callback = TRUE;
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (scaling_ppi), TRUE);
+ suppress_scaling_callback = FALSE;
+ gtk_adjustment_value_changed (GTK_ADJUSTMENT (scaling_adjustment));
+ suppress_preview_reset--;
+ }
+ }
+ else if (auto_paper_size)
+ {
+ gdouble twidth = printable_width * pv->scaling / 100;
+
+ print_width = twidth + .5;
+ print_height =
+ (twidth * (gdouble) image_height / (gdouble) image_width) + .5;
+ }
+ else
+ {
+ /* we do pv->scaling % of height or width, whatever is less */
+ /* this is relative to printable size */
+ if (image_width * printable_height > printable_width * image_height)
+ /* if image_width/image_height > printable_width/printable_height */
+ /* i.e. if image is wider relative to its height than the width
+ of the printable area relative to its height */
+ {
+ gdouble twidth = printable_width * pv->scaling / 100;
+
+ print_width = twidth + .5;
+ print_height =
+ (twidth * (gdouble) image_height / (gdouble) image_width) + .5;
+ }
+ else
+ {
+ gdouble theight = printable_height * pv->scaling /100;
+
+ print_height = theight + .5;
+ print_width =
+ (theight * (gdouble) image_width / (gdouble) image_height) + .5;
+ }
+ }
+
+ if (auto_paper_size)
+ set_media_size(stp_get_string_parameter(pv->v, "PageSize"));
+
+ stp_set_width(pv->v, print_width);
+ stp_set_height(pv->v, print_height);
+
+ if (pv->invalid_mask & INVALID_LEFT)
+ stp_set_left (pv->v, (paper_width - print_width) / 2);
+
+ if (stp_get_left(pv->v) < left)
+ stp_set_left(pv->v, left);
+
+ if (stp_get_left (pv->v) > right - print_width)
+ stp_set_left (pv->v, right - print_width);
+
+ if (pv->invalid_mask & INVALID_TOP)
+ stp_set_top (pv->v, ((paper_height - print_height) / 2));
+ if (stp_get_top(pv->v) < top)
+ stp_set_top(pv->v, top);
+
+ if (stp_get_top (pv->v) > bottom - print_height)
+ stp_set_top (pv->v, bottom - print_height);
+
+ pv->invalid_mask = 0;
+
+ set_all_entry_values();
+ suppress_preview_update--;
+
+ /* draw image */
+ if (! suppress_preview_update && !thumbnail_update_pending)
+ {
+ thumbnail_update_pending = TRUE;
+ g_idle_add(idle_preview_thumbnail, NULL);
+ }
+}
+
+/*
+ * preview_button_callback() -
+ */
+static void
+preview_button_callback (GtkWidget *widget,
+ GdkEventButton *event,
+ gpointer data)
+{
+ if (event->type == GDK_BUTTON_PRESS)
+ {
+ if (preview_active == 0)
+ {
+ mouse_x = event->x;
+ mouse_y = event->y;
+ orig_left = stp_get_left (pv->v);
+ orig_top = stp_get_top (pv->v);
+ mouse_button = event->button;
+ buttons_mask = 1 << event->button;
+ buttons_pressed++;
+ preview_active = 1;
+ stpui_disable_help();
+ move_constraint =
+ (event->state & GDK_SHIFT_MASK) ? MOVE_CONSTRAIN : MOVE_ANY;
+ if (event->state & GDK_CONTROL_MASK)
+ move_constraint |= MOVE_GRID;
+ }
+ else if ((buttons_mask & (1 << event->button)) == 0)
+ {
+ if (preview_active == 1)
+ {
+ stpui_enable_help();
+ preview_active = -1;
+ stp_set_left (pv->v, orig_left);
+ stp_set_top (pv->v, orig_top);
+ preview_update ();
+ }
+ buttons_mask |= 1 << event->button;
+ buttons_pressed++;
+ }
+ }
+ else if (event->type == GDK_BUTTON_RELEASE)
+ {
+ buttons_pressed--;
+ buttons_mask &= ~(1 << event->button);
+ if (buttons_pressed == 0)
+ {
+ stpui_enable_help ();
+ preview_active = 0;
+ }
+ }
+}
+
+/*
+ * preview_motion_callback() -
+ */
+static void
+preview_motion_callback (GtkWidget *widget,
+ GdkEventMotion *event,
+ gpointer data)
+{
+
+ gint old_top = stp_get_top (pv->v);
+ gint old_left = stp_get_left (pv->v);
+ gint new_top = old_top;
+ gint new_left = old_left;
+ gint steps;
+ if (preview_active != 1 || event->type != GDK_MOTION_NOTIFY)
+ return;
+ if (move_constraint == MOVE_CONSTRAIN)
+ {
+ int dx = abs(event->x - mouse_x);
+ int dy = abs(event->y - mouse_y);
+ if (dx > dy && dx > 3)
+ move_constraint = MOVE_HORIZONTAL;
+ else if (dy > dx && dy > 3)
+ move_constraint = MOVE_VERTICAL;
+ else
+ return;
+ }
+
+ switch (mouse_button)
+ {
+ case 1:
+ if (move_constraint & MOVE_VERTICAL)
+ new_top = orig_top + INCH * (event->y - mouse_y) / preview_ppi;
+ if (move_constraint & MOVE_HORIZONTAL)
+ new_left = orig_left + INCH * (event->x - mouse_x) / preview_ppi;
+ break;
+ case 3:
+ if (move_constraint & MOVE_VERTICAL)
+ new_top = orig_top + event->y - mouse_y;
+ if (move_constraint & MOVE_HORIZONTAL)
+ new_left = orig_left + event->x - mouse_x;
+ break;
+ case 2:
+ if (move_constraint & MOVE_HORIZONTAL)
+ {
+ gint increment_width =
+ ((move_constraint & MOVE_GRID) && pv->scaling > 0) ?
+ printable_width * pv->scaling / 100 : print_width;
+ gint x_threshold = MAX (1, (preview_ppi * increment_width) / INCH);
+ if (event->x > mouse_x)
+ steps = MIN((event->x - mouse_x) / x_threshold,
+ ((right - orig_left) / increment_width) - 1);
+ else
+ steps = -(MIN((mouse_x - event->x) / x_threshold,
+ (orig_left - left) / increment_width));
+ new_left = orig_left + steps * increment_width;
+ }
+ if (move_constraint & MOVE_VERTICAL)
+ {
+ gint increment_height =
+ ((move_constraint & MOVE_GRID) && pv->scaling > 0) ?
+ printable_height * pv->scaling / 100 : print_height;
+ gint y_threshold = MAX (1, (preview_ppi * increment_height) / INCH);
+ if (event->y > mouse_y)
+ steps = MIN((event->y - mouse_y) / y_threshold,
+ ((bottom - orig_top) / increment_height) - 1);
+ else
+ steps = -(MIN((mouse_y - event->y) / y_threshold,
+ (orig_top - top) / increment_height));
+ new_top = orig_top + steps * increment_height;
+ }
+ break;
+ }
+
+ if (new_top < top)
+ new_top = top;
+ if (new_top > bottom - print_height)
+ new_top = bottom - print_height;
+ if (new_left < left)
+ new_left = left;
+ if (new_left > right - print_width)
+ new_left = right - print_width;
+
+ if (new_top != old_top || new_left != old_left)
+ {
+ stp_set_top (pv->v, new_top);
+ stp_set_left (pv->v, new_left);
+ preview_update ();
+ }
+}
+
+static void
+color_update (GtkAdjustment *adjustment)
+{
+ int i;
+ for (i = 0; i < current_option_count; i++)
+ {
+ option_t *opt = &(current_options[i]);
+ if (opt->fast_desc->p_type == STP_PARAMETER_TYPE_DOUBLE &&
+ opt->fast_desc->p_level <= MAXIMUM_PARAMETER_LEVEL &&
+ opt->info.flt.adjustment &&
+ adjustment == GTK_ADJUSTMENT(opt->info.flt.adjustment))
+ {
+ invalidate_preview_thumbnail ();
+ if (stp_get_float_parameter(pv->v, opt->fast_desc->name) !=
+ adjustment->value)
+ {
+ stp_set_float_parameter(pv->v, opt->fast_desc->name,
+ adjustment->value);
+ update_adjusted_thumbnail();
+ }
+ }
+ }
+}
+
+static void
+dimension_update (GtkAdjustment *adjustment)
+{
+ int i;
+ gdouble unit_scaler = units[pv->unit].scale;
+ for (i = 0; i < current_option_count; i++)
+ {
+ option_t *opt = &(current_options[i]);
+ if (opt->fast_desc->p_type == STP_PARAMETER_TYPE_DIMENSION &&
+ opt->fast_desc->p_level <= MAXIMUM_PARAMETER_LEVEL &&
+ opt->info.flt.adjustment &&
+ adjustment == GTK_ADJUSTMENT(opt->info.flt.adjustment))
+ {
+ invalidate_preview_thumbnail ();
+ if (stp_get_dimension_parameter(pv->v, opt->fast_desc->name) !=
+ adjustment->value * unit_scaler)
+ {
+ stp_set_dimension_parameter(pv->v, opt->fast_desc->name,
+ adjustment->value * unit_scaler);
+ update_adjusted_thumbnail();
+ }
+ }
+ }
+}
+
+static void
+set_controls_active (GtkObject *checkbutton, gpointer xopt)
+{
+ option_t *opt = (option_t *) xopt;
+ stp_parameter_t desc;
+ gboolean setting =
+ gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(checkbutton));
+ if (setting && opt->fast_desc->p_level <= MAXIMUM_PARAMETER_LEVEL)
+ {
+ switch (opt->fast_desc->p_type)
+ {
+ case STP_PARAMETER_TYPE_DOUBLE:
+ set_adjustment_active(opt, TRUE, FALSE);
+ if (! stp_check_float_parameter(pv->v, opt->fast_desc->name,
+ STP_PARAMETER_INACTIVE))
+ {
+ stp_describe_parameter(pv->v, opt->fast_desc->name, &desc);
+ stp_set_float_parameter(pv->v, opt->fast_desc->name,
+ desc.deflt.dbl);
+ stp_parameter_description_destroy(&desc);
+ }
+ stp_set_float_parameter_active(pv->v, opt->fast_desc->name,
+ STP_PARAMETER_ACTIVE);
+ break;
+ case STP_PARAMETER_TYPE_DIMENSION:
+ set_adjustment_active(opt, TRUE, FALSE);
+ if (! stp_check_dimension_parameter(pv->v, opt->fast_desc->name,
+ STP_PARAMETER_INACTIVE))
+ {
+ stp_describe_parameter(pv->v, opt->fast_desc->name, &desc);
+ stp_set_dimension_parameter(pv->v, opt->fast_desc->name,
+ desc.deflt.dimension);
+ stp_parameter_description_destroy(&desc);
+ }
+ stp_set_dimension_parameter_active(pv->v, opt->fast_desc->name,
+ STP_PARAMETER_ACTIVE);
+ break;
+ case STP_PARAMETER_TYPE_CURVE:
+ set_curve_active(opt, TRUE, FALSE);
+ if (! stp_check_curve_parameter(pv->v, opt->fast_desc->name,
+ STP_PARAMETER_INACTIVE))
+ {
+ stp_describe_parameter(pv->v, opt->fast_desc->name, &desc);
+ stp_set_curve_parameter(pv->v, opt->fast_desc->name,
+ desc.deflt.curve);
+ stp_parameter_description_destroy(&desc);
+ }
+ stp_set_curve_parameter_active(pv->v, opt->fast_desc->name,
+ STP_PARAMETER_ACTIVE);
+ break;
+ case STP_PARAMETER_TYPE_STRING_LIST:
+ set_combo_active(opt, TRUE, FALSE);
+ if (! stp_check_string_parameter(pv->v, opt->fast_desc->name,
+ STP_PARAMETER_INACTIVE))
+ {
+ stp_describe_parameter(pv->v, opt->fast_desc->name, &desc);
+ stp_set_string_parameter(pv->v, opt->fast_desc->name,
+ desc.deflt.str);
+ stp_parameter_description_destroy(&desc);
+ }
+ stp_set_string_parameter_active(pv->v, opt->fast_desc->name,
+ STP_PARAMETER_ACTIVE);
+ break;
+ case STP_PARAMETER_TYPE_BOOLEAN:
+ set_bool_active(opt, TRUE, FALSE);
+ if (! stp_check_boolean_parameter(pv->v, opt->fast_desc->name,
+ STP_PARAMETER_INACTIVE))
+ {
+ stp_describe_parameter(pv->v, opt->fast_desc->name, &desc);
+ stp_set_boolean_parameter(pv->v, opt->fast_desc->name,
+ desc.deflt.boolean);
+ stp_parameter_description_destroy(&desc);
+ }
+ stp_set_boolean_parameter_active(pv->v, opt->fast_desc->name,
+ STP_PARAMETER_ACTIVE);
+ break;
+ default:
+ break;
+ }
+ }
+ else
+ {
+ switch (opt->fast_desc->p_type)
+ {
+ case STP_PARAMETER_TYPE_DOUBLE:
+ set_adjustment_active(opt, FALSE, FALSE);
+ stp_set_float_parameter_active(pv->v, opt->fast_desc->name,
+ STP_PARAMETER_INACTIVE);
+ break;
+ case STP_PARAMETER_TYPE_DIMENSION:
+ set_adjustment_active(opt, FALSE, FALSE);
+ stp_set_dimension_parameter_active(pv->v, opt->fast_desc->name,
+ STP_PARAMETER_INACTIVE);
+ break;
+ case STP_PARAMETER_TYPE_CURVE:
+ set_curve_active(opt, FALSE, FALSE);
+ stp_set_curve_parameter_active(pv->v, opt->fast_desc->name,
+ STP_PARAMETER_INACTIVE);
+ break;
+ case STP_PARAMETER_TYPE_STRING_LIST:
+ set_combo_active(opt, FALSE, FALSE);
+ stp_set_string_parameter_active(pv->v, opt->fast_desc->name,
+ STP_PARAMETER_INACTIVE);
+ break;
+ case STP_PARAMETER_TYPE_BOOLEAN: /* ??? */
+ set_bool_active(opt, FALSE, FALSE);
+ stp_set_boolean_parameter_active(pv->v, opt->fast_desc->name,
+ STP_PARAMETER_INACTIVE);
+ break;
+ default:
+ break;
+ }
+ }
+ invalidate_preview_thumbnail();
+ update_adjusted_thumbnail();
+}
+
+static void
+set_color_defaults (void)
+{
+ int i;
+ for (i = 0; i < current_option_count; i++)
+ {
+ option_t *opt = &(current_options[i]);
+ if (opt->fast_desc->p_level <= MAXIMUM_PARAMETER_LEVEL &&
+ opt->fast_desc->p_class == STP_PARAMETER_CLASS_OUTPUT &&
+ opt->is_active && !opt->fast_desc->read_only)
+ {
+ stp_parameter_activity_t active;
+ gdouble unit_scaler;
+ switch (opt->fast_desc->p_type)
+ {
+ case STP_PARAMETER_TYPE_DOUBLE:
+ active =
+ stp_get_float_parameter_active(pv->v, opt->fast_desc->name);
+ stp_set_float_parameter(pv->v, opt->fast_desc->name,
+ opt->info.flt.deflt);
+ stp_set_float_parameter_active(pv->v, opt->fast_desc->name,
+ active);
+ break;
+ case STP_PARAMETER_TYPE_DIMENSION:
+ unit_scaler = units[pv->unit].scale;
+ active =
+ stp_get_dimension_parameter_active(pv->v,
+ opt->fast_desc->name);
+ stp_set_dimension_parameter(pv->v, opt->fast_desc->name,
+ opt->info.flt.deflt * unit_scaler);
+ stp_set_dimension_parameter_active(pv->v, opt->fast_desc->name,
+ active);
+ break;
+ case STP_PARAMETER_TYPE_BOOLEAN:
+ active =
+ stp_get_boolean_parameter_active(pv->v, opt->fast_desc->name);
+ stp_set_boolean_parameter(pv->v, opt->fast_desc->name,
+ opt->info.bool.deflt);
+ stp_set_boolean_parameter_active(pv->v, opt->fast_desc->name,
+ active);
+ break;
+ case STP_PARAMETER_TYPE_STRING_LIST:
+ active =
+ stp_get_string_parameter_active(pv->v, opt->fast_desc->name);
+ stp_set_string_parameter(pv->v, opt->fast_desc->name,
+ opt->info.list.default_val);
+ stp_set_string_parameter_active(pv->v, opt->fast_desc->name,
+ active);
+ break;
+ default:
+ break;
+ }
+ }
+ }
+
+ do_color_updates ();
+}
+
+gint
+stpui_do_print_dialog(void)
+{
+ /*
+ * Get printrc options...
+ */
+ stpui_printrc_load ();
+
+ /*
+ * Print dialog window...
+ */
+ create_main_window();
+
+ gtk_main ();
+ gdk_flush ();
+
+ /*
+ * Set printrc options...
+ */
+ if (saveme)
+ stpui_printrc_save ();
+
+ /*
+ * Return ok/cancel...
+ */
+ return (runme);
+}
diff --git a/src/gutenprintui2/plist.c b/src/gutenprintui2/plist.c
new file mode 100644
index 0000000..f895580
--- /dev/null
+++ b/src/gutenprintui2/plist.c
@@ -0,0 +1,1751 @@
+/*
+ * "$Id: plist.c,v 1.5 2005/06/14 02:47:13 rlk Exp $"
+ *
+ * Print plug-in for the GIMP.
+ *
+ * Copyright 1997-2000 Michael Sweet (mike@easysw.com) and
+ * Robert Krawitz (rlk@alum.mit.edu)
+ *
+ * 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 2 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <gutenprint/gutenprint-intl-internal.h>
+#include <gutenprint/gutenprint.h>
+#include <gutenprintui2/gutenprintui.h>
+#include "gutenprintui-internal.h"
+
+#include <unistd.h>
+#include <ctype.h>
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+#include <locale.h>
+
+#include <sys/types.h>
+#include <signal.h>
+#include <sys/wait.h>
+
+
+typedef enum
+{
+ PRINTERS_NONE,
+ PRINTERS_LPC,
+ PRINTERS_LPSTAT
+} printer_system_t;
+
+static int compare_printers (stpui_plist_t *p1, stpui_plist_t *p2);
+
+int stpui_plist_current = 0, /* Current system printer */
+ stpui_plist_count = 0; /* Number of system printers */
+stpui_plist_t *stpui_plist; /* System printers */
+int stpui_show_all_paper_sizes = 0;
+static char *printrc_name = NULL;
+static char *image_type;
+static gint image_raw_channels = 0;
+static gint image_channel_depth = 8;
+static stp_string_list_t *default_parameters = NULL;
+stp_string_list_t *stpui_system_print_queues;
+static const char *copy_count_name = "STPUICopyCount";
+
+#define SAFE_FREE(x) \
+do \
+{ \
+ if ((x)) \
+ g_free((char *)(x)); \
+ ((x)) = NULL; \
+} while (0)
+
+typedef struct
+{
+ const char *printing_system_name;
+ const char *printing_system_text;
+ const char *print_command;
+ const char *queue_select;
+ const char *raw_flag;
+ const char *key_file;
+ const char *scan_command;
+ const char *copy_count_command;
+} print_system_t;
+
+/*
+ * Generic printing system, based on SysV lp
+ */
+static const print_system_t default_printing_system =
+ { "SysV", N_("System V lp"), "lp -s", "-d", "-oraw", "/usr/bin/lp",
+ "/usr/bin/lpstat -v | grep -i '^device for ' | awk '{print $3}' | sed 's/://'",
+ "-n" };
+
+static print_system_t known_printing_systems[] =
+{
+ { "CUPS", N_("CUPS"), "lp -s", "-d", "-oraw", "/usr/sbin/cupsd",
+ "/usr/bin/lpstat -v | grep -i '^device for ' | awk '{print $3}' | sed 's/://'",
+ "-n" },
+ { "SysV", N_("System V lp"), "lp -s", "-d", "-oraw", "/usr/bin/lp",
+ "/usr/bin/lpstat -v | grep -i '^device for ' | awk '{print $3}' | sed 's/://'",
+ "-n" },
+ { "lpd", N_("Berkeley lpd (/etc/lpc)"), "lpr", "-P", "-l", "/etc/lpc",
+ "/etc/lpc status | grep '^...*:' | sed 's/:.*//'",
+ "-#" },
+ { "lpd", N_("Berkeley lpd (/usr/bsd/lpc)"), "lpr", "-P", "-l", "/usr/bsd/lpc",
+ "/usr/bsd/lpc status | grep '^...*:' | sed 's/:.*//'",
+ "-#" },
+ { "lpd", N_("Berkeley lpd (/usr/etc/lpc"), "lpr", "-P", "-l", "/usr/etc/lpc",
+ "/usr/etc/lpc status | grep '^...*:' | sed 's/:.*//'",
+ "-#" },
+ { "lpd", N_("Berkeley lpd (/usr/libexec/lpc)"), "lpr", "-P", "-l", "/usr/libexec/lpc",
+ "/usr/libexec/lpc status | grep '^...*:' | sed 's/:.*//'",
+ "-#" },
+ { "lpd", N_("Berkeley lpd (/usr/sbin/lpc)"), "lpr", "-P", "-l", "/usr/sbin/lpc",
+ "/usr/sbin/lpc status | grep '^...*:' | sed 's/:.*//'",
+ "-#" },
+};
+
+static unsigned print_system_count = sizeof(known_printing_systems) / sizeof(print_system_t);
+
+static const print_system_t *global_printing_system = NULL;
+
+static void
+initialize_default_parameters(void)
+{
+ default_parameters = stp_string_list_create();
+ stp_string_list_add_string(default_parameters, "PrintingSystem", "Autodetect");
+ stp_string_list_add_string(default_parameters, "PrintCommand", "");
+ stp_string_list_add_string(default_parameters, "QueueSelect", "");
+ stp_string_list_add_string(default_parameters, "RawOutputFlag", "");
+ stp_string_list_add_string(default_parameters, "ScanOnStartup", "False");
+ stp_string_list_add_string(default_parameters, "ScanPrintersCommand", "");
+}
+
+void
+stpui_set_global_parameter(const char *param, const char *value)
+{
+ stp_string_list_remove_string(default_parameters, param);
+ stp_string_list_add_string(default_parameters, param, value);
+}
+
+const char *
+stpui_get_global_parameter(const char *param)
+{
+ stp_param_string_t *ps = stp_string_list_find(default_parameters, param);
+ if (ps)
+ return ps->text;
+ else
+ return NULL;
+}
+
+static const print_system_t *
+identify_print_system(void)
+{
+ int i;
+ if (!global_printing_system)
+ {
+ for (i = 0; i < print_system_count; i++)
+ {
+ if (!access(known_printing_systems[i].key_file, R_OK))
+ {
+ global_printing_system = &(known_printing_systems[i]);
+ break;
+ }
+ }
+ if (!global_printing_system)
+ global_printing_system = &default_printing_system;
+ }
+ return global_printing_system;
+}
+
+char *
+stpui_build_standard_print_command(const stpui_plist_t *plist,
+ const stp_printer_t *printer)
+{
+ const char *queue_name = stpui_plist_get_queue_name(plist);
+ const char *extra_options = stpui_plist_get_extra_printer_options(plist);
+ const char *family = stp_printer_get_family(printer);
+ int copy_count = stpui_plist_get_copy_count(plist);
+ int raw = 0;
+ char *print_cmd;
+ char *count_string = NULL;
+ if (!queue_name)
+ queue_name = "";
+ identify_print_system();
+ if (strcmp(family, "ps") == 0)
+ raw = 0;
+ else
+ raw = 1;
+
+ if (copy_count > 1)
+ stp_asprintf(&count_string, "%s %d ",
+ global_printing_system->copy_count_command, copy_count);
+
+ stp_asprintf(&print_cmd, "%s %s %s %s %s%s%s",
+ global_printing_system->print_command,
+ queue_name[0] ? global_printing_system->queue_select : "",
+ queue_name[0] ? g_shell_quote(queue_name) : "",
+ count_string ? count_string : "",
+ raw ? global_printing_system->raw_flag : "",
+ extra_options ? " " : "",
+ extra_options ? extra_options : "");
+ SAFE_FREE(count_string);
+ return print_cmd;
+}
+
+void
+stpui_set_printrc_file(const char *name)
+{
+ if (name && name == printrc_name)
+ return;
+ SAFE_FREE(printrc_name);
+ if (name)
+ printrc_name = g_strdup(name);
+ else
+ printrc_name = g_build_filename(g_get_home_dir(), ".gutenprintrc", NULL);
+}
+
+const char *
+stpui_get_printrc_file(void)
+{
+ if (!printrc_name)
+ stpui_set_printrc_file(NULL);
+ return printrc_name;
+}
+
+#define PLIST_ACCESSORS(name) \
+void \
+stpui_plist_set_##name(stpui_plist_t *p, const char *val) \
+{ \
+ if (p->name == val) \
+ return; \
+ SAFE_FREE(p->name); \
+ p->name = g_strdup(val); \
+} \
+ \
+void \
+stpui_plist_set_##name##_n(stpui_plist_t *p, const char *val, int n) \
+{ \
+ if (p->name == val) \
+ return; \
+ SAFE_FREE(p->name); \
+ p->name = g_strndup(val, n); \
+} \
+ \
+const char * \
+stpui_plist_get_##name(const stpui_plist_t *p) \
+{ \
+ return p->name; \
+}
+
+PLIST_ACCESSORS(output_filename)
+PLIST_ACCESSORS(name)
+PLIST_ACCESSORS(queue_name)
+PLIST_ACCESSORS(extra_printer_options)
+PLIST_ACCESSORS(custom_command)
+PLIST_ACCESSORS(current_standard_command)
+
+void
+stpui_plist_set_command_type(stpui_plist_t *p, command_t val)
+{
+ switch (val)
+ {
+ case COMMAND_TYPE_DEFAULT:
+ case COMMAND_TYPE_CUSTOM:
+ case COMMAND_TYPE_FILE:
+ p->command_type = val;
+ break;
+ default:
+ p->command_type = COMMAND_TYPE_DEFAULT;
+ }
+}
+
+command_t
+stpui_plist_get_command_type(const stpui_plist_t *p)
+{
+ return p->command_type;
+}
+
+void
+stpui_plist_set_copy_count(stpui_plist_t *p, gint copy_count)
+{
+ if (copy_count > 0)
+ stp_set_int_parameter(p->v, copy_count_name, copy_count);
+}
+
+gint
+stpui_plist_get_copy_count(const stpui_plist_t *p)
+{
+ if (stp_check_int_parameter(p->v, copy_count_name, STP_PARAMETER_ACTIVE))
+ return stp_get_int_parameter(p->v, copy_count_name);
+ else
+ return 1;
+}
+
+void
+stpui_set_image_type(const char *itype)
+{
+ image_type = g_strdup(itype);
+}
+
+void
+stpui_set_image_raw_channels(gint channels)
+{
+ image_raw_channels = channels;
+}
+
+void
+stpui_set_image_channel_depth(gint depth)
+{
+ image_channel_depth = depth;
+}
+
+void
+stpui_printer_initialize(stpui_plist_t *printer)
+{
+ char tmp[32];
+ stpui_plist_set_name(printer, "");
+ stpui_plist_set_output_filename(printer, "");
+ stpui_plist_set_queue_name(printer, "");
+ stpui_plist_set_extra_printer_options(printer, "");
+ stpui_plist_set_custom_command(printer, "");
+ stpui_plist_set_current_standard_command(printer, "");
+ printer->command_type = COMMAND_TYPE_DEFAULT;
+ printer->scaling = 100.0;
+ printer->orientation = ORIENT_AUTO;
+ printer->auto_size_roll_feed_paper = 0;
+ printer->unit = 0;
+ printer->v = stp_vars_create();
+ stpui_plist_set_copy_count(printer, 1);
+ stp_set_string_parameter(printer->v, "InputImageType", image_type);
+ if (image_raw_channels)
+ {
+ (void) sprintf(tmp, "%d", image_raw_channels);
+ stp_set_string_parameter(printer->v, "RawChannels", tmp);
+ }
+ if (image_channel_depth)
+ {
+ (void) sprintf(tmp, "%d", image_channel_depth);
+ stp_set_string_parameter(printer->v, "ChannelBitDepth", tmp);
+ }
+ printer->invalid_mask = INVALID_TOP | INVALID_LEFT;
+}
+
+static void
+stpui_plist_destroy(stpui_plist_t *printer)
+{
+ SAFE_FREE(printer->name);
+ SAFE_FREE(printer->queue_name);
+ SAFE_FREE(printer->extra_printer_options);
+ SAFE_FREE(printer->custom_command);
+ SAFE_FREE(printer->current_standard_command);
+ SAFE_FREE(printer->output_filename);
+ stp_vars_destroy(printer->v);
+}
+
+void
+stpui_plist_copy(stpui_plist_t *vd, const stpui_plist_t *vs)
+{
+ if (vs == vd)
+ return;
+ stp_vars_copy(vd->v, vs->v);
+ vd->scaling = vs->scaling;
+ vd->orientation = vs->orientation;
+ vd->auto_size_roll_feed_paper = vs->auto_size_roll_feed_paper;
+ vd->unit = vs->unit;
+ vd->invalid_mask = vs->invalid_mask;
+ vd->command_type = vs->command_type;
+ stpui_plist_set_name(vd, stpui_plist_get_name(vs));
+ stpui_plist_set_queue_name(vd, stpui_plist_get_queue_name(vs));
+ stpui_plist_set_extra_printer_options(vd, stpui_plist_get_extra_printer_options(vs));
+ stpui_plist_set_custom_command(vd, stpui_plist_get_custom_command(vs));
+ stpui_plist_set_current_standard_command(vd, stpui_plist_get_current_standard_command(vs));
+ stpui_plist_set_output_filename(vd, stpui_plist_get_output_filename(vs));
+ stpui_plist_set_copy_count(vd, stpui_plist_get_copy_count(vs));
+}
+
+static stpui_plist_t *
+allocate_stpui_plist_copy(const stpui_plist_t *vs)
+{
+ stpui_plist_t *rep = g_malloc(sizeof(stpui_plist_t));
+ memset(rep, 0, sizeof(stpui_plist_t));
+ rep->v = stp_vars_create();
+ stpui_plist_copy(rep, vs);
+ return rep;
+}
+
+static void
+check_plist(int count)
+{
+ static int current_plist_size = 0;
+ int i;
+ if (count <= current_plist_size)
+ return;
+ else if (current_plist_size == 0)
+ {
+ current_plist_size = count;
+ stpui_plist = g_malloc(current_plist_size * sizeof(stpui_plist_t));
+ for (i = 0; i < current_plist_size; i++)
+ {
+ memset(&(stpui_plist[i]), 0, sizeof(stpui_plist_t));
+ stpui_printer_initialize(&(stpui_plist[i]));
+ }
+ }
+ else
+ {
+ int old_plist_size = current_plist_size;
+ current_plist_size *= 2;
+ if (current_plist_size < count)
+ current_plist_size = count;
+ stpui_plist = g_realloc(stpui_plist, current_plist_size * sizeof(stpui_plist_t));
+ for (i = old_plist_size; i < current_plist_size; i++)
+ {
+ memset(&(stpui_plist[i]), 0, sizeof(stpui_plist_t));
+ stpui_printer_initialize(&(stpui_plist[i]));
+ }
+ }
+}
+
+#define GET_MANDATORY_INTERNAL_STRING_PARAM(param) \
+do { \
+ if ((commaptr = strchr(lineptr, ',')) == NULL) \
+ continue; \
+ stpui_plist_set_##param##_n(&key, lineptr, commaptr - line); \
+ lineptr = commaptr + 1; \
+} while (0)
+
+#define GET_MANDATORY_STRING_PARAM(param) \
+do { \
+ if ((commaptr = strchr(lineptr, ',')) == NULL) \
+ continue; \
+ stp_set_##param##_n(key.v, lineptr, commaptr - line); \
+ lineptr = commaptr + 1; \
+} while (0)
+
+static int
+get_mandatory_string_param(stp_vars_t *v, const char *param, char **lineptr)
+{
+ char *commaptr = strchr(*lineptr, ',');
+ if (commaptr == NULL)
+ return 0;
+ stp_set_string_parameter_n(v, param, *lineptr, commaptr - *lineptr);
+ *lineptr = commaptr + 1;
+ return 1;
+}
+
+static int
+get_mandatory_file_param(stp_vars_t *v, const char *param, char **lineptr)
+{
+ char *commaptr = strchr(*lineptr, ',');
+ if (commaptr == NULL)
+ return 0;
+ stp_set_file_parameter_n(v, param, *lineptr, commaptr - *lineptr);
+ *lineptr = commaptr + 1;
+ return 1;
+}
+
+#define GET_MANDATORY_INT_PARAM(param) \
+do { \
+ if ((commaptr = strchr(lineptr, ',')) == NULL) \
+ continue; \
+ stp_set_##param(key.v, atoi(lineptr)); \
+ lineptr = commaptr + 1; \
+} while (0)
+
+#define GET_MANDATORY_INTERNAL_INT_PARAM(param) \
+do { \
+ if ((commaptr = strchr(lineptr, ',')) == NULL) \
+ continue; \
+ key.param = atoi(lineptr); \
+ lineptr = commaptr + 1; \
+} while (0)
+
+static void
+get_optional_string_param(stp_vars_t *v, const char *param,
+ char **lineptr, int *keepgoing)
+{
+ if (*keepgoing)
+ {
+ char *commaptr = strchr(*lineptr, ',');
+ if (commaptr == NULL)
+ {
+ stp_set_string_parameter(v, param, *lineptr);
+ *keepgoing = 0;
+ }
+ else
+ {
+ stp_set_string_parameter_n(v, param, *lineptr, commaptr - *lineptr);
+ *lineptr = commaptr + 1;
+ }
+ }
+}
+
+#define GET_OPTIONAL_INT_PARAM(param) \
+do { \
+ if ((keepgoing == 0) || ((commaptr = strchr(lineptr, ',')) == NULL)) \
+ { \
+ keepgoing = 0; \
+ } \
+ else \
+ { \
+ stp_set_##param(key.v, atoi(lineptr)); \
+ lineptr = commaptr + 1; \
+ } \
+} while (0)
+
+#define GET_OPTIONAL_INTERNAL_INT_PARAM(param) \
+do { \
+ if ((keepgoing == 0) || ((commaptr = strchr(lineptr, ',')) == NULL)) \
+ { \
+ keepgoing = 0; \
+ } \
+ else \
+ { \
+ key.param = atoi(lineptr); \
+ lineptr = commaptr + 1; \
+ } \
+} while (0)
+
+#define IGNORE_OPTIONAL_PARAM(param) \
+do { \
+ if ((keepgoing == 0) || ((commaptr = strchr(lineptr, ',')) == NULL)) \
+ { \
+ keepgoing = 0; \
+ } \
+ else \
+ { \
+ lineptr = commaptr + 1; \
+ } \
+} while (0)
+
+static void
+get_optional_float_param(stp_vars_t *v, const char *param,
+ char **lineptr, int *keepgoing)
+{
+ if (*keepgoing)
+ {
+ char *commaptr = strchr(*lineptr, ',');
+ if (commaptr == NULL)
+ {
+ stp_set_float_parameter(v, param, atof(*lineptr));
+ *keepgoing = 0;
+ }
+ else
+ {
+ stp_set_float_parameter(v, param, atof(*lineptr));
+ *lineptr = commaptr + 1;
+ }
+ }
+}
+
+#define GET_OPTIONAL_INTERNAL_FLOAT_PARAM(param) \
+do { \
+ if ((keepgoing == 0) || ((commaptr = strchr(lineptr, ',')) == NULL)) \
+ { \
+ keepgoing = 0; \
+ } \
+ else \
+ { \
+ key.param = atof(lineptr); \
+ } \
+} while (0)
+
+static void *
+psearch(const void *key, void *base, size_t nmemb, size_t size,
+ int (*compar)(const void *, const void *))
+{
+ int i;
+ char *cbase = (char *) base;
+ for (i = 0; i < nmemb; i++)
+ {
+ if ((*compar)(key, (const void *) cbase) == 0)
+ return (void *) cbase;
+ cbase += size;
+ }
+ return NULL;
+}
+
+stpui_plist_t *
+stpui_plist_create(const char *name, const char *driver)
+{
+ stpui_plist_t key;
+ stpui_plist_t *answer = NULL;
+ memset(&key, 0, sizeof(key));
+ stpui_printer_initialize(&key);
+ key.invalid_mask = 0;
+ stpui_plist_set_name(&key, name);
+ stp_set_driver(key.v, driver);
+ if (stpui_plist_add(&key, 0))
+ answer = psearch(&key, stpui_plist, stpui_plist_count,
+ sizeof(stpui_plist_t),
+ (int (*)(const void *, const void *)) compare_printers);
+ SAFE_FREE(key.name);
+ SAFE_FREE(key.queue_name);
+ SAFE_FREE(key.extra_printer_options);
+ SAFE_FREE(key.custom_command);
+ SAFE_FREE(key.current_standard_command);
+ SAFE_FREE(key.output_filename);
+ stp_vars_destroy(key.v);
+ return answer;
+}
+
+int
+stpui_plist_add(const stpui_plist_t *key, int add_only)
+{
+ /*
+ * The format of the list is the File printer followed by a qsort'ed list
+ * of system printers. So, if we want to update the file printer, it is
+ * always first in the list, else call psearch.
+ */
+ stpui_plist_t *p;
+ if (stp_get_printer(key->v))
+ {
+ p = psearch(key, stpui_plist, stpui_plist_count,
+ sizeof(stpui_plist_t),
+ (int (*)(const void *, const void *)) compare_printers);
+ if (p == NULL)
+ {
+#ifdef DEBUG
+ fprintf(stderr, "Adding new printer from printrc file: %s\n",
+ key->name);
+#endif
+ check_plist(stpui_plist_count + 1);
+ p = stpui_plist + stpui_plist_count;
+ stpui_plist_count++;
+ stpui_plist_copy(p, key);
+ if (strlen(stpui_plist_get_queue_name(p)) == 0 &&
+ stp_string_list_is_present(stpui_system_print_queues,
+ stpui_plist_get_name(p)))
+ stpui_plist_set_queue_name(p, stpui_plist_get_name(p));
+ }
+ else
+ {
+ if (add_only)
+ return 0;
+#ifdef DEBUG
+ fprintf(stderr, "Updating printer %s.\n", key->name);
+#endif
+ stpui_plist_copy(p, key);
+ }
+ }
+ return 1;
+}
+
+static void
+stpui_printrc_load_v0(FILE *fp)
+{
+ char line[1024]; /* Line in printrc file */
+ char *lineptr; /* Pointer in line */
+ char *commaptr; /* Pointer to next comma */
+ stpui_plist_t key; /* Search key */
+ int keepgoing = 1;
+ (void) memset(line, 0, 1024);
+ (void) memset(&key, 0, sizeof(stpui_plist_t));
+ stpui_printer_initialize(&key);
+ key.name = g_strdup(_("File"));
+ while (fgets(line, sizeof(line), fp) != NULL)
+ {
+ /*
+ * Read old format printrc lines...
+ */
+
+ stpui_printer_initialize(&key);
+ key.invalid_mask = 0;
+ lineptr = line;
+
+ /*
+ * Read the command-delimited printer definition data. Note that
+ * we can't use sscanf because %[^,] fails if the string is empty...
+ */
+
+ GET_MANDATORY_INTERNAL_STRING_PARAM(name);
+ GET_MANDATORY_INTERNAL_STRING_PARAM(custom_command);
+ GET_MANDATORY_STRING_PARAM(driver);
+
+ if (! stp_get_printer(key.v))
+ continue;
+
+ if (!get_mandatory_file_param(key.v, "PPDFile", &lineptr))
+ continue;
+ if ((commaptr = strchr(lineptr, ',')) != NULL)
+ {
+ switch (atoi(lineptr))
+ {
+ case 1:
+ stp_set_string_parameter(key.v, "PrintingMode", "Color");
+ break;
+ case 0:
+ default:
+ stp_set_string_parameter(key.v, "PrintingMode", "BW");
+ break;
+ }
+ }
+ else
+ continue;
+
+ if (!get_mandatory_string_param(key.v, "Resolution", &lineptr))
+ continue;
+ if (!get_mandatory_string_param(key.v, "PageSize", &lineptr))
+ continue;
+ if (!get_mandatory_string_param(key.v, "MediaType", &lineptr))
+ continue;
+
+ get_optional_string_param(key.v, "InputSlot", &lineptr, &keepgoing);
+ get_optional_float_param(key.v, "Brightness", &lineptr, &keepgoing);
+
+ GET_OPTIONAL_INTERNAL_FLOAT_PARAM(scaling);
+ GET_OPTIONAL_INTERNAL_INT_PARAM(orientation);
+ GET_OPTIONAL_INT_PARAM(left);
+ GET_OPTIONAL_INT_PARAM(top);
+ get_optional_float_param(key.v, "Gamma", &lineptr, &keepgoing);
+ get_optional_float_param(key.v, "Contrast", &lineptr, &keepgoing);
+ get_optional_float_param(key.v, "Cyan", &lineptr, &keepgoing);
+ get_optional_float_param(key.v, "Magenta", &lineptr, &keepgoing);
+ get_optional_float_param(key.v, "Yellow", &lineptr, &keepgoing);
+ IGNORE_OPTIONAL_PARAM(linear);
+ IGNORE_OPTIONAL_PARAM(image_type);
+ get_optional_float_param(key.v, "Saturation", &lineptr, &keepgoing);
+ get_optional_float_param(key.v, "Density", &lineptr, &keepgoing);
+ get_optional_string_param(key.v, "InkType", &lineptr, &keepgoing);
+ get_optional_string_param(key.v,"DitherAlgorithm",&lineptr,&keepgoing);
+ GET_OPTIONAL_INTERNAL_INT_PARAM(unit);
+ stpui_plist_add(&key, 0);
+ g_free(key.name);
+ stp_vars_destroy(key.v);
+ }
+ stpui_plist_current = 0;
+}
+
+static void
+stpui_printrc_load_v1(FILE *fp)
+{
+ char line[1024]; /* Line in printrc file */
+ stpui_plist_t key; /* Search key */
+ char * current_printer = 0; /* printer to select */
+ (void) memset(line, 0, 1024);
+ (void) memset(&key, 0, sizeof(stpui_plist_t));
+ stpui_printer_initialize(&key);
+ key.name = g_strdup(_("File"));
+ while (fgets(line, sizeof(line), fp) != NULL)
+ {
+ /*
+ * Read new format printrc lines...
+ */
+
+ char *keyword, *end, *value;
+
+ keyword = line;
+ for (keyword = line; g_ascii_isspace(*keyword); keyword++)
+ {
+ /* skip initial spaces... */
+ }
+ if (!g_ascii_isalpha(*keyword))
+ continue;
+ for (end = keyword; g_ascii_isalnum(*end) || *end == '-'; end++)
+ {
+ /* find end of keyword... */
+ }
+ value = end;
+ while (g_ascii_isspace(*value))
+ {
+ /* skip over white space... */
+ value++;
+ }
+ if (*value != ':')
+ continue;
+ value++;
+ *end = '\0';
+ while (g_ascii_isspace(*value))
+ {
+ /* skip over white space... */
+ value++;
+ }
+ for (end = value; *end && *end != '\n'; end++)
+ {
+ /* find end of line... */
+ }
+ *end = '\0';
+#ifdef DEBUG
+ fprintf(stderr, "Keyword = `%s', value = `%s'\n", keyword, value);
+#endif
+ if (strcasecmp("current-printer", keyword) == 0)
+ {
+ if (current_printer)
+ g_free (current_printer);
+ current_printer = g_strdup(value);
+ }
+ else if (strcasecmp("printer", keyword) == 0)
+ {
+ /* Switch to printer named VALUE */
+ stpui_plist_add(&key, 0);
+#ifdef DEBUG
+ fprintf(stderr,
+ "output_to is now %s\n", stpui_plist_get_output_to(&key));
+#endif
+
+ stp_vars_destroy(key.v);
+ stpui_printer_initialize(&key);
+ key.invalid_mask = 0;
+ stpui_plist_set_name(&key, value);
+ }
+ else if (strcasecmp("destination", keyword) == 0)
+ stpui_plist_set_custom_command(&key, value);
+ else if (strcasecmp("driver", keyword) == 0)
+ stp_set_driver(key.v, value);
+ else if (strcasecmp("ppd-file", keyword) == 0)
+ stp_set_file_parameter(key.v, "PPDFile", value);
+ else if (strcasecmp("output-type", keyword) == 0)
+ {
+ switch (atoi(value))
+ {
+ case 1:
+ stp_set_string_parameter(key.v, "PrintingMode", "Color");
+ break;
+ case 0:
+ default:
+ stp_set_string_parameter(key.v, "PrintingMode", "BW");
+ break;
+ }
+ }
+ else if (strcasecmp("media-size", keyword) == 0)
+ stp_set_string_parameter(key.v, "PageSize", value);
+ else if (strcasecmp("media-type", keyword) == 0)
+ stp_set_string_parameter(key.v, "MediaType", value);
+ else if (strcasecmp("media-source", keyword) == 0)
+ stp_set_float_parameter(key.v, "Brightness", atof(value));
+ else if (strcasecmp("scaling", keyword) == 0)
+ key.scaling = atof(value);
+ else if (strcasecmp("orientation", keyword) == 0)
+ key.orientation = atoi(value);
+ else if (strcasecmp("left", keyword) == 0)
+ stp_set_left(key.v, atoi(value));
+ else if (strcasecmp("top", keyword) == 0)
+ stp_set_top(key.v, atoi(value));
+ else if (strcasecmp("linear", keyword) == 0)
+ /* Ignore linear */
+ ;
+ else if (strcasecmp("image-type", keyword) == 0)
+ /* Ignore image type */
+ ;
+ else if (strcasecmp("unit", keyword) == 0)
+ key.unit = atoi(value);
+ else if (strcasecmp("custom-page-width", keyword) == 0)
+ stp_set_page_width(key.v, atoi(value));
+ else if (strcasecmp("custom-page-height", keyword) == 0)
+ stp_set_page_height(key.v, atoi(value));
+ /* Special case Ink-Type and Dither-Algorithm */
+ else if (strcasecmp("ink-type", keyword) == 0)
+ stp_set_string_parameter(key.v, "InkType", value);
+ else if (strcasecmp("dither-algorithm", keyword) == 0)
+ stp_set_string_parameter(key.v, "DitherAlgorithm", value);
+ else
+ {
+ stp_parameter_t desc;
+ stp_curve_t *curve;
+ stp_describe_parameter(key.v, keyword, &desc);
+ switch (desc.p_type)
+ {
+ case STP_PARAMETER_TYPE_STRING_LIST:
+ stp_set_string_parameter(key.v, keyword, value);
+ break;
+ case STP_PARAMETER_TYPE_FILE:
+ stp_set_file_parameter(key.v, keyword, value);
+ break;
+ case STP_PARAMETER_TYPE_DOUBLE:
+ stp_set_float_parameter(key.v, keyword, atof(value));
+ break;
+ case STP_PARAMETER_TYPE_INT:
+ stp_set_int_parameter(key.v, keyword, atoi(value));
+ break;
+ case STP_PARAMETER_TYPE_BOOLEAN:
+ stp_set_boolean_parameter(key.v, keyword, atoi(value));
+ break;
+ case STP_PARAMETER_TYPE_CURVE:
+ curve = stp_curve_create_from_string(value);
+ if (curve)
+ {
+ stp_set_curve_parameter(key.v, keyword, curve);
+ stp_curve_destroy(curve);
+ }
+ break;
+ default:
+ if (strlen(value))
+ {
+ char buf[1024];
+ snprintf(buf, sizeof(buf),
+ "Unrecognized keyword `%s' in printrc; value `%s' (%d)\n",
+ keyword, value, desc.p_type);
+ }
+ }
+ stp_parameter_description_destroy(&desc);
+ }
+ }
+ if (strlen(key.name) > 0)
+ {
+ stpui_plist_add(&key, 0);
+ stp_vars_destroy(key.v);
+ g_free(key.name);
+ }
+ if (current_printer)
+ {
+ int i;
+ for (i = 0; i < stpui_plist_count; i ++)
+ if (strcmp(current_printer, stpui_plist[i].name) == 0)
+ stpui_plist_current = i;
+ }
+}
+
+char *stpui_printrc_current_printer = NULL;
+extern FILE *yyin;
+extern int yyparse(void);
+
+static void
+stpui_printrc_load_v2(FILE *fp)
+{
+ int retval;
+ yyin = fp;
+
+ stpui_printrc_current_printer = NULL;
+ retval = yyparse();
+ if (stpui_printrc_current_printer)
+ {
+ int i;
+ for (i = 0; i < stpui_plist_count; i ++)
+ {
+ if (strcmp(stpui_printrc_current_printer, stpui_plist[i].name) == 0)
+ stpui_plist_current = i;
+ if (!stp_check_boolean_parameter(stpui_plist[i].v,
+ "PageSizeExtended",
+ STP_PARAMETER_ACTIVE))
+ stp_set_boolean_parameter(stpui_plist[i].v, "PageSizeExtended", 0);
+ }
+ SAFE_FREE(stpui_printrc_current_printer);
+ }
+}
+
+/*
+ * 'stpui_printrc_load()' - Load the printer resource configuration file.
+ */
+void
+stpui_printrc_load(void)
+{
+ FILE *fp; /* Printrc file */
+ char line[1024]; /* Line in printrc file */
+ int format = 0; /* rc file format version */
+ const char *filename = stpui_get_printrc_file();
+
+ initialize_default_parameters();
+ check_plist(1);
+
+ /*
+ * Get the printer list...
+ */
+
+ stpui_get_system_printers();
+
+ if ((fp = fopen(filename, "r")) != NULL)
+ {
+ (void) memset(line, 0, 1024);
+ if (fgets(line, sizeof(line), fp) != NULL)
+ {
+ /* Force locale to "C", so that numbers scan correctly */
+ setlocale(LC_ALL, "C");
+ if (strncmp("#PRINTRCv", line, 9) == 0)
+ {
+#ifdef DEBUG
+ fprintf(stderr, "Found printrc version tag: `%s'\n", line);
+ fprintf(stderr, "Version number: `%s'\n", &(line[9]));
+#endif
+ (void) sscanf(&(line[9]), "%d", &format);
+ }
+ setlocale(LC_ALL, "");
+ }
+ rewind(fp);
+ switch (format)
+ {
+ case 0:
+ stpui_printrc_load_v0(fp);
+ break;
+ case 1:
+ stpui_printrc_load_v1(fp);
+ break;
+ case 2:
+ case 3:
+ case 4:
+ stpui_printrc_load_v2(fp);
+ break;
+ }
+ (void) fclose(fp);
+ }
+ if (stpui_plist_count == 0)
+ stpui_plist_create(_("Printer"), "ps2");
+}
+
+/*
+ * 'stpui_printrc_save()' - Save the current printer resource configuration.
+ */
+void
+stpui_printrc_save(void)
+{
+ FILE *fp; /* Printrc file */
+ int i; /* Looping var */
+ size_t global_settings_count = stp_string_list_count(default_parameters);
+ stpui_plist_t *p; /* Current printer */
+ const char *filename = stpui_get_printrc_file();
+
+
+ if ((fp = fopen(filename, "w")) != NULL)
+ {
+ /*
+ * Write the contents of the printer list...
+ */
+
+ /* Force locale to "C", so that numbers print correctly */
+ setlocale(LC_ALL, "C");
+#ifdef DEBUG
+ fprintf(stderr, "Number of printers: %d\n", stpui_plist_count);
+#endif
+
+ fputs("#PRINTRCv4 written by Gutenprint " PLUG_IN_VERSION "\n\n", fp);
+
+ fprintf(fp, "Global-Settings:\n");
+ fprintf(fp, " Current-Printer: \"%s\"\n",
+ stpui_plist[stpui_plist_current].name);
+ fprintf(fp, " Show-All-Paper-Sizes: %s\n",
+ stpui_show_all_paper_sizes ? "True" : "False");
+ for (i = 0; i < global_settings_count; i++)
+ {
+ stp_param_string_t *ps = stp_string_list_param(default_parameters, i);
+ fprintf(fp, " %s \"%s\"\n", ps->name, ps->text);
+ }
+ fprintf(fp, "End-Global-Settings:\n");
+
+ for (i = 0, p = stpui_plist; i < stpui_plist_count; i ++, p ++)
+ {
+ int count;
+ int j;
+ stp_parameter_list_t *params = stp_get_parameter_list(p->v);
+ count = stp_parameter_list_count(params);
+ fprintf(fp, "\nPrinter: \"%s\" \"%s\"\n",
+ p->name, stp_get_driver(p->v));
+ fprintf(fp, " Command-Type: %d\n", p->command_type);
+ fprintf(fp, " Queue-Name: \"%s\"\n", p->queue_name);
+ fprintf(fp, " Output-Filename: \"%s\"\n", p->output_filename);
+ fprintf(fp, " Extra-Printer-Options: \"%s\"\n", p->extra_printer_options);
+ fprintf(fp, " Custom-Command: \"%s\"\n", p->custom_command);
+ fprintf(fp, " Scaling: %.3f\n", p->scaling);
+ fprintf(fp, " Orientation: %d\n", p->orientation);
+ fprintf(fp, " Autosize-Roll-Paper: %d\n", p->auto_size_roll_feed_paper);
+ fprintf(fp, " Unit: %d\n", p->unit);
+
+ fprintf(fp, " Left: %d\n", stp_get_left(p->v));
+ fprintf(fp, " Top: %d\n", stp_get_top(p->v));
+ fprintf(fp, " Custom_Page_Width: %d\n", stp_get_page_width(p->v));
+ fprintf(fp, " Custom_Page_Height: %d\n", stp_get_page_height(p->v));
+ fprintf(fp, " Parameter %s Int True %d\n", copy_count_name,
+ stpui_plist_get_copy_count(p));
+
+ for (j = 0; j < count; j++)
+ {
+ const stp_parameter_t *param = stp_parameter_list_param(params, j);
+ if (strcmp(param->name, "AppGamma") == 0)
+ continue;
+ switch (param->p_type)
+ {
+ case STP_PARAMETER_TYPE_STRING_LIST:
+ if (stp_check_string_parameter(p->v, param->name,
+ STP_PARAMETER_INACTIVE))
+ fprintf(fp, " Parameter %s String %s \"%s\"\n",
+ param->name,
+ ((stp_get_string_parameter_active
+ (p->v, param->name) == STP_PARAMETER_ACTIVE) ?
+ "True" : "False"),
+ stp_get_string_parameter(p->v, param->name));
+ break;
+ case STP_PARAMETER_TYPE_FILE:
+ if (stp_check_file_parameter(p->v, param->name,
+ STP_PARAMETER_INACTIVE))
+ fprintf(fp, " Parameter %s File %s \"%s\"\n", param->name,
+ ((stp_get_file_parameter_active
+ (p->v, param->name) == STP_PARAMETER_ACTIVE) ?
+ "True" : "False"),
+ stp_get_file_parameter(p->v, param->name));
+ break;
+ case STP_PARAMETER_TYPE_DOUBLE:
+ if (stp_check_float_parameter(p->v, param->name,
+ STP_PARAMETER_INACTIVE))
+ fprintf(fp, " Parameter %s Double %s %f\n", param->name,
+ ((stp_get_float_parameter_active
+ (p->v, param->name) == STP_PARAMETER_ACTIVE) ?
+ "True" : "False"),
+ stp_get_float_parameter(p->v, param->name));
+ break;
+ case STP_PARAMETER_TYPE_DIMENSION:
+ if (stp_check_dimension_parameter(p->v, param->name,
+ STP_PARAMETER_INACTIVE))
+ fprintf(fp, " Parameter %s Dimension %s %d\n", param->name,
+ ((stp_get_dimension_parameter_active
+ (p->v, param->name) == STP_PARAMETER_ACTIVE) ?
+ "True" : "False"),
+ stp_get_dimension_parameter(p->v, param->name));
+ break;
+ case STP_PARAMETER_TYPE_INT:
+ if (stp_check_int_parameter(p->v, param->name,
+ STP_PARAMETER_INACTIVE))
+ fprintf(fp, " Parameter %s Int %s %d\n", param->name,
+ ((stp_get_int_parameter_active
+ (p->v, param->name) == STP_PARAMETER_ACTIVE) ?
+ "True" : "False"),
+ stp_get_int_parameter(p->v, param->name));
+ break;
+ case STP_PARAMETER_TYPE_BOOLEAN:
+ if (stp_check_boolean_parameter(p->v, param->name,
+ STP_PARAMETER_INACTIVE))
+ fprintf(fp, " Parameter %s Boolean %s %s\n", param->name,
+ ((stp_get_boolean_parameter_active
+ (p->v, param->name) == STP_PARAMETER_ACTIVE) ?
+ "True" : "False"),
+ (stp_get_boolean_parameter(p->v, param->name) ?
+ "True" : "False"));
+ break;
+ case STP_PARAMETER_TYPE_CURVE:
+ if (stp_check_curve_parameter(p->v, param->name,
+ STP_PARAMETER_INACTIVE))
+ {
+ const stp_curve_t *curve =
+ stp_get_curve_parameter(p->v, param->name);
+ if (curve)
+ {
+ fprintf(fp, " Parameter %s Curve %s '",
+ param->name,
+ ((stp_get_curve_parameter_active
+ (p->v, param->name) ==
+ STP_PARAMETER_ACTIVE) ?
+ "True" : "False"));
+ stp_curve_write(fp, curve);
+ fprintf(fp, "'\n");
+ }
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ stp_parameter_list_destroy(params);
+#ifdef DEBUG
+ fprintf(stderr, "Wrote printer %d: %s\n", i, p->name);
+#endif
+ }
+ setlocale(LC_ALL, "");
+ fclose(fp);
+ }
+ else
+ fprintf(stderr, "could not open printrc file \"%s\"\n",filename);
+}
+
+/*
+ * 'compare_printers()' - Compare system printer names for qsort().
+ */
+
+static int
+compare_printers(stpui_plist_t *p1, stpui_plist_t *p2)
+{
+ return (strcmp(p1->name, p2->name));
+}
+
+/*
+ * 'stpui_get_system_printers()' - Get a complete list of printers from the spooler.
+ */
+
+void
+stpui_get_system_printers(void)
+{
+ FILE *pfile; /* Pipe to status command */
+ char line[1025]; /* Line from status command */
+
+ stpui_system_print_queues = stp_string_list_create();
+ stp_string_list_add_string(stpui_system_print_queues, "",
+ _("(Default Printer)"));
+
+ /*
+ * Run the command, if any, to get the available printers...
+ */
+
+ identify_print_system();
+ if (global_printing_system)
+ {
+ if ((pfile = popen(global_printing_system->scan_command, "r")) != NULL)
+ {
+ /*
+ * Read input as needed...
+ */
+
+ while (fgets(line, sizeof(line), pfile) != NULL)
+ {
+ char *tmp_ptr;
+ if ((tmp_ptr = strchr(line, '\n')))
+ tmp_ptr[0] = '\0';
+ if ((tmp_ptr = strchr(line, '\r')))
+ tmp_ptr[0] = '\0';
+ if (strlen(line) > 0)
+ {
+ if (!stp_string_list_is_present(stpui_system_print_queues, line))
+ stp_string_list_add_string(stpui_system_print_queues,
+ line, line);
+ }
+ }
+ pclose(pfile);
+ }
+ }
+}
+
+const stpui_plist_t *
+stpui_get_current_printer(void)
+{
+ return &(stpui_plist[stpui_plist_current]);
+}
+
+/*
+ * 'usr1_handler()' - Make a note when we receive SIGUSR1.
+ */
+
+static volatile int usr1_interrupt;
+
+static void
+usr1_handler (int sig)
+{
+ usr1_interrupt = 1;
+}
+
+static void
+writefunc(void *file, const char *buf, size_t bytes)
+{
+ FILE *prn = (FILE *)file;
+ fwrite(buf, 1, bytes, prn);
+}
+
+static void
+stpui_errfunc(void *file, const char *buf, size_t bytes)
+{
+ g_message(buf);
+}
+
+/*
+ *
+ * Process control for actually printing. Documented 20040821
+ * by Robert Krawitz.
+ *
+ * In addition to the print command itself and the output generator,
+ * we spawn two additional processes to monitor the print job and clean
+ * up. We do this because the GIMP is very unfriendly about how it
+ * terminates plugins when the user cancels an operation: it sends a
+ * SIGKILL, which prevents the plugin from cleaning up. Since the
+ * plugin is sending data to an lpr process, this SIGKILL closes off
+ * the input to lpr. lpr doesn't know that its parent has died
+ * inappropriately, and happily proceeds to print the partial job.
+ *
+ * (The child may not actually be lpr, of course, but we'll just use
+ * that nomenclature for convenience.)
+ *
+ * The first such process is the "lpr monitor". Its job is to
+ * watch the parent (the actual data generator). If its parent dies,
+ * it kills the print command. Notice that it must keep the file
+ * descriptor used to write to the lpr process open, since as soon as
+ * the last writer to this pipe is closed, the lpr process sees its
+ * input close. Therefore, it first kills the child with SIGTERM and
+ * then closes the pipe. Perhaps a more robust method would be to
+ * send a SIGTERM followed by a SIGKILL, but we can worry about that
+ * later. The lpr monitor process is killed with SIGUSR1 by the
+ * master upon successful completion, at which point it exits. The lpr
+ * monitor itself detects that the master has finished by periodically
+ * sending it a kill 0 (a null signal). When the parent exits, this
+ * attempt to signal will return failure. This has a potential race
+ * condition if another process is created with the same PID between
+ * checks. A more robust (but more complicated) solution would involve
+ * IPC of some kind.
+ *
+ * The second such process (the "error monitor") monitors the stderr
+ * (and stdout) of the lpr process, to send any error messages back
+ * to the user. Since the GIMP is normally not launched from a
+ * terminal window, any errors would get lost. The error monitor
+ * captures this output and reports it back. It stays around until
+ * its input is closed (normally by the lpr process exiting), at
+ * which point it reports to the master that it has finished, and the
+ * master can clean up and return.
+ *
+ * The actual master process spawns the lpr monitor, which spawns
+ * the process that will later run the lpr command, which itself
+ * spawns the error monitor.
+ *
+ * This architecture is perhaps unnecessarily complex; the lpr monitor
+ * and error monitor could perhaps be combined into a single process
+ * that watches both for the parent to go away and for the error messages.
+ *
+ * The following diagrams illustrate the control flow during the normal
+ * case and also when the print job is cancelled. The notation for file
+ * descriptors is a number prefixed with < for an input file descriptor
+ * and suffixed > for an output file descriptor. For example, <0 means
+ * input file descriptor 0 and 1> means output file descriptor 1. The
+ * key to the file descriptors is given below. A file descriptor named
+ * x,y refers to file descriptor y duplicated onto file descriptor x.
+ * So "<0,3" means input file descriptor 3 (pipefd[0]) dup2'ed onto
+ * file descriptor 0.
+ *
+ * fd0 = fd 0
+ * fd1 = fd 1
+ * fd2 = fd 2
+ * fd3 = pipefd[0]
+ * fd4 = pipefd[1]
+ * fd5 = syncfd[0]
+ * fd6 = syncfd[1]
+ * fd7 = errfd[0]
+ * fd8 = errfd[1]
+ *
+ *
+ * NORMAL CASE
+ *
+ * PARENT CHILD 1 CHILD 2 CHILD 3
+ * (print generator) (lpr monitor) (print command) (error monitor)
+ * |
+ * stpui_print
+ * |
+ * | <0 1> 2>
+ * |
+ * | pipe(syncfd)
+ * |
+ * | <0 1> 2> <5 6>
+ * |
+ * | pipe(pipefd)
+ * |
+ * | <0 1> 2> <3 4>
+ * | <5 6>
+ * |
+ * | fork =============|
+ * | |
+ * | close(63) | close(syncfd[0])
+ * | | <0 1> 2> <3 4>
+ * | <0 1> 2> 4> <5 | 6>
+ * | |
+ * | | fork =============|
+ * | | |
+ * | | close(01263) | dup2(pipefd[0], 0)
+ * | | | close(pipefd[0]
+ * | | 4> | close(pipefd[1]
+ * | | |
+ * | | | 1> 2> <0,3 6>
+ * | | |
+ * | | | pipe(errfd)
+ * | | | 1> 2> <0,3 6>
+ * | | | <7 8>
+ * | | |
+ * | | | fork =============|
+ * | | | | close(012348)
+ * | | | close(12) | 6> <7
+ * | | | |
+ * | | | <0,3 6> <7 8> |
+ * | | | |
+ * | | | dup2(errfd[1],1) |
+ * | | | dup2(errfd[1],2) |
+ * | | | close(errfd[1]) |
+ * | | | close(pipefd[0]) |
+ * | | | close(pipefd[1]) |
+ * | | | close(syncfd[1]) |
+ * |<<<<<<<<<<<<<<<<<<<|kill(0,0) * EXEC lpr |
+ * |>>>>>>>>>>>>>>>>>>>|OK | <0,3 1,8> 2,8> |
+ * | | | |
+ * | write>>>>>>>>>>>>>+>>>>>>>>>>>>>>>>>>>| |
+ * | | | write(2,8)??>>>>>>|read(<7)->warn
+ * | | | |
+ * | close(4)>>>>>>>>>>+>>>>>>>>>>>>>>>>>>>| |
+ * | <0 1> 2> <5 | | |
+ * | kill>>>>>>>>>>>>>>| | |
+ * | | close(4)>>>>>>>>>>| eof(<0,3) |
+ * | | | |
+ * | | *no open fd* | 1,8> 2,8> |
+ * | | exit | |
+ * | | | exit>>>>>>>>>>>>>>| eof(<7)
+ * | wait<<<<<<<<<<<<<<X X | 6>
+ * | |
+ * | read(<5)<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<| write(6>)
+ * | |
+ * | close(5) | exit
+ * | X
+ * | 0< 1> 2>
+ * |
+ * | return
+ * X
+ *
+ *
+ * ERROR CASE (job cancelled)
+ *
+ * PARENT CHILD 1 CHILD 2 CHILD 3
+ * (print generator) (lpr monitor) (print command) (error monitor)
+ * |
+ * stpui_print
+ * |
+ * | <0 1> 2>
+ * |
+ * | pipe(syncfd)
+ * |
+ * | <0 1> 2> <5 6>
+ * |
+ * | pipe(pipefd)
+ * |
+ * | <0 1> 2> <3 4>
+ * | <5 6>
+ * |
+ * | fork =============|
+ * | |
+ * | close(63) | close(syncfd[0]
+ * | | <0 1> 2> <3 4>
+ * | <0 1> 2> 4> <5 | 6>
+ * | |
+ * | | fork =============|
+ * | | |
+ * | | close(01263) | dup2(pipefd[0], 0)
+ * | | | close(pipefd[0]
+ * | | 4> | close(pipefd[1]
+ * | | |
+ * | | | 1> 2> <3,0 6>
+ * | | |
+ * | | | pipe(errfd)
+ * | | | 1> 2> <3,0 6>
+ * | | | <7 8>
+ * | | |
+ * | | | fork =============|
+ * | | | | close(012348)
+ * | | | close(12) | 6> <7
+ * | | | |
+ * | | | <3,0 6> <7 8> |
+ * | | | |
+ * | | | dup2(errfd[1],1) |
+ * | | | dup2(errfd[1],2) |
+ * | | | close(3468) |
+ * |<<<<<<<<<<<<<<<<<<<|kill(0,0) * EXEC lpr |
+ * |>>>>>>>>>>>>>>>>>>>|OK | <0,3 1,8> 2,8> |
+ * | | | |
+ * | write>>>>>>>>>>>>>+>>>>>>>>>>>>>>>>>>>| |
+ * | | | write(2,8)??>>>>>>|read(<7)->warn
+ * | KILLED | | |
+ * | close(01245)>>>>>>+>>>>>>>>>>>>>>>>>>>| |
+ * X | | |
+ * <<<<<<<<<<<<<<<<<<<|kill(0,0) | |
+ * >>>>>>>>>>>>>>>>>>>|DEAD! | |
+ * |kill(2)>>>>>>>>>>>>|Terminated |
+ * |close(4>)>>>>>>>>>>|eof(0,3) |
+ * | | 1,8> 2,8> |
+ * | *no open fd* |exit>>>>>>>>>>>>>>>|eof(7)
+ * | exit X |
+ * X | 6>
+ * <| write(6)
+ * | exit/SIGPIPE
+ * X
+ */
+
+int
+stpui_print(const stpui_plist_t *printer, stpui_image_t *image)
+{
+ int ppid = getpid (), /* PID of plugin */
+ opid, /* PID of output process */
+ cpid = 0, /* PID of control/monitor process */
+ pipefd[2], /* Fds of the pipe connecting all the above */
+ errfd[2], /* Message logger from lp command */
+ syncfd[2]; /* Sync the logger */
+ FILE *prn = NULL; /* Print file/command */
+ int do_sync = 0;
+ int print_status = 0;
+ int dummy;
+
+ /*
+ * Open the file/execute the print command...
+ */
+
+ if (stpui_plist_get_command_type(printer) == COMMAND_TYPE_DEFAULT ||
+ stpui_plist_get_command_type(printer) == COMMAND_TYPE_CUSTOM)
+ {
+ /*
+ * The following IPC code is only necessary because the GIMP kills
+ * plugins with SIGKILL if its "Cancel" button is pressed; this
+ * gives the plugin no chance whatsoever to clean up after itself.
+ */
+ do_sync = 1;
+ usr1_interrupt = 0;
+ signal (SIGUSR1, usr1_handler);
+ if (pipe (syncfd) != 0)
+ {
+ do_sync = 0;
+ }
+ if (pipe (pipefd) != 0)
+ {
+ prn = NULL;
+ }
+ else
+ {
+ cpid = fork ();
+ if (cpid < 0) /* Error */
+ {
+ do_sync = 0;
+ prn = NULL;
+ }
+ else if (cpid == 0) /* Child 1 (lpr monitor and printer command) */
+ {
+ /* LPR monitor process. Printer output is piped to us. */
+ close(syncfd[0]);
+ opid = fork ();
+ if (opid < 0)
+ {
+ /* Errors will cause the plugin to get a SIGPIPE. */
+ exit (1);
+ }
+ else if (opid == 0) /* Child 2 (printer command) */
+ {
+ dup2 (pipefd[0], 0);
+ close (pipefd[0]);
+ close (pipefd[1]);
+ if (pipe(errfd) == 0)
+ {
+ opid = fork();
+ if (opid < 0)
+ _exit(1);
+ else if (opid == 0) /* Child 3 (monitors stderr) */
+ {
+ stp_outfunc_t errfunc = stpui_get_errfunc();
+ void *errdata = stpui_get_errdata();
+ /* calls g_message on anything it sees */
+ char buf[4096];
+
+ close (pipefd[0]);
+ close (pipefd[1]);
+ close (0);
+ close (1);
+ close (2);
+ close (errfd[1]);
+ while (1)
+ {
+ ssize_t bytes = read(errfd[0], buf, 4095);
+ if (bytes > 0)
+ {
+ buf[bytes] = '\0';
+ (*errfunc)(errdata, buf, bytes);
+ }
+ else
+ {
+ if (bytes < 0)
+ {
+ snprintf(buf, 4095,
+ "Read messages failed: %s\n",
+ strerror(errno));
+ (*errfunc)(errdata, buf, strlen(buf));
+ }
+ write(syncfd[1], "Done", 5);
+ _exit(0);
+ }
+ }
+ /* NOTREACHED */
+ write(syncfd[1], "Done", 5);
+ _exit(0);
+ }
+ else /* Child 2 (printer command) */
+ {
+ const char *command;
+ if (stpui_plist_get_command_type(printer) ==
+ COMMAND_TYPE_DEFAULT)
+ command =
+ stpui_build_standard_print_command
+ (printer, stp_get_printer(printer->v));
+ else
+ command = stpui_plist_get_custom_command(printer);
+ (void) close(2);
+ (void) close(1);
+ dup2 (errfd[1], 2);
+ dup2 (errfd[1], 1);
+ close(errfd[1]);
+ close (pipefd[0]);
+ close (pipefd[1]);
+ close(syncfd[1]);
+ execl("/bin/sh", "/bin/sh", "-c", command, NULL);
+ /* NOTREACHED */
+ _exit (1);
+ }
+ /* NOTREACHED */
+ _exit(1);
+ }
+ else /* pipe() failed! */
+ {
+ _exit(1);
+ }
+ }
+ else /* Child 1 (lpr monitor) */
+ {
+ /*
+ * If the print plugin gets SIGKILLed by gimp, we kill lpr
+ * in turn. If the plugin signals us with SIGUSR1 that it's
+ * finished printing normally, we close our end of the pipe,
+ * and go away.
+ *
+ * Note that we keep pipefd[1] -- which is the pipe from
+ * the print plugin to the lpr process -- open during this.
+ * If we don't, and the parent gets killed, lpr will notice
+ * its stdin getting closed off and start printing.
+ * This way its stdin stays open until we kill it.
+ */
+ close (0);
+ close (1);
+ close (2);
+ close (syncfd[1]);
+ close (pipefd[0]);
+ while (usr1_interrupt == 0)
+ {
+ /*
+ * Note potential race condition, if some other process
+ * happens to get the same pid!
+ */
+ if (kill (ppid, 0) < 0)
+ {
+ /*
+ * The print plugin has been killed!
+ * Note that there is no possibility of the print
+ * job sending us a SIGUSR1 and then exiting;
+ * the parent (print plugin) stays around after
+ * sending us the SIGUSR1, and then waits
+ * for us to die.
+ */
+ kill (opid, SIGTERM);
+ waitpid (opid, &dummy, 0);
+ close (pipefd[1]);
+ /*
+ * We do not want to allow cleanup before exiting.
+ * The exiting parent has already closed the
+ * connection to the X server; if we try to clean
+ * up, we'll notice that fact and complain.
+ */
+ _exit (0);
+ }
+ sleep (5);
+ }
+ /* We got SIGUSR1. */
+ close (pipefd[1]);
+ /*
+ * We do not want to allow cleanup before exiting.
+ * The exiting parent has already closed the connection
+ * to the X server; if we try to clean up, we'll notice
+ * that fact and complain.
+ */
+ _exit (0);
+ }
+ }
+ else /* Parent (actually generates the output) */
+ {
+ close (syncfd[1]);
+ close (pipefd[0]);
+ /* Parent process. We generate the printer output. */
+ prn = fdopen (pipefd[1], "w");
+ /* and fall through... */
+ }
+ }
+ }
+ else
+ prn = fopen (stpui_plist_get_output_filename(printer), "wb");
+
+ if (prn != NULL)
+ {
+ char tmp[32];
+ stpui_plist_t *np = allocate_stpui_plist_copy(printer);
+ const stp_vars_t *current_vars =
+ stp_printer_get_defaults(stp_get_printer(np->v));
+ int orientation;
+ stp_merge_printvars(np->v, current_vars);
+ stp_set_string_parameter(np->v, "InputImageType", image_type);
+ if (image_raw_channels)
+ {
+ sprintf(tmp, "%d", image_raw_channels);
+ stp_set_string_parameter(np->v, "RawChannels", tmp);
+ }
+ sprintf(tmp, "%d", image_channel_depth);
+ stp_set_string_parameter(np->v, "ChannelBitDepth", tmp);
+
+ /*
+ * Set up the orientation
+ */
+ orientation = np->orientation;
+ if (orientation == ORIENT_AUTO)
+ orientation = stpui_compute_orientation();
+ switch (orientation)
+ {
+ case ORIENT_PORTRAIT:
+ break;
+ case ORIENT_LANDSCAPE:
+ if (image->rotate_cw)
+ (image->rotate_cw)(image);
+ break;
+ case ORIENT_UPSIDEDOWN:
+ if (image->rotate_180)
+ (image->rotate_180)(image);
+ break;
+ case ORIENT_SEASCAPE:
+ if (image->rotate_ccw)
+ (image->rotate_ccw)(image);
+ break;
+ }
+
+ /*
+ * Finally, call the print driver to send the image to the printer
+ * and close the output file/command...
+ */
+
+ stp_set_outfunc(np->v, writefunc);
+ stp_set_errfunc(np->v, stpui_get_errfunc());
+ stp_set_outdata(np->v, prn);
+ stp_set_errdata(np->v, stpui_get_errdata());
+ print_status = stp_print(np->v, &(image->im));
+
+ /*
+ * Note that we do not use popen() to create the output, therefore
+ * we do not use pclose() to close it. See bug 1013565.
+ */
+ (void) fclose(prn);
+ if (stpui_plist_get_command_type(printer) == COMMAND_TYPE_DEFAULT ||
+ stpui_plist_get_command_type(printer) == COMMAND_TYPE_CUSTOM)
+ {
+ /*
+ * It is important for us to first close off the lpr process,
+ * then kill the lpr monitor (child 1), and then wait for it
+ * to die before exiting.
+ */
+ kill (cpid, SIGUSR1);
+ waitpid (cpid, &dummy, 0);
+ }
+
+ /*
+ * Make sure that any errors have been reported back to the user
+ * prior to completion. In addition, explicitly close off the
+ * synchronization file descriptor since we're merely returning,
+ * not exiting, and don't want to leave any pollution around.
+ */
+ if (do_sync)
+ {
+ char buf[8];
+ (void) read(syncfd[0], buf, 8);
+ (void) close(syncfd[0]);
+ }
+ stpui_plist_destroy(np);
+ g_free(np);
+ return 1;
+ }
+ return 0;
+}
+
+/*
+ * End of "$Id: plist.c,v 1.5 2005/06/14 02:47:13 rlk Exp $".
+ */
diff --git a/src/gutenprintui2/print-image-thumbnail.c b/src/gutenprintui2/print-image-thumbnail.c
new file mode 100644
index 0000000..51fd136
--- /dev/null
+++ b/src/gutenprintui2/print-image-thumbnail.c
@@ -0,0 +1,130 @@
+/*
+ * "$Id: print-image-thumbnail.c,v 1.1 2004/09/17 18:38:14 rleigh Exp $"
+ *
+ * Print plug-in for the GIMP.
+ *
+ * Copyright 1997-2000 Michael Sweet (mike@easysw.com) and
+ * Robert Krawitz (rlk@alum.mit.edu)
+ * Copyright 2000 Charles Briscoe-Smith <cpbs@debian.org>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <sys/types.h>
+#include <string.h>
+
+#include <gutenprintui2/gutenprintui.h>
+#include "gutenprintui-internal.h"
+
+/* Concrete type to represent image */
+typedef struct
+{
+ const guchar *data;
+ gint w, h, bpp;
+ gint32 real_bpp;
+} thumbnail_image_t;
+
+static const char *Thumbnail_get_appname(stp_image_t *image);
+static void Thumbnail_conclude(stp_image_t *image);
+static stp_image_status_t Thumbnail_get_row(stp_image_t *image,
+ unsigned char *data,
+ size_t byte_limit, int row);
+static int Thumbnail_height(stp_image_t *image);
+static int Thumbnail_width(stp_image_t *image);
+static void Thumbnail_reset(stp_image_t *image);
+static void Thumbnail_init(stp_image_t *image);
+
+static stp_image_t theImage =
+{
+ Thumbnail_init,
+ Thumbnail_reset,
+ Thumbnail_width,
+ Thumbnail_height,
+ Thumbnail_get_row,
+ Thumbnail_get_appname,
+ Thumbnail_conclude,
+ NULL
+};
+
+stp_image_t *
+stpui_image_thumbnail_new(const guchar *data, gint w, gint h, gint bpp)
+{
+ thumbnail_image_t *im;
+ if (! theImage.rep)
+ theImage.rep = stp_malloc(sizeof(thumbnail_image_t));
+ im = (thumbnail_image_t *) (theImage.rep);
+ memset(im, 0, sizeof(thumbnail_image_t));
+ im->data = data;
+ im->w = w;
+ im->h = h;
+ im->bpp = bpp;
+
+ theImage.reset(&theImage);
+ return &theImage;
+}
+
+static int
+Thumbnail_width(stp_image_t *image)
+{
+ thumbnail_image_t *im = (thumbnail_image_t *) (image->rep);
+ return im->w;
+}
+
+static int
+Thumbnail_height(stp_image_t *image)
+{
+ thumbnail_image_t *im = (thumbnail_image_t *) (image->rep);
+ return im->h;
+}
+
+static stp_image_status_t
+Thumbnail_get_row(stp_image_t *image, unsigned char *data,
+ size_t byte_limit, int row)
+{
+ thumbnail_image_t *im = (thumbnail_image_t *) (image->rep);
+ const guchar *where = im->data + (row * im->w * im->bpp);
+ memcpy(data, where, im->w * im->bpp);
+ return STP_IMAGE_STATUS_OK;
+}
+
+static void
+Thumbnail_init(stp_image_t *image)
+{
+ /* Nothing to do. */
+}
+
+static void
+Thumbnail_reset(stp_image_t *image)
+{
+}
+
+static void
+Thumbnail_conclude(stp_image_t *image)
+{
+}
+
+static const char *
+Thumbnail_get_appname(stp_image_t *image)
+{
+ static char pluginname[] = "Thumbnail V" VERSION " - " RELEASE_DATE;
+ return pluginname;
+}
+
+/*
+ * End of "$Id: print-image-thumbnail.c,v 1.1 2004/09/17 18:38:14 rleigh Exp $".
+ */
diff --git a/src/gutenprintui2/printrc.h b/src/gutenprintui2/printrc.h
new file mode 100644
index 0000000..2ff4220
--- /dev/null
+++ b/src/gutenprintui2/printrc.h
@@ -0,0 +1,44 @@
+/*
+ * "$Id: printrc.h,v 1.1 2004/09/17 18:38:14 rleigh Exp $"
+ *
+ * Print plug-in for the GIMP.
+ *
+ * Copyright 1997-2000 Michael Sweet (mike@easysw.com),
+ * Robert Krawitz (rlk@alum.mit.edu). and Steve Miller (smiller@rni.net
+ *
+ * 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 2 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ *
+ * Revision History:
+ *
+ * See ChangeLog
+ */
+
+#ifndef GUTENPRINTUI_PRINTRC_H
+#define GUTENPRINTUI_PRINTRC_H
+
+#if ! defined (YYSTYPE) && ! defined (YYSTYPE_IS_DECLARED)
+typedef union yylv {
+ int ival;
+ double dval;
+ char *sval;
+} YYSTYPE;
+# define yystype YYSTYPE /* obsolescent; will be withdrawn */
+# define YYSTYPE_IS_DECLARED 1
+#endif
+
+#include "printrcy.h"
+
+#endif /* GUTENPRINTUI_PRINTRC_H */
diff --git a/src/gutenprintui2/printrcl.c b/src/gutenprintui2/printrcl.c
new file mode 100644
index 0000000..6d6cd19
--- /dev/null
+++ b/src/gutenprintui2/printrcl.c
@@ -0,0 +1,2106 @@
+
+#line 3 "printrcl.c"
+
+#define YY_INT_ALIGNED short int
+
+/* A lexical scanner generated by flex */
+
+#define FLEX_SCANNER
+#define YY_FLEX_MAJOR_VERSION 2
+#define YY_FLEX_MINOR_VERSION 5
+#define YY_FLEX_SUBMINOR_VERSION 31
+#if YY_FLEX_SUBMINOR_VERSION > 0
+#define FLEX_BETA
+#endif
+
+/* First, we deal with platform-specific or compiler-specific issues. */
+
+/* begin standard C headers. */
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+#include <stdlib.h>
+
+/* end standard C headers. */
+
+/* flex integer type definitions */
+
+#ifndef FLEXINT_H
+#define FLEXINT_H
+
+/* C99 systems have <inttypes.h>. Non-C99 systems may or may not. */
+
+#if defined __STDC_VERSION__ && __STDC_VERSION__ >= 199901L
+#include <inttypes.h>
+typedef int8_t flex_int8_t;
+typedef uint8_t flex_uint8_t;
+typedef int16_t flex_int16_t;
+typedef uint16_t flex_uint16_t;
+typedef int32_t flex_int32_t;
+typedef uint32_t flex_uint32_t;
+#else
+typedef signed char flex_int8_t;
+typedef short int flex_int16_t;
+typedef int flex_int32_t;
+typedef unsigned char flex_uint8_t;
+typedef unsigned short int flex_uint16_t;
+typedef unsigned int flex_uint32_t;
+#endif /* ! C99 */
+
+/* Limits of integral types. */
+#ifndef INT8_MIN
+#define INT8_MIN (-128)
+#endif
+#ifndef INT16_MIN
+#define INT16_MIN (-32767-1)
+#endif
+#ifndef INT32_MIN
+#define INT32_MIN (-2147483647-1)
+#endif
+#ifndef INT8_MAX
+#define INT8_MAX (127)
+#endif
+#ifndef INT16_MAX
+#define INT16_MAX (32767)
+#endif
+#ifndef INT32_MAX
+#define INT32_MAX (2147483647)
+#endif
+#ifndef UINT8_MAX
+#define UINT8_MAX (255U)
+#endif
+#ifndef UINT16_MAX
+#define UINT16_MAX (65535U)
+#endif
+#ifndef UINT32_MAX
+#define UINT32_MAX (4294967295U)
+#endif
+
+#endif /* ! FLEXINT_H */
+
+#ifdef __cplusplus
+
+/* The "const" storage-class-modifier is valid. */
+#define YY_USE_CONST
+
+#else /* ! __cplusplus */
+
+#if __STDC__
+
+#define YY_USE_CONST
+
+#endif /* __STDC__ */
+#endif /* ! __cplusplus */
+
+#ifdef YY_USE_CONST
+#define yyconst const
+#else
+#define yyconst
+#endif
+
+/* Returned upon end-of-file. */
+#define YY_NULL 0
+
+/* Promotes a possibly negative, possibly signed char to an unsigned
+ * integer for use as an array index. If the signed char is negative,
+ * we want to instead treat it as an 8-bit unsigned char, hence the
+ * double cast.
+ */
+#define YY_SC_TO_UI(c) ((unsigned int) (unsigned char) c)
+
+/* Enter a start condition. This macro really ought to take a parameter,
+ * but we do it the disgusting crufty way forced on us by the ()-less
+ * definition of BEGIN.
+ */
+#define BEGIN (yy_start) = 1 + 2 *
+
+/* Translate the current start state into a value that can be later handed
+ * to BEGIN to return to the state. The YYSTATE alias is for lex
+ * compatibility.
+ */
+#define YY_START (((yy_start) - 1) / 2)
+#define YYSTATE YY_START
+
+/* Action number for EOF rule of a given start state. */
+#define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1)
+
+/* Special action meaning "start processing a new file". */
+#define YY_NEW_FILE yyrestart(yyin )
+
+#define YY_END_OF_BUFFER_CHAR 0
+
+/* Size of default input buffer. */
+#ifndef YY_BUF_SIZE
+#define YY_BUF_SIZE 16384
+#endif
+
+#ifndef YY_TYPEDEF_YY_BUFFER_STATE
+#define YY_TYPEDEF_YY_BUFFER_STATE
+typedef struct yy_buffer_state *YY_BUFFER_STATE;
+#endif
+
+extern int yyleng;
+
+extern FILE *yyin, *yyout;
+
+#define EOB_ACT_CONTINUE_SCAN 0
+#define EOB_ACT_END_OF_FILE 1
+#define EOB_ACT_LAST_MATCH 2
+
+ #define YY_LESS_LINENO(n)
+
+/* Return all but the first "n" matched characters back to the input stream. */
+#define yyless(n) \
+ do \
+ { \
+ /* Undo effects of setting up yytext. */ \
+ int yyless_macro_arg = (n); \
+ YY_LESS_LINENO(yyless_macro_arg);\
+ *yy_cp = (yy_hold_char); \
+ YY_RESTORE_YY_MORE_OFFSET \
+ (yy_c_buf_p) = yy_cp = yy_bp + yyless_macro_arg - YY_MORE_ADJ; \
+ YY_DO_BEFORE_ACTION; /* set up yytext again */ \
+ } \
+ while ( 0 )
+
+#define unput(c) yyunput( c, (yytext_ptr) )
+
+/* The following is because we cannot portably get our hands on size_t
+ * (without autoconf's help, which isn't available because we want
+ * flex-generated scanners to compile on their own).
+ */
+
+#ifndef YY_TYPEDEF_YY_SIZE_T
+#define YY_TYPEDEF_YY_SIZE_T
+typedef unsigned int yy_size_t;
+#endif
+
+#ifndef YY_STRUCT_YY_BUFFER_STATE
+#define YY_STRUCT_YY_BUFFER_STATE
+struct yy_buffer_state
+ {
+ FILE *yy_input_file;
+
+ char *yy_ch_buf; /* input buffer */
+ char *yy_buf_pos; /* current position in input buffer */
+
+ /* Size of input buffer in bytes, not including room for EOB
+ * characters.
+ */
+ yy_size_t yy_buf_size;
+
+ /* Number of characters read into yy_ch_buf, not including EOB
+ * characters.
+ */
+ int yy_n_chars;
+
+ /* Whether we "own" the buffer - i.e., we know we created it,
+ * and can realloc() it to grow it, and should free() it to
+ * delete it.
+ */
+ int yy_is_our_buffer;
+
+ /* Whether this is an "interactive" input source; if so, and
+ * if we're using stdio for input, then we want to use getc()
+ * instead of fread(), to make sure we stop fetching input after
+ * each newline.
+ */
+ int yy_is_interactive;
+
+ /* Whether we're considered to be at the beginning of a line.
+ * If so, '^' rules will be active on the next match, otherwise
+ * not.
+ */
+ int yy_at_bol;
+
+ int yy_bs_lineno; /**< The line count. */
+ int yy_bs_column; /**< The column count. */
+
+ /* Whether to try to fill the input buffer when we reach the
+ * end of it.
+ */
+ int yy_fill_buffer;
+
+ int yy_buffer_status;
+
+#define YY_BUFFER_NEW 0
+#define YY_BUFFER_NORMAL 1
+ /* When an EOF's been seen but there's still some text to process
+ * then we mark the buffer as YY_EOF_PENDING, to indicate that we
+ * shouldn't try reading from the input source any more. We might
+ * still have a bunch of tokens to match, though, because of
+ * possible backing-up.
+ *
+ * When we actually see the EOF, we change the status to "new"
+ * (via yyrestart()), so that the user can continue scanning by
+ * just pointing yyin at a new input file.
+ */
+#define YY_BUFFER_EOF_PENDING 2
+
+ };
+#endif /* !YY_STRUCT_YY_BUFFER_STATE */
+
+/* Stack of input buffers. */
+static size_t yy_buffer_stack_top = 0; /**< index of top of stack. */
+static size_t yy_buffer_stack_max = 0; /**< capacity of stack. */
+static YY_BUFFER_STATE * yy_buffer_stack = 0; /**< Stack as an array. */
+
+/* We provide macros for accessing buffer states in case in the
+ * future we want to put the buffer states in a more general
+ * "scanner state".
+ *
+ * Returns the top of the stack, or NULL.
+ */
+#define YY_CURRENT_BUFFER ( (yy_buffer_stack) \
+ ? (yy_buffer_stack)[(yy_buffer_stack_top)] \
+ : NULL)
+
+/* Same as previous macro, but useful when we know that the buffer stack is not
+ * NULL or when we need an lvalue. For internal use only.
+ */
+#define YY_CURRENT_BUFFER_LVALUE (yy_buffer_stack)[(yy_buffer_stack_top)]
+
+/* yy_hold_char holds the character lost when yytext is formed. */
+static char yy_hold_char;
+static int yy_n_chars; /* number of characters read into yy_ch_buf */
+int yyleng;
+
+/* Points to current character in buffer. */
+static char *yy_c_buf_p = (char *) 0;
+static int yy_init = 1; /* whether we need to initialize */
+static int yy_start = 0; /* start state number */
+
+/* Flag which is used to allow yywrap()'s to do buffer switches
+ * instead of setting up a fresh yyin. A bit of a hack ...
+ */
+static int yy_did_buffer_switch_on_eof;
+
+void yyrestart (FILE *input_file );
+void yy_switch_to_buffer (YY_BUFFER_STATE new_buffer );
+YY_BUFFER_STATE yy_create_buffer (FILE *file,int size );
+void yy_delete_buffer (YY_BUFFER_STATE b );
+void yy_flush_buffer (YY_BUFFER_STATE b );
+void yypush_buffer_state (YY_BUFFER_STATE new_buffer );
+void yypop_buffer_state (void );
+
+static void yyensure_buffer_stack (void );
+static void yy_load_buffer_state (void );
+static void yy_init_buffer (YY_BUFFER_STATE b,FILE *file );
+
+#define YY_FLUSH_BUFFER yy_flush_buffer(YY_CURRENT_BUFFER )
+
+YY_BUFFER_STATE yy_scan_buffer (char *base,yy_size_t size );
+YY_BUFFER_STATE yy_scan_string (yyconst char *yy_str );
+YY_BUFFER_STATE yy_scan_bytes (yyconst char *bytes,int len );
+
+void *yyalloc (yy_size_t );
+void *yyrealloc (void *,yy_size_t );
+void yyfree (void * );
+
+#define yy_new_buffer yy_create_buffer
+
+#define yy_set_interactive(is_interactive) \
+ { \
+ if ( ! YY_CURRENT_BUFFER ){ \
+ yyensure_buffer_stack (); \
+ YY_CURRENT_BUFFER_LVALUE = \
+ yy_create_buffer(yyin,YY_BUF_SIZE ); \
+ } \
+ YY_CURRENT_BUFFER_LVALUE->yy_is_interactive = is_interactive; \
+ }
+
+#define yy_set_bol(at_bol) \
+ { \
+ if ( ! YY_CURRENT_BUFFER ){\
+ yyensure_buffer_stack (); \
+ YY_CURRENT_BUFFER_LVALUE = \
+ yy_create_buffer(yyin,YY_BUF_SIZE ); \
+ } \
+ YY_CURRENT_BUFFER_LVALUE->yy_at_bol = at_bol; \
+ }
+
+#define YY_AT_BOL() (YY_CURRENT_BUFFER_LVALUE->yy_at_bol)
+
+#define yywrap(n) 1
+#define YY_SKIP_YYWRAP
+
+typedef unsigned char YY_CHAR;
+
+FILE *yyin = (FILE *) 0, *yyout = (FILE *) 0;
+
+typedef int yy_state_type;
+
+extern int yylineno;
+
+int yylineno = 1;
+
+extern char *yytext;
+#define yytext_ptr yytext
+
+static yy_state_type yy_get_previous_state (void );
+static yy_state_type yy_try_NUL_trans (yy_state_type current_state );
+static int yy_get_next_buffer (void );
+static void yy_fatal_error (yyconst char msg[] );
+
+/* Done after the current pattern has been matched and before the
+ * corresponding action - sets up yytext.
+ */
+#define YY_DO_BEFORE_ACTION \
+ (yytext_ptr) = yy_bp; \
+ yyleng = (size_t) (yy_cp - yy_bp); \
+ (yy_hold_char) = *yy_cp; \
+ *yy_cp = '\0'; \
+ (yy_c_buf_p) = yy_cp;
+
+#define YY_NUM_RULES 40
+#define YY_END_OF_BUFFER 41
+/* This struct is not used in this scanner,
+ but its presence is necessary. */
+struct yy_trans_info
+ {
+ flex_int32_t yy_verify;
+ flex_int32_t yy_nxt;
+ };
+static yyconst flex_int16_t yy_accept[335] =
+ { 0,
+ 0, 0, 41, 40, 37, 39, 40, 38, 40, 40,
+ 31, 35, 35, 35, 35, 35, 35, 35, 35, 35,
+ 35, 35, 35, 35, 35, 35, 35, 37, 0, 33,
+ 38, 38, 0, 31, 0, 0, 35, 35, 35, 35,
+ 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,
+ 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,
+ 35, 35, 35, 38, 32, 0, 32, 35, 35, 35,
+ 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,
+ 35, 24, 35, 35, 35, 35, 35, 35, 35, 35,
+ 35, 35, 35, 35, 38, 35, 35, 35, 35, 35,
+
+ 35, 35, 35, 35, 35, 0, 35, 35, 26, 35,
+ 35, 35, 35, 35, 35, 35, 35, 35, 35, 11,
+ 34, 35, 38, 35, 35, 35, 35, 30, 35, 35,
+ 35, 35, 35, 0, 35, 35, 10, 35, 35, 35,
+ 35, 35, 35, 0, 35, 8, 38, 35, 35, 35,
+ 35, 35, 35, 35, 27, 35, 0, 0, 35, 35,
+ 35, 35, 35, 0, 35, 0, 25, 38, 35, 29,
+ 35, 35, 0, 35, 35, 35, 9, 0, 0, 0,
+ 23, 35, 0, 35, 35, 35, 0, 35, 0, 38,
+ 35, 0, 0, 0, 35, 35, 35, 0, 0, 0,
+
+ 35, 0, 35, 35, 3, 0, 5, 0, 38, 0,
+ 0, 0, 0, 35, 35, 28, 0, 0, 0, 35,
+ 0, 35, 15, 0, 0, 38, 0, 0, 0, 0,
+ 35, 35, 0, 0, 0, 35, 0, 35, 0, 0,
+ 38, 36, 0, 0, 0, 0, 35, 35, 0, 0,
+ 0, 35, 0, 35, 16, 0, 0, 0, 0, 0,
+ 35, 4, 0, 0, 0, 6, 0, 14, 0, 0,
+ 20, 0, 0, 35, 35, 0, 0, 0, 0, 0,
+ 0, 0, 0, 35, 35, 0, 0, 0, 0, 0,
+ 0, 0, 19, 35, 35, 0, 0, 0, 0, 0,
+
+ 0, 1, 35, 35, 0, 0, 21, 17, 0, 0,
+ 35, 35, 0, 0, 0, 0, 35, 12, 0, 0,
+ 0, 0, 13, 0, 0, 0, 7, 22, 0, 0,
+ 0, 2, 18, 0
+ } ;
+
+static yyconst flex_int32_t yy_ec[256] =
+ { 0,
+ 1, 1, 1, 1, 1, 1, 1, 1, 2, 3,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 2, 1, 4, 5, 1, 1, 1, 6, 1,
+ 1, 1, 7, 1, 8, 9, 1, 10, 10, 11,
+ 11, 11, 10, 10, 10, 10, 10, 12, 1, 1,
+ 1, 1, 1, 1, 14, 15, 16, 17, 18, 19,
+ 20, 21, 22, 23, 23, 24, 25, 26, 27, 28,
+ 29, 30, 31, 32, 33, 34, 35, 36, 37, 38,
+ 1, 1, 1, 1, 13, 1, 14, 15, 16, 17,
+
+ 18, 19, 20, 21, 22, 23, 23, 24, 25, 26,
+ 27, 28, 29, 30, 31, 32, 33, 34, 35, 36,
+ 37, 38, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1
+ } ;
+
+static yyconst flex_int32_t yy_meta[39] =
+ { 0,
+ 1, 1, 2, 1, 1, 1, 1, 1, 1, 3,
+ 3, 1, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3
+ } ;
+
+static yyconst flex_int16_t yy_base[340] =
+ { 0,
+ 0, 0, 374, 375, 371, 375, 368, 343, 364, 29,
+ 32, 336, 341, 18, 26, 21, 32, 343, 0, 340,
+ 347, 19, 41, 331, 42, 32, 337, 360, 357, 375,
+ 0, 330, 353, 55, 50, 68, 0, 326, 330, 331,
+ 37, 324, 329, 320, 330, 334, 318, 325, 324, 320,
+ 314, 326, 322, 311, 312, 319, 322, 325, 311, 307,
+ 308, 302, 312, 311, 59, 70, 72, 305, 307, 305,
+ 54, 297, 296, 309, 311, 291, 316, 293, 291, 303,
+ 305, 0, 287, 300, 289, 302, 289, 281, 289, 277,
+ 289, 298, 291, 276, 281, 275, 287, 290, 285, 284,
+
+ 274, 278, 273, 274, 279, 276, 281, 276, 0, 279,
+ 280, 265, 257, 264, 256, 269, 264, 277, 258, 375,
+ 0, 271, 250, 259, 266, 253, 252, 0, 252, 250,
+ 244, 256, 243, 248, 263, 246, 375, 237, 236, 249,
+ 248, 257, 238, 249, 242, 375, 231, 222, 233, 241,
+ 225, 77, 242, 233, 0, 242, 226, 224, 79, 237,
+ 81, 218, 219, 222, 227, 222, 0, 229, 226, 0,
+ 235, 234, 225, 212, 207, 211, 375, 222, 206, 204,
+ 375, 202, 214, 200, 213, 218, 215, 216, 203, 192,
+ 217, 192, 195, 195, 207, 198, 193, 204, 195, 198,
+
+ 193, 192, 176, 182, 375, 186, 375, 202, 198, 178,
+ 170, 176, 180, 184, 176, 0, 178, 175, 168, 172,
+ 174, 169, 0, 178, 167, 191, 166, 164, 169, 165,
+ 171, 162, 179, 154, 153, 158, 165, 164, 169, 166,
+ 176, 375, 154, 159, 150, 161, 161, 161, 141, 153,
+ 148, 157, 142, 155, 375, 138, 141, 152, 131, 136,
+ 51, 375, 143, 130, 133, 375, 144, 375, 139, 148,
+ 375, 137, 137, 135, 130, 119, 142, 129, 123, 117,
+ 118, 115, 132, 121, 125, 109, 113, 108, 120, 129,
+ 122, 123, 375, 114, 101, 110, 103, 118, 117, 97,
+
+ 99, 375, 105, 104, 98, 91, 375, 375, 100, 103,
+ 88, 107, 98, 95, 78, 85, 102, 375, 82, 85,
+ 93, 98, 375, 97, 82, 76, 375, 375, 68, 84,
+ 81, 375, 375, 375, 94, 97, 100, 89, 103
+ } ;
+
+static yyconst flex_int16_t yy_def[340] =
+ { 0,
+ 334, 1, 334, 334, 334, 334, 335, 336, 337, 334,
+ 334, 338, 338, 338, 338, 338, 338, 338, 338, 338,
+ 338, 338, 338, 338, 338, 338, 338, 334, 335, 334,
+ 336, 336, 337, 334, 334, 334, 338, 338, 338, 338,
+ 338, 338, 338, 338, 338, 338, 338, 338, 338, 338,
+ 338, 338, 338, 338, 338, 338, 338, 338, 338, 338,
+ 338, 338, 338, 336, 334, 334, 334, 338, 338, 338,
+ 338, 338, 338, 338, 338, 338, 338, 338, 338, 338,
+ 338, 338, 338, 338, 338, 338, 338, 338, 338, 338,
+ 338, 338, 338, 338, 336, 338, 338, 338, 338, 338,
+
+ 338, 338, 338, 338, 338, 334, 338, 338, 338, 338,
+ 338, 338, 338, 338, 338, 338, 338, 338, 338, 334,
+ 338, 338, 336, 338, 338, 338, 338, 338, 338, 338,
+ 338, 338, 338, 334, 338, 338, 334, 338, 338, 338,
+ 338, 338, 338, 334, 338, 334, 336, 338, 338, 338,
+ 338, 338, 338, 338, 338, 338, 334, 334, 338, 338,
+ 338, 338, 338, 334, 338, 334, 338, 336, 338, 338,
+ 338, 338, 334, 338, 338, 338, 334, 334, 334, 334,
+ 334, 338, 334, 338, 338, 338, 334, 338, 334, 336,
+ 338, 334, 334, 334, 338, 338, 338, 334, 334, 334,
+
+ 338, 334, 338, 338, 334, 334, 334, 334, 336, 334,
+ 334, 334, 334, 338, 338, 338, 334, 334, 334, 338,
+ 334, 338, 338, 334, 334, 339, 334, 334, 334, 334,
+ 338, 338, 334, 334, 334, 338, 334, 338, 334, 334,
+ 339, 334, 334, 334, 334, 334, 338, 338, 334, 334,
+ 334, 338, 334, 338, 334, 334, 334, 334, 334, 334,
+ 338, 334, 334, 334, 334, 334, 334, 334, 334, 334,
+ 334, 334, 334, 338, 338, 334, 334, 334, 334, 334,
+ 334, 334, 334, 338, 338, 334, 334, 334, 334, 334,
+ 334, 334, 334, 338, 338, 334, 334, 334, 334, 334,
+
+ 334, 334, 338, 338, 334, 334, 334, 334, 334, 334,
+ 338, 338, 334, 334, 334, 334, 338, 334, 334, 334,
+ 334, 334, 334, 334, 334, 334, 334, 334, 334, 334,
+ 334, 334, 334, 0, 334, 334, 334, 334, 334
+ } ;
+
+static yyconst flex_int16_t yy_nxt[414] =
+ { 0,
+ 4, 5, 6, 7, 8, 9, 10, 10, 4, 11,
+ 11, 4, 4, 12, 13, 14, 15, 16, 17, 18,
+ 19, 20, 19, 21, 19, 19, 22, 23, 24, 19,
+ 25, 26, 27, 19, 19, 19, 19, 19, 34, 34,
+ 35, 34, 34, 42, 40, 48, 46, 43, 53, 36,
+ 41, 54, 44, 49, 55, 45, 47, 58, 61, 65,
+ 65, 62, 59, 35, 34, 34, 71, 72, 65, 65,
+ 56, 274, 36, 60, 66, 66, 36, 67, 67, 67,
+ 67, 67, 67, 99, 173, 275, 180, 100, 183, 174,
+ 181, 37, 333, 184, 29, 332, 29, 31, 331, 31,
+
+ 33, 33, 33, 241, 241, 241, 330, 329, 328, 327,
+ 326, 325, 324, 323, 322, 321, 320, 319, 318, 317,
+ 316, 315, 314, 313, 312, 311, 310, 309, 308, 307,
+ 306, 305, 304, 303, 302, 301, 300, 299, 298, 297,
+ 296, 295, 294, 293, 292, 291, 290, 289, 288, 287,
+ 286, 285, 284, 283, 282, 281, 280, 279, 278, 277,
+ 276, 273, 272, 271, 270, 269, 268, 267, 266, 265,
+ 264, 263, 262, 261, 260, 259, 258, 257, 242, 256,
+ 255, 254, 253, 252, 251, 250, 249, 248, 247, 246,
+ 245, 244, 243, 242, 240, 239, 238, 237, 236, 235,
+
+ 234, 233, 232, 231, 230, 229, 228, 227, 226, 225,
+ 224, 223, 222, 221, 220, 219, 218, 217, 216, 215,
+ 214, 213, 212, 211, 210, 209, 208, 207, 206, 205,
+ 204, 203, 202, 201, 200, 199, 198, 197, 196, 195,
+ 194, 193, 192, 191, 190, 189, 188, 187, 186, 185,
+ 182, 179, 178, 177, 176, 175, 172, 171, 170, 169,
+ 168, 167, 166, 165, 164, 163, 162, 161, 160, 159,
+ 158, 157, 156, 155, 154, 153, 152, 151, 150, 149,
+ 148, 147, 146, 145, 144, 143, 142, 141, 140, 139,
+ 138, 137, 136, 121, 135, 134, 133, 132, 131, 130,
+
+ 129, 128, 127, 126, 125, 124, 123, 122, 121, 120,
+ 119, 118, 117, 116, 115, 114, 113, 112, 111, 110,
+ 109, 108, 107, 106, 105, 104, 103, 102, 101, 98,
+ 97, 96, 95, 94, 93, 92, 91, 90, 89, 88,
+ 87, 86, 85, 84, 83, 82, 81, 80, 79, 78,
+ 77, 76, 75, 74, 73, 70, 69, 68, 30, 64,
+ 30, 28, 63, 57, 52, 51, 50, 39, 38, 30,
+ 32, 30, 28, 334, 3, 334, 334, 334, 334, 334,
+ 334, 334, 334, 334, 334, 334, 334, 334, 334, 334,
+ 334, 334, 334, 334, 334, 334, 334, 334, 334, 334,
+
+ 334, 334, 334, 334, 334, 334, 334, 334, 334, 334,
+ 334, 334, 334
+ } ;
+
+static yyconst flex_int16_t yy_chk[414] =
+ { 0,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 10, 10,
+ 11, 11, 11, 15, 14, 17, 16, 15, 22, 11,
+ 14, 22, 15, 17, 23, 15, 16, 25, 26, 35,
+ 35, 26, 25, 34, 34, 34, 41, 41, 65, 65,
+ 23, 261, 34, 25, 36, 36, 65, 36, 36, 66,
+ 66, 67, 67, 71, 152, 261, 159, 71, 161, 152,
+ 159, 338, 331, 161, 335, 330, 335, 336, 329, 336,
+
+ 337, 337, 337, 339, 339, 339, 326, 325, 324, 322,
+ 321, 320, 319, 317, 316, 315, 314, 313, 312, 311,
+ 310, 309, 306, 305, 304, 303, 301, 300, 299, 298,
+ 297, 296, 295, 294, 292, 291, 290, 289, 288, 287,
+ 286, 285, 284, 283, 282, 281, 280, 279, 278, 277,
+ 276, 275, 274, 273, 272, 270, 269, 267, 265, 264,
+ 263, 260, 259, 258, 257, 256, 254, 253, 252, 251,
+ 250, 249, 248, 247, 246, 245, 244, 243, 241, 240,
+ 239, 238, 237, 236, 235, 234, 233, 232, 231, 230,
+ 229, 228, 227, 226, 225, 224, 222, 221, 220, 219,
+
+ 218, 217, 215, 214, 213, 212, 211, 210, 209, 208,
+ 206, 204, 203, 202, 201, 200, 199, 198, 197, 196,
+ 195, 194, 193, 192, 191, 190, 189, 188, 187, 186,
+ 185, 184, 183, 182, 180, 179, 178, 176, 175, 174,
+ 173, 172, 171, 169, 168, 166, 165, 164, 163, 162,
+ 160, 158, 157, 156, 154, 153, 151, 150, 149, 148,
+ 147, 145, 144, 143, 142, 141, 140, 139, 138, 136,
+ 135, 134, 133, 132, 131, 130, 129, 127, 126, 125,
+ 124, 123, 122, 119, 118, 117, 116, 115, 114, 113,
+ 112, 111, 110, 108, 107, 106, 105, 104, 103, 102,
+
+ 101, 100, 99, 98, 97, 96, 95, 94, 93, 92,
+ 91, 90, 89, 88, 87, 86, 85, 84, 83, 81,
+ 80, 79, 78, 77, 76, 75, 74, 73, 72, 70,
+ 69, 68, 64, 63, 62, 61, 60, 59, 58, 57,
+ 56, 55, 54, 53, 52, 51, 50, 49, 48, 47,
+ 46, 45, 44, 43, 42, 40, 39, 38, 33, 32,
+ 29, 28, 27, 24, 21, 20, 18, 13, 12, 9,
+ 8, 7, 5, 3, 334, 334, 334, 334, 334, 334,
+ 334, 334, 334, 334, 334, 334, 334, 334, 334, 334,
+ 334, 334, 334, 334, 334, 334, 334, 334, 334, 334,
+
+ 334, 334, 334, 334, 334, 334, 334, 334, 334, 334,
+ 334, 334, 334
+ } ;
+
+static yy_state_type yy_last_accepting_state;
+static char *yy_last_accepting_cpos;
+
+extern int yy_flex_debug;
+int yy_flex_debug = 0;
+
+/* The intent behind this definition is that it'll catch
+ * any uses of REJECT which flex missed.
+ */
+#define REJECT reject_used_but_not_detected
+#define yymore() yymore_used_but_not_detected
+#define YY_MORE_ADJ 0
+#define YY_RESTORE_YY_MORE_OFFSET
+char *yytext;
+#line 1 "printrcl.l"
+/* -*-Mode: C-*-
+ * "$Id: printrcl.l,v 1.1 2004/09/17 18:38:14 rleigh Exp $"
+ *
+ * printrc parser
+ *
+ * Copyright 2003 Robert Krawitz <rlk@alum.mit.edu>
+ *
+ * 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 2 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+#line 24 "printrcl.l"
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <gutenprint/gutenprint-intl-internal.h>
+#include <gutenprintui2/gutenprintui.h>
+#include "gutenprintui-internal.h"
+#include "printrc.h"
+
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#define YY_NO_UNPUT
+
+int mylineno = 1;
+
+#define DBG(x) \
+do \
+ { \
+ if (getenv("STP_DEBUG_PRINTRC")) \
+ fprintf(stderr, "'%s' => %s\n", yytext, #x); \
+ } \
+ while (0)
+
+static char *
+q_strdup(const char *s)
+{
+ /* Strip the leading and trailing quote */
+ if (strlen(s) <= 2)
+ return NULL;
+ else
+ return g_strndup(s + 1, strlen(s) - 2);
+}
+
+#line 701 "printrcl.c"
+
+#define INITIAL 0
+
+#ifndef YY_NO_UNISTD_H
+/* Special case for "unistd.h", since it is non-ANSI. We include it way
+ * down here because we want the user's section 1 to have been scanned first.
+ * The user has a chance to override it with an option.
+ */
+#include <unistd.h>
+#endif
+
+#ifndef YY_EXTRA_TYPE
+#define YY_EXTRA_TYPE void *
+#endif
+
+/* Macros after this point can all be overridden by user definitions in
+ * section 1.
+ */
+
+#ifndef YY_SKIP_YYWRAP
+#ifdef __cplusplus
+extern "C" int yywrap (void );
+#else
+extern int yywrap (void );
+#endif
+#endif
+
+ static void yyunput (int c,char *buf_ptr );
+
+#ifndef yytext_ptr
+static void yy_flex_strncpy (char *,yyconst char *,int );
+#endif
+
+#ifdef YY_NEED_STRLEN
+static int yy_flex_strlen (yyconst char * );
+#endif
+
+#ifndef YY_NO_INPUT
+
+#ifdef __cplusplus
+static int yyinput (void );
+#else
+static int input (void );
+#endif
+
+#endif
+
+/* Amount of stuff to slurp up with each read. */
+#ifndef YY_READ_BUF_SIZE
+#define YY_READ_BUF_SIZE 8192
+#endif
+
+/* Copy whatever the last rule matched to the standard output. */
+#ifndef ECHO
+/* This used to be an fputs(), but since the string might contain NUL's,
+ * we now use fwrite().
+ */
+#define ECHO (void) fwrite( yytext, yyleng, 1, yyout )
+#endif
+
+/* Gets input and stuffs it into "buf". number of characters read, or YY_NULL,
+ * is returned in "result".
+ */
+#ifndef YY_INPUT
+#define YY_INPUT(buf,result,max_size) \
+ if ( YY_CURRENT_BUFFER_LVALUE->yy_is_interactive ) \
+ { \
+ int c = '*'; \
+ size_t n; \
+ for ( n = 0; n < max_size && \
+ (c = getc( yyin )) != EOF && c != '\n'; ++n ) \
+ buf[n] = (char) c; \
+ if ( c == '\n' ) \
+ buf[n++] = (char) c; \
+ if ( c == EOF && ferror( yyin ) ) \
+ YY_FATAL_ERROR( "input in flex scanner failed" ); \
+ result = n; \
+ } \
+ else \
+ { \
+ errno=0; \
+ while ( (result = fread(buf, 1, max_size, yyin))==0 && ferror(yyin)) \
+ { \
+ if( errno != EINTR) \
+ { \
+ YY_FATAL_ERROR( "input in flex scanner failed" ); \
+ break; \
+ } \
+ errno=0; \
+ clearerr(yyin); \
+ } \
+ }\
+\
+
+#endif
+
+/* No semi-colon after return; correct usage is to write "yyterminate();" -
+ * we don't want an extra ';' after the "return" because that will cause
+ * some compilers to complain about unreachable statements.
+ */
+#ifndef yyterminate
+#define yyterminate() return YY_NULL
+#endif
+
+/* Number of entries by which start-condition stack grows. */
+#ifndef YY_START_STACK_INCR
+#define YY_START_STACK_INCR 25
+#endif
+
+/* Report a fatal error. */
+#ifndef YY_FATAL_ERROR
+#define YY_FATAL_ERROR(msg) yy_fatal_error( msg )
+#endif
+
+/* end tables serialization structures and prototypes */
+
+/* Default declaration of generated scanner - a define so the user can
+ * easily add parameters.
+ */
+#ifndef YY_DECL
+#define YY_DECL_IS_OURS 1
+
+extern int yylex (void);
+
+#define YY_DECL int yylex (void)
+#endif /* !YY_DECL */
+
+/* Code executed at the beginning of each rule, after yytext and yyleng
+ * have been set up.
+ */
+#ifndef YY_USER_ACTION
+#define YY_USER_ACTION
+#endif
+
+/* Code executed at the end of each rule. */
+#ifndef YY_BREAK
+#define YY_BREAK break;
+#endif
+
+#define YY_RULE_SETUP \
+ YY_USER_ACTION
+
+/** The main scanner function which does all the work.
+ */
+YY_DECL
+{
+ register yy_state_type yy_current_state;
+ register char *yy_cp, *yy_bp;
+ register int yy_act;
+
+#line 73 "printrcl.l"
+
+
+#line 855 "printrcl.c"
+
+ if ( (yy_init) )
+ {
+ (yy_init) = 0;
+
+#ifdef YY_USER_INIT
+ YY_USER_INIT;
+#endif
+
+ if ( ! (yy_start) )
+ (yy_start) = 1; /* first start state */
+
+ if ( ! yyin )
+ yyin = stdin;
+
+ if ( ! yyout )
+ yyout = stdout;
+
+ if ( ! YY_CURRENT_BUFFER ) {
+ yyensure_buffer_stack ();
+ YY_CURRENT_BUFFER_LVALUE =
+ yy_create_buffer(yyin,YY_BUF_SIZE );
+ }
+
+ yy_load_buffer_state( );
+ }
+
+ while ( 1 ) /* loops until end-of-file is reached */
+ {
+ yy_cp = (yy_c_buf_p);
+
+ /* Support of yytext. */
+ *yy_cp = (yy_hold_char);
+
+ /* yy_bp points to the position in yy_ch_buf of the start of
+ * the current run.
+ */
+ yy_bp = yy_cp;
+
+ yy_current_state = (yy_start);
+yy_match:
+ do
+ {
+ register YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)];
+ if ( yy_accept[yy_current_state] )
+ {
+ (yy_last_accepting_state) = yy_current_state;
+ (yy_last_accepting_cpos) = yy_cp;
+ }
+ while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
+ {
+ yy_current_state = (int) yy_def[yy_current_state];
+ if ( yy_current_state >= 335 )
+ yy_c = yy_meta[(unsigned int) yy_c];
+ }
+ yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
+ ++yy_cp;
+ }
+ while ( yy_base[yy_current_state] != 375 );
+
+yy_find_action:
+ yy_act = yy_accept[yy_current_state];
+ if ( yy_act == 0 )
+ { /* have to back up */
+ yy_cp = (yy_last_accepting_cpos);
+ yy_current_state = (yy_last_accepting_state);
+ yy_act = yy_accept[yy_current_state];
+ }
+
+ YY_DO_BEFORE_ACTION;
+
+do_action: /* This label is used only to access EOF actions. */
+
+ switch ( yy_act )
+ { /* beginning of action switch */
+ case 0: /* must back up */
+ /* undo the effects of YY_DO_BEFORE_ACTION */
+ *yy_cp = (yy_hold_char);
+ yy_cp = (yy_last_accepting_cpos);
+ yy_current_state = (yy_last_accepting_state);
+ goto yy_find_action;
+
+case 1:
+YY_RULE_SETUP
+#line 75 "printrcl.l"
+DBG(CURRENT_PRINTER); return CURRENT_PRINTER;
+ YY_BREAK
+case 2:
+YY_RULE_SETUP
+#line 76 "printrcl.l"
+DBG(SHOW_ALL_PAPER_SIZES); return SHOW_ALL_PAPER_SIZES;
+ YY_BREAK
+case 3:
+YY_RULE_SETUP
+#line 77 "printrcl.l"
+DBG(PRINTER); return PRINTER;
+ YY_BREAK
+case 4:
+YY_RULE_SETUP
+#line 78 "printrcl.l"
+DBG(DESTINATION); return DESTINATION;
+ YY_BREAK
+case 5:
+YY_RULE_SETUP
+#line 79 "printrcl.l"
+DBG(SCALING); return SCALING;
+ YY_BREAK
+case 6:
+YY_RULE_SETUP
+#line 80 "printrcl.l"
+DBG(ORIENTATION); return ORIENTATION;
+ YY_BREAK
+case 7:
+YY_RULE_SETUP
+#line 81 "printrcl.l"
+DBG(AUTOSIZE_ROLL_PAPER); return AUTOSIZE_ROLL_PAPER;
+ YY_BREAK
+case 8:
+YY_RULE_SETUP
+#line 82 "printrcl.l"
+DBG(UNIT); return UNIT;
+ YY_BREAK
+case 9:
+YY_RULE_SETUP
+#line 83 "printrcl.l"
+DBG(DRIVER); return DRIVER;
+ YY_BREAK
+case 10:
+YY_RULE_SETUP
+#line 84 "printrcl.l"
+DBG(LEFT); return LEFT;
+ YY_BREAK
+case 11:
+YY_RULE_SETUP
+#line 85 "printrcl.l"
+DBG(TOP); return TOP;
+ YY_BREAK
+case 12:
+YY_RULE_SETUP
+#line 86 "printrcl.l"
+DBG(CUSTOM_PAGE_WIDTH); return CUSTOM_PAGE_WIDTH;
+ YY_BREAK
+case 13:
+YY_RULE_SETUP
+#line 87 "printrcl.l"
+DBG(CUSTOM_PAGE_HEIGHT); return CUSTOM_PAGE_HEIGHT;
+ YY_BREAK
+case 14:
+YY_RULE_SETUP
+#line 88 "printrcl.l"
+DBG(OUTPUT_TYPE); return OUTPUT_TYPE;
+ YY_BREAK
+case 15:
+YY_RULE_SETUP
+#line 89 "printrcl.l"
+DBG(PARAMETER); return PARAMETER;
+ YY_BREAK
+case 16:
+YY_RULE_SETUP
+#line 90 "printrcl.l"
+DBG(QUEUE_NAME); return QUEUE_NAME;
+ YY_BREAK
+case 17:
+YY_RULE_SETUP
+#line 91 "printrcl.l"
+DBG(OUTPUT_FILENAME); return OUTPUT_FILENAME;
+ YY_BREAK
+case 18:
+YY_RULE_SETUP
+#line 92 "printrcl.l"
+DBG(EXTRA_PRINTER_OPTIONS); return EXTRA_PRINTER_OPTIONS;
+ YY_BREAK
+case 19:
+YY_RULE_SETUP
+#line 93 "printrcl.l"
+DBG(CUSTOM_COMMAND); return CUSTOM_COMMAND;
+ YY_BREAK
+case 20:
+YY_RULE_SETUP
+#line 94 "printrcl.l"
+DBG(COMMAND_TYPE); return COMMAND_TYPE;
+ YY_BREAK
+case 21:
+YY_RULE_SETUP
+#line 95 "printrcl.l"
+DBG(GLOBAL_SETTINGS); return GLOBAL_SETTINGS;
+ YY_BREAK
+case 22:
+YY_RULE_SETUP
+#line 96 "printrcl.l"
+DBG(END_GLOBAL_SETTINGS); return END_GLOBAL_SETTINGS;
+ YY_BREAK
+case 23:
+YY_RULE_SETUP
+#line 97 "printrcl.l"
+DBG(GLOBAL); return GLOBAL;
+ YY_BREAK
+case 24:
+YY_RULE_SETUP
+#line 99 "printrcl.l"
+DBG(pINT); return pINT;
+ YY_BREAK
+case 25:
+YY_RULE_SETUP
+#line 100 "printrcl.l"
+DBG(pSTRING_LIST); return pSTRING_LIST;
+ YY_BREAK
+case 26:
+YY_RULE_SETUP
+#line 101 "printrcl.l"
+DBG(pFILE); return pFILE;
+ YY_BREAK
+case 27:
+YY_RULE_SETUP
+#line 102 "printrcl.l"
+DBG(pDOUBLE); return pDOUBLE;
+ YY_BREAK
+case 28:
+YY_RULE_SETUP
+#line 103 "printrcl.l"
+DBG(pDIMENSION); return pDIMENSION;
+ YY_BREAK
+case 29:
+YY_RULE_SETUP
+#line 104 "printrcl.l"
+DBG(pBOOLEAN); return pBOOLEAN;
+ YY_BREAK
+case 30:
+YY_RULE_SETUP
+#line 105 "printrcl.l"
+DBG(pCURVE); return pCURVE;
+ YY_BREAK
+case 31:
+YY_RULE_SETUP
+#line 107 "printrcl.l"
+yylval.ival = atoi(yytext); DBG(tINT); return tINT;
+ YY_BREAK
+case 32:
+YY_RULE_SETUP
+#line 108 "printrcl.l"
+yylval.dval = strtod(yytext, NULL); DBG(tDOUBLE); return tDOUBLE;
+ YY_BREAK
+case 33:
+/* rule 33 can match eol */
+YY_RULE_SETUP
+#line 109 "printrcl.l"
+yylval.sval = q_strdup(yytext); DBG(tSTRING); return tSTRING;
+ YY_BREAK
+case 34:
+YY_RULE_SETUP
+#line 110 "printrcl.l"
+yylval.sval = g_strdup(yytext); DBG(tBOOLEAN); return tBOOLEAN;
+ YY_BREAK
+case 35:
+YY_RULE_SETUP
+#line 111 "printrcl.l"
+yylval.sval = g_strdup(yytext); DBG(tWORD); return tWORD;
+ YY_BREAK
+case 36:
+/* rule 36 can match eol */
+YY_RULE_SETUP
+#line 112 "printrcl.l"
+DBG(PRINTRC_HDR); return PRINTRC_HDR;
+ YY_BREAK
+case 37:
+YY_RULE_SETUP
+#line 113 "printrcl.l"
+DBG(whitespace1); /* Skip blanks/tabs */
+ YY_BREAK
+case 38:
+YY_RULE_SETUP
+#line 114 "printrcl.l"
+DBG(comment1); /* Skip comments */
+ YY_BREAK
+case 39:
+/* rule 39 can match eol */
+YY_RULE_SETUP
+#line 115 "printrcl.l"
+DBG(newline); mylineno++;
+ YY_BREAK
+case 40:
+YY_RULE_SETUP
+#line 116 "printrcl.l"
+ECHO;
+ YY_BREAK
+#line 1141 "printrcl.c"
+case YY_STATE_EOF(INITIAL):
+ yyterminate();
+
+ case YY_END_OF_BUFFER:
+ {
+ /* Amount of text matched not including the EOB char. */
+ int yy_amount_of_matched_text = (int) (yy_cp - (yytext_ptr)) - 1;
+
+ /* Undo the effects of YY_DO_BEFORE_ACTION. */
+ *yy_cp = (yy_hold_char);
+ YY_RESTORE_YY_MORE_OFFSET
+
+ if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_NEW )
+ {
+ /* We're scanning a new file or input source. It's
+ * possible that this happened because the user
+ * just pointed yyin at a new source and called
+ * yylex(). If so, then we have to assure
+ * consistency between YY_CURRENT_BUFFER and our
+ * globals. Here is the right place to do so, because
+ * this is the first action (other than possibly a
+ * back-up) that will match for the new input source.
+ */
+ (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars;
+ YY_CURRENT_BUFFER_LVALUE->yy_input_file = yyin;
+ YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = YY_BUFFER_NORMAL;
+ }
+
+ /* Note that here we test for yy_c_buf_p "<=" to the position
+ * of the first EOB in the buffer, since yy_c_buf_p will
+ * already have been incremented past the NUL character
+ * (since all states make transitions on EOB to the
+ * end-of-buffer state). Contrast this with the test
+ * in input().
+ */
+ if ( (yy_c_buf_p) <= &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] )
+ { /* This was really a NUL. */
+ yy_state_type yy_next_state;
+
+ (yy_c_buf_p) = (yytext_ptr) + yy_amount_of_matched_text;
+
+ yy_current_state = yy_get_previous_state( );
+
+ /* Okay, we're now positioned to make the NUL
+ * transition. We couldn't have
+ * yy_get_previous_state() go ahead and do it
+ * for us because it doesn't know how to deal
+ * with the possibility of jamming (and we don't
+ * want to build jamming into it because then it
+ * will run more slowly).
+ */
+
+ yy_next_state = yy_try_NUL_trans( yy_current_state );
+
+ yy_bp = (yytext_ptr) + YY_MORE_ADJ;
+
+ if ( yy_next_state )
+ {
+ /* Consume the NUL. */
+ yy_cp = ++(yy_c_buf_p);
+ yy_current_state = yy_next_state;
+ goto yy_match;
+ }
+
+ else
+ {
+ yy_cp = (yy_c_buf_p);
+ goto yy_find_action;
+ }
+ }
+
+ else switch ( yy_get_next_buffer( ) )
+ {
+ case EOB_ACT_END_OF_FILE:
+ {
+ (yy_did_buffer_switch_on_eof) = 0;
+
+ if ( yywrap( ) )
+ {
+ /* Note: because we've taken care in
+ * yy_get_next_buffer() to have set up
+ * yytext, we can now set up
+ * yy_c_buf_p so that if some total
+ * hoser (like flex itself) wants to
+ * call the scanner after we return the
+ * YY_NULL, it'll still work - another
+ * YY_NULL will get returned.
+ */
+ (yy_c_buf_p) = (yytext_ptr) + YY_MORE_ADJ;
+
+ yy_act = YY_STATE_EOF(YY_START);
+ goto do_action;
+ }
+
+ else
+ {
+ if ( ! (yy_did_buffer_switch_on_eof) )
+ YY_NEW_FILE;
+ }
+ break;
+ }
+
+ case EOB_ACT_CONTINUE_SCAN:
+ (yy_c_buf_p) =
+ (yytext_ptr) + yy_amount_of_matched_text;
+
+ yy_current_state = yy_get_previous_state( );
+
+ yy_cp = (yy_c_buf_p);
+ yy_bp = (yytext_ptr) + YY_MORE_ADJ;
+ goto yy_match;
+
+ case EOB_ACT_LAST_MATCH:
+ (yy_c_buf_p) =
+ &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)];
+
+ yy_current_state = yy_get_previous_state( );
+
+ yy_cp = (yy_c_buf_p);
+ yy_bp = (yytext_ptr) + YY_MORE_ADJ;
+ goto yy_find_action;
+ }
+ break;
+ }
+
+ default:
+ YY_FATAL_ERROR(
+ "fatal flex scanner internal error--no action found" );
+ } /* end of action switch */
+ } /* end of scanning one token */
+} /* end of yylex */
+
+/* yy_get_next_buffer - try to read in a new buffer
+ *
+ * Returns a code representing an action:
+ * EOB_ACT_LAST_MATCH -
+ * EOB_ACT_CONTINUE_SCAN - continue scanning from current position
+ * EOB_ACT_END_OF_FILE - end of file
+ */
+static int yy_get_next_buffer (void)
+{
+ register char *dest = YY_CURRENT_BUFFER_LVALUE->yy_ch_buf;
+ register char *source = (yytext_ptr);
+ register int number_to_move, i;
+ int ret_val;
+
+ if ( (yy_c_buf_p) > &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] )
+ YY_FATAL_ERROR(
+ "fatal flex scanner internal error--end of buffer missed" );
+
+ if ( YY_CURRENT_BUFFER_LVALUE->yy_fill_buffer == 0 )
+ { /* Don't try to fill the buffer, so this is an EOF. */
+ if ( (yy_c_buf_p) - (yytext_ptr) - YY_MORE_ADJ == 1 )
+ {
+ /* We matched a single character, the EOB, so
+ * treat this as a final EOF.
+ */
+ return EOB_ACT_END_OF_FILE;
+ }
+
+ else
+ {
+ /* We matched some text prior to the EOB, first
+ * process it.
+ */
+ return EOB_ACT_LAST_MATCH;
+ }
+ }
+
+ /* Try to read more data. */
+
+ /* First move last chars to start of buffer. */
+ number_to_move = (int) ((yy_c_buf_p) - (yytext_ptr)) - 1;
+
+ for ( i = 0; i < number_to_move; ++i )
+ *(dest++) = *(source++);
+
+ if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_EOF_PENDING )
+ /* don't do the read, it's not guaranteed to return an EOF,
+ * just force an EOF
+ */
+ YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars) = 0;
+
+ else
+ {
+ size_t num_to_read =
+ YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1;
+
+ while ( num_to_read <= 0 )
+ { /* Not enough room in the buffer - grow it. */
+
+ /* just a shorter name for the current buffer */
+ YY_BUFFER_STATE b = YY_CURRENT_BUFFER;
+
+ int yy_c_buf_p_offset =
+ (int) ((yy_c_buf_p) - b->yy_ch_buf);
+
+ if ( b->yy_is_our_buffer )
+ {
+ int new_size = b->yy_buf_size * 2;
+
+ if ( new_size <= 0 )
+ b->yy_buf_size += b->yy_buf_size / 8;
+ else
+ b->yy_buf_size *= 2;
+
+ b->yy_ch_buf = (char *)
+ /* Include room in for 2 EOB chars. */
+ yyrealloc((void *) b->yy_ch_buf,b->yy_buf_size + 2 );
+ }
+ else
+ /* Can't grow it, we don't own it. */
+ b->yy_ch_buf = 0;
+
+ if ( ! b->yy_ch_buf )
+ YY_FATAL_ERROR(
+ "fatal error - scanner input buffer overflow" );
+
+ (yy_c_buf_p) = &b->yy_ch_buf[yy_c_buf_p_offset];
+
+ num_to_read = YY_CURRENT_BUFFER_LVALUE->yy_buf_size -
+ number_to_move - 1;
+
+ }
+
+ if ( num_to_read > YY_READ_BUF_SIZE )
+ num_to_read = YY_READ_BUF_SIZE;
+
+ /* Read in more data. */
+ YY_INPUT( (&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]),
+ (yy_n_chars), num_to_read );
+
+ YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars);
+ }
+
+ if ( (yy_n_chars) == 0 )
+ {
+ if ( number_to_move == YY_MORE_ADJ )
+ {
+ ret_val = EOB_ACT_END_OF_FILE;
+ yyrestart(yyin );
+ }
+
+ else
+ {
+ ret_val = EOB_ACT_LAST_MATCH;
+ YY_CURRENT_BUFFER_LVALUE->yy_buffer_status =
+ YY_BUFFER_EOF_PENDING;
+ }
+ }
+
+ else
+ ret_val = EOB_ACT_CONTINUE_SCAN;
+
+ (yy_n_chars) += number_to_move;
+ YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] = YY_END_OF_BUFFER_CHAR;
+ YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] = YY_END_OF_BUFFER_CHAR;
+
+ (yytext_ptr) = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[0];
+
+ return ret_val;
+}
+
+/* yy_get_previous_state - get the state just before the EOB char was reached */
+
+ static yy_state_type yy_get_previous_state (void)
+{
+ register yy_state_type yy_current_state;
+ register char *yy_cp;
+
+ yy_current_state = (yy_start);
+
+ for ( yy_cp = (yytext_ptr) + YY_MORE_ADJ; yy_cp < (yy_c_buf_p); ++yy_cp )
+ {
+ register YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1);
+ if ( yy_accept[yy_current_state] )
+ {
+ (yy_last_accepting_state) = yy_current_state;
+ (yy_last_accepting_cpos) = yy_cp;
+ }
+ while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
+ {
+ yy_current_state = (int) yy_def[yy_current_state];
+ if ( yy_current_state >= 335 )
+ yy_c = yy_meta[(unsigned int) yy_c];
+ }
+ yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
+ }
+
+ return yy_current_state;
+}
+
+/* yy_try_NUL_trans - try to make a transition on the NUL character
+ *
+ * synopsis
+ * next_state = yy_try_NUL_trans( current_state );
+ */
+ static yy_state_type yy_try_NUL_trans (yy_state_type yy_current_state )
+{
+ register int yy_is_jam;
+ register char *yy_cp = (yy_c_buf_p);
+
+ register YY_CHAR yy_c = 1;
+ if ( yy_accept[yy_current_state] )
+ {
+ (yy_last_accepting_state) = yy_current_state;
+ (yy_last_accepting_cpos) = yy_cp;
+ }
+ while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
+ {
+ yy_current_state = (int) yy_def[yy_current_state];
+ if ( yy_current_state >= 335 )
+ yy_c = yy_meta[(unsigned int) yy_c];
+ }
+ yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
+ yy_is_jam = (yy_current_state == 334);
+
+ return yy_is_jam ? 0 : yy_current_state;
+}
+
+ static void yyunput (int c, register char * yy_bp )
+{
+ register char *yy_cp;
+
+ yy_cp = (yy_c_buf_p);
+
+ /* undo effects of setting up yytext */
+ *yy_cp = (yy_hold_char);
+
+ if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 )
+ { /* need to shift things up to make room */
+ /* +2 for EOB chars. */
+ register int number_to_move = (yy_n_chars) + 2;
+ register char *dest = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[
+ YY_CURRENT_BUFFER_LVALUE->yy_buf_size + 2];
+ register char *source =
+ &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move];
+
+ while ( source > YY_CURRENT_BUFFER_LVALUE->yy_ch_buf )
+ *--dest = *--source;
+
+ yy_cp += (int) (dest - source);
+ yy_bp += (int) (dest - source);
+ YY_CURRENT_BUFFER_LVALUE->yy_n_chars =
+ (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_buf_size;
+
+ if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 )
+ YY_FATAL_ERROR( "flex scanner push-back overflow" );
+ }
+
+ *--yy_cp = (char) c;
+
+ (yytext_ptr) = yy_bp;
+ (yy_hold_char) = *yy_cp;
+ (yy_c_buf_p) = yy_cp;
+}
+
+#ifndef YY_NO_INPUT
+#ifdef __cplusplus
+ static int yyinput (void)
+#else
+ static int input (void)
+#endif
+
+{
+ int c;
+
+ *(yy_c_buf_p) = (yy_hold_char);
+
+ if ( *(yy_c_buf_p) == YY_END_OF_BUFFER_CHAR )
+ {
+ /* yy_c_buf_p now points to the character we want to return.
+ * If this occurs *before* the EOB characters, then it's a
+ * valid NUL; if not, then we've hit the end of the buffer.
+ */
+ if ( (yy_c_buf_p) < &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] )
+ /* This was really a NUL. */
+ *(yy_c_buf_p) = '\0';
+
+ else
+ { /* need more input */
+ int offset = (yy_c_buf_p) - (yytext_ptr);
+ ++(yy_c_buf_p);
+
+ switch ( yy_get_next_buffer( ) )
+ {
+ case EOB_ACT_LAST_MATCH:
+ /* This happens because yy_g_n_b()
+ * sees that we've accumulated a
+ * token and flags that we need to
+ * try matching the token before
+ * proceeding. But for input(),
+ * there's no matching to consider.
+ * So convert the EOB_ACT_LAST_MATCH
+ * to EOB_ACT_END_OF_FILE.
+ */
+
+ /* Reset buffer status. */
+ yyrestart(yyin );
+
+ /*FALLTHROUGH*/
+
+ case EOB_ACT_END_OF_FILE:
+ {
+ if ( yywrap( ) )
+ return EOF;
+
+ if ( ! (yy_did_buffer_switch_on_eof) )
+ YY_NEW_FILE;
+#ifdef __cplusplus
+ return yyinput();
+#else
+ return input();
+#endif
+ }
+
+ case EOB_ACT_CONTINUE_SCAN:
+ (yy_c_buf_p) = (yytext_ptr) + offset;
+ break;
+ }
+ }
+ }
+
+ c = *(unsigned char *) (yy_c_buf_p); /* cast for 8-bit char's */
+ *(yy_c_buf_p) = '\0'; /* preserve yytext */
+ (yy_hold_char) = *++(yy_c_buf_p);
+
+ return c;
+}
+#endif /* ifndef YY_NO_INPUT */
+
+/** Immediately switch to a different input stream.
+ * @param input_file A readable stream.
+ *
+ * @note This function does not reset the start condition to @c INITIAL .
+ */
+ void yyrestart (FILE * input_file )
+{
+
+ if ( ! YY_CURRENT_BUFFER ){
+ yyensure_buffer_stack ();
+ YY_CURRENT_BUFFER_LVALUE =
+ yy_create_buffer(yyin,YY_BUF_SIZE );
+ }
+
+ yy_init_buffer(YY_CURRENT_BUFFER,input_file );
+ yy_load_buffer_state( );
+}
+
+/** Switch to a different input buffer.
+ * @param new_buffer The new input buffer.
+ *
+ */
+ void yy_switch_to_buffer (YY_BUFFER_STATE new_buffer )
+{
+
+ /* TODO. We should be able to replace this entire function body
+ * with
+ * yypop_buffer_state();
+ * yypush_buffer_state(new_buffer);
+ */
+ yyensure_buffer_stack ();
+ if ( YY_CURRENT_BUFFER == new_buffer )
+ return;
+
+ if ( YY_CURRENT_BUFFER )
+ {
+ /* Flush out information for old buffer. */
+ *(yy_c_buf_p) = (yy_hold_char);
+ YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p);
+ YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars);
+ }
+
+ YY_CURRENT_BUFFER_LVALUE = new_buffer;
+ yy_load_buffer_state( );
+
+ /* We don't actually know whether we did this switch during
+ * EOF (yywrap()) processing, but the only time this flag
+ * is looked at is after yywrap() is called, so it's safe
+ * to go ahead and always set it.
+ */
+ (yy_did_buffer_switch_on_eof) = 1;
+}
+
+static void yy_load_buffer_state (void)
+{
+ (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars;
+ (yytext_ptr) = (yy_c_buf_p) = YY_CURRENT_BUFFER_LVALUE->yy_buf_pos;
+ yyin = YY_CURRENT_BUFFER_LVALUE->yy_input_file;
+ (yy_hold_char) = *(yy_c_buf_p);
+}
+
+/** Allocate and initialize an input buffer state.
+ * @param file A readable stream.
+ * @param size The character buffer size in bytes. When in doubt, use @c YY_BUF_SIZE.
+ *
+ * @return the allocated buffer state.
+ */
+ YY_BUFFER_STATE yy_create_buffer (FILE * file, int size )
+{
+ YY_BUFFER_STATE b;
+
+ b = (YY_BUFFER_STATE) yyalloc(sizeof( struct yy_buffer_state ) );
+ if ( ! b )
+ YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" );
+
+ b->yy_buf_size = size;
+
+ /* yy_ch_buf has to be 2 characters longer than the size given because
+ * we need to put in 2 end-of-buffer characters.
+ */
+ b->yy_ch_buf = (char *) yyalloc(b->yy_buf_size + 2 );
+ if ( ! b->yy_ch_buf )
+ YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" );
+
+ b->yy_is_our_buffer = 1;
+
+ yy_init_buffer(b,file );
+
+ return b;
+}
+
+/** Destroy the buffer.
+ * @param b a buffer created with yy_create_buffer()
+ *
+ */
+ void yy_delete_buffer (YY_BUFFER_STATE b )
+{
+
+ if ( ! b )
+ return;
+
+ if ( b == YY_CURRENT_BUFFER ) /* Not sure if we should pop here. */
+ YY_CURRENT_BUFFER_LVALUE = (YY_BUFFER_STATE) 0;
+
+ if ( b->yy_is_our_buffer )
+ yyfree((void *) b->yy_ch_buf );
+
+ yyfree((void *) b );
+}
+
+#ifndef __cplusplus
+extern int isatty (int );
+#endif /* __cplusplus */
+
+/* Initializes or reinitializes a buffer.
+ * This function is sometimes called more than once on the same buffer,
+ * such as during a yyrestart() or at EOF.
+ */
+ static void yy_init_buffer (YY_BUFFER_STATE b, FILE * file )
+
+{
+ int oerrno = errno;
+
+ yy_flush_buffer(b );
+
+ b->yy_input_file = file;
+ b->yy_fill_buffer = 1;
+
+ /* If b is the current buffer, then yy_init_buffer was _probably_
+ * called from yyrestart() or through yy_get_next_buffer.
+ * In that case, we don't want to reset the lineno or column.
+ */
+ if (b != YY_CURRENT_BUFFER){
+ b->yy_bs_lineno = 1;
+ b->yy_bs_column = 0;
+ }
+
+ b->yy_is_interactive = file ? (isatty( fileno(file) ) > 0) : 0;
+
+ errno = oerrno;
+}
+
+/** Discard all buffered characters. On the next scan, YY_INPUT will be called.
+ * @param b the buffer state to be flushed, usually @c YY_CURRENT_BUFFER.
+ *
+ */
+ void yy_flush_buffer (YY_BUFFER_STATE b )
+{
+ if ( ! b )
+ return;
+
+ b->yy_n_chars = 0;
+
+ /* We always need two end-of-buffer characters. The first causes
+ * a transition to the end-of-buffer state. The second causes
+ * a jam in that state.
+ */
+ b->yy_ch_buf[0] = YY_END_OF_BUFFER_CHAR;
+ b->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR;
+
+ b->yy_buf_pos = &b->yy_ch_buf[0];
+
+ b->yy_at_bol = 1;
+ b->yy_buffer_status = YY_BUFFER_NEW;
+
+ if ( b == YY_CURRENT_BUFFER )
+ yy_load_buffer_state( );
+}
+
+/** Pushes the new state onto the stack. The new state becomes
+ * the current state. This function will allocate the stack
+ * if necessary.
+ * @param new_buffer The new state.
+ *
+ */
+void yypush_buffer_state (YY_BUFFER_STATE new_buffer )
+{
+ if (new_buffer == NULL)
+ return;
+
+ yyensure_buffer_stack();
+
+ /* This block is copied from yy_switch_to_buffer. */
+ if ( YY_CURRENT_BUFFER )
+ {
+ /* Flush out information for old buffer. */
+ *(yy_c_buf_p) = (yy_hold_char);
+ YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p);
+ YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars);
+ }
+
+ /* Only push if top exists. Otherwise, replace top. */
+ if (YY_CURRENT_BUFFER)
+ (yy_buffer_stack_top)++;
+ YY_CURRENT_BUFFER_LVALUE = new_buffer;
+
+ /* copied from yy_switch_to_buffer. */
+ yy_load_buffer_state( );
+ (yy_did_buffer_switch_on_eof) = 1;
+}
+
+/** Removes and deletes the top of the stack, if present.
+ * The next element becomes the new top.
+ *
+ */
+void yypop_buffer_state (void)
+{
+ if (!YY_CURRENT_BUFFER)
+ return;
+
+ yy_delete_buffer(YY_CURRENT_BUFFER );
+ YY_CURRENT_BUFFER_LVALUE = NULL;
+ if ((yy_buffer_stack_top) > 0)
+ --(yy_buffer_stack_top);
+
+ if (YY_CURRENT_BUFFER) {
+ yy_load_buffer_state( );
+ (yy_did_buffer_switch_on_eof) = 1;
+ }
+}
+
+/* Allocates the stack if it does not exist.
+ * Guarantees space for at least one push.
+ */
+static void yyensure_buffer_stack (void)
+{
+ int num_to_alloc;
+
+ if (!(yy_buffer_stack)) {
+
+ /* First allocation is just for 2 elements, since we don't know if this
+ * scanner will even need a stack. We use 2 instead of 1 to avoid an
+ * immediate realloc on the next call.
+ */
+ num_to_alloc = 1;
+ (yy_buffer_stack) = (struct yy_buffer_state**)yyalloc
+ (num_to_alloc * sizeof(struct yy_buffer_state*)
+ );
+
+ memset((yy_buffer_stack), 0, num_to_alloc * sizeof(struct yy_buffer_state*));
+
+ (yy_buffer_stack_max) = num_to_alloc;
+ (yy_buffer_stack_top) = 0;
+ return;
+ }
+
+ if ((yy_buffer_stack_top) >= ((yy_buffer_stack_max)) - 1){
+
+ /* Increase the buffer to prepare for a possible push. */
+ int grow_size = 8 /* arbitrary grow size */;
+
+ num_to_alloc = (yy_buffer_stack_max) + grow_size;
+ (yy_buffer_stack) = (struct yy_buffer_state**)yyrealloc
+ ((yy_buffer_stack),
+ num_to_alloc * sizeof(struct yy_buffer_state*)
+ );
+
+ /* zero only the new slots.*/
+ memset((yy_buffer_stack) + (yy_buffer_stack_max), 0, grow_size * sizeof(struct yy_buffer_state*));
+ (yy_buffer_stack_max) = num_to_alloc;
+ }
+}
+
+/** Setup the input buffer state to scan directly from a user-specified character buffer.
+ * @param base the character buffer
+ * @param size the size in bytes of the character buffer
+ *
+ * @return the newly allocated buffer state object.
+ */
+YY_BUFFER_STATE yy_scan_buffer (char * base, yy_size_t size )
+{
+ YY_BUFFER_STATE b;
+
+ if ( size < 2 ||
+ base[size-2] != YY_END_OF_BUFFER_CHAR ||
+ base[size-1] != YY_END_OF_BUFFER_CHAR )
+ /* They forgot to leave room for the EOB's. */
+ return 0;
+
+ b = (YY_BUFFER_STATE) yyalloc(sizeof( struct yy_buffer_state ) );
+ if ( ! b )
+ YY_FATAL_ERROR( "out of dynamic memory in yy_scan_buffer()" );
+
+ b->yy_buf_size = size - 2; /* "- 2" to take care of EOB's */
+ b->yy_buf_pos = b->yy_ch_buf = base;
+ b->yy_is_our_buffer = 0;
+ b->yy_input_file = 0;
+ b->yy_n_chars = b->yy_buf_size;
+ b->yy_is_interactive = 0;
+ b->yy_at_bol = 1;
+ b->yy_fill_buffer = 0;
+ b->yy_buffer_status = YY_BUFFER_NEW;
+
+ yy_switch_to_buffer(b );
+
+ return b;
+}
+
+/** Setup the input buffer state to scan a string. The next call to yylex() will
+ * scan from a @e copy of @a str.
+ * @param str a NUL-terminated string to scan
+ *
+ * @return the newly allocated buffer state object.
+ * @note If you want to scan bytes that may contain NUL values, then use
+ * yy_scan_bytes() instead.
+ */
+YY_BUFFER_STATE yy_scan_string (yyconst char * yy_str )
+{
+
+ return yy_scan_bytes(yy_str,strlen(yy_str) );
+}
+
+/** Setup the input buffer state to scan the given bytes. The next call to yylex() will
+ * scan from a @e copy of @a bytes.
+ * @param bytes the byte buffer to scan
+ * @param len the number of bytes in the buffer pointed to by @a bytes.
+ *
+ * @return the newly allocated buffer state object.
+ */
+YY_BUFFER_STATE yy_scan_bytes (yyconst char * bytes, int len )
+{
+ YY_BUFFER_STATE b;
+ char *buf;
+ yy_size_t n;
+ int i;
+
+ /* Get memory for full buffer, including space for trailing EOB's. */
+ n = len + 2;
+ buf = (char *) yyalloc(n );
+ if ( ! buf )
+ YY_FATAL_ERROR( "out of dynamic memory in yy_scan_bytes()" );
+
+ for ( i = 0; i < len; ++i )
+ buf[i] = bytes[i];
+
+ buf[len] = buf[len+1] = YY_END_OF_BUFFER_CHAR;
+
+ b = yy_scan_buffer(buf,n );
+ if ( ! b )
+ YY_FATAL_ERROR( "bad buffer in yy_scan_bytes()" );
+
+ /* It's okay to grow etc. this buffer, and we should throw it
+ * away when we're done.
+ */
+ b->yy_is_our_buffer = 1;
+
+ return b;
+}
+
+#ifndef YY_EXIT_FAILURE
+#define YY_EXIT_FAILURE 2
+#endif
+
+static void yy_fatal_error (yyconst char* msg )
+{
+ (void) fprintf( stderr, "%s\n", msg );
+ exit( YY_EXIT_FAILURE );
+}
+
+/* Redefine yyless() so it works in section 3 code. */
+
+#undef yyless
+#define yyless(n) \
+ do \
+ { \
+ /* Undo effects of setting up yytext. */ \
+ int yyless_macro_arg = (n); \
+ YY_LESS_LINENO(yyless_macro_arg);\
+ yytext[yyleng] = (yy_hold_char); \
+ (yy_c_buf_p) = yytext + yyless_macro_arg; \
+ (yy_hold_char) = *(yy_c_buf_p); \
+ *(yy_c_buf_p) = '\0'; \
+ yyleng = yyless_macro_arg; \
+ } \
+ while ( 0 )
+
+/* Accessor methods (get/set functions) to struct members. */
+
+/** Get the current line number.
+ *
+ */
+int yyget_lineno (void)
+{
+
+ return yylineno;
+}
+
+/** Get the input stream.
+ *
+ */
+FILE *yyget_in (void)
+{
+ return yyin;
+}
+
+/** Get the output stream.
+ *
+ */
+FILE *yyget_out (void)
+{
+ return yyout;
+}
+
+/** Get the length of the current token.
+ *
+ */
+int yyget_leng (void)
+{
+ return yyleng;
+}
+
+/** Get the current token.
+ *
+ */
+
+char *yyget_text (void)
+{
+ return yytext;
+}
+
+/** Set the current line number.
+ * @param line_number
+ *
+ */
+void yyset_lineno (int line_number )
+{
+
+ yylineno = line_number;
+}
+
+/** Set the input stream. This does not discard the current
+ * input buffer.
+ * @param in_str A readable stream.
+ *
+ * @see yy_switch_to_buffer
+ */
+void yyset_in (FILE * in_str )
+{
+ yyin = in_str ;
+}
+
+void yyset_out (FILE * out_str )
+{
+ yyout = out_str ;
+}
+
+int yyget_debug (void)
+{
+ return yy_flex_debug;
+}
+
+void yyset_debug (int bdebug )
+{
+ yy_flex_debug = bdebug ;
+}
+
+/* yylex_destroy is for both reentrant and non-reentrant scanners. */
+int yylex_destroy (void)
+{
+
+ /* Pop the buffer stack, destroying each element. */
+ while(YY_CURRENT_BUFFER){
+ yy_delete_buffer(YY_CURRENT_BUFFER );
+ YY_CURRENT_BUFFER_LVALUE = NULL;
+ yypop_buffer_state();
+ }
+
+ /* Destroy the stack itself. */
+ yyfree((yy_buffer_stack) );
+ (yy_buffer_stack) = NULL;
+
+ return 0;
+}
+
+/*
+ * Internal utility routines.
+ */
+
+#ifndef yytext_ptr
+static void yy_flex_strncpy (char* s1, yyconst char * s2, int n )
+{
+ register int i;
+ for ( i = 0; i < n; ++i )
+ s1[i] = s2[i];
+}
+#endif
+
+#ifdef YY_NEED_STRLEN
+static int yy_flex_strlen (yyconst char * s )
+{
+ register int n;
+ for ( n = 0; s[n]; ++n )
+ ;
+
+ return n;
+}
+#endif
+
+void *yyalloc (yy_size_t size )
+{
+ return (void *) malloc( size );
+}
+
+void *yyrealloc (void * ptr, yy_size_t size )
+{
+ /* The cast to (char *) in the following accommodates both
+ * implementations that use char* generic pointers, and those
+ * that use void* generic pointers. It works with the latter
+ * because both ANSI C and C++ allow castless assignment from
+ * any pointer type to void*, and deal with argument conversions
+ * as though doing an assignment.
+ */
+ return (void *) realloc( (char *) ptr, size );
+}
+
+void yyfree (void * ptr )
+{
+ free( (char *) ptr ); /* see yyrealloc() for (char *) cast */
+}
+
+#define YYTABLES_NAME "yytables"
+
+#undef YY_NEW_FILE
+#undef YY_FLUSH_BUFFER
+#undef yy_set_bol
+#undef yy_new_buffer
+#undef yy_set_interactive
+#undef yytext_ptr
+#undef YY_DO_BEFORE_ACTION
+
+#ifdef YY_DECL_IS_OURS
+#undef YY_DECL_IS_OURS
+#undef YY_DECL
+#endif
+#line 116 "printrcl.l"
diff --git a/src/gutenprintui2/printrcl.l b/src/gutenprintui2/printrcl.l
new file mode 100644
index 0000000..018adf0
--- /dev/null
+++ b/src/gutenprintui2/printrcl.l
@@ -0,0 +1,115 @@
+/* -*-Mode: C-*-
+ * "$Id: printrcl.l,v 1.1 2004/09/17 18:38:14 rleigh Exp $"
+ *
+ * printrc parser
+ *
+ * Copyright 2003 Robert Krawitz <rlk@alum.mit.edu>
+ *
+ * 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 2 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+%{
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <gutenprint/gutenprint-intl-internal.h>
+#include <gutenprintui2/gutenprintui.h>
+#include "gutenprintui-internal.h"
+#include "printrc.h"
+
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#define YY_NO_UNPUT
+
+int mylineno = 1;
+
+#define DBG(x) \
+do \
+ { \
+ if (getenv("STP_DEBUG_PRINTRC")) \
+ fprintf(stderr, "'%s' => %s\n", yytext, #x); \
+ } \
+ while (0)
+
+static char *
+q_strdup(const char *s)
+{
+ /* Strip the leading and trailing quote */
+ if (strlen(s) <= 2)
+ return NULL;
+ else
+ return g_strndup(s + 1, strlen(s) - 2);
+}
+
+%}
+
+%option noyywrap
+
+digit [0-9]
+boolean (True)|(False)
+integer [-+]?{digit}+
+float [-+]?{digit}+(\.{digit}+)?([eE][-+]?{digit}+)?
+string ([\"][^\"\n]*[\"])|([\'][^\']*[\'])
+ws [ \t]+
+printrc_hdr #PRINTRCv[234].*\n
+word [a-zA-Z][a-zA-Z0-9_]*
+
+%%
+
+Current-Printer: DBG(CURRENT_PRINTER); return CURRENT_PRINTER;
+Show-All-Paper-Sizes: DBG(SHOW_ALL_PAPER_SIZES); return SHOW_ALL_PAPER_SIZES;
+Printer: DBG(PRINTER); return PRINTER;
+Destination: DBG(DESTINATION); return DESTINATION;
+Scaling: DBG(SCALING); return SCALING;
+Orientation: DBG(ORIENTATION); return ORIENTATION;
+Autosize-Roll-Paper: DBG(AUTOSIZE_ROLL_PAPER); return AUTOSIZE_ROLL_PAPER;
+Unit: DBG(UNIT); return UNIT;
+Driver: DBG(DRIVER); return DRIVER;
+Left: DBG(LEFT); return LEFT;
+Top: DBG(TOP); return TOP;
+Custom_Page_Width: DBG(CUSTOM_PAGE_WIDTH); return CUSTOM_PAGE_WIDTH;
+Custom_Page_Height: DBG(CUSTOM_PAGE_HEIGHT); return CUSTOM_PAGE_HEIGHT;
+Output_Type: DBG(OUTPUT_TYPE); return OUTPUT_TYPE;
+Parameter DBG(PARAMETER); return PARAMETER;
+Queue-Name: DBG(QUEUE_NAME); return QUEUE_NAME;
+Output-Filename: DBG(OUTPUT_FILENAME); return OUTPUT_FILENAME;
+Extra-Printer-Options: DBG(EXTRA_PRINTER_OPTIONS); return EXTRA_PRINTER_OPTIONS;
+Custom-Command: DBG(CUSTOM_COMMAND); return CUSTOM_COMMAND;
+Command-Type: DBG(COMMAND_TYPE); return COMMAND_TYPE;
+Global-Settings: DBG(GLOBAL_SETTINGS); return GLOBAL_SETTINGS;
+End-Global-Settings: DBG(END_GLOBAL_SETTINGS); return END_GLOBAL_SETTINGS;
+Global: DBG(GLOBAL); return GLOBAL;
+
+Int DBG(pINT); return pINT;
+String DBG(pSTRING_LIST); return pSTRING_LIST;
+File DBG(pFILE); return pFILE;
+Double DBG(pDOUBLE); return pDOUBLE;
+Dimension DBG(pDIMENSION); return pDIMENSION;
+Boolean DBG(pBOOLEAN); return pBOOLEAN;
+Curve DBG(pCURVE); return pCURVE;
+
+{integer} yylval.ival = atoi(yytext); DBG(tINT); return tINT;
+{float} yylval.dval = strtod(yytext, NULL); DBG(tDOUBLE); return tDOUBLE;
+{string} yylval.sval = q_strdup(yytext); DBG(tSTRING); return tSTRING;
+{boolean} yylval.sval = g_strdup(yytext); DBG(tBOOLEAN); return tBOOLEAN;
+{word} yylval.sval = g_strdup(yytext); DBG(tWORD); return tWORD;
+{printrc_hdr} DBG(PRINTRC_HDR); return PRINTRC_HDR;
+{ws} DBG(whitespace1); /* Skip blanks/tabs */
+#[^\n]* DBG(comment1); /* Skip comments */
+\n DBG(newline); mylineno++;
diff --git a/src/gutenprintui2/printrcy.c b/src/gutenprintui2/printrcy.c
new file mode 100644
index 0000000..4495ae6
--- /dev/null
+++ b/src/gutenprintui2/printrcy.c
@@ -0,0 +1,1694 @@
+/* A Bison parser, made by GNU Bison 1.875d. */
+
+/* Skeleton parser for Yacc-like parsing with Bison,
+ Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
+
+ 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 2, 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, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
+
+/* As a special exception, when this file is copied by Bison into a
+ Bison output file, you may use that output file without restriction.
+ This special exception was added by the Free Software Foundation
+ in version 1.24 of Bison. */
+
+/* Written by Richard Stallman by simplifying the original so called
+ ``semantic'' parser. */
+
+/* All symbols defined below should begin with yy or YY, to avoid
+ infringing on user name space. This should be done even for local
+ variables, as they might otherwise be expanded by user macros.
+ There are some unavoidable exceptions within include files to
+ define necessary library symbols; they are noted "INFRINGES ON
+ USER NAME SPACE" below. */
+
+/* Identify Bison output. */
+#define YYBISON 1
+
+/* Skeleton name. */
+#define YYSKELETON_NAME "yacc.c"
+
+/* Pure parsers. */
+#define YYPURE 0
+
+/* Using locations. */
+#define YYLSP_NEEDED 0
+
+
+
+/* Tokens. */
+#ifndef YYTOKENTYPE
+# define YYTOKENTYPE
+ /* Put the tokens into the symbol table, so that GDB and other debuggers
+ know about them. */
+ enum yytokentype {
+ tINT = 258,
+ tDOUBLE = 259,
+ tDIMENSION = 260,
+ tBOOLEAN = 261,
+ tSTRING = 262,
+ tWORD = 263,
+ tGSWORD = 264,
+ CURRENT_PRINTER = 265,
+ SHOW_ALL_PAPER_SIZES = 266,
+ PRINTER = 267,
+ DESTINATION = 268,
+ SCALING = 269,
+ ORIENTATION = 270,
+ AUTOSIZE_ROLL_PAPER = 271,
+ UNIT = 272,
+ DRIVER = 273,
+ LEFT = 274,
+ TOP = 275,
+ CUSTOM_PAGE_WIDTH = 276,
+ CUSTOM_PAGE_HEIGHT = 277,
+ OUTPUT_TYPE = 278,
+ PRINTRC_HDR = 279,
+ PARAMETER = 280,
+ QUEUE_NAME = 281,
+ OUTPUT_FILENAME = 282,
+ EXTRA_PRINTER_OPTIONS = 283,
+ CUSTOM_COMMAND = 284,
+ COMMAND_TYPE = 285,
+ GLOBAL_SETTINGS = 286,
+ GLOBAL = 287,
+ END_GLOBAL_SETTINGS = 288,
+ pINT = 289,
+ pSTRING_LIST = 290,
+ pFILE = 291,
+ pDOUBLE = 292,
+ pDIMENSION = 293,
+ pBOOLEAN = 294,
+ pCURVE = 295
+ };
+#endif
+#define tINT 258
+#define tDOUBLE 259
+#define tDIMENSION 260
+#define tBOOLEAN 261
+#define tSTRING 262
+#define tWORD 263
+#define tGSWORD 264
+#define CURRENT_PRINTER 265
+#define SHOW_ALL_PAPER_SIZES 266
+#define PRINTER 267
+#define DESTINATION 268
+#define SCALING 269
+#define ORIENTATION 270
+#define AUTOSIZE_ROLL_PAPER 271
+#define UNIT 272
+#define DRIVER 273
+#define LEFT 274
+#define TOP 275
+#define CUSTOM_PAGE_WIDTH 276
+#define CUSTOM_PAGE_HEIGHT 277
+#define OUTPUT_TYPE 278
+#define PRINTRC_HDR 279
+#define PARAMETER 280
+#define QUEUE_NAME 281
+#define OUTPUT_FILENAME 282
+#define EXTRA_PRINTER_OPTIONS 283
+#define CUSTOM_COMMAND 284
+#define COMMAND_TYPE 285
+#define GLOBAL_SETTINGS 286
+#define GLOBAL 287
+#define END_GLOBAL_SETTINGS 288
+#define pINT 289
+#define pSTRING_LIST 290
+#define pFILE 291
+#define pDOUBLE 292
+#define pDIMENSION 293
+#define pBOOLEAN 294
+#define pCURVE 295
+
+
+
+
+/* Copy the first part of user declarations. */
+#line 23 "printrcy.y"
+
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <gutenprint/gutenprint-intl-internal.h>
+#include <gutenprintui2/gutenprintui.h>
+#include "gutenprintui-internal.h"
+#include "printrc.h"
+
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+extern int mylineno;
+
+extern int yylex(void);
+char *quotestrip(const char *i);
+char *endstrip(const char *i);
+
+extern char* yytext;
+
+static int yyerror( const char *s )
+{
+ fprintf(stderr,"stdin:%d: %s before '%s'\n", mylineno, s, yytext);
+ return 0;
+}
+
+static stpui_plist_t *current_printer = NULL;
+
+
+
+/* Enabling traces. */
+#ifndef YYDEBUG
+# define YYDEBUG 0
+#endif
+
+/* Enabling verbose error messages. */
+#ifdef YYERROR_VERBOSE
+# undef YYERROR_VERBOSE
+# define YYERROR_VERBOSE 1
+#else
+# define YYERROR_VERBOSE 0
+#endif
+
+#if ! defined (YYSTYPE) && ! defined (YYSTYPE_IS_DECLARED)
+typedef int YYSTYPE;
+# define yystype YYSTYPE /* obsolescent; will be withdrawn */
+# define YYSTYPE_IS_DECLARED 1
+# define YYSTYPE_IS_TRIVIAL 1
+#endif
+
+
+
+/* Copy the second part of user declarations. */
+
+
+/* Line 214 of yacc.c. */
+#line 200 "printrcy.c"
+
+#if ! defined (yyoverflow) || YYERROR_VERBOSE
+
+# ifndef YYFREE
+# define YYFREE free
+# endif
+# ifndef YYMALLOC
+# define YYMALLOC malloc
+# endif
+
+/* The parser invokes alloca or malloc; define the necessary symbols. */
+
+# ifdef YYSTACK_USE_ALLOCA
+# if YYSTACK_USE_ALLOCA
+# define YYSTACK_ALLOC alloca
+# endif
+# else
+# if defined (alloca) || defined (_ALLOCA_H)
+# define YYSTACK_ALLOC alloca
+# else
+# ifdef __GNUC__
+# define YYSTACK_ALLOC __builtin_alloca
+# endif
+# endif
+# endif
+
+# ifdef YYSTACK_ALLOC
+ /* Pacify GCC's `empty if-body' warning. */
+# define YYSTACK_FREE(Ptr) do { /* empty */; } while (0)
+# else
+# if defined (__STDC__) || defined (__cplusplus)
+# include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
+# define YYSIZE_T size_t
+# endif
+# define YYSTACK_ALLOC YYMALLOC
+# define YYSTACK_FREE YYFREE
+# endif
+#endif /* ! defined (yyoverflow) || YYERROR_VERBOSE */
+
+
+#if (! defined (yyoverflow) \
+ && (! defined (__cplusplus) \
+ || (defined (YYSTYPE_IS_TRIVIAL) && YYSTYPE_IS_TRIVIAL)))
+
+/* A type that is properly aligned for any stack member. */
+union yyalloc
+{
+ short int yyss;
+ YYSTYPE yyvs;
+ };
+
+/* The size of the maximum gap between one aligned stack and the next. */
+# define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1)
+
+/* The size of an array large to enough to hold all stacks, each with
+ N elements. */
+# define YYSTACK_BYTES(N) \
+ ((N) * (sizeof (short int) + sizeof (YYSTYPE)) \
+ + YYSTACK_GAP_MAXIMUM)
+
+/* Copy COUNT objects from FROM to TO. The source and destination do
+ not overlap. */
+# ifndef YYCOPY
+# if defined (__GNUC__) && 1 < __GNUC__
+# define YYCOPY(To, From, Count) \
+ __builtin_memcpy (To, From, (Count) * sizeof (*(From)))
+# else
+# define YYCOPY(To, From, Count) \
+ do \
+ { \
+ register YYSIZE_T yyi; \
+ for (yyi = 0; yyi < (Count); yyi++) \
+ (To)[yyi] = (From)[yyi]; \
+ } \
+ while (0)
+# endif
+# endif
+
+/* Relocate STACK from its old location to the new one. The
+ local variables YYSIZE and YYSTACKSIZE give the old and new number of
+ elements in the stack, and YYPTR gives the new location of the
+ stack. Advance YYPTR to a properly aligned location for the next
+ stack. */
+# define YYSTACK_RELOCATE(Stack) \
+ do \
+ { \
+ YYSIZE_T yynewbytes; \
+ YYCOPY (&yyptr->Stack, Stack, yysize); \
+ Stack = &yyptr->Stack; \
+ yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \
+ yyptr += yynewbytes / sizeof (*yyptr); \
+ } \
+ while (0)
+
+#endif
+
+#if defined (__STDC__) || defined (__cplusplus)
+ typedef signed char yysigned_char;
+#else
+ typedef short int yysigned_char;
+#endif
+
+/* YYFINAL -- State number of the termination state. */
+#define YYFINAL 10
+/* YYLAST -- Last index in YYTABLE. */
+#define YYLAST 75
+
+/* YYNTOKENS -- Number of terminals. */
+#define YYNTOKENS 41
+/* YYNNTS -- Number of nonterminals. */
+#define YYNNTS 42
+/* YYNRULES -- Number of rules. */
+#define YYNRULES 70
+/* YYNRULES -- Number of states. */
+#define YYNSTATES 114
+
+/* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */
+#define YYUNDEFTOK 2
+#define YYMAXUTOK 295
+
+#define YYTRANSLATE(YYX) \
+ ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK)
+
+/* YYTRANSLATE[YYLEX] -- Bison symbol number corresponding to YYLEX. */
+static const unsigned char yytranslate[] =
+{
+ 0, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 1, 2, 3, 4,
+ 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
+ 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
+ 25, 26, 27, 28, 29, 30, 31, 32, 33, 34,
+ 35, 36, 37, 38, 39, 40
+};
+
+#if YYDEBUG
+/* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in
+ YYRHS. */
+static const unsigned char yyprhs[] =
+{
+ 0, 0, 3, 7, 10, 13, 16, 19, 22, 25,
+ 28, 31, 34, 37, 40, 43, 46, 49, 52, 53,
+ 58, 63, 68, 73, 78, 83, 88, 90, 92, 94,
+ 96, 98, 100, 102, 105, 108, 110, 112, 114, 116,
+ 118, 120, 122, 124, 126, 128, 130, 132, 134, 136,
+ 138, 140, 143, 145, 149, 152, 154, 157, 160, 162,
+ 164, 167, 170, 172, 174, 177, 179, 183, 185, 187,
+ 189
+};
+
+/* YYRHS -- A `-1'-separated list of the rules' RHS. */
+static const yysigned_char yyrhs[] =
+{
+ 82, 0, -1, 12, 7, 7, -1, 13, 7, -1,
+ 26, 7, -1, 27, 7, -1, 28, 7, -1, 29,
+ 7, -1, 30, 3, -1, 14, 4, -1, 15, 3,
+ -1, 16, 3, -1, 17, 3, -1, 19, 3, -1,
+ 20, 3, -1, 23, 3, -1, 21, 3, -1, 22,
+ 3, -1, -1, 8, 34, 6, 3, -1, 8, 35,
+ 6, 7, -1, 8, 36, 6, 7, -1, 8, 37,
+ 6, 4, -1, 8, 38, 6, 3, -1, 8, 39,
+ 6, 6, -1, 8, 40, 6, 7, -1, 59, -1,
+ 60, -1, 61, -1, 62, -1, 64, -1, 65, -1,
+ 63, -1, 25, 66, -1, 68, 67, -1, 58, -1,
+ 43, -1, 49, -1, 50, -1, 51, -1, 52, -1,
+ 53, -1, 54, -1, 56, -1, 57, -1, 55, -1,
+ 44, -1, 45, -1, 46, -1, 47, -1, 48, -1,
+ 70, 69, -1, 58, -1, 42, 70, 68, -1, 72,
+ 71, -1, 58, -1, 10, 7, -1, 11, 6, -1,
+ 73, -1, 74, -1, 73, 74, -1, 8, 7, -1,
+ 75, -1, 77, -1, 79, 78, -1, 58, -1, 31,
+ 79, 33, -1, 80, -1, 76, -1, 58, -1, 24,
+ 81, 72, -1
+};
+
+/* YYRLINE[YYN] -- source line where rule number YYN was defined. */
+static const unsigned short int yyrline[] =
+{
+ 0, 100, 100, 111, 118, 128, 138, 148, 158, 164,
+ 168, 172, 176, 180, 184, 188, 206, 210, 214, 217,
+ 231, 246, 261, 275, 289, 307, 327, 327, 327, 327,
+ 328, 328, 328, 331, 334, 334, 337, 337, 337, 337,
+ 338, 338, 338, 338, 338, 339, 339, 339, 339, 340,
+ 340, 343, 343, 346, 349, 349, 352, 356, 366, 366,
+ 369, 372, 383, 383, 386, 386, 389, 392, 392, 392,
+ 395
+};
+#endif
+
+#if YYDEBUG || YYERROR_VERBOSE
+/* YYTNME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM.
+ First, the terminals, then, starting at YYNTOKENS, nonterminals. */
+static const char *const yytname[] =
+{
+ "$end", "error", "$undefined", "tINT", "tDOUBLE", "tDIMENSION",
+ "tBOOLEAN", "tSTRING", "tWORD", "tGSWORD", "CURRENT_PRINTER",
+ "SHOW_ALL_PAPER_SIZES", "PRINTER", "DESTINATION", "SCALING",
+ "ORIENTATION", "AUTOSIZE_ROLL_PAPER", "UNIT", "DRIVER", "LEFT", "TOP",
+ "CUSTOM_PAGE_WIDTH", "CUSTOM_PAGE_HEIGHT", "OUTPUT_TYPE", "PRINTRC_HDR",
+ "PARAMETER", "QUEUE_NAME", "OUTPUT_FILENAME", "EXTRA_PRINTER_OPTIONS",
+ "CUSTOM_COMMAND", "COMMAND_TYPE", "GLOBAL_SETTINGS", "GLOBAL",
+ "END_GLOBAL_SETTINGS", "pINT", "pSTRING_LIST", "pFILE", "pDOUBLE",
+ "pDIMENSION", "pBOOLEAN", "pCURVE", "$accept", "Printer", "Destination",
+ "Queue_Name", "Output_Filename", "Extra_Printer_Options",
+ "Custom_Command", "Command_Type", "Scaling", "Orientation",
+ "Autosize_Roll_Paper", "Unit", "Left", "Top", "Output_Type",
+ "Custom_Page_Width", "Custom_Page_Height", "Empty", "Int_Param",
+ "String_List_Param", "File_Param", "Double_Param", "Dimension_Param",
+ "Boolean_Param", "Curve_Param", "Typed_Param", "Parameter", "Parameters",
+ "Standard_Value", "Standard_Values", "A_Printer", "Printers",
+ "Current_Printer", "Show_All_Paper_Sizes", "Global", "Old_Globals",
+ "New_Global_Setting", "Global_Setting", "Global_Settings",
+ "Global_Subblock", "Global_Block", "Thing", 0
+};
+#endif
+
+# ifdef YYPRINT
+/* YYTOKNUM[YYLEX-NUM] -- Internal token number corresponding to
+ token YYLEX-NUM. */
+static const unsigned short int yytoknum[] =
+{
+ 0, 256, 257, 258, 259, 260, 261, 262, 263, 264,
+ 265, 266, 267, 268, 269, 270, 271, 272, 273, 274,
+ 275, 276, 277, 278, 279, 280, 281, 282, 283, 284,
+ 285, 286, 287, 288, 289, 290, 291, 292, 293, 294,
+ 295
+};
+# endif
+
+/* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */
+static const unsigned char yyr1[] =
+{
+ 0, 41, 42, 43, 44, 45, 46, 47, 48, 49,
+ 50, 51, 52, 53, 54, 55, 56, 57, 58, 59,
+ 60, 61, 62, 63, 64, 65, 66, 66, 66, 66,
+ 66, 66, 66, 67, 68, 68, 69, 69, 69, 69,
+ 69, 69, 69, 69, 69, 69, 69, 69, 69, 69,
+ 69, 70, 70, 71, 72, 72, 73, 74, 75, 75,
+ 76, 77, 78, 78, 79, 79, 80, 81, 81, 81,
+ 82
+};
+
+/* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */
+static const unsigned char yyr2[] =
+{
+ 0, 2, 3, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 0, 4,
+ 4, 4, 4, 4, 4, 4, 1, 1, 1, 1,
+ 1, 1, 1, 2, 2, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 2, 1, 3, 2, 1, 2, 2, 1, 1,
+ 2, 2, 1, 1, 2, 1, 3, 1, 1, 1,
+ 3
+};
+
+/* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state
+ STATE-NUM when YYTABLE doesn't specify something else to do. Zero
+ means the default is an error. */
+static const unsigned char yydefact[] =
+{
+ 0, 18, 0, 0, 18, 69, 0, 68, 67, 18,
+ 1, 56, 65, 0, 0, 60, 55, 70, 0, 66,
+ 58, 59, 62, 63, 64, 57, 0, 18, 54, 61,
+ 0, 52, 18, 2, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 36,
+ 46, 47, 48, 49, 50, 37, 38, 39, 40, 41,
+ 42, 45, 43, 44, 35, 53, 51, 3, 9, 10,
+ 11, 12, 13, 14, 16, 17, 15, 4, 5, 6,
+ 7, 8, 0, 34, 0, 26, 27, 28, 29, 32,
+ 30, 31, 33, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 19, 20, 21,
+ 22, 23, 24, 25
+};
+
+/* YYDEFGOTO[NTERM-NUM]. */
+static const yysigned_char yydefgoto[] =
+{
+ -1, 27, 49, 50, 51, 52, 53, 54, 55, 56,
+ 57, 58, 59, 60, 61, 62, 63, 5, 85, 86,
+ 87, 88, 89, 90, 91, 92, 83, 65, 66, 32,
+ 28, 17, 6, 15, 22, 7, 23, 24, 13, 8,
+ 9, 2
+};
+
+/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing
+ STATE-NUM. */
+#define YYPACT_NINF -26
+static const yysigned_char yypact[] =
+{
+ -22, -2, 6, 0, -26, -26, 5, -26, -26, -26,
+ -26, -26, -26, -7, 11, -26, -26, 7, 13, -26,
+ -26, -26, -26, -26, -26, -26, 14, -26, -26, -26,
+ 15, -26, 17, -26, 18, 20, 24, 32, 38, 39,
+ 45, 46, 47, 48, 49, 50, 51, 52, 57, -26,
+ -26, -26, -26, -26, -26, -26, -26, -26, -26, -26,
+ -26, -26, -26, -26, -26, 27, -26, -26, -26, -26,
+ -26, -26, -26, -26, -26, -26, -26, -26, -26, -26,
+ -26, -26, 10, -26, -25, -26, -26, -26, -26, -26,
+ -26, -26, -26, 55, 56, 58, 59, 60, 61, 62,
+ 66, 63, 64, 68, 70, 69, 67, -26, -26, -26,
+ -26, -26, -26, -26
+};
+
+/* YYPGOTO[NTERM-NUM]. */
+static const yysigned_char yypgoto[] =
+{
+ -26, -26, -26, -26, -26, -26, -26, -26, -26, -26,
+ -26, -26, -26, -26, -26, -26, -26, -4, -26, -26,
+ -26, -26, -26, -26, -26, -26, -26, -26, -26, -26,
+ -26, -26, 40, 41, -26, -26, -26, -26, -26, -26,
+ -26, -26
+};
+
+/* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If
+ positive, shift that token. If negative, reduce the rule which
+ number is the opposite. If zero, do what YYDEFACT says.
+ If YYTABLE_NINF, syntax error. */
+#define YYTABLE_NINF -1
+static const unsigned char yytable[] =
+{
+ 12, 18, 1, 3, 14, 16, 10, 11, 3, 93,
+ 94, 95, 96, 97, 98, 99, 14, 25, 84, 26,
+ 29, 30, 33, 31, 68, 67, 19, 69, 64, 4,
+ 34, 35, 36, 37, 38, 70, 39, 40, 41, 42,
+ 43, 71, 72, 44, 45, 46, 47, 48, 73, 74,
+ 75, 76, 82, 20, 21, 0, 77, 78, 79, 80,
+ 81, 100, 101, 0, 102, 103, 104, 105, 106, 107,
+ 108, 109, 110, 111, 113, 112
+};
+
+static const yysigned_char yycheck[] =
+{
+ 4, 8, 24, 10, 11, 9, 0, 7, 10, 34,
+ 35, 36, 37, 38, 39, 40, 11, 6, 8, 12,
+ 7, 7, 7, 27, 4, 7, 33, 3, 32, 31,
+ 13, 14, 15, 16, 17, 3, 19, 20, 21, 22,
+ 23, 3, 3, 26, 27, 28, 29, 30, 3, 3,
+ 3, 3, 25, 13, 13, -1, 7, 7, 7, 7,
+ 3, 6, 6, -1, 6, 6, 6, 6, 6, 3,
+ 7, 7, 4, 3, 7, 6
+};
+
+/* YYSTOS[STATE-NUM] -- The (internal number of the) accessing
+ symbol of state STATE-NUM. */
+static const unsigned char yystos[] =
+{
+ 0, 24, 82, 10, 31, 58, 73, 76, 80, 81,
+ 0, 7, 58, 79, 11, 74, 58, 72, 8, 33,
+ 73, 74, 75, 77, 78, 6, 12, 42, 71, 7,
+ 7, 58, 70, 7, 13, 14, 15, 16, 17, 19,
+ 20, 21, 22, 23, 26, 27, 28, 29, 30, 43,
+ 44, 45, 46, 47, 48, 49, 50, 51, 52, 53,
+ 54, 55, 56, 57, 58, 68, 69, 7, 4, 3,
+ 3, 3, 3, 3, 3, 3, 3, 7, 7, 7,
+ 7, 3, 25, 67, 8, 59, 60, 61, 62, 63,
+ 64, 65, 66, 34, 35, 36, 37, 38, 39, 40,
+ 6, 6, 6, 6, 6, 6, 6, 3, 7, 7,
+ 4, 3, 6, 7
+};
+
+#if ! defined (YYSIZE_T) && defined (__SIZE_TYPE__)
+# define YYSIZE_T __SIZE_TYPE__
+#endif
+#if ! defined (YYSIZE_T) && defined (size_t)
+# define YYSIZE_T size_t
+#endif
+#if ! defined (YYSIZE_T)
+# if defined (__STDC__) || defined (__cplusplus)
+# include <stddef.h> /* INFRINGES ON USER NAME SPACE */
+# define YYSIZE_T size_t
+# endif
+#endif
+#if ! defined (YYSIZE_T)
+# define YYSIZE_T unsigned int
+#endif
+
+#define yyerrok (yyerrstatus = 0)
+#define yyclearin (yychar = YYEMPTY)
+#define YYEMPTY (-2)
+#define YYEOF 0
+
+#define YYACCEPT goto yyacceptlab
+#define YYABORT goto yyabortlab
+#define YYERROR goto yyerrorlab
+
+
+/* Like YYERROR except do call yyerror. This remains here temporarily
+ to ease the transition to the new meaning of YYERROR, for GCC.
+ Once GCC version 2 has supplanted version 1, this can go. */
+
+#define YYFAIL goto yyerrlab
+
+#define YYRECOVERING() (!!yyerrstatus)
+
+#define YYBACKUP(Token, Value) \
+do \
+ if (yychar == YYEMPTY && yylen == 1) \
+ { \
+ yychar = (Token); \
+ yylval = (Value); \
+ yytoken = YYTRANSLATE (yychar); \
+ YYPOPSTACK; \
+ goto yybackup; \
+ } \
+ else \
+ { \
+ yyerror ("syntax error: cannot back up");\
+ YYERROR; \
+ } \
+while (0)
+
+#define YYTERROR 1
+#define YYERRCODE 256
+
+/* YYLLOC_DEFAULT -- Compute the default location (before the actions
+ are run). */
+
+#ifndef YYLLOC_DEFAULT
+# define YYLLOC_DEFAULT(Current, Rhs, N) \
+ ((Current).first_line = (Rhs)[1].first_line, \
+ (Current).first_column = (Rhs)[1].first_column, \
+ (Current).last_line = (Rhs)[N].last_line, \
+ (Current).last_column = (Rhs)[N].last_column)
+#endif
+
+/* YYLEX -- calling `yylex' with the right arguments. */
+
+#ifdef YYLEX_PARAM
+# define YYLEX yylex (YYLEX_PARAM)
+#else
+# define YYLEX yylex ()
+#endif
+
+/* Enable debugging if requested. */
+#if YYDEBUG
+
+# ifndef YYFPRINTF
+# include <stdio.h> /* INFRINGES ON USER NAME SPACE */
+# define YYFPRINTF fprintf
+# endif
+
+# define YYDPRINTF(Args) \
+do { \
+ if (yydebug) \
+ YYFPRINTF Args; \
+} while (0)
+
+# define YYDSYMPRINT(Args) \
+do { \
+ if (yydebug) \
+ yysymprint Args; \
+} while (0)
+
+# define YYDSYMPRINTF(Title, Token, Value, Location) \
+do { \
+ if (yydebug) \
+ { \
+ YYFPRINTF (stderr, "%s ", Title); \
+ yysymprint (stderr, \
+ Token, Value); \
+ YYFPRINTF (stderr, "\n"); \
+ } \
+} while (0)
+
+/*------------------------------------------------------------------.
+| yy_stack_print -- Print the state stack from its BOTTOM up to its |
+| TOP (included). |
+`------------------------------------------------------------------*/
+
+#if defined (__STDC__) || defined (__cplusplus)
+static void
+yy_stack_print (short int *bottom, short int *top)
+#else
+static void
+yy_stack_print (bottom, top)
+ short int *bottom;
+ short int *top;
+#endif
+{
+ YYFPRINTF (stderr, "Stack now");
+ for (/* Nothing. */; bottom <= top; ++bottom)
+ YYFPRINTF (stderr, " %d", *bottom);
+ YYFPRINTF (stderr, "\n");
+}
+
+# define YY_STACK_PRINT(Bottom, Top) \
+do { \
+ if (yydebug) \
+ yy_stack_print ((Bottom), (Top)); \
+} while (0)
+
+
+/*------------------------------------------------.
+| Report that the YYRULE is going to be reduced. |
+`------------------------------------------------*/
+
+#if defined (__STDC__) || defined (__cplusplus)
+static void
+yy_reduce_print (int yyrule)
+#else
+static void
+yy_reduce_print (yyrule)
+ int yyrule;
+#endif
+{
+ int yyi;
+ unsigned int yylno = yyrline[yyrule];
+ YYFPRINTF (stderr, "Reducing stack by rule %d (line %u), ",
+ yyrule - 1, yylno);
+ /* Print the symbols being reduced, and their result. */
+ for (yyi = yyprhs[yyrule]; 0 <= yyrhs[yyi]; yyi++)
+ YYFPRINTF (stderr, "%s ", yytname [yyrhs[yyi]]);
+ YYFPRINTF (stderr, "-> %s\n", yytname [yyr1[yyrule]]);
+}
+
+# define YY_REDUCE_PRINT(Rule) \
+do { \
+ if (yydebug) \
+ yy_reduce_print (Rule); \
+} while (0)
+
+/* Nonzero means print parse trace. It is left uninitialized so that
+ multiple parsers can coexist. */
+int yydebug;
+#else /* !YYDEBUG */
+# define YYDPRINTF(Args)
+# define YYDSYMPRINT(Args)
+# define YYDSYMPRINTF(Title, Token, Value, Location)
+# define YY_STACK_PRINT(Bottom, Top)
+# define YY_REDUCE_PRINT(Rule)
+#endif /* !YYDEBUG */
+
+
+/* YYINITDEPTH -- initial size of the parser's stacks. */
+#ifndef YYINITDEPTH
+# define YYINITDEPTH 200
+#endif
+
+/* YYMAXDEPTH -- maximum size the stacks can grow to (effective only
+ if the built-in stack extension method is used).
+
+ Do not make this value too large; the results are undefined if
+ SIZE_MAX < YYSTACK_BYTES (YYMAXDEPTH)
+ evaluated with infinite-precision integer arithmetic. */
+
+#if defined (YYMAXDEPTH) && YYMAXDEPTH == 0
+# undef YYMAXDEPTH
+#endif
+
+#ifndef YYMAXDEPTH
+# define YYMAXDEPTH 10000
+#endif
+
+
+
+#if YYERROR_VERBOSE
+
+# ifndef yystrlen
+# if defined (__GLIBC__) && defined (_STRING_H)
+# define yystrlen strlen
+# else
+/* Return the length of YYSTR. */
+static YYSIZE_T
+# if defined (__STDC__) || defined (__cplusplus)
+yystrlen (const char *yystr)
+# else
+yystrlen (yystr)
+ const char *yystr;
+# endif
+{
+ register const char *yys = yystr;
+
+ while (*yys++ != '\0')
+ continue;
+
+ return yys - yystr - 1;
+}
+# endif
+# endif
+
+# ifndef yystpcpy
+# if defined (__GLIBC__) && defined (_STRING_H) && defined (_GNU_SOURCE)
+# define yystpcpy stpcpy
+# else
+/* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in
+ YYDEST. */
+static char *
+# if defined (__STDC__) || defined (__cplusplus)
+yystpcpy (char *yydest, const char *yysrc)
+# else
+yystpcpy (yydest, yysrc)
+ char *yydest;
+ const char *yysrc;
+# endif
+{
+ register char *yyd = yydest;
+ register const char *yys = yysrc;
+
+ while ((*yyd++ = *yys++) != '\0')
+ continue;
+
+ return yyd - 1;
+}
+# endif
+# endif
+
+#endif /* !YYERROR_VERBOSE */
+
+
+
+#if YYDEBUG
+/*--------------------------------.
+| Print this symbol on YYOUTPUT. |
+`--------------------------------*/
+
+#if defined (__STDC__) || defined (__cplusplus)
+static void
+yysymprint (FILE *yyoutput, int yytype, YYSTYPE *yyvaluep)
+#else
+static void
+yysymprint (yyoutput, yytype, yyvaluep)
+ FILE *yyoutput;
+ int yytype;
+ YYSTYPE *yyvaluep;
+#endif
+{
+ /* Pacify ``unused variable'' warnings. */
+ (void) yyvaluep;
+
+ if (yytype < YYNTOKENS)
+ {
+ YYFPRINTF (yyoutput, "token %s (", yytname[yytype]);
+# ifdef YYPRINT
+ YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep);
+# endif
+ }
+ else
+ YYFPRINTF (yyoutput, "nterm %s (", yytname[yytype]);
+
+ switch (yytype)
+ {
+ default:
+ break;
+ }
+ YYFPRINTF (yyoutput, ")");
+}
+
+#endif /* ! YYDEBUG */
+/*-----------------------------------------------.
+| Release the memory associated to this symbol. |
+`-----------------------------------------------*/
+
+#if defined (__STDC__) || defined (__cplusplus)
+static void
+yydestruct (int yytype, YYSTYPE *yyvaluep)
+#else
+static void
+yydestruct (yytype, yyvaluep)
+ int yytype;
+ YYSTYPE *yyvaluep;
+#endif
+{
+ /* Pacify ``unused variable'' warnings. */
+ (void) yyvaluep;
+
+ switch (yytype)
+ {
+
+ default:
+ break;
+ }
+}
+
+
+/* Prevent warnings from -Wmissing-prototypes. */
+
+#ifdef YYPARSE_PARAM
+# if defined (__STDC__) || defined (__cplusplus)
+int yyparse (void *YYPARSE_PARAM);
+# else
+int yyparse ();
+# endif
+#else /* ! YYPARSE_PARAM */
+#if defined (__STDC__) || defined (__cplusplus)
+int yyparse (void);
+#else
+int yyparse ();
+#endif
+#endif /* ! YYPARSE_PARAM */
+
+
+
+/* The lookahead symbol. */
+int yychar;
+
+/* The semantic value of the lookahead symbol. */
+YYSTYPE yylval;
+
+/* Number of syntax errors so far. */
+int yynerrs;
+
+
+
+/*----------.
+| yyparse. |
+`----------*/
+
+#ifdef YYPARSE_PARAM
+# if defined (__STDC__) || defined (__cplusplus)
+int yyparse (void *YYPARSE_PARAM)
+# else
+int yyparse (YYPARSE_PARAM)
+ void *YYPARSE_PARAM;
+# endif
+#else /* ! YYPARSE_PARAM */
+#if defined (__STDC__) || defined (__cplusplus)
+int
+yyparse (void)
+#else
+int
+yyparse ()
+
+#endif
+#endif
+{
+
+ register int yystate;
+ register int yyn;
+ int yyresult;
+ /* Number of tokens to shift before error messages enabled. */
+ int yyerrstatus;
+ /* Lookahead token as an internal (translated) token number. */
+ int yytoken = 0;
+
+ /* Three stacks and their tools:
+ `yyss': related to states,
+ `yyvs': related to semantic values,
+ `yyls': related to locations.
+
+ Refer to the stacks thru separate pointers, to allow yyoverflow
+ to reallocate them elsewhere. */
+
+ /* The state stack. */
+ short int yyssa[YYINITDEPTH];
+ short int *yyss = yyssa;
+ register short int *yyssp;
+
+ /* The semantic value stack. */
+ YYSTYPE yyvsa[YYINITDEPTH];
+ YYSTYPE *yyvs = yyvsa;
+ register YYSTYPE *yyvsp;
+
+
+
+#define YYPOPSTACK (yyvsp--, yyssp--)
+
+ YYSIZE_T yystacksize = YYINITDEPTH;
+
+ /* The variables used to return semantic value and location from the
+ action routines. */
+ YYSTYPE yyval;
+
+
+ /* When reducing, the number of symbols on the RHS of the reduced
+ rule. */
+ int yylen;
+
+ YYDPRINTF ((stderr, "Starting parse\n"));
+
+ yystate = 0;
+ yyerrstatus = 0;
+ yynerrs = 0;
+ yychar = YYEMPTY; /* Cause a token to be read. */
+
+ /* Initialize stack pointers.
+ Waste one element of value and location stack
+ so that they stay on the same level as the state stack.
+ The wasted elements are never initialized. */
+
+ yyssp = yyss;
+ yyvsp = yyvs;
+
+
+ goto yysetstate;
+
+/*------------------------------------------------------------.
+| yynewstate -- Push a new state, which is found in yystate. |
+`------------------------------------------------------------*/
+ yynewstate:
+ /* In all cases, when you get here, the value and location stacks
+ have just been pushed. so pushing a state here evens the stacks.
+ */
+ yyssp++;
+
+ yysetstate:
+ *yyssp = yystate;
+
+ if (yyss + yystacksize - 1 <= yyssp)
+ {
+ /* Get the current used size of the three stacks, in elements. */
+ YYSIZE_T yysize = yyssp - yyss + 1;
+
+#ifdef yyoverflow
+ {
+ /* Give user a chance to reallocate the stack. Use copies of
+ these so that the &'s don't force the real ones into
+ memory. */
+ YYSTYPE *yyvs1 = yyvs;
+ short int *yyss1 = yyss;
+
+
+ /* Each stack pointer address is followed by the size of the
+ data in use in that stack, in bytes. This used to be a
+ conditional around just the two extra args, but that might
+ be undefined if yyoverflow is a macro. */
+ yyoverflow ("parser stack overflow",
+ &yyss1, yysize * sizeof (*yyssp),
+ &yyvs1, yysize * sizeof (*yyvsp),
+
+ &yystacksize);
+
+ yyss = yyss1;
+ yyvs = yyvs1;
+ }
+#else /* no yyoverflow */
+# ifndef YYSTACK_RELOCATE
+ goto yyoverflowlab;
+# else
+ /* Extend the stack our own way. */
+ if (YYMAXDEPTH <= yystacksize)
+ goto yyoverflowlab;
+ yystacksize *= 2;
+ if (YYMAXDEPTH < yystacksize)
+ yystacksize = YYMAXDEPTH;
+
+ {
+ short int *yyss1 = yyss;
+ union yyalloc *yyptr =
+ (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize));
+ if (! yyptr)
+ goto yyoverflowlab;
+ YYSTACK_RELOCATE (yyss);
+ YYSTACK_RELOCATE (yyvs);
+
+# undef YYSTACK_RELOCATE
+ if (yyss1 != yyssa)
+ YYSTACK_FREE (yyss1);
+ }
+# endif
+#endif /* no yyoverflow */
+
+ yyssp = yyss + yysize - 1;
+ yyvsp = yyvs + yysize - 1;
+
+
+ YYDPRINTF ((stderr, "Stack size increased to %lu\n",
+ (unsigned long int) yystacksize));
+
+ if (yyss + yystacksize - 1 <= yyssp)
+ YYABORT;
+ }
+
+ YYDPRINTF ((stderr, "Entering state %d\n", yystate));
+
+ goto yybackup;
+
+/*-----------.
+| yybackup. |
+`-----------*/
+yybackup:
+
+/* Do appropriate processing given the current state. */
+/* Read a lookahead token if we need one and don't already have one. */
+/* yyresume: */
+
+ /* First try to decide what to do without reference to lookahead token. */
+
+ yyn = yypact[yystate];
+ if (yyn == YYPACT_NINF)
+ goto yydefault;
+
+ /* Not known => get a lookahead token if don't already have one. */
+
+ /* YYCHAR is either YYEMPTY or YYEOF or a valid lookahead symbol. */
+ if (yychar == YYEMPTY)
+ {
+ YYDPRINTF ((stderr, "Reading a token: "));
+ yychar = YYLEX;
+ }
+
+ if (yychar <= YYEOF)
+ {
+ yychar = yytoken = YYEOF;
+ YYDPRINTF ((stderr, "Now at end of input.\n"));
+ }
+ else
+ {
+ yytoken = YYTRANSLATE (yychar);
+ YYDSYMPRINTF ("Next token is", yytoken, &yylval, &yylloc);
+ }
+
+ /* If the proper action on seeing token YYTOKEN is to reduce or to
+ detect an error, take that action. */
+ yyn += yytoken;
+ if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken)
+ goto yydefault;
+ yyn = yytable[yyn];
+ if (yyn <= 0)
+ {
+ if (yyn == 0 || yyn == YYTABLE_NINF)
+ goto yyerrlab;
+ yyn = -yyn;
+ goto yyreduce;
+ }
+
+ if (yyn == YYFINAL)
+ YYACCEPT;
+
+ /* Shift the lookahead token. */
+ YYDPRINTF ((stderr, "Shifting token %s, ", yytname[yytoken]));
+
+ /* Discard the token being shifted unless it is eof. */
+ if (yychar != YYEOF)
+ yychar = YYEMPTY;
+
+ *++yyvsp = yylval;
+
+
+ /* Count tokens shifted since error; after three, turn off error
+ status. */
+ if (yyerrstatus)
+ yyerrstatus--;
+
+ yystate = yyn;
+ goto yynewstate;
+
+
+/*-----------------------------------------------------------.
+| yydefault -- do the default action for the current state. |
+`-----------------------------------------------------------*/
+yydefault:
+ yyn = yydefact[yystate];
+ if (yyn == 0)
+ goto yyerrlab;
+ goto yyreduce;
+
+
+/*-----------------------------.
+| yyreduce -- Do a reduction. |
+`-----------------------------*/
+yyreduce:
+ /* yyn is the number of a rule to reduce with. */
+ yylen = yyr2[yyn];
+
+ /* If YYLEN is nonzero, implement the default value of the action:
+ `$$ = $1'.
+
+ Otherwise, the following line sets YYVAL to garbage.
+ This behavior is undocumented and Bison
+ users should not rely upon it. Assigning to YYVAL
+ unconditionally makes the parser a bit smaller, and it avoids a
+ GCC warning that YYVAL may be used uninitialized. */
+ yyval = yyvsp[1-yylen];
+
+
+ YY_REDUCE_PRINT (yyn);
+ switch (yyn)
+ {
+ case 2:
+#line 101 "printrcy.y"
+ {
+ current_printer = stpui_plist_create(yyvsp[-1].sval, yyvsp[0].sval);
+ g_free(yyvsp[-1].sval);
+ g_free(yyvsp[0].sval);
+ }
+ break;
+
+ case 3:
+#line 112 "printrcy.y"
+ {
+ if (yyvsp[0].sval)
+ g_free(yyvsp[0].sval);
+ }
+ break;
+
+ case 4:
+#line 119 "printrcy.y"
+ {
+ if (yyvsp[0].sval)
+ {
+ stpui_plist_set_queue_name(current_printer, yyvsp[0].sval);
+ g_free(yyvsp[0].sval);
+ }
+ }
+ break;
+
+ case 5:
+#line 129 "printrcy.y"
+ {
+ if (yyvsp[0].sval)
+ {
+ stpui_plist_set_output_filename(current_printer, yyvsp[0].sval);
+ g_free(yyvsp[0].sval);
+ }
+ }
+ break;
+
+ case 6:
+#line 139 "printrcy.y"
+ {
+ if (yyvsp[0].sval)
+ {
+ stpui_plist_set_extra_printer_options(current_printer, yyvsp[0].sval);
+ g_free(yyvsp[0].sval);
+ }
+ }
+ break;
+
+ case 7:
+#line 149 "printrcy.y"
+ {
+ if (yyvsp[0].sval)
+ {
+ stpui_plist_set_custom_command(current_printer, yyvsp[0].sval);
+ g_free(yyvsp[0].sval);
+ }
+ }
+ break;
+
+ case 8:
+#line 159 "printrcy.y"
+ {
+ stpui_plist_set_command_type(current_printer, yyvsp[0].ival);
+ }
+ break;
+
+ case 9:
+#line 165 "printrcy.y"
+ { current_printer->scaling = yyvsp[0].dval; }
+ break;
+
+ case 10:
+#line 169 "printrcy.y"
+ { current_printer->orientation = yyvsp[0].ival; }
+ break;
+
+ case 11:
+#line 173 "printrcy.y"
+ { current_printer->auto_size_roll_feed_paper = yyvsp[0].ival; }
+ break;
+
+ case 12:
+#line 177 "printrcy.y"
+ { current_printer->unit = yyvsp[0].ival; }
+ break;
+
+ case 13:
+#line 181 "printrcy.y"
+ { stp_set_left(current_printer->v, yyvsp[0].ival); }
+ break;
+
+ case 14:
+#line 185 "printrcy.y"
+ { stp_set_top(current_printer->v, yyvsp[0].ival); }
+ break;
+
+ case 15:
+#line 189 "printrcy.y"
+ {
+ switch (yyvsp[0].ival)
+ {
+ case 0:
+ stp_set_string_parameter
+ (current_printer->v, "PrintingMode", "BW");
+ break;
+ case 1:
+ case 2:
+ default:
+ stp_set_string_parameter
+ (current_printer->v, "PrintingMode", "Color");
+ break;
+ }
+ }
+ break;
+
+ case 16:
+#line 207 "printrcy.y"
+ { stp_set_page_width(current_printer->v, yyvsp[0].ival); }
+ break;
+
+ case 17:
+#line 211 "printrcy.y"
+ { stp_set_page_height(current_printer->v, yyvsp[0].ival); }
+ break;
+
+ case 19:
+#line 218 "printrcy.y"
+ {
+ stp_set_int_parameter(current_printer->v, yyvsp[-3].sval, yyvsp[0].ival);
+ if (strcmp(yyvsp[-1].sval, "False") == 0)
+ stp_set_int_parameter_active(current_printer->v, yyvsp[-3].sval,
+ STP_PARAMETER_INACTIVE);
+ else
+ stp_set_int_parameter_active(current_printer->v, yyvsp[-3].sval,
+ STP_PARAMETER_ACTIVE);
+ g_free(yyvsp[-3].sval);
+ g_free(yyvsp[-1].sval);
+ }
+ break;
+
+ case 20:
+#line 232 "printrcy.y"
+ {
+ stp_set_string_parameter(current_printer->v, yyvsp[-3].sval, yyvsp[0].sval);
+ if (strcmp(yyvsp[-1].sval, "False") == 0)
+ stp_set_string_parameter_active(current_printer->v, yyvsp[-3].sval,
+ STP_PARAMETER_INACTIVE);
+ else
+ stp_set_string_parameter_active(current_printer->v, yyvsp[-3].sval,
+ STP_PARAMETER_ACTIVE);
+ g_free(yyvsp[-3].sval);
+ g_free(yyvsp[-1].sval);
+ g_free(yyvsp[0].sval);
+ }
+ break;
+
+ case 21:
+#line 247 "printrcy.y"
+ {
+ stp_set_file_parameter(current_printer->v, yyvsp[-3].sval, yyvsp[0].sval);
+ if (strcmp(yyvsp[-1].sval, "False") == 0)
+ stp_set_file_parameter_active(current_printer->v, yyvsp[-3].sval,
+ STP_PARAMETER_INACTIVE);
+ else
+ stp_set_file_parameter_active(current_printer->v, yyvsp[-3].sval,
+ STP_PARAMETER_ACTIVE);
+ g_free(yyvsp[-3].sval);
+ g_free(yyvsp[-1].sval);
+ g_free(yyvsp[0].sval);
+ }
+ break;
+
+ case 22:
+#line 262 "printrcy.y"
+ {
+ stp_set_float_parameter(current_printer->v, yyvsp[-3].sval, yyvsp[0].dval);
+ if (strcmp(yyvsp[-1].sval, "False") == 0)
+ stp_set_float_parameter_active(current_printer->v, yyvsp[-3].sval,
+ STP_PARAMETER_INACTIVE);
+ else
+ stp_set_float_parameter_active(current_printer->v, yyvsp[-3].sval,
+ STP_PARAMETER_ACTIVE);
+ g_free(yyvsp[-3].sval);
+ g_free(yyvsp[-1].sval);
+ }
+ break;
+
+ case 23:
+#line 276 "printrcy.y"
+ {
+ stp_set_dimension_parameter(current_printer->v, yyvsp[-3].sval, yyvsp[0].ival);
+ if (strcmp(yyvsp[-1].sval, "False") == 0)
+ stp_set_dimension_parameter_active(current_printer->v, yyvsp[-3].sval,
+ STP_PARAMETER_INACTIVE);
+ else
+ stp_set_dimension_parameter_active(current_printer->v, yyvsp[-3].sval,
+ STP_PARAMETER_ACTIVE);
+ g_free(yyvsp[-3].sval);
+ g_free(yyvsp[-1].sval);
+ }
+ break;
+
+ case 24:
+#line 290 "printrcy.y"
+ {
+ if (strcmp(yyvsp[0].sval, "False") == 0)
+ stp_set_boolean_parameter(current_printer->v, yyvsp[-3].sval, 0);
+ else
+ stp_set_boolean_parameter(current_printer->v, yyvsp[-3].sval, 1);
+ if (strcmp(yyvsp[-1].sval, "False") == 0)
+ stp_set_boolean_parameter_active(current_printer->v, yyvsp[-3].sval,
+ STP_PARAMETER_INACTIVE);
+ else
+ stp_set_boolean_parameter_active(current_printer->v, yyvsp[-3].sval,
+ STP_PARAMETER_ACTIVE);
+ g_free(yyvsp[-3].sval);
+ g_free(yyvsp[-1].sval);
+ g_free(yyvsp[0].sval);
+ }
+ break;
+
+ case 25:
+#line 308 "printrcy.y"
+ {
+ stp_curve_t *curve = stp_curve_create_from_string(yyvsp[0].sval);
+ if (curve)
+ {
+ stp_set_curve_parameter(current_printer->v, yyvsp[-3].sval, curve);
+ if (strcmp(yyvsp[-1].sval, "False") == 0)
+ stp_set_curve_parameter_active(current_printer->v, yyvsp[-3].sval,
+ STP_PARAMETER_INACTIVE);
+ else
+ stp_set_curve_parameter_active(current_printer->v, yyvsp[-3].sval,
+ STP_PARAMETER_ACTIVE);
+ stp_curve_destroy(curve);
+ }
+ g_free(yyvsp[-3].sval);
+ g_free(yyvsp[-1].sval);
+ g_free(yyvsp[0].sval);
+ }
+ break;
+
+ case 56:
+#line 353 "printrcy.y"
+ { stpui_printrc_current_printer = yyvsp[0].sval; }
+ break;
+
+ case 57:
+#line 357 "printrcy.y"
+ {
+ if (strcmp(yyvsp[0].sval, "True") == 0)
+ stpui_show_all_paper_sizes = 1;
+ else
+ stpui_show_all_paper_sizes = 0;
+ g_free(yyvsp[0].sval);
+ }
+ break;
+
+ case 61:
+#line 373 "printrcy.y"
+ {
+ if (yyvsp[0].sval)
+ {
+ stpui_set_global_parameter(yyvsp[-1].sval, yyvsp[0].sval);
+ g_free(yyvsp[0].sval);
+ }
+ g_free(yyvsp[-1].sval);
+ }
+ break;
+
+
+ }
+
+/* Line 1010 of yacc.c. */
+#line 1468 "printrcy.c"
+
+ yyvsp -= yylen;
+ yyssp -= yylen;
+
+
+ YY_STACK_PRINT (yyss, yyssp);
+
+ *++yyvsp = yyval;
+
+
+ /* Now `shift' the result of the reduction. Determine what state
+ that goes to, based on the state we popped back to and the rule
+ number reduced by. */
+
+ yyn = yyr1[yyn];
+
+ yystate = yypgoto[yyn - YYNTOKENS] + *yyssp;
+ if (0 <= yystate && yystate <= YYLAST && yycheck[yystate] == *yyssp)
+ yystate = yytable[yystate];
+ else
+ yystate = yydefgoto[yyn - YYNTOKENS];
+
+ goto yynewstate;
+
+
+/*------------------------------------.
+| yyerrlab -- here on detecting error |
+`------------------------------------*/
+yyerrlab:
+ /* If not already recovering from an error, report this error. */
+ if (!yyerrstatus)
+ {
+ ++yynerrs;
+#if YYERROR_VERBOSE
+ yyn = yypact[yystate];
+
+ if (YYPACT_NINF < yyn && yyn < YYLAST)
+ {
+ YYSIZE_T yysize = 0;
+ int yytype = YYTRANSLATE (yychar);
+ const char* yyprefix;
+ char *yymsg;
+ int yyx;
+
+ /* Start YYX at -YYN if negative to avoid negative indexes in
+ YYCHECK. */
+ int yyxbegin = yyn < 0 ? -yyn : 0;
+
+ /* Stay within bounds of both yycheck and yytname. */
+ int yychecklim = YYLAST - yyn;
+ int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS;
+ int yycount = 0;
+
+ yyprefix = ", expecting ";
+ for (yyx = yyxbegin; yyx < yyxend; ++yyx)
+ if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR)
+ {
+ yysize += yystrlen (yyprefix) + yystrlen (yytname [yyx]);
+ yycount += 1;
+ if (yycount == 5)
+ {
+ yysize = 0;
+ break;
+ }
+ }
+ yysize += (sizeof ("syntax error, unexpected ")
+ + yystrlen (yytname[yytype]));
+ yymsg = (char *) YYSTACK_ALLOC (yysize);
+ if (yymsg != 0)
+ {
+ char *yyp = yystpcpy (yymsg, "syntax error, unexpected ");
+ yyp = yystpcpy (yyp, yytname[yytype]);
+
+ if (yycount < 5)
+ {
+ yyprefix = ", expecting ";
+ for (yyx = yyxbegin; yyx < yyxend; ++yyx)
+ if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR)
+ {
+ yyp = yystpcpy (yyp, yyprefix);
+ yyp = yystpcpy (yyp, yytname[yyx]);
+ yyprefix = " or ";
+ }
+ }
+ yyerror (yymsg);
+ YYSTACK_FREE (yymsg);
+ }
+ else
+ yyerror ("syntax error; also virtual memory exhausted");
+ }
+ else
+#endif /* YYERROR_VERBOSE */
+ yyerror ("syntax error");
+ }
+
+
+
+ if (yyerrstatus == 3)
+ {
+ /* If just tried and failed to reuse lookahead token after an
+ error, discard it. */
+
+ if (yychar <= YYEOF)
+ {
+ /* If at end of input, pop the error token,
+ then the rest of the stack, then return failure. */
+ if (yychar == YYEOF)
+ for (;;)
+ {
+ YYPOPSTACK;
+ if (yyssp == yyss)
+ YYABORT;
+ YYDSYMPRINTF ("Error: popping", yystos[*yyssp], yyvsp, yylsp);
+ yydestruct (yystos[*yyssp], yyvsp);
+ }
+ }
+ else
+ {
+ YYDSYMPRINTF ("Error: discarding", yytoken, &yylval, &yylloc);
+ yydestruct (yytoken, &yylval);
+ yychar = YYEMPTY;
+
+ }
+ }
+
+ /* Else will try to reuse lookahead token after shifting the error
+ token. */
+ goto yyerrlab1;
+
+
+/*---------------------------------------------------.
+| yyerrorlab -- error raised explicitly by YYERROR. |
+`---------------------------------------------------*/
+yyerrorlab:
+
+#ifdef __GNUC__
+ /* Pacify GCC when the user code never invokes YYERROR and the label
+ yyerrorlab therefore never appears in user code. */
+ if (0)
+ goto yyerrorlab;
+#endif
+
+ yyvsp -= yylen;
+ yyssp -= yylen;
+ yystate = *yyssp;
+ goto yyerrlab1;
+
+
+/*-------------------------------------------------------------.
+| yyerrlab1 -- common code for both syntax error and YYERROR. |
+`-------------------------------------------------------------*/
+yyerrlab1:
+ yyerrstatus = 3; /* Each real token shifted decrements this. */
+
+ for (;;)
+ {
+ yyn = yypact[yystate];
+ if (yyn != YYPACT_NINF)
+ {
+ yyn += YYTERROR;
+ if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR)
+ {
+ yyn = yytable[yyn];
+ if (0 < yyn)
+ break;
+ }
+ }
+
+ /* Pop the current state because it cannot handle the error token. */
+ if (yyssp == yyss)
+ YYABORT;
+
+ YYDSYMPRINTF ("Error: popping", yystos[*yyssp], yyvsp, yylsp);
+ yydestruct (yystos[yystate], yyvsp);
+ YYPOPSTACK;
+ yystate = *yyssp;
+ YY_STACK_PRINT (yyss, yyssp);
+ }
+
+ if (yyn == YYFINAL)
+ YYACCEPT;
+
+ YYDPRINTF ((stderr, "Shifting error token, "));
+
+ *++yyvsp = yylval;
+
+
+ yystate = yyn;
+ goto yynewstate;
+
+
+/*-------------------------------------.
+| yyacceptlab -- YYACCEPT comes here. |
+`-------------------------------------*/
+yyacceptlab:
+ yyresult = 0;
+ goto yyreturn;
+
+/*-----------------------------------.
+| yyabortlab -- YYABORT comes here. |
+`-----------------------------------*/
+yyabortlab:
+ yyresult = 1;
+ goto yyreturn;
+
+#ifndef yyoverflow
+/*----------------------------------------------.
+| yyoverflowlab -- parser overflow comes here. |
+`----------------------------------------------*/
+yyoverflowlab:
+ yyerror ("parser stack overflow");
+ yyresult = 2;
+ /* Fall through. */
+#endif
+
+yyreturn:
+#ifndef yyoverflow
+ if (yyss != yyssa)
+ YYSTACK_FREE (yyss);
+#endif
+ return yyresult;
+}
+
+
+#line 398 "printrcy.y"
+
+
diff --git a/src/gutenprintui2/printrcy.h b/src/gutenprintui2/printrcy.h
new file mode 100644
index 0000000..2273fb7
--- /dev/null
+++ b/src/gutenprintui2/printrcy.h
@@ -0,0 +1,124 @@
+/* A Bison parser, made by GNU Bison 1.875d. */
+
+/* Skeleton parser for Yacc-like parsing with Bison,
+ Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
+
+ 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 2, 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, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
+
+/* As a special exception, when this file is copied by Bison into a
+ Bison output file, you may use that output file without restriction.
+ This special exception was added by the Free Software Foundation
+ in version 1.24 of Bison. */
+
+/* Tokens. */
+#ifndef YYTOKENTYPE
+# define YYTOKENTYPE
+ /* Put the tokens into the symbol table, so that GDB and other debuggers
+ know about them. */
+ enum yytokentype {
+ tINT = 258,
+ tDOUBLE = 259,
+ tDIMENSION = 260,
+ tBOOLEAN = 261,
+ tSTRING = 262,
+ tWORD = 263,
+ tGSWORD = 264,
+ CURRENT_PRINTER = 265,
+ SHOW_ALL_PAPER_SIZES = 266,
+ PRINTER = 267,
+ DESTINATION = 268,
+ SCALING = 269,
+ ORIENTATION = 270,
+ AUTOSIZE_ROLL_PAPER = 271,
+ UNIT = 272,
+ DRIVER = 273,
+ LEFT = 274,
+ TOP = 275,
+ CUSTOM_PAGE_WIDTH = 276,
+ CUSTOM_PAGE_HEIGHT = 277,
+ OUTPUT_TYPE = 278,
+ PRINTRC_HDR = 279,
+ PARAMETER = 280,
+ QUEUE_NAME = 281,
+ OUTPUT_FILENAME = 282,
+ EXTRA_PRINTER_OPTIONS = 283,
+ CUSTOM_COMMAND = 284,
+ COMMAND_TYPE = 285,
+ GLOBAL_SETTINGS = 286,
+ GLOBAL = 287,
+ END_GLOBAL_SETTINGS = 288,
+ pINT = 289,
+ pSTRING_LIST = 290,
+ pFILE = 291,
+ pDOUBLE = 292,
+ pDIMENSION = 293,
+ pBOOLEAN = 294,
+ pCURVE = 295
+ };
+#endif
+#define tINT 258
+#define tDOUBLE 259
+#define tDIMENSION 260
+#define tBOOLEAN 261
+#define tSTRING 262
+#define tWORD 263
+#define tGSWORD 264
+#define CURRENT_PRINTER 265
+#define SHOW_ALL_PAPER_SIZES 266
+#define PRINTER 267
+#define DESTINATION 268
+#define SCALING 269
+#define ORIENTATION 270
+#define AUTOSIZE_ROLL_PAPER 271
+#define UNIT 272
+#define DRIVER 273
+#define LEFT 274
+#define TOP 275
+#define CUSTOM_PAGE_WIDTH 276
+#define CUSTOM_PAGE_HEIGHT 277
+#define OUTPUT_TYPE 278
+#define PRINTRC_HDR 279
+#define PARAMETER 280
+#define QUEUE_NAME 281
+#define OUTPUT_FILENAME 282
+#define EXTRA_PRINTER_OPTIONS 283
+#define CUSTOM_COMMAND 284
+#define COMMAND_TYPE 285
+#define GLOBAL_SETTINGS 286
+#define GLOBAL 287
+#define END_GLOBAL_SETTINGS 288
+#define pINT 289
+#define pSTRING_LIST 290
+#define pFILE 291
+#define pDOUBLE 292
+#define pDIMENSION 293
+#define pBOOLEAN 294
+#define pCURVE 295
+
+
+
+
+#if ! defined (YYSTYPE) && ! defined (YYSTYPE_IS_DECLARED)
+typedef int YYSTYPE;
+# define yystype YYSTYPE /* obsolescent; will be withdrawn */
+# define YYSTYPE_IS_DECLARED 1
+# define YYSTYPE_IS_TRIVIAL 1
+#endif
+
+extern YYSTYPE yylval;
+
+
+
diff --git a/src/gutenprintui2/printrcy.y b/src/gutenprintui2/printrcy.y
new file mode 100644
index 0000000..58bd36e
--- /dev/null
+++ b/src/gutenprintui2/printrcy.y
@@ -0,0 +1,398 @@
+/*
+ * "$Id: printrcy.y,v 1.1 2004/09/17 18:38:14 rleigh Exp $"
+ *
+ * Test pattern generator for Gutenprint
+ *
+ * Copyright 2001 Robert Krawitz <rlk@alum.mit.edu>
+ *
+ * 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 2 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+%{
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <gutenprint/gutenprint-intl-internal.h>
+#include <gutenprintui2/gutenprintui.h>
+#include "gutenprintui-internal.h"
+#include "printrc.h"
+
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+extern int mylineno;
+
+extern int yylex(void);
+char *quotestrip(const char *i);
+char *endstrip(const char *i);
+
+extern char* yytext;
+
+static int yyerror( const char *s )
+{
+ fprintf(stderr,"stdin:%d: %s before '%s'\n", mylineno, s, yytext);
+ return 0;
+}
+
+static stpui_plist_t *current_printer = NULL;
+
+%}
+
+%token <ival> tINT
+%token <dval> tDOUBLE
+%token <ival> tDIMENSION
+%token <sval> tBOOLEAN
+%token <sval> tSTRING
+%token <sval> tWORD
+%token <sval> tGSWORD
+
+%token CURRENT_PRINTER
+%token SHOW_ALL_PAPER_SIZES
+%token PRINTER
+%token DESTINATION
+%token SCALING
+%token ORIENTATION
+%token AUTOSIZE_ROLL_PAPER
+%token UNIT
+%token DRIVER
+%token LEFT
+%token TOP
+%token CUSTOM_PAGE_WIDTH
+%token CUSTOM_PAGE_HEIGHT
+%token OUTPUT_TYPE
+%token PRINTRC_HDR
+%token PARAMETER
+%token QUEUE_NAME
+%token OUTPUT_FILENAME
+%token EXTRA_PRINTER_OPTIONS
+%token CUSTOM_COMMAND
+%token COMMAND_TYPE
+%token GLOBAL_SETTINGS
+%token GLOBAL
+%token END_GLOBAL_SETTINGS
+%token pINT
+%token pSTRING_LIST
+%token pFILE
+%token pDOUBLE
+%token pDIMENSION
+%token pBOOLEAN
+%token pCURVE
+
+%start Thing
+
+%%
+
+Printer: PRINTER tSTRING tSTRING
+ {
+ current_printer = stpui_plist_create($2, $3);
+ g_free($2);
+ g_free($3);
+ }
+;
+
+/*
+ * Destination is obsolete; ignore it.
+ */
+Destination: DESTINATION tSTRING
+ {
+ if ($2)
+ g_free($2);
+ }
+;
+
+Queue_Name: QUEUE_NAME tSTRING
+ {
+ if ($2)
+ {
+ stpui_plist_set_queue_name(current_printer, $2);
+ g_free($2);
+ }
+ }
+;
+
+Output_Filename: OUTPUT_FILENAME tSTRING
+ {
+ if ($2)
+ {
+ stpui_plist_set_output_filename(current_printer, $2);
+ g_free($2);
+ }
+ }
+;
+
+Extra_Printer_Options: EXTRA_PRINTER_OPTIONS tSTRING
+ {
+ if ($2)
+ {
+ stpui_plist_set_extra_printer_options(current_printer, $2);
+ g_free($2);
+ }
+ }
+;
+
+Custom_Command: CUSTOM_COMMAND tSTRING
+ {
+ if ($2)
+ {
+ stpui_plist_set_custom_command(current_printer, $2);
+ g_free($2);
+ }
+ }
+;
+
+Command_Type: COMMAND_TYPE tINT
+ {
+ stpui_plist_set_command_type(current_printer, $2);
+ }
+;
+
+Scaling: SCALING tDOUBLE
+ { current_printer->scaling = $2; }
+;
+
+Orientation: ORIENTATION tINT
+ { current_printer->orientation = $2; }
+;
+
+Autosize_Roll_Paper: AUTOSIZE_ROLL_PAPER tINT
+ { current_printer->auto_size_roll_feed_paper = $2; }
+;
+
+Unit: UNIT tINT
+ { current_printer->unit = $2; }
+;
+
+Left: LEFT tINT
+ { stp_set_left(current_printer->v, $2); }
+;
+
+Top: TOP tINT
+ { stp_set_top(current_printer->v, $2); }
+;
+
+Output_Type: OUTPUT_TYPE tINT
+ {
+ switch ($2)
+ {
+ case 0:
+ stp_set_string_parameter
+ (current_printer->v, "PrintingMode", "BW");
+ break;
+ case 1:
+ case 2:
+ default:
+ stp_set_string_parameter
+ (current_printer->v, "PrintingMode", "Color");
+ break;
+ }
+ }
+;
+
+Custom_Page_Width: CUSTOM_PAGE_WIDTH tINT
+ { stp_set_page_width(current_printer->v, $2); }
+;
+
+Custom_Page_Height: CUSTOM_PAGE_HEIGHT tINT
+ { stp_set_page_height(current_printer->v, $2); }
+;
+
+Empty:
+;
+
+Int_Param: tWORD pINT tBOOLEAN tINT
+ {
+ stp_set_int_parameter(current_printer->v, $1, $4);
+ if (strcmp($3, "False") == 0)
+ stp_set_int_parameter_active(current_printer->v, $1,
+ STP_PARAMETER_INACTIVE);
+ else
+ stp_set_int_parameter_active(current_printer->v, $1,
+ STP_PARAMETER_ACTIVE);
+ g_free($1);
+ g_free($3);
+ }
+;
+
+String_List_Param: tWORD pSTRING_LIST tBOOLEAN tSTRING
+ {
+ stp_set_string_parameter(current_printer->v, $1, $4);
+ if (strcmp($3, "False") == 0)
+ stp_set_string_parameter_active(current_printer->v, $1,
+ STP_PARAMETER_INACTIVE);
+ else
+ stp_set_string_parameter_active(current_printer->v, $1,
+ STP_PARAMETER_ACTIVE);
+ g_free($1);
+ g_free($3);
+ g_free($4);
+ }
+;
+
+File_Param: tWORD pFILE tBOOLEAN tSTRING
+ {
+ stp_set_file_parameter(current_printer->v, $1, $4);
+ if (strcmp($3, "False") == 0)
+ stp_set_file_parameter_active(current_printer->v, $1,
+ STP_PARAMETER_INACTIVE);
+ else
+ stp_set_file_parameter_active(current_printer->v, $1,
+ STP_PARAMETER_ACTIVE);
+ g_free($1);
+ g_free($3);
+ g_free($4);
+ }
+;
+
+Double_Param: tWORD pDOUBLE tBOOLEAN tDOUBLE
+ {
+ stp_set_float_parameter(current_printer->v, $1, $4);
+ if (strcmp($3, "False") == 0)
+ stp_set_float_parameter_active(current_printer->v, $1,
+ STP_PARAMETER_INACTIVE);
+ else
+ stp_set_float_parameter_active(current_printer->v, $1,
+ STP_PARAMETER_ACTIVE);
+ g_free($1);
+ g_free($3);
+ }
+;
+
+Dimension_Param: tWORD pDIMENSION tBOOLEAN tINT
+ {
+ stp_set_dimension_parameter(current_printer->v, $1, $4);
+ if (strcmp($3, "False") == 0)
+ stp_set_dimension_parameter_active(current_printer->v, $1,
+ STP_PARAMETER_INACTIVE);
+ else
+ stp_set_dimension_parameter_active(current_printer->v, $1,
+ STP_PARAMETER_ACTIVE);
+ g_free($1);
+ g_free($3);
+ }
+;
+
+Boolean_Param: tWORD pBOOLEAN tBOOLEAN tBOOLEAN
+ {
+ if (strcmp($4, "False") == 0)
+ stp_set_boolean_parameter(current_printer->v, $1, 0);
+ else
+ stp_set_boolean_parameter(current_printer->v, $1, 1);
+ if (strcmp($3, "False") == 0)
+ stp_set_boolean_parameter_active(current_printer->v, $1,
+ STP_PARAMETER_INACTIVE);
+ else
+ stp_set_boolean_parameter_active(current_printer->v, $1,
+ STP_PARAMETER_ACTIVE);
+ g_free($1);
+ g_free($3);
+ g_free($4);
+ }
+;
+
+Curve_Param: tWORD pCURVE tBOOLEAN tSTRING
+ {
+ stp_curve_t *curve = stp_curve_create_from_string($4);
+ if (curve)
+ {
+ stp_set_curve_parameter(current_printer->v, $1, curve);
+ if (strcmp($3, "False") == 0)
+ stp_set_curve_parameter_active(current_printer->v, $1,
+ STP_PARAMETER_INACTIVE);
+ else
+ stp_set_curve_parameter_active(current_printer->v, $1,
+ STP_PARAMETER_ACTIVE);
+ stp_curve_destroy(curve);
+ }
+ g_free($1);
+ g_free($3);
+ g_free($4);
+ }
+;
+
+Typed_Param: Int_Param | String_List_Param | File_Param | Double_Param
+ | Boolean_Param | Curve_Param | Dimension_Param
+;
+
+Parameter: PARAMETER Typed_Param
+;
+
+Parameters: Parameters Parameter | Empty
+;
+
+Standard_Value: Destination | Scaling | Orientation | Autosize_Roll_Paper |
+ Unit | Left | Top | Custom_Page_Width | Custom_Page_Height |
+ Output_Type | Queue_Name | Output_Filename | Extra_Printer_Options |
+ Custom_Command | Command_Type
+;
+
+Standard_Values: Standard_Values Standard_Value | Empty
+;
+
+A_Printer: Printer Standard_Values Parameters
+;
+
+Printers: Printers A_Printer | Empty
+;
+
+Current_Printer: CURRENT_PRINTER tSTRING
+ { stpui_printrc_current_printer = $2; }
+;
+
+Show_All_Paper_Sizes: SHOW_ALL_PAPER_SIZES tBOOLEAN
+ {
+ if (strcmp($2, "True") == 0)
+ stpui_show_all_paper_sizes = 1;
+ else
+ stpui_show_all_paper_sizes = 0;
+ g_free($2);
+ }
+;
+
+Global: Current_Printer | Show_All_Paper_Sizes
+;
+
+Old_Globals: Current_Printer Show_All_Paper_Sizes
+;
+
+New_Global_Setting: tWORD tSTRING
+ {
+ if ($2)
+ {
+ stpui_set_global_parameter($1, $2);
+ g_free($2);
+ }
+ g_free($1);
+ }
+;
+
+Global_Setting: Global | New_Global_Setting
+;
+
+Global_Settings: Global_Settings Global_Setting | Empty
+;
+
+Global_Subblock: GLOBAL_SETTINGS Global_Settings END_GLOBAL_SETTINGS
+;
+
+Global_Block: Global_Subblock | Old_Globals | Empty
+;
+
+Thing: PRINTRC_HDR Global_Block Printers
+;
+
+%%
diff --git a/src/gutenprintui2/typebuiltins.c b/src/gutenprintui2/typebuiltins.c
new file mode 100644
index 0000000..a44e5f7
--- /dev/null
+++ b/src/gutenprintui2/typebuiltins.c
@@ -0,0 +1,58 @@
+
+/* Generated data (by glib-mkenums) */
+
+#include <gutenprintui2/gutenprintui.h>
+
+/* enumerations from "../../include/gutenprintui2/gutenprintui.h" */
+GType
+orient_t_orient_t_get_type (void)
+{
+ static GType etype = 0;
+ if (etype == 0) {
+ static const GEnumValue values[] = {
+ { ORIENT_AUTO, "ORIENT_AUTO", "auto" },
+ { ORIENT_PORTRAIT, "ORIENT_PORTRAIT", "portrait" },
+ { ORIENT_LANDSCAPE, "ORIENT_LANDSCAPE", "landscape" },
+ { ORIENT_UPSIDEDOWN, "ORIENT_UPSIDEDOWN", "upsidedown" },
+ { ORIENT_SEASCAPE, "ORIENT_SEASCAPE", "seascape" },
+ { 0, NULL, NULL }
+ };
+ etype = g_enum_register_static ("orient_t", values);
+ }
+ return etype;
+}
+GType
+command_t_command_t_get_type (void)
+{
+ static GType etype = 0;
+ if (etype == 0) {
+ static const GEnumValue values[] = {
+ { COMMAND_TYPE_DEFAULT, "COMMAND_TYPE_DEFAULT", "default" },
+ { COMMAND_TYPE_CUSTOM, "COMMAND_TYPE_CUSTOM", "custom" },
+ { COMMAND_TYPE_FILE, "COMMAND_TYPE_FILE", "file" },
+ { 0, NULL, NULL }
+ };
+ etype = g_enum_register_static ("command_t", values);
+ }
+ return etype;
+}
+
+/* enumerations from "../../include/gutenprintui2/curve.h" */
+GType
+stpui_curve_type_get_type (void)
+{
+ static GType etype = 0;
+ if (etype == 0) {
+ static const GEnumValue values[] = {
+ { STPUI_CURVE_TYPE_LINEAR, "STPUI_CURVE_TYPE_LINEAR", "linear" },
+ { STPUI_CURVE_TYPE_SPLINE, "STPUI_CURVE_TYPE_SPLINE", "spline" },
+ { STPUI_CURVE_TYPE_FREE, "STPUI_CURVE_TYPE_FREE", "free" },
+ { 0, NULL, NULL }
+ };
+ etype = g_enum_register_static ("StpuiCurveType", values);
+ }
+ return etype;
+}
+
+/* Generated data ends here */
+
diff --git a/src/gutenprintui2/ui-utils.c b/src/gutenprintui2/ui-utils.c
new file mode 100644
index 0000000..b4ec44d
--- /dev/null
+++ b/src/gutenprintui2/ui-utils.c
@@ -0,0 +1,874 @@
+/*
+ * "$Id: ui-utils.c,v 1.2 2005/04/09 14:52:34 rlk Exp $"
+ *
+ * Main window code for Print plug-in for the GIMP.
+ *
+ * Copyright 1997-2000 Michael Sweet (mike@easysw.com),
+ * Robert Krawitz (rlk@alum.mit.edu), Steve Miller (smiller@rni.net)
+ * and Michael Natterer (mitch@gimp.org)
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <gutenprint/gutenprint-intl-internal.h>
+#include <gutenprintui2/gutenprintui.h>
+#include "gutenprintui-internal.h"
+
+#include <stdio.h>
+#include <string.h>
+
+static void default_errfunc(void *data, const char *buffer, size_t bytes);
+static gchar *image_filename;
+static stp_outfunc_t the_errfunc = default_errfunc;
+static void *the_errdata = NULL;
+static get_thumbnail_func_t thumbnail_func;
+static void *thumbnail_private_data;
+
+/*****************************************************************\
+* *
+* The following from libgimp/gimpdialog.c *
+* *
+\*****************************************************************/
+
+typedef void (*StpuiBasicCallback) (GObject *object,
+ gpointer user_data);
+
+/* local callbacks of dialog_new () */
+static gint
+dialog_delete_callback (GtkWidget *widget,
+ GdkEvent *event,
+ gpointer data)
+{
+ StpuiBasicCallback cancel_callback;
+ GtkWidget *cancel_widget;
+
+ cancel_callback =
+ (StpuiBasicCallback) g_object_get_data (G_OBJECT (widget),
+ "dialog_cancel_callback");
+ cancel_widget =
+ (GtkWidget*) g_object_get_data (G_OBJECT (widget),
+ "dialog_cancel_widget");
+
+ /* the cancel callback has to destroy the dialog */
+ if (cancel_callback)
+ (* cancel_callback) (G_OBJECT(cancel_widget), data);
+
+ return TRUE;
+}
+
+/**
+ * dialog_create_action_areav:
+ * @dialog: The #GtkDialog you want to create the action_area for.
+ * @args: A @va_list as obtained with va_start() describing the action_area
+ * buttons.
+ *
+ */
+static void
+dialog_create_action_areav (GtkDialog *dialog,
+ va_list args)
+{
+ GtkWidget *hbbox = NULL;
+ GtkWidget *button;
+
+ /* action area variables */
+ const gchar *label;
+ GtkSignalFunc callback;
+ gpointer data;
+ GObject *slot_object;
+ GtkWidget **widget_ptr;
+ gboolean default_action;
+ gboolean connect_delete;
+
+ gboolean delete_connected = FALSE;
+
+ g_return_if_fail (dialog != NULL);
+ g_return_if_fail (GTK_IS_DIALOG (dialog));
+
+ /* prepare the action_area */
+ label = va_arg (args, const gchar *);
+
+ if (label)
+ {
+ gtk_container_set_border_width (GTK_CONTAINER (dialog->action_area), 2);
+ gtk_box_set_homogeneous (GTK_BOX (dialog->action_area), FALSE);
+
+ hbbox = gtk_hbutton_box_new ();
+ gtk_button_box_set_spacing (GTK_BUTTON_BOX (hbbox), 4);
+ gtk_box_pack_end (GTK_BOX (dialog->action_area), hbbox, FALSE, FALSE, 0);
+ gtk_widget_show (hbbox);
+ }
+
+ /* the action_area buttons */
+ while (label)
+ {
+ callback = va_arg (args, GtkSignalFunc);
+ data = va_arg (args, gpointer);
+ slot_object = va_arg (args, GObject *);
+ widget_ptr = va_arg (args, GtkWidget **);
+ default_action = va_arg (args, gboolean);
+ connect_delete = va_arg (args, gboolean);
+
+ button = gtk_button_new_with_label (label);
+ GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
+ gtk_box_pack_start (GTK_BOX (hbbox), button, FALSE, FALSE, 0);
+
+ if (slot_object == (GObject *) 1)
+ slot_object = G_OBJECT (dialog);
+
+ if (data == NULL)
+ data = dialog;
+
+ if (callback)
+ {
+ if (slot_object)
+ g_signal_connect_object (G_OBJECT (button), "clicked",
+ G_CALLBACK (callback),
+ slot_object, G_CONNECT_SWAPPED);
+ else
+ g_signal_connect (G_OBJECT (button), "clicked",
+ G_CALLBACK (callback),
+ data);
+ }
+
+ if (widget_ptr)
+ *widget_ptr = button;
+
+ if (connect_delete && callback && !delete_connected)
+ {
+ gtk_object_set_data (GTK_OBJECT (dialog),
+ "dialog_cancel_callback",
+ (gpointer) callback);
+ gtk_object_set_data (GTK_OBJECT (dialog),
+ "dialog_cancel_widget",
+ slot_object ? slot_object : G_OBJECT (button));
+
+ /* catch the WM delete event */
+ g_signal_connect (G_OBJECT (dialog), "delete_event",
+ G_CALLBACK (dialog_delete_callback),
+ data);
+
+ delete_connected = TRUE;
+ }
+
+ if (default_action)
+ gtk_widget_grab_default (button);
+ gtk_widget_show (button);
+
+ label = va_arg (args, gchar *);
+ }
+}
+
+/**
+ * dialog_new:
+ * @title: The dialog's title which will be set with gtk_window_set_title().
+ * @position: The dialog's initial position which will be set with
+ * gtk_window_set_position().
+ * @resizable: Is the dialog resizable?, ...
+ * @allow_grow: ... it't @allow_grow flag and ...
+ * @auto_shrink: ... it's @auto_shrink flag which will all be set with
+ * gtk_window_set_policy().
+ * @...: A #NULL terminated @va_list destribing the action_area buttons.
+ *
+ * This function simply packs the action_area arguments passed in "..."
+ * into a @va_list variable and passes everything to dialog_newv().
+ *
+ * For a description of the format of the @va_list describing the
+ * action_area buttons see dialog_create_action_areav().
+ *
+ * Returns: A #GtkDialog.
+ *
+ */
+GtkWidget *
+stpui_dialog_new (const gchar *title,
+ GtkWindowPosition position,
+ gboolean resizable,
+
+ /* specify action area buttons as va_list:
+ * const gchar *label,
+ * GtkSignalFunc callback,
+ * gpointer data,
+ * GObject *slot_object,
+ * GtkWidget **widget_ptr,
+ * gboolean default_action,
+ * gboolean connect_delete,
+ */
+
+ ...)
+{
+ GtkWidget *dialog;
+ va_list args;
+
+ va_start (args, resizable);
+
+ g_return_val_if_fail (title != NULL, NULL);
+
+ dialog = gtk_dialog_new ();
+ gtk_window_set_title (GTK_WINDOW (dialog), title);
+ gtk_window_set_position (GTK_WINDOW (dialog), position);
+ gtk_window_set_resizable (GTK_WINDOW (dialog), resizable);
+
+ /* prepare the action_area */
+ dialog_create_action_areav (GTK_DIALOG (dialog), args);
+
+ va_end (args);
+
+ return dialog;
+}
+
+/*****************************************************************\
+* *
+* The following from libgimp/gimpwidgets.c *
+* *
+\*****************************************************************/
+
+/**
+ * option_menu_new:
+ * @menu_only: #TRUE if the function should return a #GtkMenu only.
+ * @...: A #NULL terminated @va_list describing the menu items.
+ *
+ * Returns: A #GtkOptionMenu or a #GtkMenu (depending on @menu_only).
+ **/
+GtkWidget *
+stpui_option_menu_new(gboolean menu_only,
+
+ /* specify menu items as va_list:
+ * const gchar *label,
+ * GtkSignalFunc callback,
+ * gpointer data,
+ * gpointer user_data,
+ * GtkWidget **widget_ptr,
+ * gboolean active
+ */
+
+ ...)
+{
+ GtkWidget *menu;
+ GtkWidget *menuitem;
+
+ /* menu item variables */
+ const gchar *label;
+ GtkSignalFunc callback;
+ gpointer data;
+ gpointer user_data;
+ GtkWidget **widget_ptr;
+ gboolean active;
+
+ va_list args;
+ gint i;
+ gint initial_index;
+
+ menu = gtk_menu_new ();
+
+ /* create the menu items */
+ initial_index = 0;
+
+ va_start (args, menu_only);
+ label = va_arg (args, const gchar *);
+
+ for (i = 0; label; i++)
+ {
+ callback = va_arg (args, GtkSignalFunc);
+ data = va_arg (args, gpointer);
+ user_data = va_arg (args, gpointer);
+ widget_ptr = va_arg (args, GtkWidget **);
+ active = va_arg (args, gboolean);
+
+ if (strcmp (label, "---"))
+ {
+ menuitem = gtk_menu_item_new_with_label (label);
+
+ g_signal_connect (G_OBJECT (menuitem), "activate",
+ callback,
+ data);
+
+ if (user_data)
+ gtk_object_set_user_data (GTK_OBJECT (menuitem), user_data);
+ }
+ else
+ {
+ menuitem = gtk_menu_item_new ();
+
+ gtk_widget_set_sensitive (menuitem, FALSE);
+ }
+
+ gtk_menu_append (GTK_MENU (menu), menuitem);
+
+ if (widget_ptr)
+ *widget_ptr = menuitem;
+
+ gtk_widget_show (menuitem);
+
+ /* remember the initial menu item */
+ if (active)
+ initial_index = i;
+
+ label = va_arg (args, const gchar *);
+ }
+ va_end (args);
+
+ if (! menu_only)
+ {
+ GtkWidget *optionmenu;
+
+ optionmenu = gtk_option_menu_new ();
+ gtk_option_menu_set_menu (GTK_OPTION_MENU (optionmenu), menu);
+
+ /* select the initial menu item */
+ gtk_option_menu_set_history (GTK_OPTION_MENU (optionmenu), initial_index);
+
+ return optionmenu;
+ }
+
+ return menu;
+}
+
+/*****************************************************************\
+* *
+* The following from libgimp/gimpwidgets.c *
+* *
+\*****************************************************************/
+
+/**
+ * spin_button_new:
+ * @adjustment: Returns the spinbutton's #GtkAdjustment.
+ * @value: The initial value of the spinbutton.
+ * @lower: The lower boundary.
+ * @upper: The uppper boundary.
+ * @step_increment: The spinbutton's step increment.
+ * @page_increment: The spinbutton's page increment (mouse button 2).
+ * @page_size: The spinbutton's page size.
+ * @climb_rate: The spinbutton's climb rate.
+ * @digits: The spinbutton's number of decimal digits.
+ *
+ * This function is a shortcut for gtk_adjustment_new() and a subsequent
+ * gtk_spin_button_new() and does some more initialisation stuff like
+ * setting a standard minimun horizontal size.
+ *
+ * Returns: A #GtkSpinbutton and it's #GtkAdjustment.
+ **/
+static GtkWidget *
+spin_button_new (GtkObject **adjustment, /* return value */
+ gfloat value,
+ gfloat lower,
+ gfloat upper,
+ gfloat step_increment,
+ gfloat page_increment,
+ gfloat page_size,
+ gfloat climb_rate,
+ guint digits)
+{
+ GtkWidget *spinbutton;
+
+ *adjustment = gtk_adjustment_new (value, lower, upper,
+ step_increment, page_increment, page_size);
+
+ spinbutton = gtk_spin_button_new (GTK_ADJUSTMENT (*adjustment),
+ climb_rate, digits);
+ gtk_spin_button_set_numeric (GTK_SPIN_BUTTON (spinbutton), TRUE);
+ gtk_widget_set_usize (spinbutton, 75, -1);
+
+ return spinbutton;
+}
+
+static void
+scale_entry_unconstrained_adjustment_callback (GtkAdjustment *adjustment,
+ GtkAdjustment *other_adj)
+{
+ g_signal_handlers_block_matched (G_OBJECT (other_adj),
+ G_SIGNAL_MATCH_DATA,
+ 0,
+ 0,
+ NULL,
+ NULL,
+ adjustment);
+
+ gtk_adjustment_set_value (other_adj, adjustment->value);
+
+ g_signal_handlers_unblock_matched (G_OBJECT (other_adj),
+ G_SIGNAL_MATCH_DATA,
+ 0,
+ 0,
+ NULL,
+ NULL,
+ adjustment);
+}
+
+/**
+ * scale_entry_new:
+ * @table: The #GtkTable the widgets will be attached to.
+ * @column: The column to start with.
+ * @row: The row to attach the widgets.
+ * @text: The text for the #GtkLabel which will appear
+ * left of the #GtkHScale.
+ * @scale_usize: The minimum horizontal size of the #GtkHScale.
+ * @spinbutton_usize: The minimum horizontal size of the #GtkSpinButton.
+ * @value: The initial value.
+ * @lower: The lower boundary.
+ * @upper: The upper boundary.
+ * @step_increment: The step increment.
+ * @page_increment: The page increment.
+ * @digits: The number of decimal digits.
+ * @constrain: #TRUE if the range of possible values of the
+ * #GtkSpinButton should be the same as of the #GtkHScale.
+ * @unconstrained_lower: The spinbutton's lower boundary
+ * if @constrain == #FALSE.
+ * @unconstrained_upper: The spinbutton's upper boundary
+ * if @constrain == #FALSE.
+ * @tooltip: A tooltip message for the scale and the spinbutton.
+ *
+ * This function creates a #GtkLabel, a #GtkHScale and a #GtkSpinButton and
+ * attaches them to a 3-column #GtkTable.
+ *
+ * Returns: The #GtkSpinButton's #GtkAdjustment.
+ **/
+GtkObject *
+stpui_scale_entry_new(GtkTable *table,
+ gint column,
+ gint row,
+ const gchar *text,
+ gint scale_usize,
+ gint spinbutton_usize,
+ gfloat value,
+ gfloat lower,
+ gfloat upper,
+ gfloat step_increment,
+ gfloat page_increment,
+ guint digits,
+ gboolean constrain,
+ gfloat unconstrained_lower,
+ gfloat unconstrained_upper,
+ const gchar *tooltip)
+{
+ GtkWidget *label;
+ GtkWidget *scale;
+ GtkWidget *spinbutton;
+ GtkObject *adjustment;
+ GtkObject *return_adj;
+
+ label = gtk_label_new (text);
+ gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
+ gtk_table_attach (GTK_TABLE (table), label,
+ column + 1, column + 2, row, row + 1,
+ GTK_FILL, GTK_FILL, 0, 0);
+ gtk_widget_show (label);
+
+ if (! constrain &&
+ unconstrained_lower <= lower &&
+ unconstrained_upper >= upper)
+ {
+ GtkObject *constrained_adj;
+
+ constrained_adj = gtk_adjustment_new (value, lower, upper,
+ step_increment, page_increment,
+ 0.0);
+
+ spinbutton = spin_button_new (&adjustment, value,
+ unconstrained_lower,
+ unconstrained_upper,
+ step_increment, page_increment, 0.0,
+ 1.0, digits);
+
+ g_signal_connect
+ (G_OBJECT (constrained_adj), "value_changed",
+ G_CALLBACK (scale_entry_unconstrained_adjustment_callback),
+ adjustment);
+
+ g_signal_connect
+ (G_OBJECT (adjustment), "value_changed",
+ G_CALLBACK (scale_entry_unconstrained_adjustment_callback),
+ constrained_adj);
+
+ return_adj = adjustment;
+
+ adjustment = constrained_adj;
+ }
+ else
+ {
+ spinbutton = spin_button_new (&adjustment, value, lower, upper,
+ step_increment, page_increment, 0.0,
+ 1.0, digits);
+
+ return_adj = adjustment;
+ }
+
+ if (spinbutton_usize > 0)
+ gtk_widget_set_usize (spinbutton, spinbutton_usize, -1);
+
+ scale = gtk_hscale_new (GTK_ADJUSTMENT (adjustment));
+ if (scale_usize > 0)
+ gtk_widget_set_usize (scale, scale_usize, -1);
+ gtk_scale_set_digits (GTK_SCALE (scale), digits);
+ gtk_scale_set_draw_value (GTK_SCALE (scale), FALSE);
+ gtk_table_attach (GTK_TABLE (table), scale,
+ column + 2, column + 3, row, row + 1,
+ GTK_FILL | GTK_EXPAND, GTK_FILL, 0, 0);
+ gtk_widget_show (scale);
+
+ gtk_table_attach (GTK_TABLE (table), spinbutton,
+ column + 3, column + 4, row, row + 1,
+ GTK_SHRINK, GTK_SHRINK, 0, 0);
+ gtk_widget_show (spinbutton);
+
+ if (tooltip)
+ {
+ stpui_set_help_data (scale, tooltip);
+ stpui_set_help_data (spinbutton, tooltip);
+ }
+
+ gtk_object_set_data (GTK_OBJECT (return_adj), "label", label);
+ gtk_object_set_data (GTK_OBJECT (return_adj), "scale", scale);
+ gtk_object_set_data (GTK_OBJECT (return_adj), "spinbutton", spinbutton);
+
+ return return_adj;
+}
+
+/**
+ * table_attach_aligned:
+ * @table: The #GtkTable the widgets will be attached to.
+ * @column: The column to start with.
+ * @row: The row to attach the eidgets.
+ * @label_text: The text for the #GtkLabel which will be attached left of the
+ * widget.
+ * @xalign: The horizontal alignment of the #GtkLabel.
+ * @yalign: The vertival alignment of the #GtkLabel.
+ * @widget: The #GtkWidget to attach right of the label.
+ * @colspan: The number of columns the widget will use.
+ * @left_align: #TRUE if the widget should be left-aligned.
+ *
+ * Note that the @label_text can be #NULL and that the widget will be attached
+ * starting at (@column + 1) in this case, too.
+ **/
+void
+stpui_table_attach_aligned (GtkTable *table,
+ gint column,
+ gint row,
+ const gchar *label_text,
+ gfloat xalign,
+ gfloat yalign,
+ GtkWidget *widget,
+ gint colspan,
+ gboolean left_align)
+{
+ if (label_text)
+ {
+ GtkWidget *label;
+
+ label = gtk_label_new (label_text);
+ gtk_misc_set_alignment (GTK_MISC (label), xalign, yalign);
+ gtk_label_set_justify (GTK_LABEL (label), GTK_JUSTIFY_LEFT);
+ gtk_table_attach (table, label, column, column + 1, row, row + 1,
+ GTK_FILL, GTK_FILL, 0, 0);
+ gtk_widget_show (label);
+ }
+
+ gtk_widget_show (widget);
+ if (left_align)
+ {
+ GtkWidget *alignment;
+
+ alignment = gtk_alignment_new (0.0, 0.5, 0.0, 0.0);
+ gtk_container_add (GTK_CONTAINER (alignment), widget);
+
+ widget = alignment;
+ }
+
+ gtk_table_attach (table, widget, column + 1, column + 1 + colspan,
+ row, row + 1,
+ GTK_FILL | GTK_EXPAND, GTK_FILL, 0, 0);
+
+ gtk_widget_show (widget);
+}
+
+/*****************************************************************\
+* *
+* The following borrowed from libgimp/gimphelpui.c *
+* *
+\*****************************************************************/
+
+static GtkTooltips * tool_tips = NULL;
+
+/**
+ * stpui_help_init:
+ *
+ * This function initializes GIMP's help system.
+ *
+ * Currently it only creates a #GtkTooltips object with gtk_tooltips_new()
+ * which will be used by help_stpui_set_help_data().
+ **/
+void
+stpui_help_init (void)
+{
+ tool_tips = gtk_tooltips_new ();
+}
+
+/**
+ * stpui_help_free:
+ *
+ * This function frees the memory used by the #GtkTooltips created by
+ * stpui_help_init().
+ **/
+void
+stpui_help_free (void)
+{
+ gtk_object_destroy (GTK_OBJECT (tool_tips));
+ gtk_object_unref (GTK_OBJECT (tool_tips));
+}
+
+/**
+ * help_enable_tooltips:
+ *
+ * This function calls gtk_tooltips_enable().
+ **/
+void
+stpui_enable_help (void)
+{
+ gtk_tooltips_enable (tool_tips);
+}
+
+/**
+ * help_disable_tooltips:
+ *
+ * This function calls gtk_tooltips_disable().
+ **/
+
+void
+stpui_disable_help (void)
+{
+ gtk_tooltips_disable (tool_tips);
+}
+
+void
+stpui_set_help_data (GtkWidget *widget, const gchar *tooltip)
+{
+ g_return_if_fail (widget != NULL);
+ g_return_if_fail (GTK_IS_WIDGET (widget));
+
+ if (tooltip)
+ {
+ gtk_tooltips_set_tip (tool_tips, widget, tooltip, NULL);
+ }
+}
+
+/*****************************************************************\
+* *
+* The below is new code *
+* *
+\*****************************************************************/
+
+
+void
+stpui_set_image_filename(const char *name)
+{
+ if (name && name == image_filename)
+ return;
+ if (image_filename)
+ g_free(image_filename);
+ if (name)
+ image_filename = g_strdup(name);
+ else
+ image_filename = g_strdup("");
+}
+
+const char *
+stpui_get_image_filename(void)
+{
+ stpui_set_image_filename(image_filename);
+ return(image_filename);
+}
+
+static void
+default_errfunc(void *data, const char *buffer, size_t bytes)
+{
+ fwrite(buffer, 1, bytes, data ? data : stderr);
+}
+
+void
+stpui_set_errfunc(stp_outfunc_t wfunc)
+{
+ the_errfunc = wfunc;
+}
+
+stp_outfunc_t
+stpui_get_errfunc(void)
+{
+ return the_errfunc;
+}
+
+void
+stpui_set_errdata(void *errdata)
+{
+ the_errdata = errdata;
+}
+
+void *
+stpui_get_errdata(void)
+{
+ return the_errdata;
+}
+
+void
+stpui_set_thumbnail_func(get_thumbnail_func_t func)
+{
+ thumbnail_func = func;
+}
+
+get_thumbnail_func_t
+stpui_get_thumbnail_func(void)
+{
+ return thumbnail_func;
+}
+
+void
+stpui_set_thumbnail_data(void *data)
+{
+ thumbnail_private_data = data;
+}
+
+void *
+stpui_get_thumbnail_data(void)
+{
+ return thumbnail_private_data;
+}
+
+GtkWidget *
+stpui_create_entry(GtkWidget *table, int hpos, int vpos, const char *text,
+ const char *help, GCallback callback)
+{
+ GtkWidget *entry = gtk_entry_new();
+ gtk_widget_set_usize(entry, 60, 0);
+ stpui_table_attach_aligned(GTK_TABLE(table), hpos, vpos, text,
+ 0.0, 0.5, entry, 1, TRUE);
+ stpui_set_help_data(entry, help);
+ g_signal_connect(G_OBJECT(entry), "activate",
+ G_CALLBACK(callback), NULL);
+ return entry;
+}
+
+GSList *
+stpui_create_radio_button(radio_group_t *radio, GSList *group,
+ GtkWidget *table, int hpos, int vpos,
+ GCallback callback)
+{
+ radio->button = gtk_radio_button_new_with_label(group, _(radio->name));
+ group = gtk_radio_button_group(GTK_RADIO_BUTTON(radio->button));
+ stpui_table_attach_aligned(GTK_TABLE(table), hpos, vpos, NULL, 0.5, 0.5,
+ radio->button, 1, FALSE);
+ stpui_set_help_data(radio->button, _(radio->help));
+ g_signal_connect(G_OBJECT(radio->button), "toggled",
+ G_CALLBACK(callback), (gpointer) radio->value);
+ return group;
+}
+
+void
+stpui_set_adjustment_tooltip (GtkObject *adj, const gchar *tip)
+{
+ stpui_set_help_data (GTK_WIDGET (SCALE_ENTRY_SCALE (adj)), tip);
+ stpui_set_help_data (GTK_WIDGET (SCALE_ENTRY_SPINBUTTON (adj)), tip);
+}
+
+static GtkWidget *
+table_label(GtkTable *table, gint column, gint row)
+{
+ GList *children = table->children;;
+ while (children)
+ {
+ GtkTableChild *child = (GtkTableChild *)children->data;
+ if (child->left_attach == column + 1 && child->top_attach == row)
+ return child->widget;
+ children = children->next;
+ }
+ return NULL;
+}
+
+void
+stpui_create_new_combo(option_t *option, GtkWidget *table,
+ int hpos, int vpos, gboolean is_optional)
+{
+ GtkWidget *event_box = gtk_event_box_new();
+ GtkWidget *combo = gtk_combo_new();
+
+ option->checkbox = gtk_check_button_new();
+ gtk_table_attach(GTK_TABLE(table), option->checkbox,
+ hpos, hpos + 1, vpos, vpos + 1,
+ GTK_EXPAND|GTK_FILL, GTK_FILL, 0, 0);
+
+ option->info.list.combo = combo;
+ gtk_container_add(GTK_CONTAINER(event_box), combo);
+ gtk_widget_show(combo);
+ gtk_widget_show(event_box);
+ stpui_set_help_data(event_box, _(option->fast_desc->help));
+ stpui_table_attach_aligned
+ (GTK_TABLE(table), hpos + 1, vpos, _(option->fast_desc->text),
+ 0.0, 0.5, event_box, 2, TRUE);
+ option->info.list.label = table_label(GTK_TABLE(table), hpos, vpos);
+}
+
+const char *
+stpui_combo_get_name(GtkWidget *combo,
+ const stp_string_list_t *options)
+{
+ if (options)
+ {
+ gint i;
+ gint num_options = stp_string_list_count(options);
+ const gchar *text = (gtk_entry_get_text(GTK_ENTRY(GTK_COMBO(combo)->entry)));
+
+ if (text == NULL)
+ return (NULL);
+
+ if (num_options == 0)
+ return ((const char *)text);
+
+ for (i = 0; i < num_options; i ++)
+ if (strcmp(stp_string_list_param(options, i)->text, text) == 0)
+ return (stp_string_list_param(options, i)->name);
+ }
+ return (NULL);
+}
+
+void
+stpui_create_scale_entry(option_t *opt,
+ GtkTable *table,
+ gint column,
+ gint row,
+ const gchar *text,
+ gint scale_usize,
+ gint spinbutton_usize,
+ gfloat value,
+ gfloat lower,
+ gfloat upper,
+ gfloat step_increment,
+ gfloat page_increment,
+ guint digits,
+ gboolean constrain,
+ gfloat unconstrained_lower,
+ gfloat unconstrained_upper,
+ const gchar *tooltip,
+ gboolean is_optional)
+{
+ opt->checkbox = gtk_check_button_new();
+ gtk_table_attach(GTK_TABLE(table), opt->checkbox,
+ column, column + 1, row, row + 1,
+ GTK_EXPAND|GTK_FILL, GTK_FILL, 0, 0);
+ opt->info.flt.adjustment =
+ stpui_scale_entry_new(table, column, row, text, scale_usize,
+ spinbutton_usize, value, lower, upper,
+ step_increment, page_increment, digits, constrain,
+ unconstrained_lower, unconstrained_upper, tooltip);
+}