diff options
| author | Alessio Treglia <alessio@debian.org> | 2010-07-12 19:34:33 +0200 | 
|---|---|---|
| committer | Alessio Treglia <alessio@debian.org> | 2010-07-12 19:34:33 +0200 | 
| commit | c15dc3b14e35850849f3559ac0305b4cac4a7046 (patch) | |
| tree | 2742af1506956e8f7e2e750e5907d36c627538da /src | |
| parent | 37e8ad6c00349fd62f09c8cfe3e22acf545db2ac (diff) | |
Imported Upstream version 2.31.5~bzr424upstream/2.31.5.bzr424
Diffstat (limited to 'src')
| -rw-r--r-- | src/Makefile.am | 1 | ||||
| -rw-r--r-- | src/Makefile.in | 661 | ||||
| -rw-r--r-- | src/book.c | 614 | ||||
| -rw-r--r-- | src/book.h | 4 | ||||
| -rw-r--r-- | src/page.c | 28 | ||||
| -rw-r--r-- | src/page.h | 4 | ||||
| -rw-r--r-- | src/scanner.c | 44 | ||||
| -rw-r--r-- | src/simple-scan.c | 54 | ||||
| -rw-r--r-- | src/ui.c | 632 | ||||
| -rw-r--r-- | src/ui.h | 1 | 
10 files changed, 933 insertions, 1110 deletions
| diff --git a/src/Makefile.am b/src/Makefile.am index e6654d0..8a4f587 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -29,6 +29,7 @@ simple_scan_CFLAGS = \  simple_scan_LDADD = \  	$(SIMPLE_SCAN_LIBS) \  	-lsane \ +	-ljpeg \  	-lm  DISTCLEANFILES = \ diff --git a/src/Makefile.in b/src/Makefile.in deleted file mode 100644 index 5665293..0000000 --- a/src/Makefile.in +++ /dev/null @@ -1,661 +0,0 @@ -# Makefile.in generated by automake 1.11.1 from Makefile.am. -# @configure_input@ - -# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, -# 2003, 2004, 2005, 2006, 2007, 2008, 2009  Free Software Foundation, -# Inc. -# This Makefile.in is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY, to the extent permitted by law; without -# even the implied warranty of MERCHANTABILITY or FITNESS FOR A -# PARTICULAR PURPOSE. - -@SET_MAKE@ - -VPATH = @srcdir@ -pkgdatadir = $(datadir)/@PACKAGE@ -pkgincludedir = $(includedir)/@PACKAGE@ -pkglibdir = $(libdir)/@PACKAGE@ -pkglibexecdir = $(libexecdir)/@PACKAGE@ -am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd -install_sh_DATA = $(install_sh) -c -m 644 -install_sh_PROGRAM = $(install_sh) -c -install_sh_SCRIPT = $(install_sh) -c -INSTALL_HEADER = $(INSTALL_DATA) -transform = $(program_transform_name) -NORMAL_INSTALL = : -PRE_INSTALL = : -POST_INSTALL = : -NORMAL_UNINSTALL = : -PRE_UNINSTALL = : -POST_UNINSTALL = : -bin_PROGRAMS = simple-scan$(EXEEXT) -subdir = src -DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in -ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 -am__aclocal_m4_deps = $(top_srcdir)/configure.ac -am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ -	$(ACLOCAL_M4) -mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs -CONFIG_CLEAN_FILES = -CONFIG_CLEAN_VPATH_FILES = -am__installdirs = "$(DESTDIR)$(bindir)" -PROGRAMS = $(bin_PROGRAMS) -am_simple_scan_OBJECTS = simple_scan-book.$(OBJEXT) \ -	simple_scan-book-view.$(OBJEXT) simple_scan-page.$(OBJEXT) \ -	simple_scan-page-view.$(OBJEXT) \ -	simple_scan-simple-scan.$(OBJEXT) \ -	simple_scan-scanner.$(OBJEXT) simple_scan-ui.$(OBJEXT) -simple_scan_OBJECTS = $(am_simple_scan_OBJECTS) -am__DEPENDENCIES_1 = -simple_scan_DEPENDENCIES = $(am__DEPENDENCIES_1) -simple_scan_LINK = $(CCLD) $(simple_scan_CFLAGS) $(CFLAGS) \ -	$(AM_LDFLAGS) $(LDFLAGS) -o $@ -DEFAULT_INCLUDES = -I.@am__isrc@ -depcomp = $(SHELL) $(top_srcdir)/depcomp -am__depfiles_maybe = depfiles -am__mv = mv -f -AM_V_lt = $(am__v_lt_$(V)) -am__v_lt_ = $(am__v_lt_$(AM_DEFAULT_VERBOSITY)) -am__v_lt_0 = --silent -COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ -	$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -AM_V_CC = $(am__v_CC_$(V)) -am__v_CC_ = $(am__v_CC_$(AM_DEFAULT_VERBOSITY)) -am__v_CC_0 = @echo "  CC    " $@; -AM_V_at = $(am__v_at_$(V)) -am__v_at_ = $(am__v_at_$(AM_DEFAULT_VERBOSITY)) -am__v_at_0 = @ -CCLD = $(CC) -LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ -AM_V_CCLD = $(am__v_CCLD_$(V)) -am__v_CCLD_ = $(am__v_CCLD_$(AM_DEFAULT_VERBOSITY)) -am__v_CCLD_0 = @echo "  CCLD  " $@; -AM_V_GEN = $(am__v_GEN_$(V)) -am__v_GEN_ = $(am__v_GEN_$(AM_DEFAULT_VERBOSITY)) -am__v_GEN_0 = @echo "  GEN   " $@; -SOURCES = $(simple_scan_SOURCES) -DIST_SOURCES = $(simple_scan_SOURCES) -ETAGS = etags -CTAGS = ctags -DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) -ACLOCAL = @ACLOCAL@ -ALL_LINGUAS = @ALL_LINGUAS@ -AMTAR = @AMTAR@ -AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ -AUTOCONF = @AUTOCONF@ -AUTOHEADER = @AUTOHEADER@ -AUTOMAKE = @AUTOMAKE@ -AWK = @AWK@ -CATALOGS = @CATALOGS@ -CATOBJEXT = @CATOBJEXT@ -CC = @CC@ -CCDEPMODE = @CCDEPMODE@ -CFLAGS = @CFLAGS@ -CPP = @CPP@ -CPPFLAGS = @CPPFLAGS@ -CYGPATH_W = @CYGPATH_W@ -DATADIRNAME = @DATADIRNAME@ -DEFS = @DEFS@ -DEPDIR = @DEPDIR@ -DISABLE_DEPRECATED = @DISABLE_DEPRECATED@ -DISTCHECK_CONFIGURE_FLAGS = @DISTCHECK_CONFIGURE_FLAGS@ -DOC_USER_FORMATS = @DOC_USER_FORMATS@ -ECHO_C = @ECHO_C@ -ECHO_N = @ECHO_N@ -ECHO_T = @ECHO_T@ -EGREP = @EGREP@ -EXEEXT = @EXEEXT@ -GCONF_SCHEMA_CONFIG_SOURCE = @GCONF_SCHEMA_CONFIG_SOURCE@ -GCONF_SCHEMA_FILE_DIR = @GCONF_SCHEMA_FILE_DIR@ -GETTEXT_PACKAGE = @GETTEXT_PACKAGE@ -GMOFILES = @GMOFILES@ -GMSGFMT = @GMSGFMT@ -GREP = @GREP@ -HELP_DIR = @HELP_DIR@ -INSTALL = @INSTALL@ -INSTALL_DATA = @INSTALL_DATA@ -INSTALL_PROGRAM = @INSTALL_PROGRAM@ -INSTALL_SCRIPT = @INSTALL_SCRIPT@ -INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ -INSTOBJEXT = @INSTOBJEXT@ -INTLLIBS = @INTLLIBS@ -INTLTOOL_EXTRACT = @INTLTOOL_EXTRACT@ -INTLTOOL_MERGE = @INTLTOOL_MERGE@ -INTLTOOL_PERL = @INTLTOOL_PERL@ -INTLTOOL_UPDATE = @INTLTOOL_UPDATE@ -LDFLAGS = @LDFLAGS@ -LIBOBJS = @LIBOBJS@ -LIBS = @LIBS@ -LN_S = @LN_S@ -LTLIBOBJS = @LTLIBOBJS@ -MAINT = @MAINT@ -MAKEINFO = @MAKEINFO@ -MKDIR_P = @MKDIR_P@ -MKINSTALLDIRS = @MKINSTALLDIRS@ -MSGFMT = @MSGFMT@ -MSGFMT_OPTS = @MSGFMT_OPTS@ -MSGMERGE = @MSGMERGE@ -OBJEXT = @OBJEXT@ -OMF_DIR = @OMF_DIR@ -PACKAGE = @PACKAGE@ -PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ -PACKAGE_NAME = @PACKAGE_NAME@ -PACKAGE_STRING = @PACKAGE_STRING@ -PACKAGE_TARNAME = @PACKAGE_TARNAME@ -PACKAGE_URL = @PACKAGE_URL@ -PACKAGE_VERSION = @PACKAGE_VERSION@ -PATH_SEPARATOR = @PATH_SEPARATOR@ -PKG_CONFIG = @PKG_CONFIG@ -POFILES = @POFILES@ -POSUB = @POSUB@ -PO_IN_DATADIR_FALSE = @PO_IN_DATADIR_FALSE@ -PO_IN_DATADIR_TRUE = @PO_IN_DATADIR_TRUE@ -SET_MAKE = @SET_MAKE@ -SHELL = @SHELL@ -SIMPLE_SCAN_CFLAGS = @SIMPLE_SCAN_CFLAGS@ -SIMPLE_SCAN_LIBS = @SIMPLE_SCAN_LIBS@ -STRIP = @STRIP@ -USE_NLS = @USE_NLS@ -VERSION = @VERSION@ -WARN_CFLAGS = @WARN_CFLAGS@ -XGETTEXT = @XGETTEXT@ -abs_builddir = @abs_builddir@ -abs_srcdir = @abs_srcdir@ -abs_top_builddir = @abs_top_builddir@ -abs_top_srcdir = @abs_top_srcdir@ -ac_ct_CC = @ac_ct_CC@ -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_alias = @build_alias@ -builddir = @builddir@ -datadir = @datadir@ -datarootdir = @datarootdir@ -docdir = @docdir@ -dvidir = @dvidir@ -exec_prefix = @exec_prefix@ -host_alias = @host_alias@ -htmldir = @htmldir@ -includedir = @includedir@ -infodir = @infodir@ -install_sh = @install_sh@ -libdir = @libdir@ -libexecdir = @libexecdir@ -localedir = @localedir@ -localstatedir = @localstatedir@ -mandir = @mandir@ -mkdir_p = @mkdir_p@ -oldincludedir = @oldincludedir@ -pdfdir = @pdfdir@ -prefix = @prefix@ -program_transform_name = @program_transform_name@ -psdir = @psdir@ -sbindir = @sbindir@ -sharedstatedir = @sharedstatedir@ -srcdir = @srcdir@ -sysconfdir = @sysconfdir@ -target_alias = @target_alias@ -top_build_prefix = @top_build_prefix@ -top_builddir = @top_builddir@ -top_srcdir = @top_srcdir@ -simple_scan_SOURCES = \ -	book.c \ -	book.h \ -	book-view.c \ -	book-view.h \ -	page.c \ -	page.h \ -	page-view.c \ -	page-view.h \ -	simple-scan.c \ -	scanner.c \ -	scanner.h \ -	ui.c \ -	ui.h - -simple_scan_CFLAGS = \ -	$(SIMPLE_SCAN_CFLAGS) \ -	$(WARN_CFLAGS) \ -	-DVERSION=\"$(VERSION)\" \ -	-DGETTEXT_PACKAGE=\"$(GETTEXT_PACKAGE)\" \ -	-DLOCALE_DIR=\"$(localedir)\" \ -	-DUI_DIR=\"$(datadir)/simple-scan/\" \ -	-DICON_DIR=\"$(datadir)/simple-scan/icons\" \ -	-DGCONF_DIR=\"/apps/simple-scan\" \ -	-DSIMPLE_SCAN_BINARY=\"simple-scan\" - -simple_scan_LDADD = \ -	$(SIMPLE_SCAN_LIBS) \ -	-lsane \ -	-lm - -DISTCLEANFILES = \ -	Makefile.in - -all: all-am - -.SUFFIXES: -.SUFFIXES: .c .o .obj -$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am  $(am__configure_deps) -	@for dep in $?; do \ -	  case '$(am__configure_deps)' in \ -	    *$$dep*) \ -	      ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ -	        && { if test -f $@; then exit 0; else break; fi; }; \ -	      exit 1;; \ -	  esac; \ -	done; \ -	echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/Makefile'; \ -	$(am__cd) $(top_srcdir) && \ -	  $(AUTOMAKE) --gnu src/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 -$(am__aclocal_m4_deps): -install-binPROGRAMS: $(bin_PROGRAMS) -	@$(NORMAL_INSTALL) -	test -z "$(bindir)" || $(MKDIR_P) "$(DESTDIR)$(bindir)" -	@list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ -	for p in $$list; do echo "$$p $$p"; done | \ -	sed 's/$(EXEEXT)$$//' | \ -	while read p p1; do if test -f $$p; \ -	  then echo "$$p"; echo "$$p"; else :; fi; \ -	done | \ -	sed -e 'p;s,.*/,,;n;h' -e 's|.*|.|' \ -	    -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \ -	sed 'N;N;N;s,\n, ,g' | \ -	$(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \ -	  { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \ -	    if ($$2 == $$4) files[d] = files[d] " " $$1; \ -	    else { print "f", $$3 "/" $$4, $$1; } } \ -	  END { for (d in files) print "f", d, files[d] }' | \ -	while read type dir files; do \ -	    if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \ -	    test -z "$$files" || { \ -	      echo " $(INSTALL_PROGRAM_ENV) $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(bindir)$$dir'"; \ -	      $(INSTALL_PROGRAM_ENV) $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(bindir)$$dir" || exit $$?; \ -	    } \ -	; done - -uninstall-binPROGRAMS: -	@$(NORMAL_UNINSTALL) -	@list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ -	files=`for p in $$list; do echo "$$p"; done | \ -	  sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \ -	      -e 's/$$/$(EXEEXT)/' `; \ -	test -n "$$list" || exit 0; \ -	echo " ( cd '$(DESTDIR)$(bindir)' && rm -f" $$files ")"; \ -	cd "$(DESTDIR)$(bindir)" && rm -f $$files - -clean-binPROGRAMS: -	-test -z "$(bin_PROGRAMS)" || rm -f $(bin_PROGRAMS) -simple-scan$(EXEEXT): $(simple_scan_OBJECTS) $(simple_scan_DEPENDENCIES)  -	@rm -f simple-scan$(EXEEXT) -	$(AM_V_CCLD)$(simple_scan_LINK) $(simple_scan_OBJECTS) $(simple_scan_LDADD) $(LIBS) - -mostlyclean-compile: -	-rm -f *.$(OBJEXT) - -distclean-compile: -	-rm -f *.tab.c - -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/simple_scan-book-view.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/simple_scan-book.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/simple_scan-page-view.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/simple_scan-page.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/simple_scan-scanner.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/simple_scan-simple-scan.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/simple_scan-ui.Po@am__quote@ - -.c.o: -@am__fastdepCC_TRUE@	$(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< -@am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po -@am__fastdepCC_FALSE@	$(AM_V_CC) @AM_BACKSLASH@ -@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@	$(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` -@am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po -@am__fastdepCC_FALSE@	$(AM_V_CC) @AM_BACKSLASH@ -@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) '$<'` - -simple_scan-book.o: book.c -@am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(simple_scan_CFLAGS) $(CFLAGS) -MT simple_scan-book.o -MD -MP -MF $(DEPDIR)/simple_scan-book.Tpo -c -o simple_scan-book.o `test -f 'book.c' || echo '$(srcdir)/'`book.c -@am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/simple_scan-book.Tpo $(DEPDIR)/simple_scan-book.Po -@am__fastdepCC_FALSE@	$(AM_V_CC) @AM_BACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='book.c' object='simple_scan-book.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(simple_scan_CFLAGS) $(CFLAGS) -c -o simple_scan-book.o `test -f 'book.c' || echo '$(srcdir)/'`book.c - -simple_scan-book.obj: book.c -@am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(simple_scan_CFLAGS) $(CFLAGS) -MT simple_scan-book.obj -MD -MP -MF $(DEPDIR)/simple_scan-book.Tpo -c -o simple_scan-book.obj `if test -f 'book.c'; then $(CYGPATH_W) 'book.c'; else $(CYGPATH_W) '$(srcdir)/book.c'; fi` -@am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/simple_scan-book.Tpo $(DEPDIR)/simple_scan-book.Po -@am__fastdepCC_FALSE@	$(AM_V_CC) @AM_BACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='book.c' object='simple_scan-book.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(simple_scan_CFLAGS) $(CFLAGS) -c -o simple_scan-book.obj `if test -f 'book.c'; then $(CYGPATH_W) 'book.c'; else $(CYGPATH_W) '$(srcdir)/book.c'; fi` - -simple_scan-book-view.o: book-view.c -@am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(simple_scan_CFLAGS) $(CFLAGS) -MT simple_scan-book-view.o -MD -MP -MF $(DEPDIR)/simple_scan-book-view.Tpo -c -o simple_scan-book-view.o `test -f 'book-view.c' || echo '$(srcdir)/'`book-view.c -@am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/simple_scan-book-view.Tpo $(DEPDIR)/simple_scan-book-view.Po -@am__fastdepCC_FALSE@	$(AM_V_CC) @AM_BACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='book-view.c' object='simple_scan-book-view.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(simple_scan_CFLAGS) $(CFLAGS) -c -o simple_scan-book-view.o `test -f 'book-view.c' || echo '$(srcdir)/'`book-view.c - -simple_scan-book-view.obj: book-view.c -@am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(simple_scan_CFLAGS) $(CFLAGS) -MT simple_scan-book-view.obj -MD -MP -MF $(DEPDIR)/simple_scan-book-view.Tpo -c -o simple_scan-book-view.obj `if test -f 'book-view.c'; then $(CYGPATH_W) 'book-view.c'; else $(CYGPATH_W) '$(srcdir)/book-view.c'; fi` -@am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/simple_scan-book-view.Tpo $(DEPDIR)/simple_scan-book-view.Po -@am__fastdepCC_FALSE@	$(AM_V_CC) @AM_BACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='book-view.c' object='simple_scan-book-view.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(simple_scan_CFLAGS) $(CFLAGS) -c -o simple_scan-book-view.obj `if test -f 'book-view.c'; then $(CYGPATH_W) 'book-view.c'; else $(CYGPATH_W) '$(srcdir)/book-view.c'; fi` - -simple_scan-page.o: page.c -@am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(simple_scan_CFLAGS) $(CFLAGS) -MT simple_scan-page.o -MD -MP -MF $(DEPDIR)/simple_scan-page.Tpo -c -o simple_scan-page.o `test -f 'page.c' || echo '$(srcdir)/'`page.c -@am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/simple_scan-page.Tpo $(DEPDIR)/simple_scan-page.Po -@am__fastdepCC_FALSE@	$(AM_V_CC) @AM_BACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='page.c' object='simple_scan-page.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(simple_scan_CFLAGS) $(CFLAGS) -c -o simple_scan-page.o `test -f 'page.c' || echo '$(srcdir)/'`page.c - -simple_scan-page.obj: page.c -@am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(simple_scan_CFLAGS) $(CFLAGS) -MT simple_scan-page.obj -MD -MP -MF $(DEPDIR)/simple_scan-page.Tpo -c -o simple_scan-page.obj `if test -f 'page.c'; then $(CYGPATH_W) 'page.c'; else $(CYGPATH_W) '$(srcdir)/page.c'; fi` -@am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/simple_scan-page.Tpo $(DEPDIR)/simple_scan-page.Po -@am__fastdepCC_FALSE@	$(AM_V_CC) @AM_BACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='page.c' object='simple_scan-page.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(simple_scan_CFLAGS) $(CFLAGS) -c -o simple_scan-page.obj `if test -f 'page.c'; then $(CYGPATH_W) 'page.c'; else $(CYGPATH_W) '$(srcdir)/page.c'; fi` - -simple_scan-page-view.o: page-view.c -@am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(simple_scan_CFLAGS) $(CFLAGS) -MT simple_scan-page-view.o -MD -MP -MF $(DEPDIR)/simple_scan-page-view.Tpo -c -o simple_scan-page-view.o `test -f 'page-view.c' || echo '$(srcdir)/'`page-view.c -@am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/simple_scan-page-view.Tpo $(DEPDIR)/simple_scan-page-view.Po -@am__fastdepCC_FALSE@	$(AM_V_CC) @AM_BACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='page-view.c' object='simple_scan-page-view.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(simple_scan_CFLAGS) $(CFLAGS) -c -o simple_scan-page-view.o `test -f 'page-view.c' || echo '$(srcdir)/'`page-view.c - -simple_scan-page-view.obj: page-view.c -@am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(simple_scan_CFLAGS) $(CFLAGS) -MT simple_scan-page-view.obj -MD -MP -MF $(DEPDIR)/simple_scan-page-view.Tpo -c -o simple_scan-page-view.obj `if test -f 'page-view.c'; then $(CYGPATH_W) 'page-view.c'; else $(CYGPATH_W) '$(srcdir)/page-view.c'; fi` -@am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/simple_scan-page-view.Tpo $(DEPDIR)/simple_scan-page-view.Po -@am__fastdepCC_FALSE@	$(AM_V_CC) @AM_BACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='page-view.c' object='simple_scan-page-view.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(simple_scan_CFLAGS) $(CFLAGS) -c -o simple_scan-page-view.obj `if test -f 'page-view.c'; then $(CYGPATH_W) 'page-view.c'; else $(CYGPATH_W) '$(srcdir)/page-view.c'; fi` - -simple_scan-simple-scan.o: simple-scan.c -@am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(simple_scan_CFLAGS) $(CFLAGS) -MT simple_scan-simple-scan.o -MD -MP -MF $(DEPDIR)/simple_scan-simple-scan.Tpo -c -o simple_scan-simple-scan.o `test -f 'simple-scan.c' || echo '$(srcdir)/'`simple-scan.c -@am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/simple_scan-simple-scan.Tpo $(DEPDIR)/simple_scan-simple-scan.Po -@am__fastdepCC_FALSE@	$(AM_V_CC) @AM_BACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='simple-scan.c' object='simple_scan-simple-scan.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(simple_scan_CFLAGS) $(CFLAGS) -c -o simple_scan-simple-scan.o `test -f 'simple-scan.c' || echo '$(srcdir)/'`simple-scan.c - -simple_scan-simple-scan.obj: simple-scan.c -@am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(simple_scan_CFLAGS) $(CFLAGS) -MT simple_scan-simple-scan.obj -MD -MP -MF $(DEPDIR)/simple_scan-simple-scan.Tpo -c -o simple_scan-simple-scan.obj `if test -f 'simple-scan.c'; then $(CYGPATH_W) 'simple-scan.c'; else $(CYGPATH_W) '$(srcdir)/simple-scan.c'; fi` -@am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/simple_scan-simple-scan.Tpo $(DEPDIR)/simple_scan-simple-scan.Po -@am__fastdepCC_FALSE@	$(AM_V_CC) @AM_BACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='simple-scan.c' object='simple_scan-simple-scan.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(simple_scan_CFLAGS) $(CFLAGS) -c -o simple_scan-simple-scan.obj `if test -f 'simple-scan.c'; then $(CYGPATH_W) 'simple-scan.c'; else $(CYGPATH_W) '$(srcdir)/simple-scan.c'; fi` - -simple_scan-scanner.o: scanner.c -@am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(simple_scan_CFLAGS) $(CFLAGS) -MT simple_scan-scanner.o -MD -MP -MF $(DEPDIR)/simple_scan-scanner.Tpo -c -o simple_scan-scanner.o `test -f 'scanner.c' || echo '$(srcdir)/'`scanner.c -@am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/simple_scan-scanner.Tpo $(DEPDIR)/simple_scan-scanner.Po -@am__fastdepCC_FALSE@	$(AM_V_CC) @AM_BACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='scanner.c' object='simple_scan-scanner.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(simple_scan_CFLAGS) $(CFLAGS) -c -o simple_scan-scanner.o `test -f 'scanner.c' || echo '$(srcdir)/'`scanner.c - -simple_scan-scanner.obj: scanner.c -@am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(simple_scan_CFLAGS) $(CFLAGS) -MT simple_scan-scanner.obj -MD -MP -MF $(DEPDIR)/simple_scan-scanner.Tpo -c -o simple_scan-scanner.obj `if test -f 'scanner.c'; then $(CYGPATH_W) 'scanner.c'; else $(CYGPATH_W) '$(srcdir)/scanner.c'; fi` -@am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/simple_scan-scanner.Tpo $(DEPDIR)/simple_scan-scanner.Po -@am__fastdepCC_FALSE@	$(AM_V_CC) @AM_BACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='scanner.c' object='simple_scan-scanner.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(simple_scan_CFLAGS) $(CFLAGS) -c -o simple_scan-scanner.obj `if test -f 'scanner.c'; then $(CYGPATH_W) 'scanner.c'; else $(CYGPATH_W) '$(srcdir)/scanner.c'; fi` - -simple_scan-ui.o: ui.c -@am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(simple_scan_CFLAGS) $(CFLAGS) -MT simple_scan-ui.o -MD -MP -MF $(DEPDIR)/simple_scan-ui.Tpo -c -o simple_scan-ui.o `test -f 'ui.c' || echo '$(srcdir)/'`ui.c -@am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/simple_scan-ui.Tpo $(DEPDIR)/simple_scan-ui.Po -@am__fastdepCC_FALSE@	$(AM_V_CC) @AM_BACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='ui.c' object='simple_scan-ui.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(simple_scan_CFLAGS) $(CFLAGS) -c -o simple_scan-ui.o `test -f 'ui.c' || echo '$(srcdir)/'`ui.c - -simple_scan-ui.obj: ui.c -@am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(simple_scan_CFLAGS) $(CFLAGS) -MT simple_scan-ui.obj -MD -MP -MF $(DEPDIR)/simple_scan-ui.Tpo -c -o simple_scan-ui.obj `if test -f 'ui.c'; then $(CYGPATH_W) 'ui.c'; else $(CYGPATH_W) '$(srcdir)/ui.c'; fi` -@am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/simple_scan-ui.Tpo $(DEPDIR)/simple_scan-ui.Po -@am__fastdepCC_FALSE@	$(AM_V_CC) @AM_BACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='ui.c' object='simple_scan-ui.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(simple_scan_CFLAGS) $(CFLAGS) -c -o simple_scan-ui.obj `if test -f 'ui.c'; then $(CYGPATH_W) 'ui.c'; else $(CYGPATH_W) '$(srcdir)/ui.c'; fi` - -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; nonempty = 1; } \ -	      END { if (nonempty) { for (i in files) print i; }; }'`; \ -	mkid -fID $$unique -tags: TAGS - -TAGS:  $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) \ -		$(TAGS_FILES) $(LISP) -	set x; \ -	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; nonempty = 1; } \ -	      END { if (nonempty) { for (i in files) print i; }; }'`; \ -	shift; \ -	if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ -	  test -n "$$unique" || unique=$$empty_fix; \ -	  if test $$# -gt 0; then \ -	    $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ -	      "$$@" $$unique; \ -	  else \ -	    $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ -	      $$unique; \ -	  fi; \ -	fi -ctags: CTAGS -CTAGS:  $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) \ -		$(TAGS_FILES) $(LISP) -	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; nonempty = 1; } \ -	      END { if (nonempty) { for (i in files) print i; }; }'`; \ -	test -z "$(CTAGS_ARGS)$$unique" \ -	  || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ -	     $$unique - -GTAGS: -	here=`$(am__cd) $(top_builddir) && pwd` \ -	  && $(am__cd) $(top_srcdir) \ -	  && gtags -i $(GTAGS_ARGS) "$$here" - -distclean-tags: -	-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags - -distdir: $(DISTFILES) -	@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ -	topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ -	list='$(DISTFILES)'; \ -	  dist_files=`for file in $$list; do echo $$file; done | \ -	  sed -e "s|^$$srcdirstrip/||;t" \ -	      -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ -	case $$dist_files in \ -	  */*) $(MKDIR_P) `echo "$$dist_files" | \ -			   sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ -			   sort -u` ;; \ -	esac; \ -	for file in $$dist_files; do \ -	  if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ -	  if test -d $$d/$$file; then \ -	    dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ -	    if test -d "$(distdir)/$$file"; then \ -	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ -	    fi; \ -	    if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ -	      cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ -	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ -	    fi; \ -	    cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ -	  else \ -	    test -f "$(distdir)/$$file" \ -	    || cp -p $$d/$$file "$(distdir)/$$file" \ -	    || exit 1; \ -	  fi; \ -	done -check-am: all-am -check: check-am -all-am: Makefile $(PROGRAMS) -installdirs: -	for dir in "$(DESTDIR)$(bindir)"; 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) -	-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) -	-test -z "$(DISTCLEANFILES)" || rm -f $(DISTCLEANFILES) - -maintainer-clean-generic: -	@echo "This command is intended for maintainers to use" -	@echo "it deletes files that may require special tools to rebuild." -clean: clean-am - -clean-am: clean-binPROGRAMS clean-generic mostlyclean-am - -distclean: distclean-am -	-rm -rf ./$(DEPDIR) -	-rm -f Makefile -distclean-am: clean-am distclean-compile distclean-generic \ -	distclean-tags - -dvi: dvi-am - -dvi-am: - -html: html-am - -html-am: - -info: info-am - -info-am: - -install-data-am: - -install-dvi: install-dvi-am - -install-dvi-am: - -install-exec-am: install-binPROGRAMS - -install-html: install-html-am - -install-html-am: - -install-info: install-info-am - -install-info-am: - -install-man: - -install-pdf: install-pdf-am - -install-pdf-am: - -install-ps: install-ps-am - -install-ps-am: - -installcheck-am: - -maintainer-clean: maintainer-clean-am -	-rm -rf ./$(DEPDIR) -	-rm -f Makefile -maintainer-clean-am: distclean-am maintainer-clean-generic - -mostlyclean: mostlyclean-am - -mostlyclean-am: mostlyclean-compile mostlyclean-generic - -pdf: pdf-am - -pdf-am: - -ps: ps-am - -ps-am: - -uninstall-am: uninstall-binPROGRAMS - -.MAKE: install-am install-strip - -.PHONY: CTAGS GTAGS all all-am check check-am clean clean-binPROGRAMS \ -	clean-generic ctags distclean distclean-compile \ -	distclean-generic distclean-tags distdir dvi dvi-am html \ -	html-am info info-am install install-am install-binPROGRAMS \ -	install-data install-data-am install-dvi install-dvi-am \ -	install-exec install-exec-am install-html install-html-am \ -	install-info install-info-am install-man install-pdf \ -	install-pdf-am install-ps install-ps-am install-strip \ -	installcheck installcheck-am installdirs maintainer-clean \ -	maintainer-clean-generic mostlyclean mostlyclean-compile \ -	mostlyclean-generic pdf pdf-am ps ps-am tags uninstall \ -	uninstall-am uninstall-binPROGRAMS - - -# 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: @@ -9,16 +9,22 @@   * license.   */ +#include <stdio.h>  #include <string.h>  #include <math.h> +#include <zlib.h> +#include <jpeglib.h>  #include <gdk/gdk.h>  #include <gdk-pixbuf/gdk-pixbuf.h>  #include <cairo/cairo-pdf.h>  #include <cairo/cairo-ps.h> -#include <unistd.h> // TEMP: Needed for close() in get_temporary_filename()  #include "book.h" +enum { +    PROP_0, +    PROP_NEEDS_SAVING +};  enum {      PAGE_ADDED, @@ -31,6 +37,8 @@ static guint signals[LAST_SIGNAL] = { 0, };  struct BookPrivate  {      GList *pages; +   +    gboolean needs_saving;  };  G_DEFINE_TYPE (Book, book, G_TYPE_OBJECT); @@ -57,17 +65,28 @@ book_clear (Book *book)  } +static void +page_changed_cb (Page *page, Book *book) +{ +    book_set_needs_saving (book, TRUE); +} + +  Page *  book_append_page (Book *book, gint width, gint height, gint dpi, Orientation orientation)  {      Page *page;      page = page_new (); +    g_signal_connect (page, "image-changed", G_CALLBACK (page_changed_cb), book); +    g_signal_connect (page, "crop-changed", G_CALLBACK (page_changed_cb), book);      page_setup (page, width, height, dpi, orientation);      book->priv->pages = g_list_append (book->priv->pages, page);      g_signal_emit (book, signals[PAGE_ADDED], 0, page); +   +    book_set_needs_saving (book, TRUE);      return page;  } @@ -76,10 +95,14 @@ book_append_page (Book *book, gint width, gint height, gint dpi, Orientation ori  void  book_delete_page (Book *book, Page *page)  { +    g_signal_handlers_disconnect_by_func (page, page_changed_cb, book); +      g_signal_emit (book, signals[PAGE_REMOVED], 0, page);      book->priv->pages = g_list_remove (book->priv->pages, page);      g_object_unref (page); + +    book_set_needs_saving (book, TRUE);  } @@ -218,160 +241,148 @@ book_save_ps (Book *book, GFile *file, GError **error)  } -// TEMP: Copied from simple-scan.c -static GFile * -get_temporary_file (const gchar *prefix, const gchar *extension) +typedef struct  { -    gint fd; -    GFile *file; -    gchar *filename, *path; -    GError *error = NULL; +    int offset; +    int n_objects; +    GList *object_offsets; +    GFileOutputStream *stream; +} PDFWriter; -    /* NOTE: I'm not sure if this is a 100% safe strategy to use g_file_open_tmp(), close and -     * use the filename but it appears to work in practise */ -    filename = g_strdup_printf ("%s-XXXXXX.%s", prefix, extension); -    fd = g_file_open_tmp (filename, &path, &error); -    g_free (filename); -    if (fd < 0) { -        g_warning ("Error saving email attachment: %s", error->message); -        g_clear_error (&error); -        return NULL; -    } -    close (fd); -   -    file = g_file_new_for_path (path); -    g_free (path); +static PDFWriter * +pdf_writer_new (GFileOutputStream *stream) +{ +    PDFWriter *writer; +    writer = g_malloc0 (sizeof (PDFWriter)); +    writer->stream = g_object_ref (stream); +    return writer; +} -    return file; + +static void +pdf_writer_free (PDFWriter *writer) +{ +    g_object_unref (writer->stream); +    g_list_free (writer->object_offsets); +    g_free (writer);  } -static goffset -get_file_size (GFile *file) +static void +pdf_write (PDFWriter *writer, const unsigned char *data, size_t length)  { -    GFileInfo *info; -    goffset size = 0; -   -    info = g_file_query_info (file, -                              G_FILE_ATTRIBUTE_STANDARD_SIZE, -                              G_FILE_QUERY_INFO_NONE, -                              NULL, -                              NULL); -    if (info) { -        size = g_file_info_get_size (info); -        g_object_unref (info); -    } +    g_output_stream_write_all (G_OUTPUT_STREAM (writer->stream), data, length, NULL, NULL, NULL); +    writer->offset += length; +} + -    return size; +static void +pdf_printf (PDFWriter *writer, const char *format, ...) +{ +    va_list args; +    gchar *string; + +    va_start (args, format); +    string = g_strdup_vprintf (format, args); +    va_end (args); +    pdf_write (writer, (unsigned char *)string, strlen (string)); + +    g_free (string);  } -static gboolean -book_save_pdf_with_imagemagick (Book *book, GFile *file, GError **error) +static int +pdf_start_object (PDFWriter *writer)  { -    GList *iter; -    GString *command_line; -    gboolean result = TRUE; -    gint exit_status = 0; -    GFile *output_file = NULL; -    GList *link, *temporary_files = NULL; +    writer->n_objects++; +    writer->object_offsets = g_list_append (writer->object_offsets, GINT_TO_POINTER (writer->offset)); +    return writer->n_objects; +} -    /* ImageMagick command to create a PDF */ -    command_line = g_string_new ("convert -adjoin"); -    /* Save each page to a file */ -    for (iter = book->priv->pages; iter && result; iter = iter->next) { -        Page *page = iter->data; -        GFile *jpeg_file, *tiff_file; -        gchar *path, *resolution_command, *stdout_text = NULL, *stderr_text = NULL; -        gint jpeg_size, tiff_size; - -        jpeg_file = get_temporary_file ("simple-scan", "jpg"); -        result = page_save (page, "jpeg", jpeg_file, error); -        jpeg_size = get_file_size (jpeg_file); -        temporary_files = g_list_append (temporary_files, jpeg_file); - -        tiff_file = get_temporary_file ("simple-scan", "tiff"); -        result = page_save (page, "tiff", tiff_file, error); -        tiff_size = get_file_size (tiff_file); -        temporary_files = g_list_append (temporary_files, tiff_file); - -        /* Use the smallest file */ -        if (jpeg_size < tiff_size) -            path = g_file_get_path (jpeg_file); -        else -            path = g_file_get_path (tiff_file); - -        resolution_command = g_strdup_printf ("convert %s -density %d %s", path, page_get_dpi (page), path); -        g_debug ("Executing ImageMagick command: %s", resolution_command); -        result = g_spawn_command_line_sync (resolution_command, &stdout_text, &stderr_text, &exit_status, error); -        if (result && exit_status != 0) { -            g_warning ("ImageMagick returned error code %d, command line was: %s", exit_status, resolution_command); -            g_warning ("stdout: %s", stdout_text); -            g_warning ("stderr: %s", stderr_text); -            result = FALSE; -            g_set_error (error, BOOK_TYPE, 0, -                         "ImageMagick returned error code %d\n" -                         "\n" -                         "Command line: %s\n" -                         "Stdout: %s\n" -                         "Stderr: %s", -                         exit_status, resolution_command, stdout_text, stderr_text); -        } -        if (!result) +static guchar * +compress_zlib (guchar *data, size_t length, size_t *n_written) +{ +    z_stream stream; +    guchar *out_data; + +    out_data = g_malloc (sizeof (guchar) * length); + +    stream.zalloc = Z_NULL; +    stream.zfree = Z_NULL; +    stream.opaque = Z_NULL; +    if (deflateInit (&stream, Z_BEST_COMPRESSION) != Z_OK) +        return NULL; + +    stream.next_in = data; +    stream.avail_in = length; +    stream.next_out = out_data; +    stream.avail_out = length; +    while (stream.avail_in > 0) { +        if (deflate (&stream, Z_FINISH) == Z_STREAM_ERROR)              break; -       -        g_string_append_printf (command_line, " %s", path); -        g_free (path);      } -    /* Use ImageMagick command to create a PDF */   -    if (result) { -        gchar *path, *stdout_text = NULL, *stderr_text = NULL; - -        output_file = get_temporary_file ("simple-scan", "pdf"); -        path = g_file_get_path (output_file); -        g_string_append_printf (command_line, " %s", path); -        g_free (path); - -        g_debug ("Executing ImageMagick command: %s", command_line->str); -        result = g_spawn_command_line_sync (command_line->str, &stdout_text, &stderr_text, &exit_status, error); -        if (result && exit_status != 0) { -            g_warning ("ImageMagick returned error code %d, command line was: %s", exit_status, command_line->str); -            g_warning ("stdout: %s", stdout_text); -            g_warning ("stderr: %s", stderr_text); -            result = FALSE; -            g_set_error (error, BOOK_TYPE, 0, -                         "ImageMagick returned error code %d\n" -                         "\n" -                         "Command line: %s\n" -                         "Stdout: %s\n" -                         "Stderr: %s", -                         exit_status, command_line->str, stdout_text, stderr_text); -        } -        g_free (stdout_text); -        g_free (stderr_text); +    deflateEnd (&stream); + +    if (stream.avail_in > 0) { +        g_free (out_data); +        return NULL;      } -    /* Move to target URI */ -    if (result) -        result = g_file_move (output_file, file, G_FILE_COPY_OVERWRITE, NULL, NULL, NULL, error); -   -    /* Delete page files */ -    for (link = temporary_files; link; link = link->next) { -        GFile *f = link->data; +    *n_written = length - stream.avail_out; + +    return out_data; +} -        g_file_delete (f, NULL, NULL); -        g_object_unref (f); + +static void jpeg_init_cb (struct jpeg_compress_struct *info) {} +static boolean jpeg_empty_cb (struct jpeg_compress_struct *info) { return TRUE; } +static void jpeg_term_cb (struct jpeg_compress_struct *info) {} + +static guchar * +compress_jpeg (GdkPixbuf *image, size_t *n_written) +{ +    struct jpeg_compress_struct info; +    struct jpeg_error_mgr jerr; +    struct jpeg_destination_mgr dest_mgr; +    int r; +    guchar *pixels; +    guchar *data; +    size_t max_length; + +    info.err = jpeg_std_error (&jerr); +    jpeg_create_compress (&info); + +    pixels = gdk_pixbuf_get_pixels (image); +    info.image_width = gdk_pixbuf_get_width (image); +    info.image_height = gdk_pixbuf_get_height (image); +    info.input_components = 3; +    info.in_color_space = JCS_RGB; /* TODO: JCS_GRAYSCALE? */ +    jpeg_set_defaults (&info); + +    max_length = info.image_width * info.image_height * info.input_components; +    data = g_malloc (sizeof (guchar) * max_length); +    dest_mgr.next_output_byte = data; +    dest_mgr.free_in_buffer = max_length; +    dest_mgr.init_destination = jpeg_init_cb; +    dest_mgr.empty_output_buffer = jpeg_empty_cb; +    dest_mgr.term_destination = jpeg_term_cb; +    info.dest = &dest_mgr; + +    jpeg_start_compress (&info, TRUE); +    for (r = 0; r < info.image_height; r++) { +        JSAMPROW row[1]; +        row[0] = pixels + r * gdk_pixbuf_get_rowstride (image); +        jpeg_write_scanlines (&info, row, 1);      } -    g_list_free (temporary_files); +    jpeg_finish_compress (&info); +    *n_written = max_length - dest_mgr.free_in_buffer; -    if (output_file) -        g_object_unref (output_file); -    g_string_free (command_line, TRUE); +    jpeg_destroy_compress (&info); -    return result; +    return data;  } @@ -379,43 +390,249 @@ static gboolean  book_save_pdf (Book *book, GFile *file, GError **error)  {      GFileOutputStream *stream; -    GList *iter; -    cairo_surface_t *surface; -    gchar *imagemagick_executable; -   -    /* Use ImageMagick if it is available as then we can compress the images */ -    imagemagick_executable = g_find_program_in_path ("convert"); -    if (imagemagick_executable) { -        g_free (imagemagick_executable); -        return book_save_pdf_with_imagemagick (book, file, error); -    } +    PDFWriter *writer; +    int catalog_number, pages_number, info_number; +    int xref_offset; +    int i;      stream = g_file_replace (file, NULL, FALSE, G_FILE_CREATE_NONE, NULL, error);      if (!stream)          return FALSE; -    surface = cairo_pdf_surface_create_for_stream ((cairo_write_func_t) write_cairo_data, -                                                   stream, 0, 0); +    writer = pdf_writer_new (stream); +    g_object_unref (stream); -    for (iter = book->priv->pages; iter; iter = iter->next) { -        Page *page = iter->data; -        double width, height; +    /* Header */ +    pdf_printf (writer, "%%PDF-1.3\n"); +   +    /* Catalog */ +    catalog_number = pdf_start_object (writer); +    pdf_printf (writer, "%d 0 obj\n", catalog_number); +    pdf_printf (writer, "<<\n"); +    pdf_printf (writer, "/Type /Catalog\n"); +    pdf_printf (writer, "/Pages %d 0 R\n", catalog_number + 1); +    pdf_printf (writer, ">>\n"); +    pdf_printf (writer, "endobj\n"); + +    /* Pages */ +    pdf_printf (writer, "\n"); +    pages_number = pdf_start_object (writer); +    pdf_printf (writer, "%d 0 obj\n", pages_number); +    pdf_printf (writer, "<<\n"); +    pdf_printf (writer, "/Type /Pages\n"); +    pdf_printf (writer, "/Kids ["); +    for (i = 0; i < book_get_n_pages (book); i++) { +        pdf_printf (writer, " %d 0 R", pages_number + 1 + (i*3)); +    } +    pdf_printf (writer, " ]\n"); +    pdf_printf (writer, "/Count %d\n", book_get_n_pages (book)); +    pdf_printf (writer, ">>\n"); +    pdf_printf (writer, "endobj\n"); + +    for (i = 0; i < book_get_n_pages (book); i++) { +        int number, width, height, depth; +        size_t data_length, compressed_length; +        Page *page;          GdkPixbuf *image; - +        guchar *pixels, *data, *compressed_data; +        gchar *command; +        const gchar *color_space, *filter = NULL; +        float page_width, page_height; + +        page = book_get_page (book, i); +        width = page_get_width (page); +        height = page_get_height (page); +        page_width = width * 72. / page_get_dpi (page); +        page_height = height * 72. / page_get_dpi (page);          image = page_get_cropped_image (page); +        pixels = gdk_pixbuf_get_pixels (image); + +        if (page_is_color (page)) { +            int row; + +            depth = 8; +            color_space = "DeviceRGB"; +            data_length = height * width * 3 + 1; +            data = g_malloc (sizeof (guchar) * data_length); +            for (row = 0; row < height; row++) { +                int x; +                guchar *in_line, *out_line; + +                in_line = pixels + row * gdk_pixbuf_get_rowstride (image); +                out_line = data + row * width * 3; +                for (x = 0; x < width; x++) { +                    guchar *in_p = in_line + x*3; +                    guchar *out_p = out_line + x*3; + +                    out_p[0] = in_p[0]; +                    out_p[1] = in_p[1]; +                    out_p[2] = in_p[2]; +                } +            } +        } +        else if (page_get_depth (page) == 1) { +            int row, offset = 7; +            guchar *write_ptr; + +            depth = 1; +            color_space = "DeviceGray"; +            data_length = (height * width + 7) / 8; +            data = g_malloc (sizeof (guchar) * data_length); +            write_ptr = data; +            write_ptr[0] = 0; +            for (row = 0; row < height; row++) { +                int x; +                guchar *in_line; + +                in_line = pixels + row * gdk_pixbuf_get_rowstride (image); +                for (x = 0; x < width; x++) { +                    guchar *in_p = in_line + x*3; +                    if (in_p[0]) +                        write_ptr[0] |= 1 << offset; +                    offset--; +                    if (offset < 0) { +                        write_ptr++; +                        write_ptr[0] = 0; +                        offset = 7; +                    } +                } +            } +        } +        else { +            int row; + +            depth = 8; +            color_space = "DeviceGray"; +            data_length = height * width + 1; +            data = g_malloc (sizeof (guchar) * data_length); +            for (row = 0; row < height; row++) { +                int x; +                guchar *in_line, *out_line; + +                in_line = pixels + row * gdk_pixbuf_get_rowstride (image); +                out_line = data + row * width; +                for (x = 0; x < width; x++) { +                    guchar *in_p = in_line + x*3; +                    guchar *out_p = out_line + x; + +                    out_p[0] = in_p[0]; +                } +            } +        } -        width = gdk_pixbuf_get_width (image) * 72.0 / page_get_dpi (page); -        height = gdk_pixbuf_get_height (image) * 72.0 / page_get_dpi (page); -        cairo_pdf_surface_set_size (surface, width, height); -        save_ps_pdf_surface (surface, image, page_get_dpi (page)); -        cairo_surface_show_page (surface); -         +        /* Compress data */ +        compressed_data = compress_zlib (data, data_length, &compressed_length); +        if (compressed_data) { +            /* Try if JPEG compression is better */ +            if (depth > 1) { +                guchar *jpeg_data; +                size_t jpeg_length; + +                jpeg_data = compress_jpeg (image, &jpeg_length); +                if (jpeg_length < compressed_length) { +                    filter = "DCTDecode"; +                    g_free (data); +                    g_free (compressed_data); +                    data = jpeg_data; +                    data_length = jpeg_length; +                } +            } + +            if (!filter) { +                filter = "FlateDecode"; +                g_free (data); +                data = compressed_data; +                data_length = compressed_length; +            } +        } + +        /* Page */ +        pdf_printf (writer, "\n"); +        number = pdf_start_object (writer); +        pdf_printf (writer, "%d 0 obj\n", number); +        pdf_printf (writer, "<<\n"); +        pdf_printf (writer, "/Type /Page\n"); +        pdf_printf (writer, "/Parent %d 0 R\n", pages_number); +        pdf_printf (writer, "/Resources << /XObject << /Im%d %d 0 R >> >>\n", i, number+1); +        pdf_printf (writer, "/MediaBox [ 0 0 %.2f %.2f ]\n", page_width, page_height); +        pdf_printf (writer, "/Contents %d 0 R\n", number+2); +        pdf_printf (writer, ">>\n"); +        pdf_printf (writer, "endobj\n"); + +        /* Page image */ +        pdf_printf (writer, "\n"); +        number = pdf_start_object (writer); +        pdf_printf (writer, "%d 0 obj\n", number); +        pdf_printf (writer, "<<\n"); +        pdf_printf (writer, "/Type /XObject\n"); +        pdf_printf (writer, "/Subtype /Image\n"); +        pdf_printf (writer, "/Width %d\n", width); +        pdf_printf (writer, "/Height %d\n", height); +        pdf_printf (writer, "/ColorSpace /%s\n", color_space); +        pdf_printf (writer, "/BitsPerComponent %d\n", depth); +        pdf_printf (writer, "/Length %d\n", data_length); +        if (filter) +          pdf_printf (writer, "/Filter /%s\n", filter); +        pdf_printf (writer, ">>\n"); +        pdf_printf (writer, "stream\n"); +        pdf_write (writer, data, data_length); +        g_free (data); +        pdf_printf (writer, "\n"); +        pdf_printf (writer, "endstream\n"); +        pdf_printf (writer, "endobj\n");       + +        /* Page contents */ +        command = g_strdup_printf ("q\n" +                                   "%d 0 0 %d 0 0 cm\n" +                                   "/Im%d Do\n" +                                   "Q", width, height, i); +        pdf_printf (writer, "\n"); +        number = pdf_start_object (writer); +        pdf_printf (writer, "%d 0 obj\n", number); +        pdf_printf (writer, "<<\n"); +        pdf_printf (writer, "/Length %d\n", strlen (command) + 1); +        pdf_printf (writer, ">>\n"); +        pdf_printf (writer, "stream\n"); +        pdf_write (writer, (unsigned char *)command, strlen (command)); +        pdf_printf (writer, "\n"); +        pdf_printf (writer, "endstream\n"); +        pdf_printf (writer, "endobj\n"); +        g_free (command); +                            g_object_unref (image);      } +   +    /* Info */ +    pdf_printf (writer, "\n"); +    info_number = pdf_start_object (writer); +    pdf_printf (writer, "%d 0 obj\n", info_number); +    pdf_printf (writer, "<<\n"); +    pdf_printf (writer, "/Creator (Simple Scan " VERSION ")\n"); +    pdf_printf (writer, ">>\n"); +    pdf_printf (writer, "endobj\n"); + +    /* Cross-reference table */ +    xref_offset = writer->offset; +    pdf_printf (writer, "xref\n"); +    pdf_printf (writer, "1 %d\n", writer->n_objects); +    GList *link; +    for (link = writer->object_offsets; link != NULL; link = link->next) { +        int offset = GPOINTER_TO_INT (link->data); +        pdf_printf (writer, "%010d 0000 n\n", offset); +    } -    cairo_surface_destroy (surface); - -    g_object_unref (stream); +    /* Trailer */ +    pdf_printf (writer, "trailer\n"); +    pdf_printf (writer, "<<\n"); +    pdf_printf (writer, "/Size %d\n", writer->n_objects); +    pdf_printf (writer, "/Info %d 0 R\n", info_number); +    pdf_printf (writer, "/Root %d 0 R\n", catalog_number); +    pdf_printf (writer, ">>\n"); +    pdf_printf (writer, "startxref\n"); +    pdf_printf (writer, "%d\n", xref_offset); +    pdf_printf (writer, "%%%%EOF\n"); +   +    pdf_writer_free (writer);      return TRUE;  } @@ -424,18 +641,79 @@ book_save_pdf (Book *book, GFile *file, GError **error)  gboolean  book_save (Book *book, const gchar *type, GFile *file, GError **error)  { +    gboolean result = FALSE; +      if (strcmp (type, "jpeg") == 0) -        return book_save_multi_file (book, "jpeg", file, error); +        result = book_save_multi_file (book, "jpeg", file, error);      else if (strcmp (type, "png") == 0) -        return book_save_multi_file (book, "png", file, error); +        result = book_save_multi_file (book, "png", file, error);      else if (strcmp (type, "tiff") == 0) -        return book_save_multi_file (book, "tiff", file, error);     +        result = book_save_multi_file (book, "tiff", file, error);          else if (strcmp (type, "ps") == 0) -        return book_save_ps (book, file, error);     +        result = book_save_ps (book, file, error);          else if (strcmp (type, "pdf") == 0) -        return book_save_pdf (book, file, error); -    else -        return FALSE; +        result = book_save_pdf (book, file, error); + +    return result; +} + + +void +book_set_needs_saving (Book *book, gboolean needs_saving) +{ +    gboolean needed_saving = book->priv->needs_saving; +    book->priv->needs_saving = needs_saving; +    if (needed_saving != needs_saving) +        g_object_notify (G_OBJECT (book), "needs-saving"); +} + + +gboolean +book_get_needs_saving (Book *book) +{ +    return book->priv->needs_saving; +} + + +static void +book_set_property (GObject      *object, +                   guint         prop_id, +                   const GValue *value, +                   GParamSpec   *pspec) +{ +    Book *self; + +    self = BOOK (object); + +    switch (prop_id) { +    case PROP_NEEDS_SAVING: +        book_set_needs_saving (self, g_value_get_boolean (value)); +        break; +    default: +        G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); +        break; +    } +} + + +static void +book_get_property (GObject    *object, +                   guint       prop_id, +                   GValue     *value, +                   GParamSpec *pspec) +{ +    Book *self; + +    self = BOOK (object); + +    switch (prop_id) { +    case PROP_NEEDS_SAVING: +        g_value_set_boolean (value, book_get_needs_saving (self)); +        break; +    default: +        G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); +        break; +    }  } @@ -453,8 +731,18 @@ book_class_init (BookClass *klass)  {      GObjectClass *object_class = G_OBJECT_CLASS (klass); +    object_class->get_property = book_get_property; +    object_class->set_property = book_set_property;      object_class->finalize = book_finalize; +    g_object_class_install_property (object_class, +                                     PROP_NEEDS_SAVING, +                                     g_param_spec_boolean ("needs-saving", +                                                           "needs-saving", +                                                           "TRUE if this book needs saving", +                                                           FALSE, +                                                           G_PARAM_READWRITE)); +      signals[PAGE_ADDED] =          g_signal_new ("page-added",                        G_TYPE_FROM_CLASS (klass), @@ -57,4 +57,8 @@ Page *book_get_page (Book *book, gint page_number);  gboolean book_save (Book *book, const gchar *type, GFile *file, GError **error); +void book_set_needs_saving (Book *book, gboolean needs_saving); + +gboolean book_get_needs_saving (Book *book); +  #endif /* _BOOK_H_ */ @@ -31,6 +31,9 @@ struct PagePrivate      /* Number of rows in this page or -1 if currently unknown */      gint rows; +    /* Bit depth */ +    gint depth; +      /* Color profile */      gchar *color_profile; @@ -43,6 +46,9 @@ struct PagePrivate      /* TRUE if have some page data */      gboolean has_data; +    /* TRUE if have color data */ +    gboolean is_color; +      /* Expected next scan row */      gint scan_line; @@ -179,6 +185,21 @@ gboolean page_has_data (Page *page)  } +gboolean page_is_color (Page *page) +{ +    g_return_val_if_fail (page != NULL, FALSE); +    return page->priv->is_color; +} + + +gint +page_get_depth (Page *page) +{ +    g_return_val_if_fail (page != NULL, 0); +    return page->priv->depth; +} + +  gint page_get_scan_line (Page *page)  {      g_return_val_if_fail (page != NULL, -1); @@ -191,7 +212,7 @@ set_pixel (ScanLine *line, gint n, gint x, guchar *pixel)  {      gint sample;      guchar *data; -   +      data = line->data + line->data_length * n;      switch (line->format) { @@ -231,6 +252,11 @@ parse_line (Page *page, ScanLine *line, gint n, gboolean *size_changed)      line_number = line->number + n; +    if (line->format != LINE_GRAY) +        page->priv->is_color = TRUE; +    if (line->depth > page->priv->depth) +        page->priv->depth = line->depth; +      /* Extend image if necessary */      while (line_number >= page_get_scan_height (page)) {          GdkPixbuf *image; @@ -82,6 +82,10 @@ gboolean page_is_scanning (Page *page);  gboolean page_has_data (Page *page); +gboolean page_is_color (Page *page); + +gint page_get_depth (Page *page); +  gint page_get_scan_line (Page *page);  void page_parse_scan_line (Page *page, ScanLine *line); diff --git a/src/scanner.c b/src/scanner.c index a8d09f9..8383f9f 100644 --- a/src/scanner.c +++ b/src/scanner.c @@ -792,7 +792,7 @@ close_device (Scanner *scanner)          g_debug ("sane_close ()");          scanner->priv->handle = NULL;      } -   +      g_free (scanner->priv->buffer);      scanner->priv->buffer = NULL; @@ -1320,10 +1320,12 @@ do_read (Scanner *scanner)                          n_to_read, &n_read);      g_debug ("sane_read (%d) -> (%s, %d)", n_to_read, get_status_string (status), n_read); -    /* End of variable length frame */ -    if (status == SANE_STATUS_EOF && -        scanner->priv->parameters.lines == -1 && -        scanner->priv->bytes_remaining == scanner->priv->parameters.bytes_per_line) { +    /* Completed read */ +    if (status == SANE_STATUS_EOF) { +        if (scanner->priv->parameters.lines > 0 && scanner->priv->line_count != scanner->priv->parameters.lines) +            g_warning ("Scan completed with %d lines, expected %d lines", scanner->priv->parameters.lines, scanner->priv->parameters.lines); +        if (scanner->priv->n_used > 0) +            g_warning ("Scan complete with %d bytes of unused data", scanner->priv->n_used);          do_complete_page (scanner);          return;      } @@ -1344,6 +1346,7 @@ do_read (Scanner *scanner)      /* Feed out lines */      if (scanner->priv->n_used >= scanner->priv->parameters.bytes_per_line) {          ScanLine *line; +        int i, n_remaining;          line = g_malloc(sizeof(ScanLine));          switch (scanner->priv->parameters.format) { @@ -1373,27 +1376,18 @@ do_read (Scanner *scanner)          scanner->priv->buffer = NULL;          scanner->priv->line_count += line->n_lines; -        /* On last line */ -        if (scanner->priv->parameters.lines > 0 && scanner->priv->line_count >= scanner->priv->parameters.lines) { -            emit_signal (scanner, GOT_LINE, line); -            do_complete_page (scanner); -        } -        else { -            int i, n_remaining; - -            /* Increase buffer size if did full read */ -            if (full_read) -                scanner->priv->buffer_size += scanner->priv->parameters.bytes_per_line; - -            scanner->priv->buffer = g_malloc(sizeof(SANE_Byte) * scanner->priv->buffer_size); -            n_remaining = scanner->priv->n_used - (line->n_lines * line->data_length); -            scanner->priv->n_used = 0; -            for (i = 0; i < n_remaining; i++) { -                scanner->priv->buffer[i] = line->data[i + (line->n_lines * line->data_length)]; -                scanner->priv->n_used++;                 -            } -            emit_signal (scanner, GOT_LINE, line); +        /* Increase buffer size if did full read */ +        if (full_read) +            scanner->priv->buffer_size += scanner->priv->parameters.bytes_per_line; + +        scanner->priv->buffer = g_malloc(sizeof(SANE_Byte) * scanner->priv->buffer_size); +        n_remaining = scanner->priv->n_used - (line->n_lines * line->data_length); +        scanner->priv->n_used = 0; +        for (i = 0; i < n_remaining; i++) { +            scanner->priv->buffer[i] = line->data[i + (line->n_lines * line->data_length)]; +            scanner->priv->n_used++;          } +        emit_signal (scanner, GOT_LINE, line);      }  } diff --git a/src/simple-scan.c b/src/simple-scan.c index b8c3962..54236ae 100644 --- a/src/simple-scan.c +++ b/src/simple-scan.c @@ -26,6 +26,8 @@  static ScanDevice *default_device = NULL; +static gboolean have_devices = FALSE; +  static GUdevClient *udev_client;  static SimpleScan *ui; @@ -62,6 +64,7 @@ update_scan_devices_cb (Scanner *scanner, GList *devices)              devices_copy = g_list_prepend (devices_copy, default_device);      } +    have_devices = devices_copy != NULL;      ui_set_scan_devices (ui, devices_copy);      g_list_free (devices_copy); @@ -261,7 +264,7 @@ scanner_failed_cb (Scanner *scanner, GError *error)                         /* Title of error dialog when scan failed */                         _("Failed to scan"),                         error->message, -                       TRUE); +                       have_devices);      }  } @@ -305,54 +308,6 @@ cancel_cb (SimpleScan *ui)  } -static gboolean -save_book_by_extension (GFile *file, GError **error) -{ -    gboolean result; -    gchar *uri, *uri_lower; - -    uri = g_file_get_uri (file); -    uri_lower = g_utf8_strdown (uri, -1); -    if (g_str_has_suffix (uri_lower, ".pdf")) -        result = book_save (book, "pdf", file, error); -    else if (g_str_has_suffix (uri_lower, ".ps")) -        result = book_save (book, "ps", file, error); -    else if (g_str_has_suffix (uri_lower, ".png")) -        result = book_save (book, "png", file, error); -    else if (g_str_has_suffix (uri_lower, ".tif") || g_str_has_suffix (uri_lower, ".tiff")) -        result = book_save (book, "tiff", file, error); -    else -        result = book_save (book, "jpeg", file, error); - -    g_free (uri); -    g_free (uri_lower); - -    return result; -} - - -static void -save_cb (SimpleScan *ui, const gchar *uri) -{ -    GError *error = NULL; -    GFile *file; - -    g_debug ("Saving to '%s'", uri); - -    file = g_file_new_for_uri (uri); -    if (!save_book_by_extension (file, &error)) { -        g_warning ("Error saving file: %s", error->message); -        ui_show_error (ui, -                       /* Title of error dialog when save failed */ -                       _("Failed to save file"), -                       error->message, -               FALSE); -        g_error_free (error); -    } -    g_object_unref (file); -} - -  static gchar *  get_temporary_filename (const gchar *prefix, const gchar *extension)  { @@ -625,7 +580,6 @@ main (int argc, char **argv)      book = ui_get_book (ui);      g_signal_connect (ui, "start-scan", G_CALLBACK (scan_cb), NULL);      g_signal_connect (ui, "stop-scan", G_CALLBACK (cancel_cb), NULL); -    g_signal_connect (ui, "save", G_CALLBACK (save_cb), NULL);      g_signal_connect (ui, "email", G_CALLBACK (email_cb), NULL);      g_signal_connect (ui, "quit", G_CALLBACK (quit_cb), NULL); @@ -28,7 +28,6 @@  enum {      START_SCAN,      STOP_SCAN, -    SAVE,      EMAIL,      QUIT,      LAST_SIGNAL @@ -43,7 +42,10 @@ struct SimpleScanPrivate      GtkBuilder *builder;      GtkWidget *window, *main_vbox; +    GtkWidget *info_bar, *info_bar_image, *info_bar_label; +    GtkWidget *info_bar_close_button, *info_bar_change_scanner_button;      GtkWidget *page_delete_menuitem, *crop_rotate_menuitem; +    GtkWidget *save_menuitem, *save_as_menuitem, *save_toolbutton;      GtkWidget *stop_menuitem, *stop_toolbutton;      GtkWidget *text_toolbar_menuitem, *text_menu_menuitem; @@ -58,14 +60,18 @@ struct SimpleScanPrivate      GtkTreeModel *device_model, *text_dpi_model, *photo_dpi_model, *page_side_model, *paper_size_model;      gboolean setting_devices, user_selected_device; +    gboolean have_error; +    gchar *error_title, *error_text; +    gboolean error_change_scanner_hint; +      Book *book; +    gchar *book_uri; +        BookView *book_view;      gboolean updating_page_menu;      gint default_page_width, default_page_height, default_page_dpi;      Orientation default_page_orientation; -    gboolean have_device_list; -      gchar *document_hint;      gchar *default_file_name; @@ -110,6 +116,22 @@ find_scan_device (SimpleScan *ui, const char *device, GtkTreeIter *iter)  } +static void +show_error_dialog (SimpleScan *ui, const char *error_title, const char *error_text) +{ +    GtkWidget *dialog; + +    dialog = gtk_message_dialog_new (GTK_WINDOW (ui->priv->window), +                                     GTK_DIALOG_MODAL, +                                     GTK_MESSAGE_WARNING, +                                     GTK_BUTTONS_NONE, +                                     "%s", error_title); +    gtk_dialog_add_button (GTK_DIALOG (dialog), GTK_STOCK_CLOSE, 0); +    gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog), "%s", error_text); +    gtk_widget_destroy (dialog); +} + +  void  ui_set_default_file_name (SimpleScan *ui, const gchar *default_file_name)  { @@ -154,6 +176,47 @@ device_combo_changed_cb (GtkWidget *widget, SimpleScan *ui)  } +static void +update_info_bar (SimpleScan *ui) +{ +    GtkMessageType type; +    const gchar *title, *text, *image_id; +    gchar *message; +    gboolean show_close_button = FALSE; +    gboolean show_change_scanner_button = FALSE; +   +    if (ui->priv->have_error)  { +        type = GTK_MESSAGE_ERROR; +        image_id = GTK_STOCK_DIALOG_ERROR; +        title = ui->priv->error_title; +        text = ui->priv->error_text; +        show_close_button = TRUE; +        show_change_scanner_button = ui->priv->error_change_scanner_hint; +    } +    else if (gtk_tree_model_iter_n_children (ui->priv->device_model, NULL) == 0) { +        type = GTK_MESSAGE_WARNING; +        image_id = GTK_STOCK_DIALOG_WARNING; +        /* Warning displayed when no scanners are detected */ +        title = _("No scanners detected"); +        /* Hint to user on why there are no scanners detected */ +        text = _("Please check your scanner is connected and powered on"); +    } +    else { +        gtk_widget_hide (ui->priv->info_bar); +        return; +    } + +    gtk_info_bar_set_message_type (GTK_INFO_BAR (ui->priv->info_bar), type); +    gtk_image_set_from_stock (GTK_IMAGE (ui->priv->info_bar_image), image_id, GTK_ICON_SIZE_DIALOG); +    message = g_strdup_printf ("<big><b>%s</b></big>\n\n%s", title, text); +    gtk_label_set_markup (GTK_LABEL (ui->priv->info_bar_label), message); +    g_free (message); +    gtk_widget_set_visible (ui->priv->info_bar_close_button, show_close_button);   +    gtk_widget_set_visible (ui->priv->info_bar_change_scanner_button, show_change_scanner_button); +    gtk_widget_show (ui->priv->info_bar); +} + +  void  ui_set_scan_devices (SimpleScan *ui, GList *devices)  { @@ -222,18 +285,7 @@ ui_set_scan_devices (SimpleScan *ui, GList *devices)      ui->priv->setting_devices = FALSE; -    if (!ui->priv->have_device_list) { -        ui->priv->have_device_list = TRUE; - -        if (!devices) { -            ui_show_error (ui, -                           /* Warning displayed when no scanners are detected */ -                           _("No scanners detected"), -                           /* Hint to user on why there are no scanners detected */ -                           _("Please check your scanner is connected and powered on"), -                           FALSE); -        } -    } +    update_info_bar (ui);  } @@ -279,13 +331,272 @@ add_default_page (SimpleScan *ui)  } +static void +on_file_type_changed (GtkTreeSelection *selection, GtkWidget *dialog) +{ +    GtkTreeModel *model; +    GtkTreeIter iter; +    gchar *path, *filename, *extension, *new_filename; + +    if (!gtk_tree_selection_get_selected (selection, &model, &iter)) +        return; + +    gtk_tree_model_get (model, &iter, 1, &extension, -1); +    path = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog)); +    filename = g_path_get_basename (path); + +    /* Replace extension */ +    if (g_strrstr (filename, ".")) +        new_filename = g_strdup_printf ("%.*s%s", (int)(g_strrstr (filename, ".") - filename), filename, extension); +    else +        new_filename = g_strdup_printf ("%s%s", filename, extension); +    gtk_file_chooser_set_current_name (GTK_FILE_CHOOSER (dialog), new_filename); + +    g_free (path); +    g_free (filename); +    g_free (new_filename); +    g_free (extension); +} + + +static gchar * +choose_file_location (SimpleScan *ui) +{ +    GtkWidget *dialog; +    gint response; +    GtkFileFilter *filter; +    GtkWidget *expander, *file_type_view; +    GtkListStore *file_type_store; +    GtkTreeIter iter; +    GtkTreeViewColumn *column; +    const gchar *extension; +    gchar *directory, *uri = NULL; +    gint i; + +    struct +    { +        gchar *label, *extension; +    } file_types[] = +    { +        /* Save dialog: Label for saving in PDF format */ +        { _("PDF (multi-page document)"), ".pdf" }, +        /* Save dialog: Label for saving in JPEG format */ +        { _("JPEG (compressed)"), ".jpg" }, +        /* Save dialog: Label for saving in PNG format */ +        { _("PNG (lossless)"), ".png" }, +        { NULL, NULL } +    }; + +    /* Get directory to save to */ +    directory = gconf_client_get_string (ui->priv->client, GCONF_DIR "/save_directory", NULL); +    if (!directory || directory[0] == '\0') { +        g_free (directory); +        directory = g_strdup (g_get_user_special_dir (G_USER_DIRECTORY_DOCUMENTS)); +    } + +    dialog = gtk_file_chooser_dialog_new (/* Save dialog: Dialog title */ +                                          _("Save As..."), +                                          GTK_WINDOW (ui->priv->window), +                                          GTK_FILE_CHOOSER_ACTION_SAVE, +                                          GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, +                                          GTK_STOCK_SAVE, GTK_RESPONSE_ACCEPT, +                                          NULL); +    gtk_file_chooser_set_do_overwrite_confirmation (GTK_FILE_CHOOSER (dialog), TRUE); +    gtk_file_chooser_set_local_only (GTK_FILE_CHOOSER (dialog), FALSE); +    gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (dialog), directory); +    gtk_file_chooser_set_current_name (GTK_FILE_CHOOSER (dialog), ui->priv->default_file_name); +    g_free (directory); + +    /* Filter to only show images by default */ +    filter = gtk_file_filter_new (); +    gtk_file_filter_set_name (filter, +                              /* Save dialog: Filter name to show only image files */ +                              _("Image Files")); +    gtk_file_filter_add_pixbuf_formats (filter); +    gtk_file_filter_add_mime_type (filter, "application/pdf"); +    gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (dialog), filter); +    filter = gtk_file_filter_new (); +    gtk_file_filter_set_name (filter, +                              /* Save dialog: Filter name to show all files */ +                              _("All Files")); +    gtk_file_filter_add_pattern (filter, "*"); +    gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (dialog), filter); + +    expander = gtk_expander_new_with_mnemonic (/* */ +                                 _("Select File _Type")); +    gtk_expander_set_spacing (GTK_EXPANDER (expander), 5); +    gtk_file_chooser_set_extra_widget (GTK_FILE_CHOOSER (dialog), expander); +   +    extension = strstr (ui->priv->default_file_name, "."); +    if (!extension) +        extension = ""; + +    file_type_store = gtk_list_store_new (2, G_TYPE_STRING, G_TYPE_STRING); +    for (i = 0; file_types[i].label; i++) { +        gtk_list_store_append (file_type_store, &iter); +        gtk_list_store_set (file_type_store, &iter, 0, file_types[i].label, 1, file_types[i].extension, -1); +    } + +    file_type_view = gtk_tree_view_new_with_model (GTK_TREE_MODEL (file_type_store)); +    gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (file_type_view), FALSE); +    gtk_tree_view_set_rules_hint (GTK_TREE_VIEW (file_type_view), TRUE); +    column = gtk_tree_view_column_new_with_attributes ("", +                                                       gtk_cell_renderer_text_new (), +                                                       "text", 0, NULL); +    gtk_tree_view_append_column (GTK_TREE_VIEW (file_type_view), column); +    gtk_container_add (GTK_CONTAINER (expander), file_type_view); + +    if (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (file_type_store), &iter)) { +        do { +            gchar *e; +            gtk_tree_model_get (GTK_TREE_MODEL (file_type_store), &iter, 1, &e, -1); +            if (strcmp (extension, e) == 0) +                gtk_tree_selection_select_iter (gtk_tree_view_get_selection (GTK_TREE_VIEW (file_type_view)), &iter); +            g_free (e); +        } while (gtk_tree_model_iter_next (GTK_TREE_MODEL (file_type_store), &iter)); +    } +    g_signal_connect (gtk_tree_view_get_selection (GTK_TREE_VIEW (file_type_view)), +                      "changed", +                      G_CALLBACK (on_file_type_changed), +                      dialog); + +    gtk_widget_show_all (expander); + +    response = gtk_dialog_run (GTK_DIALOG (dialog)); + +    if (response == GTK_RESPONSE_ACCEPT) +        uri = gtk_file_chooser_get_uri (GTK_FILE_CHOOSER (dialog)); + +    gconf_client_set_string (ui->priv->client, GCONF_DIR "/save_directory", +                             gtk_file_chooser_get_current_folder (GTK_FILE_CHOOSER (dialog)), +                             NULL); + +    gtk_widget_destroy (dialog); + +    return uri; +} + + +static gboolean +save_document (SimpleScan *ui, gboolean force_choose_location) +{ +    gboolean result; +    gchar *uri, *uri_lower; +    GError *error = NULL; +    GFile *file; +   +    if (ui->priv->book_uri && !force_choose_location) +        uri = g_strdup (ui->priv->book_uri); +    else +        uri = choose_file_location (ui); +    if (!uri) +        return FALSE; + +    file = g_file_new_for_uri (uri); + +    g_debug ("Saving to '%s'", uri); + +    uri_lower = g_utf8_strdown (uri, -1); +    if (g_str_has_suffix (uri_lower, ".pdf")) +        result = book_save (ui->priv->book, "pdf", file, &error); +    else if (g_str_has_suffix (uri_lower, ".ps")) +        result = book_save (ui->priv->book, "ps", file, &error); +    else if (g_str_has_suffix (uri_lower, ".png")) +        result = book_save (ui->priv->book, "png", file, &error); +    else if (g_str_has_suffix (uri_lower, ".tif") || g_str_has_suffix (uri_lower, ".tiff")) +        result = book_save (ui->priv->book, "tiff", file, &error); +    else +        result = book_save (ui->priv->book, "jpeg", file, &error); + +    g_free (uri_lower); + +    if (result) { +        g_free (ui->priv->book_uri); +        ui->priv->book_uri = uri; +        book_set_needs_saving (ui->priv->book, FALSE); +    } +    else { +        g_free (uri); + +        g_warning ("Error saving file: %s", error->message); +        ui_show_error (ui, +                       /* Title of error dialog when save failed */ +                       _("Failed to save file"), +                       error->message, +                       FALSE); +        g_clear_error (&error); +    } + +    g_object_unref (file); + +    return result; +} + + +static gboolean +prompt_to_save (SimpleScan *ui, const gchar *title, const gchar *discard_label) +{ +    GtkWidget *dialog; +    gint response; + +    if (!book_get_needs_saving (ui->priv->book)) +        return TRUE; + +    dialog = gtk_message_dialog_new (GTK_WINDOW (ui->priv->window), +                                     GTK_DIALOG_MODAL, +                                     GTK_MESSAGE_WARNING, +                                     GTK_BUTTONS_NONE, +                                     "%s", title); +    gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog), "%s", +                                              /* Text in dialog warning when a document is about to be lost*/ +                                              _("If you don't save, changes will be permanently lost.")); +    gtk_dialog_add_button (GTK_DIALOG (dialog), discard_label, GTK_RESPONSE_NO); +    gtk_dialog_add_button (GTK_DIALOG (dialog), GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL); +    gtk_dialog_add_button (GTK_DIALOG (dialog), GTK_STOCK_SAVE, GTK_RESPONSE_YES); + +    response = gtk_dialog_run (GTK_DIALOG (dialog)); +    gtk_widget_destroy (dialog); +   +    switch (response) { +    case GTK_RESPONSE_YES: +        if (save_document (ui, FALSE)) +            return TRUE; +        else +            return FALSE; +    case GTK_RESPONSE_CANCEL: +        return FALSE; +    case GTK_RESPONSE_NO:       +    default: +        return TRUE; +    } +} + + +static void +clear_document (SimpleScan *ui) +{ +    book_clear (ui->priv->book); +    add_default_page (ui); +    g_free (ui->priv->book_uri); +    ui->priv->book_uri = NULL; +    book_set_needs_saving (ui->priv->book, FALSE); +    gtk_widget_set_sensitive (ui->priv->save_as_menuitem, FALSE); +} + +  void new_button_clicked_cb (GtkWidget *widget, SimpleScan *ui);  G_MODULE_EXPORT  void  new_button_clicked_cb (GtkWidget *widget, SimpleScan *ui)  { -    book_clear (ui->priv->book); -    add_default_page (ui); +    if (!prompt_to_save (ui, +                         /* Text in dialog warning when a document is about to be lost */ +                         _("Save current document?"), +                         /* Button in dialog to create new document and discard unsaved document */ +                         _("Discard Changes"))) +        return; + +    clear_document (ui);  } @@ -633,11 +944,10 @@ show_page_cb (BookView *view, Page *page, SimpleScan *ui)      g_object_unref (file);      if (error) { -        ui_show_error (ui, -                       /* Error message display when unable to preview image */ -                       _("Unable to open image preview application"), -                       error->message, -                       FALSE); +        show_error_dialog (ui, +                           /* Error message display when unable to preview image */ +                           _("Unable to open image preview application"), +                           error->message);          g_clear_error (&error);      }  } @@ -835,154 +1145,21 @@ page_delete_menuitem_activate_cb (GtkWidget *widget, SimpleScan *ui)  } -static void -on_file_type_changed (GtkTreeSelection *selection, GtkWidget *dialog) -{ -    GtkTreeModel *model; -    GtkTreeIter iter; -    gchar *path, *filename, *extension, *new_filename; - -    if (!gtk_tree_selection_get_selected (selection, &model, &iter)) -        return; - -    gtk_tree_model_get (model, &iter, 1, &extension, -1); -    path = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog)); -    filename = g_path_get_basename (path); - -    /* Replace extension */ -    if (g_strrstr (filename, ".")) -        new_filename = g_strdup_printf ("%.*s%s", (int)(g_strrstr (filename, ".") - filename), filename, extension); -    else -        new_filename = g_strdup_printf ("%s%s", filename, extension); -    gtk_file_chooser_set_current_name (GTK_FILE_CHOOSER (dialog), new_filename); - -    g_free (path); -    g_free (filename); -    g_free (new_filename); -    g_free (extension); -} - -  void save_file_button_clicked_cb (GtkWidget *widget, SimpleScan *ui);  G_MODULE_EXPORT  void  save_file_button_clicked_cb (GtkWidget *widget, SimpleScan *ui)  { -    GtkWidget *dialog; -    gint response; -    GtkFileFilter *filter; -    GtkWidget *expander, *file_type_view; -    GtkListStore *file_type_store; -    GtkTreeIter iter; -    GtkTreeViewColumn *column; -    const gchar *extension; -    gchar *directory; -    gint i; - -    struct -    { -        gchar *label, *extension; -    } file_types[] = -    { -        /* Save dialog: Label for saving in PDF format */ -        { _("PDF (multi-page document)"), ".pdf" }, -        /* Save dialog: Label for saving in JPEG format */ -        { _("JPEG (compressed)"), ".jpg" }, -        /* Save dialog: Label for saving in PNG format */ -        { _("PNG (lossless)"), ".png" }, -        { NULL, NULL } -    }; - -    /* Get directory to save to */ -    directory = gconf_client_get_string (ui->priv->client, GCONF_DIR "/save_directory", NULL); -    if (!directory || directory[0] == '\0') { -        g_free (directory); -        directory = g_strdup (g_get_user_special_dir (G_USER_DIRECTORY_DOCUMENTS)); -    } - -    dialog = gtk_file_chooser_dialog_new (/* Save dialog: Dialog title */ -                                          _("Save As..."), -                                          GTK_WINDOW (ui->priv->window), -                                          GTK_FILE_CHOOSER_ACTION_SAVE, -                                          GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, -                                          GTK_STOCK_SAVE, GTK_RESPONSE_ACCEPT, -                                          NULL); -    gtk_file_chooser_set_do_overwrite_confirmation (GTK_FILE_CHOOSER (dialog), TRUE); -    gtk_file_chooser_set_local_only (GTK_FILE_CHOOSER (dialog), FALSE); -    gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (dialog), directory); -    gtk_file_chooser_set_current_name (GTK_FILE_CHOOSER (dialog), ui->priv->default_file_name); -    g_free (directory); - -    /* Filter to only show images by default */ -    filter = gtk_file_filter_new (); -    gtk_file_filter_set_name (filter, -                              /* Save dialog: Filter name to show only image files */ -                              _("Image Files")); -    gtk_file_filter_add_pixbuf_formats (filter); -    gtk_file_filter_add_mime_type (filter, "application/pdf"); -    gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (dialog), filter); -    filter = gtk_file_filter_new (); -    gtk_file_filter_set_name (filter, -                              /* Save dialog: Filter name to show all files */ -                              _("All Files")); -    gtk_file_filter_add_pattern (filter, "*"); -    gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (dialog), filter); - -    expander = gtk_expander_new_with_mnemonic (/* */ -                                 _("Select File _Type")); -    gtk_expander_set_spacing (GTK_EXPANDER (expander), 5); -    gtk_file_chooser_set_extra_widget (GTK_FILE_CHOOSER (dialog), expander); -   -    extension = strstr (ui->priv->default_file_name, "."); -    if (!extension) -        extension = ""; - -    file_type_store = gtk_list_store_new (2, G_TYPE_STRING, G_TYPE_STRING); -    for (i = 0; file_types[i].label; i++) { -        gtk_list_store_append (file_type_store, &iter); -        gtk_list_store_set (file_type_store, &iter, 0, file_types[i].label, 1, file_types[i].extension, -1); -    } - -    file_type_view = gtk_tree_view_new_with_model (GTK_TREE_MODEL (file_type_store)); -    gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (file_type_view), FALSE); -    gtk_tree_view_set_rules_hint (GTK_TREE_VIEW (file_type_view), TRUE); -    column = gtk_tree_view_column_new_with_attributes ("", -                                                       gtk_cell_renderer_text_new (), -                                                       "text", 0, NULL); -    gtk_tree_view_append_column (GTK_TREE_VIEW (file_type_view), column); -    gtk_container_add (GTK_CONTAINER (expander), file_type_view); - -    if (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (file_type_store), &iter)) { -        do { -            gchar *e; -            gtk_tree_model_get (GTK_TREE_MODEL (file_type_store), &iter, 1, &e, -1); -            if (strcmp (extension, e) == 0) -                gtk_tree_selection_select_iter (gtk_tree_view_get_selection (GTK_TREE_VIEW (file_type_view)), &iter); -            g_free (e); -        } while (gtk_tree_model_iter_next (GTK_TREE_MODEL (file_type_store), &iter)); -    } -    g_signal_connect (gtk_tree_view_get_selection (GTK_TREE_VIEW (file_type_view)), -                      "changed", -                      G_CALLBACK (on_file_type_changed), -                      dialog); - -    gtk_widget_show_all (expander); - -    response = gtk_dialog_run (GTK_DIALOG (dialog)); -    if (response == GTK_RESPONSE_ACCEPT) { -        gchar *uri; - -        uri = gtk_file_chooser_get_uri (GTK_FILE_CHOOSER (dialog)); -        g_signal_emit (G_OBJECT (ui), signals[SAVE], 0, uri); +    save_document (ui, FALSE); +} -        g_free (uri); -    } -    gconf_client_set_string (ui->priv->client, GCONF_DIR "/save_directory", -                             gtk_file_chooser_get_current_folder (GTK_FILE_CHOOSER (dialog)), -                             NULL); -   -    gtk_widget_destroy (dialog); +void save_as_file_button_clicked_cb (GtkWidget *widget, SimpleScan *ui); +G_MODULE_EXPORT +void +save_as_file_button_clicked_cb (GtkWidget *widget, SimpleScan *ui) +{ +    save_document (ui, TRUE);  } @@ -1063,11 +1240,10 @@ help_contents_menuitem_activate_cb (GtkWidget *widget, SimpleScan *ui)      if (error)      { -        ui_show_error (ui, -                       /* Error message displayed when unable to launch help browser */ -                       _("Unable to open help file"), -                       error->message, -                      FALSE); +        show_error_dialog (ui, +                           /* Error message displayed when unable to launch help browser */ +                           _("Unable to open help file"), +                           error->message);          g_clear_error (&error);      }  } @@ -1116,14 +1292,19 @@ about_menuitem_activate_cb (GtkWidget *widget, SimpleScan *ui)  } -static void +static gboolean  quit (SimpleScan *ui)  {      char *device;      gint paper_width = 0, paper_height = 0;      gint i; -    // FIXME: Warn if document with unsaved changes +    if (!prompt_to_save (ui, +                         /* Text in dialog warning when a document is about to be lost */ +                         _("Save document before quitting?"), +                         /* Button in dialog to quit and discard unsaved document */ +                         _("Quit without Saving"))) +        return FALSE;      device = get_selected_device (ui);      if (device) { @@ -1151,6 +1332,8 @@ quit (SimpleScan *ui)      gconf_client_set_int (ui->priv->client, GCONF_DIR "/page_dpi", ui->priv->default_page_dpi, NULL);      g_signal_emit (G_OBJECT (ui), signals[QUIT], 0); + +    return TRUE;  } @@ -1177,6 +1360,24 @@ simple_scan_window_configure_event_cb (GtkWidget *widget, GdkEventConfigure *eve  } +static void +info_bar_response_cb (GtkWidget *widget, gint response_id, SimpleScan *ui) +{ +    if (response_id == 1) { +        gtk_widget_grab_focus (ui->priv->device_combo); +        gtk_window_present (GTK_WINDOW (ui->priv->preferences_dialog)); +    } +    else { +        ui->priv->have_error = FALSE; +        g_free (ui->priv->error_title); +        ui->priv->error_title = NULL; +        g_free (ui->priv->error_text); +        ui->priv->error_text = NULL; +        update_info_bar (ui);       +    } +} + +  gboolean simple_scan_window_window_state_event_cb (GtkWidget *widget, GdkEventWindowState *event, SimpleScan *ui);  G_MODULE_EXPORT  gboolean @@ -1193,8 +1394,7 @@ G_MODULE_EXPORT  gboolean  window_delete_event_cb (GtkWidget *widget, GdkEvent *event, SimpleScan *ui)  { -    quit (ui); -    return TRUE; +    return !quit (ui);  } @@ -1290,10 +1490,21 @@ set_dpi_combo (GtkWidget *combo, gint default_dpi, gint current_dpi)  static void +needs_saving_cb (Book *book, GParamSpec *param, SimpleScan *ui) +{ +    gtk_widget_set_sensitive (ui->priv->save_menuitem, book_get_needs_saving (book)); +    gtk_widget_set_sensitive (ui->priv->save_toolbutton, book_get_needs_saving (book)); +    if (book_get_needs_saving (book)) +        gtk_widget_set_sensitive (ui->priv->save_as_menuitem, TRUE); +} + + +static void  ui_load (SimpleScan *ui)  {      GtkBuilder *builder;      GError *error = NULL; +    GtkWidget *hbox;      GtkCellRenderer *renderer;      gchar *device, *document_type, *scan_direction, *page_side;      gint dpi, paper_width, paper_height; @@ -1306,12 +1517,11 @@ ui_load (SimpleScan *ui)      gtk_builder_add_from_file (builder, UI_DIR "simple-scan.ui", &error);      if (error) {          g_critical ("Unable to load UI: %s\n", error->message); -        ui_show_error (ui, -                       /* Title of dialog when cannot load required files */ -                       _("Files missing"), -                       /* Description in dialog when cannot load required files */ -                       _("Please check your installation"), -                       FALSE); +        show_error_dialog (ui, +                           /* Title of dialog when cannot load required files */ +                           _("Files missing"), +                           /* Description in dialog when cannot load required files */ +                           _("Please check your installation"));          exit (1);      }      gtk_builder_connect_signals (builder, ui); @@ -1320,6 +1530,9 @@ ui_load (SimpleScan *ui)      ui->priv->main_vbox = GTK_WIDGET (gtk_builder_get_object (builder, "main_vbox"));      ui->priv->page_delete_menuitem = GTK_WIDGET (gtk_builder_get_object (builder, "page_delete_menuitem"));      ui->priv->crop_rotate_menuitem = GTK_WIDGET (gtk_builder_get_object (builder, "crop_rotate_menuitem")); +    ui->priv->save_menuitem = GTK_WIDGET (gtk_builder_get_object (builder, "save_menuitem")); +    ui->priv->save_as_menuitem = GTK_WIDGET (gtk_builder_get_object (builder, "save_as_menuitem")); +    ui->priv->save_toolbutton = GTK_WIDGET (gtk_builder_get_object (builder, "save_toolbutton"));      ui->priv->stop_menuitem = GTK_WIDGET (gtk_builder_get_object (builder, "stop_scan_menuitem"));      ui->priv->stop_toolbutton = GTK_WIDGET (gtk_builder_get_object (builder, "stop_toolbutton")); @@ -1345,6 +1558,28 @@ ui_load (SimpleScan *ui)      ui->priv->paper_size_combo = GTK_WIDGET (gtk_builder_get_object (builder, "paper_size_combo"));      ui->priv->paper_size_model = gtk_combo_box_get_model (GTK_COMBO_BOX (ui->priv->paper_size_combo)); +    /* Add InfoBar (not supported in Glade) */ +    ui->priv->info_bar = gtk_info_bar_new (); +    g_signal_connect (ui->priv->info_bar, "response", G_CALLBACK (info_bar_response_cb), ui);   +    gtk_box_pack_start (GTK_BOX(ui->priv->main_vbox), ui->priv->info_bar, FALSE, TRUE, 0); +    hbox = gtk_hbox_new (FALSE, 12); +    gtk_container_add (GTK_CONTAINER (gtk_info_bar_get_content_area (GTK_INFO_BAR (ui->priv->info_bar))), hbox); +    gtk_widget_show (hbox); + +    ui->priv->info_bar_image = gtk_image_new_from_stock (GTK_STOCK_DIALOG_WARNING, GTK_ICON_SIZE_DIALOG); +    gtk_box_pack_start (GTK_BOX(hbox), ui->priv->info_bar_image, FALSE, TRUE, 0); +    gtk_widget_show (ui->priv->info_bar_image); + +    ui->priv->info_bar_label = gtk_label_new (NULL); +    gtk_misc_set_alignment (GTK_MISC (ui->priv->info_bar_label), 0.0, 0.5); +    gtk_box_pack_start (GTK_BOX(hbox), ui->priv->info_bar_label, TRUE, TRUE, 0); +    gtk_widget_show (ui->priv->info_bar_label); + +    ui->priv->info_bar_close_button = gtk_info_bar_add_button (GTK_INFO_BAR (ui->priv->info_bar), GTK_STOCK_CLOSE, GTK_RESPONSE_CLOSE); +    ui->priv->info_bar_change_scanner_button = gtk_info_bar_add_button (GTK_INFO_BAR (ui->priv->info_bar), +                                                                        /* Button in error infobar to open preferences dialog and change scanner */ +                                                                        _("Change _Scanner"), 1); +      GtkTreeIter iter;      gtk_list_store_append (GTK_LIST_STORE (ui->priv->paper_size_model), &iter);      gtk_list_store_set (GTK_LIST_STORE (ui->priv->paper_size_model), &iter, 0, 0, 1, 0, 2, @@ -1451,6 +1686,8 @@ ui_load (SimpleScan *ui)      if (book_get_n_pages (ui->priv->book) == 0)          add_default_page (ui); +    book_set_needs_saving (ui->priv->book, FALSE); +    g_signal_connect (ui->priv->book, "notify::needs-saving", G_CALLBACK (needs_saving_cb), ui);  } @@ -1495,28 +1732,13 @@ ui_set_scanning (SimpleScan *ui, gboolean scanning)  void  ui_show_error (SimpleScan *ui, const gchar *error_title, const gchar *error_text, gboolean change_scanner_hint)  { -    GtkWidget *dialog; - -    dialog = gtk_message_dialog_new (GTK_WINDOW (ui->priv->window), -                                     GTK_DIALOG_MODAL, -                                     GTK_MESSAGE_WARNING, -                                     GTK_BUTTONS_NONE, -                                     "%s", error_title); -    if (change_scanner_hint) -        gtk_dialog_add_button (GTK_DIALOG (dialog), -                               /* Button in error dialog to open prefereces dialog and change scanner */ -                               _("Change _Scanner"), -                               1); -    gtk_dialog_add_button (GTK_DIALOG (dialog), GTK_STOCK_CLOSE, 0); -    gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog), -                                              "%s", error_text); - -    if (gtk_dialog_run (GTK_DIALOG (dialog)) == 1) { -        gtk_widget_grab_focus (ui->priv->device_combo); -        gtk_window_present (GTK_WINDOW (ui->priv->preferences_dialog));         -    } - -    gtk_widget_destroy (dialog); +    ui->priv->have_error = TRUE; +    g_free (ui->priv->error_title); +    ui->priv->error_title = g_strdup (error_title); +    g_free (ui->priv->error_text); +    ui->priv->error_text = g_strdup (error_text); +    ui->priv->error_change_scanner_hint = change_scanner_hint; +    update_info_bar (ui);  } @@ -1606,14 +1828,6 @@ ui_class_init (SimpleScanClass *klass)                        NULL, NULL,                        g_cclosure_marshal_VOID__VOID,                        G_TYPE_NONE, 0); -    signals[SAVE] = -        g_signal_new ("save", -                      G_TYPE_FROM_CLASS (klass), -                      G_SIGNAL_RUN_LAST, -                      G_STRUCT_OFFSET (SimpleScanClass, save), -                      NULL, NULL, -                      g_cclosure_marshal_VOID__STRING, -                      G_TYPE_NONE, 1, G_TYPE_STRING);      signals[EMAIL] =          g_signal_new ("email",                        G_TYPE_FROM_CLASS (klass), @@ -1650,5 +1864,5 @@ ui_init (SimpleScan *ui)      ui->priv->document_hint = g_strdup ("photo");      ui->priv->default_file_name = g_strdup (_("Scanned Document.pdf"));      ui->priv->scanning = FALSE; -    ui_load (ui);    +    ui_load (ui);  } @@ -36,7 +36,6 @@ typedef struct      void (*start_scan) (SimpleScan *ui, ScanOptions *options);      void (*stop_scan) (SimpleScan *ui); -    void (*save) (SimpleScan *ui, const gchar *format);      void (*email) (SimpleScan *ui, const gchar *profile);      void (*quit) (SimpleScan *ui);  } SimpleScanClass; | 
