summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJulien BLACHE <jblache@debian.org>2006-01-10 21:58:08 +0100
committerMattia Rizzolo <mattia@mapreri.org>2014-10-03 14:05:22 +0000
commita1871913efc67d71e7b355a8a03655cbf12ab07f (patch)
treecfe538674b55d1d0325e83bbbe1a2703bd2262b9 /src
parentab2ece358cc58b7a7d1671a72d62c2cafe8811bb (diff)
parent7fad909266d49203537a28e6acc5d96b14bf4e7f (diff)
Imported Debian patch 0.99-1debian/0.99-1
Diffstat (limited to 'src')
-rw-r--r--src/.xsane-front-gtk.h.swpbin16384 -> 0 bytes
-rw-r--r--src/Makefile.in83
-rw-r--r--src/Makefile.in.orig46
-rw-r--r--src/xsane-back-gtk.c27
-rw-r--r--src/xsane-batch-scan.c20
-rw-r--r--src/xsane-batch-scan.h8
-rw-r--r--src/xsane-device-preferences.c140
-rw-r--r--src/xsane-email-project.c1912
-rw-r--r--src/xsane-email-project.h61
-rw-r--r--src/xsane-fax-project.c1312
-rw-r--r--src/xsane-fax-project.h78
-rw-r--r--src/xsane-front-gtk.c129
-rw-r--r--src/xsane-front-gtk.h6
-rw-r--r--src/xsane-gamma.c8
-rw-r--r--src/xsane-icons.c140
-rw-r--r--src/xsane-icons.h8
-rw-r--r--src/xsane-multipage-project.c1087
-rw-r--r--src/xsane-multipage-project.h58
-rw-r--r--src/xsane-preferences.c172
-rw-r--r--src/xsane-preferences.h35
-rw-r--r--src/xsane-preview.c59
-rw-r--r--src/xsane-save.c962
-rw-r--r--src/xsane-save.c.orig5801
-rw-r--r--src/xsane-save.h85
-rw-r--r--src/xsane-scan.c200
-rw-r--r--src/xsane-scan.h2
-rw-r--r--src/xsane-setup.c502
-rw-r--r--src/xsane-setup.h4
-rw-r--r--src/xsane-text.h146
-rw-r--r--src/xsane-viewer.c64
-rw-r--r--src/xsane-viewer.h5
-rw-r--r--src/xsane.c3882
-rw-r--r--src/xsane.h238
33 files changed, 12784 insertions, 4496 deletions
diff --git a/src/.xsane-front-gtk.h.swp b/src/.xsane-front-gtk.h.swp
deleted file mode 100644
index d971345..0000000
--- a/src/.xsane-front-gtk.h.swp
+++ /dev/null
Binary files differ
diff --git a/src/Makefile.in b/src/Makefile.in
index 8df620f..5debbbb 100644
--- a/src/Makefile.in
+++ b/src/Makefile.in
@@ -49,6 +49,9 @@ LIBLIB = ../lib/liblib.a
XSANE_OBJS = xsane-back-gtk.o xsane-front-gtk.o xsane-gamma.o \
xsane-preview.o xsane-viewer.o \
+ xsane-fax-project.o \
+ xsane-email-project.o \
+ xsane-multipage-project.o \
xsane-rc-io.o xsane-device-preferences.o xsane-batch-scan.o \
xsane-preferences.o xsane-setup.o xsane-save.o xsane-scan.o \
xsane-icons.o xsane.o @XSANE_ICON@
@@ -60,37 +63,37 @@ XSANE_OBJS = xsane-back-gtk.o xsane-front-gtk.o xsane-gamma.o \
all: $(PROGRAMS)
install: $(PROGRAMS)
- $(MKINSTALLDIRS) $(bindir) $(sbindir) $(datadir) $(sanedatadir) $(xsanedocdir) $(sanedatadir)/xsane
+ $(MKINSTALLDIRS) $(DESTDIR)$(bindir) $(DESTDIR)$(sbindir) $(DESTDIR)$(datadir) $(DESTDIR)$(sanedatadir) $(DESTDIR)$(xsanedocdir) $(DESTDIR)$(sanedatadir)/xsane
@for program in $(BINPROGS); do \
- $(INSTALL_PROGRAM) $${program} $(bindir)/$${program}; \
+ $(INSTALL_PROGRAM) $${program} $(DESTDIR)$(bindir)/$${program}; \
done
- $(INSTALL_DATA) $(srcdir)/xsane-style.rc $(sanedatadir)/xsane/xsane-style.rc
- $(INSTALL_DATA) $(srcdir)/xsane-startimage.pnm $(sanedatadir)/xsane/xsane-startimage.pnm
- $(INSTALL_DATA) $(srcdir)/xsane-calibration.pnm $(sanedatadir)/xsane/xsane-calibration.pnm
- $(INSTALL_DATA) $(srcdir)/xsane-logo.xpm $(sanedatadir)/xsane/xsane-logo.xpm
- $(INSTALL_DATA) $(srcdir)/xsane-gpl.txt $(sanedatadir)/xsane/xsane-gpl.txt
- $(INSTALL_DATA) $(srcdir)/xsane-eula.txt $(sanedatadir)/xsane/xsane-eula.txt
+ $(INSTALL_DATA) $(srcdir)/xsane-style.rc $(DESTDIR)$(sanedatadir)/xsane/xsane-style.rc
+ $(INSTALL_DATA) $(srcdir)/xsane-startimage.pnm $(DESTDIR)$(sanedatadir)/xsane/xsane-startimage.pnm
+ $(INSTALL_DATA) $(srcdir)/xsane-calibration.pnm $(DESTDIR)$(sanedatadir)/xsane/xsane-calibration.pnm
+ $(INSTALL_DATA) $(srcdir)/xsane-logo.xpm $(DESTDIR)$(sanedatadir)/xsane/xsane-logo.xpm
+ $(INSTALL_DATA) $(srcdir)/xsane-gpl.txt $(DESTDIR)$(sanedatadir)/xsane/xsane-gpl.txt
+ $(INSTALL_DATA) $(srcdir)/xsane-eula.txt $(DESTDIR)$(sanedatadir)/xsane/xsane-eula.txt
@for logo in *-logo.xpm; do \
- echo installing $(sanedatadir)/xsane/$${logo}; \
- $(INSTALL_DATA) $(srcdir)/$${logo} $(sanedatadir)/xsane/$${logo}; \
+ echo installing $(DESTDIR)$(sanedatadir)/xsane/$${logo}; \
+ $(INSTALL_DATA) $(srcdir)/$${logo} $(DESTDIR)$(sanedatadir)/xsane/$${logo}; \
done
uninstall:
@for program in $(BINPROGS); do \
- echo uninstalling $(bindir)/$${program}...; \
- rm -f $(bindir)/$${program}; \
+ echo uninstalling $(DESTDIR)$(bindir)/$${program}...; \
+ rm -f $(DESTDIR)$(bindir)/$${program}; \
done
- echo uninstalling $(sanedatadir)/xsane/xsane-style.rc...
- rm -f $(sanedatadir)/xsane/xsane-style.rc
- echo uninstalling $(sanedatadir)/xsane/xsane-startimage.pnm...
- rm -f $(sanedatadir)/xsane/xsane-startimage.pnm
- echo uninstalling $(sanedatadir)/xsane/xsane-calibration.pnm...
- rm -f $(sanedatadir)/xsane/xsane-calibration.pnm
- echo uninstalling $(sanedatadir)/xsane/xsane-logo.xpm...
- rm -f $(sanedatadir)/xsane/xsane-logo.xpm
+ echo uninstalling $(DESTDIR)$(sanedatadir)/xsane/xsane-style.rc...
+ rm -f $(DESTDIR)$(sanedatadir)/xsane/xsane-style.rc
+ echo uninstalling $(DESTDIR)$(sanedatadir)/xsane/xsane-startimage.pnm...
+ rm -f $(DESTDIR)$(sanedatadir)/xsane/xsane-startimage.pnm
+ echo uninstalling $(DESTDIR)$(sanedatadir)/xsane/xsane-calibration.pnm...
+ rm -f $(DESTDIR)$(sanedatadir)/xsane/xsane-calibration.pnm
+ echo uninstalling $(DESTDIR)$(sanedatadir)/xsane/xsane-logo.xpm...
+ rm -f $(DESTDIR)$(sanedatadir)/xsane/xsane-logo.xpm
@for logo in *-logo.xpm; do \
- echo uninstalling $(sanedatadir)/xsane/$${logo}; \
- rm -f $(sanedatadir)/xsane/$${logo}; \
+ echo uninstalling $(DESTDIR)$(sanedatadir)/xsane/$${logo}; \
+ rm -f $(DESTDIR)$(sanedatadir)/xsane/$${logo}; \
done
xsane: $(XSANE_OBJS) $(LIBLIB)
@@ -125,12 +128,17 @@ xsane.o: xsane-device-preferences.h
xsane.o: xsane-preferences.h
xsane.o: xsane-icons.h
xsane.o: xsane-batch-scan.h
+xsane.o: xsane-multipage-project.h
+xsane.o: xsane-fax-project.h
+xsane.o: xsane-email-project.h
+xsane.o: xsane-text.h
xsane-back-gtk.o: xsane.h
xsane-back-gtk.o: xsane-back-gtk.h
xsane-back-gtk.o: xsane-front-gtk.h
xsane-back-gtk.o: xsane-preferences.h
xsane-back-gtk.o: xsane-gamma.h
+xsane-back-gtk.o: xsane-text.h
xsane-front-gtk.o: xsane.h
xsane-front-gtk.o: xsane-back-gtk.h
@@ -139,6 +147,7 @@ xsane-front-gtk.o: xsane-preview.h
xsane-front-gtk.o: xsane-save.h
xsane-front-gtk.o: xsane-gamma.h
xsane-front-gtk.o: xsane-setup.h
+xsane-front-gtk.o: xsane-text.h
xsane-batch-scan.o: xsane.h
xsane-batch-scan.o: xsane-scan.h
@@ -148,6 +157,7 @@ xsane-batch-scan.o: xsane-front-gtk.h
xsane-batch-scan.o: xsane-rc-io.h
xsane-batch-scan.o: xsane-preview.h
xsane-batch-scan.o: xsane-gamma.h
+xsane-batch-scan.o: xsane-text.h
xsane-preview.o: xsane.h
xsane-preview.o: xsane-back-gtk.h
@@ -156,6 +166,7 @@ xsane-preview.o: xsane-batch-scan.h
xsane-preview.o: xsane-preview.h
xsane-preview.o: xsane-preferences.h
xsane-preview.o: xsane-gamma.h
+xsane-preview.o: xsane-text.h
xsane-preferecnes.o: xsane.h
xsane-preferecnes.o: xsane-preferences.h
@@ -183,6 +194,8 @@ xsane-scan.o: xsane-viewer.h
xsane-scan.o: xsane-save.h
xsane-scan.o: xsane-gamma.h
xsane-scan.o: xsane-setup.h
+xsane-scan.o: xsane-email-project.h
+xsane-scan.o: xsane-text.h
xsane-gamma.o: xsane.h
xsane-gamma.o: xsane-back-gtk.h
@@ -190,6 +203,7 @@ xsane-gamma.o: xsane-front-gtk.h
xsane-gamma.o: xsane-preferences.h
xsane-gamma.o: xsane-preview.h
xsane-gamma.o: xsane-save.h
+xsane-gamma.o: xsane-text.h
xsane-setup.o: xsane.h
xsane-setup.o: xsane-back-gtk.h
@@ -200,6 +214,7 @@ xsane-setup.o: xsane-preview.h
xsane-setup.o: xsane-save.h
xsane-setup.o: xsane-gamma.h
xsane-setup.o: xsane-batch-scan.h
+xsane-setup.o: xsane-text.h
xsane-viewer.o: xsane.h
xsane-viewer.o: xsane-back-gtk.h
@@ -209,6 +224,26 @@ xsane-viewer.o: xsane-viewer.h
xsane-viewer.o: xsane-gamma.h
xsane-viewer.o: xsane-icons.h
xsane-viewer.o: xsane-save.h
-
-
+xsane-viewer.o: xsane-text.h
+
+xsane-multipage-project.o: xsane.h
+xsane-multipage-project.o: xsane-back-gtk.h
+xsane-multipage-project.o: xsane-front-gtk.h
+xsane-multipage-project.o: xsane-preferences.h
+xsane-multipage-project.o: xsane-multipage-project.h
+xsane-multipage-project.o: xsane-text.h
+
+xsane-fax-project.o: xsane.h
+xsane-fax-project.o: xsane-back-gtk.h
+xsane-fax-project.o: xsane-front-gtk.h
+xsane-fax-project.o: xsane-preferences.h
+xsane-fax-project.o: xsane-fax-project.h
+xsane-fax-project.o: xsane-text.h
+
+xsane-email-project.o: xsane.h
+xsane-email-project.o: xsane-back-gtk.h
+xsane-email-project.o: xsane-front-gtk.h
+xsane-email-project.o: xsane-preferences.h
+xsane-email-project.o: xsane-email-project.h
+xsane-email-project.o: xsane-text.h
diff --git a/src/Makefile.in.orig b/src/Makefile.in.orig
index b171027..a0b0244 100644
--- a/src/Makefile.in.orig
+++ b/src/Makefile.in.orig
@@ -31,8 +31,8 @@ INSTALL_DATA = @INSTALL_DATA@
CC = @CC@
INCLUDES = -I. -I$(srcdir) -I$(top_builddir)/include -I$(top_srcdir)/include @INCLUDES@
-DEFS = @DEFS@ -DLOCALEDIR=$(datadir)/locale
-CPPFLAGS = @CPPFLAGS@ -DPATH_XSANE_DOC_DIR=\$(xsanedocdir) -DPATH_SANE_DATA_DIR=\$(sanedatadir)
+DEFS = @DEFS@ -DLOCALEDIR=$(datadir)/locale -DSANELOCALEDIR=$(sane_prefix)/share/locale
+CPPFLAGS = @CPPFLAGS@ -DPATH_XSANE_DOC_DIR=$(xsanedocdir) -DPATH_SANE_DATA_DIR=$(sanedatadir)
CFLAGS = @CFLAGS@ @SANE_CFLAGS@ @GIMP_CFLAGS@ @GTK_CFLAGS@
LDFLAGS = @LDFLAGS@ @SANE_LDFLAGS@
LIBS = @SANE_LIBS@ @GIMP_LIBS@ @GTK_LIBS@ @INTLLIBS@ @LIBS@
@@ -49,9 +49,12 @@ LIBLIB = ../lib/liblib.a
XSANE_OBJS = xsane-back-gtk.o xsane-front-gtk.o xsane-gamma.o \
xsane-preview.o xsane-viewer.o \
+ xsane-fax-project.o \
+ xsane-email-project.o \
+ xsane-multipage-project.o \
xsane-rc-io.o xsane-device-preferences.o xsane-batch-scan.o \
xsane-preferences.o xsane-setup.o xsane-save.o xsane-scan.o \
- xsane-icons.o xsane.o
+ xsane-icons.o xsane.o @XSANE_ICON@
.c.o:
@@ -97,6 +100,8 @@ xsane: $(XSANE_OBJS) $(LIBLIB)
$(LINK) $(XSANE_OBJS) \
$(LIBLIB) $(LIBS) $(SANE_LIBS)
+xsane-icon.opc: xsane-icon.rc xsane.ico
+ windres -i xsane-icon.rc -o xsane-icon.opc
clean:
rm -f *.o *~ .*~ *.bak
@@ -123,6 +128,10 @@ xsane.o: xsane-device-preferences.h
xsane.o: xsane-preferences.h
xsane.o: xsane-icons.h
xsane.o: xsane-batch-scan.h
+xsane.o: xsane-multipage-project.h
+xsane.o: xsane-fax-project.h
+xsane.o: xsane-email-project.h
+xsane.o: xsane-text.h
xsane-back-gtk.o: xsane.h
xsane-back-gtk.o: xsane-back-gtk.h
@@ -146,6 +155,7 @@ xsane-batch-scan.o: xsane-front-gtk.h
xsane-batch-scan.o: xsane-rc-io.h
xsane-batch-scan.o: xsane-preview.h
xsane-batch-scan.o: xsane-gamma.h
+xsane-batch-scan.o: xsane-text.h
xsane-preview.o: xsane.h
xsane-preview.o: xsane-back-gtk.h
@@ -154,6 +164,7 @@ xsane-preview.o: xsane-batch-scan.h
xsane-preview.o: xsane-preview.h
xsane-preview.o: xsane-preferences.h
xsane-preview.o: xsane-gamma.h
+xsane-preview.o: xsane-text.h
xsane-preferecnes.o: xsane.h
xsane-preferecnes.o: xsane-preferences.h
@@ -181,6 +192,8 @@ xsane-scan.o: xsane-viewer.h
xsane-scan.o: xsane-save.h
xsane-scan.o: xsane-gamma.h
xsane-scan.o: xsane-setup.h
+xsane-scan.o: xsane-email-project.h
+xsane-scan.o: xsane-text.h
xsane-gamma.o: xsane.h
xsane-gamma.o: xsane-back-gtk.h
@@ -188,6 +201,7 @@ xsane-gamma.o: xsane-front-gtk.h
xsane-gamma.o: xsane-preferences.h
xsane-gamma.o: xsane-preview.h
xsane-gamma.o: xsane-save.h
+xsane-gamma.o: xsane-text.h
xsane-setup.o: xsane.h
xsane-setup.o: xsane-back-gtk.h
@@ -198,6 +212,7 @@ xsane-setup.o: xsane-preview.h
xsane-setup.o: xsane-save.h
xsane-setup.o: xsane-gamma.h
xsane-setup.o: xsane-batch-scan.h
+xsane-setup.o: xsane-text.h
xsane-viewer.o: xsane.h
xsane-viewer.o: xsane-back-gtk.h
@@ -207,7 +222,26 @@ xsane-viewer.o: xsane-viewer.h
xsane-viewer.o: xsane-gamma.h
xsane-viewer.o: xsane-icons.h
xsane-viewer.o: xsane-save.h
-
-
-
+xsane-viewer.o: xsane-text.h
+
+xsane-multipage-project.o: xsane.h
+xsane-multipage-project.o: xsane-back-gtk.h
+xsane-multipage-project.o: xsane-front-gtk.h
+xsane-multipage-project.o: xsane-preferences.h
+xsane-multipage-project.o: xsane-multipage-project.h
+xsane-multipage-project.o: xsane-text.h
+
+xsane-fax-project.o: xsane.h
+xsane-fax-project.o: xsane-back-gtk.h
+xsane-fax-project.o: xsane-front-gtk.h
+xsane-fax-project.o: xsane-preferences.h
+xsane-fax-project.o: xsane-fax-project.h
+xsane-fax-project.o: xsane-text.h
+
+xsane-email-project.o: xsane.h
+xsane-email-project.o: xsane-back-gtk.h
+xsane-email-project.o: xsane-front-gtk.h
+xsane-email-project.o: xsane-preferences.h
+xsane-email-project.o: xsane-email-project.h
+xsane-email-project.o: xsane-text.h
diff --git a/src/xsane-back-gtk.c b/src/xsane-back-gtk.c
index c4ddeef..6599c98 100644
--- a/src/xsane-back-gtk.c
+++ b/src/xsane-back-gtk.c
@@ -269,7 +269,7 @@ int xsane_back_gtk_make_path(size_t buf_size, char *buf, const char *prog_name,
{
snprintf(buf, buf_size-2, "%s", STRINGIFY(PATH_SANE_DATA_DIR));
}
- else /* make path to temporary file */
+ else /* make path to temporary file XSANE_PATH_TMP */
{
snprintf(buf, buf_size-2, "%s", preferences.tmp_path);
}
@@ -2138,7 +2138,7 @@ void xsane_set_sensitivity(SANE_Int sensitivity)
{
DBG(DBG_proc, "xsane_set_sensitivity(%d)\n", sensitivity);
- if (xsane.shell)
+ if (xsane.dialog)
{
/* clear or rebuild histogram */
if (sensitivity)
@@ -2154,8 +2154,8 @@ void xsane_set_sensitivity(SANE_Int sensitivity)
gtk_widget_set_sensitive(xsane.menubar, sensitivity);
gtk_widget_set_sensitive(xsane.xsane_window, sensitivity);
gtk_widget_set_sensitive(GTK_WIDGET(xsane.start_button), sensitivity);
- gtk_widget_set_sensitive(xsane.standard_options_shell, sensitivity);
- gtk_widget_set_sensitive(xsane.advanced_options_shell, sensitivity);
+ gtk_widget_set_sensitive(xsane.standard_options_dialog, sensitivity);
+ gtk_widget_set_sensitive(xsane.advanced_options_dialog, sensitivity);
gtk_widget_set_sensitive(xsane.histogram_dialog, sensitivity);
#ifdef HAVE_WORKING_GTK_GAMMACURVE
gtk_widget_set_sensitive(xsane.gamma_dialog, sensitivity);
@@ -2172,22 +2172,13 @@ void xsane_set_sensitivity(SANE_Int sensitivity)
gtk_widget_set_sensitive(xsane.preview->start, sensitivity); /* Acquire preview button */
}
- if (xsane.fax_dialog)
+ if (xsane.project_dialog)
{
- /* do not change sensitivity of fax_dialog, we want the progress bar */
+ /* do not change sensitivity of project_dialog, we want the progress bar */
/* to be sensitive */
- gtk_widget_set_sensitive(xsane.fax_project_box, sensitivity);
- gtk_widget_set_sensitive(xsane.fax_project_exists, sensitivity);
- gtk_widget_set_sensitive(xsane.fax_project_entry_box, sensitivity);
- }
-
- if (xsane.mail_dialog)
- {
- /* do not change sensitivity of mail_dialog, we want the progress bar */
- /* to be sensitive */
- gtk_widget_set_sensitive(xsane.mail_project_box, sensitivity);
- gtk_widget_set_sensitive(xsane.mail_project_exists, sensitivity);
- gtk_widget_set_sensitive(xsane.mail_project_entry_box, sensitivity);
+ gtk_widget_set_sensitive(xsane.project_box, sensitivity);
+ gtk_widget_set_sensitive(xsane.project_exists, sensitivity);
+ gtk_widget_set_sensitive(xsane.project_entry_box, sensitivity);
}
if (xsane.batch_scan_dialog)
diff --git a/src/xsane-batch-scan.c b/src/xsane-batch-scan.c
index c7ae532..a356612 100644
--- a/src/xsane-batch-scan.c
+++ b/src/xsane-batch-scan.c
@@ -447,7 +447,7 @@ static void xsane_batch_scan_scan_list(void)
GList *list = GTK_LIST(xsane.batch_scan_list)->children;
Batch_Scan_Parameters *parameters = NULL;
SANE_Int val_start = SANE_TRUE;
- SANE_Int val_loop = SANE_TRUE;
+ SANE_Int val_loop = BATCH_MODE_LOOP;
SANE_Int val_end = SANE_FALSE;
SANE_Word val_next_tl_y = SANE_FIX(0.0);
@@ -463,7 +463,7 @@ static void xsane_batch_scan_scan_list(void)
{
if (!list->next) /* last scan */
{
- val_loop = SANE_FALSE;
+ val_loop = BATCH_MODE_LAST_SCAN;
val_end = SANE_TRUE;
val_next_tl_y = SANE_FIX(0.0);
}
@@ -501,7 +501,7 @@ static void xsane_batch_scan_scan_list(void)
gtk_main_iteration();
}
- xsane_scan_dialog();
+ xsane_scan_dialog(NULL);
while (xsane.scanning)
{
@@ -533,7 +533,7 @@ static void xsane_batch_scan_scan_list(void)
xsane_control_option(xsane.dev, xsane.well_known.batch_scan_end, SANE_ACTION_SET_VALUE, &val_end, NULL);
xsane_control_option(xsane.dev, xsane.well_known.batch_scan_next_tl_y, SANE_ACTION_SET_VALUE, &val_next_tl_y, NULL);
- xsane.batch_loop = FALSE; /* make sure we reset the batch scan loop flag */
+ xsane.batch_loop = BATCH_MODE_OFF; /* make sure we reset the batch scan loop flag */
if (parameters)
{
@@ -561,7 +561,11 @@ static void xsane_batch_scan_scan_selected(void)
xsane_batch_scan_establish_parameters(parameters, TRUE);
}
- xsane_scan_dialog();
+ xsane.batch_loop = BATCH_MODE_LAST_SCAN; /* to make sure we do not scan multiple times */
+
+ xsane_scan_dialog(NULL);
+
+ xsane.batch_loop = BATCH_MODE_OFF; /* make sure we reset the batch scan loop flag */
}
}
@@ -939,6 +943,12 @@ static gint xsane_batch_scan_win_delete(GtkWidget *widget, gpointer data)
{
DBG(DBG_proc, "xsane_batch_scan_win_delete\n");
+ if (preferences.show_batch_scan)
+ {
+ xsane_window_get_position(xsane.batch_scan_dialog, &xsane.batch_dialog_posx, &xsane.batch_dialog_posy);
+ gtk_window_move(GTK_WINDOW(xsane.batch_scan_dialog), xsane.batch_dialog_posx, xsane.batch_dialog_posy);
+ }
+
gtk_widget_hide(widget);
preferences.show_batch_scan = FALSE;
gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(xsane.show_batch_scan_widget), preferences.show_batch_scan);
diff --git a/src/xsane-batch-scan.h b/src/xsane-batch-scan.h
index 7437ae8..03b018d 100644
--- a/src/xsane-batch-scan.h
+++ b/src/xsane-batch-scan.h
@@ -30,6 +30,14 @@
#include <sane/sane.h>
/* ---------------------------------------------------------------------------------------------------------------------- */
+typedef enum
+{
+ BATCH_MODE_OFF = 0,
+ BATCH_MODE_LAST_SCAN,
+ BATCH_MODE_LOOP
+} BATCH_MODE_T;
+
+/* ---------------------------------------------------------------------------------------------------------------------- */
typedef struct
{
diff --git a/src/xsane-device-preferences.c b/src/xsane-device-preferences.c
index f70590b..57c5ae8 100644
--- a/src/xsane-device-preferences.c
+++ b/src/xsane-device-preferences.c
@@ -47,17 +47,20 @@ static struct
}
desc_xsane_device[] =
{
- {"xsane-main-window-x-position", xsane_rc_pref_int, DPOFFSET(shell_posx)},
- {"xsane-main-window-y-position", xsane_rc_pref_int, DPOFFSET(shell_posy)},
+ {"xsane-main-window-x-position", xsane_rc_pref_int, DPOFFSET(dialog_posx)},
+ {"xsane-main-window-y-position", xsane_rc_pref_int, DPOFFSET(dialog_posy)},
- {"xsane-main-window-width", xsane_rc_pref_int, DPOFFSET(shell_width)},
- {"xsane-main-window-height", xsane_rc_pref_int, DPOFFSET(shell_height)},
+ {"xsane-main-window-width", xsane_rc_pref_int, DPOFFSET(dialog_width)},
+ {"xsane-main-window-height", xsane_rc_pref_int, DPOFFSET(dialog_height)},
- {"xsane-standard-options-window-x-position", xsane_rc_pref_int, DPOFFSET(standard_options_shell_posx)},
- {"xsane-standard-options-window-y-position", xsane_rc_pref_int, DPOFFSET(standard_options_shell_posy)},
+ {"xsane-project-window-x-position", xsane_rc_pref_int, DPOFFSET(project_dialog_posx)},
+ {"xsane-project-window-y-position", xsane_rc_pref_int, DPOFFSET(project_dialog_posy)},
- {"xsane-advanced-options-window-x-position", xsane_rc_pref_int, DPOFFSET(advanced_options_shell_posx)},
- {"xsane-advanced-options-window-y-position", xsane_rc_pref_int, DPOFFSET(advanced_options_shell_posy)},
+ {"xsane-standard-options-window-x-position", xsane_rc_pref_int, DPOFFSET(standard_options_dialog_posx)},
+ {"xsane-standard-options-window-y-position", xsane_rc_pref_int, DPOFFSET(standard_options_dialog_posy)},
+
+ {"xsane-advanced-options-window-x-position", xsane_rc_pref_int, DPOFFSET(advanced_options_dialog_posx)},
+ {"xsane-advanced-options-window-y-position", xsane_rc_pref_int, DPOFFSET(advanced_options_dialog_posy)},
{"xsane-histogram-window-x-position", xsane_rc_pref_int, DPOFFSET(histogram_dialog_posx)},
{"xsane-histogram-window-y-position", xsane_rc_pref_int, DPOFFSET(histogram_dialog_posy)},
@@ -96,8 +99,6 @@ desc_xsane_device[] =
{"xsane-threshold-offset", xsane_rc_pref_double, DPOFFSET(threshold_off)},
{"xsane-grayscale-scanmode", xsane_rc_pref_string, DPOFFSET(grayscale_scanmode)},
- {"xsane-adf-scansource", xsane_rc_pref_string, DPOFFSET(adf_scansource)},
-
{"xsane-enhancement-rgb-default", xsane_rc_pref_int, DPOFFSET(enhancement_rgb_default)},
{"xsane-negative", xsane_rc_pref_int, DPOFFSET(negative)},
{"xsane-show-preview", xsane_rc_pref_int, DPOFFSET(show_preview)},
@@ -376,30 +377,37 @@ void xsane_device_preferences_load_file(char *filename)
DBG(DBG_proc, "xsane_device_preferences_load_file\n");
/* set geometry and position to standard values */
- xsane.shell_posx = XSANE_SHELL_POS_X;
- xsane.shell_posy = XSANE_SHELL_POS_Y;
- xsane.shell_width = XSANE_SHELL_WIDTH;
- xsane.shell_height = XSANE_SHELL_HEIGHT;
+ xsane.dialog_posx = XSANE_DIALOG_POS_X;
+ xsane.dialog_posy = XSANE_DIALOG_POS_Y;
+ xsane.dialog_width = XSANE_DIALOG_WIDTH;
+ xsane.dialog_height = XSANE_DIALOG_HEIGHT;
+
+ xsane.project_dialog_posx = XSANE_PROJECT_DIALOG_POS_X;
+ xsane.project_dialog_posy = XSANE_PROJECT_DIALOG_POS_Y;
+
+ xsane.standard_options_dialog_posx = XSANE_STD_OPTIONS_DIALOG_POS_X;
+ xsane.standard_options_dialog_posy = XSANE_STD_OPTIONS_DIALOG_POS_Y;
- xsane.standard_options_shell_posx = XSANE_STD_OPTIONS_POS_X;
- xsane.standard_options_shell_posy = XSANE_STD_OPTIONS_POS_Y;
+ xsane.advanced_options_dialog_posx = XSANE_ADV_OPTIONS_DIALOG_POS_X;
+ xsane.advanced_options_dialog_posy = XSANE_ADV_OPTIONS_DIALOG_POS_Y;
- xsane.advanced_options_shell_posx = XSANE_ADV_OPTIONS_POS_X;
- xsane.advanced_options_shell_posy = XSANE_ADV_OPTIONS_POS_Y;
+ xsane.histogram_dialog_posx = XSANE_HISTOGRAM_DIALOG_POS_X;
+ xsane.histogram_dialog_posy = XSANE_HISTOGRAM_DIALOG_POS_Y;
- xsane.histogram_dialog_posx = XSANE_HISTOGRAM_POS_X;
- xsane.histogram_dialog_posy = XSANE_HISTOGRAM_POS_Y;
+ xsane.gamma_dialog_posx = XSANE_GAMMA_DIALOG_POS_X;
+ xsane.gamma_dialog_posy = XSANE_GAMMA_DIALOG_POS_Y;
- xsane.gamma_dialog_posx = XSANE_GAMMA_POS_X;
- xsane.gamma_dialog_posy = XSANE_GAMMA_POS_Y;
+ xsane.batch_dialog_posx = XSANE_BATCH_DIALOG_POS_X;
+ xsane.batch_dialog_posy = XSANE_BATCH_DIALOG_POS_Y;
- xsane.batch_dialog_posx = XSANE_BATCH_POS_X;
- xsane.batch_dialog_posy = XSANE_BATCH_POS_Y;
+ xsane.preview_dialog_posx = XSANE_PREVIEW_DIALOG_POS_X;
+ xsane.preview_dialog_posy = XSANE_PREVIEW_DIALOG_POS_Y;
+ xsane.preview_dialog_width = XSANE_PREVIEW_DIALOG_WIDTH;
+ xsane.preview_dialog_height = XSANE_PREVIEW_DIALOG_HEIGHT;
- xsane.preview_dialog_posx = XSANE_PREVIEW_POS_X;
- xsane.preview_dialog_posy = XSANE_PREVIEW_POS_Y;
- xsane.preview_dialog_width = XSANE_PREVIEW_WIDTH;
- xsane.preview_dialog_height = XSANE_PREVIEW_HEIGHT;
+ xsane.resolution = 1.0;
+ xsane.resolution_x = 1.0;
+ xsane.resolution_y = 1.0;
xsane.gamma = 1.0;
xsane.gamma_red = 1.0;
@@ -424,8 +432,6 @@ void xsane_device_preferences_load_file(char *filename)
xsane.threshold_mul = 1.0;
xsane.threshold_off = 0.0;
- xsane.adf_scansource = 0; /* Empty String => keeps adf scansource */
-
xsane.enhancement_rgb_default = 1;
xsane.negative = 0;
xsane.show_preview = 1;
@@ -552,17 +558,27 @@ void xsane_device_preferences_load_file(char *filename)
}
}
}
- gtk_window_move(GTK_WINDOW(xsane.shell), xsane.shell_posx, xsane.shell_posy);
- gtk_window_set_default_size(GTK_WINDOW(xsane.shell), xsane.shell_width, xsane.shell_height);
- gtk_window_move(GTK_WINDOW(xsane.standard_options_shell), xsane.standard_options_shell_posx, xsane.standard_options_shell_posy);
- gtk_window_move(GTK_WINDOW(xsane.advanced_options_shell), xsane.advanced_options_shell_posx, xsane.advanced_options_shell_posy);
+ gtk_window_move(GTK_WINDOW(xsane.dialog), xsane.dialog_posx, xsane.dialog_posy);
+ gtk_window_set_default_size(GTK_WINDOW(xsane.dialog), xsane.dialog_width, xsane.dialog_height);
+
+ if (xsane.project_dialog)
+ {
+ gtk_window_move(GTK_WINDOW(xsane.project_dialog), xsane.project_dialog_posx, xsane.project_dialog_posy);
+ }
+
+ gtk_window_move(GTK_WINDOW(xsane.standard_options_dialog), xsane.standard_options_dialog_posx, xsane.standard_options_dialog_posy);
+ gtk_window_move(GTK_WINDOW(xsane.advanced_options_dialog), xsane.advanced_options_dialog_posx, xsane.advanced_options_dialog_posy);
gtk_window_move(GTK_WINDOW(xsane.histogram_dialog), xsane.histogram_dialog_posx, xsane.histogram_dialog_posy);
#if 0
gtk_window_move(GTK_WINDOW(xsane.gamma_dialog), xsane.gamma_dialog_posx, xsane.gamma_dialog_posy);
#endif
gtk_window_move(GTK_WINDOW(xsane.batch_scan_dialog), xsane.batch_dialog_posx, xsane.batch_dialog_posy);
gtk_window_move(GTK_WINDOW(xsane.preview->top), xsane.preview_dialog_posx, xsane.preview_dialog_posy);
+#ifdef HAVE_GTK2
+ gtk_window_resize(GTK_WINDOW(xsane.preview->top), xsane.preview_dialog_width, xsane.preview_dialog_height);
+#else
gtk_window_set_default_size(GTK_WINDOW(xsane.preview->top), xsane.preview_dialog_width, xsane.preview_dialog_height);
+#endif
xsane_update_param(0);
xsane_refresh_dialog();
@@ -655,34 +671,66 @@ void xsane_device_preferences_save_file(char *filename)
XSANE_RC_IO_W_STRINGCONST(&w, XSANE_VERSION);
/* make geometry and position values up to date */
- xsane_window_get_position(xsane.shell, &xsane.shell_posx, &xsane.shell_posy);
- gdk_drawable_get_size(xsane.shell->window, &xsane.shell_width, &xsane.shell_height);
- gtk_window_move(GTK_WINDOW(xsane.shell), xsane.shell_posx, xsane.shell_posy); /* geometry used when window closed and opened again */
- gtk_window_set_default_size(GTK_WINDOW(xsane.shell), xsane.shell_width, xsane.shell_height);
+ xsane_window_get_position(xsane.dialog, &xsane.dialog_posx, &xsane.dialog_posy);
+ gdk_drawable_get_size(xsane.dialog->window, &xsane.dialog_width, &xsane.dialog_height);
+#if 0 /* TO BE REMOVED */
+ gtk_window_move(GTK_WINDOW(xsane.dialog), xsane.dialog_posx, xsane.dialog_posy); /* geometry used when window closed and opened again */
+ gtk_window_set_default_size(GTK_WINDOW(xsane.dialog), xsane.dialog_width, xsane.dialog_height);
+#endif
- xsane_window_get_position(xsane.standard_options_shell, &xsane.standard_options_shell_posx, &xsane.standard_options_shell_posy);
- gtk_window_move(GTK_WINDOW(xsane.standard_options_shell), xsane.standard_options_shell_posx, xsane.standard_options_shell_posy);
+ if (xsane.project_dialog)
+ {
+ xsane_window_get_position(xsane.project_dialog, &xsane.project_dialog_posx, &xsane.project_dialog_posy);
+#if 0 /* TO BE REMOVED */
+ gtk_window_move(GTK_WINDOW(xsane.project_dialog), xsane.project_dialog_posx, xsane.project_dialog_posy);
+#endif
+ }
- xsane_window_get_position(xsane.advanced_options_shell, &xsane.advanced_options_shell_posx, &xsane.advanced_options_shell_posy);
- gtk_window_move(GTK_WINDOW(xsane.advanced_options_shell), xsane.advanced_options_shell_posx, xsane.advanced_options_shell_posy);
+ if (preferences.show_standard_options)
+ {
+ xsane_window_get_position(xsane.standard_options_dialog, &xsane.standard_options_dialog_posx, &xsane.standard_options_dialog_posy);
+#if 0 /* TO BE REMOVED */
+ gtk_window_move(GTK_WINDOW(xsane.standard_options_dialog), xsane.standard_options_dialog_posx, xsane.standard_options_dialog_posy);
+#endif
+ }
- xsane_window_get_position(xsane.histogram_dialog, &xsane.histogram_dialog_posx, &xsane.histogram_dialog_posy);
- gtk_window_move(GTK_WINDOW(xsane.histogram_dialog), xsane.histogram_dialog_posx, xsane.histogram_dialog_posy);
+ if (preferences.show_advanced_options)
+ {
+ xsane_window_get_position(xsane.advanced_options_dialog, &xsane.advanced_options_dialog_posx, &xsane.advanced_options_dialog_posy);
+#if 0 /* TO BE REMOVED */
+ gtk_window_move(GTK_WINDOW(xsane.advanced_options_dialog), xsane.advanced_options_dialog_posx, xsane.advanced_options_dialog_posy);
+#endif
+ }
+
+ if (preferences.show_histogram)
+ {
+ xsane_window_get_position(xsane.histogram_dialog, &xsane.histogram_dialog_posx, &xsane.histogram_dialog_posy);
+#if 0 /* TO BE REMOVED */
+ gtk_window_move(GTK_WINDOW(xsane.histogram_dialog), xsane.histogram_dialog_posx, xsane.histogram_dialog_posy);
+#endif
+ }
#if 0
xsane_window_get_position(xsane.gamma_dialog, &xsane.gamma_dialog_posx, &xsane.gamma_dialog_posy);
gtk_window_move(GTK_WINDOW(xsane.gamma_dialog), xsane.gamma_dialog_posx, xsane.gamma_dialog_posy);
#endif
- xsane_window_get_position(xsane.batch_scan_dialog, &xsane.batch_dialog_posx, &xsane.batch_dialog_posy);
- gtk_window_move(GTK_WINDOW(xsane.batch_scan_dialog), xsane.batch_dialog_posx, xsane.batch_dialog_posy);
+ if (preferences.show_batch_scan)
+ {
+ xsane_window_get_position(xsane.batch_scan_dialog, &xsane.batch_dialog_posx, &xsane.batch_dialog_posy);
+#if 0 /* TO BE REMOVED */
+ gtk_window_move(GTK_WINDOW(xsane.batch_scan_dialog), xsane.batch_dialog_posx, xsane.batch_dialog_posy);
+#endif
+ }
if (xsane.preview)
{
xsane_window_get_position(xsane.preview->top, &xsane.preview_dialog_posx, &xsane.preview_dialog_posy);
gdk_drawable_get_size(xsane.preview->top->window, &xsane.preview_dialog_width, &xsane.preview_dialog_height);
+#if 0
gtk_window_move(GTK_WINDOW(xsane.preview->top), xsane.preview_dialog_posx, xsane.preview_dialog_posy);
gtk_window_set_default_size(GTK_WINDOW(xsane.preview->top), xsane.preview_dialog_width, xsane.preview_dialog_height);
+#endif
}
xsane_device_preferences_save_values(&w, xsane.dev);
diff --git a/src/xsane-email-project.c b/src/xsane-email-project.c
new file mode 100644
index 0000000..67713ec
--- /dev/null
+++ b/src/xsane-email-project.c
@@ -0,0 +1,1912 @@
+/* xsane -- a graphical (X11, gtk) scanner-oriented SANE frontend
+
+ xsane-email-project.c
+
+ Oliver Rauch <Oliver.Rauch@rauch-domain.de>
+ Copyright (C) 1998-2005 Oliver Rauch
+ This file is part of the XSANE package.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+/* ---------------------------------------------------------------------------------------------------------------------- */
+
+#include "xsane.h"
+#include "xsane-back-gtk.h"
+#include "xsane-front-gtk.h"
+#include "xsane-preview.h"
+#include "xsane-save.h"
+#include "xsane-gamma.h"
+#include "xsane-setup.h"
+#include "xsane-scan.h"
+#include "xsane-rc-io.h"
+#include "xsane-device-preferences.h"
+#include "xsane-preferences.h"
+#include "xsane-icons.h"
+#include "xsane-batch-scan.h"
+
+#ifdef HAVE_LIBPNG
+#ifdef HAVE_LIBZ
+#include <png.h>
+#include <zlib.h>
+#endif
+#endif
+
+#include <sys/wait.h>
+
+/* ---------------------------------------------------------------------------------------------------------------------- */
+
+#ifdef XSANE_ACTIVATE_EMAIL
+
+/* ---------------------------------------------------------------------------------------------------------------------- */
+
+static guint xsane_email_send_timer = 0;
+
+/* ---------------------------------------------------------------------------------------------------------------------- */
+
+/* forward declarations: */
+
+void xsane_email_project_save(void);
+void xsane_email_dialog(void);
+
+static gint xsane_email_dialog_delete();
+static void xsane_email_filetype_callback(GtkWidget *filetype_option_menu, char *filetype);
+static void xsane_email_receiver_changed_callback(GtkWidget *widget, gpointer data);
+static void xsane_email_subject_changed_callback(GtkWidget *widget, gpointer data);
+static void xsane_email_project_changed_callback(GtkWidget *widget, gpointer data);
+static void xsane_email_html_mode_callback(GtkWidget *widget);
+static void xsane_email_project_display_status(void);
+static void xsane_email_project_load(void);
+static void xsane_email_project_delete(void);
+static void xsane_email_project_update_project_status();
+static void xsane_email_project_create(void);
+static void xsane_email_entry_move_up_callback(GtkWidget *widget, gpointer list);
+static void xsane_email_entry_move_down_callback(GtkWidget *widget, gpointer list);
+static void xsane_email_entry_rename_callback(GtkWidget *widget, gpointer list);
+static void xsane_email_entry_delete_callback(GtkWidget *widget, gpointer list);
+static void xsane_email_show_callback(GtkWidget *widget, gpointer data);
+#if 0
+static void xsane_email_edit_callback(GtkWidget *widget, gpointer data);
+#endif
+static void xsane_email_send_process(void);
+static void xsane_email_send(void);
+
+
+/* ---------------------------------------------------------------------------------------------------------------------- */
+
+static gint xsane_email_dialog_delete()
+{
+ return TRUE;
+}
+
+/* ---------------------------------------------------------------------------------------------------------------------- */
+
+static void xsane_email_filetype_callback(GtkWidget *filetype_option_menu, char *filetype)
+{
+ DBG(DBG_proc, "xsane_email_filetype_callback(%s)\n", filetype);
+
+ if (preferences.email_filetype)
+ {
+ free(preferences.email_filetype);
+ }
+ preferences.email_filetype = strdup(filetype);
+}
+
+/* ---------------------------------------------------------------------------------------------------------------------- */
+
+void xsane_email_dialog()
+{
+ GtkWidget *email_dialog, *email_scan_vbox, *email_project_vbox;
+ GtkWidget *email_project_exists_hbox, *button;
+ GtkWidget *hbox;
+ GtkWidget *scrolled_window, *list;
+ GtkWidget *pixmapwidget, *text;
+ GtkWidget *attachment_frame, *text_frame;
+ GtkWidget *label;
+ GtkWidget *filetype_menu, *filetype_item;
+ GtkWidget *filetype_option_menu;
+ GdkPixmap *pixmap;
+ GdkBitmap *mask;
+ char buf[64];
+ int filetype_nr;
+ int select_item;
+
+ DBG(DBG_proc, "xsane_email_dialog\n");
+
+ if (xsane.project_dialog)
+ {
+ return; /* window already is open */
+ }
+
+ /* GTK_WINDOW_TOPLEVEL looks better but does not place it nice*/
+ email_dialog = gtk_window_new(GTK_WINDOW_TOPLEVEL);
+
+ snprintf(buf, sizeof(buf), "%s %s", xsane.prog_name, WINDOW_EMAIL_PROJECT);
+ gtk_window_set_title(GTK_WINDOW(email_dialog), buf);
+ g_signal_connect(GTK_OBJECT(email_dialog), "delete_event", (GtkSignalFunc) xsane_email_dialog_delete, NULL);
+ xsane_set_window_icon(email_dialog, 0);
+ gtk_window_add_accel_group(GTK_WINDOW(email_dialog), xsane.accelerator_group);
+
+ /* set the main vbox */
+ email_scan_vbox = gtk_vbox_new(FALSE, 0);
+ gtk_container_set_border_width(GTK_CONTAINER(email_scan_vbox), 0);
+ gtk_container_add(GTK_CONTAINER(email_dialog), email_scan_vbox);
+ gtk_widget_show(email_scan_vbox);
+
+
+ /* email project */
+ hbox = gtk_hbox_new(FALSE, 2);
+ gtk_container_set_border_width(GTK_CONTAINER(hbox), 2);
+ gtk_box_pack_start(GTK_BOX(email_scan_vbox), hbox, FALSE, FALSE, 1);
+
+ pixmap = gdk_pixmap_create_from_xpm_d(xsane.dialog->window, &mask, xsane.bg_trans, (gchar **) email_xpm);
+ pixmapwidget = gtk_image_new_from_pixmap(pixmap, mask);
+ gtk_box_pack_start(GTK_BOX(hbox), pixmapwidget, FALSE, FALSE, 2);
+ gdk_drawable_unref(pixmap);
+
+ text = gtk_entry_new();
+ xsane_back_gtk_set_tooltip(xsane.tooltips, text, DESC_EMAIL_PROJECT);
+ gtk_entry_set_max_length(GTK_ENTRY(text), 128);
+ gtk_entry_set_text(GTK_ENTRY(text), (char *) preferences.email_project);
+ gtk_box_pack_start(GTK_BOX(hbox), text, TRUE, TRUE, 4);
+ g_signal_connect(GTK_OBJECT(text), "changed", (GtkSignalFunc) xsane_email_project_changed_callback, NULL);
+
+ xsane.project_entry = text;
+ xsane.project_entry_box = hbox;
+
+ gtk_widget_show(pixmapwidget);
+ gtk_widget_show(text);
+ gtk_widget_show(hbox);
+
+ email_project_vbox = gtk_vbox_new(/* homogeneous */ FALSE, 0);
+ gtk_box_pack_start(GTK_BOX(email_scan_vbox), email_project_vbox, TRUE, TRUE, 0);
+ gtk_widget_show(email_project_vbox);
+
+
+ /* email receiver */
+ hbox = gtk_hbox_new(FALSE, 2);
+ gtk_container_set_border_width(GTK_CONTAINER(hbox), 2);
+ gtk_box_pack_start(GTK_BOX(email_project_vbox), hbox, FALSE, FALSE, 1);
+
+ gtk_widget_realize(email_dialog);
+
+ pixmap = gdk_pixmap_create_from_xpm_d(email_dialog->window, &mask, xsane.bg_trans, (gchar **) emailreceiver_xpm);
+ pixmapwidget = gtk_image_new_from_pixmap(pixmap, mask);
+ gtk_box_pack_start(GTK_BOX(hbox), pixmapwidget, FALSE, FALSE, 2);
+ gdk_drawable_unref(pixmap);
+
+ text = gtk_entry_new();
+ gtk_entry_set_max_length(GTK_ENTRY(text), 128);
+ xsane_back_gtk_set_tooltip(xsane.tooltips, text, DESC_EMAIL_RECEIVER);
+ gtk_box_pack_start(GTK_BOX(hbox), text, TRUE, TRUE, 4);
+ g_signal_connect(GTK_OBJECT(text), "changed", (GtkSignalFunc) xsane_email_receiver_changed_callback, NULL);
+
+ xsane.email_receiver_entry = text;
+
+ gtk_widget_show(pixmapwidget);
+ gtk_widget_show(text);
+ gtk_widget_show(hbox);
+
+
+ /* subject */
+ hbox = gtk_hbox_new(FALSE, 2);
+ gtk_container_set_border_width(GTK_CONTAINER(hbox), 2);
+ gtk_box_pack_start(GTK_BOX(email_project_vbox), hbox, FALSE, FALSE, 1);
+
+ gtk_widget_realize(email_dialog);
+
+ pixmap = gdk_pixmap_create_from_xpm_d(email_dialog->window, &mask, xsane.bg_trans, (gchar **) subject_xpm);
+ pixmapwidget = gtk_image_new_from_pixmap(pixmap, mask);
+ gtk_box_pack_start(GTK_BOX(hbox), pixmapwidget, FALSE, FALSE, 2);
+ gdk_drawable_unref(pixmap);
+
+ text = gtk_entry_new();
+ xsane_back_gtk_set_tooltip(xsane.tooltips, text, DESC_EMAIL_SUBJECT);
+ gtk_entry_set_max_length(GTK_ENTRY(text), 128);
+ gtk_box_pack_start(GTK_BOX(hbox), text, TRUE, TRUE, 4);
+ g_signal_connect(GTK_OBJECT(text), "changed", (GtkSignalFunc) xsane_email_subject_changed_callback, NULL);
+
+ xsane.email_subject_entry = text;
+
+ gtk_widget_show(pixmapwidget);
+ gtk_widget_show(text);
+ gtk_widget_show(hbox);
+
+
+ /* email text frame */
+ text_frame = gtk_frame_new(TEXT_EMAIL_TEXT);
+ gtk_box_pack_start(GTK_BOX(email_project_vbox), text_frame, TRUE, TRUE, 2);
+ gtk_widget_show(text_frame);
+
+ /* email text box */
+ hbox = gtk_hbox_new(FALSE, 2);
+ gtk_container_set_border_width(GTK_CONTAINER(hbox), 4);
+ gtk_container_add(GTK_CONTAINER(text_frame), hbox);
+ gtk_widget_show(hbox);
+
+#ifdef HAVE_GTK_TEXT_VIEW_H
+ {
+ GtkWidget *scrolled_window, *text_view, *text_buffer;
+
+ /* create a scrolled window to get a vertical scrollbar */
+ scrolled_window = gtk_scrolled_window_new(NULL, NULL);
+ gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolled_window), GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
+ gtk_container_add(GTK_CONTAINER(hbox), scrolled_window);
+ gtk_widget_show(scrolled_window);
+
+ /* create the gtk_text_view widget */
+ text_view = gtk_text_view_new();
+ gtk_text_view_set_editable(GTK_TEXT_VIEW(text_view), TRUE);
+ gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW(text_view), GTK_WRAP_WORD);
+ gtk_container_add(GTK_CONTAINER(scrolled_window), text_view);
+ gtk_widget_show(text_view);
+
+ /* get the text_buffer widget and insert the text from file */
+ text_buffer = (GtkWidget *) gtk_text_view_get_buffer(GTK_TEXT_VIEW(text_view));
+
+ xsane.email_text_widget = text_buffer;
+ }
+#else
+ {
+ GtkWidget *vscrollbar;
+
+ /* Create the GtkText widget */
+ text = gtk_text_new(NULL, NULL);
+ gtk_text_set_editable(GTK_TEXT(text), TRUE); /* text is editable */
+ gtk_text_set_word_wrap(GTK_TEXT(text), TRUE); /* wrap complete words */
+ gtk_box_pack_start(GTK_BOX(hbox), text, TRUE, TRUE, 0);
+ gtk_widget_show(text);
+ xsane.email_text_widget = text;
+
+ /* Add a vertical scrollbar to the GtkText widget */
+ vscrollbar = gtk_vscrollbar_new(GTK_TEXT(text)->vadj);
+ gtk_box_pack_start(GTK_BOX(hbox), vscrollbar, FALSE, FALSE, 0);
+ gtk_widget_show(vscrollbar);
+ }
+#endif
+
+
+ /* html email */
+ button = gtk_check_button_new_with_label(RADIO_BUTTON_HTML_EMAIL);
+ xsane_back_gtk_set_tooltip(xsane.tooltips, button, DESC_HTML_EMAIL);
+ gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button), xsane.email_html_mode);
+ gtk_box_pack_start(GTK_BOX(email_project_vbox), button, FALSE, FALSE, 2);
+ gtk_widget_show(button);
+ g_signal_connect(GTK_OBJECT(button), "clicked", (GtkSignalFunc) xsane_email_html_mode_callback, NULL);
+ xsane.email_html_mode_widget = button;
+
+ /* FILETYPE MENU */
+ /* button box, active when project exists */
+ hbox = gtk_hbox_new(FALSE, 2);
+ gtk_container_set_border_width(GTK_CONTAINER(hbox), 2);
+ gtk_box_pack_start(GTK_BOX(email_project_vbox), hbox, FALSE, FALSE, 1);
+ gtk_widget_show(hbox);
+
+ filetype_menu = gtk_menu_new();
+
+ filetype_nr = -1;
+ select_item = 0;
+
+#ifdef HAVE_LIBJPEG
+ filetype_item = gtk_menu_item_new_with_label(MENU_ITEM_FILETYPE_JPEG);
+ gtk_container_add(GTK_CONTAINER(filetype_menu), filetype_item);
+ g_signal_connect(GTK_OBJECT(filetype_item), "activate", (GtkSignalFunc) xsane_email_filetype_callback, (void *) XSANE_FILETYPE_JPEG);
+ gtk_widget_show(filetype_item);
+ filetype_nr++;
+ if ( (preferences.email_filetype) && (!strcasecmp(preferences.email_filetype, XSANE_FILETYPE_JPEG)) )
+ {
+ select_item = filetype_nr;
+ }
+#endif
+
+
+ filetype_item = gtk_menu_item_new_with_label(MENU_ITEM_FILETYPE_PDF);
+ gtk_container_add(GTK_CONTAINER(filetype_menu), filetype_item);
+ g_signal_connect(GTK_OBJECT(filetype_item), "activate", (GtkSignalFunc) xsane_email_filetype_callback, (void *) XSANE_FILETYPE_PDF);
+ gtk_widget_show(filetype_item);
+ filetype_nr++;
+ if ( (preferences.email_filetype) && (!strcasecmp(preferences.email_filetype, XSANE_FILETYPE_PDF)) )
+ {
+ select_item = filetype_nr;
+ }
+
+
+#ifdef HAVE_LIBPNG
+#ifdef HAVE_LIBZ
+ filetype_item = gtk_menu_item_new_with_label(MENU_ITEM_FILETYPE_PNG);
+ gtk_container_add(GTK_CONTAINER(filetype_menu), filetype_item);
+ g_signal_connect(GTK_OBJECT(filetype_item), "activate", (GtkSignalFunc) xsane_email_filetype_callback, (void *) XSANE_FILETYPE_PNG);
+ gtk_widget_show(filetype_item);
+ filetype_nr++;
+ if ( (preferences.email_filetype) && (!strcasecmp(preferences.email_filetype, XSANE_FILETYPE_PNG)) )
+ {
+ select_item = filetype_nr;
+ }
+#endif
+#endif
+
+ filetype_item = gtk_menu_item_new_with_label(MENU_ITEM_FILETYPE_PS);
+ gtk_container_add(GTK_CONTAINER(filetype_menu), filetype_item);
+ g_signal_connect(GTK_OBJECT(filetype_item), "activate", (GtkSignalFunc) xsane_email_filetype_callback, (void *) XSANE_FILETYPE_PS);
+ gtk_widget_show(filetype_item);
+ filetype_nr++;
+ if ( (preferences.email_filetype) && (!strcasecmp(preferences.email_filetype, XSANE_FILETYPE_PS)) )
+ {
+ select_item = filetype_nr;
+ }
+
+
+#ifdef HAVE_LIBTIFF
+ filetype_item = gtk_menu_item_new_with_label(MENU_ITEM_FILETYPE_TIFF);
+ gtk_container_add(GTK_CONTAINER(filetype_menu), filetype_item);
+ g_signal_connect(GTK_OBJECT(filetype_item), "activate", (GtkSignalFunc) xsane_email_filetype_callback, (void *) XSANE_FILETYPE_TIFF);
+ gtk_widget_show(filetype_item);
+ filetype_nr++;
+ if ( (preferences.email_filetype) && (!strcasecmp(preferences.email_filetype, XSANE_FILETYPE_TIFF)) )
+ {
+ select_item = filetype_nr;
+ }
+#endif
+
+ label = gtk_label_new(TEXT_EMAIL_FILETYPE);
+ gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 2);
+ gtk_widget_show(label);
+
+ filetype_option_menu = gtk_option_menu_new();
+ xsane_back_gtk_set_tooltip(xsane.tooltips, filetype_option_menu, DESC_EMAIL_FILETYPE);
+ gtk_option_menu_set_menu(GTK_OPTION_MENU(filetype_option_menu), filetype_menu);
+ if (select_item >= 0)
+ {
+ gtk_option_menu_set_history(GTK_OPTION_MENU(filetype_option_menu), select_item);
+ }
+ gtk_box_pack_end(GTK_BOX(hbox), filetype_option_menu, FALSE, FALSE, 2);
+ gtk_widget_show(filetype_menu);
+ gtk_widget_show(filetype_option_menu);
+
+
+ /* attachment frame */
+ attachment_frame = gtk_frame_new(TEXT_ATTACHMENTS);
+ gtk_box_pack_start(GTK_BOX(email_project_vbox), attachment_frame, FALSE, FALSE, 2);
+ gtk_widget_show(attachment_frame);
+
+ /* attachment list */
+ scrolled_window = gtk_scrolled_window_new(0, 0);
+ gtk_widget_set_size_request(scrolled_window, 200, 100);
+ gtk_container_add(GTK_CONTAINER(attachment_frame), scrolled_window);
+ gtk_widget_show(scrolled_window);
+
+ list = gtk_list_new();
+/* gtk_list_set_selection_mode(list, GTK_SELECTION_BROWSE); */
+
+ gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(scrolled_window), list);
+ gtk_widget_show(list);
+ xsane.project_list = list;
+
+
+ /* button box, active when project exists */
+ hbox = gtk_hbox_new(FALSE, 2);
+ gtk_container_set_border_width(GTK_CONTAINER(hbox), 2);
+ gtk_box_pack_start(GTK_BOX(email_project_vbox), hbox, FALSE, FALSE, 1);
+
+ button = gtk_button_new_with_label(BUTTON_IMAGE_SHOW);
+ g_signal_connect(GTK_OBJECT(button), "clicked", (GtkSignalFunc) xsane_email_show_callback, list);
+ gtk_box_pack_start(GTK_BOX(hbox), button, TRUE, TRUE, 0);
+ gtk_widget_show(button);
+
+#if 0
+ /* before we enable the edit function we have to make sure that the rename function
+ does also rename the image name of the opened viewer */
+ button = gtk_button_new_with_label(BUTTON_IMAGE_EDIT);
+ g_signal_connect(GTK_OBJECT(button), "clicked", (GtkSignalFunc) xsane_email_edit_callback, list);
+ gtk_box_pack_start(GTK_BOX(hbox), button, TRUE, TRUE, 0);
+ gtk_widget_show(button);
+#endif
+
+ button = gtk_button_new_with_label(BUTTON_IMAGE_RENAME);
+ g_signal_connect(GTK_OBJECT(button), "clicked", (GtkSignalFunc) xsane_email_entry_rename_callback, list);
+ gtk_box_pack_start(GTK_BOX(hbox), button, TRUE, TRUE, 0);
+ gtk_widget_show(button);
+
+ button = gtk_button_new_with_label(BUTTON_IMAGE_DELETE);
+ g_signal_connect(GTK_OBJECT(button), "clicked", (GtkSignalFunc) xsane_email_entry_delete_callback, list);
+ gtk_box_pack_start(GTK_BOX(hbox), button, TRUE, TRUE, 0);
+ gtk_widget_show(button);
+
+ xsane_button_new_with_pixmap(email_dialog->window, hbox, move_up_xpm, 0, (GtkSignalFunc) xsane_email_entry_move_up_callback, list);
+ xsane_button_new_with_pixmap(email_dialog->window, hbox, move_down_xpm, 0, (GtkSignalFunc) xsane_email_entry_move_down_callback, list);
+
+ gtk_widget_show(hbox);
+
+ xsane.project_box = email_project_vbox;
+
+
+ /* set the main hbox */
+ hbox = gtk_hbox_new(FALSE, 0);
+ xsane_separator_new(email_project_vbox, 2);
+ gtk_box_pack_end(GTK_BOX(email_scan_vbox), hbox, FALSE, FALSE, 5);
+ gtk_container_set_border_width(GTK_CONTAINER(hbox), 5);
+ gtk_widget_show(hbox);
+
+
+ email_project_exists_hbox = gtk_hbox_new(FALSE, 2);
+ gtk_box_pack_start(GTK_BOX(hbox), email_project_exists_hbox, TRUE, TRUE, 0);
+
+ button = gtk_button_new_with_label(BUTTON_SEND_PROJECT);
+ g_signal_connect(GTK_OBJECT(button), "clicked", (GtkSignalFunc) xsane_email_send, NULL);
+ gtk_box_pack_start(GTK_BOX(email_project_exists_hbox), button, TRUE, TRUE, 0);
+ gtk_widget_show(button);
+
+ button = gtk_button_new_with_label(BUTTON_DELETE_PROJECT);
+ g_signal_connect(GTK_OBJECT(button), "clicked", (GtkSignalFunc) xsane_email_project_delete, NULL);
+ gtk_box_pack_start(GTK_BOX(email_project_exists_hbox), button, TRUE, TRUE, 0);
+ gtk_widget_show(button);
+
+ gtk_widget_show(email_project_exists_hbox);
+ xsane.project_exists = email_project_exists_hbox;
+
+ button = gtk_button_new_with_label(BUTTON_CREATE_PROJECT);
+ g_signal_connect(GTK_OBJECT(button), "clicked", (GtkSignalFunc) xsane_email_project_create, NULL);
+ gtk_box_pack_start(GTK_BOX(hbox), button, TRUE, TRUE, 0);
+ xsane.project_not_exists = button;
+
+ /* progress bar */
+ xsane.project_progress_bar = (GtkProgressBar *) gtk_progress_bar_new();
+ gtk_box_pack_start(GTK_BOX(email_scan_vbox), (GtkWidget *) xsane.project_progress_bar, FALSE, FALSE, 0);
+ gtk_progress_set_show_text(GTK_PROGRESS(xsane.project_progress_bar), TRUE);
+ gtk_progress_set_format_string(GTK_PROGRESS(xsane.project_progress_bar), "");
+ gtk_widget_show(GTK_WIDGET(xsane.project_progress_bar));
+
+
+ xsane.project_dialog = email_dialog;
+
+ xsane_email_project_load();
+
+ gtk_window_move(GTK_WINDOW(xsane.project_dialog), xsane.project_dialog_posx, xsane.project_dialog_posy);
+ gtk_widget_show(email_dialog);
+}
+
+/* ---------------------------------------------------------------------------------------------------------------------- */
+
+static void xsane_email_project_set_sensitive(int sensitive)
+{
+ gtk_widget_set_sensitive(xsane.project_box, sensitive);
+ gtk_widget_set_sensitive(xsane.project_exists, sensitive);
+}
+
+/* ---------------------------------------------------------------------------------------------------------------------- */
+
+static void xsane_email_project_display_status()
+{
+ FILE *lockfile;
+ char buf[256];
+ char filename[PATH_MAX];
+ int val;
+ int i, c;
+
+ DBG(DBG_proc, "xsane_email_project_display_status\n");
+
+ snprintf(filename, sizeof(filename), "%s/lockfile", preferences.email_project);
+ lockfile = fopen(filename, "rb"); /* read binary (b for win32) */
+
+ if (lockfile)
+ {
+ i=0;
+ c=0;
+ while ((i<255) && (c != 10) && (c != EOF)) /* first line is email status */
+ {
+ c = fgetc(lockfile);
+ buf[i++] = c;
+ }
+ buf[i-1] = 0;
+
+ fscanf(lockfile, "%d\n", &val);
+
+ fclose(lockfile);
+
+ if ( (!strcmp(buf, TEXT_EMAIL_STATUS_SENDING)) ||
+ (!strcmp(buf, TEXT_EMAIL_STATUS_SENT)) ||
+ (!strcmp(buf, TEXT_PROJECT_STATUS_ERR_READ_PROJECT)) ||
+ (!strcmp(buf, TEXT_EMAIL_STATUS_POP3_CONNECTION_FAILED)) ||
+ (!strcmp(buf, TEXT_EMAIL_STATUS_POP3_LOGIN_FAILED)) ||
+ (!strcmp(buf, TEXT_EMAIL_STATUS_ASMTP_AUTH_FAILED)) ||
+ (!strcmp(buf, TEXT_EMAIL_STATUS_SMTP_CONNECTION_FAILED)) ||
+ (!strcmp(buf, TEXT_EMAIL_STATUS_SMTP_ERR_FROM)) ||
+ (!strcmp(buf, TEXT_EMAIL_STATUS_SMTP_ERR_RCPT)) ||
+ (!strcmp(buf, TEXT_EMAIL_STATUS_SMTP_ERR_DATA)) ||
+ (!strcmp(buf, TEXT_EMAIL_STATUS_SENT)) )
+ {
+ if (strcmp(xsane.email_status, buf))
+ {
+ if (xsane.email_status)
+ {
+ free(xsane.email_status);
+ }
+ xsane.email_status = strdup(buf);
+
+ if (xsane.project_progress_bar)
+ {
+ gtk_progress_set_format_string(GTK_PROGRESS(xsane.project_progress_bar), _(xsane.email_status));
+ }
+ }
+
+ xsane.email_progress_val = val / 100.0;
+ if (xsane.project_progress_bar)
+ {
+ gtk_progress_bar_update(GTK_PROGRESS_BAR(xsane.project_progress_bar), xsane.email_progress_val);
+ }
+
+ DBG(DBG_info, "reading from lockfile: email_status %s, email_progress_val %1.3f\n" , xsane.email_status, xsane.email_progress_val);
+
+ if (strcmp(xsane.email_status, TEXT_EMAIL_STATUS_SENDING)) /* not sending */
+ {
+ DBG(DBG_info, "removing %s\n", filename);
+ remove(filename); /* remove lockfile */
+
+ xsane.email_progress_val = 0.0;
+
+ xsane_email_project_update_project_status();
+
+ if (xsane.project_dialog)
+ {
+ xsane_email_project_load();
+
+ xsane_email_project_set_sensitive(TRUE);
+ gtk_widget_set_sensitive(GTK_WIDGET(xsane.start_button), TRUE);
+ }
+ }
+ }
+ }
+ else
+ {
+ DBG(DBG_info, "no lockfile present\n");
+ if (xsane.project_progress_bar)
+ {
+ gtk_progress_set_format_string(GTK_PROGRESS(xsane.project_progress_bar), _(xsane.email_status));
+ gtk_progress_bar_update(GTK_PROGRESS_BAR(xsane.project_progress_bar), xsane.email_progress_val);
+ }
+
+ while (gtk_events_pending())
+ {
+ gtk_main_iteration();
+ }
+ }
+}
+
+/* ---------------------------------------------------------------------------------------------------------------------- */
+
+static gint xsane_email_send_timer_callback(gpointer data)
+{
+ xsane_email_project_display_status();
+
+ if (strcmp(xsane.email_status, TEXT_EMAIL_STATUS_SENDING)) /* not sending */
+ {
+ if (xsane_email_send_timer)
+ {
+ DBG(DBG_info, "disabling email send timer\n");
+ xsane_email_send_timer = 0;
+ }
+ }
+
+ return xsane_email_send_timer;
+}
+
+/* ---------------------------------------------------------------------------------------------------------------------- */
+
+static void xsane_email_project_load()
+{
+ FILE *projectfile;
+ char page[256];
+ char *type;
+ char *extension;
+ char buf[256];
+ char filename[PATH_MAX];
+ GtkWidget *list_item;
+ int i;
+ int c;
+
+ DBG(DBG_proc, "xsane_email_project_load\n");
+
+ if (xsane.email_status)
+ {
+ free(xsane.email_status);
+ xsane.email_status = NULL;
+ }
+
+ if (xsane.email_receiver)
+ {
+ free(xsane.email_receiver);
+ xsane.email_receiver = NULL;
+ }
+
+ if (xsane.email_filename)
+ {
+ free(xsane.email_filename);
+ xsane.email_filename = NULL;
+ }
+
+ if (xsane.email_subject)
+ {
+ free(xsane.email_subject);
+ xsane.email_subject = NULL;
+ }
+
+ g_signal_handlers_disconnect_by_func(GTK_OBJECT(xsane.email_receiver_entry), GTK_SIGNAL_FUNC(xsane_email_receiver_changed_callback), 0);
+ g_signal_handlers_disconnect_by_func(GTK_OBJECT(xsane.email_subject_entry), GTK_SIGNAL_FUNC(xsane_email_subject_changed_callback), 0);
+ g_signal_handlers_disconnect_by_func(GTK_OBJECT(xsane.email_html_mode_widget), GTK_SIGNAL_FUNC(xsane_email_html_mode_callback), 0);
+
+#ifdef HAVE_GTK_TEXT_VIEW_H
+ gtk_text_buffer_set_text(GTK_TEXT_BUFFER(xsane.email_text_widget), "", 0);
+#else
+ gtk_text_set_point(GTK_TEXT(xsane.email_text_widget), 0);
+ gtk_text_forward_delete(GTK_TEXT(xsane.email_text_widget), gtk_text_get_length(GTK_TEXT(xsane.email_text_widget)));
+#endif
+ gtk_list_remove_items(GTK_LIST(xsane.project_list), GTK_LIST(xsane.project_list)->children);
+
+ snprintf(filename, sizeof(filename), "%s/xsane-mail-list", preferences.email_project);
+ projectfile = fopen(filename, "rb"); /* read binary (b for win32) */
+
+ if ((!projectfile) || (feof(projectfile)))
+ {
+ snprintf(filename, sizeof(filename), "%s/image-1.pnm", preferences.email_project);
+ xsane.email_filename=strdup(filename);
+ xsane_update_counter_in_filename(&xsane.email_filename, FALSE, 0, preferences.filename_counter_len); /* correct counter len */
+
+ xsane.email_status=strdup(TEXT_PROJECT_STATUS_NOT_CREATED);
+ xsane.email_progress_val = 0.0;
+
+ xsane.email_receiver=strdup("");
+ gtk_entry_set_text(GTK_ENTRY(xsane.email_receiver_entry), (char *) xsane.email_receiver);
+
+ xsane.email_subject=strdup("");
+ gtk_entry_set_text(GTK_ENTRY(xsane.email_subject_entry), (char *) xsane.email_subject);
+
+ gtk_widget_hide(xsane.project_exists);
+ gtk_widget_show(xsane.project_not_exists);
+
+ gtk_widget_set_sensitive(xsane.project_box, FALSE);
+ gtk_widget_set_sensitive(xsane.project_exists, FALSE);
+ /* do not change sensitivity of email_project_entry_box here !!! */
+ gtk_widget_set_sensitive(GTK_WIDGET(xsane.start_button), FALSE);
+
+ xsane.email_project_save = 0;
+ }
+ else
+ {
+ i=0;
+ c=0;
+ while ((i<255) && (c != 10) && (c != EOF)) /* first line is email status */
+ {
+ c = fgetc(projectfile);
+ page[i++] = c;
+ }
+ page[i-1] = 0;
+ if (strchr(page, '@'))
+ {
+ *strchr(page, '@') = 0;
+ }
+
+ if (xsane.email_status)
+ {
+ free(xsane.email_status);
+ }
+ xsane.email_status = strdup(page);
+ xsane.email_progress_val = 0.0;
+
+
+ i=0;
+ c=0;
+ while ((i<255) && (c != 10) && (c != EOF)) /* second line is email address */
+ {
+ c = fgetc(projectfile);
+ page[i++] = c;
+ }
+ page[i-1] = 0;
+
+ xsane.email_receiver=strdup(page);
+ gtk_entry_set_text(GTK_ENTRY(xsane.email_receiver_entry), (char *) xsane.email_receiver);
+
+
+ i=0;
+ c=0;
+ while ((i<255) && (c != 10) && (c != EOF)) /* third line is next email filename */
+ {
+ c = fgetc(projectfile);
+ page[i++] = c;
+ }
+ page[i-1] = 0;
+
+ snprintf(filename, sizeof(filename), "%s/%s", preferences.email_project, page);
+ xsane.email_filename=strdup(filename);
+
+
+ i=0;
+ c=0;
+ while ((i<255) && (c != 10) && (c != EOF)) /* fourth line is subject */
+ {
+ c = fgetc(projectfile);
+ page[i++] = c;
+ }
+ page[i-1] = 0;
+
+ xsane.email_subject=strdup(page);
+ gtk_entry_set_text(GTK_ENTRY(xsane.email_subject_entry), (char *) xsane.email_subject);
+
+
+ i=0;
+ c=0;
+ while ((i<255) && (c != 10) && (c != EOF)) /* fifth line is html/ascii */
+ {
+ c = fgetc(projectfile);
+ page[i++] = c;
+ }
+ page[i-1] = 0;
+
+ if (!strcasecmp("html", page))
+ {
+ xsane.email_html_mode = 1;
+ }
+ else
+ {
+ xsane.email_html_mode = 0;
+ }
+
+ gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(xsane.email_html_mode_widget), xsane.email_html_mode);
+
+
+ while (!feof(projectfile))
+ {
+ i=0;
+ c=0;
+
+ while ((i<255) && (c != 10) && (c != EOF))
+ {
+ c = fgetc(projectfile);
+ page[i++] = c;
+ }
+ page[i-1]=0;
+
+ if (!strcmp("mailtext:", page))
+ {
+ break; /* emailtext follows */
+ }
+
+ extension = strrchr(page, '.');
+ if (extension)
+ {
+ type = strdup(extension);
+ *extension = 0;
+ }
+ else
+ {
+ type = strdup("");
+ }
+
+ if (c > 1)
+ {
+ list_item = gtk_list_item_new_with_label(page);
+ gtk_object_set_data(GTK_OBJECT(list_item), "list_item_data", strdup(page));
+ gtk_object_set_data(GTK_OBJECT(list_item), "list_item_type", strdup(type));
+ gtk_container_add(GTK_CONTAINER(xsane.project_list), list_item);
+ gtk_widget_show(list_item);
+ }
+ }
+
+ while (!feof(projectfile))
+ {
+ i = fread(buf, 1, sizeof(buf), projectfile);
+#ifdef HAVE_GTK_TEXT_VIEW_H
+ gtk_text_buffer_insert_at_cursor(GTK_TEXT_BUFFER(xsane.email_text_widget), buf, i);
+#else
+ gtk_text_insert(GTK_TEXT(xsane.email_text_widget), NULL, NULL, NULL, buf, i);
+#endif
+ }
+
+ if (!strcmp(xsane.email_status, TEXT_EMAIL_STATUS_SENDING)) /* email project is locked (sending) */
+ {
+ xsane_email_project_set_sensitive(FALSE);
+ gtk_widget_set_sensitive(xsane.project_entry_box, TRUE);
+ gtk_widget_set_sensitive(GTK_WIDGET(xsane.start_button), FALSE);
+
+ if (xsane_email_send_timer == 0)
+ {
+ xsane_email_send_timer = gtk_timeout_add(100, (GtkFunction) xsane_email_send_timer_callback, NULL);
+ DBG(DBG_info, "enabling email send timer (%d)\n", xsane_email_send_timer);
+ }
+ }
+ else
+ {
+ xsane_email_project_set_sensitive(TRUE);
+ gtk_widget_set_sensitive(xsane.project_entry_box, TRUE);
+ gtk_widget_set_sensitive(GTK_WIDGET(xsane.start_button), TRUE);
+ }
+
+ gtk_widget_show(xsane.project_exists);
+ gtk_widget_hide(xsane.project_not_exists);
+
+ xsane.email_project_save = 1;
+ }
+
+ if (projectfile)
+ {
+ fclose(projectfile);
+ }
+
+ gtk_progress_set_format_string(GTK_PROGRESS(xsane.project_progress_bar), _(xsane.email_status));
+ gtk_progress_bar_update(GTK_PROGRESS_BAR(xsane.project_progress_bar), xsane.email_progress_val);
+
+ xsane_email_project_display_status();
+
+ g_signal_connect(GTK_OBJECT(xsane.email_html_mode_widget), "clicked", (GtkSignalFunc) xsane_email_html_mode_callback, NULL);
+ g_signal_connect(GTK_OBJECT(xsane.email_receiver_entry), "changed", (GtkSignalFunc) xsane_email_receiver_changed_callback, NULL);
+ g_signal_connect(GTK_OBJECT(xsane.email_subject_entry), "changed", (GtkSignalFunc) xsane_email_subject_changed_callback, NULL);
+}
+
+/* ---------------------------------------------------------------------------------------------------------------------- */
+
+static void xsane_email_project_delete()
+{
+ char *page;
+ char *type;
+ char file[256];
+ GList *list = (GList *) GTK_LIST(xsane.project_list)->children;
+ GtkObject *list_item;
+
+ DBG(DBG_proc, "xsane_email_project_delete\n");
+
+ while (list)
+ {
+ list_item = GTK_OBJECT(list->data);
+ page = strdup((char *) gtk_object_get_data(list_item, "list_item_data"));
+ type = strdup((char *) gtk_object_get_data(list_item, "list_item_type"));
+ xsane_convert_text_to_filename(&page);
+ snprintf(file, sizeof(file), "%s/%s%s", preferences.email_project, page, type);
+ free(page);
+ free(type);
+ remove(file);
+ list = list->next;
+ }
+ snprintf(file, sizeof(file), "%s/xsane-mail-list", preferences.email_project);
+ remove(file);
+ snprintf(file, sizeof(file), "%s", preferences.email_project);
+ rmdir(file);
+
+ xsane_email_project_load();
+}
+
+/* ---------------------------------------------------------------------------------------------------------------------- */
+
+static void xsane_email_project_update_project_status()
+{
+ FILE *projectfile;
+ char filename[PATH_MAX];
+ char buf[256];
+
+ snprintf(filename, sizeof(filename), "%s/xsane-mail-list", preferences.email_project);
+ projectfile = fopen(filename, "r+b"); /* r+ = read and write, position = start of file */
+
+ snprintf(buf, 32, "%s@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@", xsane.email_status); /* fill 32 characters status line */
+ fprintf(projectfile, "%s\n", buf); /* first line is status of email */
+
+ fclose(projectfile);
+}
+
+/* ---------------------------------------------------------------------------------------------------------------------- */
+
+void xsane_email_project_save()
+{
+ FILE *projectfile;
+ GList *list = (GList *) GTK_LIST(xsane.project_list)->children;
+ GtkObject *list_item;
+ char *page;
+ char *type;
+ gchar *email_text;
+ char filename[256];
+
+ DBG(DBG_proc, "xsane_email_project_save\n");
+
+ umask((mode_t) preferences.directory_umask); /* define new file permissions */
+ mkdir(preferences.email_project, 0777); /* make sure directory exists */
+
+ snprintf(filename, sizeof(filename), "%s/xsane-mail-list", preferences.email_project);
+
+ if (xsane_create_secure_file(filename)) /* remove possibly existing symbolic links for security */
+ {
+ char buf[256];
+
+ snprintf(buf, sizeof(buf), "%s %s %s\n", ERR_DURING_SAVE, ERR_CREATE_SECURE_FILE, filename);
+ xsane_back_gtk_error(buf, TRUE);
+ return; /* error */
+ }
+
+ projectfile = fopen(filename, "wb"); /* write binary (b for win32) */
+
+ if (xsane.email_status)
+ {
+ char buf[256];
+
+ snprintf(buf, 32, "%s@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@", xsane.email_status); /* fill 32 characters status line */
+ fprintf(projectfile, "%s\n", buf); /* first line is status of email */
+ gtk_progress_set_format_string(GTK_PROGRESS(xsane.project_progress_bar), _(xsane.email_status));
+ gtk_progress_bar_update(GTK_PROGRESS_BAR(xsane.project_progress_bar), 0.0);
+ }
+ else
+ {
+ fprintf(projectfile, " \n"); /* no email status */
+ gtk_progress_set_format_string(GTK_PROGRESS(xsane.project_progress_bar), "");
+ gtk_progress_bar_update(GTK_PROGRESS_BAR(xsane.project_progress_bar), 0.0);
+ }
+
+ if (xsane.email_receiver)
+ {
+ fprintf(projectfile, "%s\n", xsane.email_receiver); /* second line is receiver phone number or address */
+ }
+ else
+ {
+ fprintf(projectfile, "\n");
+ }
+
+ if (xsane.email_filename)
+ {
+ fprintf(projectfile, "%s\n", strrchr(xsane.email_filename, '/')+1); /* third line is next email filename */
+ }
+ else
+ {
+ fprintf(projectfile, "\n");
+ }
+
+ if (xsane.email_subject)
+ {
+ fprintf(projectfile, "%s\n", xsane.email_subject); /* fourth line is subject */
+ }
+ else
+ {
+ fprintf(projectfile, "\n");
+ }
+
+ if (xsane.email_html_mode) /* fith line is mode html/ascii */
+ {
+ fprintf(projectfile, "html\n");
+ }
+ else
+ {
+ fprintf(projectfile, "ascii\n");
+ }
+
+
+ while (list)
+ {
+ list_item = GTK_OBJECT(list->data);
+ page = (char *) gtk_object_get_data(list_item, "list_item_data");
+ type = (char *) gtk_object_get_data(list_item, "list_item_type");
+ fprintf(projectfile, "%s%s\n", page, type);
+ list = list->next;
+ }
+
+ /* save email text */
+ fprintf(projectfile, "mailtext:\n");
+#ifdef HAVE_GTK_TEXT_VIEW_H
+ {
+ GtkTextIter start, end;
+
+ gtk_text_buffer_get_start_iter(GTK_TEXT_BUFFER(xsane.email_text_widget), &start);
+ gtk_text_buffer_get_end_iter(GTK_TEXT_BUFFER(xsane.email_text_widget), &end);
+ email_text = gtk_text_buffer_get_text(GTK_TEXT_BUFFER(xsane.email_text_widget), &start, &end, FALSE);
+ }
+#else
+ email_text = gtk_editable_get_chars(GTK_EDITABLE(xsane.email_text_widget), 0, -1);
+#endif
+ fprintf(projectfile, "%s", email_text);
+
+ fclose(projectfile);
+}
+
+/* ---------------------------------------------------------------------------------------------------------------------- */
+
+static void xsane_email_project_create()
+{
+ DBG(DBG_proc, "xsane_email_project_create\n");
+
+ if (strlen(preferences.email_project))
+ {
+ if (xsane.email_status)
+ {
+ free(xsane.email_status);
+ }
+ xsane.email_status = strdup(TEXT_PROJECT_STATUS_CREATED);
+ xsane_email_project_save();
+ xsane_email_project_load();
+ }
+}
+
+/* ---------------------------------------------------------------------------------------------------------------------- */
+
+static void xsane_email_receiver_changed_callback(GtkWidget *widget, gpointer data)
+{
+ DBG(DBG_proc, "xsane_email_receiver_changed_callback\n");
+
+ if (xsane.email_receiver)
+ {
+ free((void *) xsane.email_receiver);
+ }
+ xsane.email_receiver = strdup(gtk_entry_get_text(GTK_ENTRY(widget)));
+
+ if (xsane.email_status)
+ {
+ free(xsane.email_status);
+ }
+ xsane.email_status = strdup(TEXT_PROJECT_STATUS_CHANGED);
+ xsane.email_project_save = 1;
+ xsane_email_project_display_status();
+}
+
+/* ---------------------------------------------------------------------------------------------------------------------- */
+
+static void xsane_email_subject_changed_callback(GtkWidget *widget, gpointer data)
+{
+ DBG(DBG_proc, "xsane_email_subject_changed_callback\n");
+
+ if (xsane.email_subject)
+ {
+ free((void *) xsane.email_subject);
+ }
+ xsane.email_subject = strdup(gtk_entry_get_text(GTK_ENTRY(widget)));
+
+ if (xsane.email_status)
+ {
+ free(xsane.email_status);
+ }
+ xsane.email_status = strdup(TEXT_PROJECT_STATUS_CHANGED);
+ xsane.email_project_save = 1;
+ xsane_email_project_display_status();
+}
+
+/* ---------------------------------------------------------------------------------------------------------------------- */
+
+static void xsane_email_project_changed_callback(GtkWidget *widget, gpointer data)
+{
+ DBG(DBG_proc, "xsane_email_project_changed_callback\n");
+
+ if (xsane.email_project_save)
+ {
+ xsane.email_project_save = 0;
+ xsane_email_project_save();
+ }
+
+ if (preferences.email_project)
+ {
+ free((void *) preferences.email_project);
+ }
+ preferences.email_project = strdup(gtk_entry_get_text(GTK_ENTRY(widget)));
+
+ xsane_email_project_load();
+}
+
+/* ---------------------------------------------------------------------------------------------------------------------- */
+
+static void xsane_email_html_mode_callback(GtkWidget * widget)
+{
+ DBG(DBG_proc, "xsane_email_html_mode_callback\n");
+
+ xsane.email_html_mode = (GTK_TOGGLE_BUTTON(widget)->active != 0);
+
+ /* we can save it because this routine is only called when the project already exists */
+ if (xsane.email_status)
+ {
+ free(xsane.email_status);
+ }
+ xsane.email_status = strdup(TEXT_PROJECT_STATUS_CHANGED);
+ xsane.email_project_save = 1;
+ xsane_email_project_display_status();
+}
+
+/* ---------------------------------------------------------------------------------------------------------------------- */
+
+static void xsane_email_entry_move_up_callback(GtkWidget *widget, gpointer list)
+{
+ GList *select;
+ GList *item = GTK_LIST(list)->children;
+ GtkWidget *list_item_1;
+ GtkWidget *list_item_2;
+ int position;
+ int newpos;
+
+ DBG(DBG_proc, "xsane_email_entry_move_up\n");
+
+ select = GTK_LIST(list)->selection;
+ if (select)
+ {
+ list_item_1 = select->data;
+
+ position = gtk_list_child_position(GTK_LIST(list), list_item_1);
+ position--; /* move up */
+ newpos = position;
+
+ if (position >= 0)
+ {
+ while (position>0)
+ {
+ item = item->next;
+ position--;
+ }
+
+ list_item_2 = item->data;
+ if (list_item_2)
+ {
+ xsane_front_gtk_list_entries_swap(list_item_1, list_item_2);
+ gtk_list_select_item(GTK_LIST(list), newpos);
+
+ if (xsane.email_status)
+ {
+ free(xsane.email_status);
+ }
+ xsane.email_status = strdup(TEXT_PROJECT_STATUS_CHANGED);
+ xsane_email_project_save();
+ }
+ }
+ }
+}
+
+/* ---------------------------------------------------------------------------------------------------------------------- */
+
+static void xsane_email_entry_move_down_callback(GtkWidget *widget, gpointer list)
+{
+ GList *select;
+ GList *item = GTK_LIST(list)->children;
+ GtkWidget *list_item_1;
+ GtkWidget *list_item_2;
+ int position;
+ int newpos;
+
+ DBG(DBG_proc, "xsane_email_entry_move_down\n");
+
+ select = GTK_LIST(list)->selection;
+ if (select)
+ {
+ list_item_1 = select->data;
+
+ position = gtk_list_child_position(GTK_LIST(list), list_item_1);
+ position++; /* move down */
+ newpos = position;
+
+ while ((position>0) && (item))
+ {
+ item = item->next;
+ position--;
+ }
+
+ if (item)
+ {
+ list_item_2 = item->data;
+ if (list_item_2)
+ {
+ xsane_front_gtk_list_entries_swap(list_item_1, list_item_2);
+ gtk_list_select_item(GTK_LIST(list), newpos);
+
+ if (xsane.email_status)
+ {
+ free(xsane.email_status);
+ }
+ xsane.email_status = strdup(TEXT_PROJECT_STATUS_CHANGED);
+ xsane_email_project_save();
+ }
+ }
+ }
+}
+
+/* ---------------------------------------------------------------------------------------------------------------------- */
+
+int xsane_email_entry_rename;
+
+static void xsane_email_entry_rename_button_callback(GtkWidget *widget, gpointer data)
+{
+ DBG(DBG_proc, "xsane_email_entry_rename\n");
+
+ xsane_email_entry_rename = (int) data;
+}
+
+/* ---------------------------------------------------------------------------------------------------------------------- */
+
+static void xsane_email_entry_rename_callback(GtkWidget *widget, gpointer list)
+{
+ GtkWidget *list_item;
+ GList *select;
+ char *oldpage;
+ char *newpage;
+ char *type;
+ char oldfile[256];
+ char newfile[256];
+
+ DBG(DBG_proc, "xsane_email_entry_rename_callback\n");
+
+ select = GTK_LIST(list)->selection;
+ if (select)
+ {
+ GtkWidget *rename_dialog;
+ GtkWidget *text;
+ GtkWidget *button;
+ GtkWidget *vbox, *hbox;
+ char filename[PATH_MAX];
+
+ list_item = select->data;
+ oldpage = strdup((char *) gtk_object_get_data(GTK_OBJECT(list_item), "list_item_data"));
+ type = strdup((char *) gtk_object_get_data(GTK_OBJECT(list_item), "list_item_type"));
+
+ xsane_set_sensitivity(FALSE);
+
+ rename_dialog = gtk_window_new(GTK_WINDOW_TOPLEVEL);
+ xsane_set_window_icon(rename_dialog, 0);
+
+ /* set the main vbox */
+ vbox = gtk_vbox_new(FALSE, 0);
+ gtk_container_set_border_width(GTK_CONTAINER(vbox), 0);
+ gtk_container_add(GTK_CONTAINER(rename_dialog), vbox);
+ gtk_widget_show(vbox);
+
+ /* set the main hbox */
+ hbox = gtk_hbox_new(FALSE, 0);
+ xsane_separator_new(vbox, 2);
+ gtk_box_pack_end(GTK_BOX(vbox), hbox, FALSE, FALSE, 5);
+ gtk_container_set_border_width(GTK_CONTAINER(hbox), 5);
+ gtk_widget_show(hbox);
+
+ gtk_window_set_position(GTK_WINDOW(rename_dialog), GTK_WIN_POS_CENTER);
+ gtk_window_set_resizable(GTK_WINDOW(rename_dialog), FALSE);
+ snprintf(filename, sizeof(filename), "%s %s", xsane.prog_name, WINDOW_EMAIL_RENAME);
+ gtk_window_set_title(GTK_WINDOW(rename_dialog), filename);
+ g_signal_connect(GTK_OBJECT(rename_dialog), "delete_event", (GtkSignalFunc) xsane_email_entry_rename_button_callback, (void *) -1);
+ gtk_widget_show(rename_dialog);
+
+ text = gtk_entry_new();
+ xsane_back_gtk_set_tooltip(xsane.tooltips, text, DESC_EMAIL_IMAGENAME);
+ gtk_entry_set_max_length(GTK_ENTRY(text), 64);
+ gtk_entry_set_text(GTK_ENTRY(text), oldpage);
+ gtk_widget_set_size_request(text, 300, -1);
+ gtk_box_pack_start(GTK_BOX(vbox), text, TRUE, TRUE, 4);
+ gtk_widget_show(text);
+
+
+#ifdef HAVE_GTK2
+ button = gtk_button_new_from_stock(GTK_STOCK_OK);
+#else
+ button = gtk_button_new_with_label(BUTTON_OK);
+#endif
+ g_signal_connect(GTK_OBJECT(button), "clicked", (GtkSignalFunc) xsane_email_entry_rename_button_callback, (void *) 1);
+ gtk_box_pack_start(GTK_BOX(hbox), button, TRUE, TRUE, 0);
+ gtk_widget_show(button);
+
+#ifdef HAVE_GTK2
+ button = gtk_button_new_from_stock(GTK_STOCK_CANCEL);
+#else
+ button = gtk_button_new_with_label(BUTTON_CANCEL);
+#endif
+ g_signal_connect(GTK_OBJECT(button), "clicked", (GtkSignalFunc) xsane_email_entry_rename_button_callback,(void *) -1);
+ gtk_box_pack_start(GTK_BOX(hbox), button, TRUE, TRUE, 0);
+ gtk_widget_show(button);
+
+
+ xsane_email_entry_rename = 0;
+
+ while (xsane_email_entry_rename == 0)
+ {
+ while (gtk_events_pending())
+ {
+ gtk_main_iteration();
+ }
+ }
+
+ newpage = strdup(gtk_entry_get_text(GTK_ENTRY(text)));
+
+ if (xsane_email_entry_rename == 1)
+ {
+ gtk_label_set(GTK_LABEL(gtk_container_children(GTK_CONTAINER(list_item))->data), newpage);
+ gtk_object_set_data(GTK_OBJECT(list_item), "list_item_data", strdup(newpage));
+
+ xsane_convert_text_to_filename(&oldpage);
+ xsane_convert_text_to_filename(&newpage);
+ snprintf(oldfile, sizeof(oldfile), "%s/%s%s", preferences.email_project, oldpage, type);
+ snprintf(newfile, sizeof(newfile), "%s/%s%s", preferences.email_project, newpage, type);
+
+ rename(oldfile, newfile);
+
+ if (xsane.email_status)
+ {
+ free(xsane.email_status);
+ }
+ xsane.email_status = strdup(TEXT_PROJECT_STATUS_CHANGED);
+ xsane_email_project_save();
+ }
+
+ free(oldpage);
+ free(newpage);
+
+ gtk_widget_destroy(rename_dialog);
+
+ xsane_set_sensitivity(TRUE);
+ }
+}
+
+/* ---------------------------------------------------------------------------------------------------------------------- */
+
+static void xsane_email_entry_delete_callback(GtkWidget *widget, gpointer list)
+{
+ GtkObject *list_item;
+ GList *select;
+ char *page;
+ char *type;
+ char file[256];
+
+ DBG(DBG_proc, "xsane_email_entry_delete_callback\n");
+
+ select = GTK_LIST(list)->selection;
+ if (select)
+ {
+ list_item = GTK_OBJECT(select->data);
+ page = strdup((char *) gtk_object_get_data(list_item, "list_item_data"));
+ type = strdup((char *) gtk_object_get_data(list_item, "list_item_type"));
+ xsane_convert_text_to_filename(&page);
+ snprintf(file, sizeof(file), "%s/%s%s", preferences.email_project, page, type);
+ free(page);
+ free(type);
+ remove(file);
+ gtk_widget_destroy(GTK_WIDGET(list_item));
+
+ if (xsane.email_status)
+ {
+ free(xsane.email_status);
+ }
+ xsane.email_status = strdup(TEXT_PROJECT_STATUS_CHANGED);
+ xsane_email_project_save();
+ }
+}
+
+/* ---------------------------------------------------------------------------------------------------------------------- */
+
+static void xsane_email_show_callback(GtkWidget *widget, gpointer list)
+{
+ GtkObject *list_item;
+ GList *select;
+ char *page;
+ char *type;
+ char filename[256];
+
+ DBG(DBG_proc, "xsane_email_entry_show_callback\n");
+
+ select = GTK_LIST(list)->selection;
+ if (select)
+ {
+ list_item = GTK_OBJECT(select->data);
+ page = strdup((char *) gtk_object_get_data(list_item, "list_item_data"));
+ type = strdup((char *) gtk_object_get_data(list_item, "list_item_type"));
+ xsane_convert_text_to_filename(&page);
+ snprintf(filename, sizeof(filename), "%s/%s%s", preferences.email_project, page, type);
+ free(page);
+ free(type);
+
+ xsane_viewer_new(filename, NULL, FALSE, filename, VIEWER_NO_MODIFICATION, IMAGE_SAVED);
+ }
+}
+
+/* ---------------------------------------------------------------------------------------------------------------------- */
+
+#if 0
+static void xsane_email_edit_callback(GtkWidget *widget, gpointer list)
+{
+ GtkObject *list_item;
+ GList *select;
+ char *page;
+ char *type;
+ char filename[256];
+ char outfilename[256];
+ Image_info image_info;
+ int cancel_save = 0;
+
+ DBG(DBG_proc, "xsane_email_entry_show_callback\n");
+
+ select = GTK_LIST(list)->selection;
+ if (select)
+ {
+ list_item = GTK_OBJECT(select->data);
+ page = strdup((char *) gtk_object_get_data(list_item, "list_item_data"));
+ type = strdup((char *) gtk_object_get_data(list_item, "list_item_type"));
+ xsane_convert_text_to_filename(&page);
+ snprintf(filename, sizeof(filename), "%s/%s%s", preferences.email_project, page, type);
+ free(page);
+ free(type);
+
+ xsane_back_gtk_make_path(sizeof(outfilename), outfilename, 0, 0, "xsane-viewer-", xsane.dev_name, ".pnm", XSANE_PATH_TMP);
+ xsane_copy_file_by_name(outfilename, filename, xsane.multipage_progress_bar, &cancel_save);
+
+ gtk_progress_set_format_string(GTK_PROGRESS(xsane.project_progress_bar), "");
+ gtk_progress_bar_update(GTK_PROGRESS_BAR(xsane.project_progress_bar), 0.0);
+
+ xsane_viewer_new(outfilename, NULL, FALSE, filename, VIEWER_NO_NAME_MODIFICATION, IMAGE_SAVED);
+ }
+}
+#endif
+
+/* ---------------------------------------------------------------------------------------------------------------------- */
+
+static void xsane_create_email(int fd)
+{
+ FILE *attachment_file;
+ FILE *projectfile;
+ char *boundary="-----partseparator";
+ char *image_filename;
+ char *email_text = NULL;
+ char *email_text_pos = NULL;
+ char **attachment_filename = NULL;
+ char *mime_type = NULL;
+ char buf[256];
+ char filename[256];
+ char content_id[256];
+ char image[256];
+ int i, j;
+ int c;
+ int attachments = 0;
+ int use_attachment = 0;
+ int email_text_size = 0;
+ int display_images_inline = FALSE;
+
+ DBG(DBG_proc, "xsane_create_email\n");
+
+ snprintf(filename, sizeof(filename), "%s/xsane-mail-list", preferences.email_project);
+ projectfile = fopen(filename, "rb"); /* read binary (b for win32) */
+
+ if ((!projectfile) || (feof(projectfile)))
+ {
+ DBG(DBG_error, "could not open email project file %s\n", filename);
+
+ if (xsane.email_status)
+ {
+ free(xsane.email_status);
+ }
+ xsane.email_status = strdup(TEXT_PROJECT_STATUS_ERR_READ_PROJECT);
+ xsane.email_progress_val = 0.0;
+ xsane_front_gtk_email_project_update_lockfile_status();
+
+ return;
+ }
+
+ for (i=0; i<5; i++) /* skip 5 lines */
+ {
+ j=0;
+ c=0;
+ while ((j<255) && (c != 10) && (c != EOF)) /* first line is email status */
+ {
+ c = fgetc(projectfile);
+ j++;
+ }
+ }
+
+ if (!strcmp(preferences.email_filetype, XSANE_FILETYPE_PNG))
+ {
+ mime_type = "image/png";
+ display_images_inline = TRUE;
+ }
+ else if (!strcmp(preferences.email_filetype, XSANE_FILETYPE_JPEG))
+ {
+ mime_type = "image/jpeg";
+ display_images_inline = TRUE;
+ }
+ else if (!strcmp(preferences.email_filetype, XSANE_FILETYPE_TIFF))
+ {
+ mime_type = "image/tiff";
+ display_images_inline = TRUE;
+ }
+ else if (!strcmp(preferences.email_filetype, XSANE_FILETYPE_PDF))
+ {
+ mime_type = "doc/pdf";
+ display_images_inline = FALSE;
+ }
+ else if (!strcmp(preferences.email_filetype, XSANE_FILETYPE_PS))
+ {
+ mime_type = "doc/postscript";
+ display_images_inline = FALSE;
+ }
+ else
+ {
+ mime_type = "doc/unknown";
+ display_images_inline = FALSE;
+ }
+
+ DBG(DBG_info, "reading list of attachments:\n");
+ /* read list of attachments */
+ while (!feof(projectfile))
+ {
+ /* read next attachment line */
+ i=0;
+ c=0;
+ while ((i<255) && (c != 10) && (c != EOF))
+ {
+ c = fgetc(projectfile);
+ image[i++] = c;
+ }
+ image[i-1]=0;
+
+ if (strcmp("mailtext:", image) && (c > 1))
+ {
+ char imagename[256];
+ char *filename;
+ char *extension;
+
+ DBG(DBG_info, " - %s\n", image);
+
+ extension = strrchr(image, '.');
+ if (extension)
+ {
+ *extension = 0;
+ }
+
+ snprintf(imagename, sizeof(imagename), "%s%s", image, preferences.email_filetype);
+ filename=strdup(imagename);
+ xsane_convert_text_to_filename(&filename);
+ attachment_filename = realloc(attachment_filename, (attachments+1)*sizeof(void *));
+ attachment_filename[attachments++] = strdup(filename);
+ free(filename);
+ }
+ else
+ {
+ break;
+ }
+ }
+
+ /* read email text */
+ while (!feof(projectfile))
+ {
+ email_text = realloc(email_text, email_text_size+1025); /* increase email_text by 1KB */
+ email_text_size += fread(email_text+email_text_size, 1, 1024, projectfile); /* read next KB */
+ }
+ DBG(DBG_info, "%d bytes emailtext read\n", email_text_size);
+
+ *(email_text + email_text_size) = 0; /* set end of text marker */
+ email_text_pos = email_text;
+
+ if (xsane.email_html_mode) /* create html email */
+ {
+ DBG(DBG_info, "sending email in html format\n");
+
+ write_email_header(fd, preferences.email_from, preferences.email_reply_to, xsane.email_receiver, xsane.email_subject, boundary, 1 /* related */);
+ write_email_mime_html(fd, boundary);
+
+ DBG(DBG_info, "sending email text\n");
+ while (*email_text_pos != 0)
+ {
+ if (!strncasecmp("<image>", email_text_pos, 7)) /* insert image */
+ {
+ email_text_pos += 6; /* <image> is 7 characters, 6 additional ones */
+
+ if (use_attachment < attachments)
+ {
+ image_filename = attachment_filename[use_attachment++];
+ DBG(DBG_info, "inserting image cid for %s\n", image_filename);
+ snprintf(content_id, sizeof(content_id), "%s", image_filename); /* content_id */
+
+ /* doc files like ps and pdf can not be displayed inline in html email */
+ if (display_images_inline)
+ {
+ snprintf(buf, sizeof(buf), "<p><img SRC=\"cid:%s\">\n", content_id);
+ }
+ write(fd, buf, strlen(buf));
+ }
+ else /* more images selected than available */
+ {
+ }
+ }
+ else if (*email_text_pos == 10) /* new line */
+ {
+ snprintf(buf, sizeof(buf), "<br>\n");
+ write(fd, buf, strlen(buf));
+ }
+ else
+ {
+ write(fd, email_text_pos, 1);
+ }
+ email_text_pos++;
+ }
+
+ while (use_attachment < attachments) /* append not already referenced images */
+ {
+ image_filename = attachment_filename[use_attachment++];
+ DBG(DBG_info, "appending image cid for %s\n", image_filename);
+ snprintf(content_id, sizeof(content_id), "%s", image_filename); /* content_id */
+
+ /* doc files like ps and pdf can not be displayed inline in html email */
+ if (display_images_inline)
+ {
+ snprintf(buf, sizeof(buf), "<p><img SRC=\"cid:%s\">\n", content_id);
+ }
+ write(fd, buf, strlen(buf));
+ }
+
+ snprintf(buf, sizeof(buf), "</html>\n");
+ write(fd, buf, strlen(buf));
+
+
+ for (i=0; i<attachments; i++)
+ {
+ image_filename = attachment_filename[i];
+ snprintf(content_id, sizeof(content_id), "%s", image_filename); /* content_id */
+ snprintf(filename, sizeof(filename), "%s/mail-%s", preferences.email_project, image_filename);
+ attachment_file = fopen(filename, "rb"); /* read, b=binary for win32 */
+
+ if (attachment_file)
+ {
+ DBG(DBG_info, "attaching file \"%s\" as \"%s\" with type %s\n", filename, image_filename, preferences.email_filetype);
+ write_email_attach_image(fd, boundary, content_id, mime_type, attachment_file, image_filename);
+
+ remove(filename);
+ }
+ else /* could not open attachment file */
+ {
+ DBG(DBG_error, "could not open attachment file \"%s\"\n", filename);
+ }
+
+ free(attachment_filename[i]);
+ }
+ free(attachment_filename);
+
+ write_email_footer(fd, boundary);
+ }
+ else /* ascii email */
+ {
+ DBG(DBG_info, "sending email in ascii format\n");
+
+ write_email_header(fd, preferences.email_from, preferences.email_reply_to, xsane.email_receiver, xsane.email_subject, boundary, 0 /* not related */);
+ write_email_mime_ascii(fd, boundary);
+
+ write(fd, email_text, strlen(email_text));
+ write(fd, "\n\n", 2);
+
+ for (i=0; i<attachments; i++)
+ {
+ image_filename = strdup(attachment_filename[i]);
+ snprintf(content_id, sizeof(content_id), "%s", image_filename); /* content_id */
+ snprintf(filename, sizeof(filename), "%s/mail-%s", preferences.email_project, image_filename);
+ attachment_file = fopen(filename, "rb"); /* read, b=binary for win32 */
+
+ if (attachment_file)
+ {
+ DBG(DBG_info, "attaching file \"%s\" as \"%s\" with type %s\n", filename, image_filename, preferences.email_filetype);
+ write_email_attach_image(fd, boundary, content_id, mime_type, attachment_file, image_filename);
+
+ remove(filename);
+ }
+ else /* could not open attachment file */
+ {
+ DBG(DBG_error, "could not oppen attachment png file \"%s\"\n", filename);
+ }
+
+ free(image_filename);
+ free(attachment_filename[i]);
+ }
+ free(attachment_filename);
+
+ write_email_footer(fd, boundary);
+ }
+
+ free(email_text);
+
+ if (projectfile)
+ {
+ fclose(projectfile);
+ }
+}
+
+/* ---------------------------------------------------------------------------------------------------------------------- */
+
+static void xsane_email_send_process()
+{
+ int fd_socket;
+ int status;
+ char *password;
+ int i;
+
+ DBG(DBG_proc, "xsane_email_send_process\n");
+
+ password = strdup(preferences.email_auth_pass);
+
+ for (i=0; i<strlen(password); i++)
+ {
+ password[i] ^= 0x53;
+ }
+
+ /* pop3 authentication */
+ if (preferences.email_authentication == EMAIL_AUTH_POP3)
+ {
+ fd_socket = open_socket(preferences.email_pop3_server, preferences.email_pop3_port);
+
+ if (fd_socket < 0) /* could not open socket */
+ {
+ if (xsane.email_status)
+ {
+ free(xsane.email_status);
+ }
+ xsane.email_status = strdup(TEXT_EMAIL_STATUS_POP3_CONNECTION_FAILED);
+ xsane.email_progress_val = 0.0;
+ xsane_front_gtk_email_project_update_lockfile_status();
+
+ free(password);
+
+ return;
+ }
+
+ status = pop3_login(fd_socket, preferences.email_auth_user, password);
+
+ close(fd_socket);
+
+ if (status == -1)
+ {
+ if (xsane.email_status)
+ {
+ free(xsane.email_status);
+ }
+ xsane.email_status = strdup(TEXT_EMAIL_STATUS_POP3_LOGIN_FAILED);
+ xsane.email_progress_val = 0.0;
+ xsane_front_gtk_email_project_update_lockfile_status();
+
+ free(password);
+
+ return;
+ }
+
+ DBG(DBG_info, "POP3 authentication done\n");
+ }
+
+
+
+ /* smtp email */
+ fd_socket = open_socket(preferences.email_smtp_server, preferences.email_smtp_port);
+
+ if (fd_socket < 0) /* could not open socket */
+ {
+ if (xsane.email_status)
+ {
+ free(xsane.email_status);
+ }
+ xsane.email_status = strdup(TEXT_EMAIL_STATUS_SMTP_CONNECTION_FAILED);
+ xsane.email_progress_val = 0.0;
+ xsane_front_gtk_email_project_update_lockfile_status();
+
+ free(password);
+
+ return;
+ }
+
+
+ status = write_smtp_header(fd_socket, preferences.email_from, xsane.email_receiver,
+ preferences.email_authentication, preferences.email_auth_user, password);
+ if (status == -1)
+ {
+ return;
+ }
+
+
+ xsane_create_email(fd_socket); /* create email and write to socket */
+
+ write_smtp_footer(fd_socket);
+
+ close(fd_socket);
+
+ if (xsane.email_status)
+ {
+ free(xsane.email_status);
+ }
+ xsane.email_status = strdup(TEXT_EMAIL_STATUS_SENT);
+ xsane.email_progress_val = 1.0;
+ xsane_front_gtk_email_project_update_lockfile_status();
+
+ free(password);
+
+ _exit(0);
+}
+
+/* ---------------------------------------------------------------------------------------------------------------------- */
+
+static void xsane_email_send()
+{
+ pid_t pid;
+ char *image;
+ char *type;
+ GList *list = (GList *) GTK_LIST(xsane.project_list)->children;
+ GtkObject *list_item;
+ char source_filename[PATH_MAX];
+ char email_filename[PATH_MAX];
+ int output_format;
+ int cancel_save = 0;
+
+ DBG(DBG_proc, "xsane_email_send\n");
+
+ xsane_set_sensitivity(FALSE); /* do not allow changing xsane mode */
+
+ while (gtk_events_pending())
+ {
+ DBG(DBG_info, "calling gtk_main_iteration\n");
+ gtk_main_iteration();
+ }
+
+ if (xsane.email_project_save)
+ {
+ xsane.email_project_save = 0;
+ xsane_email_project_save();
+ }
+
+ xsane.email_progress_size = 0;
+ xsane.email_progress_bytes = 0;
+
+ while (list)
+ {
+ list_item = GTK_OBJECT(list->data);
+ image = strdup((char *) gtk_object_get_data(list_item, "list_item_data"));
+ type = strdup((char *) gtk_object_get_data(list_item, "list_item_type"));
+ xsane_convert_text_to_filename(&image);
+ snprintf(source_filename, sizeof(source_filename), "%s/%s%s", preferences.email_project, image, type);
+ snprintf(email_filename, sizeof(email_filename), "%s/mail-%s%s", preferences.email_project, image, preferences.email_filetype);
+ free(image);
+ free(type);
+ DBG(DBG_info, "converting %s to %s\n", source_filename, email_filename);
+ output_format = xsane_identify_output_format(email_filename, NULL, NULL);
+ xsane_save_image_as(email_filename, source_filename, output_format, xsane.project_progress_bar, &cancel_save);
+ list = list->next;
+ xsane.email_progress_size += xsane_get_filesize(email_filename);
+ }
+
+
+ if (xsane.email_status)
+ {
+ free(xsane.email_status);
+ }
+ xsane.email_status = strdup(TEXT_EMAIL_STATUS_SENDING);
+ xsane.email_progress_val = 0.0;
+ xsane_email_project_display_status(); /* display status before creating lockfile! */
+ xsane_front_gtk_email_project_update_lockfile_status(); /* create lockfile and update status */
+
+ pid = fork();
+
+ if (pid == 0) /* new process */
+ {
+ FILE *ipc_file = NULL;
+
+ if (xsane.ipc_pipefd[0])
+ {
+ close(xsane.ipc_pipefd[0]); /* close reading end of pipe */
+ ipc_file = fdopen(xsane.ipc_pipefd[1], "w");
+ }
+
+ DBG(DBG_info, "trying to change user id for new subprocess:\n");
+ DBG(DBG_info, "old effective uid = %d\n", (int) geteuid());
+ setuid(getuid());
+ DBG(DBG_info, "new effective uid = %d\n", (int) geteuid());
+
+ xsane_email_send_process();
+
+ _exit(0); /* do not use exit() here! otherwise gtk gets in trouble */
+ }
+ else /* parent process */
+ {
+ xsane_front_gtk_add_process_to_list(pid); /* add pid to child process list */
+ }
+
+ xsane_email_send_timer = gtk_timeout_add(100, (GtkFunction) xsane_email_send_timer_callback, NULL);
+ DBG(DBG_info, "enabling email send timer (%d)\n", xsane_email_send_timer);
+
+ xsane_set_sensitivity(TRUE); /* allow changing xsane mode */
+#if 0
+ gtk_widget_set_sensitive(xsane.project_entry_box, TRUE);
+ gtk_widget_set_sensitive(GTK_WIDGET(xsane.start_button), FALSE);
+ gtk_widget_set_sensitive(xsane.project_box, FALSE);
+#endif
+ xsane_email_project_set_sensitive(FALSE);
+}
+
+#endif
diff --git a/src/xsane-email-project.h b/src/xsane-email-project.h
new file mode 100644
index 0000000..2148ef2
--- /dev/null
+++ b/src/xsane-email-project.h
@@ -0,0 +1,61 @@
+/* xsane -- a graphical (X11, gtk) scanner-oriented SANE frontend
+
+ xsane-email-project.h
+
+ Oliver Rauch <Oliver.Rauch@rauch-domain.de>
+ Copyright (C) 1998-2005 Oliver Rauch
+ This file is part of the XSANE package.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+/* ---------------------------------------------------------------------------------------------------------------------- */
+
+#ifndef HAVE_XSANE_EMAIL_PROJECT_H
+#define HAVE_XSANE_EMAIL_PROJECT_H
+
+
+#include "xsane.h"
+#include "xsane-back-gtk.h"
+#include "xsane-front-gtk.h"
+#include "xsane-preview.h"
+#include "xsane-save.h"
+#include "xsane-gamma.h"
+#include "xsane-setup.h"
+#include "xsane-scan.h"
+#include "xsane-rc-io.h"
+#include "xsane-device-preferences.h"
+#include "xsane-preferences.h"
+#include "xsane-icons.h"
+#include "xsane-batch-scan.h"
+
+#ifdef HAVE_LIBPNG
+# ifdef HAVE_LIBZ
+# include <png.h>
+# include <zlib.h>
+# endif
+#endif
+
+#include <sys/wait.h>
+
+/* ---------------------------------------------------------------------------------------------------------------------- */
+
+#ifdef XSANE_ACTIVATE_EMAIL
+
+extern void xsane_email_dialog(void);
+extern void xsane_email_project_save(void);
+
+#endif
+
+#endif
diff --git a/src/xsane-fax-project.c b/src/xsane-fax-project.c
new file mode 100644
index 0000000..0d0e4dc
--- /dev/null
+++ b/src/xsane-fax-project.c
@@ -0,0 +1,1312 @@
+/* xsane -- a graphical (X11, gtk) scanner-oriented SANE frontend
+
+ xsane-fax-project.c
+
+ Oliver Rauch <Oliver.Rauch@rauch-domain.de>
+ Copyright (C) 1998-2005 Oliver Rauch
+ This file is part of the XSANE package.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+/* ---------------------------------------------------------------------------------------------------------------------- */
+
+#include "xsane.h"
+#include "xsane-back-gtk.h"
+#include "xsane-front-gtk.h"
+#include "xsane-preview.h"
+#include "xsane-save.h"
+#include "xsane-gamma.h"
+#include "xsane-setup.h"
+#include "xsane-scan.h"
+#include "xsane-multipage-project.h"
+#include "xsane-fax-project.h"
+#include "xsane-rc-io.h"
+#include "xsane-device-preferences.h"
+#include "xsane-preferences.h"
+#include "xsane-icons.h"
+#include "xsane-batch-scan.h"
+
+#ifdef HAVE_LIBPNG
+#ifdef HAVE_LIBZ
+#include <png.h>
+#include <zlib.h>
+#endif
+#endif
+
+#include <sys/wait.h>
+
+/* ---------------------------------------------------------------------------------------------------------------------- */
+
+/* ---------------------------------------------------------------------------------------------------------------------- */
+
+/* forward declarations: */
+
+void xsane_fax_dialog(void);
+void xsane_fax_project_save(void);
+
+static gint xsane_fax_dialog_delete();
+static void xsane_fax_receiver_changed_callback(GtkWidget *widget, gpointer data);
+static void xsane_fax_project_changed_callback(GtkWidget *widget, gpointer data);
+static void xsane_fax_fine_mode_callback(GtkWidget *widget);
+static void xsane_fax_project_update_project_status();
+static void xsane_fax_project_load(void);
+static void xsane_fax_project_delete(void);
+static void xsane_fax_project_create(void);
+static void xsane_fax_entry_move_up_callback(GtkWidget *widget, gpointer list);
+static void xsane_fax_entry_move_down_callback(GtkWidget *widget, gpointer list);
+static void xsane_fax_entry_rename_callback(GtkWidget *widget, gpointer list);
+static void xsane_fax_entry_insert_callback(GtkWidget *widget, gpointer list);
+static void xsane_fax_entry_delete_callback(GtkWidget *widget, gpointer list);
+static void xsane_fax_show_callback(GtkWidget *widget, gpointer data);
+static void xsane_fax_send(void);
+
+/* ---------------------------------------------------------------------------------------------------------------------- */
+
+static gint xsane_fax_dialog_delete()
+{
+ return TRUE;
+}
+
+/* ---------------------------------------------------------------------------------------------------------------------- */
+
+void xsane_fax_dialog()
+{
+ GtkWidget *fax_dialog, *fax_scan_vbox, *fax_project_vbox, *hbox, *fax_project_exists_hbox, *button;
+ GtkWidget *scrolled_window, *list;
+ char buf[64];
+ GtkWidget *pixmapwidget, *text;
+ GtkWidget *pages_frame;
+ GdkBitmap *mask;
+ GdkPixmap *pixmap;
+
+ DBG(DBG_proc, "xsane_fax_dialog\n");
+
+ if (xsane.project_dialog)
+ {
+ return; /* window already is open */
+ }
+
+ /* GTK_WINDOW_TOPLEVEL looks better but does not place it nice*/
+ fax_dialog = gtk_window_new(GTK_WINDOW_TOPLEVEL);
+
+ snprintf(buf, sizeof(buf), "%s %s", xsane.prog_name, WINDOW_FAX_PROJECT);
+ gtk_window_set_title(GTK_WINDOW(fax_dialog), buf);
+ g_signal_connect(GTK_OBJECT(fax_dialog), "delete_event", (GtkSignalFunc) xsane_fax_dialog_delete, NULL);
+ xsane_set_window_icon(fax_dialog, 0);
+ gtk_window_add_accel_group(GTK_WINDOW(fax_dialog), xsane.accelerator_group);
+
+ /* set the main vbox */
+ fax_scan_vbox = gtk_vbox_new(FALSE, 0);
+ gtk_container_set_border_width(GTK_CONTAINER(fax_scan_vbox), 0);
+ gtk_container_add(GTK_CONTAINER(fax_dialog), fax_scan_vbox);
+ gtk_widget_show(fax_scan_vbox);
+
+ /* fax project */
+
+ hbox = gtk_hbox_new(FALSE, 2);
+ gtk_container_set_border_width(GTK_CONTAINER(hbox), 2);
+ gtk_box_pack_start(GTK_BOX(fax_scan_vbox), hbox, FALSE, FALSE, 1);
+
+ pixmap = gdk_pixmap_create_from_xpm_d(xsane.dialog->window, &mask, xsane.bg_trans, (gchar **) fax_xpm);
+ pixmapwidget = gtk_image_new_from_pixmap(pixmap, mask);
+ gtk_box_pack_start(GTK_BOX(hbox), pixmapwidget, FALSE, FALSE, 2);
+ gdk_drawable_unref(pixmap);
+
+ text = gtk_entry_new();
+ xsane_back_gtk_set_tooltip(xsane.tooltips, text, DESC_FAXPROJECT);
+ gtk_entry_set_max_length(GTK_ENTRY(text), 128);
+ gtk_entry_set_text(GTK_ENTRY(text), (char *) preferences.fax_project);
+ gtk_box_pack_start(GTK_BOX(hbox), text, TRUE, TRUE, 4);
+ g_signal_connect(GTK_OBJECT(text), "changed", (GtkSignalFunc) xsane_fax_project_changed_callback, NULL);
+
+ xsane.project_entry = text;
+ xsane.project_entry_box = hbox;
+
+ gtk_widget_show(pixmapwidget);
+ gtk_widget_show(text);
+ gtk_widget_show(hbox);
+
+ fax_project_vbox = gtk_vbox_new(/* homogeneous */ FALSE, 0);
+ gtk_box_pack_start(GTK_BOX(fax_scan_vbox), fax_project_vbox, TRUE, TRUE, 0);
+ gtk_widget_show(fax_project_vbox);
+
+ /* fax receiver */
+
+ hbox = gtk_hbox_new(FALSE, 2);
+ gtk_container_set_border_width(GTK_CONTAINER(hbox), 2);
+ gtk_box_pack_start(GTK_BOX(fax_project_vbox), hbox, FALSE, FALSE, 1);
+
+ gtk_widget_realize(fax_dialog);
+
+ pixmap = gdk_pixmap_create_from_xpm_d(fax_dialog->window, &mask, xsane.bg_trans, (gchar **) faxreceiver_xpm);
+ pixmapwidget = gtk_image_new_from_pixmap(pixmap, mask);
+ gtk_box_pack_start(GTK_BOX(hbox), pixmapwidget, FALSE, FALSE, 2);
+ gdk_drawable_unref(pixmap);
+
+ text = gtk_entry_new();
+ xsane_back_gtk_set_tooltip(xsane.tooltips, text, DESC_FAXRECEIVER);
+ gtk_entry_set_max_length(GTK_ENTRY(text), 128);
+ gtk_box_pack_start(GTK_BOX(hbox), text, TRUE, TRUE, 4);
+ g_signal_connect(GTK_OBJECT(text), "changed", (GtkSignalFunc) xsane_fax_receiver_changed_callback, NULL);
+
+ xsane.fax_receiver_entry = text;
+
+ gtk_widget_show(pixmapwidget);
+ gtk_widget_show(text);
+ gtk_widget_show(hbox);
+
+ /* fine mode */
+ button = gtk_check_button_new_with_label(RADIO_BUTTON_FINE_MODE);
+ xsane_back_gtk_set_tooltip(xsane.tooltips, button, DESC_FAX_FINE_MODE);
+ gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button), preferences.fax_fine_mode);
+ gtk_box_pack_start(GTK_BOX(fax_project_vbox), button, FALSE, FALSE, 2);
+ gtk_widget_show(button);
+ g_signal_connect(GTK_OBJECT(button), "clicked", (GtkSignalFunc) xsane_fax_fine_mode_callback, NULL);
+
+
+ /* pages frame */
+ pages_frame = gtk_frame_new(TEXT_PAGES);
+ gtk_box_pack_start(GTK_BOX(fax_project_vbox), pages_frame, TRUE, TRUE, 2);
+ gtk_widget_show(pages_frame);
+
+ scrolled_window = gtk_scrolled_window_new(0, 0);
+ gtk_widget_set_size_request(scrolled_window, 200, 100);
+ gtk_container_add(GTK_CONTAINER(pages_frame), scrolled_window);
+ gtk_widget_show(scrolled_window);
+
+ list = gtk_list_new();
+/* gtk_list_set_selection_mode(list, GTK_SELECTION_BROWSE); */
+
+ gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(scrolled_window), list);
+
+ gtk_widget_show(list);
+
+ xsane.project_list = list;
+
+
+ hbox = gtk_hbox_new(FALSE, 2);
+ gtk_container_set_border_width(GTK_CONTAINER(hbox), 2);
+ gtk_box_pack_start(GTK_BOX(fax_project_vbox), hbox, FALSE, FALSE, 1);
+
+ button = gtk_button_new_with_label(BUTTON_FILE_INSERT);
+ g_signal_connect(GTK_OBJECT(button), "clicked", (GtkSignalFunc) xsane_fax_entry_insert_callback, list);
+ gtk_box_pack_start(GTK_BOX(hbox), button, TRUE, TRUE, 0);
+ gtk_widget_show(button);
+
+ button = gtk_button_new_with_label(BUTTON_PAGE_SHOW);
+ g_signal_connect(GTK_OBJECT(button), "clicked", (GtkSignalFunc) xsane_fax_show_callback, list);
+ gtk_box_pack_start(GTK_BOX(hbox), button, TRUE, TRUE, 0);
+ gtk_widget_show(button);
+
+ button = gtk_button_new_with_label(BUTTON_PAGE_RENAME);
+ g_signal_connect(GTK_OBJECT(button), "clicked", (GtkSignalFunc) xsane_fax_entry_rename_callback, list);
+ gtk_box_pack_start(GTK_BOX(hbox), button, TRUE, TRUE, 0);
+ gtk_widget_show(button);
+
+ button = gtk_button_new_with_label(BUTTON_PAGE_DELETE);
+ g_signal_connect(GTK_OBJECT(button), "clicked", (GtkSignalFunc) xsane_fax_entry_delete_callback, list);
+ gtk_box_pack_start(GTK_BOX(hbox), button, TRUE, TRUE, 0);
+ gtk_widget_show(button);
+
+ xsane_button_new_with_pixmap(fax_dialog->window, hbox, move_up_xpm, 0, (GtkSignalFunc) xsane_fax_entry_move_up_callback, list);
+ xsane_button_new_with_pixmap(fax_dialog->window, hbox, move_down_xpm, 0, (GtkSignalFunc) xsane_fax_entry_move_down_callback, list);
+
+ gtk_widget_show(hbox);
+
+ xsane.project_box = fax_project_vbox;
+
+ /* set the main hbox */
+ hbox = gtk_hbox_new(FALSE, 0);
+ xsane_separator_new(fax_project_vbox, 2);
+ gtk_box_pack_end(GTK_BOX(fax_scan_vbox), hbox, FALSE, FALSE, 5);
+ gtk_container_set_border_width(GTK_CONTAINER(hbox), 5);
+ gtk_widget_show(hbox);
+
+
+ fax_project_exists_hbox = gtk_hbox_new(FALSE, 2);
+ gtk_box_pack_start(GTK_BOX(hbox), fax_project_exists_hbox, TRUE, TRUE, 0);
+
+ button = gtk_button_new_with_label(BUTTON_SEND_PROJECT);
+ g_signal_connect(GTK_OBJECT(button), "clicked", (GtkSignalFunc) xsane_fax_send, NULL);
+ gtk_box_pack_start(GTK_BOX(fax_project_exists_hbox), button, TRUE, TRUE, 0);
+ gtk_widget_show(button);
+
+ button = gtk_button_new_with_label(BUTTON_DELETE_PROJECT);
+ g_signal_connect(GTK_OBJECT(button), "clicked", (GtkSignalFunc) xsane_fax_project_delete, NULL);
+ gtk_box_pack_start(GTK_BOX(fax_project_exists_hbox), button, TRUE, TRUE, 0);
+ gtk_widget_show(button);
+
+ gtk_widget_show(fax_project_exists_hbox);
+ xsane.project_exists = fax_project_exists_hbox;
+
+ button = gtk_button_new_with_label(BUTTON_CREATE_PROJECT);
+ g_signal_connect(GTK_OBJECT(button), "clicked", (GtkSignalFunc) xsane_fax_project_create, NULL);
+ gtk_box_pack_start(GTK_BOX(hbox), button, TRUE, TRUE, 0);
+ xsane.project_not_exists = button;
+
+ /* progress bar */
+ xsane.project_progress_bar = (GtkProgressBar *) gtk_progress_bar_new();
+ gtk_box_pack_start(GTK_BOX(fax_scan_vbox), (GtkWidget *) xsane.project_progress_bar, FALSE, FALSE, 0);
+ gtk_progress_set_show_text(GTK_PROGRESS(xsane.project_progress_bar), TRUE);
+ gtk_progress_set_format_string(GTK_PROGRESS(xsane.project_progress_bar), "");
+ gtk_widget_show(GTK_WIDGET(xsane.project_progress_bar));
+
+
+ xsane.project_dialog = fax_dialog;
+
+ xsane_fax_project_load();
+
+ gtk_window_move(GTK_WINDOW(xsane.project_dialog), xsane.project_dialog_posx, xsane.project_dialog_posy);
+ gtk_widget_show(fax_dialog);
+}
+
+/* ---------------------------------------------------------------------------------------------------------------------- */
+
+static void xsane_fax_project_load()
+{
+ FILE *projectfile;
+ char page[256];
+ char filename[PATH_MAX];
+ GtkWidget *list_item;
+ int i;
+ int c;
+
+ DBG(DBG_proc, "xsane_fax_project_load\n");
+
+ if (xsane.fax_status)
+ {
+ free(xsane.fax_status);
+ xsane.fax_status = NULL;
+ }
+
+ if (xsane.fax_receiver)
+ {
+ free(xsane.fax_receiver);
+ xsane.fax_receiver = NULL;
+ }
+
+ g_signal_handlers_disconnect_by_func(GTK_OBJECT(xsane.fax_receiver_entry), GTK_SIGNAL_FUNC(xsane_fax_receiver_changed_callback), 0);
+ gtk_list_remove_items(GTK_LIST(xsane.project_list), GTK_LIST(xsane.project_list)->children);
+
+ snprintf(filename, sizeof(filename), "%s/xsane-fax-list", preferences.fax_project);
+ projectfile = fopen(filename, "rb"); /* read binary (b for win32) */
+
+ if ((!projectfile) || (feof(projectfile)))
+ {
+ xsane.fax_status=strdup(TEXT_PROJECT_STATUS_NOT_CREATED);
+
+ snprintf(filename, sizeof(filename), "%s/page-1.pnm", preferences.fax_project);
+ xsane.fax_filename=strdup(filename);
+ xsane_update_counter_in_filename(&xsane.fax_filename, FALSE, 0, preferences.filename_counter_len); /* correct counter len */
+
+ xsane.fax_receiver=strdup("");
+ gtk_entry_set_text(GTK_ENTRY(xsane.fax_receiver_entry), (char *) xsane.fax_receiver);
+
+ gtk_widget_set_sensitive(xsane.project_box, FALSE);
+ gtk_widget_hide(xsane.project_exists);
+ gtk_widget_show(xsane.project_not_exists);
+ gtk_widget_set_sensitive(GTK_WIDGET(xsane.start_button), FALSE);
+ }
+ else
+ {
+ i=0;
+ c=0;
+ while ((i<255) && (c != 10) && (c != EOF)) /* first line is fax status */
+ {
+ c = fgetc(projectfile);
+ page[i++] = c;
+ }
+ page[i-1] = 0;
+ if (strchr(page, '@'))
+ {
+ *strchr(page, '@') = 0;
+ }
+ xsane.fax_status = strdup(page);
+
+ i=0;
+ c=0;
+ while ((i<255) && (c != 10) && (c != EOF)) /* second line is receiver phone number or address */
+ {
+ c = fgetc(projectfile);
+ page[i++] = c;
+ }
+ page[i-1] = 0;
+
+ xsane.fax_receiver=strdup(page);
+ gtk_entry_set_text(GTK_ENTRY(xsane.fax_receiver_entry), (char *) xsane.fax_receiver);
+
+
+ i=0;
+ c=0;
+ while ((i<255) && (c != 10) && (c != EOF)) /* third line is next fax filename */
+ {
+ c = fgetc(projectfile);
+ page[i++] = c;
+ }
+ page[i-1] = 0;
+
+ snprintf(filename, sizeof(filename), "%s/%s", preferences.fax_project, page);
+ xsane.fax_filename=strdup(filename);
+
+ while (!feof(projectfile))
+ {
+ i=0;
+ c=0;
+
+ while ((i<255) && (c != 10) && (c != EOF))
+ {
+ c = fgetc(projectfile);
+ page[i++] = c;
+ }
+ page[i-1]=0;
+
+ if (c > 1)
+ {
+ char *type;
+ char *extension;
+
+ extension = strrchr(page, '.');
+ if (extension)
+ {
+ type = strdup(extension);
+ *extension = 0;
+ }
+ else
+ {
+ type = strdup("");
+ }
+
+ list_item = gtk_list_item_new_with_label(page);
+ gtk_object_set_data(GTK_OBJECT(list_item), "list_item_data", strdup(page));
+ gtk_object_set_data(GTK_OBJECT(list_item), "list_item_type", strdup(type));
+ gtk_container_add(GTK_CONTAINER(xsane.project_list), list_item);
+ gtk_widget_show(list_item);
+ }
+ }
+ gtk_widget_set_sensitive(xsane.project_box, TRUE);
+ gtk_widget_show(xsane.project_exists);
+ gtk_widget_hide(xsane.project_not_exists);
+ gtk_widget_set_sensitive(GTK_WIDGET(xsane.start_button), TRUE);
+ }
+
+ if (projectfile)
+ {
+ fclose(projectfile);
+ }
+
+ g_signal_connect(GTK_OBJECT(xsane.fax_receiver_entry), "changed", (GtkSignalFunc) xsane_fax_receiver_changed_callback, NULL);
+
+ gtk_progress_set_format_string(GTK_PROGRESS(xsane.project_progress_bar), _(xsane.fax_status));
+ gtk_progress_bar_update(GTK_PROGRESS_BAR(xsane.project_progress_bar), 0.0);
+}
+
+/* ---------------------------------------------------------------------------------------------------------------------- */
+
+static void xsane_fax_project_delete()
+{
+ char *page;
+ char file[256];
+ GList *list = (GList *) GTK_LIST(xsane.project_list)->children;
+ GtkObject *list_item;
+
+ DBG(DBG_proc, "xsane_fax_project_delete\n");
+
+ while (list)
+ {
+ list_item = GTK_OBJECT(list->data);
+ page = strdup((char *) gtk_object_get_data(list_item, "list_item_data"));
+ xsane_convert_text_to_filename(&page);
+ snprintf(file, sizeof(file), "%s/%s.pnm", preferences.fax_project, page);
+ free(page);
+ remove(file);
+ list = list->next;
+ }
+ snprintf(file, sizeof(file), "%s/xsane-fax-list", preferences.fax_project);
+ remove(file);
+ snprintf(file, sizeof(file), "%s", preferences.fax_project);
+ rmdir(file);
+
+ xsane_fax_project_load();
+}
+
+/* ---------------------------------------------------------------------------------------------------------------------- */
+
+static void xsane_fax_project_update_project_status()
+{
+ FILE *projectfile;
+ char filename[PATH_MAX];
+ char buf[256];
+
+ snprintf(filename, sizeof(filename), "%s/xsane-fax-list", preferences.fax_project);
+ projectfile = fopen(filename, "r+b"); /* r+ = read and write, position = start of file */
+
+ snprintf(buf, 32, "%s@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@", xsane.fax_status); /* fill 32 characters status line */
+ fprintf(projectfile, "%s\n", buf); /* first line is status of mail */
+
+ fclose(projectfile);
+}
+
+/* ---------------------------------------------------------------------------------------------------------------------- */
+
+void xsane_fax_project_save()
+{
+ FILE *projectfile;
+ char *page;
+ char *type;
+ char filename[256];
+ GList *list = (GList *) GTK_LIST(xsane.project_list)->children;
+ GtkObject *list_item;
+
+ DBG(DBG_proc, "xsane_fax_project_save\n");
+
+ umask((mode_t) preferences.directory_umask); /* define new file permissions */
+ mkdir(preferences.fax_project, 0777); /* make sure directory exists */
+
+ snprintf(filename, sizeof(filename), "%s/xsane-fax-list", preferences.fax_project);
+
+ if (xsane_create_secure_file(filename)) /* remove possibly existing symbolic links for security
+*/
+ {
+ char buf[256];
+
+ snprintf(buf, sizeof(buf), "%s %s %s\n", ERR_DURING_SAVE, ERR_CREATE_SECURE_FILE, filename);
+ xsane_back_gtk_error(buf, TRUE);
+ return; /* error */
+ }
+ projectfile = fopen(filename, "wb"); /* write binary (b for win32) */
+
+ if (!projectfile)
+ {
+ xsane_back_gtk_error(ERR_CREATE_FAX_PROJECT, TRUE);
+
+ return;
+ }
+
+ if (xsane.fax_status)
+ {
+ char buf[256];
+
+ snprintf(buf, 32, "%s@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@", xsane.fax_status); /* fill 32 characters status line */
+ fprintf(projectfile, "%s\n", buf); /* first line is status of mail */
+ gtk_progress_set_format_string(GTK_PROGRESS(xsane.project_progress_bar), _(xsane.fax_status));
+ gtk_progress_bar_update(GTK_PROGRESS_BAR(xsane.project_progress_bar), 0.0);
+ }
+ else
+ {
+ fprintf(projectfile, " \n"); /* no mail status */
+ gtk_progress_set_format_string(GTK_PROGRESS(xsane.project_progress_bar), "");
+ gtk_progress_bar_update(GTK_PROGRESS_BAR(xsane.project_progress_bar), 0.0);
+ }
+
+ if (xsane.fax_receiver)
+ {
+ fprintf(projectfile, "%s\n", xsane.fax_receiver); /* first line is receiver phone number or address */
+ }
+ else
+ {
+ fprintf(projectfile, "\n");
+ }
+
+ if (xsane.fax_filename)
+ {
+ fprintf(projectfile, "%s\n", strrchr(xsane.fax_filename, '/')+1); /* second line is next fax filename */
+ }
+ else
+ {
+ fprintf(projectfile, "\n");
+ }
+
+
+ while (list)
+ {
+ list_item = GTK_OBJECT(list->data);
+ page = (char *) gtk_object_get_data(list_item, "list_item_data");
+ type = (char *) gtk_object_get_data(list_item, "list_item_type");
+ fprintf(projectfile, "%s%s\n", page, type);
+ list = list->next;
+ }
+ fclose(projectfile);
+}
+
+/* ---------------------------------------------------------------------------------------------------------------------- */
+
+static void xsane_fax_project_create()
+{
+ DBG(DBG_proc, "xsane_fax_project_create\n");
+
+ if (strlen(preferences.fax_project))
+ {
+ if (xsane.fax_status)
+ {
+ free(xsane.fax_status);
+ }
+ xsane.fax_status = strdup(TEXT_PROJECT_STATUS_CREATED);
+ xsane_fax_project_save();
+ xsane_fax_project_load();
+ }
+}
+
+/* ---------------------------------------------------------------------------------------------------------------------- */
+
+static void xsane_fax_receiver_changed_callback(GtkWidget *widget, gpointer data)
+{
+ DBG(DBG_proc, "xsane_fax_receiver_changed_callback\n");
+
+ if (xsane.fax_status)
+ {
+ free(xsane.fax_status);
+ }
+ xsane.fax_status = strdup(TEXT_PROJECT_STATUS_CHANGED);
+
+ if (xsane.fax_receiver)
+ {
+ free((void *) xsane.fax_receiver);
+ }
+ xsane.fax_receiver = strdup(gtk_entry_get_text(GTK_ENTRY(widget)));
+
+ xsane_fax_project_save();
+
+ gtk_progress_set_format_string(GTK_PROGRESS(xsane.project_progress_bar), _(xsane.fax_status));
+ gtk_progress_bar_update(GTK_PROGRESS_BAR(xsane.project_progress_bar), 0.0);
+}
+
+/* ---------------------------------------------------------------------------------------------------------------------- */
+
+static void xsane_fax_project_changed_callback(GtkWidget *widget, gpointer data)
+{
+ DBG(DBG_proc, "xsane_fax_project_changed_callback\n");
+
+ if (preferences.fax_project)
+ {
+ free((void *) preferences.fax_project);
+ }
+ preferences.fax_project = strdup(gtk_entry_get_text(GTK_ENTRY(widget)));
+
+ xsane_fax_project_load();
+}
+
+/* ---------------------------------------------------------------------------------------------------------------------- */
+
+static void xsane_fax_fine_mode_callback(GtkWidget * widget)
+{
+ DBG(DBG_proc, "xsane_fax_fine_mode_callback\n");
+
+ preferences.fax_fine_mode = (GTK_TOGGLE_BUTTON(widget)->active != 0);
+}
+
+/* ---------------------------------------------------------------------------------------------------------------------- */
+
+static void xsane_fax_entry_move_up_callback(GtkWidget *widget, gpointer list)
+{
+ GList *select;
+ GList *item = GTK_LIST(list)->children;
+ GtkWidget *list_item_1;
+ GtkWidget *list_item_2;
+ int position;
+ int newpos;
+
+ DBG(DBG_proc, "xsane_fax_entry_move_up\n");
+
+ select = GTK_LIST(list)->selection;
+ if (select)
+ {
+ list_item_1 = select->data;
+
+ position = gtk_list_child_position(GTK_LIST(list), list_item_1);
+ position--; /* move up */
+ newpos = position;
+
+ if (position >= 0)
+ {
+ while (position>0)
+ {
+ item = item->next;
+ position--;
+ }
+
+ list_item_2 = item->data;
+ if (list_item_2)
+ {
+ xsane_front_gtk_list_entries_swap(list_item_1, list_item_2);
+ gtk_list_select_item(GTK_LIST(list), newpos);
+ xsane_fax_project_save();
+ }
+ }
+ }
+}
+
+/* ---------------------------------------------------------------------------------------------------------------------- */
+
+static void xsane_fax_entry_move_down_callback(GtkWidget *widget, gpointer list)
+{
+ GList *select;
+ GList *item = GTK_LIST(list)->children;
+ GtkWidget *list_item_1;
+ GtkWidget *list_item_2;
+ int position;
+ int newpos;
+
+ DBG(DBG_proc, "xsane_fax_entry_move_down\n");
+
+ select = GTK_LIST(list)->selection;
+ if (select)
+ {
+ list_item_1 = select->data;
+
+ position = gtk_list_child_position(GTK_LIST(list), list_item_1);
+ position++; /* move down */
+ newpos = position;
+
+ while ((position>0) && (item))
+ {
+ item = item->next;
+ position--;
+ }
+
+ if (item)
+ {
+ list_item_2 = item->data;
+ if (list_item_2)
+ {
+ xsane_front_gtk_list_entries_swap(list_item_1, list_item_2);
+ gtk_list_select_item(GTK_LIST(list), newpos);
+ xsane_fax_project_save();
+ }
+ }
+ }
+}
+
+/* ---------------------------------------------------------------------------------------------------------------------- */
+
+int xsane_fax_entry_rename;
+
+static void xsane_fax_entry_rename_button_callback(GtkWidget *widget, gpointer data)
+{
+ DBG(DBG_proc, "xsane_fax_entry_rename\n");
+
+ xsane_fax_entry_rename = (int) data;
+}
+
+/* ---------------------------------------------------------------------------------------------------------------------- */
+
+static void xsane_fax_entry_rename_callback(GtkWidget *widget, gpointer list)
+{
+ GtkWidget *list_item;
+ GList *select;
+ char *oldpage;
+ char *newpage;
+ char *type;
+ char oldfile[256];
+ char newfile[256];
+
+ DBG(DBG_proc, "xsane_fax_entry_rename_callback\n");
+
+ select = GTK_LIST(list)->selection;
+ if (select)
+ {
+ GtkWidget *rename_dialog;
+ GtkWidget *text;
+ GtkWidget *button;
+ GtkWidget *vbox, *hbox;
+ char filename[PATH_MAX];
+
+ list_item = select->data;
+ oldpage = strdup((char *) gtk_object_get_data(GTK_OBJECT(list_item), "list_item_data"));
+ type = strdup((char *) gtk_object_get_data(GTK_OBJECT(list_item), "list_item_type"));
+
+ xsane_set_sensitivity(FALSE);
+
+ rename_dialog = gtk_window_new(GTK_WINDOW_TOPLEVEL);
+ xsane_set_window_icon(rename_dialog, 0);
+
+ /* set the main vbox */
+ vbox = gtk_vbox_new(FALSE, 0);
+ gtk_container_set_border_width(GTK_CONTAINER(vbox), 0);
+ gtk_container_add(GTK_CONTAINER(rename_dialog), vbox);
+ gtk_widget_show(vbox);
+
+ /* set the main hbox */
+ hbox = gtk_hbox_new(FALSE, 0);
+ xsane_separator_new(vbox, 2);
+ gtk_box_pack_end(GTK_BOX(vbox), hbox, FALSE, FALSE, 5);
+ gtk_container_set_border_width(GTK_CONTAINER(hbox), 5);
+ gtk_widget_show(hbox);
+
+ gtk_window_set_position(GTK_WINDOW(rename_dialog), GTK_WIN_POS_CENTER);
+ gtk_window_set_resizable(GTK_WINDOW(rename_dialog), FALSE);
+ snprintf(filename, sizeof(filename), "%s %s", xsane.prog_name, WINDOW_FAX_RENAME);
+ gtk_window_set_title(GTK_WINDOW(rename_dialog), filename);
+ g_signal_connect(GTK_OBJECT(rename_dialog), "delete_event", (GtkSignalFunc) xsane_fax_entry_rename_button_callback,(void *) -1);
+ gtk_widget_show(rename_dialog);
+
+ text = gtk_entry_new();
+ xsane_back_gtk_set_tooltip(xsane.tooltips, text, DESC_FAXPAGENAME);
+ gtk_entry_set_max_length(GTK_ENTRY(text), 64);
+ gtk_entry_set_text(GTK_ENTRY(text), oldpage);
+ gtk_widget_set_size_request(text, 300, -1);
+ gtk_box_pack_start(GTK_BOX(vbox), text, TRUE, TRUE, 4);
+ gtk_widget_show(text);
+
+
+#ifdef HAVE_GTK2
+ button = gtk_button_new_from_stock(GTK_STOCK_OK);
+#else
+ button = gtk_button_new_with_label(BUTTON_OK);
+#endif
+ g_signal_connect(GTK_OBJECT(button), "clicked", (GtkSignalFunc) xsane_fax_entry_rename_button_callback, (void *) 1);
+ gtk_box_pack_start(GTK_BOX(hbox), button, TRUE, TRUE, 0);
+ gtk_widget_show(button);
+
+#ifdef HAVE_GTK2
+ button = gtk_button_new_from_stock(GTK_STOCK_CANCEL);
+#else
+ button = gtk_button_new_with_label(BUTTON_CANCEL);
+#endif
+ g_signal_connect(GTK_OBJECT(button), "clicked", (GtkSignalFunc) xsane_fax_entry_rename_button_callback, (void *) -1);
+ gtk_box_pack_start(GTK_BOX(hbox), button, TRUE, TRUE, 0);
+ gtk_widget_show(button);
+
+
+ xsane_fax_entry_rename = 0;
+
+ while (xsane_fax_entry_rename == 0)
+ {
+ while (gtk_events_pending())
+ {
+ gtk_main_iteration();
+ }
+ }
+
+ newpage = strdup(gtk_entry_get_text(GTK_ENTRY(text)));
+
+ if (xsane_fax_entry_rename == 1)
+ {
+ gtk_label_set(GTK_LABEL(gtk_container_children(GTK_CONTAINER(list_item))->data), newpage);
+ gtk_object_set_data(GTK_OBJECT(list_item), "list_item_data", strdup(newpage));
+
+ xsane_convert_text_to_filename(&oldpage);
+ xsane_convert_text_to_filename(&newpage);
+ snprintf(oldfile, sizeof(oldfile), "%s/%s%s", preferences.fax_project, oldpage, type);
+ snprintf(newfile, sizeof(newfile), "%s/%s%s", preferences.fax_project, newpage, type);
+
+ rename(oldfile, newfile);
+
+ xsane_fax_project_save();
+ }
+
+ free(oldpage);
+ free(newpage);
+ free(type);
+
+ gtk_widget_destroy(rename_dialog);
+
+ xsane_set_sensitivity(TRUE);
+ }
+}
+
+/* ---------------------------------------------------------------------------------------------------------------------- */
+
+static void xsane_fax_entry_insert_callback(GtkWidget *widget, gpointer list)
+{
+ GtkWidget *list_item;
+ char filename[PATH_MAX];
+ char windowname[255];
+
+ DBG(DBG_proc, "xsane_fax_entry_insert_callback\n");
+
+ xsane_set_sensitivity(FALSE);
+
+ snprintf(windowname, sizeof(windowname), "%s %s %s", xsane.prog_name, WINDOW_FAX_INSERT, preferences.fax_project);
+ filename[0] = 0;
+
+ umask((mode_t) preferences.directory_umask); /* define new file permissions */
+
+ if (!xsane_back_gtk_get_filename(windowname, filename, sizeof(filename), filename, NULL, TRUE, FALSE, FALSE, FALSE)) /* filename is selected */
+ {
+ FILE *sourcefile;
+
+ sourcefile = fopen(filename, "rb"); /* read binary (b for win32) */
+ if (sourcefile) /* file exists */
+ {
+ char buf[1024];
+
+ fgets(buf, sizeof(buf), sourcefile);
+
+ if (!strncmp("%!PS", buf, 4))
+ {
+ FILE *destfile;
+ char destpath[PATH_MAX];
+ char *destfilename;
+ char *destfiletype;
+ char *extension;
+
+ destfilename = strdup(strrchr(filename, '/')+1);
+ extension = strrchr(destfilename, '.');
+ if (extension)
+ {
+ destfiletype = strdup(extension);
+ *extension = 0;
+ }
+ else
+ {
+ destfiletype = strdup("");
+ }
+
+ snprintf(destpath, sizeof(destpath), "%s/%s%s", preferences.fax_project, destfilename, destfiletype);
+ /* copy file to project directory */
+ if (xsane_create_secure_file(destpath)) /* remove possibly existing symbolic links for security
+*/
+ {
+ fclose(sourcefile);
+ snprintf(buf, sizeof(buf), "%s %s %s\n", ERR_DURING_SAVE, ERR_CREATE_SECURE_FILE, destpath);
+ xsane_back_gtk_error(buf, TRUE);
+ return; /* error */
+ }
+
+ destfile = fopen(destpath, "wb"); /* write binary (b for win32) */
+
+ if (destfile) /* file is created */
+ {
+ fprintf(destfile, "%s\n", buf);
+
+ while (!feof(sourcefile))
+ {
+ fgets(buf, sizeof(buf), sourcefile);
+ fprintf(destfile, "%s", buf);
+ }
+
+ fclose(destfile);
+
+
+ /* add filename to fax page list */
+ list_item = gtk_list_item_new_with_label(destfilename);
+ gtk_object_set_data(GTK_OBJECT(list_item), "list_item_data", strdup(destfilename));
+ gtk_object_set_data(GTK_OBJECT(list_item), "list_item_type", strdup(destfiletype));
+ gtk_container_add(GTK_CONTAINER(xsane.project_list), list_item);
+ gtk_widget_show(list_item);
+
+ xsane_update_counter_in_filename(&xsane.fax_filename, TRUE, 1, preferences.filename_counter_len);
+ xsane_fax_project_save();
+ free(destfilename);
+ }
+ else /* file could not be created */
+ {
+ snprintf(buf, sizeof(buf), "%s %s", ERR_OPEN_FAILED, filename);
+ xsane_back_gtk_decision(ERR_HEADER_ERROR, (gchar **) error_xpm, buf, BUTTON_OK, NULL, TRUE /* wait */);
+ }
+ }
+ else
+ {
+ snprintf(buf, sizeof(buf), ERR_FILE_NOT_POSTSCRIPT, filename);
+ xsane_back_gtk_decision(ERR_HEADER_ERROR, (gchar **) error_xpm, buf, BUTTON_OK, NULL, TRUE /* wait */);
+ }
+
+ fclose(sourcefile);
+ }
+ else
+ {
+ char buf[256];
+ snprintf(buf, sizeof(buf), ERR_FILE_NOT_EXISTS, filename);
+ xsane_back_gtk_decision(ERR_HEADER_ERROR, (gchar **) error_xpm, buf, BUTTON_OK, NULL, TRUE /* wait */);
+ }
+ }
+
+ umask(XSANE_DEFAULT_UMASK); /* define new file permissions */
+
+ xsane_set_sensitivity(TRUE);
+}
+
+/* ---------------------------------------------------------------------------------------------------------------------- */
+
+static void xsane_fax_entry_delete_callback(GtkWidget *widget, gpointer list)
+{
+ GtkObject *list_item;
+ GList *select;
+ char *page;
+ char *type;
+ char filename[PATH_MAX];
+
+ DBG(DBG_proc, "xsane_fax_entry_delete_callback\n");
+
+ select = GTK_LIST(list)->selection;
+ if (select)
+ {
+ list_item = GTK_OBJECT(select->data);
+ page = strdup((char *) gtk_object_get_data(list_item, "list_item_data"));
+ type = strdup((char *) gtk_object_get_data(list_item, "list_item_type"));
+ xsane_convert_text_to_filename(&page);
+ snprintf(filename, sizeof(filename), "%s/%s%s", preferences.fax_project, page, type);
+ free(page);
+ free(type);
+ remove(filename);
+ gtk_widget_destroy(GTK_WIDGET(list_item));
+ xsane_fax_project_save();
+ }
+}
+
+/* ---------------------------------------------------------------------------------------------------------------------- */
+
+static void xsane_fax_show_callback(GtkWidget *widget, gpointer list)
+{
+ GtkObject *list_item;
+ GList *select;
+ char *page;
+ char *type;
+ char filename[256];
+
+ DBG(DBG_proc, "xsane_fax_entry_show_callback\n");
+
+ select = GTK_LIST(list)->selection;
+ if (select)
+ {
+ list_item = GTK_OBJECT(select->data);
+ page = strdup((char *) gtk_object_get_data(list_item, "list_item_data"));
+ type = strdup((char *) gtk_object_get_data(list_item, "list_item_type"));
+ xsane_convert_text_to_filename(&page);
+ snprintf(filename, sizeof(filename), "%s/%s%s", preferences.fax_project, page, type);
+
+ if (!strncmp(type, ".pnm", 4))
+ {
+ /* when we do not allow any modification then we can work with the original file */
+ /* so we do not have to copy the image into a dummy file here! */
+
+ xsane_viewer_new(filename, NULL, FALSE, filename, VIEWER_NO_MODIFICATION, IMAGE_SAVED);
+ }
+ else if (!strncmp(type, ".ps", 3))
+ {
+ char *arg[100];
+ int argnr;
+ pid_t pid;
+
+ argnr = xsane_parse_options(preferences.fax_viewer, arg);
+ arg[argnr++] = filename;
+ arg[argnr] = 0;
+
+ pid = fork();
+
+ if (pid == 0) /* new process */
+ {
+ FILE *ipc_file = NULL;
+
+ if (xsane.ipc_pipefd[0])
+ {
+ close(xsane.ipc_pipefd[0]); /* close reading end of pipe */
+ ipc_file = fdopen(xsane.ipc_pipefd[1], "w");
+ }
+
+ DBG(DBG_info, "trying to change user id fo new subprocess:\n");
+ DBG(DBG_info, "old effective uid = %d\n", (int) geteuid());
+ setuid(getuid());
+ DBG(DBG_info, "new effective uid = %d\n", (int) geteuid());
+
+ execvp(arg[0], arg); /* does not return if successfully */
+ DBG(DBG_error, "%s %s\n", ERR_FAILED_EXEC_FAX_VIEWER, preferences.fax_viewer);
+
+ /* send error message via IPC pipe to parent process */
+ if (ipc_file)
+ {
+ fprintf(ipc_file, "%s %s:\n%s", ERR_FAILED_EXEC_FAX_VIEWER, preferences.fax_viewer, strerror(errno));
+ fflush(ipc_file); /* make sure message is displayed */
+ fclose(ipc_file);
+ }
+
+ _exit(0); /* do not use exit() here! otherwise gtk gets in trouble */
+ }
+ else /* parent process */
+ {
+ xsane_front_gtk_add_process_to_list(pid); /* add pid to child process list */
+ }
+ }
+
+ free(page);
+ free(type);
+ }
+}
+
+/* ---------------------------------------------------------------------------------------------------------------------- */
+
+static int xsane_fax_convert_pnm_to_ps(char *source_filename, char *fax_filename)
+{
+ FILE *outfile;
+ FILE *infile;
+ Image_info image_info;
+ char buf[256];
+ int cancel_save;
+
+ /* open progressbar */
+ snprintf(buf, sizeof(buf), "%s - %s", PROGRESS_CONVERTING_DATA, source_filename);
+ gtk_progress_set_format_string(GTK_PROGRESS(xsane.project_progress_bar), buf);
+ gtk_progress_bar_update(GTK_PROGRESS_BAR(xsane.project_progress_bar), 0.0);
+
+ while (gtk_events_pending())
+ {
+ DBG(DBG_info, "calling gtk_main_iteration\n");
+ gtk_main_iteration();
+ }
+
+ infile = fopen(source_filename, "rb"); /* read binary (b for win32) */
+ if (infile != 0)
+ {
+ xsane_read_pnm_header(infile, &image_info);
+
+ umask((mode_t) preferences.image_umask); /* define image file permissions */
+ outfile = fopen(fax_filename, "wb"); /* b = binary mode for win32 */
+ umask(XSANE_DEFAULT_UMASK); /* define new file permissions */
+ if (outfile != 0)
+ {
+ float imagewidth, imageheight;
+
+ imagewidth = 72.0 * image_info.image_width /image_info.resolution_x; /* width in 1/72 inch */
+ imageheight = 72.0 * image_info.image_height/image_info.resolution_y; /* height in 1/72 inch */
+
+ DBG(DBG_info, "imagewidth = %f 1/72 inch\n", imagewidth);
+ DBG(DBG_info, "imageheight = %f 1/72 inch\n", imageheight);
+
+ xsane_save_ps(outfile, infile,
+ &image_info,
+ imagewidth, imageheight,
+ preferences.fax_leftoffset * 72.0/MM_PER_INCH, /* paper_left_margin */
+ preferences.fax_bottomoffset * 72.0/MM_PER_INCH, /* paper_bottom_margin */
+ preferences.fax_width * 72.0/MM_PER_INCH, /* paper_width */
+ preferences.fax_height * 72.0/MM_PER_INCH, /* paper_height */
+ 0 /* portrait top left */,
+ preferences.fax_ps_flatdecoded, /* use ps level 3 zlib compression */
+ xsane.project_progress_bar,
+ &cancel_save);
+ fclose(outfile);
+ }
+ else
+ {
+ char buf[256];
+
+ DBG(DBG_info, "open of faxfile `%s'failed : %s\n", fax_filename, strerror(errno));
+
+ snprintf(buf, sizeof(buf), "%s `%s': %s", ERR_OPEN_FAILED, fax_filename, strerror(errno));
+ xsane_back_gtk_error(buf, TRUE);
+ }
+
+ fclose(infile);
+ }
+ else
+ {
+ char buf[256];
+
+ DBG(DBG_info, "open of faxfile `%s'failed : %s\n", source_filename, strerror(errno));
+
+ snprintf(buf, sizeof(buf), "%s `%s': %s", ERR_OPEN_FAILED, source_filename, strerror(errno));
+ xsane_back_gtk_error(buf, TRUE);
+ }
+
+ gtk_progress_set_format_string(GTK_PROGRESS(xsane.project_progress_bar), "");
+ gtk_progress_bar_update(GTK_PROGRESS_BAR(xsane.project_progress_bar), 0.0);
+
+ while (gtk_events_pending())
+ {
+ DBG(DBG_info, "calling gtk_main_iteration\n");
+ gtk_main_iteration();
+ }
+
+ return 0;
+}
+
+/* ---------------------------------------------------------------------------------------------------------------------- */
+
+static void xsane_fax_send()
+{
+ char *page;
+ char *type;
+ char *fax_type=".ps";
+ GList *list = (GList *) GTK_LIST(xsane.project_list)->children;
+ GtkObject *list_item;
+ pid_t pid;
+ char *arg[1000];
+ char buf[256];
+ char source_filename[PATH_MAX];
+ char fax_filename[PATH_MAX];
+ int argnr = 0;
+ int i;
+
+ DBG(DBG_proc, "xsane_fax_send\n");
+
+ if (list)
+ {
+ if (!xsane_front_gtk_option_defined(xsane.fax_receiver))
+ {
+ snprintf(buf, sizeof(buf), "%s\n", ERR_SENDFAX_RECEIVER_MISSING);
+ xsane_back_gtk_error(buf, TRUE);
+ return;
+ }
+
+ xsane_set_sensitivity(FALSE);
+ /* gtk_widget_set_sensitive(xsane.project_dialog, FALSE); */
+
+ argnr = xsane_parse_options(preferences.fax_command, arg);
+
+ if (preferences.fax_fine_mode) /* fine mode */
+ {
+ if (xsane_front_gtk_option_defined(preferences.fax_fine_option))
+ {
+ arg[argnr++] = strdup(preferences.fax_fine_option);
+ }
+ }
+ else /* normal mode */
+ {
+ if (xsane_front_gtk_option_defined(preferences.fax_normal_option))
+ {
+ arg[argnr++] = strdup(preferences.fax_normal_option);
+ }
+ }
+
+ if (xsane_front_gtk_option_defined(preferences.fax_receiver_option))
+ {
+ arg[argnr++] = strdup(preferences.fax_receiver_option);
+ }
+ arg[argnr++] = strdup(xsane.fax_receiver);
+
+ if (xsane_front_gtk_option_defined(preferences.fax_postscript_option))
+ {
+ arg[argnr++] = strdup(preferences.fax_postscript_option);
+ }
+
+ while ((list) && (argnr<999)) /* add pages to options */
+ {
+ list_item = GTK_OBJECT(list->data);
+ page = strdup((char *) gtk_object_get_data(list_item, "list_item_data"));
+ type = strdup((char *) gtk_object_get_data(list_item, "list_item_type"));
+ xsane_convert_text_to_filename(&page);
+ snprintf(source_filename, sizeof(source_filename), "%s/%s%s", preferences.fax_project, page, type);
+ snprintf(fax_filename, sizeof(fax_filename), "%s/%s-fax%s", preferences.fax_project, page, fax_type);
+ if (xsane_create_secure_file(fax_filename)) /* remove possibly existing symbolic links for security */
+ {
+ char buf[256];
+
+ snprintf(buf, sizeof(buf), "%s %s %s\n", ERR_DURING_SAVE, ERR_CREATE_SECURE_FILE, fax_filename);
+ xsane_back_gtk_error(buf, TRUE);
+ return; /* error */
+ }
+
+ if (!strncmp(type, ".pnm", 4))
+ {
+ DBG(DBG_info, "converting %s to %s\n", source_filename, fax_filename);
+ xsane_fax_convert_pnm_to_ps(source_filename, fax_filename);
+ }
+ else if (!strncmp(type, ".ps", 3))
+ {
+ int cancel_save = 0;
+ xsane_copy_file_by_name(fax_filename, source_filename, xsane.project_progress_bar, &cancel_save);
+ }
+ arg[argnr++] = strdup(fax_filename);
+ list = list->next;
+ free(page);
+ free(type);
+ }
+
+ arg[argnr] = 0;
+
+ pid = fork();
+
+ if (pid == 0) /* new process */
+ {
+ FILE *ipc_file = NULL;
+
+ if (xsane.ipc_pipefd[0])
+ {
+ close(xsane.ipc_pipefd[0]); /* close reading end of pipe */
+ ipc_file = fdopen(xsane.ipc_pipefd[1], "w");
+ }
+
+ DBG(DBG_info, "trying to change user id for new subprocess:\n");
+ DBG(DBG_info, "old effective uid = %d\n", (int) geteuid());
+ setuid(getuid());
+ DBG(DBG_info, "new effective uid = %d\n", (int) geteuid());
+
+ execvp(arg[0], arg); /* does not return if successfully */
+ DBG(DBG_error, "%s %s\n", ERR_FAILED_EXEC_FAX_CMD, preferences.fax_command);
+
+ /* send error message via IPC pipe to parent process */
+ if (ipc_file)
+ {
+ fprintf(ipc_file, "%s %s:\n%s", ERR_FAILED_EXEC_FAX_CMD, preferences.fax_command, strerror(errno));
+ fflush(ipc_file); /* make sure message is displayed */
+ fclose(ipc_file);
+ }
+
+ _exit(0); /* do not use exit() here! otherwise gtk gets in trouble */
+ }
+ else /* parent process */
+ {
+ xsane_front_gtk_add_process_to_list(pid); /* add pid to child process list */
+ }
+
+ for (i=0; i<argnr; i++)
+ {
+ free(arg[i]);
+ }
+
+ if (xsane.fax_status)
+ {
+ free(xsane.fax_status);
+ }
+ xsane.fax_status = strdup(TEXT_FAX_STATUS_QUEUEING_FAX);
+ xsane_fax_project_update_project_status();
+ gtk_progress_set_format_string(GTK_PROGRESS(xsane.project_progress_bar), _(xsane.fax_status));
+ gtk_progress_bar_update(GTK_PROGRESS_BAR(xsane.project_progress_bar), 0.0);
+
+ while (pid)
+ {
+ int status = 0;
+ pid_t pid_status = waitpid(pid, &status, WNOHANG);
+
+ if ( (pid_status < 0 ) || (pid == pid_status) )
+ {
+ pid = 0; /* ok, child process has terminated */
+ }
+
+ while (gtk_events_pending())
+ {
+ gtk_main_iteration();
+ }
+ }
+
+ /* delete created fax files */
+ list = (GList *) GTK_LIST(xsane.project_list)->children;
+ while (list)
+ {
+ list_item = GTK_OBJECT(list->data);
+ page = strdup((char *) gtk_object_get_data(list_item, "list_item_data"));
+ xsane_convert_text_to_filename(&page);
+ snprintf(fax_filename, sizeof(fax_filename), "%s/%s-fax%s", preferences.fax_project, page, fax_type);
+ free(page);
+
+ DBG(DBG_info, "removing %s\n", fax_filename);
+ remove(fax_filename);
+
+ list = list->next;
+ }
+
+ xsane.fax_status = strdup(TEXT_FAX_STATUS_FAX_QUEUED);
+ xsane_fax_project_update_project_status();
+ gtk_progress_set_format_string(GTK_PROGRESS(xsane.project_progress_bar), _(xsane.fax_status));
+ gtk_progress_bar_update(GTK_PROGRESS_BAR(xsane.project_progress_bar), 0.0);
+
+ xsane_set_sensitivity(TRUE);
+
+ /* gtk_widget_set_sensitive(xsane.project_dialog, TRUE); */
+ }
+
+ DBG(DBG_info, "xsane_fax_send: done\n");
+}
+
+/* ---------------------------------------------------------------------------------------------------------------------- */
diff --git a/src/xsane-fax-project.h b/src/xsane-fax-project.h
new file mode 100644
index 0000000..775aafc
--- /dev/null
+++ b/src/xsane-fax-project.h
@@ -0,0 +1,78 @@
+/* xsane -- a graphical (X11, gtk) scanner-oriented SANE frontend
+
+ xsane-fax-project.h
+
+ Oliver Rauch <Oliver.Rauch@rauch-domain.de>
+ Copyright (C) 1998-2005 Oliver Rauch
+ This file is part of the XSANE package.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+/* ---------------------------------------------------------------------------------------------------------------------- */
+
+#ifndef HAVE_XSANE_FAX_PROJECT_H
+#define HAVE_XSANE_FAX_PROJECT_H
+
+#include "xsane.h"
+#include "xsane-back-gtk.h"
+#include "xsane-front-gtk.h"
+#include "xsane-preview.h"
+#include "xsane-save.h"
+#include "xsane-gamma.h"
+#include "xsane-setup.h"
+#include "xsane-scan.h"
+#include "xsane-multipage-project.h"
+#include "xsane-fax-project.h"
+#include "xsane-rc-io.h"
+#include "xsane-device-preferences.h"
+#include "xsane-preferences.h"
+#include "xsane-icons.h"
+#include "xsane-batch-scan.h"
+
+#ifdef HAVE_LIBPNG
+#ifdef HAVE_LIBZ
+#include <png.h>
+#include <zlib.h>
+#endif
+#endif
+
+#include <sys/wait.h>
+
+/* ---------------------------------------------------------------------------------------------------------------------- */
+
+/* ---------------------------------------------------------------------------------------------------------------------- */
+
+extern void xsane_fax_dialog(void);
+extern void xsane_fax_project_save(void);
+
+#if 0
+static gint xsane_fax_dialog_delete();
+static void xsane_fax_receiver_changed_callback(GtkWidget *widget, gpointer data);
+static void xsane_fax_project_changed_callback(GtkWidget *widget, gpointer data);
+static void xsane_fax_fine_mode_callback(GtkWidget *widget);
+static void xsane_fax_project_update_project_status();
+static void xsane_fax_project_load(void);
+static void xsane_fax_project_delete(void);
+static void xsane_fax_project_create(void);
+static void xsane_fax_entry_move_up_callback(GtkWidget *widget, gpointer list);
+static void xsane_fax_entry_move_down_callback(GtkWidget *widget, gpointer list);
+static void xsane_fax_entry_rename_callback(GtkWidget *widget, gpointer list);
+static void xsane_fax_entry_insert_callback(GtkWidget *widget, gpointer list);
+static void xsane_fax_entry_delete_callback(GtkWidget *widget, gpointer list);
+static void xsane_fax_show_callback(GtkWidget *widget, gpointer data);
+static void xsane_fax_send(void);
+#endif
+
+#endif
diff --git a/src/xsane-front-gtk.c b/src/xsane-front-gtk.c
index 3e9196c..4eb4add 100644
--- a/src/xsane-front-gtk.c
+++ b/src/xsane-front-gtk.c
@@ -356,9 +356,18 @@ void xsane_set_all_resolutions(void)
if (new_resolution < 0) /* set y resolution not possible */
{
new_resolution = xsane_set_resolution(xsane.well_known.dpi, xsane.resolution); /* set common resolution if necessary */
- xsane.resolution = new_resolution;
- xsane.resolution_x = new_resolution;
- xsane.resolution_y = new_resolution;
+ if (new_resolution > 0)
+ {
+ xsane.resolution = new_resolution;
+ xsane.resolution_x = new_resolution;
+ xsane.resolution_y = new_resolution;
+ }
+ else
+ {
+ xsane.resolution = 72.0;
+ xsane.resolution_x = 72.0;
+ xsane.resolution_y = 72.0;
+ }
}
else /* we were able to set y resolution */
{
@@ -441,7 +450,7 @@ void xsane_define_maximum_output_size()
preview_set_maximum_output_size(xsane.preview, preferences.fax_width, preferences.fax_height, 0);
break;
- case XSANE_MAIL:
+ case XSANE_EMAIL:
preview_set_maximum_output_size(xsane.preview, INF, INF, 0);
break;
@@ -1396,6 +1405,9 @@ void xsane_outputfilename_new(GtkWidget *vbox)
GtkWidget *xsane_filename_counter_step_menu;
GtkWidget *xsane_filename_counter_step_item;
GtkWidget *xsane_label;
+ GtkWidget *pixmapwidget;
+ GdkBitmap *mask;
+ GdkPixmap *pixmap;
gchar buf[200];
int i,j;
int select_item = 0;
@@ -1432,13 +1444,15 @@ void xsane_outputfilename_new(GtkWidget *vbox)
hbox = gtk_hbox_new(FALSE, 2);
gtk_container_set_border_width(GTK_CONTAINER(hbox), 2);
- gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 2);
+ gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 1);
/* filename counter step */
-
- xsane_label = gtk_label_new(TEXT_FILENAME_COUNTER_STEP);
- gtk_box_pack_start(GTK_BOX(hbox), xsane_label, FALSE, FALSE, 2);
- gtk_widget_show(xsane_label);
+
+ pixmap = gdk_pixmap_create_from_xpm_d(xsane.xsane_window->window, &mask, xsane.bg_trans, (gchar **) step_xpm);
+ pixmapwidget = gtk_image_new_from_pixmap(pixmap, mask);
+ gtk_box_pack_start(GTK_BOX(hbox), pixmapwidget, FALSE, FALSE, 2);
+ gtk_widget_show(pixmapwidget);
+ gdk_drawable_unref(pixmap);
xsane_filename_counter_step_option_menu = gtk_option_menu_new();
xsane_back_gtk_set_tooltip(xsane.tooltips, xsane_filename_counter_step_option_menu, DESC_FILENAME_COUNTER_STEP);
@@ -1689,7 +1703,7 @@ int xsane_identify_output_format(char *filename, char *filetype, char **ext)
DBG(DBG_proc, "xsane_identify_output_format\n");
- if ((filetype) && (*filetype))
+ if ((filetype) && (*filetype) && (!xsane.force_filename))
{
extension = filetype+1; /* go to filetype, skip leading dot */
}
@@ -1897,7 +1911,7 @@ int xsane_display_eula(int ask_for_accept)
XSANE_COPYRIGHT_SIGN, XSANE_COPYRIGHT_TXT,
TEXT_EULA,
TEXT_HOMEPAGE, XSANE_HOMEPAGE,
- TEXT_EMAIL, XSANE_EMAIL);
+ TEXT_EMAIL_ADR, XSANE_EMAIL_ADR);
label = gtk_label_new(buf);
gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, FALSE, 0);
@@ -2141,7 +2155,7 @@ void xsane_display_gpl(void)
XSANE_COPYRIGHT_SIGN, XSANE_COPYRIGHT_TXT,
TEXT_GPL,
TEXT_HOMEPAGE, XSANE_HOMEPAGE,
- TEXT_EMAIL, XSANE_EMAIL);
+ TEXT_EMAIL_ADR, XSANE_EMAIL_ADR);
label = gtk_label_new(buf);
gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, FALSE, 0);
@@ -2433,24 +2447,105 @@ int xsane_front_gtk_getname_dialog(const char *dialog_title, const char *desc_te
}
/* ---------------------------------------------------------------------------------------------------------------------- */
-#ifdef XSANE_ACTIVATE_MAIL
-void xsane_front_gtk_mail_project_update_lockfile_status()
+
+void xsane_front_gtk_list_entries_swap(GtkWidget *list_item_1, GtkWidget *list_item_2)
+{
+ char *page1;
+ char *page2;
+ char *type1;
+ char *type2;
+
+ DBG(DBG_proc, "xsane_front_gtk_list_entries_swap\n");
+
+ page1 = (char *) gtk_object_get_data(GTK_OBJECT(list_item_1), "list_item_data");
+ type1 = (char *) gtk_object_get_data(GTK_OBJECT(list_item_1), "list_item_type");
+ page2 = (char *) gtk_object_get_data(GTK_OBJECT(list_item_2), "list_item_data");
+ type2 = (char *) gtk_object_get_data(GTK_OBJECT(list_item_2), "list_item_type");
+
+ gtk_label_set(GTK_LABEL(gtk_container_children(GTK_CONTAINER(list_item_1))->data), page2);
+ gtk_label_set(GTK_LABEL(gtk_container_children(GTK_CONTAINER(list_item_2))->data), page1);
+ gtk_object_set_data(GTK_OBJECT(list_item_1), "list_item_data", page2);
+ gtk_object_set_data(GTK_OBJECT(list_item_1), "list_item_type", type2);
+ gtk_object_set_data(GTK_OBJECT(list_item_2), "list_item_data", page1);
+ gtk_object_set_data(GTK_OBJECT(list_item_2), "list_item_type", type1);
+}
+
+/* ---------------------------------------------------------------------------------------------------------------------- */
+
+void xsane_front_gtk_add_process_to_list(pid_t pid)
+{
+ XsaneChildprocess *newprocess;
+
+ DBG(DBG_proc, "xsane_front_gtk_add_process_to_list(%d)\n", pid);
+
+ newprocess = malloc(sizeof(XsaneChildprocess));
+ newprocess->pid = pid;
+ newprocess->next = xsane.childprocess_list;
+ xsane.childprocess_list = newprocess;
+}
+
+/* ---------------------------------------------------------------------------------------------------------------------- */
+
+int xsane_front_gtk_option_defined(char *string)
+{
+ if (string)
+ {
+ while (*string == ' ') /* skip spaces */
+ {
+ string++;
+ }
+ if (*string != 0)
+ {
+ return 1;
+ }
+ }
+ return 0;
+}
+
+/* ---------------------------------------------------------------------------------------------------------------------- */
+#ifdef XSANE_ACTIVATE_EMAIL
+void xsane_front_gtk_email_project_update_lockfile_status()
{
FILE *lockfile;
char filename[PATH_MAX];
- snprintf(filename, sizeof(filename), "%s/lockfile", preferences.mail_project);
+ snprintf(filename, sizeof(filename), "%s/lockfile", preferences.email_project);
lockfile = fopen(filename, "wb");
if (lockfile)
{
- fprintf(lockfile, "%s\n", xsane.mail_status); /* first line is status of mail */
- fprintf(lockfile, "%3d\n", (int) (xsane.mail_progress_val * 100));
+ fprintf(lockfile, "%s\n", xsane.email_status); /* first line is status of mail */
+ fprintf(lockfile, "%3d\n", (int) (xsane.email_progress_val * 100));
}
fclose(lockfile);
}
#endif
/* ---------------------------------------------------------------------------------------------------------------------- */
+
+void xsane_project_dialog_close()
+{
+ DBG(DBG_proc, "xsane_project_dialog_close\n");
+
+ if (xsane.project_dialog == NULL)
+ {
+ return;
+ }
+
+ if (xsane.project_dialog)
+ {
+ xsane_window_get_position(xsane.project_dialog, &xsane.project_dialog_posx, &xsane.project_dialog_posy);
+ gtk_window_move(GTK_WINDOW(xsane.project_dialog), xsane.project_dialog_posx, xsane.project_dialog_posy);
+ }
+
+ gtk_widget_destroy(xsane.project_dialog);
+
+ xsane.project_dialog = NULL;
+ xsane.project_list = NULL;
+ xsane.project_progress_bar = NULL;
+}
+
+/* ---------------------------------------------------------------------------------------------------------------------- */
+
diff --git a/src/xsane-front-gtk.h b/src/xsane-front-gtk.h
index 53d63a6..1db2b7b 100644
--- a/src/xsane-front-gtk.h
+++ b/src/xsane-front-gtk.h
@@ -81,7 +81,11 @@ extern void xsane_display_gpl(void);
extern void xsane_window_get_position(GtkWidget *gtk_window, gint *x, gint *y);
extern void xsane_widget_test_uposition(GtkWidget *gtk_window);
extern int xsane_front_gtk_getname_dialog(const char *dialog_title, const char *desc_text, char *oldname, char **newname);
-extern void xsane_front_gtk_mail_project_update_lockfile_status();
+extern void xsane_front_gtk_list_entries_swap(GtkWidget *list_item_1, GtkWidget *list_item_2);
+extern void xsane_front_gtk_add_process_to_list(pid_t pid);
+extern int xsane_front_gtk_option_defined(char *string);
+extern void xsane_front_gtk_email_project_update_lockfile_status(void);
+extern void xsane_project_dialog_close(void);
/* ---------------------------------------------------------------------------------------------------------------------- */
diff --git a/src/xsane-gamma.c b/src/xsane-gamma.c
index d43eecf..fdae222 100644
--- a/src/xsane-gamma.c
+++ b/src/xsane-gamma.c
@@ -2157,6 +2157,12 @@ static gint xsane_histogram_win_delete(GtkWidget *widget, gpointer data)
{
DBG(DBG_proc, "xsane_histogram_win_delete\n");
+ if (preferences.show_histogram)
+ {
+ xsane_window_get_position(xsane.histogram_dialog, &xsane.histogram_dialog_posx, &xsane.histogram_dialog_posy);
+ gtk_window_move(GTK_WINDOW(xsane.histogram_dialog), xsane.histogram_dialog_posx, xsane.histogram_dialog_posy);
+ }
+
gtk_widget_hide(widget);
preferences.show_histogram = FALSE;
gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(xsane.show_histogram_widget), preferences.show_histogram);
@@ -2183,7 +2189,7 @@ void xsane_create_histogram_dialog(const char *devicetext)
xsane.histogram_dialog = gtk_window_new(GTK_WINDOW_TOPLEVEL);
gtk_window_set_resizable(GTK_WINDOW(xsane.histogram_dialog), FALSE);
- gtk_window_move(GTK_WINDOW(xsane.histogram_dialog), XSANE_HISTOGRAM_POS_X, XSANE_HISTOGRAM_POS_Y);
+ gtk_window_move(GTK_WINDOW(xsane.histogram_dialog), XSANE_HISTOGRAM_DIALOG_POS_X, XSANE_HISTOGRAM_DIALOG_POS_Y);
g_signal_connect(GTK_OBJECT(xsane.histogram_dialog), "delete_event", GTK_SIGNAL_FUNC(xsane_histogram_win_delete), NULL);
sprintf(windowname, "%s %s", WINDOW_HISTOGRAM, devicetext);
gtk_window_set_title(GTK_WINDOW(xsane.histogram_dialog), windowname);
diff --git a/src/xsane-icons.c b/src/xsane-icons.c
index b09d2f4..f06e3cd 100644
--- a/src/xsane-icons.c
+++ b/src/xsane-icons.c
@@ -905,7 +905,7 @@ const char *person_xpm[] =
/* --------------------------------------------------- */
-const char *mail_xpm[] =
+const char *email_xpm[] =
{
/* width height num_colors chars_per_pixel */
" 20 20 4 1",
@@ -939,7 +939,7 @@ const char *mail_xpm[] =
/* --------------------------------------------------- */
-const char *mailreceiver_xpm[] =
+const char *emailreceiver_xpm[] =
{
/* width height num_colors chars_per_pixel */
" 20 20 3 1",
@@ -1005,6 +1005,110 @@ const char *subject_xpm[] =
/* --------------------------------------------------- */
+const char *adf_xpm[] =
+{
+/* width height num_colors chars_per_pixel */
+" 20 20 4 1",
+/* colors */
+"* c #000000",
+". c #ffffff",
+"- c #e0e0e0",
+" none",
+/* pixels */
+" ************",
+" *..........*",
+" ***..........*",
+" *.*..........*",
+" ***.*..........*",
+" *.*.*..........*",
+" ***.*.*..........*",
+" *.*.*.*..........*",
+" *.*.*.*..........*",
+" *.*.*.*..........*",
+" *.*.*.*..........*",
+" *.*.*.*..........*",
+" *.*.*.*..........*",
+" *.*.*.************",
+" *.*.*..........* ",
+" *.*.************ ",
+" *.*..........* ",
+" *.************ ",
+" *..........* ",
+" ************ "
+};
+
+/* --------------------------------------------------- */
+
+
+const char *target_xpm[] =
+{
+/* width height num_colors chars_per_pixel */
+" 20 20 4 1",
+/* colors */
+"+ c #101010",
+"* c #d06060",
+". c #ffffff",
+" none",
+/* pixels */
+" ** ",
+" ++**++ ",
+" ++..**..++ ",
+" +....**....+ ",
+" +...++**++...+ ",
+" +...+..**..+...+ ",
+" +..+...**...+..+ ",
+" +..+...+**+...+..+ ",
+" +..+..+.**.+..+..+ ",
+"*********..*********",
+"*********..*********",
+" +..+..+.**.+..+..+ ",
+" +..+...+**+...+..+ ",
+" +..+...**...+..+ ",
+" +...+..**..+...+ ",
+" +...++**++...+ ",
+" +....**....+ ",
+" ++..**..++ ",
+" ++**++ ",
+" ** "
+};
+
+/* --------------------------------------------------- */
+
+const char *multipage_xpm[] =
+{
+/* width height num_colors chars_per_pixel */
+" 20 20 5 1",
+/* colors */
+"* c #000000",
+". c #ffffff",
+"- c #e0e0e0",
+"# c #90a0b0",
+" none",
+/* pixels */
+"--------------------",
+"-######************-",
+"-######*..........*-",
+"-###****..........*-",
+"-###*..*..........*-",
+"-****..*..........*-",
+"-*..*..*..........*-",
+"-*..*..*..........*-",
+"-*..*..*..........*-",
+"-*..*..*..........*-",
+"-*..*..*..........*-",
+"-*..*..*..........*-",
+"-*..*..*..........*-",
+"-*..*..*..........*-",
+"-*..*..************-",
+"-*..*..........*###-",
+"-*..************###-",
+"-*..........*######-",
+"-************######-",
+"--------------------"
+};
+
+/* --------------------------------------------------- */
+
const char *colormode_xpm[] = {
/* width height num_colors chars_per_pixel */
" 20 20 23 1",
@@ -1057,6 +1161,38 @@ const char *colormode_xpm[] = {
/* --------------------------------------------------- */
+const char *step_xpm[] = {
+/* width height num_colors chars_per_pixel */
+" 20 20 3 1",
+/* colors */
+". c #000000",
+"# c #a0a0a0",
+" none",
+/* pixels */
+" ",
+" ",
+" ",
+" ",
+" ",
+" ",
+" ",
+" ...... ",
+" ...... ",
+" .....#. ",
+" ......#. ",
+" ........#. ",
+" .........#....... ",
+" .................. ",
+" .................. ",
+" .................. ",
+" ...... ....... ",
+" ",
+" ",
+" "
+};
+
+/* --------------------------------------------------- */
+
const char *medium_xpm[] = {
/* width height num_colors chars_per_pixel */
" 20 20 3 1",
diff --git a/src/xsane-icons.h b/src/xsane-icons.h
index 900ad17..1e4e1a1 100644
--- a/src/xsane-icons.h
+++ b/src/xsane-icons.h
@@ -60,10 +60,14 @@ extern const char *mirror_x_xpm[];
extern const char *mirror_y_xpm[];
extern const char *fax_xpm[];
extern const char *faxreceiver_xpm[];
-extern const char *mail_xpm[];
-extern const char *mailreceiver_xpm[];
+extern const char *email_xpm[];
+extern const char *emailreceiver_xpm[];
extern const char *subject_xpm[];
+extern const char *adf_xpm[];
+extern const char *target_xpm[];
+extern const char *multipage_xpm[];
extern const char *colormode_xpm[];
+extern const char *step_xpm[];
extern const char *medium_xpm[];
extern const char *medium_edit_xpm[];
extern const char *medium_delete_xpm[];
diff --git a/src/xsane-multipage-project.c b/src/xsane-multipage-project.c
new file mode 100644
index 0000000..5a6f1ab
--- /dev/null
+++ b/src/xsane-multipage-project.c
@@ -0,0 +1,1087 @@
+/* xsane -- a graphical (X11, gtk) scanner-oriented SANE frontend
+
+ xsane-multipage-project.c
+
+ Oliver Rauch <Oliver.Rauch@rauch-domain.de>
+ Copyright (C) 2005 Oliver Rauch
+ This file is part of the XSANE package.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+/* ---------------------------------------------------------------------------------------------------------------------- */
+
+
+#include "stdio.h"
+#include "xsane.h"
+#include "xsane-back-gtk.h"
+#include "xsane-front-gtk.h"
+#include "xsane-preview.h"
+#include "xsane-save.h"
+#include "xsane-gamma.h"
+#include "xsane-setup.h"
+#include "xsane-scan.h"
+#include "xsane-rc-io.h"
+#include "xsane-device-preferences.h"
+#include "xsane-preferences.h"
+#include "xsane-icons.h"
+#include "xsane-batch-scan.h"
+
+#ifdef HAVE_LIBTIFF
+# include "tiffio.h"
+#endif
+
+#include <sys/wait.h>
+
+/* ---------------------------------------------------------------------------------------------------------------------- */
+/* ---------------------------------------------------------------------------------------------------------------------- */
+
+/* forward declarations: */
+
+
+void xsane_multipage_dialog(void);
+void xsane_multipage_dialog_close(void);
+void xsane_multipage_project_save(void);
+static gint xsane_multipage_dialog_delete();
+static void xsane_multipage_filetype_callback(GtkWidget *filetype_option_menu, char *filetype);
+static void xsane_multipage_project_changed_callback(GtkWidget *widget, gpointer data);
+static void xsane_multipage_project_load(void);
+static void xsane_multipage_project_delete(void);
+static void xsane_multipage_project_create(void);
+static void xsane_multipage_entry_move_up_callback(GtkWidget *widget, gpointer list);
+static void xsane_multipage_entry_move_down_callback(GtkWidget *widget, gpointer list);
+static void xsane_multipage_entry_delete_callback(GtkWidget *widget, gpointer list);
+static void xsane_multipage_show_callback(GtkWidget *widget, gpointer data);
+static void xsane_multipage_edit_callback(GtkWidget *widget, gpointer data);
+static void xsane_multipage_save_file(void);
+
+/* ---------------------------------------------------------------------------------------------------------------------- */
+
+static gint xsane_multipage_dialog_delete()
+{
+ return TRUE;
+}
+
+/* ---------------------------------------------------------------------------------------------------------------------- */
+
+static void xsane_multipage_filetype_callback(GtkWidget *filetype_option_menu, char *filetype)
+{
+ DBG(DBG_proc, "xsane_multipage_filetype_callback(%s)\n", filetype);
+
+ if (preferences.multipage_filetype)
+ {
+ free(preferences.multipage_filetype);
+ }
+ preferences.multipage_filetype = strdup(filetype);
+}
+
+/* ---------------------------------------------------------------------------------------------------------------------- */
+
+void xsane_multipage_dialog()
+{
+ GtkWidget *multipage_dialog, *multipage_scan_vbox, *multipage_project_vbox;
+ GtkWidget *multipage_project_exists_hbox, *button;
+ GtkWidget *hbox;
+ GtkWidget *scrolled_window, *list;
+ GtkWidget *pixmapwidget, *text;
+ GtkWidget *pages_frame;
+ GtkWidget *label;
+ GtkWidget *filetype_menu, *filetype_item;
+ GtkWidget *filetype_option_menu;
+ GdkPixmap *pixmap;
+ GdkBitmap *mask;
+ char buf[64];
+ int filetype_nr;
+ int select_item;
+
+ DBG(DBG_proc, "xsane_multipage_dialog\n");
+
+ if (xsane.project_dialog)
+ {
+ return; /* window already is open */
+ }
+
+ /* GTK_WINDOW_TOPLEVEL looks better but does not place it nice*/
+ multipage_dialog = gtk_window_new(GTK_WINDOW_TOPLEVEL);
+
+ snprintf(buf, sizeof(buf), "%s %s", xsane.prog_name, WINDOW_MULTIPAGE_PROJECT);
+ gtk_window_set_title(GTK_WINDOW(multipage_dialog), buf);
+ g_signal_connect(GTK_OBJECT(multipage_dialog), "delete_event", (GtkSignalFunc) xsane_multipage_dialog_delete, NULL);
+ xsane_set_window_icon(multipage_dialog, 0);
+ gtk_window_add_accel_group(GTK_WINDOW(multipage_dialog), xsane.accelerator_group);
+
+ /* set the main vbox */
+ multipage_scan_vbox = gtk_vbox_new(FALSE, 0);
+ gtk_container_set_border_width(GTK_CONTAINER(multipage_scan_vbox), 0);
+ gtk_container_add(GTK_CONTAINER(multipage_dialog), multipage_scan_vbox);
+ gtk_widget_show(multipage_scan_vbox);
+
+
+ /* multipage project */
+ hbox = gtk_hbox_new(FALSE, 2);
+ gtk_container_set_border_width(GTK_CONTAINER(hbox), 2);
+ gtk_box_pack_start(GTK_BOX(multipage_scan_vbox), hbox, FALSE, FALSE, 1);
+
+ pixmap = gdk_pixmap_create_from_xpm_d(xsane.dialog->window, &mask, xsane.bg_trans, (gchar **) multipage_xpm);
+ pixmapwidget = gtk_image_new_from_pixmap(pixmap, mask);
+ gtk_box_pack_start(GTK_BOX(hbox), pixmapwidget, FALSE, FALSE, 2);
+ gdk_drawable_unref(pixmap);
+
+ text = gtk_entry_new();
+ xsane_back_gtk_set_tooltip(xsane.tooltips, text, DESC_MULTIPAGE_PROJECT);
+ gtk_entry_set_max_length(GTK_ENTRY(text), 128);
+ gtk_entry_set_text(GTK_ENTRY(text), (char *) preferences.multipage_project);
+ gtk_box_pack_start(GTK_BOX(hbox), text, TRUE, TRUE, 4);
+ g_signal_connect(GTK_OBJECT(text), "changed", (GtkSignalFunc) xsane_multipage_project_changed_callback, NULL);
+
+ xsane.project_entry = text;
+ xsane.project_entry_box = hbox;
+
+ gtk_widget_show(pixmapwidget);
+ gtk_widget_show(text);
+ gtk_widget_show(hbox);
+
+ multipage_project_vbox = gtk_vbox_new(/* homogeneous */ FALSE, 0);
+ gtk_box_pack_start(GTK_BOX(multipage_scan_vbox), multipage_project_vbox, TRUE, TRUE, 0);
+ gtk_widget_show(multipage_project_vbox);
+
+
+ /* FILETYPE MENU */
+ /* button box, active when project exists */
+ hbox = gtk_hbox_new(FALSE, 2);
+ gtk_container_set_border_width(GTK_CONTAINER(hbox), 2);
+ gtk_box_pack_start(GTK_BOX(multipage_project_vbox), hbox, FALSE, FALSE, 1);
+ gtk_widget_show(hbox);
+
+ filetype_menu = gtk_menu_new();
+
+ filetype_nr = -1;
+ select_item = 0;
+
+
+ filetype_item = gtk_menu_item_new_with_label(MENU_ITEM_FILETYPE_PDF);
+ gtk_container_add(GTK_CONTAINER(filetype_menu), filetype_item);
+ g_signal_connect(GTK_OBJECT(filetype_item), "activate", (GtkSignalFunc) xsane_multipage_filetype_callback, (void *) XSANE_FILETYPE_PDF);
+ gtk_widget_show(filetype_item);
+ filetype_nr++;
+ if ( (preferences.multipage_filetype) && (!strcasecmp(preferences.multipage_filetype, XSANE_FILETYPE_PDF)) )
+ {
+ select_item = filetype_nr;
+ }
+
+
+ filetype_item = gtk_menu_item_new_with_label(MENU_ITEM_FILETYPE_PS);
+ gtk_container_add(GTK_CONTAINER(filetype_menu), filetype_item);
+ g_signal_connect(GTK_OBJECT(filetype_item), "activate", (GtkSignalFunc) xsane_multipage_filetype_callback, (void *) XSANE_FILETYPE_PS);
+ gtk_widget_show(filetype_item);
+ filetype_nr++;
+ if ( (preferences.multipage_filetype) && (!strcasecmp(preferences.multipage_filetype, XSANE_FILETYPE_PS)) )
+ {
+ select_item = filetype_nr;
+ }
+
+
+#ifdef HAVE_LIBTIFF
+ filetype_item = gtk_menu_item_new_with_label(MENU_ITEM_FILETYPE_TIFF);
+ gtk_container_add(GTK_CONTAINER(filetype_menu), filetype_item);
+ g_signal_connect(GTK_OBJECT(filetype_item), "activate", (GtkSignalFunc) xsane_multipage_filetype_callback, (void *) XSANE_FILETYPE_TIFF);
+ gtk_widget_show(filetype_item);
+ filetype_nr++;
+ if ( (preferences.multipage_filetype) && (!strcasecmp(preferences.multipage_filetype, XSANE_FILETYPE_TIFF)) )
+ {
+ select_item = filetype_nr;
+ }
+#endif
+
+ label = gtk_label_new(TEXT_MULTIPAGE_FILETYPE);
+ gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 2);
+ gtk_widget_show(label);
+
+ filetype_option_menu = gtk_option_menu_new();
+ xsane_back_gtk_set_tooltip(xsane.tooltips, filetype_option_menu, DESC_MULTIPAGE_FILETYPE);
+ gtk_option_menu_set_menu(GTK_OPTION_MENU(filetype_option_menu), filetype_menu);
+ if (select_item >= 0)
+ {
+ gtk_option_menu_set_history(GTK_OPTION_MENU(filetype_option_menu), select_item);
+ }
+ gtk_box_pack_end(GTK_BOX(hbox), filetype_option_menu, FALSE, FALSE, 2);
+ gtk_widget_show(filetype_menu);
+ gtk_widget_show(filetype_option_menu);
+
+
+ /* pages frame */
+ pages_frame = gtk_frame_new(TEXT_PAGES);
+ gtk_box_pack_start(GTK_BOX(multipage_project_vbox), pages_frame, TRUE, TRUE, 2);
+ gtk_widget_show(pages_frame);
+
+ /* pages list */
+ scrolled_window = gtk_scrolled_window_new(0, 0);
+ gtk_widget_set_size_request(scrolled_window, 200, 100);
+ gtk_container_add(GTK_CONTAINER(pages_frame), scrolled_window);
+ gtk_widget_show(scrolled_window);
+
+ list = gtk_list_new();
+/* gtk_list_set_selection_mode(list, GTK_SELECTION_BROWSE); */
+
+ gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(scrolled_window), list);
+ gtk_widget_show(list);
+ xsane.project_list = list;
+
+
+ /* button box, active when project exists */
+ hbox = gtk_hbox_new(FALSE, 2);
+ gtk_container_set_border_width(GTK_CONTAINER(hbox), 2);
+ gtk_box_pack_start(GTK_BOX(multipage_project_vbox), hbox, FALSE, FALSE, 1);
+
+ button = gtk_button_new_with_label(BUTTON_IMAGE_SHOW);
+ g_signal_connect(GTK_OBJECT(button), "clicked", (GtkSignalFunc) xsane_multipage_show_callback, list);
+ gtk_box_pack_start(GTK_BOX(hbox), button, TRUE, TRUE, 0);
+ gtk_widget_show(button);
+
+ button = gtk_button_new_with_label(BUTTON_IMAGE_EDIT);
+ g_signal_connect(GTK_OBJECT(button), "clicked", (GtkSignalFunc) xsane_multipage_edit_callback, list);
+ gtk_box_pack_start(GTK_BOX(hbox), button, TRUE, TRUE, 0);
+ gtk_widget_show(button);
+
+ button = gtk_button_new_with_label(BUTTON_IMAGE_DELETE);
+ g_signal_connect(GTK_OBJECT(button), "clicked", (GtkSignalFunc) xsane_multipage_entry_delete_callback, list);
+ gtk_box_pack_start(GTK_BOX(hbox), button, TRUE, TRUE, 0);
+ gtk_widget_show(button);
+
+ xsane_button_new_with_pixmap(multipage_dialog->window, hbox, move_up_xpm, 0, (GtkSignalFunc) xsane_multipage_entry_move_up_callback, list);
+ xsane_button_new_with_pixmap(multipage_dialog->window, hbox, move_down_xpm, 0, (GtkSignalFunc) xsane_multipage_entry_move_down_callback, list);
+
+ gtk_widget_show(hbox);
+
+ xsane.project_box = multipage_project_vbox;
+
+ /* set the main hbox */
+ hbox = gtk_hbox_new(FALSE, 0);
+ xsane_separator_new(multipage_scan_vbox, 2);
+ gtk_box_pack_end(GTK_BOX(multipage_scan_vbox), hbox, FALSE, FALSE, 5);
+ gtk_container_set_border_width(GTK_CONTAINER(hbox), 5);
+ gtk_widget_show(hbox);
+
+
+ multipage_project_exists_hbox = gtk_hbox_new(FALSE, 2);
+ gtk_box_pack_start(GTK_BOX(hbox), multipage_project_exists_hbox, TRUE, TRUE, 0);
+
+ button = gtk_button_new_with_label(BUTTON_SAVE_MULTIPAGE);
+ g_signal_connect(GTK_OBJECT(button), "clicked", (GtkSignalFunc) xsane_multipage_save_file, NULL);
+ gtk_box_pack_start(GTK_BOX(multipage_project_exists_hbox), button, TRUE, TRUE, 0);
+ gtk_widget_show(button);
+
+ button = gtk_button_new_with_label(BUTTON_DELETE_PROJECT);
+ g_signal_connect(GTK_OBJECT(button), "clicked", (GtkSignalFunc) xsane_multipage_project_delete, NULL);
+ gtk_box_pack_start(GTK_BOX(multipage_project_exists_hbox), button, TRUE, TRUE, 0);
+ gtk_widget_show(button);
+
+ gtk_widget_show(multipage_project_exists_hbox);
+ xsane.project_exists = multipage_project_exists_hbox;
+
+ button = gtk_button_new_with_label(BUTTON_CREATE_PROJECT);
+ g_signal_connect(GTK_OBJECT(button), "clicked", (GtkSignalFunc) xsane_multipage_project_create, NULL);
+ gtk_box_pack_start(GTK_BOX(hbox), button, TRUE, TRUE, 0);
+ xsane.project_not_exists = button;
+
+ /* progress bar */
+ xsane.project_progress_bar = (GtkProgressBar *) gtk_progress_bar_new();
+ gtk_box_pack_start(GTK_BOX(multipage_scan_vbox), (GtkWidget *) xsane.project_progress_bar, FALSE, FALSE, 0);
+ gtk_progress_set_show_text(GTK_PROGRESS(xsane.project_progress_bar), TRUE);
+ gtk_progress_set_format_string(GTK_PROGRESS(xsane.project_progress_bar), "");
+ gtk_widget_show(GTK_WIDGET(xsane.project_progress_bar));
+
+
+ xsane.project_dialog = multipage_dialog;
+
+ xsane_multipage_project_load();
+
+ gtk_window_move(GTK_WINDOW(xsane.project_dialog), xsane.project_dialog_posx, xsane.project_dialog_posy);
+ gtk_widget_show(multipage_dialog);
+}
+
+/* ---------------------------------------------------------------------------------------------------------------------- */
+
+static void xsane_multipage_project_set_sensitive(int sensitive)
+{
+ gtk_widget_set_sensitive(xsane.project_box, sensitive);
+ gtk_widget_set_sensitive(xsane.project_exists, sensitive);
+}
+
+/* ---------------------------------------------------------------------------------------------------------------------- */
+
+static void xsane_multipage_project_load()
+{
+ FILE *projectfile;
+ char page[256];
+ char filename[PATH_MAX];
+ GtkWidget *list_item;
+ int i;
+ int c;
+
+ DBG(DBG_proc, "xsane_multipage_project_load\n");
+
+ if (xsane.multipage_status)
+ {
+ free(xsane.multipage_status);
+ xsane.multipage_status = NULL;
+ }
+
+ if (xsane.multipage_filename)
+ {
+ free(xsane.multipage_filename);
+ xsane.multipage_filename = NULL;
+ }
+
+ gtk_list_remove_items(GTK_LIST(xsane.project_list), GTK_LIST(xsane.project_list)->children);
+
+ snprintf(filename, sizeof(filename), "%s/xsane-multipage-list", preferences.multipage_project);
+ projectfile = fopen(filename, "rb"); /* read binary (b for win32) */
+
+ if ((!projectfile) || (feof(projectfile)))
+ {
+ snprintf(filename, sizeof(filename), "%s/image-1.pnm", preferences.multipage_project);
+ xsane.multipage_filename=strdup(filename);
+ xsane_update_counter_in_filename(&xsane.multipage_filename, FALSE, 0, preferences.filename_counter_len); /* correct counter len */
+
+ xsane.multipage_status=strdup(TEXT_PROJECT_STATUS_NOT_CREATED);
+
+ gtk_widget_hide(xsane.project_exists);
+ gtk_widget_show(xsane.project_not_exists);
+
+ gtk_widget_set_sensitive(xsane.project_box, FALSE);
+ gtk_widget_set_sensitive(xsane.project_exists, FALSE);
+ /* do not change sensitivity of multipage_project_entry_box here !!! */
+ gtk_widget_set_sensitive(GTK_WIDGET(xsane.start_button), FALSE);
+ }
+ else
+ {
+ i=0;
+ c=0;
+ while ((i<255) && (c != 10) && (c != EOF)) /* first line is multipage status */
+ {
+ c = fgetc(projectfile);
+ page[i++] = c;
+ }
+ page[i-1] = 0;
+ if (strchr(page, '@'))
+ {
+ *strchr(page, '@') = 0;
+ }
+
+ if (xsane.multipage_status)
+ {
+ free(xsane.multipage_status);
+ }
+ xsane.multipage_status = strdup(page);
+
+
+ i=0;
+ c=0;
+ while ((i<255) && (c != 10) && (c != EOF)) /* second line is next multipage filename */
+ {
+ c = fgetc(projectfile);
+ page[i++] = c;
+ }
+ page[i-1] = 0;
+
+ snprintf(filename, sizeof(filename), "%s/%s", preferences.multipage_project, page);
+ xsane.multipage_filename=strdup(filename);
+
+ while (!feof(projectfile))
+ {
+ i=0;
+ c=0;
+
+ while ((i<255) && (c != 10) && (c != EOF))
+ {
+ c = fgetc(projectfile);
+ page[i++] = c;
+ }
+ page[i-1]=0;
+
+ if (c > 1)
+ {
+ char *type;
+ char *extension;
+
+ extension = strrchr(page, '.');
+ if (extension)
+ {
+ type = strdup(extension);
+ *extension = 0;
+ }
+ else
+ {
+ type = strdup("");
+ }
+
+ list_item = gtk_list_item_new_with_label(page);
+ gtk_object_set_data(GTK_OBJECT(list_item), "list_item_data", strdup(page));
+ gtk_object_set_data(GTK_OBJECT(list_item), "list_item_type", strdup(type));
+ gtk_container_add(GTK_CONTAINER(xsane.project_list), list_item);
+ gtk_widget_show(list_item);
+ }
+ }
+
+ if (!strcmp(xsane.multipage_status, TEXT_PROJECT_STATUS_FILE_SAVING))
+ {
+ xsane_multipage_project_set_sensitive(FALSE);
+ gtk_widget_set_sensitive(xsane.project_entry_box, TRUE);
+ gtk_widget_set_sensitive(GTK_WIDGET(xsane.start_button), FALSE);
+ }
+ else
+ {
+ xsane_multipage_project_set_sensitive(TRUE);
+ gtk_widget_set_sensitive(xsane.project_entry_box, TRUE);
+ gtk_widget_set_sensitive(GTK_WIDGET(xsane.start_button), TRUE);
+ }
+
+ gtk_widget_show(xsane.project_exists);
+ gtk_widget_hide(xsane.project_not_exists);
+ }
+
+ if (projectfile)
+ {
+ fclose(projectfile);
+ }
+
+ gtk_progress_set_format_string(GTK_PROGRESS(xsane.project_progress_bar), _(xsane.multipage_status));
+ gtk_progress_bar_update(GTK_PROGRESS_BAR(xsane.project_progress_bar), 0.0);
+}
+
+/* ---------------------------------------------------------------------------------------------------------------------- */
+
+static void xsane_multipage_project_delete()
+{
+ char *page;
+ char *type;
+ char file[256];
+ GList *list = (GList *) GTK_LIST(xsane.project_list)->children;
+ GtkObject *list_item;
+
+ DBG(DBG_proc, "xsane_multipage_project_delete\n");
+
+ while (list)
+ {
+ list_item = GTK_OBJECT(list->data);
+ page = strdup((char *) gtk_object_get_data(list_item, "list_item_data"));
+ type = strdup((char *) gtk_object_get_data(list_item, "list_item_type"));
+ xsane_convert_text_to_filename(&page);
+ snprintf(file, sizeof(file), "%s/%s%s", preferences.multipage_project, page, type);
+ free(page);
+ free(type);
+ remove(file);
+ list = list->next;
+ }
+ snprintf(file, sizeof(file), "%s/xsane-multipage-list", preferences.multipage_project);
+ remove(file);
+ snprintf(file, sizeof(file), "%s", preferences.multipage_project);
+ rmdir(file);
+
+ xsane_multipage_project_load();
+}
+
+/* ---------------------------------------------------------------------------------------------------------------------- */
+
+void xsane_multipage_project_save()
+{
+ FILE *projectfile;
+ GList *list = (GList *) GTK_LIST(xsane.project_list)->children;
+ GtkObject *list_item;
+ char *page;
+ char *type;
+ char filename[256];
+
+ DBG(DBG_proc, "xsane_multipage_project_save\n");
+
+ umask((mode_t) preferences.directory_umask); /* define new file permissions */
+ mkdir(preferences.multipage_project, 0777); /* make sure directory exists */
+
+ snprintf(filename, sizeof(filename), "%s/xsane-multipage-list", preferences.multipage_project);
+
+ if (xsane_create_secure_file(filename)) /* remove possibly existing symbolic links for security */
+ {
+ char buf[256];
+
+ snprintf(buf, sizeof(buf), "%s %s %s\n", ERR_DURING_SAVE, ERR_CREATE_SECURE_FILE, filename);
+ xsane_back_gtk_error(buf, TRUE);
+ return; /* error */
+ }
+
+ projectfile = fopen(filename, "wb"); /* write binary (b for win32) */
+
+ if (xsane.multipage_status)
+ {
+ char buf[256];
+
+ snprintf(buf, 32, "%s@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@", xsane.multipage_status); /* fill 32 characters status line */
+ fprintf(projectfile, "%s\n", buf); /* first line is status of multipage */
+ gtk_progress_set_format_string(GTK_PROGRESS(xsane.project_progress_bar), _(xsane.multipage_status));
+ gtk_progress_bar_update(GTK_PROGRESS_BAR(xsane.project_progress_bar), 0.0);
+ }
+ else
+ {
+ fprintf(projectfile, " \n"); /* no multipage status */
+ gtk_progress_set_format_string(GTK_PROGRESS(xsane.project_progress_bar), "");
+ gtk_progress_bar_update(GTK_PROGRESS_BAR(xsane.project_progress_bar), 0.0);
+ }
+
+ if (xsane.multipage_filename)
+ {
+ fprintf(projectfile, "%s\n", strrchr(xsane.multipage_filename, '/')+1); /* third line is next multipage filename */
+ }
+ else
+ {
+ fprintf(projectfile, "\n");
+ }
+
+ while (list)
+ {
+ list_item = GTK_OBJECT(list->data);
+ page = (char *) gtk_object_get_data(list_item, "list_item_data");
+ type = (char *) gtk_object_get_data(list_item, "list_item_type");
+ fprintf(projectfile, "%s%s\n", page, type);
+ list = list->next;
+ }
+
+ fclose(projectfile);
+}
+
+/* ---------------------------------------------------------------------------------------------------------------------- */
+
+static void xsane_multipage_project_create()
+{
+ DBG(DBG_proc, "xsane_multipage_project_create\n");
+
+ if (strlen(preferences.multipage_project))
+ {
+ if (xsane.multipage_status)
+ {
+ free(xsane.multipage_status);
+ }
+ xsane.multipage_status = strdup(TEXT_PROJECT_STATUS_CREATED);
+ xsane_multipage_project_save();
+ xsane_multipage_project_load();
+ }
+}
+
+/* ---------------------------------------------------------------------------------------------------------------------- */
+
+static void xsane_multipage_project_changed_callback(GtkWidget *widget, gpointer data)
+{
+ DBG(DBG_proc, "xsane_multipage_project_changed_callback\n");
+
+ if (preferences.multipage_project)
+ {
+ free((void *) preferences.multipage_project);
+ }
+ preferences.multipage_project = strdup(gtk_entry_get_text(GTK_ENTRY(widget)));
+
+ xsane_multipage_project_load();
+}
+
+/* ---------------------------------------------------------------------------------------------------------------------- */
+
+static void xsane_multipage_entry_move_up_callback(GtkWidget *widget, gpointer list)
+{
+ GList *select;
+ GList *item = GTK_LIST(list)->children;
+ GtkWidget *list_item_1;
+ GtkWidget *list_item_2;
+ int position;
+ int newpos;
+
+ DBG(DBG_proc, "xsane_multipage_entry_move_up\n");
+
+ select = GTK_LIST(list)->selection;
+ if (select)
+ {
+ list_item_1 = select->data;
+
+ position = gtk_list_child_position(GTK_LIST(list), list_item_1);
+ position--; /* move up */
+ newpos = position;
+
+ if (position >= 0)
+ {
+ while (position>0)
+ {
+ item = item->next;
+ position--;
+ }
+
+ list_item_2 = item->data;
+ if (list_item_2)
+ {
+ xsane_front_gtk_list_entries_swap(list_item_1, list_item_2);
+ gtk_list_select_item(GTK_LIST(list), newpos);
+
+ if (xsane.multipage_status)
+ {
+ free(xsane.multipage_status);
+ }
+ xsane.multipage_status = strdup(TEXT_PROJECT_STATUS_CHANGED);
+ xsane_multipage_project_save();
+ }
+ }
+ }
+}
+
+/* ---------------------------------------------------------------------------------------------------------------------- */
+
+static void xsane_multipage_entry_move_down_callback(GtkWidget *widget, gpointer list)
+{
+ GList *select;
+ GList *item = GTK_LIST(list)->children;
+ GtkWidget *list_item_1;
+ GtkWidget *list_item_2;
+ int position;
+ int newpos;
+
+ DBG(DBG_proc, "xsane_multipage_entry_move_down\n");
+
+ select = GTK_LIST(list)->selection;
+ if (select)
+ {
+ list_item_1 = select->data;
+
+ position = gtk_list_child_position(GTK_LIST(list), list_item_1);
+ position++; /* move down */
+ newpos = position;
+
+ while ((position>0) && (item))
+ {
+ item = item->next;
+ position--;
+ }
+
+ if (item)
+ {
+ list_item_2 = item->data;
+ if (list_item_2)
+ {
+ xsane_front_gtk_list_entries_swap(list_item_1, list_item_2);
+ gtk_list_select_item(GTK_LIST(list), newpos);
+
+ if (xsane.multipage_status)
+ {
+ free(xsane.multipage_status);
+ }
+ xsane.multipage_status = strdup(TEXT_PROJECT_STATUS_CHANGED);
+ xsane_multipage_project_save();
+ }
+ }
+ }
+}
+
+/* ---------------------------------------------------------------------------------------------------------------------- */
+
+static void xsane_multipage_entry_delete_callback(GtkWidget *widget, gpointer list)
+{
+ GtkObject *list_item;
+ GList *select;
+ char *page;
+ char *type;
+ char file[256];
+
+ DBG(DBG_proc, "xsane_multipage_entry_delete_callback\n");
+
+ select = GTK_LIST(list)->selection;
+ if (select)
+ {
+ list_item = GTK_OBJECT(select->data);
+ page = strdup((char *) gtk_object_get_data(list_item, "list_item_data"));
+ type = strdup((char *) gtk_object_get_data(list_item, "list_item_type"));
+ xsane_convert_text_to_filename(&page);
+ snprintf(file, sizeof(file), "%s/%s%s", preferences.multipage_project, page, type);
+ free(page);
+ free(type);
+ remove(file);
+ gtk_widget_destroy(GTK_WIDGET(list_item));
+
+ if (xsane.multipage_status)
+ {
+ free(xsane.multipage_status);
+ }
+ xsane.multipage_status = strdup(TEXT_PROJECT_STATUS_CHANGED);
+ xsane_multipage_project_save();
+ }
+}
+
+/* ---------------------------------------------------------------------------------------------------------------------- */
+
+static void xsane_multipage_show_callback(GtkWidget *widget, gpointer list)
+{
+ GtkObject *list_item;
+ GList *select;
+ char *page;
+ char *type;
+ char filename[256];
+
+ DBG(DBG_proc, "xsane_multipage_entry_show_callback\n");
+
+ select = GTK_LIST(list)->selection;
+ if (select)
+ {
+ list_item = GTK_OBJECT(select->data);
+ page = strdup((char *) gtk_object_get_data(list_item, "list_item_data"));
+ type = strdup((char *) gtk_object_get_data(list_item, "list_item_type"));
+ xsane_convert_text_to_filename(&page);
+ snprintf(filename, sizeof(filename), "%s/%s%s", preferences.multipage_project, page, type);
+ free(page);
+ free(type);
+
+ xsane_viewer_new(filename, NULL, FALSE, filename, VIEWER_NO_MODIFICATION, IMAGE_SAVED);
+ }
+}
+
+/* ---------------------------------------------------------------------------------------------------------------------- */
+
+static void xsane_multipage_edit_callback(GtkWidget *widget, gpointer list)
+{
+ GtkObject *list_item;
+ GList *select;
+ char *page;
+ char *type;
+ char filename[PATH_MAX];
+ char outfilename[PATH_MAX];
+ int cancel_save = 0;
+
+ DBG(DBG_proc, "xsane_multipage_entry_show_callback\n");
+
+ select = GTK_LIST(list)->selection;
+ if (select)
+ {
+ list_item = GTK_OBJECT(select->data);
+ page = strdup((char *) gtk_object_get_data(list_item, "list_item_data"));
+ type = strdup((char *) gtk_object_get_data(list_item, "list_item_type"));
+ xsane_convert_text_to_filename(&page);
+ snprintf(filename, sizeof(filename), "%s/%s%s", preferences.multipage_project, page, type);
+ free(page);
+ free(type);
+
+ xsane_back_gtk_make_path(sizeof(outfilename), outfilename, 0, 0, "xsane-viewer-", xsane.dev_name, ".pnm", XSANE_PATH_TMP);
+ xsane_copy_file_by_name(outfilename, filename, xsane.project_progress_bar, &cancel_save);
+
+ xsane.multipage_status = strdup(TEXT_PROJECT_STATUS_CHANGED);
+ xsane_multipage_project_save();
+
+ gtk_progress_set_format_string(GTK_PROGRESS(xsane.project_progress_bar), _(xsane.multipage_status));
+ gtk_progress_bar_update(GTK_PROGRESS_BAR(xsane.project_progress_bar), 0.0);
+
+ xsane_viewer_new(outfilename, NULL, FALSE, filename, VIEWER_NO_NAME_MODIFICATION, IMAGE_SAVED);
+ }
+}
+
+/* ---------------------------------------------------------------------------------------------------------------------- */
+
+static void xsane_multipage_save_file()
+{
+ char *image;
+ char *type;
+ GList *list = (GList *) GTK_LIST(xsane.project_list)->children;
+ GtkObject *list_item;
+ char source_filename[PATH_MAX];
+ char multipage_filename[PATH_MAX];
+ int output_format;
+ int cancel_save = 0;
+ int page, pages = 0;
+ FILE *outfile = NULL, *imagefile = NULL;
+#ifdef HAVE_LIBTIFF
+ TIFF *tiffile = NULL;
+#endif
+ Image_info image_info;
+ long int source_size = 0;
+ float imagewidth, imageheight;
+ char buf[255];
+ struct pdf_xref xref;
+
+ DBG(DBG_proc, "xsane_multipage_save_file\n");
+
+ xsane_set_sensitivity(FALSE); /* do not allow changing xsane mode */
+ xsane_multipage_project_set_sensitive(FALSE);
+
+ while (gtk_events_pending())
+ {
+ DBG(DBG_info, "calling gtk_main_iteration\n");
+ gtk_main_iteration();
+ }
+
+ if (xsane.multipage_status)
+ {
+ free(xsane.multipage_status);
+ }
+ xsane.multipage_status = strdup(TEXT_PROJECT_STATUS_FILE_SAVING);
+
+ gtk_progress_set_format_string(GTK_PROGRESS(xsane.project_progress_bar), _(xsane.multipage_status));
+ gtk_progress_bar_update(GTK_PROGRESS_BAR(xsane.project_progress_bar), 0.0);
+
+
+ snprintf(multipage_filename, sizeof(multipage_filename), "%s%s", preferences.multipage_project, preferences.multipage_filetype);
+ output_format = xsane_identify_output_format(multipage_filename, NULL, NULL);
+
+ while (list)
+ {
+ list_item = GTK_OBJECT(list->data);
+ image = strdup((char *) gtk_object_get_data(list_item, "list_item_data"));
+ type = strdup((char *) gtk_object_get_data(list_item, "list_item_type"));
+ xsane_convert_text_to_filename(&image);
+ snprintf(source_filename, sizeof(source_filename), "%s/%s%s", preferences.multipage_project, image, type);
+ free(image);
+ free(type);
+ list = list->next;
+ pages++;
+ source_size += xsane_get_filesize(source_filename);
+ }
+
+
+ if ( (preferences.overwrite_warning) ) /* test if filename already used */
+ {
+ FILE *testfile;
+
+ testfile = fopen(multipage_filename, "rb"); /* read binary (b for win32) */
+ if (testfile) /* filename used: skip */
+ {
+ char buf[256];
+
+ fclose(testfile);
+
+ snprintf(buf, sizeof(buf), WARN_FILE_EXISTS, multipage_filename);
+ if (xsane_back_gtk_decision(ERR_HEADER_WARNING, (gchar **) warning_xpm, buf, BUTTON_OVERWRITE, BUTTON_CANCEL, TRUE /* wait */) == FALSE)
+ {
+ xsane_set_sensitivity(TRUE);
+ xsane_multipage_project_set_sensitive(TRUE);
+ if (xsane.multipage_status)
+ {
+ free(xsane.multipage_status);
+ }
+ xsane.multipage_status = strdup(TEXT_PROJECT_STATUS_FILE_SAVING_ABORTED);
+
+ gtk_progress_set_format_string(GTK_PROGRESS(xsane.project_progress_bar), _(xsane.multipage_status));
+ gtk_progress_bar_update(GTK_PROGRESS_BAR(xsane.project_progress_bar), 0.0);
+ return;
+ }
+ }
+ }
+
+
+ if (xsane_create_secure_file(multipage_filename)) /* remove possibly existing symbolic links for security */
+ {
+ snprintf(buf, sizeof(buf), "%s %s %s\n", ERR_DURING_SAVE, ERR_CREATE_SECURE_FILE, multipage_filename);
+ xsane_back_gtk_error(buf, TRUE);
+ xsane_multipage_project_set_sensitive(TRUE);
+ xsane_set_sensitivity(TRUE); /* allow changing xsane mode */
+ return;
+ }
+
+ DBG(DBG_info, "xsane_multipage_save_file: created %s\n", multipage_filename);
+
+
+ if ((output_format == XSANE_PS) || (output_format == XSANE_PDF))
+ {
+ outfile = fopen(multipage_filename, "wb"); /* b = binary mode for win32 */
+ if (!outfile)
+ {
+ snprintf(buf, sizeof(buf), "%s %s %s\n", ERR_DURING_SAVE, ERR_CREATE_SECURE_FILE, multipage_filename);
+ xsane_back_gtk_error(buf, TRUE);
+ xsane_multipage_project_set_sensitive(TRUE);
+ xsane_set_sensitivity(TRUE); /* allow changing xsane mode */
+
+ if (xsane.multipage_status)
+ {
+ free(xsane.multipage_status);
+ }
+ xsane.multipage_status = strdup(TEXT_PROJECT_STATUS_FILE_SAVING_ERROR);
+
+ gtk_progress_set_format_string(GTK_PROGRESS(xsane.project_progress_bar), _(xsane.multipage_status));
+ gtk_progress_bar_update(GTK_PROGRESS_BAR(xsane.project_progress_bar), 0.0);
+ return;
+ }
+
+ if (output_format == XSANE_PS)
+ {
+ xsane_save_ps_create_document_header(outfile, pages, preferences.save_ps_flatdecoded);
+ }
+ else if (output_format == XSANE_PDF)
+ {
+ xsane_save_pdf_create_document_header(outfile, &xref, pages, preferences.save_pdf_flatdecoded);
+ }
+ }
+#ifdef HAVE_LIBTIFF
+ else if (output_format == XSANE_TIFF)
+ {
+ tiffile = TIFFOpen(multipage_filename, "w");
+ if (!tiffile)
+ {
+ snprintf(buf, sizeof(buf), "%s %s %s\n", ERR_DURING_SAVE, ERR_OPEN_FAILED, multipage_filename);
+ xsane_back_gtk_error(buf, TRUE);
+ xsane_multipage_project_set_sensitive(TRUE);
+ xsane_set_sensitivity(TRUE); /* allow changing xsane mode */
+
+ if (xsane.multipage_status)
+ {
+ free(xsane.multipage_status);
+ }
+ xsane.multipage_status = strdup(TEXT_PROJECT_STATUS_FILE_SAVING_ERROR);
+
+ gtk_progress_set_format_string(GTK_PROGRESS(xsane.project_progress_bar), _(xsane.multipage_status));
+ gtk_progress_bar_update(GTK_PROGRESS_BAR(xsane.project_progress_bar), 0.0);
+ return;
+ }
+ }
+#endif
+ else
+ {
+ snprintf(buf, sizeof(buf), "%s unsupported multipage fileformat\n", ERR_DURING_SAVE);
+ xsane_back_gtk_error(buf, TRUE);
+ xsane_multipage_project_set_sensitive(TRUE);
+ xsane_set_sensitivity(TRUE); /* allow changing xsane mode */
+
+ if (xsane.multipage_status)
+ {
+ free(xsane.multipage_status);
+ }
+ xsane.multipage_status = strdup(TEXT_PROJECT_STATUS_FILE_SAVING_ERROR);
+
+ gtk_progress_set_format_string(GTK_PROGRESS(xsane.project_progress_bar), _(xsane.multipage_status));
+ gtk_progress_bar_update(GTK_PROGRESS_BAR(xsane.project_progress_bar), 0.0);
+ return;
+ }
+
+
+ list = (GList *) GTK_LIST(xsane.project_list)->children;
+
+ page = 1;
+ while (list)
+ {
+ list_item = GTK_OBJECT(list->data);
+ image = strdup((char *) gtk_object_get_data(list_item, "list_item_data"));
+ type = strdup((char *) gtk_object_get_data(list_item, "list_item_type"));
+ xsane_convert_text_to_filename(&image);
+ snprintf(source_filename, sizeof(source_filename), "%s/%s%s", preferences.multipage_project, image, type);
+
+ snprintf(buf, sizeof(buf), "%s %s %d/%d", _(xsane.multipage_status), PROGRESS_PAGE, page, pages);
+ gtk_progress_set_format_string(GTK_PROGRESS(xsane.project_progress_bar), buf);
+
+ imagefile = fopen(source_filename, "rb"); /* read binary (b for win32) */
+ if (!imagefile)
+ {
+ DBG(DBG_error, "could not read imagefile %s\n", source_filename);
+ return;
+ }
+
+ xsane_read_pnm_header(imagefile, &image_info);
+
+ if (output_format == XSANE_PS)
+ {
+ imagewidth = 72.0 * image_info.image_width/image_info.resolution_x; /* width in 1/72 inch */
+ imageheight = 72.0 * image_info.image_height/image_info.resolution_y; /* height in 1/72 inch */
+
+ xsane_save_ps_page(outfile, page,
+ imagefile, &image_info, imagewidth, imageheight,
+ 0, 0, imagewidth, imageheight, 0 /* portrait top left */,
+ preferences.save_ps_flatdecoded,
+ xsane.project_progress_bar, &cancel_save);
+ }
+ else if (output_format == XSANE_PDF)
+ {
+ imagewidth = 72.0 * image_info.image_width/image_info.resolution_x; /* width in 1/72 inch */
+ imageheight = 72.0 * image_info.image_height/image_info.resolution_y; /* height in 1/72 inch */
+
+ xsane_save_pdf_page(outfile, &xref, page,
+ imagefile, &image_info, imagewidth, imageheight,
+ 0, 0, imagewidth, imageheight, 0 /* portrait top left */,
+ preferences.save_pdf_flatdecoded,
+ xsane.project_progress_bar, &cancel_save);
+ }
+#ifdef HAVE_LIBTIFF
+ else if (output_format == XSANE_TIFF)
+ {
+ xsane_save_tiff_page(tiffile, page, pages, imagefile, &image_info, preferences.jpeg_quality,
+ xsane.project_progress_bar, &cancel_save);
+ }
+#endif
+
+ free(image);
+ free(type);
+ list = list->next;
+
+ page++;
+ }
+
+ if (output_format == XSANE_PS)
+ {
+ xsane_save_ps_create_document_trailer(outfile, 0 /* we defined pages at beginning */);
+
+ if (ferror(outfile))
+ {
+ char buf[255];
+
+ snprintf(buf, sizeof(buf), "%s %s", ERR_DURING_SAVE, strerror(errno));
+ DBG(DBG_error, "%s\n", buf);
+ xsane_back_gtk_decision(ERR_HEADER_ERROR, (gchar **) error_xpm, buf, BUTTON_OK, NULL, TRUE /* wait */);
+ cancel_save = 1;
+ }
+
+ fclose(outfile);
+ }
+ else if (output_format == XSANE_PDF)
+ {
+ xsane_save_pdf_create_document_trailer(outfile, &xref, pages);
+
+ if (ferror(outfile))
+ {
+ char buf[255];
+
+ snprintf(buf, sizeof(buf), "%s %s", ERR_DURING_SAVE, strerror(errno));
+ DBG(DBG_error, "%s\n", buf);
+ xsane_back_gtk_decision(ERR_HEADER_ERROR, (gchar **) error_xpm, buf, BUTTON_OK, NULL, TRUE /* wait */);
+ cancel_save = 1;
+ }
+
+ fclose(outfile);
+ }
+#ifdef HAVE_LIBTIFF
+ else if (output_format == XSANE_TIFF)
+ {
+ TIFFClose(tiffile);
+ }
+#endif
+
+ if (xsane.multipage_status)
+ {
+ free(xsane.multipage_status);
+ xsane.multipage_status = NULL;
+ }
+
+ if (cancel_save)
+ {
+ xsane.multipage_status = strdup(ERR_DURING_SAVE);
+ }
+ else
+ {
+ xsane.multipage_status = strdup(TEXT_PROJECT_STATUS_FILE_SAVED);
+ }
+ xsane_multipage_project_save();
+
+
+ gtk_progress_set_format_string(GTK_PROGRESS(xsane.project_progress_bar), _(xsane.multipage_status));
+ gtk_progress_bar_update(GTK_PROGRESS_BAR(xsane.project_progress_bar), 0.0);
+
+ xsane_multipage_project_set_sensitive(TRUE);
+ xsane_set_sensitivity(TRUE); /* allow changing xsane mode */
+}
+
+
diff --git a/src/xsane-multipage-project.h b/src/xsane-multipage-project.h
new file mode 100644
index 0000000..5f945eb
--- /dev/null
+++ b/src/xsane-multipage-project.h
@@ -0,0 +1,58 @@
+/* xsane -- a graphical (X11, gtk) scanner-oriented SANE frontend
+
+ xsane-multipage-project.h
+
+ Oliver Rauch <Oliver.Rauch@rauch-domain.de>
+ Copyright (C) 2005 Oliver Rauch
+ This file is part of the XSANE package.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+/* ---------------------------------------------------------------------------------------------------------------------- */
+
+#ifndef HAVE_XSANE_MULTIPAGE_PROJECT_H
+#define HAVE_XSANE_MULTIPAGE_PROJECT_H
+
+
+#include "xsane.h"
+#include "xsane-back-gtk.h"
+#include "xsane-front-gtk.h"
+#include "xsane-preview.h"
+#include "xsane-save.h"
+#include "xsane-gamma.h"
+#include "xsane-setup.h"
+#include "xsane-scan.h"
+#include "xsane-rc-io.h"
+#include "xsane-device-preferences.h"
+#include "xsane-preferences.h"
+#include "xsane-icons.h"
+#include "xsane-batch-scan.h"
+
+#ifdef HAVE_LIBPNG
+# ifdef HAVE_LIBZ
+# include <png.h>
+# include <zlib.h>
+# endif
+#endif
+
+#include <sys/wait.h>
+
+/* ---------------------------------------------------------------------------------------------------------------------- */
+
+
+extern void xsane_multipage_dialog(void);
+extern void xsane_multipage_project_save(void);
+
+#endif
diff --git a/src/xsane-preferences.c b/src/xsane-preferences.c
index b38cdbb..011e802 100644
--- a/src/xsane-preferences.c
+++ b/src/xsane-preferences.c
@@ -69,20 +69,22 @@ Preferences preferences =
0.0, /* fax_leftoffset */
0.0, /* fax_bottomoffset */
1, /* fax_fine_mode */
-#ifdef XSANE_ACTIVATE_MAIL
+ 1, /* fax_ps_flatdecoded */
+#ifdef XSANE_ACTIVATE_EMAIL
0, /* no default from email address */
0, /* no default reply to email address */
0, /* no default smtp server */
25, /* default smtp port */
- 0, /* no pop3 authentification */
+ 0, /* no email authentication */
+ 0, /* no default email authorization user */
+ 0, /* no default email authorization passsword */
0, /* no default pop3 server */
110, /* default pop3 port */
- 0, /* no default pop3 user */
- 0, /* no default pop3 passsword */
- 0, /* no mail project */
- 0, /* no mail viewer */
- 0, /* no mail filetype */
+ 0, /* no email project */
+ 0, /* no email filetype */
#endif
+ 0, /* no multipage project */
+ 0, /* no multipage filetype */
0, /* no default ocrcommand */
0, /* no default ocr input file option */
0, /* no default ocr output file option */
@@ -92,16 +94,20 @@ Preferences preferences =
0, /* no doc viewer */
80.0, /* jpeg_quality */
7.0, /* png_compression */
+ 6.0, /* tiff_zip_compression */
COMPRESSION_PACKBITS, /* tiff_compression16_nr */
COMPRESSION_JPEG, /* tiff_compression8_nr */
COMPRESSION_CCITTFAX3, /* tiff_compression1_nr */
1, /* save_devprefs_at_exit */
1, /* overwrite_warning */
1, /* skip_existing_numbers */
+ 1, /* save_ps_flatdecoded */
+ 1, /* save_pdf_flatdecoded */
0, /* save_pnm16_as_ascii */
0, /* reduce_16bit_to_8bit */
1, /* filename_counter_step */
4, /* filename_counter_len */
+ 1, /* adf_pages_max */
6, /* show_range_mode */
1, /* tooltips enabled */
1, /* show histogram */
@@ -176,20 +182,22 @@ desc[] =
{"fax-left-offset", xsane_rc_pref_double, POFFSET(fax_leftoffset)},
{"fax-bottom-offset", xsane_rc_pref_double, POFFSET(fax_bottomoffset)},
{"fax-fine-mode", xsane_rc_pref_int, POFFSET(fax_fine_mode)},
-#ifdef XSANE_ACTIVATE_MAIL
- {"mail-from", xsane_rc_pref_string, POFFSET(mail_from)},
- {"mail-reply-to", xsane_rc_pref_string, POFFSET(mail_reply_to)},
- {"mail-smtp-server", xsane_rc_pref_string, POFFSET(mail_smtp_server)},
- {"mail-smtp-port", xsane_rc_pref_int, POFFSET(mail_smtp_port)},
- {"mail-pop3-authentification", xsane_rc_pref_int, POFFSET(mail_pop3_authentification)},
- {"mail-pop3-server", xsane_rc_pref_string, POFFSET(mail_pop3_server)},
- {"mail-pop3-port", xsane_rc_pref_int, POFFSET(mail_pop3_port)},
- {"mail-pop3-user", xsane_rc_pref_string, POFFSET(mail_pop3_user)},
- {"mail-pop3-pass", xsane_rc_pref_string, POFFSET(mail_pop3_pass)},
- {"mail-project", xsane_rc_pref_string, POFFSET(mail_project)},
- {"mail-viewer", xsane_rc_pref_string, POFFSET(mail_viewer)},
- {"mail-filetype", xsane_rc_pref_string, POFFSET(mail_filetype)},
+ {"fax-ps-flatdecoded", xsane_rc_pref_int, POFFSET(fax_ps_flatdecoded)},
+#ifdef XSANE_ACTIVATE_EMAIL
+ {"e-mail-from", xsane_rc_pref_string, POFFSET(email_from)},
+ {"e-mail-reply-to", xsane_rc_pref_string, POFFSET(email_reply_to)},
+ {"e-mail-smtp-server", xsane_rc_pref_string, POFFSET(email_smtp_server)},
+ {"e-mail-smtp-port", xsane_rc_pref_int, POFFSET(email_smtp_port)},
+ {"e-mail-authentication", xsane_rc_pref_int, POFFSET(email_authentication)},
+ {"e-mail-auth-user", xsane_rc_pref_string, POFFSET(email_auth_user)},
+ {"e-mail-auth-pass", xsane_rc_pref_string, POFFSET(email_auth_pass)},
+ {"e-mail-pop3-server", xsane_rc_pref_string, POFFSET(email_pop3_server)},
+ {"e-mail-pop3-port", xsane_rc_pref_int, POFFSET(email_pop3_port)},
+ {"e-mail-project", xsane_rc_pref_string, POFFSET(email_project)},
+ {"e-mail-filetype", xsane_rc_pref_string, POFFSET(email_filetype)},
#endif
+ {"multipage-project", xsane_rc_pref_string, POFFSET(multipage_project)},
+ {"multipage-filetype", xsane_rc_pref_string, POFFSET(multipage_filetype)},
{"ocr-command", xsane_rc_pref_string, POFFSET(ocr_command)},
{"ocr-inputfile-option", xsane_rc_pref_string, POFFSET(ocr_inputfile_option)},
{"ocr-outputfile-options", xsane_rc_pref_string, POFFSET(ocr_outputfile_option)},
@@ -199,16 +207,20 @@ desc[] =
{"browser", xsane_rc_pref_string, POFFSET(browser)},
{"jpeg-quality", xsane_rc_pref_double, POFFSET(jpeg_quality)},
{"png-compression", xsane_rc_pref_double, POFFSET(png_compression)},
+ {"tiff-zip-compression", xsane_rc_pref_double, POFFSET(tiff_zip_compression)},
{"tiff-compression16_nr", xsane_rc_pref_int, POFFSET(tiff_compression16_nr)},
{"tiff-compression8_nr", xsane_rc_pref_int, POFFSET(tiff_compression8_nr)},
{"tiff-compression1_nr", xsane_rc_pref_int, POFFSET(tiff_compression1_nr)},
{"save-devprefs-at-exit", xsane_rc_pref_int, POFFSET(save_devprefs_at_exit)},
{"overwrite-warning", xsane_rc_pref_int, POFFSET(overwrite_warning)},
{"skip-existing-numbers", xsane_rc_pref_int, POFFSET(skip_existing_numbers)},
+ {"save-ps-flatdecoded", xsane_rc_pref_int, POFFSET(save_ps_flatdecoded)},
+ {"save-pdf-flatdecoded", xsane_rc_pref_int, POFFSET(save_pdf_flatdecoded)},
{"save-pnm16-as-ascii", xsane_rc_pref_int, POFFSET( save_pnm16_as_ascii)},
{"reduce-16bit-to8bit", xsane_rc_pref_int, POFFSET(reduce_16bit_to_8bit)},
{"filename-counter-step", xsane_rc_pref_int, POFFSET(filename_counter_step)},
{"filename-counter-len", xsane_rc_pref_int, POFFSET(filename_counter_len)},
+ {"adf-pages-max", xsane_rc_pref_int, POFFSET(adf_pages_max)},
{"show-range-mode", xsane_rc_pref_int, POFFSET(show_range_mode)},
{"tool-tips", xsane_rc_pref_int, POFFSET(tooltips_enabled)},
{"show-histogram", xsane_rc_pref_int, POFFSET(show_histogram)},
@@ -276,7 +288,8 @@ desc_printer[] =
{"printer-gamma", xsane_rc_pref_double, PRTOFFSET(gamma)},
{"printer-gamma-red", xsane_rc_pref_double, PRTOFFSET(gamma_red)},
{"printer-gamma-green", xsane_rc_pref_double, PRTOFFSET(gamma_green)},
- {"printer-gamma-blue", xsane_rc_pref_double, PRTOFFSET(gamma_blue)}
+ {"printer-gamma-blue", xsane_rc_pref_double, PRTOFFSET(gamma_blue)},
+ {"printer-ps-flatdecoded", xsane_rc_pref_int, PRTOFFSET(ps_flatdecoded)}
};
/* --------------------------------------------------------------------- */
@@ -385,6 +398,7 @@ void preferences_restore(int fd)
SANE_String name;
Wire w;
int i, n;
+ int item_identified = 1;
DBG(DBG_proc, "preferences_restore\n");
@@ -428,7 +442,7 @@ void preferences_restore(int fd)
}
}
- if (!strcmp(name, "printerdefinitions"))
+ if ( (!strcmp(name, "printer-name")) || (!strcmp(name, "preset-area-name")) )
{
break;
}
@@ -440,12 +454,35 @@ void preferences_restore(int fd)
}
}
- preferences.printer = calloc(preferences.printerdefinitions, sizeof(void *));
- n=0;
- while (n < preferences.printerdefinitions)
+ preferences.printer = NULL;
+ preferences.printer = calloc(1, sizeof(void *));
+ n=-1;
+ item_identified = 1;
+ while (item_identified)
{
- preferences.printer[n] = calloc(sizeof(Preferences_printer_t), 1);
- for (i = 0; i < NELEMS(desc_printer); ++i)
+ if (strcmp(name, desc_printer[0].name) == 0)
+ {
+ n++;
+ preferences.printer = realloc(preferences.printer, (n+1)*sizeof(void *));
+ preferences.printer[n] = calloc(sizeof(Preferences_printer_t), 1);
+ (*desc_printer[0].codec) (&w, preferences.printer[n], desc_printer[0].offset);
+ DBG(DBG_info2, "reading preferences printer definition %s\n", preferences.printer[n]->name);
+ item_identified = 1;
+ }
+ else
+ {
+ item_identified = 0;
+ for (i = 1; i < NELEMS(desc_printer); ++i)
+ {
+ if (strcmp(name, desc_printer[i].name) == 0)
+ {
+ (*desc_printer[i].codec) (&w, preferences.printer[n], desc_printer[i].offset);
+ item_identified = 1;
+ }
+ }
+ }
+
+ if (item_identified)
{
xsane_rc_io_w_space(&w, 3);
if (w.status)
@@ -460,23 +497,19 @@ void preferences_restore(int fd)
xsane_rc_io_w_exit(&w);
return;
}
-
- if (strcmp(name, desc_printer[i].name) == 0)
- {
- (*desc_printer[i].codec) (&w, preferences.printer[n], desc_printer[i].offset);
- }
- else
- {
- break;
- }
}
- DBG(DBG_info2, "preferences printer definition %s read\n", preferences.printer[n]->name);
- n++;
}
+ preferences.printerdefinitions = n+1;
+ /* finished reading printer definitions */
+
- if (preferences.preset_area_definitions)
+
+ n=-1;
+ if (strcmp(name, desc_preset_area[0].name) == 0) /* at least one preset area definition ? */
{
- preferences.preset_area = calloc(preferences.preset_area_definitions, sizeof(void *));
+ /* then we define "Full size" as definition 0 */
+ n++;
+ preferences.preset_area = calloc(1, sizeof(void *));
preferences.preset_area[0] = calloc(sizeof(Preferences_preset_area_t), 1);
preferences.preset_area[0]->name = strdup(_(MENU_ITEM_SURFACE_FULL_SIZE));
@@ -484,41 +517,54 @@ void preferences_restore(int fd)
preferences.preset_area[0]->yoffset = 0.0;
preferences.preset_area[0]->width = INF;
preferences.preset_area[0]->height = INF;
+ }
- n=1;
- while (n < preferences.preset_area_definitions)
+ item_identified = 1;
+ while (item_identified)
+ {
+ if (strcmp(name, desc_preset_area[0].name) == 0)
{
+ n++;
+ preferences.preset_area = realloc(preferences.preset_area, (n+1) * sizeof(void *));
preferences.preset_area[n] = calloc(sizeof(Preferences_preset_area_t), 1);
- for (i = 0; i < NELEMS(desc_preset_area); ++i)
- {
- xsane_rc_io_w_space(&w, 3);
- if (w.status)
- {
- xsane_rc_io_w_exit(&w);
- return;
- }
-
- xsane_rc_io_w_string(&w, &name);
- if (w.status || !name)
- {
- xsane_rc_io_w_exit(&w);
- return;
- }
+ (*desc_preset_area[0].codec) (&w, preferences.preset_area[n], desc_preset_area[0].offset);
+ DBG(DBG_info2, "reading preset area definition %s\n", preferences.preset_area[n]->name);
+ item_identified = 1;
+ }
+ else
+ {
+ item_identified = 0;
+ for (i = 1; i < NELEMS(desc_preset_area); ++i)
+ {
if (strcmp(name, desc_preset_area[i].name) == 0)
{
(*desc_preset_area[i].codec) (&w, preferences.preset_area[n], desc_preset_area[i].offset);
- }
- else
- {
- break;
+ item_identified = 1;
}
}
- DBG(DBG_info2, "preferences preset area definition %s read\n", preferences.preset_area[n]->name);
- n++;
+ }
+
+ if (item_identified)
+ {
+ xsane_rc_io_w_space(&w, 3);
+ if (w.status)
+ {
+ xsane_rc_io_w_exit(&w);
+ return;
+ }
+
+ xsane_rc_io_w_string(&w, &name);
+ if (w.status || !name)
+ {
+ xsane_rc_io_w_exit(&w);
+ return;
+ }
}
}
+ preferences.preset_area_definitions = n+1;
+
xsane_rc_io_w_exit(&w);
}
diff --git a/src/xsane-preferences.h b/src/xsane-preferences.h
index e59a66c..9f0e442 100644
--- a/src/xsane-preferences.h
+++ b/src/xsane-preferences.h
@@ -48,6 +48,7 @@ typedef struct
double gamma_red; /* printer gamma red */
double gamma_green; /* printer gamma green */
double gamma_blue; /* printer gamma blue */
+ int ps_flatdecoded; /* flatdecode (zlib compression), ps level 3 */
}
Preferences_printer_t;
@@ -107,21 +108,23 @@ typedef struct
double fax_leftoffset; /* left offset of fax paper in mm */
double fax_bottomoffset; /* bottom offset of fax paper in mm */
int fax_fine_mode; /* use fine or normal mode */
-
-#ifdef XSANE_ACTIVATE_MAIL
- char *mail_from; /* email address of sender */
- char *mail_reply_to; /* email address for replied emails */
- char *mail_smtp_server; /* ip address or domain name of smtp server */
- int mail_smtp_port; /* port to connect to smtp sever */
- int mail_pop3_authentification; /* use pop3 login for authentification */
- char *mail_pop3_server; /* ip address or domain name of pop3 server */
- int mail_pop3_port; /* port to connect to pop3 server */
- char *mail_pop3_user; /* user name for pop3 server */
- char *mail_pop3_pass; /* password for pop3 server */
- char *mail_project; /* mail project */
- char *mail_viewer; /* mail viewer */
- char *mail_filetype; /* mail filetype */
+ int fax_ps_flatdecoded; /* use postscript level 3 zlib compression */
+
+#ifdef XSANE_ACTIVATE_EMAIL
+ char *email_from; /* email address of sender */
+ char *email_reply_to; /* email address for replied emails */
+ char *email_smtp_server; /* ip address or domain name of smtp server */
+ int email_smtp_port; /* port to connect to smtp sever */
+ int email_authentication; /* type for email authentication */
+ char *email_auth_user; /* user name for email authorization */
+ char *email_auth_pass; /* password for email authorization */
+ char *email_pop3_server; /* ip address or domain name of pop3 server */
+ int email_pop3_port; /* port to connect to pop3 server */
+ char *email_project; /* mail project */
+ char *email_filetype; /* mail filetype */
#endif
+ char *multipage_project; /* multipage project */
+ char *multipage_filetype; /* multipage filetype */
char *ocr_command; /* ocrcommand */
char *ocr_inputfile_option; /* option for input file */
@@ -134,16 +137,20 @@ typedef struct
double jpeg_quality; /* quality when saving image as jpeg */
double png_compression; /* compression when saving image as pnm */
+ double tiff_zip_compression; /* compression rate for tiff zip (deflate) */
int tiff_compression16_nr; /* compression type nr when saving 16i bit image as tiff */
int tiff_compression8_nr; /* compression type nr when saving 8 bit image as tiff */
int tiff_compression1_nr; /* compression type nr when saving 1 bit image as tiff */
int save_devprefs_at_exit; /* save device preferences at exit */
int overwrite_warning; /* warn if file exists */
int skip_existing_numbers; /* skip used filenames when automatically increase counter */
+ int save_ps_flatdecoded; /* use zlib to for postscript compression (flatdecode) */
+ int save_pdf_flatdecoded; /* use zlib to for pdf compression (flatdecode) */
int save_pnm16_as_ascii; /* selection if pnm 16 bit is saved as ascii or binary file */
int reduce_16bit_to_8bit; /* reduce images with 16 bits/color to 8 bits/color */
int filename_counter_step; /* filename_counter += filename_counter_step; */
int filename_counter_len; /* minimum length of filename_counter */
+ int adf_pages_max; /* maximum pages to scan in adf mode */
int show_range_mode; /* how to show a range */
int tooltips_enabled; /* should tooltips be disabled? */
diff --git a/src/xsane-preview.c b/src/xsane-preview.c
index 5bd6457..b59ef1b 100644
--- a/src/xsane-preview.c
+++ b/src/xsane-preview.c
@@ -2405,12 +2405,22 @@ int preview_create_batch_icon_from_file(Preview *p, FILE *in, Batch_Scan_Paramet
void preview_create_batch_icon(Preview *p, Batch_Scan_Parameters *parameters)
{
- FILE *in;
+ FILE *in = NULL;
int quality = 0;
int time = 0;
+ int level;
- in = fopen(xsane.preview->filename[0], "rb");
- quality = preview_create_batch_icon_from_file(xsane.preview, in, parameters, quality, &time);
+ for(level = 2; level >= 0; level--)
+ {
+ if (p->filename[level])
+ {
+ in = fopen(p->filename[level], "rb"); /* read binary (b for win32) */
+ if (in)
+ {
+ quality = preview_create_batch_icon_from_file(xsane.preview, in, parameters, quality, &time);
+ }
+ }
+ }
if (quality <= 0)
{
@@ -2430,7 +2440,6 @@ void preview_create_batch_icon(Preview *p, Batch_Scan_Parameters *parameters)
}
fclose(in);
}
-
/* ---------------------------------------------------------------------------------------------------------------------- */
static int preview_restore_image_from_file(Preview *p, FILE *in, int min_quality, int *min_time)
@@ -4122,8 +4131,6 @@ static void preview_create_preset_area_menu(Preview *p, int selection)
void preview_generate_preview_filenames(Preview *p)
{
char filename[PATH_MAX];
- char buf[256];
- int error_flag = 0;
int i;
DBG(DBG_proc, "preview_generate_preview_filenames\n");
@@ -4143,30 +4150,23 @@ void preview_generate_preview_filenames(Preview *p)
}
else
{
- p->filename[i] = NULL; /* mark filename does not exist */
DBG(DBG_error, "ERROR: could not create preview file %s\n", filename);
- error_flag = 1;
+ p->filename[0] = NULL; /* mark filename does not exist */
+ p->filename[1] = NULL; /* mark filename does not exist */
+ p->filename[2] = NULL; /* mark filename does not exist */
+ break; /* do not try next preview level, one error is enough */
}
}
else
{
DBG(DBG_error, "ERROR: could not create filename for preview level %d\n", i);
- p->filename[i] = NULL;
- error_flag = 2;
+ p->filename[0] = NULL; /* mark filename does not exist */
+ p->filename[1] = NULL; /* mark filename does not exist */
+ p->filename[2] = NULL; /* mark filename does not exist */
+ break; /* do not try next preview level, one error is enough */
}
}
- if (error_flag == 1)
- {
- snprintf(buf, sizeof(buf), ERR_CREATE_PREVIEW_FILE);
- xsane_back_gtk_error(buf, TRUE);
- }
- else if (error_flag == 2)
- {
- snprintf(buf, sizeof(buf), ERR_CREATE_PREVIEW_FILENAME);
- xsane_back_gtk_error(buf, TRUE);
- }
-
return;
}
@@ -4526,17 +4526,6 @@ Preview *preview_new(void)
gtk_container_add(GTK_CONTAINER(frame), p->zoom);
gtk_widget_show(p->zoom);
-#if 0
- /* the RGB label */
- frame = gtk_frame_new(0);
- gtk_box_pack_start(GTK_BOX(p->menu_box), frame, FALSE, FALSE, 3);
- gtk_widget_show(frame);
- p->rgb_label = gtk_label_new(0);
- gtk_container_add(GTK_CONTAINER(frame), p->rgb_label);
- gtk_widget_show(p->rgb_label);
- preview_display_color_components(p, -1, -1); /* display "###, ###, ###" */
-#endif
-
gtk_widget_show(p->menu_box);
/* the menu box is ready */
@@ -4592,7 +4581,6 @@ Preview *preview_new(void)
gtk_widget_show(p->cancel);
gtk_widget_set_sensitive(p->cancel, FALSE);
-#if 1
/* the RGB label */
frame = gtk_frame_new(0);
gtk_box_pack_start(GTK_BOX(action_box), frame, FALSE, FALSE, 3);
@@ -4601,14 +4589,13 @@ Preview *preview_new(void)
gtk_container_add(GTK_CONTAINER(frame), p->rgb_label);
gtk_widget_show(p->rgb_label);
preview_display_color_components(p, -1, -1); /* display "###, ###, ###" */
-#endif
preview_update_surface(p, 0);
gtk_widget_show(p->window);
gtk_widget_show(p->top);
- cursor = gdk_cursor_new(XSANE_CURSOR_PREVIEW); /* set default curosr */
+ cursor = gdk_cursor_new(XSANE_CURSOR_PREVIEW); /* set default cursor */
gdk_window_set_cursor(p->window->window, cursor);
gdk_cursor_unref(cursor);
p->cursornr = XSANE_CURSOR_PREVIEW;
@@ -4622,7 +4609,7 @@ Preview *preview_new(void)
preview_display_valid(p);
- return p;
+ return p;
}
diff --git a/src/xsane-save.c b/src/xsane-save.c
index 2567898..9c3784b 100644
--- a/src/xsane-save.c
+++ b/src/xsane-save.c
@@ -25,6 +25,7 @@
#include "xsane.h"
#include "xsane-back-gtk.h"
#include "xsane-front-gtk.h"
+#include "xsane-save.h"
#include <time.h>
#include <sys/wait.h>
@@ -666,10 +667,10 @@ void xsane_write_pnm_header(FILE *file, Image_info *image_info, int save_pnm16_a
int xsane_copy_file(FILE *outfile, FILE *infile, GtkProgressBar *progress_bar, int *cancel_save)
{
- int size;
- int bytes;
- int bytes_sum = 0;
- char buf[65536];
+ long size;
+ long bytes_sum = 0;
+ size_t bytes;
+ unsigned char buf[65536];
DBG(DBG_proc, "copying file\n");
@@ -700,6 +701,17 @@ int xsane_copy_file(FILE *outfile, FILE *infile, GtkProgressBar *progress_bar, i
gtk_main_iteration();
}
+ if (ferror(infile))
+ {
+ char buf[255];
+
+ snprintf(buf, sizeof(buf), "%s %s", ERR_DURING_READ, strerror(errno));
+ DBG(DBG_error, "%s\n", buf);
+ xsane_back_gtk_decision(ERR_HEADER_ERROR, (gchar **) error_xpm, buf, BUTTON_OK, NULL, TRUE /* wait */);
+ *cancel_save = 1;
+ break;
+ }
+
if (ferror(outfile))
{
char buf[255];
@@ -721,12 +733,12 @@ int xsane_copy_file(FILE *outfile, FILE *infile, GtkProgressBar *progress_bar, i
if (size != bytes_sum)
{
- DBG(DBG_info, "copy errro, not complete, %d bytes of %d bytes copied\n", bytes_sum, size);
+ DBG(DBG_info, "copy errro, not complete, %ld bytes of %ld bytes copied\n", bytes_sum, size);
*cancel_save = 1;
return (*cancel_save);
}
- DBG(DBG_info, "copy complete, %d bytes copied\n", bytes_sum);
+ DBG(DBG_info, "copy complete, %ld bytes copied\n", bytes_sum);
return (*cancel_save);
}
@@ -1373,11 +1385,10 @@ int xsane_save_blur_image(FILE *outfile, FILE *imagefile, Image_info *image_info
int x, y, sx, sy;
int xmin, xmax;
int ymin, ymax;
- float val, norm;
+ double val, norm, outer_factor;
unsigned char *line_cache;
int bytespp = 1;
int intradius;
- float outer_factor;
int xmin_flag;
int xmax_flag;
int ymin_flag;
@@ -1498,7 +1509,7 @@ int xsane_save_blur_image(FILE *outfile, FILE *imagefile, Image_info *image_info
}
fputc((char) ((int) (val/norm)), outfile);
}
- else
+ else /* bytespp == 2 */
{
guint16 *line_cache16 = (guint16 *) line_cache;
guint16 val16;
@@ -2216,17 +2227,74 @@ int xsane_save_rotate_image(FILE *outfile, FILE *imagefile, Image_info *image_in
/* ---------------------------------------------------------------------------------------------------------------------- */
-static void xsane_save_ps_create_header(FILE *outfile, Image_info *image_info,
- float width, float height,
- int paper_left_margin, int paper_bottom_margin,
- int paper_width, int paper_height,
- int paper_orientation,
- GtkProgressBar *progress_bar)
+void xsane_save_ps_create_document_header(FILE *outfile, int pages, int flatdecode)
+{
+ DBG(DBG_proc, "xsane_save_ps_create_document_header\n");
+
+ fprintf(outfile, "%%!PS-Adobe-3.0\n");
+ fprintf(outfile, "%%%%Creator: XSane version %s (sane %d.%d) - by Oliver Rauch\n", VERSION,
+ SANE_VERSION_MAJOR(xsane.sane_backend_versioncode),
+ SANE_VERSION_MINOR(xsane.sane_backend_versioncode));
+ fprintf(outfile, "%%%%DocumentData: Clean7Bit\n");
+ if (flatdecode)
+ {
+ fprintf(outfile, "%%%%LanguageLevel: 3\n");
+ }
+ else
+ {
+ fprintf(outfile, "%%%%LanguageLevel: 2\n");
+ }
+
+ if (pages)
+ {
+ fprintf(outfile, "%%%%Pages: %d\n", pages);
+ }
+ else
+ {
+ fprintf(outfile, "%%%%Pages: (atend)\n");
+ }
+
+ fprintf(outfile, "%%%%EndComments\n");
+ fprintf(outfile, "\n");
+ fprintf(outfile, "/origstate save def\n");
+ fprintf(outfile, "20 dict begin\n");
+}
+
+/* ---------------------------------------------------------------------------------------------------------------------- */
+
+void xsane_save_ps_create_document_trailer(FILE *outfile, int pages)
+{
+ DBG(DBG_proc, "xsane_save_ps_create_document_trailer\n");
+
+ fprintf(outfile, "end\n");
+ fprintf(outfile, "origstate restore\n");
+
+ if (pages)
+ {
+ fprintf(outfile, "%%%%Trailer\n");
+ fprintf(outfile, "%%%%Pages: %d\n", pages);
+ }
+
+ fprintf(outfile, "%%%%EOF\n");
+ fprintf(outfile, "\n");
+
+}
+
+/* ---------------------------------------------------------------------------------------------------------------------- */
+
+/* page = [1 .. pages] */
+static void xsane_save_ps_create_page_header(FILE *outfile, int page,
+ Image_info *image_info,
+ float width, float height,
+ int paper_left_margin, int paper_bottom_margin,
+ int paper_width, int paper_height,
+ int paper_orientation, int flatdecode,
+ GtkProgressBar *progress_bar)
{
int degree, position_left, position_bottom, box_left, box_bottom, box_right, box_top, depth;
int left, bottom;
- DBG(DBG_proc, "xsane_save_ps_create_header\n");
+ DBG(DBG_proc, "xsane_save_ps_create_page_header\n");
switch (paper_orientation)
{
@@ -2312,19 +2380,9 @@ static void xsane_save_ps_create_header(FILE *outfile, Image_info *image_info,
depth = 8;
}
- fprintf(outfile, "%%!PS-Adobe-3.0\n");
- fprintf(outfile, "%%%%Creator: XSane version %s (sane %d.%d) - by Oliver Rauch\n", VERSION,
- SANE_VERSION_MAJOR(xsane.sane_backend_versioncode),
- SANE_VERSION_MINOR(xsane.sane_backend_versioncode));
- fprintf(outfile, "%%%%DocumentData: Clean7Bit\n");
- fprintf(outfile, "%%%%LanguageLevel: 2\n");
- fprintf(outfile, "%%%%Pages: 1\n");
- fprintf(outfile, "%%%%BoundingBox: %d %d %d %d\n", box_left, box_bottom, box_right, box_top);
- fprintf(outfile, "%%%%EndComments\n");
fprintf(outfile, "\n");
- fprintf(outfile, "/origstate save def\n");
- fprintf(outfile, "20 dict begin\n");
- fprintf(outfile, "%%%%Page: 1 1\n");
+ fprintf(outfile, "%%%%Page: %d %d\n", page, page);
+ fprintf(outfile, "%%%%PageBoundingBox: %d %d %d %d\n", box_left, box_bottom, box_right, box_top);
if (depth == 1)
{
@@ -2341,7 +2399,10 @@ static void xsane_save_ps_create_header(FILE *outfile, Image_info *image_info,
fprintf(outfile, "currentfile\n");
fprintf(outfile, "/ASCII85Decode filter\n");
#ifdef HAVE_LIBZ
- fprintf(outfile, "/FlateDecode filter\n");
+ if (flatdecode)
+ {
+ fprintf(outfile, "/FlateDecode filter\n");
+ }
#endif
if (image_info->colors == 3) /* what about RGBA here ? */
@@ -2358,28 +2419,35 @@ static void xsane_save_ps_create_header(FILE *outfile, Image_info *image_info,
/* ---------------------------------------------------------------------------------------------------------------------- */
+static void xsane_save_ps_create_page_trailer(FILE *outfile)
+{
+ fprintf(outfile, "\n");
+ fprintf(outfile, "showpage\n");
+ fprintf(outfile, "%%%%PageTrailer\n");
+}
+
+/* ---------------------------------------------------------------------------------------------------------------------- */
+
+#ifdef HAVE_LIBZ
/* Utility function for the PostScript output */
-static int xsane_write_compressed_a85(FILE *outfile, unsigned char *line, int len, int finish)
+static int xsane_write_compressed_a85_flatdecode(FILE *outfile, unsigned char *line, int len, int finish)
{
static unsigned char *cbuf = NULL;
static int cbuflen = 0;
static int linelen = 0;
int i, j;
int outlen;
-#ifdef HAVE_LIBZ
static int init = 0;
static z_stream s;
int ret;
int flush;
-#endif
static int a85count = 0;
static guint32 a85tuple = 0;
static unsigned char a85block[6] = {0, 0, 0, 0, 0, 0};
static int count = 0;
- DBG(DBG_proc, "xsane_write_compressed_a85\n");
+ DBG(DBG_proc, "xsane_write_compressed_a85_flatdecode\n");
-#ifdef HAVE_LIBZ
if (linelen != len)
{
linelen = len;
@@ -2436,10 +2504,6 @@ static int xsane_write_compressed_a85(FILE *outfile, unsigned char *line, int le
}
outlen = cbuflen - s.avail_out;
-#else
- cbuf = line;
- outlen = len;
-#endif /* HAVE_LIBZ */
/* ASCII85 (base 85) encoding */
for (i = 0; i < outlen; i++)
@@ -2504,9 +2568,7 @@ static int xsane_write_compressed_a85(FILE *outfile, unsigned char *line, int le
break;
}
}
-#ifdef HAVE_LIBZ
} while (s.avail_out == 0);
-#endif
if (finish)
{
@@ -2538,12 +2600,135 @@ static int xsane_write_compressed_a85(FILE *outfile, unsigned char *line, int le
fprintf(outfile, "\n");
}
fprintf(outfile, "~>\n");
-#ifdef HAVE_LIBZ
deflateEnd(&s);
free(cbuf);
cbuf = NULL;
init = 0;
+ a85tuple = 0;
+ a85count = 0;
+ cbuflen = 0;
+ linelen = 0;
+ count = 0;
+ }
+
+ return 0;
+}
#endif
+
+/* ---------------------------------------------------------------------------------------------------------------------- */
+
+/* Utility function for the PostScript output */
+static int xsane_write_compressed_a85(FILE *outfile, unsigned char *line, int len, int finish)
+{
+ static unsigned char *cbuf = NULL;
+ static int cbuflen = 0;
+ static int linelen = 0;
+ int i, j;
+ int outlen;
+ static int a85count = 0;
+ static guint32 a85tuple = 0;
+ static unsigned char a85block[6] = {0, 0, 0, 0, 0, 0};
+ static int count = 0;
+
+ DBG(DBG_proc, "xsane_write_compressed_a85\n");
+
+ cbuf = line;
+ outlen = len;
+
+ /* ASCII85 (base 85) encoding */
+ for (i = 0; i < outlen; i++)
+ {
+ switch (a85count)
+ {
+ case 0:
+ a85tuple |= (cbuf[i] << 24);
+ a85count++;
+ break;
+
+ case 1:
+ a85tuple |= (cbuf[i] << 16);
+ a85count++;
+ break;
+
+ case 2:
+ a85tuple |= (cbuf[i] << 8);
+ a85count++;
+ break;
+
+ case 3:
+ a85tuple |= (cbuf[i] << 0);
+
+ if (count == 40)
+ {
+ fprintf(outfile, "\n");
+ count = 0;
+ }
+
+ if (a85tuple == 0)
+ {
+ fprintf(outfile, "z");
+ count++;
+ }
+ else
+ {
+ /* The ASCII chars must be written in reverse order, hence -> a85block[4-j] */
+ for (j = 0; j < 5; j++)
+ {
+ a85block[4-j] = a85tuple % 85 + '!';
+ a85tuple /= 85;
+ }
+
+ for (j = 0; j < 5; j++)
+ {
+ fprintf(outfile, "%c", a85block[j]);
+ count++;
+ if (count == 40)
+ {
+ fprintf(outfile, "\n");
+ count = 0;
+ }
+ }
+ }
+
+ a85count = 0;
+ a85tuple = 0;
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ if (finish)
+ {
+ DBG(DBG_info, "finish\n");
+ if (a85count > 0)
+ {
+ a85count++;
+ for (j = 0; j <= a85count; j++)
+ {
+ a85block[j] = a85tuple % 85 + '!';
+ a85tuple /= 85;
+ }
+ /* Reverse order */
+ for (j--; j > 0; j--)
+ {
+ if (count == 40)
+ {
+ fprintf(outfile, "\n");
+ count = 0;
+ }
+ fprintf(outfile, "%c", a85block[j]);
+ count++;
+ }
+ }
+
+ /* ASCII85 EOD marker + newline*/
+ if (count + 2 > 40)
+ {
+ fprintf(outfile, "\n");
+ }
+ fprintf(outfile, "~>\n");
a85tuple = 0;
a85count = 0;
cbuflen = 0;
@@ -2556,7 +2741,7 @@ static int xsane_write_compressed_a85(FILE *outfile, unsigned char *line, int le
/* ---------------------------------------------------------------------------------------------------------------------- */
-static int xsane_save_ps_pdf_bw(FILE *outfile, FILE *imagefile, Image_info *image_info, GtkProgressBar *progress_bar, int *cancel_save)
+static int xsane_save_ps_pdf_bw(FILE *outfile, FILE *imagefile, Image_info *image_info, int flatdecode, GtkProgressBar *progress_bar, int *cancel_save)
{
int x, y;
int bytes_per_line = (image_info->image_width+7)/8;
@@ -2593,7 +2778,16 @@ static int xsane_save_ps_pdf_bw(FILE *outfile, FILE *imagefile, Image_info *imag
line[x] = fgetc(imagefile) ^ 255;
}
- ret = xsane_write_compressed_a85(outfile, line, bytes_per_line, (y == image_info->image_height - 1));
+#ifdef HAVE_LIBZ
+ if (flatdecode)
+ {
+ ret = xsane_write_compressed_a85_flatdecode(outfile, line, bytes_per_line, (y == image_info->image_height - 1));
+ }
+ else
+#endif
+ {
+ ret = xsane_write_compressed_a85(outfile, line, bytes_per_line, (y == image_info->image_height - 1));
+ }
if ((ret != 0) || (ferror(outfile)))
{
@@ -2628,7 +2822,7 @@ static int xsane_save_ps_pdf_bw(FILE *outfile, FILE *imagefile, Image_info *imag
/* ---------------------------------------------------------------------------------------------------------------------- */
-static int xsane_save_ps_pdf_gray(FILE *outfile, FILE *imagefile, Image_info *image_info, GtkProgressBar *progress_bar, int *cancel_save)
+static int xsane_save_ps_pdf_gray(FILE *outfile, FILE *imagefile, Image_info *image_info, int flatdecode, GtkProgressBar *progress_bar, int *cancel_save)
{
int x, y;
int ret;
@@ -2671,7 +2865,16 @@ static int xsane_save_ps_pdf_gray(FILE *outfile, FILE *imagefile, Image_info *im
}
}
- ret = xsane_write_compressed_a85(outfile, line, image_info->image_width, (y == image_info->image_height - 1));
+#ifdef HAVE_LIBZ
+ if (flatdecode)
+ {
+ ret = xsane_write_compressed_a85_flatdecode(outfile, line, image_info->image_width, (y == image_info->image_height - 1));
+ }
+ else
+#endif
+ {
+ ret = xsane_write_compressed_a85(outfile, line, image_info->image_width, (y == image_info->image_height - 1));
+ }
if ((ret != 0) || (ferror(outfile)))
{
@@ -2712,7 +2915,7 @@ static int xsane_save_ps_pdf_gray(FILE *outfile, FILE *imagefile, Image_info *im
/* ---------------------------------------------------------------------------------------------------------------------- */
-static int xsane_save_ps_pdf_color(FILE *outfile, FILE *imagefile, Image_info *image_info, GtkProgressBar *progress_bar, int *cancel_save)
+static int xsane_save_ps_pdf_color(FILE *outfile, FILE *imagefile, Image_info *image_info, int flatdecode, GtkProgressBar *progress_bar, int *cancel_save)
{
int x, y;
int ret;
@@ -2769,7 +2972,16 @@ static int xsane_save_ps_pdf_color(FILE *outfile, FILE *imagefile, Image_info *i
}
}
- ret = xsane_write_compressed_a85(outfile, line, (image_info->image_width * 3), (y == image_info->image_height - 1));
+#ifdef HAVE_LIBZ
+ if (flatdecode)
+ {
+ ret = xsane_write_compressed_a85_flatdecode(outfile, line, (image_info->image_width * 3), (y == image_info->image_height - 1));
+ }
+ else
+#endif
+ {
+ ret = xsane_write_compressed_a85(outfile, line, (image_info->image_width * 3), (y == image_info->image_height - 1));
+ }
if ((ret != 0) || (ferror(outfile)))
{
@@ -2804,40 +3016,37 @@ static int xsane_save_ps_pdf_color(FILE *outfile, FILE *imagefile, Image_info *i
/* ---------------------------------------------------------------------------------------------------------------------- */
-int xsane_save_ps(FILE *outfile, FILE *imagefile, Image_info *image_info, float width, float height,
- int paper_left_margin, int paper_bottom_margin, int paperheight, int paperwidth, int paper_orientation,
- GtkProgressBar *progress_bar, int *cancel_save)
+int xsane_save_ps_page(FILE *outfile, int page,
+ FILE *imagefile, Image_info *image_info, float width, float height,
+ int paper_left_margin, int paper_bottom_margin, int paperwidth, int paperheight, int paper_orientation,
+ int flatdecode,
+ GtkProgressBar *progress_bar, int *cancel_save)
{
- DBG(DBG_proc, "xsane_save_ps\n");
+ DBG(DBG_proc, "xsane_save_ps_page\n");
- *cancel_save = 0;
-
- xsane_save_ps_create_header(outfile, image_info, width, height,
- paper_left_margin, paper_bottom_margin, paperheight, paperwidth, paper_orientation,
- progress_bar);
+ xsane_save_ps_create_page_header(outfile, page,
+ image_info, width, height,
+ paper_left_margin, paper_bottom_margin, paperwidth, paperheight, paper_orientation,
+ flatdecode,
+ progress_bar);
if (image_info->colors == 1) /* lineart, halftone, grayscale */
{
if (image_info->depth == 1) /* lineart, halftone */
{
- xsane_save_ps_pdf_bw(outfile, imagefile, image_info, progress_bar, cancel_save);
+ xsane_save_ps_pdf_bw(outfile, imagefile, image_info, flatdecode, progress_bar, cancel_save);
}
else /* grayscale */
{
- xsane_save_ps_pdf_gray(outfile, imagefile, image_info, progress_bar, cancel_save);
+ xsane_save_ps_pdf_gray(outfile, imagefile, image_info, flatdecode, progress_bar, cancel_save);
}
}
else /* color RGB */
{
- xsane_save_ps_pdf_color(outfile, imagefile, image_info, progress_bar, cancel_save);
+ xsane_save_ps_pdf_color(outfile, imagefile, image_info, flatdecode, progress_bar, cancel_save);
}
- fprintf(outfile, "\n");
- fprintf(outfile, "showpage\n");
- fprintf(outfile, "end\n");
- fprintf(outfile, "origstate restore\n");
- fprintf(outfile, "%%%%EOF\n");
- fprintf(outfile, "\n");
+ xsane_save_ps_create_page_trailer(outfile);
if (ferror(outfile))
{
@@ -2854,31 +3063,94 @@ int xsane_save_ps(FILE *outfile, FILE *imagefile, Image_info *image_info, float
/* ---------------------------------------------------------------------------------------------------------------------- */
-/* The pdf_xref struct holds byte offsets from the beginning of the PDF
- * file to each object of the PDF file -- used to build the xref table
- */
-struct pdf_xref
+int xsane_save_ps(FILE *outfile, FILE *imagefile, Image_info *image_info, float width, float height,
+ int paper_left_margin, int paper_bottom_margin, int paperwidth, int paperheight, int paper_orientation,
+ int flatdecode,
+ GtkProgressBar *progress_bar, int *cancel_save)
{
- unsigned long obj5; /* obj 5 0 */
- unsigned long obj6; /* obj 6 0 */
- unsigned long obj7; /* obj 7 0 */
- unsigned long xref; /* xref table */
- unsigned long slen; /* length of image stream */
- unsigned long slenp; /* position of image stream length */
-};
+ DBG(DBG_proc, "xsane_save_ps\n");
+
+ *cancel_save = 0;
+
+ xsane_save_ps_create_document_header(outfile, 1 /* pages */, flatdecode);
+
+ xsane_save_ps_page(outfile, 1 /* page */,
+ imagefile, image_info, width, height,
+ paper_left_margin, paper_bottom_margin, paperwidth, paperheight, paper_orientation,
+ flatdecode,
+ progress_bar, cancel_save);
+
+ xsane_save_ps_create_document_trailer(outfile, 0 /* we defined pages at beginning */);
+
+ if (ferror(outfile))
+ {
+ char buf[255];
+
+ snprintf(buf, sizeof(buf), "%s %s", ERR_DURING_SAVE, strerror(errno));
+ DBG(DBG_error, "%s\n", buf);
+ xsane_back_gtk_decision(ERR_HEADER_ERROR, (gchar **) error_xpm, buf, BUTTON_OK, NULL, TRUE /* wait */);
+ *cancel_save = 1;
+ }
+
+ return (*cancel_save);
+}
+
+/* ---------------------------------------------------------------------------------------------------------------------- */
+
+void xsane_save_pdf_create_document_header(FILE *outfile, struct pdf_xref *xref, int pages, int flatdecode)
+{
+ int i;
+
+ DBG(DBG_proc, "xsane_save_pdf_create_document_header\n");
+
+ fprintf(outfile, "%%PDF-1.4\n");
+ fprintf(outfile, "\n");
+ xref->obj[1] = ftell(outfile);
+ fprintf(outfile, "1 0 obj\n");
+ fprintf(outfile, " << /Type /Catalog\n");
+ fprintf(outfile, " /Outlines 2 0 R\n");
+ fprintf(outfile, " /Pages 3 0 R\n");
+ fprintf(outfile, " >>\n");
+ fprintf(outfile, "endobj\n");
+ fprintf(outfile, "\n");
+ xref->obj[2] = ftell(outfile);
+ fprintf(outfile, "2 0 obj\n");
+ fprintf(outfile, " << /Type /Outlines\n");
+ fprintf(outfile, " /Count 0\n");
+ fprintf(outfile, " >>\n");
+ fprintf(outfile, "endobj\n");
+ fprintf(outfile, "\n");
+ xref->obj[3] = ftell(outfile);
+ fprintf(outfile, "3 0 obj\n");
+ fprintf(outfile, " << /Type /Pages\n");
+ fprintf(outfile, " /Kids [\n");
+ for (i=0; i < pages; i++)
+ {
+ fprintf(outfile, " %d 0 R\n", i * 2 + 4);
+ }
+ fprintf(outfile, " ]\n");
+ fprintf(outfile, " /Count %d\n", pages);
+ fprintf(outfile, " >>\n");
+ fprintf(outfile, "endobj\n");
+ fprintf(outfile, "\n");
+}
+
+/* ---------------------------------------------------------------------------------------------------------------------- */
-static void xsane_save_pdf_create_header(FILE *outfile, Image_info *image_info,
- float width, float height,
- int paper_left_margin, int paper_bottom_margin,
- int paper_width, int paper_height,
- int paper_orientation,
- GtkProgressBar *progress_bar, struct pdf_xref *xref)
+/* page = [1 .. pages] */
+static void xsane_save_pdf_create_page_header(FILE *outfile, struct pdf_xref *xref, int page,
+ Image_info *image_info,
+ float width, float height,
+ int paper_left_margin, int paper_bottom_margin,
+ int paper_width, int paper_height,
+ int paper_orientation, int flatdecode,
+ GtkProgressBar *progress_bar)
{
int position_left, position_bottom, box_left, box_bottom, box_right, box_top, depth;
int left, bottom;
float rad;
- DBG(DBG_proc, "xsane_save_pdf_create_header\n");
+ DBG(DBG_proc, "xsane_save_pdf_create_page_header\n");
switch (paper_orientation)
{
@@ -2964,42 +3236,21 @@ static void xsane_save_pdf_create_header(FILE *outfile, Image_info *image_info,
depth = 8;
}
- fprintf(outfile, "%%PDF-1.4\n");
- fprintf(outfile, "\n");
- fprintf(outfile, "1 0 obj\n");
- fprintf(outfile, " << /Type /Catalog\n");
- fprintf(outfile, " /Outlines 2 0 R\n");
- fprintf(outfile, " /Pages 3 0 R\n");
- fprintf(outfile, " >>\n");
- fprintf(outfile, "endobj\n");
- fprintf(outfile, "\n");
- fprintf(outfile, "2 0 obj\n");
- fprintf(outfile, " << /Type /Outlines\n");
- fprintf(outfile, " /Count 0\n");
- fprintf(outfile, " >>\n");
- fprintf(outfile, "endobj\n");
- fprintf(outfile, "\n");
- fprintf(outfile, "3 0 obj\n");
- fprintf(outfile, " << /Type /Pages\n");
- fprintf(outfile, " /Kids [4 0 R]\n");
- fprintf(outfile, " /Count 1\n");
- fprintf(outfile, " >>\n");
- fprintf(outfile, "endobj\n");
- fprintf(outfile, "\n");
- fprintf(outfile, "4 0 obj\n");
+ xref->obj[page * 2 + 2] = ftell(outfile);
+ fprintf(outfile, "%d 0 obj\n", page * 2 + 2);
fprintf(outfile, " << /Type /Page\n");
fprintf(outfile, " /Parent 3 0 R\n");
fprintf(outfile, " /MediaBox [%d %d %d %d]\n", box_left, box_bottom, box_right, box_top);
- fprintf(outfile, " /Contents 5 0 R\n");
- fprintf(outfile, " /Resources << /ProcSet 6 0 R >>\n");
+ fprintf(outfile, " /Contents %d 0 R\n", page * 2 + 3);
+ fprintf(outfile, " /Resources << /ProcSet %d 0 R >>\n", page * 2 + 4);
fprintf(outfile, " >>\n");
fprintf(outfile, "endobj\n");
fprintf(outfile, "\n");
/* Offset of object 5, for xref */
- xref->obj5 = ftell(outfile);
+ xref->obj[page * 2 + 3] = ftell(outfile);
- fprintf(outfile, "5 0 obj\n");
+ fprintf(outfile, "%d 0 obj\n", page * 2 + 3);
fprintf(outfile, " << /Length >>\n");
/* Position of the stream length, to be written later on */
@@ -3035,73 +3286,42 @@ static void xsane_save_pdf_create_header(FILE *outfile, Image_info *image_info,
}
#ifdef HAVE_LIBZ
+ if (flatdecode)
+ {
fprintf(outfile, " /F [/A85 /FlateDecode]\n");
-#else
+ }
+ else
+ {
fprintf(outfile, " /F /A85\n");
+ }
+#else
+ fprintf(outfile, " /F /A85\n");
#endif
- fprintf(outfile, "ID\n");
+ fprintf(outfile, "ID\n");
}
/* ---------------------------------------------------------------------------------------------------------------------- */
-int xsane_save_pdf(FILE *outfile, FILE *imagefile, Image_info *image_info, float width, float height,
- int paper_left_margin, int paper_bottom_margin, int paperheight, int paperwidth, int paper_orientation,
- GtkProgressBar *progress_bar, int *cancel_save)
+void xsane_save_pdf_create_document_trailer(FILE *outfile, struct pdf_xref *xref, int pages)
{
- struct tm *t;
- time_t tt;
- struct pdf_xref xref;
-
- DBG(DBG_proc, "xsane_save_pdf\n");
-
- *cancel_save = 0;
-
- xsane_save_pdf_create_header(outfile, image_info, width, height,
- paper_left_margin, paper_bottom_margin, paperheight, paperwidth, paper_orientation,
- progress_bar, &xref);
-
- if (image_info->colors == 1) /* lineart, halftone, grayscale */
- {
- if (image_info->depth == 1) /* lineart, halftone */
- {
- xsane_save_ps_pdf_bw(outfile, imagefile, image_info, progress_bar, cancel_save);
- }
- else /* grayscale */
- {
- xsane_save_ps_pdf_gray(outfile, imagefile, image_info, progress_bar, cancel_save);
- }
- }
- else /* color RGB */
- {
- xsane_save_ps_pdf_color(outfile, imagefile, image_info, progress_bar, cancel_save);
- }
-
- /* PDF trailer */
- fprintf(outfile, "EI\n");
- fprintf(outfile, "Q\n");
+ struct tm *t;
+ time_t tt;
+ int i;
- /* Go back and write the length of the stream */
- xref.slen = ftell(outfile) - xref.slen - 1;
- fseek(outfile, xref.slenp, SEEK_SET);
- fprintf(outfile, "%lu", xref.slen);
- fseek(outfile, 0L, SEEK_END);
-
- fprintf(outfile, "endstream\n");
- fprintf(outfile, "endobj\n");
- fprintf(outfile, "\n");
+ /* PDF document trailer */
/* Offset of object 6, for xref */
- xref.obj6 = ftell(outfile);
+ xref->obj[pages * 2 + 4] = ftell(outfile);
- fprintf(outfile, "6 0 obj\n");
+ fprintf(outfile, "%d 0 obj\n", pages * 2 + 4);
fprintf(outfile, " [/PDF]\n");
fprintf(outfile, "endobj\n");
fprintf(outfile, "\n");
/* Offset of object 7, for xref */
- xref.obj7 = ftell(outfile);
+ xref->obj[pages * 2 + 5] = ftell(outfile);
- fprintf(outfile, "7 0 obj\n");
+ fprintf(outfile, "%d 0 obj\n", pages * 2 + 5);
fprintf(outfile, " << /Title (XSane scanned image)\n");
fprintf(outfile, " /Creator (XSane version %s (sane %d.%d) - by Oliver Rauch)\n",
VERSION,
@@ -3119,27 +3339,117 @@ int xsane_save_pdf(FILE *outfile, FILE *imagefile, Image_info *image_info, float
fprintf(outfile, "\n");
/* Offset of xref, for startxref below */
- xref.xref = ftell(outfile);
+ xref->xref = ftell(outfile);
fprintf(outfile, "xref\n");
- fprintf(outfile, "0 8\n");
+ fprintf(outfile, "0 %d\n", pages * 2 + 6);
fprintf(outfile, "0000000000 65535 f \n");
- fprintf(outfile, "0000000010 00000 n \n");
- fprintf(outfile, "0000000094 00000 n \n");
- fprintf(outfile, "0000000153 00000 n \n");
- fprintf(outfile, "0000000229 00000 n \n");
- fprintf(outfile, "%010lu 00000 n \n", xref.obj5);
- fprintf(outfile, "%010lu 00000 n \n", xref.obj6);
- fprintf(outfile, "%010lu 00000 n \n", xref.obj7);
+
+ for (i=1; i <= pages * 2 + 5; i++)
+ {
+ fprintf(outfile, "%010lu 00000 n \n", xref->obj[i]);
+ }
+
fprintf(outfile, "\n");
fprintf(outfile, "trailer\n");
- fprintf(outfile, " << /Size 8\n");
+ fprintf(outfile, " << /Size %d\n", pages * 2 + 6);
fprintf(outfile, " /Root 1 0 R\n");
- fprintf(outfile, " /Info 7 0 R\n");
+ fprintf(outfile, " /Info %d 0 R\n", pages * 2 + 5);
fprintf(outfile, " >>\n");
fprintf(outfile, "startxref\n");
- fprintf(outfile, "%lu\n", xref.xref);
+ fprintf(outfile, "%lu\n", xref->xref);
fprintf(outfile, "%%%%EOF\n");
+}
+
+/* ---------------------------------------------------------------------------------------------------------------------- */
+
+static void xsane_save_pdf_create_page_trailer(FILE *outfile, struct pdf_xref *xref)
+{
+ /* PDF page trailer */
+ fprintf(outfile, "EI\n");
+ fprintf(outfile, "Q\n");
+
+ /* Go back and write the length of the stream */
+ xref->slen = ftell(outfile) - xref->slen - 1;
+ fseek(outfile, xref->slenp, SEEK_SET);
+ fprintf(outfile, "%lu", xref->slen);
+ fseek(outfile, 0L, SEEK_END);
+
+ fprintf(outfile, "endstream\n");
+ fprintf(outfile, "endobj\n");
+ fprintf(outfile, "\n");
+}
+
+/* ---------------------------------------------------------------------------------------------------------------------- */
+
+int xsane_save_pdf_page(FILE *outfile, struct pdf_xref *xref, int page,
+ FILE *imagefile, Image_info *image_info, float width, float height,
+ int paper_left_margin, int paper_bottom_margin, int paperwidth, int paperheight, int paper_orientation,
+ int flatdecode,
+ GtkProgressBar *progress_bar, int *cancel_save)
+{
+
+ DBG(DBG_proc, "xsane_save_pdf_page\n");
+
+ xsane_save_pdf_create_page_header(outfile, xref, page,
+ image_info, width, height,
+ paper_left_margin, paper_bottom_margin, paperwidth, paperheight, paper_orientation,
+ flatdecode,
+ progress_bar);
+
+ if (image_info->colors == 1) /* lineart, halftone, grayscale */
+ {
+ if (image_info->depth == 1) /* lineart, halftone */
+ {
+ xsane_save_ps_pdf_bw(outfile, imagefile, image_info, flatdecode, progress_bar, cancel_save);
+ }
+ else /* grayscale */
+ {
+ xsane_save_ps_pdf_gray(outfile, imagefile, image_info, flatdecode, progress_bar, cancel_save);
+ }
+ }
+ else /* color RGB */
+ {
+ xsane_save_ps_pdf_color(outfile, imagefile, image_info, flatdecode, progress_bar, cancel_save);
+ }
+
+ xsane_save_pdf_create_page_trailer(outfile, xref);
+
+ if (ferror(outfile))
+ {
+ char buf[255];
+
+ snprintf(buf, sizeof(buf), "%s %s", ERR_DURING_SAVE, strerror(errno));
+ DBG(DBG_error, "%s\n", buf);
+ xsane_back_gtk_decision(ERR_HEADER_ERROR, (gchar **) error_xpm, buf, BUTTON_OK, NULL, TRUE /* wait */);
+ *cancel_save = 1;
+ }
+
+ return (*cancel_save);
+}
+
+/* ---------------------------------------------------------------------------------------------------------------------- */
+
+int xsane_save_pdf(FILE *outfile, FILE *imagefile, Image_info *image_info, float width, float height,
+ int paper_left_margin, int paper_bottom_margin, int paperwidth, int paperheight, int paper_orientation,
+ int flatdecode,
+ GtkProgressBar *progress_bar, int *cancel_save)
+{
+ struct pdf_xref xref;
+
+ DBG(DBG_proc, "xsane_save_pdf\n");
+
+ *cancel_save = 0;
+
+ xsane_save_pdf_create_document_header(outfile, &xref, 1, flatdecode);
+
+ xsane_save_pdf_page(outfile, &xref, 1,
+ imagefile, image_info, width, height,
+ paper_left_margin, paper_bottom_margin, paperwidth, paperheight, paper_orientation,
+ flatdecode,
+ progress_bar, cancel_save);
+
+ xsane_save_pdf_create_document_trailer(outfile, &xref, 1);
if (ferror(outfile))
{
@@ -3243,6 +3553,11 @@ int xsane_save_jpeg(FILE *outfile, FILE *imagefile, Image_info *image_info, int
cinfo.X_density = image_info->resolution_x;
cinfo.Y_density = image_info->resolution_y;
+#if 0
+ cinfo.smoothing_factor = 0.0; /* 0 .. 100 */
+ cinfo.dct_method = JDCT_FLOAT; /* JDCT_ISLOW, JDCT_IFAST, JDCT_FLOAT */
+#endif
+
jpeg_start_compress(&cinfo, TRUE);
for (y = 0; y < image_info->image_height; y++)
@@ -3313,9 +3628,11 @@ int xsane_save_jpeg(FILE *outfile, FILE *imagefile, Image_info *image_info, int
/* ---------------------------------------------------------------------------------------------------------------------- */
#ifdef HAVE_LIBTIFF
-int xsane_save_tiff(const char *outfilename, FILE *imagefile, Image_info *image_info, int quality, GtkProgressBar *progress_bar, int *cancel_save)
+/* pages = 0 => single page tiff, page = 0 */
+/* pages > 0 => page = [1 .. pages] */
+int xsane_save_tiff_page(TIFF *tiffile, int page, int pages, FILE *imagefile, Image_info *image_info, int quality,
+ GtkProgressBar *progress_bar, int *cancel_save)
{
- TIFF *tiffile;
char *data;
char buf[256];
int y, w;
@@ -3325,7 +3642,7 @@ int xsane_save_tiff(const char *outfilename, FILE *imagefile, Image_info *image_
struct tm *ptm;
time_t now;
- DBG(DBG_proc, "xsane_save_tiff\n");
+ DBG(DBG_proc, "xsane_save_tiff_page(%d/%d\n", page, pages);
*cancel_save = 0;
@@ -3361,26 +3678,7 @@ int xsane_save_tiff(const char *outfilename, FILE *imagefile, Image_info *image_
bytes = 2;
}
- if (xsane_create_secure_file(outfilename)) /* remove possibly existing symbolic links for security */
- {
- snprintf(buf, sizeof(buf), "%s %s %s\n", ERR_DURING_SAVE, ERR_CREATE_SECURE_FILE, outfilename);
- xsane_back_gtk_error(buf, TRUE);
- return -1; /* error */
- }
-
- tiffile = TIFFOpen(outfilename, "w");
- if (!tiffile)
- {
- snprintf(buf, sizeof(buf), "%s %s %s\n", ERR_DURING_SAVE, ERR_OPEN_FAILED, outfilename);
- xsane_back_gtk_error(buf, TRUE);
- return -1; /* error */
- }
-
-#if 0
- data = malloc(pixel_width * components * bytes);
-#else
data = (char *)_TIFFmalloc(image_info->image_width * components * bytes);
-#endif
if (!data)
{
@@ -3391,11 +3689,11 @@ int xsane_save_tiff(const char *outfilename, FILE *imagefile, Image_info *image_
TIFFSetField(tiffile, TIFFTAG_IMAGEWIDTH, image_info->image_width);
TIFFSetField(tiffile, TIFFTAG_IMAGELENGTH, image_info->image_height);
- TIFFSetField(tiffile, TIFFTAG_ORIENTATION, ORIENTATION_TOPLEFT);
TIFFSetField(tiffile, TIFFTAG_BITSPERSAMPLE, image_info->depth);
+ TIFFSetField(tiffile, TIFFTAG_SAMPLESPERPIXEL, components);
+ TIFFSetField(tiffile, TIFFTAG_ORIENTATION, ORIENTATION_TOPLEFT);
TIFFSetField(tiffile, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG);
TIFFSetField(tiffile, TIFFTAG_COMPRESSION, compression);
- TIFFSetField(tiffile, TIFFTAG_SAMPLESPERPIXEL, components);
TIFFSetField(tiffile, TIFFTAG_SOFTWARE, "xsane");
time(&now);
@@ -3403,19 +3701,33 @@ int xsane_save_tiff(const char *outfilename, FILE *imagefile, Image_info *image_
sprintf(buf, "%04d:%02d:%02d %02d:%02d:%02d", 1900+ptm->tm_year, ptm->tm_mon+1, ptm->tm_mday, ptm->tm_hour, ptm->tm_min, ptm->tm_sec);
TIFFSetField(tiffile, TIFFTAG_DATETIME, buf);
- TIFFSetField(tiffile, TIFFTAG_RESOLUTIONUNIT, RESUNIT_INCH);
- TIFFSetField(tiffile, TIFFTAG_XRESOLUTION, image_info->resolution_x);
- TIFFSetField(tiffile, TIFFTAG_YRESOLUTION, image_info->resolution_y);
+ if (image_info->resolution_x > 0.0)
+ {
+ TIFFSetField(tiffile, TIFFTAG_RESOLUTIONUNIT, RESUNIT_INCH);
+ TIFFSetField(tiffile, TIFFTAG_XRESOLUTION, image_info->resolution_x);
+ TIFFSetField(tiffile, TIFFTAG_YRESOLUTION, image_info->resolution_y);
+ }
- if (compression == COMPRESSION_JPEG)
+ if (compression == COMPRESSION_DEFLATE)
+ {
+ TIFFSetField(tiffile, TIFFTAG_ZIPQUALITY, (int) preferences.tiff_zip_compression);
+ }
+ else if (compression == COMPRESSION_JPEG)
{
TIFFSetField(tiffile, TIFFTAG_JPEGQUALITY, quality);
- TIFFSetField(tiffile, TIFFTAG_JPEGCOLORMODE, JPEGCOLORMODE_RAW); /* should be default, but to be sure */
}
if (image_info->colors == 3)
{
- TIFFSetField(tiffile, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_RGB);
+ if (compression == COMPRESSION_JPEG)
+ {
+ TIFFSetField(tiffile, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_YCBCR);
+ TIFFSetField(tiffile, TIFFTAG_JPEGCOLORMODE, JPEGCOLORMODE_RGB); /* convert from RGB (to YCBCR) */
+ }
+ else /* no jpeg compression */
+ {
+ TIFFSetField(tiffile, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_RGB);
+ }
}
else
{
@@ -3425,12 +3737,19 @@ int xsane_save_tiff(const char *outfilename, FILE *imagefile, Image_info *image_
}
else /* grayscale */
{
- TIFFSetField(tiffile, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_MINISBLACK);
+ TIFFSetField(tiffile, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_MINISBLACK);
+ /* we have to do nothing special for jpeg! */
}
}
TIFFSetField(tiffile, TIFFTAG_ROWSPERSTRIP, TIFFDefaultStripSize(tiffile, -1));
+ if (pages)
+ {
+ TIFFSetField(tiffile, TIFFTAG_SUBFILETYPE, FILETYPE_PAGE);
+ TIFFSetField(tiffile, TIFFTAG_PAGENUMBER, page, pages);
+ }
+
w = TIFFScanlineSize(tiffile);
for (y = 0; y < image_info->image_height; y++)
@@ -3460,12 +3779,12 @@ int xsane_save_tiff(const char *outfilename, FILE *imagefile, Image_info *image_
}
}
- TIFFClose(tiffile);
-#if 0
- free(data);
-#else
+ if (pages)
+ {
+ TIFFWriteDirectory(tiffile);
+ }
+
_TIFFfree(data);
-#endif
return (*cancel_save);
}
#endif
@@ -4278,7 +4597,26 @@ int xsane_save_image_as(char *output_filename, char *input_filename, int output_
#ifdef HAVE_LIBTIFF
if (output_format == XSANE_TIFF) /* routines that want to have filename for saving */
{
- xsane_save_tiff(output_filename, infile, &image_info, preferences.jpeg_quality, progress_bar, cancel_save);
+ TIFF *tiffile;
+
+ if (xsane_create_secure_file(output_filename)) /* remove possibly existing symbolic links for security */
+ {
+ snprintf(buf, sizeof(buf), "%s %s %s\n", ERR_DURING_SAVE, ERR_CREATE_SECURE_FILE, output_filename);
+ xsane_back_gtk_error(buf, TRUE);
+ return -1; /* error */
+ }
+
+ tiffile = TIFFOpen(output_filename, "w");
+ if (!tiffile)
+ {
+ snprintf(buf, sizeof(buf), "%s %s %s\n", ERR_DURING_SAVE, ERR_OPEN_FAILED, output_filename);
+ xsane_back_gtk_error(buf, TRUE);
+ return -1; /* error */
+ }
+
+ xsane_save_tiff_page(tiffile, 0, 0, infile, &image_info, preferences.jpeg_quality, progress_bar, cancel_save);
+
+ TIFFClose(tiffile);
}
else /* routines that want to have filedescriptor for saving */
#endif /* HAVE_LIBTIFF */
@@ -4347,6 +4685,7 @@ int xsane_save_image_as(char *output_filename, char *input_filename, int output_
(int) imagewidth, /* paper_width */
(int) imageheight, /* paper_height */
0 /* portrait top left */,
+ preferences.save_ps_flatdecoded,
progress_bar,
cancel_save);
}
@@ -4367,6 +4706,7 @@ int xsane_save_image_as(char *output_filename, char *input_filename, int output_
(int) imagewidth, /* paper_width */
(int) imageheight, /* paper_height */
0 /* portrait top left */,
+ preferences.save_pdf_flatdecoded,
progress_bar,
cancel_save);
}
@@ -5039,7 +5379,7 @@ int xsane_transfer_to_gimp(char *input_filename, GtkProgressBar *progress_bar, i
/* ---------------------------------------------------------------------------------------------------------------------- */
/* ---------------------------------------------------------------------------------------------------------------------- */
-#ifdef XSANE_ACTIVATE_MAIL
+#ifdef XSANE_ACTIVATE_EMAIL
/* character base of base64 coding */
static const char base64[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
@@ -5074,6 +5414,41 @@ static void write_3chars_as_base64(unsigned char c1, unsigned char c2, unsigned
/* ---------------------------------------------------------------------------------------------------------------------- */
+void write_string_base64(int fd_socket, unsigned char *string, int len)
+{
+ int i;
+ int pad;
+ unsigned char c1, c2, c3;
+
+ for (i = 0; i < len; i+=3)
+ {
+ c1 = string[i];
+ c2 = string[i+1];
+ c3 = string[i+2];
+
+ pad = i - len + 3;
+
+ if (pad < 0)
+ {
+ pad = 0;
+ }
+ else if (pad)
+ {
+ c3 = 0;
+
+ if (pad == 2)
+ {
+ c2 = 0;
+ }
+ }
+
+ write_3chars_as_base64(c1, c2, c3, pad, fd_socket);
+ }
+ write(fd_socket, "\r\n", 2);
+}
+
+/* ---------------------------------------------------------------------------------------------------------------------- */
+
void write_base64(int fd_socket, FILE *infile)
{
int c1, c2, c3;
@@ -5107,11 +5482,11 @@ void write_base64(int fd_socket, FILE *infile)
pos = 0;
}
- xsane.mail_progress_bytes += 3;
- if ((int) ((xsane.mail_progress_bytes * 100) / xsane.mail_progress_size) != (int) (xsane.mail_progress_val * 100))
+ xsane.email_progress_bytes += 3;
+ if ((int) ((xsane.email_progress_bytes * 100) / xsane.email_progress_size) != (int) (xsane.email_progress_val * 100))
{
- xsane.mail_progress_val = (float) xsane.mail_progress_bytes / xsane.mail_progress_size;
- xsane_front_gtk_mail_project_update_lockfile_status();
+ xsane.email_progress_val = (float) xsane.email_progress_bytes / xsane.email_progress_size;
+ xsane_front_gtk_email_project_update_lockfile_status();
}
}
@@ -5120,13 +5495,13 @@ void write_base64(int fd_socket, FILE *infile)
write(fd_socket, "\n", 1);
}
- xsane.mail_progress_val = 1.0;
- xsane_front_gtk_mail_project_update_lockfile_status();
+ xsane.email_progress_val = 1.0;
+ xsane_front_gtk_email_project_update_lockfile_status();
}
/* ---------------------------------------------------------------------------------------------------------------------- */
-void write_mail_header(int fd_socket, char *from, char *reply_to, char *to, char *subject, char *boundary, int related)
+void write_email_header(int fd_socket, char *from, char *reply_to, char *to, char *subject, char *boundary, int related)
{
char buf[1024];
@@ -5162,7 +5537,7 @@ void write_mail_header(int fd_socket, char *from, char *reply_to, char *to, char
/* ---------------------------------------------------------------------------------------------------------------------- */
-void write_mail_footer(int fd_socket, char *boundary)
+void write_email_footer(int fd_socket, char *boundary)
{
char buf[1024];
@@ -5172,7 +5547,7 @@ void write_mail_footer(int fd_socket, char *boundary)
/* ---------------------------------------------------------------------------------------------------------------------- */
-void write_mail_mime_ascii(int fd_socket, char *boundary)
+void write_email_mime_ascii(int fd_socket, char *boundary)
{
char buf[1024];
@@ -5191,7 +5566,7 @@ void write_mail_mime_ascii(int fd_socket, char *boundary)
/* ---------------------------------------------------------------------------------------------------------------------- */
-void write_mail_mime_html(int fd_socket, char *boundary)
+void write_email_mime_html(int fd_socket, char *boundary)
{
char buf[1024];
@@ -5216,7 +5591,7 @@ void write_mail_mime_html(int fd_socket, char *boundary)
/* ---------------------------------------------------------------------------------------------------------------------- */
-void write_mail_attach_image(int fd_socket, char *boundary, char *content_id, char *content_type, FILE *infile, char *filename)
+void write_email_attach_image(int fd_socket, char *boundary, char *content_id, char *content_type, FILE *infile, char *filename)
{
char buf[1024];
@@ -5249,7 +5624,7 @@ void write_mail_attach_image(int fd_socket, char *boundary, char *content_id, ch
/* ---------------------------------------------------------------------------------------------------------------------- */
-void write_mail_attach_file(int fd_socket, char *boundary, FILE *infile, char *filename)
+void write_email_attach_file(int fd_socket, char *boundary, FILE *infile, char *filename)
{
char buf[1024];
@@ -5392,9 +5767,103 @@ int pop3_login(int fd_socket, char *user, char *passwd)
/* ---------------------------------------------------------------------------------------------------------------------- */
+int asmtp_authentication(int fd_socket, int auth_type, char *user, char *passwd)
+{
+ int len;
+ char buf[1024];
+
+ DBG(DBG_proc, "asmtp_authentication\n");
+
+ switch (auth_type)
+ {
+ case EMAIL_AUTH_ASMTP_PLAIN:
+ snprintf(buf, sizeof(buf), "AUTH PLAIN ");
+ DBG(DBG_info2, "> %s\\0(USER)\\0(PASSWORD)\n", buf);
+ write(fd_socket, buf, strlen(buf));
+ snprintf(buf, sizeof(buf), "%c%s%c%s", 0, user, 0, passwd);
+ write_string_base64(fd_socket, buf, strlen(user)+strlen(passwd)+2);
+ len = read(fd_socket, buf, sizeof(buf));
+ if (len >= 0)
+ {
+ buf[len] = 0;
+ }
+ DBG(DBG_info2, "< %s", buf);
+ break;
+
+ case EMAIL_AUTH_ASMTP_LOGIN:
+ snprintf(buf, sizeof(buf), "AUTH LOGIN\r\n");
+ DBG(DBG_info2, "> %s", buf);
+ write(fd_socket, buf, strlen(buf));
+ len = read(fd_socket, buf, sizeof(buf));
+ if (len >= 0)
+ {
+ buf[len] = 0;
+ }
+ DBG(DBG_info2, "< %s", buf);
+ if (buf[0] != '3')
+ {
+ DBG(DBG_info, "=> error\n");
+ return (-1);
+ }
+
+ DBG(DBG_info2, "> (USERNAME)\n");
+ write_string_base64(fd_socket, user, strlen(user));
+
+ len = read(fd_socket, buf, sizeof(buf));
+ if (len >= 0)
+ {
+ buf[len] = 0;
+ }
+ DBG(DBG_info2, "< %s", buf);
+ if (buf[0] != '3')
+ {
+ DBG(DBG_info, "=> error\n");
+ return (-1);
+ }
+
+ DBG(DBG_info2, "> (PASSWORD)\n");
+ write_string_base64(fd_socket, passwd, strlen(passwd));
+
+ len = read(fd_socket, buf, sizeof(buf));
+ if (len >= 0)
+ {
+ buf[len] = 0;
+ }
+ DBG(DBG_info2, "< %s", buf);
+ if (buf[0] != '2')
+ {
+ DBG(DBG_info, "=> error\n");
+ return (-1);
+ }
+ break;
+
+#if 0
+ case EMAIL_AUTH_ASMTP_CRAM_MD5:
+ snprintf(buf, sizeof(buf), "AUTH CRAM-MD5\r\n");
+ DBG(DBG_info2, "> %s", buf);
+ write(fd_socket, buf, strlen(buf));
+ len = read(fd_socket, buf, sizeof(buf));
+ if (len >= 0)
+ {
+ buf[len] = 0;
+ }
+ DBG(DBG_info2, "< %s", buf);
+ break;
+#endif
+
+ default:
+ DBG(DBG_proc, "no valid asmtp authentication type\n");
+ break;
+ }
+
+ return 0;
+}
+
+/* ---------------------------------------------------------------------------------------------------------------------- */
+
/* not only a write routine, also reads data */
/* returns -1 on error, 0 when ok */
-int write_smtp_header(int fd_socket, char *from, char *to)
+int write_smtp_header(int fd_socket, char *from, char *to, int auth_type, char *user, char *passwd)
{
char buf[1024];
int len;
@@ -5406,7 +5875,14 @@ int write_smtp_header(int fd_socket, char *from, char *to)
}
DBG(DBG_info2, "< %s\n", buf);
- snprintf(buf, sizeof(buf), "helo localhost\r\n");
+ if (auth_type < EMAIL_AUTH_ASMTP_PLAIN)
+ {
+ snprintf(buf, sizeof(buf), "HELO localhost\r\n");
+ }
+ else
+ {
+ snprintf(buf, sizeof(buf), "EHLO localhost\r\n");
+ }
DBG(DBG_info2, "> %s", buf);
write(fd_socket, buf, strlen(buf));
len = read(fd_socket, buf, sizeof(buf));
@@ -5420,12 +5896,19 @@ int write_smtp_header(int fd_socket, char *from, char *to)
{
DBG(DBG_info, "=> error\n");
- if (xsane.mail_status)
+ if (xsane.email_status)
{
- free(xsane.mail_status);
+ free(xsane.email_status);
}
- xsane.mail_status = strdup(TEXT_MAIL_STATUS_SMTP_CONNECTION_FAILED);
- xsane_front_gtk_mail_project_update_lockfile_status();
+ xsane.email_status = strdup(TEXT_EMAIL_STATUS_SMTP_CONNECTION_FAILED);
+ xsane_front_gtk_email_project_update_lockfile_status();
+ return -1;
+ }
+
+ if (asmtp_authentication(fd_socket, auth_type, user, passwd))
+ {
+ xsane.email_status = strdup(TEXT_EMAIL_STATUS_ASMTP_AUTH_FAILED);
+ xsane_front_gtk_email_project_update_lockfile_status();
return -1;
}
@@ -5443,12 +5926,12 @@ int write_smtp_header(int fd_socket, char *from, char *to)
{
DBG(DBG_info, "=> error\n");
- if (xsane.mail_status)
+ if (xsane.email_status)
{
- free(xsane.mail_status);
+ free(xsane.email_status);
}
- xsane.mail_status = strdup(TEXT_MAIL_STATUS_SMTP_ERR_FROM);
- xsane_front_gtk_mail_project_update_lockfile_status();
+ xsane.email_status = strdup(TEXT_EMAIL_STATUS_SMTP_ERR_FROM);
+ xsane_front_gtk_email_project_update_lockfile_status();
return -1;
}
@@ -5467,12 +5950,12 @@ int write_smtp_header(int fd_socket, char *from, char *to)
{
DBG(DBG_info, "=> error\n");
- if (xsane.mail_status)
+ if (xsane.email_status)
{
- free(xsane.mail_status);
+ free(xsane.email_status);
}
- xsane.mail_status = strdup(TEXT_MAIL_STATUS_SMTP_ERR_RCPT);
- xsane_front_gtk_mail_project_update_lockfile_status();
+ xsane.email_status = strdup(TEXT_EMAIL_STATUS_SMTP_ERR_RCPT);
+ xsane_front_gtk_email_project_update_lockfile_status();
return -1;
}
@@ -5490,12 +5973,12 @@ int write_smtp_header(int fd_socket, char *from, char *to)
{
DBG(DBG_info, "=> error\n");
- if (xsane.mail_status)
+ if (xsane.email_status)
{
- free(xsane.mail_status);
+ free(xsane.email_status);
}
- xsane.mail_status = strdup(TEXT_MAIL_STATUS_SMTP_ERR_DATA);
- xsane_front_gtk_mail_project_update_lockfile_status();
+ xsane.email_status = strdup(TEXT_EMAIL_STATUS_SMTP_ERR_DATA);
+ xsane_front_gtk_email_project_update_lockfile_status();
return -1;
}
@@ -5534,4 +6017,5 @@ int write_smtp_footer(int fd_socket)
}
#endif
+
/* ---------------------------------------------------------------------------------------------------------------------- */
diff --git a/src/xsane-save.c.orig b/src/xsane-save.c.orig
new file mode 100644
index 0000000..a495e1c
--- /dev/null
+++ b/src/xsane-save.c.orig
@@ -0,0 +1,5801 @@
+/* xsane -- a graphical (X11, gtk) scanner-oriented SANE frontend
+
+ xsane-save.c
+
+ Oliver Rauch <Oliver.Rauch@rauch-domain.de>
+ Copyright (C) 1998-2005 Oliver Rauch
+ This file is part of the XSANE package.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+/* ---------------------------------------------------------------------------------------------------------------------- */
+
+#include "xsane.h"
+#include "xsane-back-gtk.h"
+#include "xsane-front-gtk.h"
+#include <time.h>
+#include <sys/wait.h>
+
+/* the following test is always false */
+#ifdef _native_WIN32
+# include <winsock.h>
+#else
+# include <sys/socket.h>
+# include <netinet/in.h>
+# include <netdb.h>
+#endif
+
+#ifdef HAVE_LIBJPEG
+#include <jpeglib.h>
+#endif
+
+#ifdef HAVE_LIBZ
+#include <zlib.h>
+#endif
+
+#ifdef HAVE_LIBPNG
+#include <png.h>
+#endif
+
+#ifdef HAVE_LIBTIFF
+#include <tiffio.h>
+#endif
+
+#ifdef HAVE_MMAP
+#include <sys/mman.h>
+#endif
+
+#ifdef HAVE_OS2_H
+#include <process.h>
+#endif
+
+/* ---------------------------------------------------------------------------------------------------------------------- */
+
+#ifdef HAVE_ANY_GIMP
+
+#include <libgimp/gimp.h>
+
+static void xsane_gimp_query(void);
+#ifdef HAVE_GIMP_2
+static void xsane_gimp_run(const gchar *name, gint nparams, const GimpParam *param, gint *nreturn_vals, GimpParam **return_vals);
+#else
+static void xsane_gimp_run(char *name, int nparams, GimpParam *param, int *nreturn_vals, GimpParam **return_vals);
+#endif
+
+GimpPlugInInfo PLUG_IN_INFO =
+{
+ NULL, /* init_proc */
+ NULL, /* quit_proc */
+ xsane_gimp_query, /* query_proc */
+ xsane_gimp_run, /* run_proc */
+};
+
+
+static int xsane_decode_devname(const char *encoded_devname, int n,
+char *buf);
+static int xsane_encode_devname(const char *devname, int n, char *buf);
+void null_print_func(gchar *msg);
+
+#endif /* HAVE_ANY_GIMP */
+
+/* ---------------------------------------------------------------------------------------------------------------------- */
+/* why this routine ?
+ Problem: link attack
+ Bad user wants to overwrite a file (mywork.txt) of good user.
+ File permissions of mywork.txt is 700 so that bad user can not
+ change or overwrite the file. Directory permissions allow bad user
+ to write into directory. Bad user sets symlink from a file that good
+ user will write soon (image.pnm) to mywork.txt.
+ ==> Good user overwrites his own file, he is allowed to do so.
+
+ Solution: remove file.
+ Create outputfile and make sure that it does not exist while creation.
+
+ The file is created with the requested image-file permissions.
+
+ Note: This case is a bit curious because it is only a small part of a larger problem:
+ When other users have write access to the directory they simply can move
+ mywork.txt to image.pnm. If they do it in the right moment the file is
+ overwritten without any notice of good user. If they do it long before xsane
+ wants to write image.pnm then xsane will possibly ask if image.pnm shall be
+ overwritten. So the real solution is to make the direcoty permissions safe!!!
+ But some users asked for this and so I added this.
+
+
+ This routine shall not be called for temporary files because temp files shall not
+ be removed after they have been created safe. (Although a temporary file should
+ not be a symlink so there should be no problem with this)
+*/
+
+int xsane_create_secure_file(const char *filename)
+/* returns 0 on success, -1 on error */
+{
+ int fd;
+
+ DBG(DBG_proc, "xsane_create_secure_file\n");
+
+ remove(filename); /* we need to remove the file because open(..., O_EXCL) will fail otherwise */
+ umask((mode_t) preferences.image_umask); /* define image file permissions */
+ fd = open(filename, O_WRONLY | O_CREAT | O_EXCL, 0666);
+ umask(XSANE_DEFAULT_UMASK); /* define new file permissions */
+
+ if (fd > 0)
+ {
+ DBG(DBG_info, "file %s is created and secure\n", filename);
+ close(fd);
+ fd = 0;
+ }
+ else
+ {
+ DBG(DBG_info, "could not create secure file %s\n", filename);
+ }
+
+ return fd; /* -1 means file is not safe !!! otherwise 0 */
+}
+
+/* ---------------------------------------------------------------------------------------------------------------------- */
+
+void xsane_cancel_save(int *cancel_save)
+{
+ DBG(DBG_proc, "xsane_cancel_save\n");
+ *cancel_save = 1;
+}
+
+/* ---------------------------------------------------------------------------------------------------------------------- */
+
+void xsane_convert_text_to_filename(char **text)
+{
+ DBG(DBG_proc, "xsane_convert_text_to_filename\n");
+
+ if (text)
+ {
+ char *filename = *text;
+ char buf[256];
+ int buflen=0;
+ int txtlen=0;
+
+ while((filename[txtlen] != 0) && (buflen<253))
+ {
+ switch (filename[txtlen])
+ {
+ case ' ':
+ buf[buflen++] = ':';
+ buf[buflen++] = '_';
+ txtlen++;
+ break;
+
+ case '/':
+ buf[buflen++] = ':';
+ buf[buflen++] = '%';
+ txtlen++;
+ break;
+
+ case '*':
+ buf[buflen++] = ':';
+ buf[buflen++] = '#';
+ txtlen++;
+ break;
+
+ case '?':
+ buf[buflen++] = ':';
+ buf[buflen++] = 'q';
+ txtlen++;
+ break;
+
+ case '\\':
+ buf[buflen++] = ':';
+ buf[buflen++] = '=';
+ txtlen++;
+ break;
+
+ case ';':
+ buf[buflen++] = ':';
+ buf[buflen++] = '!';
+ txtlen++;
+ break;
+
+ case '&':
+ buf[buflen++] = ':';
+ buf[buflen++] = '+';
+ txtlen++;
+ break;
+
+ case '<':
+ buf[buflen++] = ':';
+ buf[buflen++] = 's';
+ txtlen++;
+ break;
+
+ case '>':
+ buf[buflen++] = ':';
+ buf[buflen++] = 'g';
+ txtlen++;
+ break;
+
+ case '|':
+ buf[buflen++] = ':';
+ buf[buflen++] = 'p';
+ txtlen++;
+ break;
+
+ case ':':
+ buf[buflen++] = ':';
+ buf[buflen++] = ':';
+ txtlen++;
+ break;
+
+ default:
+ buf[buflen++] = filename[txtlen++];
+ break;
+ }
+ }
+ buf[buflen] = 0;
+ free(filename);
+ *text = strdup(buf);
+ DBG(DBG_info, "filename = \"%s\"\n", *text);
+ }
+}
+
+/* ---------------------------------------------------------------------------------------------------------------------- */
+
+int xsane_get_filesize(char *filename)
+{
+ FILE *infile;
+ int pos;
+ int size;
+
+ infile = fopen(filename, "rb"); /* read binary (b for win32) */
+ if (infile == NULL)
+ {
+ return 0;
+ }
+
+ pos = ftell(infile);
+ fseek(infile, 0, SEEK_END); /* get size */
+ size = ftell(infile);
+ fseek(infile, pos, SEEK_SET); /* go to previous position */
+
+ fclose(infile);
+
+ return size;
+}
+
+/* ---------------------------------------------------------------------------------------------------------------------- */
+
+void xsane_ensure_counter_in_filename(char **filename, int counter_len)
+{
+ char *position_point = NULL;
+ char *position;
+ int counter = 1;
+
+ DBG(DBG_proc, "xsane_ensure_counter_in_filename\n");
+
+ if (!counter_len)
+ {
+ counter_len = 1;
+ }
+
+ position_point = strrchr(*filename, '.');
+
+ if (!position_point) /* nothing usable ? */
+ {
+ position_point = *filename + strlen(*filename); /* position_point - 1 is last character */
+ }
+
+ if (position_point)
+ {
+ position = position_point-1;
+ if ( (position < *filename) || (*position < '0') || (*position >'9') ) /* we have no counter */
+ {
+ char buf[PATH_MAX];
+ int len;
+
+ len = position_point - (*filename); /* length until "." or end of string */
+ strncpy(buf, *filename, len);
+ snprintf(buf+len, sizeof(buf)-len, "-%0*d%s", counter_len, counter, position_point);
+ *filename = strdup(buf);
+ }
+ }
+}
+
+/* ---------------------------------------------------------------------------------------------------------------------- */
+
+void xsane_update_counter_in_filename(char **filename, int skip, int step, int min_counter_len)
+{
+ FILE *testfile;
+ char *position_point = NULL;
+ char *position_counter;
+ char buf[PATH_MAX];
+ int counter;
+ int counter_len;
+ int set_counter_len = min_counter_len;
+
+ DBG(DBG_proc, "xsane_update_counter_in_filename\n");
+
+ if ( (!step) && (!min_counter_len) )
+ {
+ return; /* do not touch counter */
+ }
+
+ while (1) /* loop because we may have to skip existing files */
+ {
+ position_point = strrchr(*filename, '.');
+
+ if (!position_point) /* nothing usable ? */
+ {
+ position_point = *filename + strlen(*filename); /* here is no point, but position - 1 is last character */
+ }
+
+ if (position_point)
+ {
+ position_counter = position_point-1; /* go to last number of counter (if counter exists) */
+
+ /* search non numeric char */
+ while ( (position_counter >= *filename) && (*position_counter >= '0') && (*position_counter <='9') )
+ {
+ position_counter--; /* search fisrt numeric character */
+ }
+
+ position_counter++; /* go to first numeric charcter */
+
+ counter_len = position_point - position_counter;
+
+ if (counter_len) /* we have a counter */
+ {
+ sscanf(position_counter, "%d", &counter);
+ counter = counter + step; /* update counter */
+
+ if (counter < 0)
+ {
+ counter = 0;
+ xsane_back_gtk_warning(WARN_COUNTER_UNDERRUN, TRUE);
+ break; /* last available number ("..999") */
+ }
+
+ *position_counter = 0; /* set end of string mark to counter start */
+
+ if (set_counter_len == 0)
+ {
+ set_counter_len = counter_len;
+ }
+
+ snprintf(buf, sizeof(buf), "%s%0*d%s", *filename, set_counter_len, counter, position_point);
+
+ DBG(DBG_info, "filename = \"%s\"\n", buf);
+
+ free(*filename);
+ *filename = strdup(buf);
+
+ if (skip) /* test if filename already used */
+ {
+ if (preferences.filetype) /* add filetype to filename */
+ {
+ snprintf(buf, sizeof(buf), "%s%s", *filename, preferences.filetype);
+ testfile = fopen(buf, "rb"); /* read binary (b for win32) */
+ }
+ else /* filetype in filename */
+ {
+ testfile = fopen(*filename, "rb"); /* read binary (b for win32) */
+ }
+
+ if (testfile) /* filename used: skip */
+ {
+ fclose(testfile);
+ }
+ else
+ {
+ break; /* filename not used, ok */
+ }
+ }
+ else /* do not test if filename already used */
+ {
+ break; /* filename ok */
+ }
+ }
+ else /* no counter */
+ {
+ break; /* no counter */
+ }
+ }
+ }
+}
+
+/* ---------------------------------------------------------------------------------------------------------------------- */
+
+void xsane_read_pnm_header(FILE *file, Image_info *image_info)
+{
+ int max_val, filetype_nr;
+ char buf[256];
+
+ fgets(buf, sizeof(buf)-1, file);
+ DBG(DBG_info, "filetype header :%s", buf);
+
+ if (buf[0] == 'P')
+ {
+ filetype_nr = atoi(buf+1); /* get filetype number */
+
+ image_info->resolution_x = 72.0;
+ image_info->resolution_y = 72.0;
+ image_info->reduce_to_lineart = FALSE;
+
+ while (strcmp(buf, "# XSANE data follows\n"))
+ {
+ fgets(buf, sizeof(buf)-1, file);
+
+ if (!strncmp(buf, "# resolution_x =", 20))
+ {
+ sscanf(buf+20, "%lf", &image_info->resolution_x);
+ }
+ else if (!strncmp(buf, "# resolution_y =", 20))
+ {
+ sscanf(buf+20, "%lf", &image_info->resolution_y);
+ }
+ else if (!strncmp(buf, "# threshold =", 20))
+ {
+ sscanf(buf+20, "%lf", &image_info->threshold);
+ }
+ else if (!strncmp(buf, "# gamma =", 20))
+ {
+ sscanf(buf+20, "%lf", &image_info->gamma);
+ }
+ else if (!strncmp(buf, "# gamma IRGB =", 20))
+ {
+ sscanf(buf+20, "%lf %lf %lf %lf",
+ &image_info->gamma,
+ &image_info->gamma_red,
+ &image_info->gamma_green,
+ &image_info->gamma_blue);
+ }
+ else if (!strncmp(buf, "# brightness =", 20))
+ {
+ sscanf(buf+20, "%lf", &image_info->brightness);
+ }
+ else if (!strncmp(buf, "# brightness IRGB =", 20))
+ {
+ sscanf(buf+20, "%lf %lf %lf %lf",
+ &image_info->brightness,
+ &image_info->brightness_red,
+ &image_info->brightness_green,
+ &image_info->brightness_blue);
+ }
+ else if (!strncmp(buf, "# contrast =", 20))
+ {
+ sscanf(buf+20, "%lf", &image_info->contrast);
+ }
+ else if (!strncmp(buf, "# contrast IRGB =", 20))
+ {
+ sscanf(buf+20, "%lf %lf %lf %lf",
+ &image_info->contrast,
+ &image_info->contrast_red,
+ &image_info->contrast_green,
+ &image_info->contrast_blue);
+ }
+ else if (!strncmp(buf, "# reduce to lineart", 20))
+ {
+ image_info->reduce_to_lineart = TRUE;
+ }
+ }
+
+ fscanf(file, "%d %d", &image_info->image_width, &image_info->image_height);
+
+ image_info->depth = 1;
+
+ if (filetype_nr != 4) /* P4 = lineart */
+ {
+ fscanf(file, "%d", &max_val);
+
+ if (max_val == 255)
+ {
+ image_info->depth = 8;
+ }
+ else if (max_val == 65535)
+ {
+ image_info->depth = 16;
+ }
+ }
+
+ fgetc(file); /* read exactly one newline character */
+
+
+ image_info->colors = 1;
+
+ if (filetype_nr == 6) /* ppm RGB */
+ {
+ image_info->colors = 3;
+ }
+ }
+#ifdef SUPPORT_RGBA
+ else if (buf[0] == 'S') /* RGBA format */
+ {
+ fscanf(file, "%d %d\n%d", &image_info->image_width, &image_info->image_height, &max_val);
+ fgetc(file); /* read exactly one newline character */
+
+ image_info->depth = 1;
+
+ if (max_val == 255)
+ {
+ image_info->depth = 8;
+ }
+ else if (max_val == 65535)
+ {
+ image_info->depth = 16;
+ }
+
+ image_info->colors = 4;
+ }
+#endif
+
+ DBG(DBG_info, "xsane_read_pnm_header: width=%d, height=%d, depth=%d, colors=%d, resolution_x=%f, resolution_y=%f\n",
+ image_info->image_width, image_info->image_height, image_info->depth, image_info->colors,
+ image_info->resolution_x, image_info->resolution_y);
+}
+
+/* ---------------------------------------------------------------------------------------------------------------------- */
+
+void xsane_write_pnm_header(FILE *file, Image_info *image_info, int save_pnm16_as_ascii)
+{
+ int maxval;
+ int magic;
+
+ fflush(file);
+ rewind(file);
+
+ if (image_info->depth > 8)
+ {
+ maxval = 65535;
+
+ if (save_pnm16_as_ascii)
+ {
+ magic = 2; /* thats the magic number for grayscale ascii, 3 = color ascii */
+ }
+ else /* save pnm as binary */
+ {
+ magic = 5; /* that is the magic number for grayscake binary, 6 = color binary */
+ }
+ }
+ else
+ {
+ maxval = 255;
+ magic = 5; /* 8 bit images are always saved in binary mode */
+ }
+
+
+ if (image_info->colors == 1)
+ {
+ if (image_info->depth == 1)
+ {
+ /* do not touch the texts and length here, the reading routine needs to know the exact texts */
+ fprintf(file, "P4\n"
+ "# XSane settings:\n"
+ "# resolution_x = %6.1f\n"
+ "# resolution_y = %6.1f\n"
+ "# threshold = %4.1f\n"
+ "# XSANE data follows\n"
+ "%05d %05d\n",
+ image_info->resolution_x,
+ image_info->resolution_y,
+ image_info->threshold,
+ image_info->image_width, image_info->image_height);
+ }
+ else if (image_info->reduce_to_lineart)
+ {
+ /* do not touch the texts and length here, the reading routine needs to know the exact texts */
+ fprintf(file, "P%d\n"
+ "# XSane settings:\n"
+ "# resolution_x = %6.1f\n"
+ "# resolution_y = %6.1f\n"
+ "# threshold = %4.1f\n"
+ "# reduce to lineart\n"
+ "# XSANE data follows\n"
+ "%05d %05d\n"
+ "%d\n",
+ magic, /* P5 for binary, P2 for ascii */
+ image_info->resolution_x,
+ image_info->resolution_y,
+ image_info->threshold,
+ image_info->image_width, image_info->image_height,
+ maxval);
+ }
+ else
+ {
+ fprintf(file, "P%d\n"
+ "# XSane settings:\n"
+ "# resolution_x = %6.1f\n"
+ "# resolution_y = %6.1f\n"
+ "# gamma = %3.2f\n"
+ "# brightness = %4.1f\n"
+ "# contrast = %4.1f\n"
+ "# XSANE data follows\n"
+ "%05d %05d\n"
+ "%d\n",
+ magic, /* P5 for binary, P2 for ascii */
+ image_info->resolution_x,
+ image_info->resolution_y,
+ image_info->gamma,
+ image_info->brightness,
+ image_info->contrast,
+ image_info->image_width, image_info->image_height,
+ maxval);
+ }
+ }
+ else if (image_info->colors == 3)
+ {
+ fprintf(file, "P%d\n"
+ "# XSane settings:\n"
+ "# resolution_x = %6.1f\n"
+ "# resolution_y = %6.1f\n"
+ "# gamma IRGB = %3.2f %3.2f %3.2f %3.2f\n"
+ "# brightness IRGB = %4.1f %4.1f %4.1f %4.1f\n"
+ "# contrast IRGB = %4.1f %4.1f %4.1f %4.1f\n"
+ "# XSANE data follows\n"
+ "%05d %05d\n" \
+ "%d\n",
+ magic+1, /* P6 for binary, P3 for ascii */
+ image_info->resolution_x,
+ image_info->resolution_y,
+ image_info->gamma, image_info->gamma_red, image_info->gamma_green, image_info->gamma_blue,
+ image_info->brightness, image_info->brightness_red, image_info->brightness_green, image_info->brightness_blue,
+ image_info->contrast, image_info->contrast_red, image_info->contrast_green, image_info->contrast_blue,
+ image_info->image_width, image_info->image_height,
+ maxval);
+ }
+#ifdef SUPPORT_RGBA
+ else if (image_info->colors == 4)
+ {
+ fprintf(file, "SANE_RGBA\n" \
+ "%d %d\n" \
+ "%d\n",
+ image_info->image_width, image_info->image_height, maxval);
+ }
+#endif
+}
+
+/* ---------------------------------------------------------------------------------------------------------------------- */
+
+int xsane_copy_file(FILE *outfile, FILE *infile, GtkProgressBar *progress_bar, int *cancel_save)
+{
+ long size;
+ long bytes_sum = 0;
+ size_t bytes;
+ unsigned char buf[65536];
+
+ DBG(DBG_proc, "copying file\n");
+
+ fseek(infile, 0, SEEK_END);
+ size = ftell(infile);
+ fseek(infile, 0, SEEK_SET);
+
+ gtk_progress_bar_update(GTK_PROGRESS_BAR(progress_bar), 0.0);
+
+ while (gtk_events_pending())
+ {
+ gtk_main_iteration();
+ }
+
+ while (!feof(infile))
+ {
+ bytes = fread(buf, 1, sizeof(buf), infile);
+ if (bytes > 0)
+ {
+ fwrite(buf, 1, bytes, outfile);
+ bytes_sum += bytes;
+ }
+
+ gtk_progress_bar_update(progress_bar, (float) bytes_sum / size); /* update progress bar */
+
+ while (gtk_events_pending())
+ {
+ gtk_main_iteration();
+ }
+
+ if (ferror(infile))
+ {
+ char buf[255];
+
+ snprintf(buf, sizeof(buf), "%s %s", ERR_DURING_READ, strerror(errno));
+ DBG(DBG_error, "%s\n", buf);
+ xsane_back_gtk_decision(ERR_HEADER_ERROR, (gchar **) error_xpm, buf, BUTTON_OK, NULL, TRUE /* wait */);
+ *cancel_save = 1;
+ break;
+ }
+
+ if (ferror(outfile))
+ {
+ char buf[255];
+
+ snprintf(buf, sizeof(buf), "%s %s", ERR_DURING_SAVE, strerror(errno));
+ DBG(DBG_error, "%s\n", buf);
+ xsane_back_gtk_decision(ERR_HEADER_ERROR, (gchar **) error_xpm, buf, BUTTON_OK, NULL, TRUE /* wait */);
+ *cancel_save = 1;
+ break;
+ }
+
+ if (*cancel_save)
+ {
+ break;
+ }
+ }
+
+ fflush(outfile);
+
+ if (size != bytes_sum)
+ {
+ DBG(DBG_info, "copy errro, not complete, %ld bytes of %ld bytes copied\n", bytes_sum, size);
+ *cancel_save = 1;
+ return (*cancel_save);
+ }
+
+ DBG(DBG_info, "copy complete, %ld bytes copied\n", bytes_sum);
+
+ return (*cancel_save);
+}
+
+/* ---------------------------------------------------------------------------------------------------------------------- */
+
+int xsane_copy_file_by_name(char *output_filename, char *input_filename, GtkProgressBar *progress_bar, int *cancel_save)
+{
+ FILE *infile;
+ FILE *outfile;
+
+ DBG(DBG_proc, "copying file %s to %s\n", input_filename, output_filename);
+
+ outfile = fopen(output_filename, "wb"); /* b = binary mode for win32 */
+
+ if (outfile == 0)
+ {
+ char buf[255];
+
+ snprintf(buf, sizeof(buf), "%s `%s': %s", ERR_OPEN_FAILED, output_filename, strerror(errno));
+ xsane_back_gtk_error(buf, TRUE);
+ return -2;
+ }
+
+ infile = fopen(input_filename, "rb"); /* read binary (b for win32) */
+ if (infile == 0)
+ {
+ char buf[256];
+ snprintf(buf, sizeof(buf), "%s `%s': %s", ERR_OPEN_FAILED, input_filename, strerror(errno));
+ xsane_back_gtk_error(buf, TRUE);
+
+ fclose(outfile);
+ remove(output_filename); /* remove already created output file */
+ return -1;
+ }
+
+ xsane_copy_file(outfile, infile, progress_bar, cancel_save);
+
+ fclose(infile);
+ fclose(outfile);
+
+ gtk_progress_set_format_string(GTK_PROGRESS(progress_bar), "");
+ gtk_progress_bar_update(GTK_PROGRESS_BAR(progress_bar), 0.0);
+
+ while (gtk_events_pending())
+ {
+ gtk_main_iteration();
+ }
+
+ return (*cancel_save);
+}
+
+/* ---------------------------------------------------------------------------------------------------------------------- */
+
+int xsane_save_grayscale_image_as_lineart(FILE *outfile, FILE *imagefile, Image_info *image_info, GtkProgressBar *progress_bar, int *cancel_save)
+{
+ int x, y, bit;
+ u_char bitval, packed;
+
+ *cancel_save = 0;
+
+ image_info->depth = 1;
+
+ xsane_write_pnm_header(outfile, image_info, 0);
+
+ for (y = 0; y < image_info->image_height; y++)
+ {
+ bit = 128;
+ packed = 0;
+
+ for (x = 0; x < image_info->image_width; x++)
+ {
+ bitval = fgetc(imagefile);
+
+ if (!bitval) /* white gets 0 bit, black gets 1 bit */
+ {
+ packed |= bit;
+ }
+
+ if (bit == 1)
+ {
+ fputc(packed, outfile);
+ bit = 128;
+ packed = 0;
+ }
+ else
+ {
+ bit >>= 1;
+ }
+ }
+
+ if (bit != 128)
+ {
+ fputc(packed, outfile);
+ bit = 128;
+ packed = 0;
+ }
+
+ if (ferror(outfile))
+ {
+ char buf[255];
+
+ snprintf(buf, sizeof(buf), "%s %s", ERR_DURING_SAVE, strerror(errno));
+ DBG(DBG_error, "%s\n", buf);
+ xsane_back_gtk_decision(ERR_HEADER_ERROR, (gchar **) error_xpm, buf, BUTTON_OK, NULL, TRUE /* wait */);
+ *cancel_save = 1;
+ break;
+ }
+
+
+ gtk_progress_bar_update(progress_bar, (float) y / image_info->image_height); /* update progress bar */
+ while (gtk_events_pending()) /* give gtk the chance to display the changes */
+ {
+ gtk_main_iteration();
+ }
+
+ if (*cancel_save)
+ {
+ break;
+ }
+ }
+
+ return (*cancel_save);
+}
+
+/* ---------------------------------------------------------------------------------------------------------------------- */
+
+int xsane_save_scaled_image(FILE *outfile, FILE *imagefile, Image_info *image_info, float x_scale, float y_scale, GtkProgressBar *progress_bar, int *cancel_save)
+{
+ int original_image_width = image_info->image_width;
+ int original_image_height = image_info->image_height;
+ int new_image_width = image_info->image_width * x_scale + 0.5;
+ int new_image_height = image_info->image_height * y_scale + 0.5;
+ unsigned char *original_line;
+ guint16 *original_line16 = NULL;
+ unsigned char *new_line;
+ float *pixel_val;
+ float *pixel_norm;
+ int bytespp = 1;
+ float x, y;
+ int c;
+ int oldy;
+ int x_new, y_new;
+ float x_go, y_go;
+ float factor, x_factor, y_factor;
+ guint16 color;
+ int read_line;
+
+ DBG(DBG_proc, "xsane_save_scaled_image\n");
+
+ *cancel_save = 0;
+
+ if (image_info->depth > 8)
+ {
+ bytespp = 2;
+ }
+
+ image_info->image_width = new_image_width;
+ image_info->image_height = new_image_height;
+ image_info->resolution_x *= x_scale;
+ image_info->resolution_y *= y_scale;
+
+ original_line = malloc(original_image_width * image_info->colors * bytespp);
+ if (!original_line)
+ {
+ DBG(DBG_error, "xsane_save_scaled_image: out of memory\n");
+ return -1;
+ }
+
+ new_line = malloc(new_image_width * image_info->colors * bytespp);
+ if (!new_line)
+ {
+ free(original_line);
+ DBG(DBG_error, "xsane_save_scaled_image: out of memory\n");
+ return -1;
+ }
+
+ pixel_val = malloc(new_image_width * image_info->colors * sizeof(float));
+ if (!pixel_val)
+ {
+ free(original_line);
+ free(new_line);
+ DBG(DBG_error, "xsane_save_scaled_image: out of memory\n");
+ return -1;
+ }
+
+ pixel_norm = malloc(new_image_width * image_info->colors * sizeof(float));
+ if (!pixel_norm)
+ {
+ free(original_line);
+ free(new_line);
+ free(pixel_val);
+ DBG(DBG_error, "xsane_save_scaled_image: out of memory\n");
+ return -1;
+ }
+
+ xsane_write_pnm_header(outfile, image_info, 0);
+
+ read_line = TRUE;
+
+ memset(pixel_val, 0, new_image_width * image_info->colors * sizeof(float));
+ memset(pixel_norm, 0, new_image_width * image_info->colors * sizeof(float));
+
+ y_new = 0;
+ y_go = 1.0 / y_scale;
+ y_factor = 1.0;
+ y = 0.0;
+
+ while (y < original_image_height)
+ {
+ DBG(DBG_info2, "xsane_save_scaled_image: original line %d, new line %d\n", (int) y, y_new);
+
+ gtk_progress_bar_update(progress_bar, (float) y / original_image_height);
+ while (gtk_events_pending())
+ {
+ gtk_main_iteration();
+ }
+
+ if (read_line)
+ {
+ DBG(DBG_info, "xsane_save_scaled_image: reading original line %d\n", (int) y);
+ fread(original_line, original_image_width, image_info->colors * bytespp, imagefile); /* read one line */
+ original_line16 = (guint16 *) original_line;
+ }
+
+ x_new = 0;
+ x_go = 1.0 / x_scale;
+ x = 0.0;
+ x_factor = 1.0;
+
+ while ( (x < original_image_width) && (x_new < new_image_width) ) /* add this line to anti aliasing buffer */
+
+ {
+ factor = x_factor * y_factor;
+
+ for (c = 0; c < image_info->colors; c++)
+ {
+ if (bytespp == 1)
+ {
+ color = original_line[((int) x) * image_info->colors + c];
+ }
+ else /* bytespp == 2 */
+ {
+ color = original_line16[((int) x) * image_info->colors + c];
+ }
+
+ pixel_val [x_new * image_info->colors + c] += factor * color;
+ pixel_norm[x_new * image_info->colors + c] += factor;
+ }
+
+ x_go -= x_factor;
+
+ if (x_go <= 0.0) /* change of pixel in new image */
+ {
+ x_new++;
+ x_go = 1.0 / x_scale;
+
+ x_factor = x - (int) x; /* use pixel rest */
+ if (x_factor > x_go)
+ {
+ x_factor = x_go;
+ }
+ }
+ else
+ {
+ x_factor = x_go;
+ }
+
+ if (x_factor > 1.0)
+ {
+ x_factor = 1.0;
+ }
+
+ x += x_factor;
+ }
+
+ y_go -= y_factor;
+
+ if (y_go <= 0.0) /* normalize one line and write to destination image file */
+ {
+ DBG(DBG_info2, "xsane_save_scaled_image: writing new line %d\n", y_new);
+
+ if (bytespp == 1)
+ {
+ for (x_new = 0; x_new < new_image_width * image_info->colors; x_new++)
+ {
+ new_line[x_new] = (int) (pixel_val[x_new] / pixel_norm[x_new]);
+ }
+ }
+ else /* bytespp == 2 */
+ {
+ guint16 *new_line16 = (guint16 *) new_line;
+
+ for (x_new = 0; x_new < new_image_width * image_info->colors; x_new++)
+ {
+ new_line16[x_new] = (int) (pixel_val[x_new] / pixel_norm[x_new]);
+ }
+ }
+
+ fwrite(new_line, new_image_width, image_info->colors * bytespp, outfile); /* write one line */
+
+ if (ferror(outfile))
+ {
+ char buf[255];
+
+ snprintf(buf, sizeof(buf), "%s %s", ERR_DURING_SAVE, strerror(errno));
+ DBG(DBG_error, "%s\n", buf);
+ xsane_back_gtk_decision(ERR_HEADER_ERROR, (gchar **) error_xpm, buf, BUTTON_OK, NULL, TRUE /* wait */);
+ *cancel_save = 1;
+ break;
+ }
+
+ /* reset values and norm factors */
+ memset(pixel_val, 0, new_image_width * image_info->colors * sizeof(float));
+ memset(pixel_norm, 0, new_image_width * image_info->colors * sizeof(float));
+
+ y_new++;
+ y_go = 1.0 / y_scale;
+
+ y_factor = y - (int) y;
+ if (y_factor > y_go)
+ {
+ y_factor = y_go;
+ }
+ }
+ else
+ {
+ y_factor = y_go;
+ }
+
+ if (y_factor > 1.0)
+ {
+ y_factor = 1.0;
+ }
+
+ oldy = (int) y;
+ y += y_factor;
+ read_line = (oldy != (int) y);
+ }
+
+ free(original_line);
+ free(new_line);
+ free(pixel_val);
+ free(pixel_norm);
+
+ return (*cancel_save);
+}
+
+/* ---------------------------------------------------------------------------------------------------------------------- */
+#if 0
+int xsane_save_scaled_image(FILE *outfile, FILE *imagefile, Image_info *image_info, float x_scale, float y_scale, GtkProgressBar *progress_bar, int *cancel_save)
+{
+ float original_y;
+ int old_original_y;
+ int x, y, i;
+ int original_image_width = image_info->image_width;
+ int new_image_width = image_info->image_width * x_scale;
+ int new_image_height = image_info->image_height * y_scale;
+ unsigned char *original_line;
+ unsigned char *new_line;
+ int bytespp = 1;
+
+ DBG(DBG_proc, "xsane_save_scaled_image\n");
+
+ if (image_info->depth > 8)
+ {
+ bytespp = 2;
+ }
+
+ image_info->image_width = new_image_width;
+ image_info->image_height = new_image_height;
+ image_info->resolution_x *= x_scale;
+ image_info->resolution_y *= y_scale;
+
+ original_line = malloc(original_image_width * image_info->colors * bytespp);
+ if (!original_line)
+ {
+ DBG(DBG_error, "xsane_save_scaled_image: out of memory\n");
+ return -1;
+ }
+
+ new_line = malloc(new_image_width * image_info->colors * bytespp);
+ if (!new_line)
+ {
+ free(original_line);
+ DBG(DBG_error, "xsane_save_scaled_image: out of memory\n");
+ return -1;
+ }
+
+ xsane_write_pnm_header(outfile, image_info, 0);
+
+ original_y = 0.0;
+ old_original_y = -1;
+
+ for (y = 0; y < new_image_height; y++)
+ {
+ gtk_progress_bar_update(progress_bar, (float) y / image_info->image_height);
+ while (gtk_events_pending())
+ {
+ gtk_main_iteration();
+ }
+
+ for (; ((int) original_y) - old_original_y; old_original_y += 1)
+ {
+ fread(original_line, original_image_width, image_info->colors * bytespp, imagefile); /* read one line */
+ }
+
+ for (x = 0; x < new_image_width; x++)
+ {
+ for (i = 0; i < image_info->colors * bytespp; i++)
+ {
+ new_line[x * image_info->colors * bytespp + i] = original_line[((int) (x / x_scale)) * image_info->colors * bytespp + i];
+ }
+ }
+
+ fwrite(new_line, new_image_width, image_info->colors * bytespp, outfile); /* write one line */
+
+ original_y += 1/y_scale;
+
+ if (*cancel_save)
+ {
+ break;
+ }
+ }
+
+ free(original_line);
+ free(new_line);
+
+ fflush(outfile);
+
+ return (*cancel_save);
+}
+#endif
+
+/* ---------------------------------------------------------------------------------------------------------------------- */
+
+int xsane_save_despeckle_image(FILE *outfile, FILE *imagefile, Image_info *image_info, int radius, GtkProgressBar *progress_bar, int *cancel_save)
+{
+ int x, y, sx, sy, i;
+ int xmin, xmax;
+ int ymin, ymax;
+ int count;
+ unsigned char *line_cache;
+ unsigned char *line_cache_ptr;
+ guint16 *color_cache;
+ guint16 *color_cache_ptr;
+ int bytespp = 1;
+ int color_radius;
+ int color_width = image_info->image_width * image_info->colors;
+
+ radius--; /* correct radius : 1 means nothing happens */
+
+ if (radius < 1)
+ {
+ radius = 1;
+ }
+
+ color_radius = radius * image_info->colors;
+
+ if (image_info->depth > 8)
+ {
+ bytespp = 2;
+ }
+
+ xsane_write_pnm_header(outfile, image_info, 0);
+
+ line_cache = malloc(color_width * bytespp * (2 * radius + 1));
+ if (!line_cache)
+ {
+ DBG(DBG_error, "xsane_despeckle_image: out of memory\n");
+ return -1;
+ }
+
+ fread(line_cache, color_width * bytespp, (2 * radius + 1), imagefile);
+
+ color_cache = malloc((size_t) sizeof(guint16) * (2*radius+1)*(2*radius+1));
+
+ if (!color_cache)
+ {
+ free(line_cache);
+ DBG(DBG_error, "xsane_despeckle_image: out of memory\n");
+ return -1;
+ }
+
+ for (y = 0; y < image_info->image_height; y++)
+ {
+ gtk_progress_bar_update(progress_bar, (float) y / image_info->image_height);
+
+ while (gtk_events_pending())
+ {
+ gtk_main_iteration();
+ }
+
+ ymin = y - radius;
+ ymax = y + radius;
+
+ if (ymin < 0)
+ {
+ ymin = 0;
+ }
+
+ if (ymax > image_info->image_height)
+ {
+ ymax = image_info->image_height;
+ }
+
+ for (x = 0; x < color_width; x++)
+ {
+ xmin = x - color_radius;
+ xmax = x + color_radius;
+
+ if (xmin < 0)
+ {
+ xmin = x % image_info->colors;
+ }
+
+ if (xmax > color_width)
+ {
+ xmax = color_width;
+ }
+
+ count = 0;
+
+ color_cache_ptr = color_cache;
+
+
+ if (bytespp == 1)
+ {
+ for (sy = ymin; sy <= ymax; sy++) /* search area defined by radius - y part */
+ {
+ line_cache_ptr = line_cache + (sy-ymin) * color_width + xmin;
+
+ for (sx = xmin; sx <= xmax; sx+=image_info->colors) /* x part */
+ {
+ *color_cache_ptr = *line_cache_ptr;
+ color_cache_ptr++;
+ line_cache_ptr += image_info->colors;
+ }
+ }
+
+ /* sort color_cache */
+
+ count = color_cache_ptr - color_cache;
+
+ if (count > 1)
+ {
+ int d, j, val;
+
+ for (d = count / 2; d > 0; d = d / 2)
+ {
+ for (i = d; i < count; i++)
+ {
+ for (j = i - d, color_cache_ptr = color_cache + j; j >= 0 && color_cache_ptr[0] > color_cache_ptr[d]; j -= d, color_cache_ptr -= d)
+ {
+ val = color_cache_ptr[0];
+ color_cache_ptr[0] = color_cache_ptr[d];
+ color_cache_ptr[d] = val;
+ };
+ }
+ }
+ }
+
+ fputc((char) (color_cache[count/2]), outfile);
+ }
+ else /* 16 bit/color */
+ {
+ guint16 val16;
+ guint16 *line_cache16 = (guint16 *) line_cache;
+ guint16 *line_cache16_ptr;
+ char *bytes16 = (char *) &val16;
+
+ for (sy = ymin; sy <= ymax; sy++)
+ {
+ line_cache16_ptr = line_cache16 + (sy-ymin) * color_width + xmin;
+
+ for (sx = xmin; sx <= xmax; sx+=image_info->colors)
+ {
+ *color_cache_ptr = *line_cache16_ptr;
+ color_cache_ptr++;
+ line_cache16_ptr += image_info->colors;
+ }
+ }
+
+ /* sort color_cache */
+
+ count = color_cache_ptr - color_cache;
+
+ if (count > 1)
+ {
+ int d,j, val;
+
+ for (d = count / 2; d > 0; d = d / 2)
+ {
+ for (i = d; i < count; i++)
+ {
+ for (j = i - d, color_cache_ptr = color_cache + j; j >= 0 && color_cache_ptr[0] > color_cache_ptr[d]; j -= d, color_cache_ptr -= d)
+ {
+ val = color_cache_ptr[0];
+ color_cache_ptr[0] = color_cache_ptr[d];
+ color_cache_ptr[d] = val;
+ };
+ }
+ }
+ }
+
+ val16 = color_cache[count/2];
+ fputc(bytes16[0], outfile); /* write bytes in machine byte order */
+ fputc(bytes16[1], outfile);
+ }
+ }
+
+ if (ferror(outfile))
+ {
+ char buf[255];
+
+ snprintf(buf, sizeof(buf), "%s %s", ERR_DURING_SAVE, strerror(errno));
+ DBG(DBG_error, "%s\n", buf);
+ xsane_back_gtk_decision(ERR_HEADER_ERROR, (gchar **) error_xpm, buf, BUTTON_OK, NULL, TRUE /* wait */);
+ *cancel_save = 1;
+ break;
+ }
+
+ if ((y > radius) && (y < image_info->image_height - radius))
+ {
+ memcpy(line_cache, line_cache + color_width * bytespp,
+ color_width * bytespp * 2 * radius);
+ fread(line_cache + color_width * bytespp * 2 * radius,
+ color_width * bytespp, 1, imagefile);
+ }
+ }
+
+ fflush(outfile);
+
+ free(line_cache);
+ free(color_cache);
+
+ return 0;
+}
+
+/* ---------------------------------------------------------------------------------------------------------------------- */
+
+int xsane_save_blur_image(FILE *outfile, FILE *imagefile, Image_info *image_info, float radius, GtkProgressBar *progress_bar, int *cancel_save)
+{
+ int x, y, sx, sy;
+ int xmin, xmax;
+ int ymin, ymax;
+ double val, norm, outer_factor;
+ unsigned char *line_cache;
+ int bytespp = 1;
+ int intradius;
+ int xmin_flag;
+ int xmax_flag;
+ int ymin_flag;
+ int ymax_flag;
+
+ *cancel_save = 0;
+
+ intradius = (int) radius;
+
+ outer_factor = radius - (int) radius;
+
+ if (image_info->depth > 8)
+ {
+ bytespp = 2;
+ }
+
+ xsane_write_pnm_header(outfile, image_info, 0);
+
+ line_cache = malloc(image_info->image_width * image_info->colors * bytespp * (2 * intradius + 1));
+ if (!line_cache)
+ {
+ DBG(DBG_error, "xsane_blur_image: out of memory\n");
+ return -1;
+ }
+
+ fread(line_cache, image_info->image_width * image_info->colors * bytespp, (2 * intradius + 1), imagefile);
+
+ for (y = 0; y < image_info->image_height; y++)
+ {
+ gtk_progress_bar_update(progress_bar, (float) y / image_info->image_height);
+ while (gtk_events_pending())
+ {
+ gtk_main_iteration();
+ }
+
+ for (x = 0; x < image_info->image_width * image_info->colors; x++)
+ {
+ xmin_flag = xmax_flag = ymin_flag = ymax_flag = TRUE;
+
+ xmin = x - intradius * image_info->colors;
+ xmax = x + intradius * image_info->colors;
+
+ if (xmin < 0)
+ {
+ xmin = x % image_info->colors;
+ xmin_flag = FALSE;
+ }
+
+ if (xmax > image_info->image_width * image_info->colors)
+ {
+ xmax = image_info->image_width * image_info->colors;
+ xmax_flag = FALSE;
+ }
+
+ ymin = y - intradius;
+ ymax = y + intradius;
+
+ if (ymin < 0)
+ {
+ ymin = 0;
+ ymin_flag = FALSE;
+ }
+
+ if (ymax > image_info->image_height)
+ {
+ ymax = image_info->image_height;
+ ymax_flag = FALSE;
+ }
+
+ val = 0.0;
+ norm = 0.0;
+
+ if (bytespp == 1)
+ {
+ if (xmin_flag) /* integrate over left margin */
+ {
+ for (sy = ymin+1; sy <= ymax-1 ; sy++)
+ {
+ val += outer_factor * line_cache[(sy-ymin) * image_info->image_width * image_info->colors + xmin];
+ norm += outer_factor;
+ }
+ }
+
+ if (xmax_flag) /* integrate over right margin */
+ {
+ for (sy = ymin+1; sy <= ymax-1 ; sy++)
+ {
+ val += outer_factor * line_cache[(sy-ymin) * image_info->image_width * image_info->colors + xmax];
+ norm += outer_factor;
+ }
+ }
+
+ if (ymin_flag) /* integrate over top margin */
+ {
+ for (sx = xmin+image_info->colors; sx <= xmax-image_info->colors ; sx += image_info->colors)
+ {
+ val += outer_factor * line_cache[sx];
+ norm += outer_factor;
+ }
+ }
+
+ if (ymax_flag) /* integrate over bottom margin */
+ {
+ for (sx = xmin+image_info->colors; sx <= xmax-image_info->colors ; sx += image_info->colors)
+ {
+ val += outer_factor * line_cache[(ymax-ymin) * image_info->image_width * image_info->colors + sx];
+ norm += outer_factor;
+ }
+ }
+
+ for (sy = ymin+1; sy <= ymax-1; sy++) /* integrate internal square */
+ {
+ for (sx = xmin+image_info->colors; sx <= xmax-image_info->colors; sx+=image_info->colors)
+ {
+ val += line_cache[(sy-ymin) * image_info->image_width * image_info->colors + sx];
+ norm += 1.0;
+ }
+ }
+ fputc((char) ((int) (val/norm)), outfile);
+ }
+ else /* bytespp == 2 */
+ {
+ guint16 *line_cache16 = (guint16 *) line_cache;
+ guint16 val16;
+ char *bytes16 = (char *) &val16;
+
+ if (xmin_flag) /* integrate over left margin */
+ {
+ for (sy = ymin+1; sy <= ymax-1 ; sy++)
+ {
+ val += outer_factor * line_cache16[(sy-ymin) * image_info->image_width * image_info->colors + xmin];
+ norm += outer_factor;
+ }
+ }
+
+ if (xmax_flag) /* integrate over right margin */
+ {
+ for (sy = ymin+1; sy <= ymax-1 ; sy++)
+ {
+ val += outer_factor * line_cache16[(sy-ymin) * image_info->image_width * image_info->colors + xmax];
+ norm += outer_factor;
+ }
+ }
+
+ if (ymin_flag) /* integrate over top margin */
+ {
+ for (sx = xmin+image_info->colors; sx <= xmax-image_info->colors ; sx += image_info->colors)
+ {
+ val += outer_factor * line_cache16[sx];
+ norm += outer_factor;
+ }
+ }
+
+ if (ymax_flag) /* integrate over bottom margin */
+ {
+ for (sx = xmin+image_info->colors; sx <= xmax-image_info->colors ; sx += image_info->colors)
+ {
+ val += outer_factor * line_cache16[(ymax-ymin) * image_info->image_width * image_info->colors + sx];
+ norm += outer_factor;
+ }
+ }
+
+ for (sy = ymin; sy <= ymax; sy++) /* integrate internal square */
+ {
+ for (sx = xmin; sx <= xmax; sx+=image_info->colors)
+ {
+ val += line_cache16[(sy-ymin) * image_info->image_width * image_info->colors + sx];
+ norm += 1.0;
+ }
+ }
+
+ val16 = val / norm;
+ fputc(bytes16[0], outfile); /* write bytes in machine byte order */
+ fputc(bytes16[1], outfile);
+ }
+ }
+
+ if (ferror(outfile))
+ {
+ char buf[255];
+
+ snprintf(buf, sizeof(buf), "%s %s", ERR_DURING_SAVE, strerror(errno));
+ DBG(DBG_error, "%s\n", buf);
+ xsane_back_gtk_decision(ERR_HEADER_ERROR, (gchar **) error_xpm, buf, BUTTON_OK, NULL, TRUE /* wait */);
+ *cancel_save = 1;
+ break;
+ }
+
+ /* reset values and norm factors */
+
+ if ((y > intradius) && (y < image_info->image_height - intradius))
+ {
+ memcpy(line_cache, line_cache + image_info->image_width * image_info->colors * bytespp,
+ image_info->image_width * image_info->colors * bytespp * 2 * intradius);
+ fread(line_cache + image_info->image_width * image_info->colors * bytespp * 2 * intradius,
+ image_info->image_width * image_info->colors * bytespp, 1, imagefile);
+ }
+ }
+
+ fflush(outfile);
+ free(line_cache);
+
+ return 0;
+}
+
+/* ---------------------------------------------------------------------------------------------------------------------- */
+
+#if 0
+int xsane_save_blur_image(FILE *outfile, FILE *imagefile, Image_info *image_info, int radius, GtkProgressBar *progress_bar)
+{
+ int x, y, sx, sy;
+ int xmin, xmax;
+ int ymin, ymax;
+ int pos0;
+ int val, count;
+ unsigned char *line_cache;
+ int bytespp = 1;
+
+ if (image_info->depth > 8)
+ {
+ bytespp = 2;
+ }
+
+ pos0 = ftell(imagefile); /* mark position to skip header */
+
+ xsane_write_pnm_header(outfile, image_info, 0);
+
+ line_cache = malloc(image_info->image_width * image_info->colors * bytespp * (2 * radius + 1));
+ if (!line_cache)
+ {
+ DBG(DBG_error, "xsane_blur_image: out of memory\n");
+ return -1;
+ }
+
+ fread(line_cache, image_info->image_width * image_info->colors * bytespp, (2 * radius + 1), imagefile);
+
+ for (y = 0; y < image_info->image_height; y++)
+ {
+ gtk_progress_bar_update(progress_bar, (float) y / image_info->image_height);
+ while (gtk_events_pending())
+ {
+ gtk_main_iteration();
+ }
+
+ for (x = 0; x < image_info->image_width * image_info->colors; x++)
+ {
+ xmin = x - radius * image_info->colors;
+ xmax = x + radius * image_info->colors;
+
+ if (xmin < 0)
+ {
+ xmin = x % image_info->colors;
+ }
+
+ if (xmax > image_info->image_width * image_info->colors)
+ {
+ xmax = image_info->image_width * image_info->colors;
+ }
+
+ ymin = y - radius;
+ ymax = y + radius;
+
+ if (ymin < 0)
+ {
+ ymin = 0;
+ }
+
+ if (ymax > image_info->image_height)
+ {
+ ymax = image_info->image_height;
+ }
+
+ val = 0;
+ count = 0;
+
+ if (bytespp == 1)
+ {
+ for (sy = ymin; sy <= ymax; sy++)
+ {
+ for (sx = xmin; sx <= xmax; sx+=image_info->colors)
+ {
+ val += line_cache[(sy-ymin) * image_info->image_width * image_info->colors + sx];
+ count++;
+ }
+ }
+ fputc((char) (val/count), outfile);
+ }
+ else
+ {
+ guint16 *line_cache16 = (guint16 *) line_cache;
+ guint16 val16;
+ char *bytes16 = (char *) &val16;
+
+ for (sy = ymin; sy <= ymax; sy++)
+ {
+ for (sx = xmin; sx <= xmax; sx+=image_info->colors)
+ {
+ val += line_cache16[(sy-ymin) * image_info->image_width * image_info->colors + sx];
+ count++;
+ }
+ }
+
+ val16 = val / count;
+ fputc(bytes16[0], outfile); /* write bytes in machine byte order */
+ fputc(bytes16[1], outfile);
+ }
+ }
+
+ if ((y > radius) && (y < image_info->image_height - radius))
+ {
+ memcpy(line_cache, line_cache + image_info->image_width * image_info->colors * bytespp,
+ image_info->image_width * image_info->colors * bytespp * 2 * radius);
+ fread(line_cache + image_info->image_width * image_info->colors * bytespp * 2 * radius,
+ image_info->image_width * image_info->colors * bytespp, 1, imagefile);
+ }
+ }
+
+ fflush(outfile);
+ free(line_cache);
+
+ return 0;
+}
+#endif
+
+/* ---------------------------------------------------------------------------------------------------------------------- */
+
+int xsane_save_rotate_image(FILE *outfile, FILE *imagefile, Image_info *image_info, int rotation, GtkProgressBar *progress_bar, int *cancel_save)
+/* returns true if operation was cancelled */
+{
+ int x, y, pos0, bytespp, i;
+ int pixel_width = image_info->image_width;
+ int pixel_height = image_info->image_height;
+ float resolution_x = image_info->resolution_x;
+ float resolution_y = image_info->resolution_y;
+
+#ifdef HAVE_MMAP
+ char *mmaped_imagefile = NULL;
+#endif
+
+ DBG(DBG_proc, "xsane_save_rotate_image\n");
+
+ *cancel_save = 0;
+
+ pos0 = ftell(imagefile); /* mark position to skip header */
+
+ bytespp = image_info->colors;
+
+ if (image_info->depth > 8)
+ {
+ bytespp *= 2;
+ }
+
+ if (image_info->depth < 8) /* lineart images are expanded to grayscale until transformation is done */
+ {
+ image_info->depth = 8; /* so we have at least 8 bits/pixel here */
+ }
+
+#ifdef HAVE_MMAP
+ mmaped_imagefile = mmap(NULL, pixel_width * pixel_height * bytespp + pos0, PROT_READ, MAP_PRIVATE, fileno(imagefile), 0);
+ if (mmaped_imagefile == (char *) -1) /* mmap failed */
+ {
+ DBG(DBG_info, "xsane_save_rotate_image: unable to memory map image file, using standard file access\n");
+ mmaped_imagefile = NULL;
+ }
+ else
+ {
+ DBG(DBG_info, "xsane_save_rotate_image: using memory mapped image file\n");
+ }
+#endif
+
+ switch (rotation)
+ {
+ default:
+ break;
+
+ case 0: /* 0 degree */
+ xsane_write_pnm_header(outfile, image_info, 0);
+
+ for (y = 0; y < pixel_height; y++)
+ {
+ gtk_progress_bar_update(progress_bar, (float) y / pixel_height);
+ while (gtk_events_pending())
+ {
+ gtk_main_iteration();
+ }
+
+ for (x = 0; x < pixel_width; x++)
+ {
+#ifdef HAVE_MMAP
+ if (mmaped_imagefile)
+ {
+ char *p = mmaped_imagefile + pos0 + bytespp * (x + y * pixel_width); /* calculate correct position */
+
+ for (i=0; i<bytespp; i++)
+ {
+ fputc(*p++, outfile);
+ }
+ }
+ else
+#endif
+ {
+ for (i = 0; i < bytespp; i++)
+ {
+ fputc(fgetc(imagefile), outfile);
+ }
+ }
+ }
+
+ if (ferror(outfile))
+ {
+ char buf[255];
+
+ snprintf(buf, sizeof(buf), "%s %s", ERR_DURING_SAVE, strerror(errno));
+ DBG(DBG_error, "%s\n", buf);
+ xsane_back_gtk_decision(ERR_HEADER_ERROR, (gchar **) error_xpm, buf, BUTTON_OK, NULL, TRUE /* wait */);
+ *cancel_save = 1;
+ break;
+ }
+
+ if (*cancel_save)
+ {
+ break;
+ }
+ }
+ break;
+
+ case 1: /* 90 degree */
+ image_info->image_width = pixel_height;
+ image_info->image_height = pixel_width;
+
+ image_info->resolution_x = resolution_y;
+ image_info->resolution_y = resolution_x;
+
+ xsane_write_pnm_header(outfile, image_info, 0);
+
+ for (x=0; x<pixel_width; x++)
+ {
+ gtk_progress_bar_update(progress_bar, (float) x / pixel_width);
+ while (gtk_events_pending())
+ {
+ gtk_main_iteration();
+ }
+
+ for (y=pixel_height-1; y>=0; y--)
+ {
+#ifdef HAVE_MMAP
+ if (mmaped_imagefile)
+ {
+ char *p = mmaped_imagefile + pos0 + bytespp * (x + y * pixel_width); /* calculate correct position */
+
+ for (i=0; i<bytespp; i++)
+ {
+ fputc(*p++, outfile);
+ }
+ }
+ else
+#endif
+ {
+ fseek(imagefile, pos0 + bytespp * (x + y * pixel_width), SEEK_SET); /* go to the correct position */
+ for (i=0; i<bytespp; i++)
+ {
+ fputc(fgetc(imagefile), outfile);
+ }
+ }
+ }
+
+
+ if (ferror(outfile))
+ {
+ char buf[255];
+
+ snprintf(buf, sizeof(buf), "%s %s", ERR_DURING_SAVE, strerror(errno));
+ DBG(DBG_error, "%s\n", buf);
+ xsane_back_gtk_decision(ERR_HEADER_ERROR, (gchar **) error_xpm, buf, BUTTON_OK, NULL, TRUE /* wait */);
+ *cancel_save = 1;
+ break;
+ }
+
+ if (*cancel_save)
+ {
+ break;
+ }
+ }
+
+ break;
+
+ case 2: /* 180 degree */
+ xsane_write_pnm_header(outfile, image_info, 0);
+
+ for (y = pixel_height-1; y >= 0; y--)
+ {
+ gtk_progress_bar_update(progress_bar, (float) (pixel_height - y) / pixel_height);
+ while (gtk_events_pending())
+ {
+ gtk_main_iteration();
+ }
+
+ for (x = pixel_width-1; x >= 0; x--)
+ {
+#ifdef HAVE_MMAP
+ if (mmaped_imagefile)
+ {
+ char *p = mmaped_imagefile + pos0 + bytespp * (x + y * pixel_width); /* calculate correct position */
+
+ for (i = 0; i < bytespp; i++)
+ {
+ fputc(*p++, outfile);
+ }
+ }
+ else
+#endif
+ {
+ fseek(imagefile, pos0 + bytespp * (x + y * pixel_width), SEEK_SET); /* go to the correct position */
+ for (i = 0; i < bytespp; i++)
+ {
+ fputc(fgetc(imagefile), outfile);
+ }
+ }
+ }
+
+
+ if (ferror(outfile))
+ {
+ char buf[255];
+
+ snprintf(buf, sizeof(buf), "%s %s", ERR_DURING_SAVE, strerror(errno));
+ DBG(DBG_error, "%s\n", buf);
+ xsane_back_gtk_decision(ERR_HEADER_ERROR, (gchar **) error_xpm, buf, BUTTON_OK, NULL, TRUE /* wait */);
+ *cancel_save = 1;
+ break;
+ }
+
+ if (*cancel_save)
+ {
+ break;
+ }
+ }
+ break;
+
+ case 3: /* 270 degree */
+ image_info->image_width = pixel_height;
+ image_info->image_height = pixel_width;
+
+ image_info->resolution_x = resolution_y;
+ image_info->resolution_y = resolution_x;
+
+ xsane_write_pnm_header(outfile, image_info, 0);
+
+ for (x = pixel_width-1; x >= 0; x--)
+ {
+ gtk_progress_bar_update(progress_bar, (float) (pixel_width - x) / pixel_width);
+ while (gtk_events_pending())
+ {
+ gtk_main_iteration();
+ }
+
+ for (y = 0; y < pixel_height; y++)
+ {
+#ifdef HAVE_MMAP
+ if (mmaped_imagefile)
+ {
+ char *p = mmaped_imagefile + pos0 + bytespp * (x + y * pixel_width); /* calculate correct position */
+
+ for (i = 0; i < bytespp; i++)
+ {
+ fputc(*p++, outfile);
+ }
+ }
+ else
+#endif
+ {
+ fseek(imagefile, pos0 + bytespp * (x + y * pixel_width), SEEK_SET); /* go to the correct position */
+ for (i = 0; i < bytespp; i++)
+ {
+ fputc(fgetc(imagefile), outfile);
+ }
+ }
+ }
+
+
+ if (ferror(outfile))
+ {
+ char buf[255];
+
+ snprintf(buf, sizeof(buf), "%s %s", ERR_DURING_SAVE, strerror(errno));
+ DBG(DBG_error, "%s\n", buf);
+ xsane_back_gtk_decision(ERR_HEADER_ERROR, (gchar **) error_xpm, buf, BUTTON_OK, NULL, TRUE /* wait */);
+ *cancel_save = 1;
+ break;
+ }
+
+ if (*cancel_save)
+ {
+ break;
+ }
+ }
+ break;
+
+ case 4: /* 0 degree, x mirror */
+ xsane_write_pnm_header(outfile, image_info, 0);
+
+ for (y = 0; y < pixel_height; y++)
+ {
+ gtk_progress_bar_update(progress_bar, (float) y / pixel_height);
+ while (gtk_events_pending())
+ {
+ gtk_main_iteration();
+ }
+
+ for (x = pixel_width-1; x >= 0; x--)
+ {
+#ifdef HAVE_MMAP
+ if (mmaped_imagefile)
+ {
+ char *p = mmaped_imagefile + pos0 + bytespp * (x + y * pixel_width); /* calculate correct position */
+
+ for (i = 0; i < bytespp; i++)
+ {
+ fputc(*p++, outfile);
+ }
+ }
+ else
+#endif
+ {
+ fseek(imagefile, pos0 + bytespp * (x + y * pixel_width), SEEK_SET); /* go to the correct position */
+ for (i = 0; i < bytespp; i++)
+ {
+ fputc(fgetc(imagefile), outfile);
+ }
+ }
+ }
+
+
+ if (ferror(outfile))
+ {
+ char buf[255];
+
+ snprintf(buf, sizeof(buf), "%s %s", ERR_DURING_SAVE, strerror(errno));
+ DBG(DBG_error, "%s\n", buf);
+ xsane_back_gtk_decision(ERR_HEADER_ERROR, (gchar **) error_xpm, buf, BUTTON_OK, NULL, TRUE /* wait */);
+ *cancel_save = 1;
+ break;
+ }
+
+ if (*cancel_save)
+ {
+ break;
+ }
+ }
+ break;
+
+ case 5: /* 90 degree, x mirror */
+ image_info->image_width = pixel_height;
+ image_info->image_height = pixel_width;
+
+ image_info->resolution_x = resolution_y;
+ image_info->resolution_y = resolution_x;
+
+ xsane_write_pnm_header(outfile, image_info, 0);
+
+ for (x = 0; x < pixel_width; x++)
+ {
+ gtk_progress_bar_update(progress_bar, (float) x / pixel_width);
+ while (gtk_events_pending())
+ {
+ gtk_main_iteration();
+ }
+
+ for (y = 0; y < pixel_height; y++)
+ {
+#ifdef HAVE_MMAP
+ if (mmaped_imagefile)
+ {
+ char *p = mmaped_imagefile + pos0 + bytespp * (x + y * pixel_width); /* calculate correct position */
+
+ for (i=0; i<bytespp; i++)
+ {
+ fputc(*p++, outfile);
+ }
+ }
+ else
+#endif
+ {
+ fseek(imagefile, pos0 + bytespp * (x + y * pixel_width), SEEK_SET); /* go to the correct position */
+ for (i = 0; i < bytespp; i++)
+ {
+ fputc(fgetc(imagefile), outfile);
+ }
+ }
+ }
+
+
+ if (ferror(outfile))
+ {
+ char buf[255];
+
+ snprintf(buf, sizeof(buf), "%s %s", ERR_DURING_SAVE, strerror(errno));
+ DBG(DBG_error, "%s\n", buf);
+ xsane_back_gtk_decision(ERR_HEADER_ERROR, (gchar **) error_xpm, buf, BUTTON_OK, NULL, TRUE /* wait */);
+ *cancel_save = 1;
+ break;
+ }
+
+ if (*cancel_save)
+ {
+ break;
+ }
+ }
+
+ break;
+
+ case 6: /* 180 degree, x mirror */
+ xsane_write_pnm_header(outfile, image_info, 0);
+
+ for (y = pixel_height-1; y >= 0; y--)
+ {
+ gtk_progress_bar_update(progress_bar, (float) (pixel_height - y) / pixel_height);
+ while (gtk_events_pending())
+ {
+ gtk_main_iteration();
+ }
+
+ for (x = 0; x < pixel_width; x++)
+ {
+#ifdef HAVE_MMAP
+ if (mmaped_imagefile)
+ {
+ char *p = mmaped_imagefile + pos0 + bytespp * (x + y * pixel_width); /* calculate correct position */
+
+ for (i = 0; i < bytespp; i++)
+ {
+ fputc(*p++, outfile);
+ }
+ }
+ else
+#endif
+ {
+ fseek(imagefile, pos0 + bytespp * (x + y * pixel_width), SEEK_SET); /* go to the correct position */
+ for (i = 0; i < bytespp; i++)
+ {
+ fputc(fgetc(imagefile), outfile);
+ }
+ }
+ }
+
+
+ if (ferror(outfile))
+ {
+ char buf[255];
+
+ snprintf(buf, sizeof(buf), "%s %s", ERR_DURING_SAVE, strerror(errno));
+ DBG(DBG_error, "%s\n", buf);
+ xsane_back_gtk_decision(ERR_HEADER_ERROR, (gchar **) error_xpm, buf, BUTTON_OK, NULL, TRUE /* wait */);
+ *cancel_save = 1;
+ break;
+ }
+
+ if (*cancel_save)
+ {
+ break;
+ }
+ }
+ break;
+
+ case 7: /* 270 degree, x mirror */
+ image_info->image_width = pixel_height;
+ image_info->image_height = pixel_width;
+
+ image_info->resolution_x = resolution_y;
+ image_info->resolution_y = resolution_x;
+
+ xsane_write_pnm_header(outfile, image_info, 0);
+
+ for (x = pixel_width-1; x >= 0; x--)
+ {
+ gtk_progress_bar_update(progress_bar, (float) (pixel_width - x) / pixel_width);
+ while (gtk_events_pending())
+ {
+ gtk_main_iteration();
+ }
+
+ for (y = pixel_height-1; y >= 0; y--)
+ {
+#ifdef HAVE_MMAP
+ if (mmaped_imagefile)
+ {
+ char *p = mmaped_imagefile + pos0 + bytespp * (x + y * pixel_width); /* calculate correct position */
+
+ for (i = 0; i < bytespp; i++)
+ {
+ fputc(*p++, outfile);
+ }
+ }
+ else
+#endif
+ {
+ fseek(imagefile, pos0 + bytespp * (x + y * pixel_width), SEEK_SET); /* go to the correct position */
+ for (i = 0; i < bytespp; i++)
+ {
+ fputc(fgetc(imagefile), outfile);
+ }
+ }
+ }
+
+
+ if (ferror(outfile))
+ {
+ char buf[255];
+
+ snprintf(buf, sizeof(buf), "%s %s", ERR_DURING_SAVE, strerror(errno));
+ DBG(DBG_error, "%s\n", buf);
+ xsane_back_gtk_decision(ERR_HEADER_ERROR, (gchar **) error_xpm, buf, BUTTON_OK, NULL, TRUE /* wait */);
+ *cancel_save = 1;
+ break;
+ }
+
+ if (*cancel_save)
+ {
+ break;
+ }
+ }
+ break;
+ }
+
+#ifdef HAVE_MMAP
+ if (mmaped_imagefile)
+ {
+ munmap(mmaped_imagefile, pos0 + pixel_width * pixel_height * bytespp);
+ }
+#endif
+
+ fflush(outfile);
+
+ return (*cancel_save);
+}
+
+/* ---------------------------------------------------------------------------------------------------------------------- */
+
+void xsane_save_ps_create_document_header(FILE *outfile, int pages, int flatdecode)
+{
+ DBG(DBG_proc, "xsane_save_ps_create_document_header\n");
+
+ fprintf(outfile, "%%!PS-Adobe-3.0\n");
+ fprintf(outfile, "%%%%Creator: XSane version %s (sane %d.%d) - by Oliver Rauch\n", VERSION,
+ SANE_VERSION_MAJOR(xsane.sane_backend_versioncode),
+ SANE_VERSION_MINOR(xsane.sane_backend_versioncode));
+ fprintf(outfile, "%%%%DocumentData: Clean7Bit\n");
+ if (flatdecode)
+ {
+ fprintf(outfile, "%%%%LanguageLevel: 3\n");
+ }
+ else
+ {
+ fprintf(outfile, "%%%%LanguageLevel: 2\n");
+ }
+
+ if (pages)
+ {
+ fprintf(outfile, "%%%%Pages: %d\n", pages);
+ }
+ else
+ {
+ fprintf(outfile, "%%%%Pages: (atend)\n");
+ }
+
+ fprintf(outfile, "%%%%EndComments\n");
+ fprintf(outfile, "\n");
+ fprintf(outfile, "/origstate save def\n");
+ fprintf(outfile, "20 dict begin\n");
+}
+
+/* ---------------------------------------------------------------------------------------------------------------------- */
+
+void xsane_save_ps_create_document_trailer(FILE *outfile, int pages)
+{
+ DBG(DBG_proc, "xsane_save_ps_create_document_trailer\n");
+
+ fprintf(outfile, "end\n");
+ fprintf(outfile, "origstate restore\n");
+
+ if (pages)
+ {
+ fprintf(outfile, "%%%%Trailer\n");
+ fprintf(outfile, "%%%%Pages: %d\n", pages);
+ }
+
+ fprintf(outfile, "%%%%EOF\n");
+ fprintf(outfile, "\n");
+
+}
+
+/* ---------------------------------------------------------------------------------------------------------------------- */
+
+/* page = [1 .. pages] */
+static void xsane_save_ps_create_page_header(FILE *outfile, int page,
+ Image_info *image_info,
+ float width, float height,
+ int paper_left_margin, int paper_bottom_margin,
+ int paper_width, int paper_height,
+ int paper_orientation, int flatdecode,
+ GtkProgressBar *progress_bar)
+{
+ int degree, position_left, position_bottom, box_left, box_bottom, box_right, box_top, depth;
+ int left, bottom;
+
+ DBG(DBG_proc, "xsane_save_ps_create_page_header\n");
+
+ switch (paper_orientation)
+ {
+ default:
+ case 0: /* top left portrait */
+ left = 0.0;
+ bottom = paper_height - height;
+ break;
+
+ case 1: /* top right portrait */
+ left = paper_width - width;
+ bottom = paper_height - height;
+ break;
+
+ case 2: /* bottom right portrait */
+ left = paper_width - width;
+ bottom = 0.0;
+ break;
+
+ case 3: /* bottom left portrait */
+ left = 0.0;
+ bottom = 0.0;
+ break;
+
+ case 4: /* center portrait */
+ left = paper_width / 2.0 - width / 2.0;
+ bottom = paper_height / 2.0 - height / 2.0;
+ break;
+
+
+ case 8: /* top left landscape */
+ left = 0.0;
+ bottom = paper_width - height;
+ break;
+
+ case 9: /* top right landscape */
+ left = paper_height - width;
+ bottom = paper_width - height;
+ break;
+
+ case 10: /* bottom right landscape */
+ left = paper_height - width;
+ bottom = 0.0;
+ break;
+
+ case 11: /* bottom left landscape */
+ left = 0.0;
+ bottom = 0.0;
+ break;
+
+ case 12: /* center landscape */
+ left = paper_height / 2.0 - width / 2.0;
+ bottom = paper_width / 2.0 - height / 2.0;
+ break;
+ }
+
+
+ if (paper_orientation >= 8) /* rotate with 90 degrees - landscape mode */
+ {
+ degree = 90;
+ position_left = left + paper_bottom_margin;
+ position_bottom = bottom - paper_width - paper_left_margin;
+ box_left = paper_width - paper_left_margin - bottom - height;
+ box_bottom = left + paper_bottom_margin;
+ box_right = box_left + ceil(height);
+ box_top = box_bottom + ceil(width);
+ }
+ else /* do not rotate, portrait mode */
+ {
+ degree = 0;
+ position_left = left + paper_left_margin;
+ position_bottom = bottom + paper_bottom_margin;
+ box_left = left + paper_left_margin;
+ box_bottom = bottom + paper_bottom_margin;
+ box_right = box_left + ceil(width);
+ box_top = box_bottom + ceil(height);
+ }
+
+ depth = image_info->depth;
+
+ if (depth > 8)
+ {
+ depth = 8;
+ }
+
+ fprintf(outfile, "\n");
+ fprintf(outfile, "%%%%Page: %d %d\n", page, page);
+ fprintf(outfile, "%%%%PageBoundingBox: %d %d %d %d\n", box_left, box_bottom, box_right, box_top);
+
+ if (depth == 1)
+ {
+ fprintf(outfile, "/grays %d string def\n", image_info->image_width);
+ fprintf(outfile, "/npixels 0 def\n");
+ fprintf(outfile, "/rgbindx 0 def\n");
+ }
+
+ fprintf(outfile, "%d rotate\n", degree);
+ fprintf(outfile, "%d %d translate\n", position_left, position_bottom);
+ fprintf(outfile, "%f %f scale\n", width, height);
+ fprintf(outfile, "%d %d %d\n", image_info->image_width, image_info->image_height, depth);
+ fprintf(outfile, "[%d %d %d %d %d %d]\n", image_info->image_width, 0, 0, -image_info->image_height, 0, image_info->image_height);
+ fprintf(outfile, "currentfile\n");
+ fprintf(outfile, "/ASCII85Decode filter\n");
+#ifdef HAVE_LIBZ
+ if (flatdecode)
+ {
+ fprintf(outfile, "/FlateDecode filter\n");
+ }
+#endif
+
+ if (image_info->colors == 3) /* what about RGBA here ? */
+ {
+ fprintf(outfile, "false 3 colorimage\n");
+ fprintf(outfile, "\n");
+ }
+ else
+ {
+ fprintf(outfile, "image\n");
+ fprintf(outfile, "\n");
+ }
+}
+
+/* ---------------------------------------------------------------------------------------------------------------------- */
+
+static void xsane_save_ps_create_page_trailer(FILE *outfile)
+{
+ fprintf(outfile, "\n");
+ fprintf(outfile, "showpage\n");
+ fprintf(outfile, "%%%%PageTrailer\n");
+}
+
+/* ---------------------------------------------------------------------------------------------------------------------- */
+
+#ifdef HAVE_LIBZ
+/* Utility function for the PostScript output */
+static int xsane_write_compressed_a85_flatdecode(FILE *outfile, unsigned char *line, int len, int finish)
+{
+ static unsigned char *cbuf = NULL;
+ static int cbuflen = 0;
+ static int linelen = 0;
+ int i, j;
+ int outlen;
+ static int init = 0;
+ static z_stream s;
+ int ret;
+ int flush;
+ static int a85count = 0;
+ static guint32 a85tuple = 0;
+ static unsigned char a85block[6] = {0, 0, 0, 0, 0, 0};
+ static int count = 0;
+
+ DBG(DBG_proc, "xsane_write_compressed_a85_flatdecode\n");
+
+ if (linelen != len)
+ {
+ linelen = len;
+ if (cbuf != NULL)
+ {
+ free(cbuf);
+ }
+ /* buffer length = length + 0.1 * length + 12 (mandatory) */
+ cbuflen = len + len / 10 + 12;
+ cbuf = malloc(cbuflen);
+ }
+
+ if (cbuf == NULL)
+ {
+ DBG(DBG_error, "cbuf allocation failed\n");
+ return 1;
+ }
+
+ if (!init)
+ {
+ s.zalloc = Z_NULL;
+ s.zfree = Z_NULL;
+ s.opaque = Z_NULL;
+
+ ret = deflateInit(&s, Z_DEFAULT_COMPRESSION);
+
+ if (ret != Z_OK)
+ {
+ DBG(DBG_error, "deflateInit failed\n");
+ free(cbuf);
+ return 1;
+ }
+
+ init = 1;
+ }
+
+ s.avail_in = len;
+ s.next_in = line;
+
+ do
+ {
+ s.avail_out = cbuflen;
+ s.next_out = cbuf;
+
+ flush = (finish) ? Z_FINISH : Z_NO_FLUSH;
+
+ ret = deflate(&s, flush);
+
+ if (ret == Z_STREAM_ERROR)
+ {
+ DBG(DBG_error, "deflate failed\n");
+ free(cbuf);
+ return 1;
+ }
+
+ outlen = cbuflen - s.avail_out;
+
+ /* ASCII85 (base 85) encoding */
+ for (i = 0; i < outlen; i++)
+ {
+ switch (a85count)
+ {
+ case 0:
+ a85tuple |= (cbuf[i] << 24);
+ a85count++;
+ break;
+
+ case 1:
+ a85tuple |= (cbuf[i] << 16);
+ a85count++;
+ break;
+
+ case 2:
+ a85tuple |= (cbuf[i] << 8);
+ a85count++;
+ break;
+
+ case 3:
+ a85tuple |= (cbuf[i] << 0);
+
+ if (count == 40)
+ {
+ fprintf(outfile, "\n");
+ count = 0;
+ }
+
+ if (a85tuple == 0)
+ {
+ fprintf(outfile, "z");
+ count++;
+ }
+ else
+ {
+ /* The ASCII chars must be written in reverse order, hence -> a85block[4-j] */
+ for (j = 0; j < 5; j++)
+ {
+ a85block[4-j] = a85tuple % 85 + '!';
+ a85tuple /= 85;
+ }
+
+ for (j = 0; j < 5; j++)
+ {
+ fprintf(outfile, "%c", a85block[j]);
+ count++;
+ if (count == 40)
+ {
+ fprintf(outfile, "\n");
+ count = 0;
+ }
+ }
+ }
+
+ a85count = 0;
+ a85tuple = 0;
+ break;
+
+ default:
+ break;
+ }
+ }
+ } while (s.avail_out == 0);
+
+ if (finish)
+ {
+ DBG(DBG_info, "finish\n");
+ if (a85count > 0)
+ {
+ a85count++;
+ for (j = 0; j <= a85count; j++)
+ {
+ a85block[j] = a85tuple % 85 + '!';
+ a85tuple /= 85;
+ }
+ /* Reverse order */
+ for (j--; j > 0; j--)
+ {
+ if (count == 40)
+ {
+ fprintf(outfile, "\n");
+ count = 0;
+ }
+ fprintf(outfile, "%c", a85block[j]);
+ count++;
+ }
+ }
+
+ /* ASCII85 EOD marker + newline*/
+ if (count + 2 > 40)
+ {
+ fprintf(outfile, "\n");
+ }
+ fprintf(outfile, "~>\n");
+ deflateEnd(&s);
+ free(cbuf);
+ cbuf = NULL;
+ init = 0;
+ a85tuple = 0;
+ a85count = 0;
+ cbuflen = 0;
+ linelen = 0;
+ count = 0;
+ }
+
+ return 0;
+}
+#endif
+
+/* ---------------------------------------------------------------------------------------------------------------------- */
+
+/* Utility function for the PostScript output */
+static int xsane_write_compressed_a85(FILE *outfile, unsigned char *line, int len, int finish)
+{
+ static unsigned char *cbuf = NULL;
+ static int cbuflen = 0;
+ static int linelen = 0;
+ int i, j;
+ int outlen;
+ static int a85count = 0;
+ static guint32 a85tuple = 0;
+ static unsigned char a85block[6] = {0, 0, 0, 0, 0, 0};
+ static int count = 0;
+
+ DBG(DBG_proc, "xsane_write_compressed_a85\n");
+
+ cbuf = line;
+ outlen = len;
+
+ /* ASCII85 (base 85) encoding */
+ for (i = 0; i < outlen; i++)
+ {
+ switch (a85count)
+ {
+ case 0:
+ a85tuple |= (cbuf[i] << 24);
+ a85count++;
+ break;
+
+ case 1:
+ a85tuple |= (cbuf[i] << 16);
+ a85count++;
+ break;
+
+ case 2:
+ a85tuple |= (cbuf[i] << 8);
+ a85count++;
+ break;
+
+ case 3:
+ a85tuple |= (cbuf[i] << 0);
+
+ if (count == 40)
+ {
+ fprintf(outfile, "\n");
+ count = 0;
+ }
+
+ if (a85tuple == 0)
+ {
+ fprintf(outfile, "z");
+ count++;
+ }
+ else
+ {
+ /* The ASCII chars must be written in reverse order, hence -> a85block[4-j] */
+ for (j = 0; j < 5; j++)
+ {
+ a85block[4-j] = a85tuple % 85 + '!';
+ a85tuple /= 85;
+ }
+
+ for (j = 0; j < 5; j++)
+ {
+ fprintf(outfile, "%c", a85block[j]);
+ count++;
+ if (count == 40)
+ {
+ fprintf(outfile, "\n");
+ count = 0;
+ }
+ }
+ }
+
+ a85count = 0;
+ a85tuple = 0;
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ if (finish)
+ {
+ DBG(DBG_info, "finish\n");
+ if (a85count > 0)
+ {
+ a85count++;
+ for (j = 0; j <= a85count; j++)
+ {
+ a85block[j] = a85tuple % 85 + '!';
+ a85tuple /= 85;
+ }
+ /* Reverse order */
+ for (j--; j > 0; j--)
+ {
+ if (count == 40)
+ {
+ fprintf(outfile, "\n");
+ count = 0;
+ }
+ fprintf(outfile, "%c", a85block[j]);
+ count++;
+ }
+ }
+
+ /* ASCII85 EOD marker + newline*/
+ if (count + 2 > 40)
+ {
+ fprintf(outfile, "\n");
+ }
+ fprintf(outfile, "~>\n");
+ a85tuple = 0;
+ a85count = 0;
+ cbuflen = 0;
+ linelen = 0;
+ count = 0;
+ }
+
+ return 0;
+}
+
+/* ---------------------------------------------------------------------------------------------------------------------- */
+
+static int xsane_save_ps_pdf_bw(FILE *outfile, FILE *imagefile, Image_info *image_info, int flatdecode, GtkProgressBar *progress_bar, int *cancel_save)
+{
+ int x, y;
+ int bytes_per_line = (image_info->image_width+7)/8;
+ int ret;
+ unsigned char *line;
+
+ DBG(DBG_proc, "xsane_save_ps_pdf_bw\n");
+
+ *cancel_save = 0;
+
+ line = (unsigned char *) malloc(bytes_per_line);
+
+ if (line == NULL)
+ {
+ char buf[255];
+
+ snprintf(buf, sizeof(buf), "%s malloc failed", ERR_DURING_SAVE);
+ DBG(DBG_error, "%s\n", buf);
+ xsane_back_gtk_decision(ERR_HEADER_ERROR, (gchar **) error_xpm, buf, BUTTON_OK, NULL, TRUE /* wait */);
+ *cancel_save = 1;
+ return (*cancel_save);
+ }
+
+ for (y = 0; y < image_info->image_height; y++)
+ {
+ gtk_progress_bar_update(progress_bar, (float) y / image_info->image_height);
+ while (gtk_events_pending())
+ {
+ gtk_main_iteration();
+ }
+
+ for (x = 0; x < bytes_per_line; x++)
+ {
+ line[x] = fgetc(imagefile) ^ 255;
+ }
+
+#ifdef HAVE_LIBZ
+ if (flatdecode)
+ {
+ ret = xsane_write_compressed_a85_flatdecode(outfile, line, bytes_per_line, (y == image_info->image_height - 1));
+ }
+ else
+#endif
+ {
+ ret = xsane_write_compressed_a85(outfile, line, bytes_per_line, (y == image_info->image_height - 1));
+ }
+
+ if ((ret != 0) || (ferror(outfile)))
+ {
+ char buf[255];
+
+ if (ret == 0)
+ {
+ snprintf(buf, sizeof(buf), "%s %s", ERR_DURING_SAVE, strerror(errno));
+ }
+ else
+ {
+ snprintf(buf, sizeof(buf), "%s %s", ERR_DURING_SAVE, ERR_ZLIB);
+ }
+
+ DBG(DBG_error, "%s\n", buf);
+ xsane_back_gtk_decision(ERR_HEADER_ERROR, (gchar **) error_xpm, buf, BUTTON_OK, NULL, TRUE /* wait */);
+ *cancel_save = 1;
+
+ break;
+ }
+
+ if (*cancel_save)
+ {
+ break;
+ }
+ }
+
+ free(line);
+
+ return (*cancel_save);
+}
+
+/* ---------------------------------------------------------------------------------------------------------------------- */
+
+static int xsane_save_ps_pdf_gray(FILE *outfile, FILE *imagefile, Image_info *image_info, int flatdecode, GtkProgressBar *progress_bar, int *cancel_save)
+{
+ int x, y;
+ int ret;
+ unsigned char *line;
+
+ DBG(DBG_proc, "xsane_save_ps_pdf_gray\n");
+
+ *cancel_save = 0;
+
+ line = (unsigned char *) malloc(image_info->image_width);
+
+ if (line == NULL)
+ {
+ char buf[255];
+
+ snprintf(buf, sizeof(buf), "%s malloc failed", ERR_DURING_SAVE);
+ DBG(DBG_error, "%s\n", buf);
+ xsane_back_gtk_decision(ERR_HEADER_ERROR, (gchar **) error_xpm, buf, BUTTON_OK, NULL, TRUE /* wait */);
+ *cancel_save = 1;
+ return (*cancel_save);
+ }
+
+ for (y = 0; y < image_info->image_height; y++)
+ {
+ if (image_info->depth > 8) /* reduce 16 bit images */
+ {
+ guint16 val;
+
+ for (x = 0; x < image_info->image_width; x++)
+ {
+ fread(&val, 2, 1, imagefile);
+ line[x] = val/256;
+ }
+ }
+ else /* 8 bits/sample */
+ {
+ for (x = 0; x < image_info->image_width; x++)
+ {
+ line[x] = fgetc(imagefile);
+ }
+ }
+
+#ifdef HAVE_LIBZ
+ if (flatdecode)
+ {
+ ret = xsane_write_compressed_a85_flatdecode(outfile, line, image_info->image_width, (y == image_info->image_height - 1));
+ }
+ else
+#endif
+ {
+ ret = xsane_write_compressed_a85(outfile, line, image_info->image_width, (y == image_info->image_height - 1));
+ }
+
+ if ((ret != 0) || (ferror(outfile)))
+ {
+ char buf[255];
+
+ if (ret == 0)
+ {
+ snprintf(buf, sizeof(buf), "%s %s", ERR_DURING_SAVE, strerror(errno));
+ }
+ else
+ {
+ snprintf(buf, sizeof(buf), "%s zlib error or memory allocation problem", ERR_DURING_SAVE);
+ }
+
+ DBG(DBG_error, "%s\n", buf);
+ xsane_back_gtk_decision(ERR_HEADER_ERROR, (gchar **) error_xpm, buf, BUTTON_OK, NULL, TRUE /* wait */);
+ *cancel_save = 1;
+
+ break;
+ }
+
+ gtk_progress_bar_update(progress_bar, (float) y / image_info->image_height);
+ while (gtk_events_pending())
+ {
+ gtk_main_iteration();
+ }
+
+ if (*cancel_save)
+ {
+ break;
+ }
+ }
+
+ free(line);
+
+ return (*cancel_save);
+}
+
+/* ---------------------------------------------------------------------------------------------------------------------- */
+
+static int xsane_save_ps_pdf_color(FILE *outfile, FILE *imagefile, Image_info *image_info, int flatdecode, GtkProgressBar *progress_bar, int *cancel_save)
+{
+ int x, y;
+ int ret;
+ unsigned char *line, *linep;
+
+ DBG(DBG_proc, "xsane_save_ps_pdf_color\n");
+
+ *cancel_save = 0;
+
+ line = (unsigned char *) malloc(image_info->image_width * 3);
+
+ if (line == NULL)
+ {
+ char buf[255];
+
+ snprintf(buf, sizeof(buf), "%s malloc failed", ERR_DURING_SAVE);
+ DBG(DBG_error, "%s\n", buf);
+ xsane_back_gtk_decision(ERR_HEADER_ERROR, (gchar **) error_xpm, buf, BUTTON_OK, NULL, TRUE /* wait */);
+ *cancel_save = 1;
+ return (*cancel_save);
+ }
+
+ for (y = 0; y < image_info->image_height; y++)
+ {
+ gtk_progress_bar_update(progress_bar, (float) y / image_info->image_height);
+ while (gtk_events_pending())
+ {
+ gtk_main_iteration();
+ }
+
+ linep = line;
+
+ if (image_info->depth > 8) /* reduce 16 bit images */
+ {
+ guint16 val;
+
+ for (x = 0; x < image_info->image_width; x++)
+ {
+ fread(&val, 2, 1, imagefile);
+ *linep++ = val/256;
+ fread(&val, 2, 1, imagefile);
+ *linep++ = val/256;
+ fread(&val, 2, 1, imagefile);
+ *linep++ = val/256;
+ }
+ }
+ else /* 8 bits/sample */
+ {
+ for (x = 0; x < image_info->image_width; x++)
+ {
+ *linep++ = fgetc(imagefile);
+ *linep++ = fgetc(imagefile);
+ *linep++ = fgetc(imagefile);
+ }
+ }
+
+#ifdef HAVE_LIBZ
+ if (flatdecode)
+ {
+ ret = xsane_write_compressed_a85_flatdecode(outfile, line, (image_info->image_width * 3), (y == image_info->image_height - 1));
+ }
+ else
+#endif
+ {
+ ret = xsane_write_compressed_a85(outfile, line, (image_info->image_width * 3), (y == image_info->image_height - 1));
+ }
+
+ if ((ret != 0) || (ferror(outfile)))
+ {
+ char buf[255];
+
+ if (ret == 0)
+ {
+ snprintf(buf, sizeof(buf), "%s %s", ERR_DURING_SAVE, strerror(errno));
+ }
+ else
+ {
+ snprintf(buf, sizeof(buf), "%s zlib error or memory allocation problem", ERR_DURING_SAVE);
+ }
+
+ DBG(DBG_error, "%s\n", buf);
+ xsane_back_gtk_decision(ERR_HEADER_ERROR, (gchar **) error_xpm, buf, BUTTON_OK, NULL, TRUE /* wait */);
+ *cancel_save = 1;
+
+ break;
+ }
+
+ if (*cancel_save)
+ {
+ break;
+ }
+ }
+
+ free(line);
+
+ return (*cancel_save);
+}
+
+/* ---------------------------------------------------------------------------------------------------------------------- */
+
+int xsane_save_ps_page(FILE *outfile, int page,
+ FILE *imagefile, Image_info *image_info, float width, float height,
+ int paper_left_margin, int paper_bottom_margin, int paperheight, int paperwidth, int paper_orientation,
+ int flatdecode,
+ GtkProgressBar *progress_bar, int *cancel_save)
+{
+ DBG(DBG_proc, "xsane_save_ps_page\n");
+
+ xsane_save_ps_create_page_header(outfile, page,
+ image_info, width, height,
+ paper_left_margin, paper_bottom_margin, paperheight, paperwidth, paper_orientation,
+ flatdecode,
+ progress_bar);
+
+ if (image_info->colors == 1) /* lineart, halftone, grayscale */
+ {
+ if (image_info->depth == 1) /* lineart, halftone */
+ {
+ xsane_save_ps_pdf_bw(outfile, imagefile, image_info, flatdecode, progress_bar, cancel_save);
+ }
+ else /* grayscale */
+ {
+ xsane_save_ps_pdf_gray(outfile, imagefile, image_info, flatdecode, progress_bar, cancel_save);
+ }
+ }
+ else /* color RGB */
+ {
+ xsane_save_ps_pdf_color(outfile, imagefile, image_info, flatdecode, progress_bar, cancel_save);
+ }
+
+ xsane_save_ps_create_page_trailer(outfile);
+
+ if (ferror(outfile))
+ {
+ char buf[255];
+
+ snprintf(buf, sizeof(buf), "%s %s", ERR_DURING_SAVE, strerror(errno));
+ DBG(DBG_error, "%s\n", buf);
+ xsane_back_gtk_decision(ERR_HEADER_ERROR, (gchar **) error_xpm, buf, BUTTON_OK, NULL, TRUE /* wait */);
+ *cancel_save = 1;
+ }
+
+ return (*cancel_save);
+}
+
+/* ---------------------------------------------------------------------------------------------------------------------- */
+
+int xsane_save_ps(FILE *outfile, FILE *imagefile, Image_info *image_info, float width, float height,
+ int paper_left_margin, int paper_bottom_margin, int paperheight, int paperwidth, int paper_orientation,
+ int flatdecode,
+ GtkProgressBar *progress_bar, int *cancel_save)
+{
+ DBG(DBG_proc, "xsane_save_ps\n");
+
+ *cancel_save = 0;
+
+ xsane_save_ps_create_document_header(outfile, 1 /* pages */, flatdecode);
+
+ xsane_save_ps_page(outfile, 1 /* page */,
+ imagefile, image_info, width, height,
+ paper_left_margin, paper_bottom_margin, paperheight, paperwidth, paper_orientation,
+ flatdecode,
+ progress_bar, cancel_save);
+
+ xsane_save_ps_create_document_trailer(outfile, 0 /* we defined pages at beginning */);
+
+ if (ferror(outfile))
+ {
+ char buf[255];
+
+ snprintf(buf, sizeof(buf), "%s %s", ERR_DURING_SAVE, strerror(errno));
+ DBG(DBG_error, "%s\n", buf);
+ xsane_back_gtk_decision(ERR_HEADER_ERROR, (gchar **) error_xpm, buf, BUTTON_OK, NULL, TRUE /* wait */);
+ *cancel_save = 1;
+ }
+
+ return (*cancel_save);
+}
+
+/* ---------------------------------------------------------------------------------------------------------------------- */
+
+/* The pdf_xref struct holds byte offsets from the beginning of the PDF
+ * file to each object of the PDF file -- used to build the xref table
+ */
+struct pdf_xref
+{
+ unsigned long obj5; /* obj 5 0 */
+ unsigned long obj6; /* obj 6 0 */
+ unsigned long obj7; /* obj 7 0 */
+ unsigned long xref; /* xref table */
+ unsigned long slen; /* length of image stream */
+ unsigned long slenp; /* position of image stream length */
+};
+
+static void xsane_save_pdf_create_header(FILE *outfile, Image_info *image_info,
+ float width, float height,
+ int paper_left_margin, int paper_bottom_margin,
+ int paper_width, int paper_height,
+ int paper_orientation, int flatdecode,
+ GtkProgressBar *progress_bar, struct pdf_xref *xref)
+{
+ int position_left, position_bottom, box_left, box_bottom, box_right, box_top, depth;
+ int left, bottom;
+ float rad;
+
+ DBG(DBG_proc, "xsane_save_pdf_create_header\n");
+
+ switch (paper_orientation)
+ {
+ default:
+ case 0: /* top left portrait */
+ left = 0.0;
+ bottom = paper_height - height;
+ break;
+
+ case 1: /* top right portrait */
+ left = paper_width - width;
+ bottom = paper_height - height;
+ break;
+
+ case 2: /* bottom right portrait */
+ left = paper_width - width;
+ bottom = 0.0;
+ break;
+
+ case 3: /* bottom left portrait */
+ left = 0.0;
+ bottom = 0.0;
+ break;
+
+ case 4: /* center portrait */
+ left = paper_width / 2.0 - width / 2.0;
+ bottom = paper_height / 2.0 - height / 2.0;
+ break;
+
+
+ case 8: /* top left landscape */
+ left = 0.0;
+ bottom = paper_width - height;
+ break;
+
+ case 9: /* top right landscape */
+ left = paper_height - width;
+ bottom = paper_width - height;
+ break;
+
+ case 10: /* bottom right landscape */
+ left = paper_height - width;
+ bottom = 0.0;
+ break;
+
+ case 11: /* bottom left landscape */
+ left = 0.0;
+ bottom = 0.0;
+ break;
+
+ case 12: /* center landscape */
+ left = paper_height / 2.0 - width / 2.0;
+ bottom = paper_width / 2.0 - height / 2.0;
+ break;
+ }
+
+
+ if (paper_orientation >= 8) /* rotate with 90 degrees - landscape mode */
+ {
+ rad = -M_PI_2; /* pi / 2 */
+ position_left = left + paper_bottom_margin;
+ position_bottom = bottom - paper_width - paper_left_margin;
+ box_left = paper_width - paper_left_margin - bottom - height;
+ box_bottom = left + paper_bottom_margin;
+ box_right = box_left + ceil(height);
+ box_top = box_bottom + ceil(width);
+ }
+ else /* do not rotate, portrait mode */
+ {
+ rad = 0;
+ position_left = left + paper_left_margin;
+ position_bottom = bottom + paper_bottom_margin;
+ box_left = left + paper_left_margin;
+ box_bottom = bottom + paper_bottom_margin;
+ box_right = box_left + ceil(width);
+ box_top = box_bottom + ceil(height);
+ }
+
+ depth = image_info->depth;
+
+ if (depth > 8)
+ {
+ depth = 8;
+ }
+
+ fprintf(outfile, "%%PDF-1.4\n");
+ fprintf(outfile, "\n");
+ fprintf(outfile, "1 0 obj\n");
+ fprintf(outfile, " << /Type /Catalog\n");
+ fprintf(outfile, " /Outlines 2 0 R\n");
+ fprintf(outfile, " /Pages 3 0 R\n");
+ fprintf(outfile, " >>\n");
+ fprintf(outfile, "endobj\n");
+ fprintf(outfile, "\n");
+ fprintf(outfile, "2 0 obj\n");
+ fprintf(outfile, " << /Type /Outlines\n");
+ fprintf(outfile, " /Count 0\n");
+ fprintf(outfile, " >>\n");
+ fprintf(outfile, "endobj\n");
+ fprintf(outfile, "\n");
+ fprintf(outfile, "3 0 obj\n");
+ fprintf(outfile, " << /Type /Pages\n");
+ fprintf(outfile, " /Kids [4 0 R]\n");
+ fprintf(outfile, " /Count 1\n");
+ fprintf(outfile, " >>\n");
+ fprintf(outfile, "endobj\n");
+ fprintf(outfile, "\n");
+ fprintf(outfile, "4 0 obj\n");
+ fprintf(outfile, " << /Type /Page\n");
+ fprintf(outfile, " /Parent 3 0 R\n");
+ fprintf(outfile, " /MediaBox [%d %d %d %d]\n", box_left, box_bottom, box_right, box_top);
+ fprintf(outfile, " /Contents 5 0 R\n");
+ fprintf(outfile, " /Resources << /ProcSet 6 0 R >>\n");
+ fprintf(outfile, " >>\n");
+ fprintf(outfile, "endobj\n");
+ fprintf(outfile, "\n");
+
+ /* Offset of object 5, for xref */
+ xref->obj5 = ftell(outfile);
+
+ fprintf(outfile, "5 0 obj\n");
+ fprintf(outfile, " << /Length >>\n");
+
+ /* Position of the stream length, to be written later on */
+ xref->slenp = ftell(outfile) - 15;
+
+ fprintf(outfile, "stream\n");
+
+ /* Start of the stream data */
+ xref->slen = ftell(outfile);
+
+ fprintf(outfile, "q\n");
+ fprintf(outfile, "1 0 0 1 %d %d cm\n", position_left, position_bottom); /* translate */
+ fprintf(outfile, "%f %f -%f %f 0 0 cm\n", cos(rad), sin(rad), sin(rad), cos(rad)); /* rotate */
+ fprintf(outfile, "%f 0 0 %f 0 0 cm\n", width, height); /* scale */
+ fprintf(outfile, "BI\n");
+ fprintf(outfile, " /W %d\n", image_info->image_width);
+ fprintf(outfile, " /H %d\n", image_info->image_height);
+
+ if (image_info->colors == 3) /* what about RGBA here ? */
+ {
+ fprintf(outfile, " /CS /RGB\n");
+ fprintf(outfile, " /BPC %d\n", depth);
+ }
+ else if (image_info->depth == 1) /* BW */
+ {
+ fprintf(outfile, " /CS /G\n");
+ fprintf(outfile, " /BPC 1\n");
+ }
+ else /* gray */
+ {
+ fprintf(outfile, " /CS /G\n");
+ fprintf(outfile, " /BPC 8\n");
+ }
+
+#ifdef HAVE_LIBZ
+ if (flatdecode)
+ {
+ fprintf(outfile, " /F [/A85 /FlateDecode]\n");
+ }
+ else
+ {
+ fprintf(outfile, " /F /A85\n");
+ }
+#else
+ fprintf(outfile, " /F /A85\n");
+#endif
+ fprintf(outfile, "ID\n");
+}
+
+/* ---------------------------------------------------------------------------------------------------------------------- */
+
+int xsane_save_pdf(FILE *outfile, FILE *imagefile, Image_info *image_info, float width, float height,
+ int paper_left_margin, int paper_bottom_margin, int paperheight, int paperwidth, int paper_orientation,
+ int flatdecode,
+ GtkProgressBar *progress_bar, int *cancel_save)
+{
+ struct tm *t;
+ time_t tt;
+ struct pdf_xref xref;
+
+ DBG(DBG_proc, "xsane_save_pdf\n");
+
+ *cancel_save = 0;
+
+ xsane_save_pdf_create_header(outfile, image_info, width, height,
+ paper_left_margin, paper_bottom_margin, paperheight, paperwidth, paper_orientation,
+ flatdecode,
+ progress_bar, &xref);
+
+ if (image_info->colors == 1) /* lineart, halftone, grayscale */
+ {
+ if (image_info->depth == 1) /* lineart, halftone */
+ {
+ xsane_save_ps_pdf_bw(outfile, imagefile, image_info, flatdecode, progress_bar, cancel_save);
+ }
+ else /* grayscale */
+ {
+ xsane_save_ps_pdf_gray(outfile, imagefile, image_info, flatdecode, progress_bar, cancel_save);
+ }
+ }
+ else /* color RGB */
+ {
+ xsane_save_ps_pdf_color(outfile, imagefile, image_info, flatdecode, progress_bar, cancel_save);
+ }
+
+ /* PDF trailer */
+ fprintf(outfile, "EI\n");
+ fprintf(outfile, "Q\n");
+
+ /* Go back and write the length of the stream */
+ xref.slen = ftell(outfile) - xref.slen - 1;
+ fseek(outfile, xref.slenp, SEEK_SET);
+ fprintf(outfile, "%lu", xref.slen);
+ fseek(outfile, 0L, SEEK_END);
+
+ fprintf(outfile, "endstream\n");
+ fprintf(outfile, "endobj\n");
+ fprintf(outfile, "\n");
+
+ /* Offset of object 6, for xref */
+ xref.obj6 = ftell(outfile);
+
+ fprintf(outfile, "6 0 obj\n");
+ fprintf(outfile, " [/PDF]\n");
+ fprintf(outfile, "endobj\n");
+ fprintf(outfile, "\n");
+
+ /* Offset of object 7, for xref */
+ xref.obj7 = ftell(outfile);
+
+ fprintf(outfile, "7 0 obj\n");
+ fprintf(outfile, " << /Title (XSane scanned image)\n");
+ fprintf(outfile, " /Creator (XSane version %s (sane %d.%d) - by Oliver Rauch)\n",
+ VERSION,
+ SANE_VERSION_MAJOR(xsane.sane_backend_versioncode),
+ SANE_VERSION_MINOR(xsane.sane_backend_versioncode));
+ fprintf(outfile, " /Producer (XSane %s)\n", VERSION);
+
+ tt = time(NULL);
+ t = gmtime(&tt);
+
+ fprintf(outfile, " /CreationDate (D:%04d%02d%02d%02d%02d%02d+00'00')\n",
+ 1900 + t->tm_year, t->tm_mon + 1, t->tm_mday, t->tm_hour, t->tm_min, t->tm_sec);
+ fprintf(outfile, " >>\n");
+ fprintf(outfile, "endobj\n");
+ fprintf(outfile, "\n");
+
+ /* Offset of xref, for startxref below */
+ xref.xref = ftell(outfile);
+
+ fprintf(outfile, "xref\n");
+ fprintf(outfile, "0 8\n");
+ fprintf(outfile, "0000000000 65535 f \n");
+ fprintf(outfile, "0000000010 00000 n \n");
+ fprintf(outfile, "0000000094 00000 n \n");
+ fprintf(outfile, "0000000153 00000 n \n");
+ fprintf(outfile, "0000000229 00000 n \n");
+ fprintf(outfile, "%010lu 00000 n \n", xref.obj5);
+ fprintf(outfile, "%010lu 00000 n \n", xref.obj6);
+ fprintf(outfile, "%010lu 00000 n \n", xref.obj7);
+ fprintf(outfile, "\n");
+ fprintf(outfile, "trailer\n");
+ fprintf(outfile, " << /Size 8\n");
+ fprintf(outfile, " /Root 1 0 R\n");
+ fprintf(outfile, " /Info 7 0 R\n");
+ fprintf(outfile, " >>\n");
+ fprintf(outfile, "startxref\n");
+ fprintf(outfile, "%lu\n", xref.xref);
+ fprintf(outfile, "%%%%EOF\n");
+
+ if (ferror(outfile))
+ {
+ char buf[255];
+
+ snprintf(buf, sizeof(buf), "%s %s", ERR_DURING_SAVE, strerror(errno));
+ DBG(DBG_error, "%s\n", buf);
+ xsane_back_gtk_decision(ERR_HEADER_ERROR, (gchar **) error_xpm, buf, BUTTON_OK, NULL, TRUE /* wait */);
+ *cancel_save = 1;
+ }
+
+ return (*cancel_save);
+}
+
+/* ---------------------------------------------------------------------------------------------------------------------- */
+#ifdef HAVE_LIBJPEG
+
+typedef struct
+{
+ struct jpeg_error_mgr pub;/* "public" fields */
+ int *cancel_save;
+} xsane_jpeg_error_mgr;
+
+typedef xsane_jpeg_error_mgr *xsane_jpeg_error_mgr_ptr;
+
+static void xsane_jpeg_error_exit(j_common_ptr cinfo)
+{
+ char buf[256];
+
+ /* cinfo->err points to a xsane_jpeg_error_mgr struct */
+ xsane_jpeg_error_mgr_ptr xsane_jpeg_error_mgr_data = (xsane_jpeg_error_mgr_ptr) cinfo->err;
+
+
+ if (!*xsane_jpeg_error_mgr_data->cancel_save)
+ {
+ /* output original error message */
+ (*cinfo->err->output_message) (cinfo);
+ snprintf(buf, sizeof(buf), "%s %s", ERR_DURING_SAVE, ERR_LIBJPEG);
+ xsane_back_gtk_error(buf, TRUE);
+ }
+
+ *xsane_jpeg_error_mgr_data->cancel_save = 1;
+}
+
+int xsane_save_jpeg(FILE *outfile, FILE *imagefile, Image_info *image_info, int quality, GtkProgressBar *progress_bar, int *cancel_save)
+{
+ unsigned char *data;
+ char buf[256];
+ int components = 1;
+ int x,y;
+ int bytespp = 1;
+ struct jpeg_compress_struct cinfo;
+ xsane_jpeg_error_mgr jerr;
+ JSAMPROW row_pointer[1];
+
+ DBG(DBG_proc, "xsane_save_jpeg\n");
+
+ *cancel_save = 0;
+
+ if (image_info->colors == 3)
+ {
+ components = 3;
+ }
+
+ if (image_info->depth > 8)
+ {
+ bytespp = 2;
+ }
+
+ data = malloc(image_info->image_width * components * bytespp);
+
+ if (!data)
+ {
+ snprintf(buf, sizeof(buf), "%s %s", ERR_DURING_SAVE, ERR_NO_MEM);
+ xsane_back_gtk_error(buf, TRUE);
+ return -1; /* error */
+ }
+
+ cinfo.err = jpeg_std_error(&jerr.pub);
+ jerr.pub.error_exit = xsane_jpeg_error_exit;
+ jerr.cancel_save = cancel_save;
+
+ jpeg_create_compress(&cinfo);
+ jpeg_stdio_dest(&cinfo, outfile);
+ cinfo.image_width = image_info->image_width;
+ cinfo.image_height = image_info->image_height;
+ cinfo.input_components = components;
+ if (image_info->colors == 3)
+ {
+ cinfo.in_color_space = JCS_RGB;
+ }
+ else
+ {
+ cinfo.in_color_space = JCS_GRAYSCALE;
+ }
+ jpeg_set_defaults(&cinfo);
+
+ jpeg_set_quality(&cinfo, quality, TRUE);
+
+ cinfo.density_unit = 1; /* dpi */
+ cinfo.X_density = image_info->resolution_x;
+ cinfo.Y_density = image_info->resolution_y;
+
+ jpeg_start_compress(&cinfo, TRUE);
+
+ for (y = 0; y < image_info->image_height; y++)
+ {
+ gtk_progress_bar_update(progress_bar, (float) y / image_info->image_height);
+ while (gtk_events_pending())
+ {
+ gtk_main_iteration();
+ }
+
+ if (image_info->depth == 1)
+ {
+ int byte = 0;
+ int mask = 128;
+
+ for (x = 0; x < image_info->image_width; x++)
+ {
+
+ if ( (x % 8) == 0)
+ {
+ byte = fgetc(imagefile);
+ mask = 128;
+ }
+
+ if (byte & mask)
+ {
+ data[x] = 0;
+ }
+ else
+ {
+ data[x] = 255;
+ }
+ mask >>= 1;
+ }
+ }
+ else if (image_info->depth > 8) /* jpeg does not support 16 bits/sample, so we reduce it at first */
+ {
+ guint16 *data16 = (guint16 *) data;
+ fread(data, components * 2, image_info->image_width, imagefile);
+ for (x = 0; x < image_info->image_width * components; x++)
+ {
+ data[x] = data16[x] / 256;
+ }
+
+ }
+ else /* 8 bits/sample */
+ {
+ fread(data, components, image_info->image_width, imagefile);
+ }
+
+ row_pointer[0] = data;
+ jpeg_write_scanlines(&cinfo, row_pointer, 1);
+
+ if (*cancel_save)
+ {
+ cinfo.image_height = y; /* correct image height */
+ break;
+ }
+ }
+
+ jpeg_finish_compress(&cinfo);
+ free(data);
+
+ return (*cancel_save);
+}
+#endif
+
+/* ---------------------------------------------------------------------------------------------------------------------- */
+
+#ifdef HAVE_LIBTIFF
+/* pages = 0 => single page tiff, page = 0 */
+/* pages > 0 => page = [1 .. pages] */
+int xsane_save_tiff_page(TIFF *tiffile, int page, int pages, FILE *imagefile, Image_info *image_info, int quality,
+ GtkProgressBar *progress_bar, int *cancel_save)
+{
+ char *data;
+ char buf[256];
+ int y, w;
+ int components;
+ int compression;
+ int bytes;
+ struct tm *ptm;
+ time_t now;
+
+ DBG(DBG_proc, "xsane_save_tiff_page(%d/%d\n", page, pages);
+
+ *cancel_save = 0;
+
+ if (image_info->depth == 1)
+ {
+ compression = preferences.tiff_compression1_nr;
+ }
+ else if (image_info->depth == 8)
+ {
+ compression = preferences.tiff_compression8_nr;
+ }
+ else
+ {
+ compression = preferences.tiff_compression16_nr;
+ }
+
+
+ if (image_info->colors == 3)
+ {
+ components = 3;
+ }
+ else
+ {
+ components = 1;
+ }
+
+ if (image_info->depth <= 8)
+ {
+ bytes = 1;
+ }
+ else
+ {
+ bytes = 2;
+ }
+
+ data = (char *)_TIFFmalloc(image_info->image_width * components * bytes);
+
+ if (!data)
+ {
+ snprintf(buf, sizeof(buf), "%s %s", ERR_DURING_SAVE, ERR_NO_MEM);
+ xsane_back_gtk_error(buf, TRUE);
+ return -1; /* error */
+ }
+
+ TIFFSetField(tiffile, TIFFTAG_IMAGEWIDTH, image_info->image_width);
+ TIFFSetField(tiffile, TIFFTAG_IMAGELENGTH, image_info->image_height);
+ TIFFSetField(tiffile, TIFFTAG_BITSPERSAMPLE, image_info->depth);
+ TIFFSetField(tiffile, TIFFTAG_SAMPLESPERPIXEL, components);
+ TIFFSetField(tiffile, TIFFTAG_ORIENTATION, ORIENTATION_TOPLEFT);
+ TIFFSetField(tiffile, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG);
+ TIFFSetField(tiffile, TIFFTAG_COMPRESSION, compression);
+ TIFFSetField(tiffile, TIFFTAG_SOFTWARE, "xsane");
+
+ time(&now);
+ ptm = localtime(&now);
+ sprintf(buf, "%04d:%02d:%02d %02d:%02d:%02d", 1900+ptm->tm_year, ptm->tm_mon+1, ptm->tm_mday, ptm->tm_hour, ptm->tm_min, ptm->tm_sec);
+ TIFFSetField(tiffile, TIFFTAG_DATETIME, buf);
+
+ if (image_info->resolution_x > 0.0)
+ {
+ TIFFSetField(tiffile, TIFFTAG_RESOLUTIONUNIT, RESUNIT_INCH);
+ TIFFSetField(tiffile, TIFFTAG_XRESOLUTION, image_info->resolution_x);
+ TIFFSetField(tiffile, TIFFTAG_YRESOLUTION, image_info->resolution_y);
+ }
+
+ if (compression == COMPRESSION_JPEG)
+ {
+ TIFFSetField(tiffile, TIFFTAG_JPEGQUALITY, quality);
+ TIFFSetField(tiffile, TIFFTAG_JPEGCOLORMODE, JPEGCOLORMODE_RAW); /* should be default, but to be sure */
+ }
+
+ if (image_info->colors == 3)
+ {
+ TIFFSetField(tiffile, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_RGB);
+ }
+ else
+ {
+ if (image_info->depth == 1) /* lineart */
+ {
+ TIFFSetField(tiffile, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_MINISWHITE);
+ }
+ else /* grayscale */
+ {
+ TIFFSetField(tiffile, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_MINISBLACK);
+ }
+ }
+
+ TIFFSetField(tiffile, TIFFTAG_ROWSPERSTRIP, TIFFDefaultStripSize(tiffile, -1));
+
+ if (pages)
+ {
+ TIFFSetField(tiffile, TIFFTAG_SUBFILETYPE, FILETYPE_PAGE);
+ TIFFSetField(tiffile, TIFFTAG_PAGENUMBER, page, pages);
+ }
+
+ w = TIFFScanlineSize(tiffile);
+
+ for (y = 0; y < image_info->image_height; y++)
+ {
+ gtk_progress_bar_update(progress_bar, (float) y / image_info->image_height);
+ while (gtk_events_pending())
+ {
+ gtk_main_iteration();
+ }
+
+ fread(data, 1, w, imagefile);
+
+ if (TIFFWriteScanline(tiffile, data, y, 0) != 1)
+ {
+ char buf[255];
+
+ snprintf(buf, sizeof(buf), "%s", ERR_DURING_SAVE);
+ DBG(DBG_error, "%s\n", buf);
+ xsane_back_gtk_decision(ERR_HEADER_ERROR, (gchar **) error_xpm, buf, BUTTON_OK, NULL, TRUE /* wait */);
+ *cancel_save = 1;
+ break;
+ }
+
+ if (*cancel_save)
+ {
+ break;
+ }
+ }
+
+ if (pages)
+ {
+ TIFFWriteDirectory(tiffile);
+ }
+
+ _TIFFfree(data);
+ return (*cancel_save);
+}
+#endif
+
+/* ---------------------------------------------------------------------------------------------------------------------- */
+
+#ifdef HAVE_LIBPNG
+#ifdef HAVE_LIBZ
+int xsane_save_png(FILE *outfile, FILE *imagefile, Image_info *image_info, int compression, GtkProgressBar *progress_bar, int *cancel_save)
+{
+ png_structp png_ptr;
+ png_infop png_info_ptr;
+ png_bytep row_ptr;
+ png_color_8 sig_bit;
+ unsigned char *data;
+ char buf[256];
+ int colortype, components, byte_width;
+ int y;
+
+ DBG(DBG_proc, "xsane_save_png\n");
+
+ *cancel_save = 0;
+
+ png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, 0, 0, 0);
+ if (!png_ptr)
+ {
+ snprintf(buf, sizeof(buf), "%s %s", ERR_DURING_SAVE, ERR_LIBPNG);
+ xsane_back_gtk_error(buf, TRUE);
+ return -1; /* error */
+ }
+
+ png_info_ptr = png_create_info_struct(png_ptr);
+ if (!png_info_ptr)
+ {
+ snprintf(buf, sizeof(buf), "%s %s", ERR_DURING_SAVE, ERR_LIBTIFF);
+ xsane_back_gtk_error(buf, TRUE);
+ return -1; /* error */
+ }
+
+ if (setjmp(png_ptr->jmpbuf))
+ {
+ snprintf(buf, sizeof(buf), "%s %s", ERR_DURING_SAVE, ERR_LIBPNG);
+ xsane_back_gtk_error(buf, TRUE);
+ png_destroy_write_struct(&png_ptr, (png_infopp) 0);
+ return -1; /* error */
+ }
+
+ byte_width = image_info->image_width;
+
+ if (image_info->colors == 4) /* RGBA */
+ {
+ components = 4;
+ colortype = PNG_COLOR_TYPE_RGB_ALPHA;
+ }
+ else if (image_info->colors == 3) /* RGB */
+ {
+ components = 3;
+ colortype = PNG_COLOR_TYPE_RGB;
+ }
+ else /* gray or black/white */
+ {
+ components = 1;
+ colortype = PNG_COLOR_TYPE_GRAY;
+ }
+
+ png_init_io(png_ptr, outfile);
+ png_set_compression_level(png_ptr, compression);
+ png_set_IHDR(png_ptr, png_info_ptr, image_info->image_width, image_info->image_height, image_info->depth,
+ colortype, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE);
+
+ if (image_info->colors >=3)
+ {
+ sig_bit.red = image_info->depth;
+ sig_bit.green = image_info->depth;
+ sig_bit.blue = image_info->depth;
+
+ if (image_info->colors == 4)
+ {
+ sig_bit.alpha = image_info->depth;
+ }
+
+ }
+ else
+ {
+ sig_bit.gray = image_info->depth;
+
+ if (image_info->depth == 1)
+ {
+ byte_width = (image_info->image_width+7)/8;
+ png_set_invert_mono(png_ptr);
+ }
+ }
+
+ png_set_sBIT(png_ptr, png_info_ptr, &sig_bit);
+#if defined(PNG_pHYs_SUPPORTED)
+ png_set_pHYs(png_ptr, png_info_ptr,
+ image_info->resolution_x * 100.0 / 2.54,
+ image_info->resolution_y * 100.0 / 2.54, PNG_RESOLUTION_METER);
+#endif
+ png_write_info(png_ptr, png_info_ptr);
+ png_set_shift(png_ptr, &sig_bit);
+
+ data = malloc(image_info->image_width * components);
+
+ if (!data)
+ {
+ snprintf(buf, sizeof(buf), "%s %s", ERR_DURING_SAVE, ERR_NO_MEM);
+ xsane_back_gtk_error(buf, TRUE);
+ png_destroy_write_struct(&png_ptr, (png_infopp) 0);
+ return -1; /* error */
+ }
+
+ for (y = 0; y < image_info->image_height; y++)
+ {
+ gtk_progress_bar_update(progress_bar, (float) y / image_info->image_height);
+ while (gtk_events_pending())
+ {
+ gtk_main_iteration();
+ }
+
+ fread(data, components, byte_width, imagefile);
+
+ row_ptr = data;
+ png_write_rows(png_ptr, &row_ptr, 1); /* errors are caught by test sor setjmp(...) */
+
+ if (*cancel_save)
+ {
+ break;
+ }
+ }
+
+ free(data);
+ png_write_end(png_ptr, png_info_ptr);
+ png_destroy_write_struct(&png_ptr, (png_infopp) 0);
+
+ return (*cancel_save);
+}
+#endif
+#endif
+
+/* ---------------------------------------------------------------------------------------------------------------------- */
+
+#ifdef HAVE_LIBPNG
+#ifdef HAVE_LIBZ
+int xsane_save_png_16(FILE *outfile, FILE *imagefile, Image_info *image_info, int compression, GtkProgressBar *progress_bar, int *cancel_save)
+{
+ png_structp png_ptr;
+ png_infop png_info_ptr;
+ png_bytep row_ptr;
+ png_color_8 sig_bit; /* should be 16, but then I get a warning about wrong type */
+ unsigned char *data;
+ char buf[256];
+ int colortype, components;
+ int x,y;
+ guint16 val;
+
+ DBG(DBG_proc, "xsane_save_png16\n");
+
+ *cancel_save = 0;
+
+ png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, 0, 0, 0);
+ if (!png_ptr)
+ {
+ snprintf(buf, sizeof(buf), "%s %s", ERR_DURING_SAVE, ERR_LIBPNG);
+ xsane_back_gtk_error(buf, TRUE);
+ return -1; /* error */
+ }
+
+ png_info_ptr = png_create_info_struct(png_ptr);
+ if (!png_info_ptr)
+ {
+ snprintf(buf, sizeof(buf), "%s %s", ERR_DURING_SAVE, ERR_LIBPNG);
+ xsane_back_gtk_error(buf, TRUE);
+ return -1; /* error */
+ }
+
+ if (setjmp(png_ptr->jmpbuf))
+ {
+ snprintf(buf, sizeof(buf), "%s %s", ERR_DURING_SAVE, ERR_LIBPNG);
+ xsane_back_gtk_error(buf, TRUE);
+ png_destroy_write_struct(&png_ptr, (png_infopp) 0);
+ return -1; /* error */
+ }
+
+ if (image_info->colors == 4) /* RGBA */
+ {
+ components = 4;
+ colortype = PNG_COLOR_TYPE_RGB_ALPHA;
+ }
+ else if (image_info->colors == 3) /* RGB */
+ {
+ components = 3;
+ colortype = PNG_COLOR_TYPE_RGB;
+ }
+ else /* gray or black/white */
+ {
+ components = 1;
+ colortype = PNG_COLOR_TYPE_GRAY;
+ }
+
+ png_init_io(png_ptr, outfile);
+ png_set_compression_level(png_ptr, compression);
+ png_set_IHDR(png_ptr, png_info_ptr, image_info->image_width, image_info->image_height, 16,
+ colortype, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE);
+
+ sig_bit.red = image_info->depth;
+ sig_bit.green = image_info->depth;
+ sig_bit.blue = image_info->depth;
+ sig_bit.alpha = image_info->depth;
+ sig_bit.gray = image_info->depth;
+
+ png_set_sBIT(png_ptr, png_info_ptr, &sig_bit);
+ png_write_info(png_ptr, png_info_ptr);
+ png_set_shift(png_ptr, &sig_bit);
+ png_set_packing(png_ptr);
+
+ data = malloc(image_info->image_width * components * 2);
+
+ if (!data)
+ {
+ snprintf(buf, sizeof(buf), "%s %s", ERR_DURING_SAVE, ERR_NO_MEM);
+ xsane_back_gtk_error(buf, TRUE);
+ png_destroy_write_struct(&png_ptr, (png_infopp) 0);
+ return -1; /* error */
+ }
+
+ for (y = 0; y < image_info->image_height; y++)
+ {
+ gtk_progress_bar_update(progress_bar, (float) y / image_info->image_height);
+ while (gtk_events_pending())
+ {
+ gtk_main_iteration();
+ }
+
+ for (x = 0; x < image_info->image_width * components; x++) /* this must be changed in dependance of endianess */
+ {
+ fread(&val, 2, 1, imagefile); /* get data in machine order */
+ data[x*2+0] = val / 256; /* write data in network order (MSB first) */
+ data[x*2+1] = val & 255;
+ }
+
+ row_ptr = data;
+ png_write_rows(png_ptr, &row_ptr, 1);
+ if (*cancel_save)
+ {
+ break;
+ }
+ }
+
+ free(data);
+ png_write_end(png_ptr, png_info_ptr);
+ png_destroy_write_struct(&png_ptr, (png_infopp) 0);
+
+ return (*cancel_save);
+}
+#endif
+#endif
+
+/* ---------------------------------------------------------------------------------------------------------------------- */
+
+static int xsane_save_pnm_16_ascii_gray(FILE *outfile, FILE *imagefile, Image_info *image_info, GtkProgressBar *progress_bar, int *cancel_save)
+{
+ int x,y;
+ guint16 val;
+ int count = 0;
+
+ DBG(DBG_proc, "xsane_save_pnm_16_ascii_gray\n");
+
+ *cancel_save = 0;
+
+ for (y = 0; y < image_info->image_height; y++)
+ {
+ for (x = 0; x < image_info->image_width; x++)
+ {
+ fread(&val, 2, 1, imagefile); /* get data in machine order */
+ fprintf(outfile, "%d ", val);
+
+ if (++count >= 10)
+ {
+ fprintf(outfile, "\n");
+ count = 0;
+ }
+ }
+ fprintf(outfile, "\n");
+
+ if (ferror(outfile))
+ {
+ char buf[255];
+
+ snprintf(buf, sizeof(buf), "%s %s", ERR_DURING_SAVE, strerror(errno));
+ DBG(DBG_error, "%s\n", buf);
+ xsane_back_gtk_decision(ERR_HEADER_ERROR, (gchar **) error_xpm, buf, BUTTON_OK, NULL, TRUE /* wait */);
+ *cancel_save = 1;
+ break;
+ }
+
+ count = 0;
+
+ gtk_progress_bar_update(progress_bar, (float) y / image_info->image_height);
+ while (gtk_events_pending())
+ {
+ gtk_main_iteration();
+ }
+ if (*cancel_save)
+ {
+ break;
+ }
+ }
+
+ return (*cancel_save);
+}
+
+/* ---------------------------------------------------------------------------------------------------------------------- */
+
+static int xsane_save_pnm_16_ascii_color(FILE *outfile, FILE *imagefile, Image_info *image_info, GtkProgressBar *progress_bar, int *cancel_save)
+{
+ int x,y;
+ guint16 val;
+ int count = 0;
+
+ DBG(DBG_proc, "xsane_save_pnm_16_ascii_color\n");
+
+ *cancel_save = 0;
+
+ for (y = 0; y < image_info->image_height; y++)
+ {
+ for (x = 0; x < image_info->image_width; x++)
+ {
+ fread(&val, 2, 1, imagefile); /* get data in machine order */
+ fprintf(outfile, "%d ", val);
+
+ fread(&val, 2, 1, imagefile);
+ fprintf(outfile, "%d ", val);
+
+ fread(&val, 2, 1, imagefile);
+ fprintf(outfile, "%d ", val);
+
+ if (++count >= 3)
+ {
+ fprintf(outfile, "\n");
+ count = 0;
+ }
+ }
+ fprintf(outfile, "\n");
+
+ if (ferror(outfile))
+ {
+ char buf[255];
+
+ snprintf(buf, sizeof(buf), "%s %s", ERR_DURING_SAVE, strerror(errno));
+ DBG(DBG_error, "%s\n", buf);
+ xsane_back_gtk_decision(ERR_HEADER_ERROR, (gchar **) error_xpm, buf, BUTTON_OK, NULL, TRUE /* wait */);
+ *cancel_save = 1;
+ break;
+ }
+
+ count = 0;
+
+ gtk_progress_bar_update(progress_bar, (float) y / image_info->image_height);
+ while (gtk_events_pending())
+ {
+ gtk_main_iteration();
+ }
+
+ if (*cancel_save)
+ {
+ break;
+ }
+ }
+
+ return (*cancel_save);
+}
+
+/* ---------------------------------------------------------------------------------------------------------------------- */
+
+static int xsane_save_pnm_16_binary_gray(FILE *outfile, FILE *imagefile, Image_info *image_info, GtkProgressBar *progress_bar, int *cancel_save)
+{
+ int x,y;
+ guint16 val;
+
+ DBG(DBG_proc, "xsane_save_pnm_16_binary_gray\n");
+
+ *cancel_save = 0;
+
+ for (y = 0; y < image_info->image_height; y++)
+ {
+ for (x = 0; x < image_info->image_width; x++)
+ {
+ fread(&val, 2, 1, imagefile); /* get data in machine order */
+ fputc(val / 256, outfile); /* MSB fist */
+ fputc(val & 255, outfile); /* LSB */
+ }
+
+ gtk_progress_bar_update(progress_bar, (float) y / image_info->image_height);
+ while (gtk_events_pending())
+ {
+ gtk_main_iteration();
+ }
+
+ if (ferror(outfile))
+ {
+ char buf[255];
+
+ snprintf(buf, sizeof(buf), "%s %s", ERR_DURING_SAVE, strerror(errno));
+ DBG(DBG_error, "%s\n", buf);
+ xsane_back_gtk_decision(ERR_HEADER_ERROR, (gchar **) error_xpm, buf, BUTTON_OK, NULL, TRUE /* wait */);
+ *cancel_save = 1;
+ break;
+ }
+
+ if (*cancel_save)
+ {
+ break;
+ }
+ }
+
+ return (*cancel_save);
+}
+
+/* ---------------------------------------------------------------------------------------------------------------------- */
+
+static int xsane_save_pnm_16_binary_color(FILE *outfile, FILE *imagefile, Image_info *image_info, GtkProgressBar *progress_bar, int *cancel_save)
+{
+ int x,y;
+ guint16 val;
+
+ DBG(DBG_proc, "xsane_save_pnm_16_binary_color\n");
+
+ *cancel_save = 0;
+
+ for (y = 0; y < image_info->image_height; y++)
+ {
+ for (x = 0; x < image_info->image_width; x++)
+ {
+ /* red */
+ fread(&val, 2, 1, imagefile); /* get data in machine order */
+ fputc(val / 256, outfile); /* MSB fist */
+ fputc(val & 255, outfile); /* LSB */
+
+ /* green */
+ fread(&val, 2, 1, imagefile); /* get data in machine order */
+ fputc(val / 256, outfile); /* MSB fist */
+ fputc(val & 255, outfile); /* LSB */
+
+ /* blue */
+ fread(&val, 2, 1, imagefile); /* get data in machine order */
+ fputc(val / 256, outfile); /* MSB fist */
+ fputc(val & 255, outfile); /* LSB */
+ }
+
+ gtk_progress_bar_update(progress_bar, (float) y / image_info->image_height);
+ while (gtk_events_pending())
+ {
+ gtk_main_iteration();
+ }
+
+
+ if (ferror(outfile))
+ {
+ char buf[255];
+
+ snprintf(buf, sizeof(buf), "%s %s", ERR_DURING_SAVE, strerror(errno));
+ DBG(DBG_error, "%s\n", buf);
+ xsane_back_gtk_decision(ERR_HEADER_ERROR, (gchar **) error_xpm, buf, BUTTON_OK, NULL, TRUE /* wait */);
+ *cancel_save = 1;
+ break;
+ }
+
+ if (*cancel_save)
+ {
+ break;
+ }
+ }
+
+ return (*cancel_save);
+}
+
+/* ---------------------------------------------------------------------------------------------------------------------- */
+
+int xsane_save_pnm_16(FILE *outfile, FILE *imagefile, Image_info *image_info, GtkProgressBar *progress_bar, int *cancel_save)
+{
+ DBG(DBG_proc, "xsane_save_pnm_16\n");
+
+ *cancel_save = 0;
+
+ xsane_write_pnm_header(outfile, image_info, preferences.save_pnm16_as_ascii);
+
+ if (image_info->colors > 1)
+ {
+ if (preferences.save_pnm16_as_ascii)
+ {
+ xsane_save_pnm_16_ascii_color(outfile, imagefile, image_info, progress_bar, cancel_save);
+ }
+ else
+ {
+ xsane_save_pnm_16_binary_color(outfile, imagefile, image_info, progress_bar, cancel_save);
+ }
+ }
+ else
+ {
+ if (preferences.save_pnm16_as_ascii)
+ {
+ xsane_save_pnm_16_ascii_gray(outfile, imagefile, image_info, progress_bar, cancel_save);
+ }
+ else
+ {
+ xsane_save_pnm_16_binary_gray(outfile, imagefile, image_info, progress_bar, cancel_save);
+ }
+ }
+
+ return (*cancel_save);
+}
+
+/* ---------------------------------------------------------------------------------------------------------------------- */
+/* ---------------------------------------------------------------------------------------------------------------------- */
+
+/* 0=ok, <0=error, 1=canceled */
+int xsane_save_image_as_lineart(char *output_filename, char *input_filename, GtkProgressBar *progress_bar, int *cancel_save)
+{
+ FILE *outfile;
+ FILE *infile;
+ char buf[256];
+ Image_info image_info;
+
+ *cancel_save = 0;
+
+ outfile = fopen(output_filename, "wb"); /* b = binary mode for win32 */
+
+ if (outfile == 0)
+ {
+ snprintf(buf, sizeof(buf), "%s `%s': %s", ERR_OPEN_FAILED, output_filename, strerror(errno));
+ xsane_back_gtk_error(buf, TRUE);
+ return -2;
+ }
+
+ infile = fopen(input_filename, "rb"); /* read binary (b for win32) */
+ if (infile == 0)
+ {
+ char buf[256];
+ snprintf(buf, sizeof(buf), "%s `%s': %s", ERR_OPEN_FAILED, input_filename, strerror(errno));
+ xsane_back_gtk_error(buf, TRUE);
+
+ fclose(outfile);
+ remove(output_filename); /* remove already created output file */
+ return -1;
+ }
+
+ xsane_read_pnm_header(infile, &image_info);
+
+ xsane_save_grayscale_image_as_lineart(outfile, infile, &image_info, progress_bar, cancel_save);
+
+ fclose(infile);
+ fclose(outfile);
+
+ if (*cancel_save) /* remove output file if saving has been canceled */
+ {
+ remove(output_filename);
+ }
+
+ return (*cancel_save);
+}
+
+/* ---------------------------------------------------------------------------------------------------------------------- */
+
+int xsane_save_image_as_text(char *output_filename, char *input_filename, GtkProgressBar *progress_bar, int *cancel_save)
+{
+ char *arg[1000];
+ char buf[256];
+ int argnr;
+ pid_t pid;
+ int i;
+ int pipefd[2]; /* for progress communication with gocr */
+ FILE *ocr_progress = NULL;
+
+ DBG(DBG_proc, "xsane_save_image_as_text\n");
+
+ argnr = xsane_parse_options(preferences.ocr_command, arg);
+
+ arg[argnr++] = strdup(preferences.ocr_inputfile_option);
+ arg[argnr++] = strdup(input_filename);
+
+ arg[argnr++] = strdup(preferences.ocr_outputfile_option);
+ arg[argnr++] = strdup(output_filename);
+
+ if (preferences.ocr_use_gui_pipe)
+ {
+ if (!pipe(pipefd)) /* success */
+ {
+ DBG(DBG_info, "xsane_save_image_as_text: created pipe for progress communication\n");
+
+ arg[argnr++] = strdup(preferences.ocr_gui_outfd_option);
+
+ snprintf(buf, sizeof(buf),"%d", pipefd[1]);
+ arg[argnr++] = strdup(buf);
+ }
+ else
+ {
+ DBG(DBG_info, "xsane_save_image_as_text: could not create pipe for progress communication\n");
+ pipefd[0] = 0;
+ pipefd[1] = 0;
+ }
+ }
+ else
+ {
+ DBG(DBG_info, "xsane_save_image_as_text: no pipe for progress communication requested\n");
+ pipefd[0] = 0;
+ pipefd[1] = 0;
+ }
+
+ arg[argnr] = 0;
+
+#ifndef HAVE_OS2_H
+ pid = fork();
+
+ if (pid == 0) /* new process */
+ {
+ FILE *ipc_file = NULL;
+
+ if (xsane.ipc_pipefd[0]) /* did we create the progress pipe? */
+ {
+ close(xsane.ipc_pipefd[0]); /* close reading end of pipe */
+ ipc_file = fdopen(xsane.ipc_pipefd[1], "w");
+ }
+
+ if (pipefd[0]) /* did we create the progress pipe? */
+ {
+ close(pipefd[0]); /* close reading end of pipe */
+ }
+
+ DBG(DBG_info, "trying to change user id for new subprocess:\n");
+ DBG(DBG_info, "old effective uid = %d\n", (int) geteuid());
+ setuid(getuid());
+ DBG(DBG_info, "new effective uid = %d\n", (int) geteuid());
+
+
+ execvp(arg[0], arg); /* does not return if successfully */
+ DBG(DBG_error, "%s %s\n", ERR_FAILED_EXEC_OCR_CMD, preferences.ocr_command);
+
+ /* send error message via IPC pipe to parent process */
+ if (ipc_file)
+ {
+ fprintf(ipc_file, "%s %s:\n%s", ERR_FAILED_EXEC_OCR_CMD, preferences.ocr_command, strerror(errno));
+ fflush(ipc_file); /* make sure message is displayed */
+ fclose(ipc_file);
+ }
+
+ _exit(0); /* do not use exit() here! otherwise gtk gets in trouble */
+ }
+
+#else
+ pid = spawnvp(P_NOWAIT, arg[0], arg);
+ if (pid == -1)
+ {
+ DBG(DBG_error, "%s %s\n", ERR_FAILED_EXEC_OCR_CMD, preferences.ocr_command);
+ }
+#endif
+
+ if (pipefd[1])
+ {
+ close(pipefd[1]); /* close writing end of pipe */
+ ocr_progress = fdopen(pipefd[0], "r"); /* open reading end of pipe as file */
+ }
+
+ for (i=0; i<argnr; i++)
+ {
+ free(arg[i]);
+ }
+
+ if (ocr_progress) /* pipe available */
+ {
+ gtk_progress_bar_update(GTK_PROGRESS_BAR(progress_bar), 0.0);
+
+ while (!feof(ocr_progress))
+ {
+ int progress, subprogress;
+ float fprogress;
+
+ fgets(buf, sizeof(buf), ocr_progress);
+
+ if (!strncmp(preferences.ocr_progress_keyword, buf, strlen(preferences.ocr_progress_keyword)))
+ {
+ sscanf(buf + strlen(preferences.ocr_progress_keyword), "%d %d", &progress, &subprogress);
+
+ snprintf(buf, sizeof(buf), "%s (%d:%d)", PROGRESS_OCR, progress, subprogress);
+ gtk_progress_set_format_string(GTK_PROGRESS(progress_bar), buf);
+
+ fprogress = progress / 100.0;
+
+ if (fprogress < 0.0)
+ {
+ fprogress = 0.0;
+ }
+
+ if (fprogress > 11.0)
+ {
+ fprogress = 1.0;
+ }
+
+ gtk_progress_bar_update(GTK_PROGRESS_BAR(progress_bar), fprogress);
+ }
+
+ while (gtk_events_pending())
+ {
+ gtk_main_iteration();
+ }
+ }
+
+ gtk_progress_set_format_string(GTK_PROGRESS(progress_bar), "");
+ gtk_progress_bar_update(GTK_PROGRESS_BAR(progress_bar), 0.0);
+ }
+ else /* no pipe available */
+ {
+ while (pid)
+ {
+ int status = 0;
+ pid_t pid_status = waitpid(pid, &status, WNOHANG);
+
+ if (pid == pid_status)
+ {
+ pid = 0; /* ok, child process has terminated */
+ }
+
+ while (gtk_events_pending())
+ {
+ gtk_main_iteration();
+ }
+ }
+ }
+
+ if (pipefd[0])
+ {
+ fclose(ocr_progress); /* close reading end of pipe */
+ }
+
+ return (*cancel_save);
+}
+/* ---------------------------------------------------------------------------------------------------------------------- */
+
+/* save image in destination file format. lineart images that are stored as grayscale image are reduced to lineart! */
+int xsane_save_image_as(char *output_filename, char *input_filename, int output_format, GtkProgressBar *progress_bar, int *cancel_save)
+{
+ FILE *outfile;
+ FILE *infile;
+ char buf[256];
+ Image_info image_info;
+ char lineart_filename[PATH_MAX];
+ int remove_input_file = FALSE;
+
+ DBG(DBG_proc, "xsane_save_image_as(output_file=%s, input_file=%s, type=%d)\n", output_filename, input_filename, output_format);
+
+ *cancel_save = 0;
+
+ infile = fopen(input_filename, "rb"); /* read binary (b for win32) */
+ if (infile == 0)
+ {
+ char buf[256];
+ snprintf(buf, sizeof(buf), "%s `%s': %s", ERR_OPEN_FAILED, input_filename, strerror(errno));
+ xsane_back_gtk_error(buf, TRUE);
+
+ return -1;
+ }
+
+ xsane_read_pnm_header(infile, &image_info);
+
+ if ((image_info.reduce_to_lineart) && (output_format != XSANE_PNM))
+ {
+ DBG(DBG_info, "original image is a lineart => reduce to lineart\n");
+ fclose(infile);
+ xsane_back_gtk_make_path(sizeof(lineart_filename), lineart_filename, 0, 0, "xsane-conversion-", xsane.dev_name, ".pbm", XSANE_PATH_TMP);
+
+ snprintf(buf, sizeof(buf), "%s: %s", PROGRESS_PACKING_DATA, output_filename);
+
+ gtk_progress_set_format_string(GTK_PROGRESS(progress_bar), buf);
+ gtk_progress_bar_update(GTK_PROGRESS_BAR(progress_bar), 0.0);
+
+ while (gtk_events_pending())
+ {
+ gtk_main_iteration();
+ }
+
+ xsane_save_image_as_lineart(lineart_filename, input_filename, progress_bar, cancel_save);
+
+ input_filename = lineart_filename;
+ remove_input_file = TRUE;
+
+ infile = fopen(input_filename, "rb"); /* read binary (b for win32) */
+ if (infile == 0)
+ {
+ char buf[256];
+ snprintf(buf, sizeof(buf), "%s `%s': %s", ERR_OPEN_FAILED, input_filename, strerror(errno));
+ xsane_back_gtk_error(buf, TRUE);
+
+ return -1;
+ }
+
+ xsane_read_pnm_header(infile, &image_info);
+ }
+
+ snprintf(buf, sizeof(buf), "%s: %s", PROGRESS_SAVING_DATA, output_filename);
+
+ gtk_progress_set_format_string(GTK_PROGRESS(progress_bar), buf);
+ gtk_progress_bar_update(GTK_PROGRESS_BAR(progress_bar), 0.0);
+
+ while (gtk_events_pending())
+ {
+ gtk_main_iteration();
+ }
+
+
+#ifdef HAVE_LIBTIFF
+ if (output_format == XSANE_TIFF) /* routines that want to have filename for saving */
+ {
+ TIFF *tiffile;
+
+ if (xsane_create_secure_file(output_filename)) /* remove possibly existing symbolic links for security */
+ {
+ snprintf(buf, sizeof(buf), "%s %s %s\n", ERR_DURING_SAVE, ERR_CREATE_SECURE_FILE, output_filename);
+ xsane_back_gtk_error(buf, TRUE);
+ return -1; /* error */
+ }
+
+ tiffile = TIFFOpen(output_filename, "w");
+ if (!tiffile)
+ {
+ snprintf(buf, sizeof(buf), "%s %s %s\n", ERR_DURING_SAVE, ERR_OPEN_FAILED, output_filename);
+ xsane_back_gtk_error(buf, TRUE);
+ return -1; /* error */
+ }
+
+ xsane_save_tiff_page(tiffile, 0, 0, infile, &image_info, preferences.jpeg_quality, progress_bar, cancel_save);
+
+ TIFFClose(tiffile);
+ }
+ else /* routines that want to have filedescriptor for saving */
+#endif /* HAVE_LIBTIFF */
+ {
+ if (xsane_create_secure_file(output_filename)) /* remove possibly existing symbolic links for security */
+ {
+ snprintf(buf, sizeof(buf), "%s %s %s\n", ERR_DURING_SAVE, ERR_CREATE_SECURE_FILE, output_filename);
+ xsane_back_gtk_error(buf, TRUE);
+ return -1; /* error */
+ }
+
+ outfile = fopen(output_filename, "wb"); /* b = binary mode for win32 */
+
+ if (outfile != 0)
+ {
+ switch(output_format)
+ {
+ case XSANE_PNM:
+ if (image_info.reduce_to_lineart)
+ {
+ xsane_save_grayscale_image_as_lineart(outfile, infile, &image_info, progress_bar, cancel_save);
+ }
+ else
+ {
+ xsane_copy_file(outfile, infile, progress_bar, cancel_save);
+ }
+ break;
+
+#ifdef HAVE_LIBJPEG
+ case XSANE_JPEG:
+ xsane_save_jpeg(outfile, infile, &image_info, preferences.jpeg_quality, progress_bar, cancel_save);
+ break; /* switch format == XSANE_JPEG */
+#endif
+
+#ifdef HAVE_LIBPNG
+#ifdef HAVE_LIBZ
+ case XSANE_PNG:
+ if (image_info.depth <= 8)
+ {
+ xsane_save_png(outfile, infile, &image_info, preferences.png_compression, progress_bar, cancel_save);
+ }
+ else
+ {
+ xsane_save_png_16(outfile, infile, &image_info, preferences.png_compression, progress_bar, cancel_save);
+ }
+ break; /* switch format == XSANE_PNG */
+#endif
+#endif
+
+ case XSANE_PNM16:
+ xsane_save_pnm_16(outfile, infile, &image_info, progress_bar, cancel_save);
+ break; /* switch fomat == XSANE_PNM16 */
+
+ case XSANE_PS: /* save postscript, use original size */
+ {
+ float imagewidth, imageheight;
+
+ imagewidth = 72.0 * image_info.image_width/image_info.resolution_x; /* width in 1/72 inch */
+ imageheight = 72.0 * image_info.image_height/image_info.resolution_y; /* height in 1/72 inch */
+
+ xsane_save_ps(outfile, infile,
+ &image_info,
+ imagewidth, imageheight,
+ 0, /* paper_left_margin */
+ 0, /* paper_bottom_margin */
+ (int) imagewidth, /* paper_width */
+ (int) imageheight, /* paper_height */
+ 0 /* portrait top left */,
+ preferences.save_ps_flatdecoded,
+ progress_bar,
+ cancel_save);
+ }
+ break; /* switch format == XSANE_PS */
+
+ case XSANE_PDF: /* save PDF, use original size */
+ {
+ float imagewidth, imageheight;
+
+ imagewidth = 72.0 * image_info.image_width/image_info.resolution_x; /* width in 1/72 inch */
+ imageheight = 72.0 * image_info.image_height/image_info.resolution_y; /* height in 1/72 inch */
+
+ xsane_save_pdf(outfile, infile,
+ &image_info,
+ imagewidth, imageheight,
+ 0, /* paper_left_margin */
+ 0, /* paper_bottom_margin */
+ (int) imagewidth, /* paper_width */
+ (int) imageheight, /* paper_height */
+ 0 /* portrait top left */,
+ preferences.save_pdf_flatdecoded,
+ progress_bar,
+ cancel_save);
+ }
+ break; /* switch format == XSANE_PDF */
+
+ case XSANE_TEXT: /* save as text using ocr program like gocr/jocr */
+ {
+ xsane_save_image_as_text(output_filename, input_filename, progress_bar, cancel_save);
+ }
+ break; /* switch format == XSANE_TEXT */
+
+ default:
+ snprintf(buf, sizeof(buf),"%s", ERR_UNKNOWN_SAVING_FORMAT);
+ xsane_back_gtk_error(buf, TRUE);
+
+ fclose(outfile);
+ fclose(infile);
+
+ remove(output_filename); /* no usable output: remove output file */
+
+ if (remove_input_file)
+ {
+ remove(input_filename); /* remove lineart pbm file */
+ }
+
+ gtk_progress_set_format_string(GTK_PROGRESS(progress_bar), "");
+ gtk_progress_bar_update(GTK_PROGRESS_BAR(progress_bar), 0.0);
+
+ while (gtk_events_pending())
+ {
+ gtk_main_iteration();
+ }
+
+ return -2;
+ break; /* switch format == default */
+ }
+ fclose(outfile);
+ }
+ else
+ {
+ snprintf(buf, sizeof(buf), "%s `%s': %s", ERR_OPEN_FAILED, output_filename, strerror(errno));
+ xsane_back_gtk_error(buf, TRUE);
+
+ fclose(infile);
+
+ if (remove_input_file)
+ {
+ remove(input_filename); /* remove lineart pbm file */
+ }
+
+ gtk_progress_set_format_string(GTK_PROGRESS(progress_bar), "");
+ gtk_progress_bar_update(GTK_PROGRESS_BAR(progress_bar), 0.0);
+
+ while (gtk_events_pending())
+ {
+ gtk_main_iteration();
+ }
+
+ return -2;
+ }
+ }
+
+ fclose (infile);
+
+ if (remove_input_file)
+ {
+ remove(input_filename); /* remove lineart pbm file */
+ }
+
+ if (*cancel_save) /* remove output file if saving has been canceled */
+ {
+ remove(output_filename);
+ }
+
+ gtk_progress_set_format_string(GTK_PROGRESS(progress_bar), "");
+ gtk_progress_bar_update(GTK_PROGRESS_BAR(progress_bar), 0.0);
+
+ while (gtk_events_pending())
+ {
+ gtk_main_iteration();
+ }
+
+ return (*cancel_save);
+}
+
+/* ---------------------------------------------------------------------------------------------------------------------- */
+/* ---------------------------------------------------------------------------------------------------------------------- */
+/* ---------------------------------------------------------------------------------------------------------------------- */
+/* ---------------------------------------------------------------------------------------------------------------------- */
+
+#ifdef HAVE_ANY_GIMP
+static int xsane_decode_devname(const char *encoded_devname, int n, char *buf)
+{
+ char *dst, *limit;
+ const char *src;
+ char ch, val;
+
+ DBG(DBG_proc, "xsane_decode_devname\n");
+
+ limit = buf + n;
+ for (src = encoded_devname, dst = buf; *src; ++dst)
+ {
+ if (dst >= limit)
+ {
+ return -1;
+ }
+
+ ch = *src++;
+ /* don't use the ctype.h macros here since we don't want to allow anything non-ASCII here... */
+ if (ch != '-')
+ {
+ *dst = ch;
+ }
+ else /* decode */
+ {
+ ch = *src++;
+ if (ch == '-')
+ {
+ *dst = ch;
+ }
+ else
+ {
+ if (ch >= 'a' && ch <= 'f')
+ {
+ val = (ch - 'a') + 10;
+ }
+ else
+ {
+ val = (ch - '0');
+ }
+ val <<= 4;
+
+ ch = *src++;
+ if (ch >= 'a' && ch <= 'f')
+ {
+ val |= (ch - 'a') + 10;
+ }
+ else
+ {
+ val |= (ch - '0');
+ }
+
+ *dst = val;
+
+ ++src; /* simply skip terminating '-' for now... */
+ }
+ }
+ }
+
+ if (dst >= limit)
+ {
+ return -1;
+ }
+
+ *dst = '\0';
+ return 0;
+}
+
+/* ---------------------------------------------------------------------------------------------------------------------- */
+
+static int xsane_encode_devname(const char *devname, int n, char *buf)
+{
+ static const char hexdigit[] = "0123456789abcdef";
+ char *dst, *limit;
+ const char *src;
+ char ch;
+
+ DBG(DBG_proc, "xsane_encode_devname\n");
+
+ limit = buf + n;
+ for (src = devname, dst = buf; *src; ++src)
+ {
+ if (dst >= limit)
+ {
+ return -1;
+ }
+
+ ch = *src;
+ /* don't use the ctype.h macros here since we don't want to allow anything non-ASCII here... */
+ if ((ch >= '0' && ch <= '9') || (ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z'))
+ {
+ *dst++ = ch;
+ }
+ else /* encode */
+ {
+ if (dst + 4 >= limit)
+ {
+ return -1;
+ }
+
+ *dst++ = '-';
+ if (ch == '-')
+ {
+ *dst++ = '-';
+ }
+ else
+ {
+ *dst++ = hexdigit[(ch >> 4) & 0x0f];
+ *dst++ = hexdigit[(ch >> 0) & 0x0f];
+ *dst++ = '-';
+ }
+ }
+ }
+
+ if (dst >= limit)
+ {
+ return -1;
+ }
+
+ *dst = '\0';
+ return 0;
+}
+
+/* ---------------------------------------------------------------------------------------------------------------------- */
+
+static void xsane_gimp_query(void)
+{
+ static GimpParamDef args[] =
+ {
+ {GIMP_PDB_INT32, "run_mode", "Interactive, non-interactive"},
+ };
+ static GimpParamDef *return_vals = NULL;
+ static int nargs = sizeof(args) / sizeof(args[0]);
+ static int nreturn_vals = 0;
+ char mpath[1024];
+ char name[1024];
+ size_t len;
+ int i, j;
+
+ DBG(DBG_proc, "xsane_gimp_query\n");
+
+ snprintf(name, sizeof(name), "%s", xsane.prog_name);
+#ifdef GIMP_CHECK_VERSION
+# if GIMP_CHECK_VERSION(1,1,9)
+ snprintf(mpath, sizeof(mpath), "%s", XSANE_GIMP_MENU_DIALOG);
+# else
+ snprintf(mpath, sizeof(mpath), "%s", XSANE_GIMP_MENU_DIALOG_OLD);
+# endif
+#else
+ snprintf(mpath, sizeof(mpath), "%s", XSANE_GIMP_MENU_DIALOG_OLD);
+#endif
+ gimp_install_procedure(name,
+ XSANE_GIMP_INSTALL_BLURB,
+ XSANE_GIMP_INSTALL_HELP,
+ XSANE_AUTHOR,
+ XSANE_COPYRIGHT,
+ XSANE_DATE,
+ mpath,
+ 0, /* "RGB, GRAY", */
+ GIMP_EXTENSION,
+ nargs, nreturn_vals,
+ args, return_vals);
+
+ sane_init(&xsane.sane_backend_versioncode, (void *) xsane_authorization_callback);
+ if (SANE_VERSION_MAJOR(xsane.sane_backend_versioncode) != SANE_V_MAJOR)
+ {
+ DBG(DBG_error0, "\n\n"
+ "%s %s:\n"
+ " %s\n"
+ " %s %d\n"
+ " %s %d\n"
+ "%s\n\n",
+ xsane.prog_name, ERR_ERROR,
+ ERR_MAJOR_VERSION_NR_CONFLICT,
+ ERR_XSANE_MAJOR_VERSION, SANE_V_MAJOR,
+ ERR_BACKEND_MAJOR_VERSION, SANE_VERSION_MAJOR(xsane.sane_backend_versioncode),
+ ERR_PROGRAM_ABORTED);
+ return;
+ }
+
+ sane_get_devices(&xsane.devlist, SANE_FALSE);
+
+ for (i = 0; xsane.devlist[i]; ++i)
+ {
+ snprintf(name, sizeof(name), "%s-", xsane.prog_name);
+ if (xsane_encode_devname(xsane.devlist[i]->name, sizeof(name) - 6, name + 6) < 0)
+ {
+ continue; /* name too long... */
+ }
+
+#ifdef GIMP_CHECK_VERSION
+# if GIMP_CHECK_VERSION(1,1,9)
+ snprintf(mpath, sizeof(mpath), "%s", XSANE_GIMP_MENU);
+# else
+ snprintf(mpath, sizeof(mpath), "%s", XSANE_GIMP_MENU_OLD);
+# endif
+#else
+ snprintf(mpath, sizeof(mpath), "%s", XSANE_GIMP_MENU_OLD);
+#endif
+ len = strlen(mpath);
+ for (j = 0; xsane.devlist[i]->name[j]; ++j)
+ {
+ if (xsane.devlist[i]->name[j] == '/')
+ {
+ mpath[len++] = '\'';
+ }
+ else
+ {
+ mpath[len++] = xsane.devlist[i]->name[j];
+ }
+ }
+ mpath[len++] = '\0';
+
+ gimp_install_procedure(name,
+ XSANE_GIMP_INSTALL_BLURB,
+ XSANE_GIMP_INSTALL_HELP,
+ XSANE_AUTHOR,
+ XSANE_COPYRIGHT,
+ XSANE_DATE,
+ mpath,
+ 0, /* "RGB, GRAY", */
+ GIMP_EXTENSION,
+ nargs, nreturn_vals,
+ args, return_vals);
+ }
+
+ sane_exit();
+}
+
+/* ---------------------------------------------------------------------------------------------------------------------- */
+
+#ifdef HAVE_GIMP_2
+static void xsane_gimp_run(const gchar *name, gint nparams, const GimpParam *param, gint *nreturn_vals, GimpParam **return_vals)
+{
+ GimpRunMode run_mode;
+#else /* GIMP-1.x */
+static void xsane_gimp_run(char *name, int nparams, GimpParam *param, int *nreturn_vals, GimpParam **return_vals)
+{
+ GimpRunModeType run_mode;
+#endif
+
+ static GimpParam values[2];
+ char devname[1024];
+ char *args[2];
+ int nargs;
+
+ DBG(DBG_proc, "xsane_gimp_run\n");
+
+ run_mode = param[0].data.d_int32;
+ xsane.mode = XSANE_GIMP_EXTENSION;
+ xsane.xsane_mode = XSANE_SAVE;
+
+ *nreturn_vals = 1;
+ *return_vals = values;
+
+ values[0].type = GIMP_PDB_STATUS;
+ values[0].data.d_status = GIMP_PDB_CALLING_ERROR;
+
+ nargs = 0;
+ args[nargs++] = "xsane";
+
+ xsane.selected_dev = -1;
+ if (strncmp(name, "xsane-", 6) == 0)
+ {
+ if (xsane_decode_devname(name + 6, sizeof(devname), devname) < 0)
+ {
+ return; /* name too long */
+ }
+ args[nargs++] = devname;
+ }
+
+ switch (run_mode)
+ {
+ case GIMP_RUN_INTERACTIVE:
+#ifdef HAVE_GIMP_2
+ gimp_extension_ack();
+#endif
+ xsane_interface(nargs, args);
+ values[0].data.d_status = GIMP_PDB_SUCCESS;
+ break;
+
+ case GIMP_RUN_NONINTERACTIVE:
+ /* Make sure all the arguments are there! */
+ break;
+
+ case GIMP_RUN_WITH_LAST_VALS:
+ /* Possibly retrieve data */
+ break;
+
+ default:
+ break;
+ }
+}
+
+/* ---------------------------------------------------------------------------------------------------------------------- */
+
+void null_print_func(gchar *msg)
+{
+}
+
+/* ---------------------------------------------------------------------------------------------------------------------- */
+
+int xsane_transfer_to_gimp(char *input_filename, GtkProgressBar *progress_bar, int *cancel_save)
+{
+ int remaining;
+ size_t tile_size;
+ GimpImageType image_type = GIMP_GRAY;
+ GimpImageType drawable_type = GIMP_GRAY_IMAGE;
+ gint32 layer_ID;
+ gint32 image_ID;
+ GimpDrawable *drawable;
+ guchar *tile;
+ GimpPixelRgn region;
+ unsigned tile_offset;
+ int i, x, y;
+ Image_info image_info;
+ FILE *imagefile;
+
+ DBG(DBG_info, "xsane_transer_to_gimp\n");
+
+ *cancel_save = 0;
+
+ imagefile = fopen(input_filename, "rb"); /* read binary (b for win32) */
+ if (imagefile == 0)
+ {
+ char buf[256];
+ snprintf(buf, sizeof(buf), "%s `%s': %s", ERR_OPEN_FAILED, input_filename, strerror(errno));
+ xsane_back_gtk_error(buf, TRUE);
+
+ return -1;
+ }
+
+ xsane_read_pnm_header(imagefile, &image_info);
+
+ x = 0;
+ y = 0;
+ tile_offset = 0;
+ tile_size = image_info.image_width * gimp_tile_height();
+
+ if (image_info.colors == 3) /* RGB */
+ {
+ tile_size *= 3; /* 24 bits/pixel RGB */
+ image_type = GIMP_RGB;
+ drawable_type = GIMP_RGB_IMAGE;
+ }
+ else if (image_info.colors == 4) /* RGBA */
+ {
+ tile_size *= 4; /* 32 bits/pixel RGBA */
+ image_type = GIMP_RGB;
+ drawable_type = GIMP_RGBA_IMAGE; /* interpret infrared as alpha */
+ }
+ /* colors == 0/1 is predefined */
+
+ image_ID = gimp_image_new(image_info.image_width, image_info.image_height, image_type);
+
+/* the following is supported since gimp-1.1.? */
+#ifdef GIMP_HAVE_RESOLUTION_INFO
+ if (image_info.resolution_x > 0)
+ {
+ gimp_image_set_resolution(image_ID, image_info.resolution_x, image_info.resolution_y);
+ }
+/* gimp_image_set_unit(image_ID, unit?); */
+#endif
+
+ layer_ID = gimp_layer_new(image_ID, "Background", image_info.image_width, image_info.image_height, drawable_type, 100.0, GIMP_NORMAL_MODE);
+ gimp_image_add_layer(image_ID, layer_ID, 0);
+ drawable = gimp_drawable_get(layer_ID);
+ gimp_pixel_rgn_init(&region, drawable, 0, 0, drawable->width, drawable->height, TRUE, FALSE);
+ tile = g_new(guchar, tile_size);
+
+
+ if (image_info.colors == 1) /* gray */
+ {
+ switch (image_info.depth)
+ {
+ case 1: /* 1 bit gray => conversion to 8 bit gray */
+ for (i = 0; i < ( (image_info.image_width + 7) / 8) * image_info.image_height; ++i)
+ {
+ u_char mask;
+ int j;
+
+ mask = fgetc(imagefile);
+ for (j = 7; j >= 0; --j)
+ {
+ u_char gl = (mask & (1 << j)) ? 0x00 : 0xff;
+ tile[tile_offset++] = gl;
+
+ x++;
+
+ if (x >= image_info.image_width)
+ {
+ int tile_height = gimp_tile_height();
+
+ x = 0;
+ y++;
+
+ if (y % tile_height == 0)
+ {
+ gimp_pixel_rgn_set_rect(&region, tile, 0, y - tile_height, image_info.image_width, tile_height);
+ tile_offset = 0;
+ }
+
+ gtk_progress_bar_update(progress_bar, (float) y / image_info.image_height); /* update progress bar */
+ while (gtk_events_pending())
+ {
+ gtk_main_iteration();
+ }
+
+ break; /* leave for j loop */
+ }
+ }
+
+ if (*cancel_save)
+ {
+ break;
+ }
+ }
+ break; /* leave switch depth 1 */
+
+ case 8: /* 8 bit gray */
+ case 16: /* 16 bit gray already has been reduced to 8 bit */
+ for (i = 0; i < image_info.image_width * image_info.image_height; ++i)
+ {
+ tile[tile_offset++] = fgetc(imagefile);
+ x++;
+
+ if (x >= image_info.image_width)
+ {
+ int tile_height = gimp_tile_height();
+
+ x = 0;
+ y++;
+
+ if (y % tile_height == 0)
+ {
+ gimp_pixel_rgn_set_rect(&region, tile, 0, y - tile_height, image_info.image_width, tile_height);
+ tile_offset = 0;
+ }
+
+ gtk_progress_bar_update(progress_bar, (float) y / image_info.image_height); /* update progress bar */
+ while (gtk_events_pending())
+ {
+ gtk_main_iteration();
+ }
+ }
+
+ if (*cancel_save)
+ {
+ break;
+ }
+ }
+ break; /* leave switch depth */
+
+ default: /* bad depth */
+ break; /* default */
+ }
+ }
+ else if (image_info.colors == 3) /* RGB */
+ {
+ switch (image_info.depth)
+ {
+ case 8: /* 8 bit RGB */
+ case 16: /* 16 bit RGB already has been reduced to 8 bit */
+ for (i = 0; i < image_info.image_width * image_info.image_height*3; ++i)
+ {
+ tile[tile_offset++] = fgetc(imagefile);
+ if (tile_offset % 3 == 0)
+ {
+ x++;
+
+ if (x >= image_info.image_width)
+ {
+ int tile_height = gimp_tile_height();
+
+ x = 0;
+ y++;
+
+ if (y % tile_height == 0)
+ {
+ gimp_pixel_rgn_set_rect(&region, tile, 0, y - tile_height, image_info.image_width, tile_height);
+ tile_offset = 0;
+ }
+
+ gtk_progress_bar_update(progress_bar, (float) y / image_info.image_height); /* update progress bar */
+ while (gtk_events_pending())
+ {
+ gtk_main_iteration();
+ }
+ }
+ }
+
+ if (*cancel_save)
+ {
+ break;
+ }
+ }
+ break; /* case 8 */
+
+ default: /* bad depth */
+ break; /* default */
+ }
+ }
+#ifdef SUPPORT_RGBA
+ else if (image_info.colors == 4) /* RGBA */
+ {
+ int i;
+
+ switch (image_info.depth)
+ {
+ case 8: /* 8 bit RGBA */
+ case 16: /* 16 bit RGBA already has been reduced to 8 bit */
+ for (i = 0; i < image_info.image_width * image_info.image_height * 4; ++i)
+ {
+ tile[tile_offset++] = fgetc(imagefile);
+ if (tile_offset % 4 == 0)
+ {
+ x++;
+
+ if (x >= image_info.image_width)
+ {
+ int tile_height = gimp_tile_height();
+
+ x = 0;
+ y++;
+
+ if (y % tile_height == 0)
+ {
+ gimp_pixel_rgn_set_rect(&region, tile, 0, y - tile_height, image_info.image_width, tile_height);
+ tile_offset = 0;
+ }
+
+ gtk_progress_bar_update(progress_bar, (float) y / image_info.image_height); /* update progress bar */
+ while (gtk_events_pending())
+ {
+ gtk_main_iteration();
+ }
+ }
+ }
+
+ if (*cancel_save)
+ {
+ break;
+ }
+ }
+ break;
+
+ default: /* bad depth */
+ break;
+ }
+ }
+#endif
+
+/* scan_done part */
+ if (y > image_info.image_height)
+ {
+ y = image_info.image_height;
+ }
+
+ remaining = y % gimp_tile_height();
+
+ if (remaining)
+ {
+ gimp_pixel_rgn_set_rect(&region, tile, 0, y - remaining, image_info.image_width, remaining);
+ }
+
+ gimp_drawable_flush(drawable);
+ gimp_display_new(image_ID);
+ gimp_drawable_detach(drawable);
+ g_free(tile);
+ tile = 0;
+
+ fclose(imagefile);
+
+ return 0;
+}
+#endif /* HAVE_ANY_GIMP */
+
+/* ---------------------------------------------------------------------------------------------------------------------- */
+/* ---------------------------------------------------------------------------------------------------------------------- */
+/* ---------------------------------------------------------------------------------------------------------------------- */
+/* ---------------------------------------------------------------------------------------------------------------------- */
+
+#ifdef XSANE_ACTIVATE_MAIL
+
+/* character base of base64 coding */
+static const char base64[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
+
+/* ---------------------------------------------------------------------------------------------------------------------- */
+
+static void write_3chars_as_base64(unsigned char c1, unsigned char c2, unsigned char c3, int pads, int fd_socket)
+{
+ char buf[4];
+
+ buf[0] = base64[c1>>2]; /* wirte bits 7-2 of first char */
+ buf[1] = base64[((c1 & 0x3)<< 4) | ((c2 & 0xF0) >> 4)]; /* write bits 1,0 of first and bits 7-4 of second char */
+
+ if (pads == 2) /* only one byte used */
+ {
+ buf[2] = '='; /* char not used */
+ buf[3] = '='; /* char not used */
+ }
+ else if (pads) /* only two bytes used */
+ {
+ buf[2] = base64[((c2 & 0xF) << 2)]; /* write bits 3-0 of second char */
+ buf[3] = '='; /* char not used */
+ }
+ else
+ {
+ buf[2] = base64[((c2 & 0xF) << 2) | ((c3 & 0xC0) >>6)]; /* write bits 3-0 of second and bits 7,6 of third char */
+ buf[3] = base64[c3 & 0x3F]; /* write bits 5-0 of third char as lsb */
+ }
+
+ write(fd_socket, buf, 4);
+}
+
+/* ---------------------------------------------------------------------------------------------------------------------- */
+
+void write_base64(int fd_socket, FILE *infile)
+{
+ int c1, c2, c3;
+ int pos = 0;
+
+ while ((c1 = getc(infile)) != EOF)
+ {
+ c2 = getc(infile);
+ if (c2 == EOF)
+ {
+ write_3chars_as_base64(c1, 0, 0, 2, fd_socket);
+ }
+ else
+ {
+ c3 = getc(infile);
+ if (c3 == EOF)
+ {
+ write_3chars_as_base64(c1, c2, 0, 1, fd_socket);
+ }
+ else
+ {
+ write_3chars_as_base64(c1, c2, c3, 0, fd_socket);
+ }
+ }
+
+ pos += 4;
+ if (pos > 71)
+ {
+ write(fd_socket, "\n", 1);
+
+ pos = 0;
+ }
+
+ xsane.mail_progress_bytes += 3;
+ if ((int) ((xsane.mail_progress_bytes * 100) / xsane.mail_progress_size) != (int) (xsane.mail_progress_val * 100))
+ {
+ xsane.mail_progress_val = (float) xsane.mail_progress_bytes / xsane.mail_progress_size;
+ xsane_front_gtk_mail_project_update_lockfile_status();
+ }
+ }
+
+ if (pos)
+ {
+ write(fd_socket, "\n", 1);
+ }
+
+ xsane.mail_progress_val = 1.0;
+ xsane_front_gtk_mail_project_update_lockfile_status();
+}
+
+/* ---------------------------------------------------------------------------------------------------------------------- */
+
+void write_mail_header(int fd_socket, char *from, char *reply_to, char *to, char *subject, char *boundary, int related)
+{
+ char buf[1024];
+
+ snprintf(buf, sizeof(buf), "From: %s\n", from);
+ write(fd_socket, buf, strlen(buf));
+
+ snprintf(buf, sizeof(buf), "Reply-To: %s\n", reply_to);
+ write(fd_socket, buf, strlen(buf));
+
+ snprintf(buf, sizeof(buf), "To: %s\n", to);
+ write(fd_socket, buf, strlen(buf));
+
+ snprintf(buf, sizeof(buf), "Subject: %s\n", subject);
+ write(fd_socket, buf, strlen(buf));
+
+ snprintf(buf, sizeof(buf), "MIME-Version: 1.0\n");
+ write(fd_socket, buf, strlen(buf));
+
+ if (related) /* related means that we need a special link in the html part to display the image */
+ {
+ snprintf(buf, sizeof(buf), "Content-Type: multipart/related;\n");
+ write(fd_socket, buf, strlen(buf));
+ }
+ else
+ {
+ snprintf(buf, sizeof(buf), "Content-Type: multipart/mixed;\n");
+ write(fd_socket, buf, strlen(buf));
+ }
+
+ snprintf(buf, sizeof(buf), " boundary=\"%s\"\n\n", boundary);
+ write(fd_socket, buf, strlen(buf));
+}
+
+/* ---------------------------------------------------------------------------------------------------------------------- */
+
+void write_mail_footer(int fd_socket, char *boundary)
+{
+ char buf[1024];
+
+ snprintf(buf, sizeof(buf), "--%s--\n", boundary);
+ write(fd_socket, buf, strlen(buf));
+}
+
+/* ---------------------------------------------------------------------------------------------------------------------- */
+
+void write_mail_mime_ascii(int fd_socket, char *boundary)
+{
+ char buf[1024];
+
+ snprintf(buf, sizeof(buf), "--%s\n", boundary);
+ write(fd_socket, buf, strlen(buf));
+
+ snprintf(buf, sizeof(buf), "Content-Type: text/plain;\n");
+ write(fd_socket, buf, strlen(buf));
+
+ snprintf(buf, sizeof(buf), " charset=\"iso-8859-1\"\n");
+ write(fd_socket, buf, strlen(buf));
+
+ snprintf(buf, sizeof(buf), "Content-Transfer-Encoding: 8bit\n\n");
+ write(fd_socket, buf, strlen(buf));
+}
+
+/* ---------------------------------------------------------------------------------------------------------------------- */
+
+void write_mail_mime_html(int fd_socket, char *boundary)
+{
+ char buf[1024];
+
+ snprintf(buf, sizeof(buf), "--%s\n", boundary);
+ write(fd_socket, buf, strlen(buf));
+
+ snprintf(buf, sizeof(buf), "Content-Type: text/html;\n");
+ write(fd_socket, buf, strlen(buf));
+
+ snprintf(buf, sizeof(buf), " charset=\"us-ascii\"\n");
+ write(fd_socket, buf, strlen(buf));
+
+ snprintf(buf, sizeof(buf), "Content-Transfer-Encoding: 7bit\n\n");
+ write(fd_socket, buf, strlen(buf));
+
+ snprintf(buf, sizeof(buf), "<!doctype html public \"-//w3c//dtd html 4.0 transitional//en\">\n");
+ write(fd_socket, buf, strlen(buf));
+
+ snprintf(buf, sizeof(buf), "<html>\n");
+ write(fd_socket, buf, strlen(buf));
+}
+
+/* ---------------------------------------------------------------------------------------------------------------------- */
+
+void write_mail_attach_image(int fd_socket, char *boundary, char *content_id, char *content_type, FILE *infile, char *filename)
+{
+ char buf[1024];
+
+ snprintf(buf, sizeof(buf), "--%s\n", boundary);
+ write(fd_socket, buf, strlen(buf));
+
+ snprintf(buf, sizeof(buf), "Content-Type: %s\n", content_type);
+ write(fd_socket, buf, strlen(buf));
+
+ if (content_id)
+ {
+ snprintf(buf, sizeof(buf), "Content-ID: <%s>\n", content_id);
+ write(fd_socket, buf, strlen(buf));
+ }
+
+ snprintf(buf, sizeof(buf), "Content-Transfer-Encoding: base64\n");
+ write(fd_socket, buf, strlen(buf));
+
+ snprintf(buf, sizeof(buf), "Content-Disposition: inline;\n");
+ write(fd_socket, buf, strlen(buf));
+
+ snprintf(buf, sizeof(buf), " filename=\"%s\"\n", filename);
+ write(fd_socket, buf, strlen(buf));
+
+ snprintf(buf, sizeof(buf), "\n");
+ write(fd_socket, buf, strlen(buf));
+
+ write_base64(fd_socket, infile);
+}
+
+/* ---------------------------------------------------------------------------------------------------------------------- */
+
+void write_mail_attach_file(int fd_socket, char *boundary, FILE *infile, char *filename)
+{
+ char buf[1024];
+
+ snprintf(buf, sizeof(buf), "--%s\n", boundary);
+ write(fd_socket, buf, strlen(buf));
+
+ snprintf(buf, sizeof(buf), "Content-Type: application/octet-stream\n");
+ write(fd_socket, buf, strlen(buf));
+
+ snprintf(buf, sizeof(buf), " name=\"%s\"\n", filename);
+ write(fd_socket, buf, strlen(buf));
+
+ snprintf(buf, sizeof(buf), "Content-Transfer-Encoding: base64\n");
+ write(fd_socket, buf, strlen(buf));
+
+ snprintf(buf, sizeof(buf), "Content-Disposition: attachment;\n");
+ write(fd_socket, buf, strlen(buf));
+
+ snprintf(buf, sizeof(buf), " filename=\"%s\"\n", filename);
+ write(fd_socket, buf, strlen(buf));
+
+ snprintf(buf, sizeof(buf), "\n");
+ write(fd_socket, buf, strlen(buf));
+
+ write_base64(fd_socket, infile);
+}
+
+/* ---------------------------------------------------------------------------------------------------------------------- */
+
+/* returns fd_socket if sucessfull, < 0 when error occured */
+int open_socket(char *server, int port)
+{
+ int fd_socket;
+ struct sockaddr_in sin;
+ struct hostent *he;
+
+ he = gethostbyname(server);
+ if (!he)
+ {
+ DBG(DBG_error, "open_socket: Could not get hostname of \"%s\"\n", server);
+ return -1;
+ }
+ else
+ {
+ DBG(DBG_info, "open_socket: connecting to \"%s\" = %d.%d.%d.%d\n",
+ he->h_name,
+ (unsigned char) he->h_addr_list[0][0],
+ (unsigned char) he->h_addr_list[0][1],
+ (unsigned char) he->h_addr_list[0][2],
+ (unsigned char) he->h_addr_list[0][3]);
+ }
+
+ if (he->h_addrtype != AF_INET)
+ {
+ DBG(DBG_error, "open_socket: Unknown address family: %d\n", he->h_addrtype);
+ return -1;
+ }
+
+ fd_socket = socket(AF_INET, SOCK_STREAM, 0);
+
+ if (fd_socket < 0)
+ {
+ DBG(DBG_error, "open_socket: Could not create socket: %s\n", strerror(errno));
+ return -1;
+ }
+
+/* setsockopt (dev->ctl, level, TCP_NODELAY, &on, sizeof (on)); */
+
+ sin.sin_port = htons(port);
+ sin.sin_family = AF_INET;
+ memcpy(&sin.sin_addr, he->h_addr_list[0], he->h_length);
+
+ if (connect(fd_socket, &sin, sizeof(sin)))
+ {
+ DBG(DBG_error, "open_socket: Could not connect with port %d of socket: %s\n", ntohs(sin.sin_port), strerror(errno));
+ return -1;
+ }
+
+ DBG(DBG_info, "open_socket: Connected with port %d\n", ntohs(sin.sin_port));
+
+ return fd_socket;
+}
+
+/* ---------------------------------------------------------------------------------------------------------------------- */
+
+/* returns 0 if success */
+/* not only a write routine, also reads data */
+int pop3_login(int fd_socket, char *user, char *passwd)
+{
+ char buf[1024];
+ int len;
+
+ len = read(fd_socket, buf, sizeof(buf));
+ if (len >= 0)
+ {
+ buf[len] = 0;
+ }
+ DBG(DBG_info2, "< %s\n", buf);
+
+ snprintf(buf, sizeof(buf), "USER %s\r\n", user);
+ DBG(DBG_info2, "> USER xxx\n");
+ write(fd_socket, buf, strlen(buf));
+ len = read(fd_socket, buf, sizeof(buf));
+ if (len >= 0)
+ {
+ buf[len] = 0;
+ }
+ DBG(DBG_info2, "< %s\n", buf);
+ if (buf[0] != '+')
+ {
+ return -1;
+ }
+
+ snprintf(buf, sizeof(buf), "PASS %s\r\n", passwd);
+ DBG(DBG_info2, "> PASS xxx\n");
+ write(fd_socket, buf, strlen(buf));
+ len = read(fd_socket, buf, sizeof(buf));
+ if (len >= 0)
+ {
+ buf[len] = 0;
+ }
+ DBG(DBG_info2, "< %s\n", buf);
+ if (buf[0] != '+')
+ {
+ return -1;
+ }
+
+ snprintf(buf, sizeof(buf), "QUIT\r\n");
+ DBG(DBG_info2, "> QUIT\n");
+ write(fd_socket, buf, strlen(buf));
+ len = read(fd_socket, buf, sizeof(buf));
+ if (len >= 0)
+ {
+ buf[len] = 0;
+ }
+ DBG(DBG_info2, "< %s\n", buf);
+
+ return 0;
+}
+
+/* ---------------------------------------------------------------------------------------------------------------------- */
+
+/* not only a write routine, also reads data */
+/* returns -1 on error, 0 when ok */
+int write_smtp_header(int fd_socket, char *from, char *to)
+{
+ char buf[1024];
+ int len;
+
+ len = read(fd_socket, buf, sizeof(buf));
+ if (len >= 0)
+ {
+ buf[len] = 0;
+ }
+ DBG(DBG_info2, "< %s\n", buf);
+
+ snprintf(buf, sizeof(buf), "helo localhost\r\n");
+ DBG(DBG_info2, "> %s", buf);
+ write(fd_socket, buf, strlen(buf));
+ len = read(fd_socket, buf, sizeof(buf));
+ if (len >= 0)
+ {
+ buf[len] = 0;
+ }
+ DBG(DBG_info2, "< %s\n", buf);
+
+ if (buf[0] != '2')
+ {
+ DBG(DBG_info, "=> error\n");
+
+ if (xsane.mail_status)
+ {
+ free(xsane.mail_status);
+ }
+ xsane.mail_status = strdup(TEXT_MAIL_STATUS_SMTP_CONNECTION_FAILED);
+ xsane_front_gtk_mail_project_update_lockfile_status();
+ return -1;
+ }
+
+ snprintf(buf, sizeof(buf), "MAIL FROM: %s\r\n", from);
+ DBG(DBG_info2, "> %s", buf);
+ write(fd_socket, buf, strlen(buf));
+ len = read(fd_socket, buf, sizeof(buf));
+ if (len >= 0)
+ {
+ buf[len] = 0;
+ }
+ DBG(DBG_info2, "< %s\n", buf);
+
+ if (buf[0] != '2')
+ {
+ DBG(DBG_info, "=> error\n");
+
+ if (xsane.mail_status)
+ {
+ free(xsane.mail_status);
+ }
+ xsane.mail_status = strdup(TEXT_MAIL_STATUS_SMTP_ERR_FROM);
+ xsane_front_gtk_mail_project_update_lockfile_status();
+ return -1;
+ }
+
+
+ snprintf(buf, sizeof(buf), "RCPT TO: %s\r\n", to);
+ DBG(DBG_info2, "> %s", buf);
+ write(fd_socket, buf, strlen(buf));
+ len = read(fd_socket, buf, sizeof(buf));
+ if (len >= 0)
+ {
+ buf[len] = 0;
+ }
+ DBG(DBG_info2, "< %s\n", buf);
+
+ if (buf[0] != '2')
+ {
+ DBG(DBG_info, "=> error\n");
+
+ if (xsane.mail_status)
+ {
+ free(xsane.mail_status);
+ }
+ xsane.mail_status = strdup(TEXT_MAIL_STATUS_SMTP_ERR_RCPT);
+ xsane_front_gtk_mail_project_update_lockfile_status();
+ return -1;
+ }
+
+ snprintf(buf, sizeof(buf), "DATA\r\n");
+ DBG(DBG_info2, "> %s", buf);
+ write(fd_socket, buf, strlen(buf));
+ len = read(fd_socket, buf, sizeof(buf));
+ if (len >= 0)
+ {
+ buf[len] = 0;
+ }
+ DBG(DBG_info2, "< %s\n", buf);
+
+ if ((buf[0] != '2') && (buf[0] != '3'))
+ {
+ DBG(DBG_info, "=> error\n");
+
+ if (xsane.mail_status)
+ {
+ free(xsane.mail_status);
+ }
+ xsane.mail_status = strdup(TEXT_MAIL_STATUS_SMTP_ERR_DATA);
+ xsane_front_gtk_mail_project_update_lockfile_status();
+ return -1;
+ }
+
+ return 0;
+}
+
+/* ---------------------------------------------------------------------------------------------------------------------- */
+
+/* not only a write routine, also reads data */
+int write_smtp_footer(int fd_socket)
+{
+ char buf[1024];
+ int len;
+
+ snprintf(buf, sizeof(buf), "\r\n.\r\n");
+ DBG(DBG_info2, "> %s", buf);
+ write(fd_socket, buf, strlen(buf));
+ len = read(fd_socket, buf, sizeof(buf));
+ if (len >= 0)
+ {
+ buf[len] = 0;
+ }
+ DBG(DBG_info2, "< %s\n", buf);
+
+ snprintf(buf, sizeof(buf), "QUIT\r\n");
+ DBG(DBG_info2, "> %s", buf);
+ write(fd_socket, buf, strlen(buf));
+ len = read(fd_socket, buf, sizeof(buf));
+ if (len >= 0)
+ {
+ buf[len] = 0;
+ }
+ DBG(DBG_info2, "< %s\n", buf);
+
+ return 0;
+}
+
+#endif
+/* ---------------------------------------------------------------------------------------------------------------------- */
diff --git a/src/xsane-save.h b/src/xsane-save.h
index e2f1458..553fbd5 100644
--- a/src/xsane-save.h
+++ b/src/xsane-save.h
@@ -22,6 +22,33 @@
/* ---------------------------------------------------------------------------------------------------------------------- */
+#ifndef HAVE_XSANE_SAVE_H
+#define HAVE_XSANE_SAVE_H
+
+/* ---------------------------------------------------------------------------------------------------------------------- */
+
+#include <xsane.h>
+#ifdef HAVE_LIBTIFF
+# include "tiffio.h"
+#endif
+
+/* ---------------------------------------------------------------------------------------------------------------------- */
+
+/* The pdf_xref struct holds byte offsets from the beginning of the PDF
+ * file to each object of the PDF file -- used to build the xref table
+ */
+#define PDF_PAGES_MAX 1000
+struct pdf_xref
+{
+ unsigned long obj[PDF_PAGES_MAX * 2 + 6];
+ unsigned long xref; /* xref table */
+ unsigned long slen; /* length of image stream */
+ unsigned long slenp; /* position of image stream length */
+};
+
+/* ---------------------------------------------------------------------------------------------------------------------- */
+
+
extern int xsane_create_secure_file(const char *filename);
extern void xsane_cancel_save();
extern void xsane_convert_text_to_filename(char **filename);
@@ -38,35 +65,57 @@ extern int xsane_save_scaled_image(FILE *outfile, FILE *imagefile, Image_info *i
extern int xsane_save_despeckle_image(FILE *outfile, FILE *imagefile, Image_info *image_info, int radius, GtkProgressBar *progress_bar, int *cancel_save);
extern int xsane_save_blur_image(FILE *outfile, FILE *imagefile, Image_info *image_info, float radius, GtkProgressBar *progress_bar, int *cancel_save);
extern int xsane_save_rotate_image(FILE *outfile, FILE *imagefile, Image_info *image_info, int rotation, GtkProgressBar *progress_bar, int *cancel_save);
-extern void xsane_save_ps(FILE *outfile, FILE *imagefile, Image_info *image_info,
+extern void xsane_save_ps_create_document_header(FILE *outfile, int pages, int flatdecode);
+extern void xsane_save_ps_create_document_trailer(FILE *outfile, int pages);
+extern int xsane_save_ps_page(FILE *outfile, int page,
+ FILE *imagefile, Image_info *image_info, float width, float height,
+ int paper_left_margin, int paper_bottom_margin, int paperwidth, int paperheight, int paper_orientation,
+ int flatdecode,
+ GtkProgressBar *progress_bar, int *cancel_save);
+extern int xsane_save_ps(FILE *outfile, FILE *imagefile, Image_info *image_info,
+ float width, float height,
+ int paper_left_margin, int paper_bottom_margin, int paperwidth, int paperheight, int paper_orientation,
+ int flatdecode,
+ GtkProgressBar *progress_bar, int *cancel_save);
+extern void xsane_save_pdf_create_document_header(FILE *outfile, struct pdf_xref *xref, int pages, int flatdecode);
+extern void xsane_save_pdf_create_document_trailer(FILE *outfile, struct pdf_xref *xref, int pages);
+extern int xsane_save_pdf_page(FILE *outfile, struct pdf_xref *xref, int page,
+ FILE *imagefile, Image_info *image_info, float width, float height,
+ int paper_left_margin, int paper_bottom_margin, int paperwidth, int paperheight, int paper_orientation,
+ int flatdecode,
+ GtkProgressBar *progress_bar, int *cancel_save);
+extern int xsane_save_pdf(FILE *outfile, FILE *imagefile, Image_info *image_info,
float width, float height,
int paper_left_margin, int paper_bottom_margin, int paperwidth, int paperheight, int paper_orientation,
+ int flatdecode,
GtkProgressBar *progress_bar, int *cancel_save);
-extern void xsane_save_pdf(FILE *outfile, FILE *imagefile, Image_info *image_info,
- float width, float height,
- int paper_left_margin, int paper_bottom_margin, int paperwidth, int paperheight, int paper_orientation,
- GtkProgressBar *progress_bar, int *cancel_save);
-extern void xsane_save_jpeg(FILE *outfile, FILE *imagefile, Image_info *image_info, int quality, GtkProgressBar *progress_bar, int *cancel_save);
-extern void xsane_save_tiff(const char *outfilename, FILE *imagefile, Image_info *image_info, int quality, GtkProgressBar *progress_bar, int *cancel_save);
-extern void xsane_save_png(FILE *outfile, FILE *imagefile, Image_info *image_info, int compression, GtkProgressBar *progress_bar, int *cancel_save);
-extern void xsane_save_png_16(FILE *outfile, FILE *imagefile, Image_info *image_info, int compression, GtkProgressBar *progress_bar, int *cancel_save);
-extern void xsane_save_pnm_16(FILE *outfile, FILE *imagefile, Image_info *image_info, GtkProgressBar *progress_bar, int *cancel_save);
+#ifdef HAVE_LIBJPEG
+extern int xsane_save_jpeg(FILE *outfile, FILE *imagefile, Image_info *image_info, int quality, GtkProgressBar *progress_bar, int *cancel_save);
+#endif
+#ifdef HAVE_LIBTIFF
+extern int xsane_save_tiff_page(TIFF *tiffile, int page, int pages, FILE *imagefile, Image_info *image_info, int quality,
+ GtkProgressBar *progress_bar, int *cancel_save);
+#endif
+extern int xsane_save_png(FILE *outfile, FILE *imagefile, Image_info *image_info, int compression, GtkProgressBar *progress_bar, int *cancel_save);
+extern int xsane_save_png_16(FILE *outfile, FILE *imagefile, Image_info *image_info, int compression, GtkProgressBar *progress_bar, int *cancel_save);
+extern int xsane_save_pnm_16(FILE *outfile, FILE *imagefile, Image_info *image_info, GtkProgressBar *progress_bar, int *cancel_save);
extern int xsane_save_image_as_lineart(char *output_filename, char *input_filename, GtkProgressBar *progress_bar, int *cancel_save);
extern int xsane_save_image_as_text(char *output_filename, char *input_filename, GtkProgressBar *progress_bar, int *cancel_save);
extern int xsane_save_image_as(char *output_filename, char *input_filename, int output_format, GtkProgressBar *progress_bar, int *cancel_save);
extern void null_print_func(gchar *msg);
extern int xsane_transfer_to_gimp(char *input_filename, GtkProgressBar *progress_bar, int *cancel_save);
extern void write_base64(int fd_socket, FILE *infile);
-extern void write_mail_header(int fd_socket, char *from, char *reply_to, char *to, char *subject, char *boundary, int related);
-extern void write_mail_footer(int fd_socket, char *boundary);
-extern void write_mail_mime_ascii(int fd_socket, char *boundary);
-extern void write_mail_mime_html(int fd_socket, char *boundary);
-extern void write_mail_attach_image(int fd_socket, char *boundary, char *content_id, char *content_type, FILE *infile, char *filename);
-extern void write_mail_attach_file(int fd_socket, char *boundary, FILE *infile, char *filename);
+extern void write_email_header(int fd_socket, char *from, char *reply_to, char *to, char *subject, char *boundary, int related);
+extern void write_email_footer(int fd_socket, char *boundary);
+extern void write_email_mime_ascii(int fd_socket, char *boundary);
+extern void write_email_mime_html(int fd_socket, char *boundary);
+extern void write_email_attach_image(int fd_socket, char *boundary, char *content_id, char *content_type, FILE *infile, char *filename);
+extern void write_email_attach_file(int fd_socket, char *boundary, FILE *infile, char *filename);
extern int open_socket(char *server, int port);
extern int pop3_login(int fd_socket, char *user, char *passwd);
-extern int write_smtp_header(int fd_socket, char *from, char *to);
+extern int write_smtp_header(int fd_socket, char *from, char *to, int auth_type, char *user, char *pass);
extern int write_smtp_footer(int fd_socket);
-
+/* ---------------------------------------------------------------------------------------------------------------------- */
+#endif
/* ---------------------------------------------------------------------------------------------------------------------- */
diff --git a/src/xsane-scan.c b/src/xsane-scan.c
index 7888a16..bf054dc 100644
--- a/src/xsane-scan.c
+++ b/src/xsane-scan.c
@@ -31,6 +31,9 @@
#include "xsane-save.h"
#include "xsane-gamma.h"
#include "xsane-setup.h"
+#include "xsane-multipage-project.h"
+#include "xsane-fax-project.h"
+#include "xsane-email-project.h"
#ifdef HAVE_LIBPNG
#ifdef HAVE_LIBZ
@@ -50,7 +53,7 @@ static int xsane_test_multi_scan(void);
void xsane_scan_done(SANE_Status status);
void xsane_cancel(void);
static void xsane_start_scan(void);
-void xsane_scan_dialog(void);
+gint xsane_scan_dialog(gpointer *data);
static void xsane_create_internal_gamma_tables(void);
/* ---------------------------------------------------------------------------------------------------------------------- */
@@ -99,6 +102,13 @@ static int xsane_generate_dummy_filename(int conversion_level)
return TRUE;
}
+ else if (xsane.xsane_mode == XSANE_MULTIPAGE) /* no conversion following, save directly to the selected filename */
+ {
+ xsane.dummy_filename = strdup(xsane.multipage_filename);
+ DBG(DBG_info, "xsane.dummy_filename = %s\n", xsane.dummy_filename);
+
+ return FALSE;
+ }
else if (xsane.xsane_mode == XSANE_FAX) /* no conversion following, save directly to the selected filename */
{
xsane.dummy_filename = strdup(xsane.fax_filename);
@@ -106,9 +116,9 @@ static int xsane_generate_dummy_filename(int conversion_level)
return FALSE;
}
- else if (xsane.xsane_mode == XSANE_MAIL) /* no conversion following, save directly to the selected filename */
+ else if (xsane.xsane_mode == XSANE_EMAIL) /* no conversion following, save directly to the selected filename */
{
- xsane.dummy_filename = strdup(xsane.mail_filename);
+ xsane.dummy_filename = strdup(xsane.email_filename);
DBG(DBG_info, "xsane.dummy_filename = %s\n", xsane.dummy_filename);
return FALSE;
@@ -896,36 +906,26 @@ static RETSIGTYPE xsane_sigpipe_handler(int signal)
static int xsane_test_multi_scan(void)
{
- char *set;
- SANE_Status status;
- const SANE_Option_Descriptor *opt;
-
DBG(DBG_proc, "xsane_test_multi_scan\n");
- opt = xsane_get_option_descriptor(xsane.dev, xsane.well_known.scansource);
- if (opt)
+ if (xsane.mode == XSANE_GIMP_EXTENSION)
{
- if (SANE_OPTION_IS_ACTIVE(opt->cap))
- {
- if (opt->constraint_type == SANE_CONSTRAINT_STRING_LIST)
- {
- set = malloc(opt->size);
- status = xsane_control_option(xsane.dev, xsane.well_known.scansource, SANE_ACTION_GET_VALUE, set, 0);
+ return FALSE;
+ }
- if (status == SANE_STATUS_GOOD)
- {
- if (xsane.adf_scansource)
- {
- if (!strcmp(set, xsane.adf_scansource))
- {
- free(set);
- return TRUE;
- }
- }
- }
- free(set);
- }
- }
+ if (xsane.batch_loop)
+ {
+ return FALSE;
+ }
+
+ if (xsane.adf_page_counter+1 < preferences.adf_pages_max)
+ {
+ return TRUE;
+ }
+ else
+ {
+ xsane.adf_page_counter = 0;
+ return FALSE;
}
#if 0 /* this is planned for the next sane-standard */
@@ -1187,11 +1187,19 @@ void xsane_scan_done(SANE_Status status)
if (xsane.xsane_mode == XSANE_VIEWER)
{
- xsane_viewer_new(xsane.dummy_filename, TRUE, NULL, VIEWER_FULL_MODIFICATION);
+ if (!xsane.force_filename) /* user filename selection active */
+ {
+ xsane_viewer_new(xsane.dummy_filename, preferences.filetype, TRUE, preferences.filename, VIEWER_FULL_MODIFICATION, IMAGE_NOT_SAVED);
+ }
+ else
+ {
+ xsane_viewer_new(xsane.dummy_filename, NULL, TRUE, xsane.external_filename, VIEWER_NO_NAME_MODIFICATION, IMAGE_NOT_SAVED);
+ }
+
xsane.expand_lineart_to_grayscale = 0;
}
- if ((xsane.xsane_mode == XSANE_FAX) || (xsane.xsane_mode == XSANE_MAIL))
+ if ((xsane.xsane_mode == XSANE_MULTIPAGE) || (xsane.xsane_mode == XSANE_FAX) || (xsane.xsane_mode == XSANE_EMAIL))
{
xsane.expand_lineart_to_grayscale = 0;
}
@@ -1336,6 +1344,7 @@ void xsane_scan_done(SANE_Status status)
preferences.printer[preferences.printernr]->width * 72.0/MM_PER_INCH, /* usable paperwidth */
preferences.printer[preferences.printernr]->height * 72.0/MM_PER_INCH, /* usable paperheight */
preferences.paper_orientation,
+ preferences.printer[preferences.printernr]->ps_flatdecoded, /* ps level 3 */
xsane.progress_bar,
&xsane.cancel_save);
}
@@ -1378,7 +1387,7 @@ void xsane_scan_done(SANE_Status status)
}
}
- if ( (xsane.xsane_mode == XSANE_SAVE) && (xsane.mode == XSANE_STANDALONE) )
+ if ( ( (xsane.xsane_mode == XSANE_SAVE) || (xsane.xsane_mode == XSANE_VIEWER) ) && (xsane.mode == XSANE_STANDALONE) )
{
if (!xsane.force_filename) /* user filename selection active */
{
@@ -1395,6 +1404,47 @@ void xsane_scan_done(SANE_Status status)
xsane_update_counter_in_filename(&xsane.external_filename, TRUE, 1, 0);
}
}
+ else if (xsane.xsane_mode == XSANE_MULTIPAGE)
+ {
+ GtkWidget *list_item;
+ char *page;
+ char *type;
+ char *extension;
+
+ page = strdup(strrchr(xsane.multipage_filename,'/')+1);
+ extension = strrchr(page, '.');
+ if (extension)
+ {
+ type = strdup(extension);
+ *extension = 0;
+ }
+ else
+ {
+ type = "";
+ }
+
+ list_item = gtk_list_item_new_with_label(page);
+ gtk_object_set_data(GTK_OBJECT(list_item), "list_item_data", strdup(page));
+ gtk_object_set_data(GTK_OBJECT(list_item), "list_item_type", strdup(type));
+ gtk_container_add(GTK_CONTAINER(xsane.project_list), list_item);
+ gtk_widget_show(list_item);
+
+ xsane_update_counter_in_filename(&xsane.multipage_filename, TRUE, 1, preferences.filename_counter_len);
+ xsane_multipage_project_save();
+ free(page);
+ free(type);
+
+ if (xsane.multipage_status)
+ {
+ free(xsane.multipage_status);
+ }
+ xsane.multipage_status = strdup(TEXT_PROJECT_STATUS_CHANGED);
+
+ xsane_multipage_project_save();
+
+ gtk_progress_set_format_string(GTK_PROGRESS(xsane.project_progress_bar), _(xsane.multipage_status));
+ gtk_progress_bar_update(GTK_PROGRESS_BAR(xsane.project_progress_bar), 0.0);
+ }
else if (xsane.xsane_mode == XSANE_FAX)
{
GtkWidget *list_item;
@@ -1417,7 +1467,7 @@ void xsane_scan_done(SANE_Status status)
list_item = gtk_list_item_new_with_label(page);
gtk_object_set_data(GTK_OBJECT(list_item), "list_item_data", strdup(page));
gtk_object_set_data(GTK_OBJECT(list_item), "list_item_type", strdup(type));
- gtk_container_add(GTK_CONTAINER(xsane.fax_list), list_item);
+ gtk_container_add(GTK_CONTAINER(xsane.project_list), list_item);
gtk_widget_show(list_item);
xsane_update_counter_in_filename(&xsane.fax_filename, TRUE, 1, preferences.filename_counter_len);
@@ -1429,22 +1479,22 @@ void xsane_scan_done(SANE_Status status)
{
free(xsane.fax_status);
}
- xsane.fax_status = strdup(TEXT_FAX_STATUS_CHANGED);
+ xsane.fax_status = strdup(TEXT_PROJECT_STATUS_CHANGED);
xsane_fax_project_save();
- gtk_progress_set_format_string(GTK_PROGRESS(xsane.fax_progress_bar), _(xsane.fax_status));
- gtk_progress_bar_update(GTK_PROGRESS_BAR(xsane.fax_progress_bar), 0.0);
+ gtk_progress_set_format_string(GTK_PROGRESS(xsane.project_progress_bar), _(xsane.fax_status));
+ gtk_progress_bar_update(GTK_PROGRESS_BAR(xsane.project_progress_bar), 0.0);
}
-#ifdef XSANE_ACTIVATE_MAIL
- else if (xsane.xsane_mode == XSANE_MAIL)
+#ifdef XSANE_ACTIVATE_EMAIL
+ else if (xsane.xsane_mode == XSANE_EMAIL)
{
GtkWidget *list_item;
char *page;
char *type;
char *extension;
- page = strdup(strrchr(xsane.mail_filename,'/')+1);
+ page = strdup(strrchr(xsane.email_filename,'/')+1);
extension = strrchr(page, '.');
if (extension)
{
@@ -1459,24 +1509,24 @@ void xsane_scan_done(SANE_Status status)
list_item = gtk_list_item_new_with_label(page);
gtk_object_set_data(GTK_OBJECT(list_item), "list_item_data", strdup(page));
gtk_object_set_data(GTK_OBJECT(list_item), "list_item_type", strdup(type));
- gtk_container_add(GTK_CONTAINER(xsane.mail_list), list_item);
+ gtk_container_add(GTK_CONTAINER(xsane.project_list), list_item);
gtk_widget_show(list_item);
- xsane_update_counter_in_filename(&xsane.mail_filename, TRUE, 1, preferences.filename_counter_len);
- xsane_mail_project_save();
+ xsane_update_counter_in_filename(&xsane.email_filename, TRUE, 1, preferences.filename_counter_len);
+ xsane_email_project_save();
free(page);
free(type);
- if (xsane.mail_status)
+ if (xsane.email_status)
{
- free(xsane.mail_status);
+ free(xsane.email_status);
}
- xsane.mail_status = strdup(TEXT_MAIL_STATUS_CHANGED);
+ xsane.email_status = strdup(TEXT_PROJECT_STATUS_CHANGED);
- xsane_mail_project_save();
+ xsane_email_project_save();
- gtk_progress_set_format_string(GTK_PROGRESS(xsane.mail_progress_bar), _(xsane.mail_status));
- gtk_progress_bar_update(GTK_PROGRESS_BAR(xsane.mail_progress_bar), 0.0);
+ gtk_progress_set_format_string(GTK_PROGRESS(xsane.project_progress_bar), _(xsane.email_status));
+ gtk_progress_bar_update(GTK_PROGRESS_BAR(xsane.project_progress_bar), 0.0);
}
#endif
}
@@ -1509,15 +1559,16 @@ void xsane_scan_done(SANE_Status status)
DBG(DBG_info, "ADF mode end of scan: increment page counter and restart scan\n");
xsane.adf_page_counter += 1;
- g_signal_emit_by_name(xsane.start_button, "clicked"); /* press START button */
+ gtk_timeout_add(100, (GtkFunction)xsane_scan_dialog, NULL); /* wait 100ms then call xsane_scan_dialog(); */
}
- else if ( ( (status == SANE_STATUS_GOOD) || (status == SANE_STATUS_EOF) ) && (xsane.batch_loop) )
+ else if ( ( (status == SANE_STATUS_GOOD) || (status == SANE_STATUS_EOF) ) && (xsane.batch_loop == BATCH_MODE_LOOP) )
{
/* batch scan loop, this is not the last scan */
DBG(DBG_info, "Batch mode end of scan\n");
sane_cancel(xsane.dev); /* we have to call sane_cancel otherwise we are not able to set new parameters */
}
- else if ( ( (status != SANE_STATUS_GOOD) && (status != SANE_STATUS_EOF) ) || (!xsane.batch_loop) ) /* last scan: update histogram */
+// else if ( ( (status != SANE_STATUS_GOOD) && (status != SANE_STATUS_EOF) ) || (!xsane.batch_loop) ) /* last scan: update histogram */
+ else
{
DBG(DBG_info, "Normal end of scan\n");
xsane_set_sensitivity(TRUE); /* reactivate buttons etc */
@@ -1630,7 +1681,7 @@ static void xsane_start_scan(void)
if ((xsane.param.depth == 1) && ((xsane.scan_rotation) ||
(xsane.xsane_mode == XSANE_VIEWER) ||
(xsane.xsane_mode == XSANE_FAX) ||
- (xsane.xsane_mode == XSANE_MAIL))
+ (xsane.xsane_mode == XSANE_EMAIL))
) /* We want to do a transformation with a lineart scan */
/* or use the viewer to display a lineart scan, */
/* so we save it as grayscale */
@@ -1715,7 +1766,24 @@ static void xsane_start_scan(void)
xsane.pixelcolor = 0;
snprintf(buf, sizeof(buf), PROGRESS_RECEIVING_FRAME_DATA, _(frame_type));
- xsane_progress_new(buf, PROGRESS_SCANNING, (GtkSignalFunc) xsane_cancel, NULL);
+
+ if (preferences.adf_pages_max > 1)
+ {
+ char buf2[255];
+ if (preferences.adf_pages_max > 1)
+ {
+ snprintf(buf2, sizeof(buf), "%s (%d/%d)", PROGRESS_SCANNING, xsane.adf_page_counter+1, preferences.adf_pages_max);
+ }
+ else
+ {
+ snprintf(buf2, sizeof(buf), "%s (%d)", PROGRESS_SCANNING, xsane.adf_page_counter+1);
+ }
+ xsane_progress_new(buf, buf2, (GtkSignalFunc) xsane_cancel, NULL);
+ }
+ else
+ {
+ xsane_progress_new(buf, PROGRESS_SCANNING, (GtkSignalFunc) xsane_cancel, NULL);
+ }
while (gtk_events_pending())
{
@@ -1742,7 +1810,9 @@ static void xsane_start_scan(void)
/* Invoked when the scan button is pressed */
/* or by scan_done if automatic document feeder is selected */
-void xsane_scan_dialog(void)
+/* always returns 0 beacause ADF function calls it as timeout function */
+/* and return value 0 is used to tell the timeout handler to stop timer */
+gint xsane_scan_dialog(gpointer *data)
{
char buf[256];
const SANE_Option_Descriptor *opt;
@@ -1755,12 +1825,13 @@ void xsane_scan_dialog(void)
sane_get_parameters(xsane.dev, &xsane.param); /* update xsane.param */
- if ( (xsane.mode == XSANE_STANDALONE) && (xsane.xsane_mode == XSANE_SAVE) )
+ if ( ( (xsane.xsane_mode == XSANE_SAVE) || (xsane.xsane_mode == XSANE_VIEWER) ) && (xsane.mode == XSANE_STANDALONE) )
{
/* correct length of filename counter if it is shorter than minimum length */
if (!xsane.force_filename)
{
- if (xsane.batch_loop) /* we are doing a batch scan, so we need a counter in the filename */
+ /* when we are doing an adf or batch scan then we need a counter in the filename */
+ if ((xsane.batch_loop) || (preferences.adf_pages_max > 1))
{
xsane_ensure_counter_in_filename(&preferences.filename, preferences.filename_counter_len);
}
@@ -1791,7 +1862,7 @@ void xsane_scan_dialog(void)
if (xsane_back_gtk_decision(ERR_HEADER_WARNING, (gchar **) warning_xpm, buf, BUTTON_OVERWRITE, BUTTON_CANCEL, TRUE /* wait */) == FALSE)
{
xsane_set_sensitivity(TRUE);
- return;
+ return FALSE;
}
}
}
@@ -1812,7 +1883,7 @@ void xsane_scan_dialog(void)
}
xsane_back_gtk_error(buf, TRUE);
xsane_set_sensitivity(TRUE);
- return;
+ return FALSE;
}
#if 0 /* this is not necessary any more because the saving routines do the conversion */
else if ( ( ( (xsane.xsane_output_format == XSANE_JPEG) && xsane.param.depth == 16) ||
@@ -1824,7 +1895,7 @@ void xsane_scan_dialog(void)
if (xsane_back_gtk_decision(ERR_HEADER_INFO, (gchar **) info_xpm, buf, BUTTON_REDUCE, BUTTON_CANCEL, TRUE /* wait */) == FALSE)
{
xsane_set_sensitivity(TRUE);
- return;
+ return FALSE;
}
xsane.reduce_16bit_to_8bit = TRUE;
}
@@ -1836,7 +1907,7 @@ void xsane_scan_dialog(void)
snprintf(buf, sizeof(buf), "No RGBA data format !!!"); /* user selected output format RGBA, scanner uses other format */
xsane_back_gtk_error(buf, TRUE);
xsane_set_sensitivity(TRUE);
- return;
+ return FALSE;
}
#endif
}
@@ -1846,7 +1917,7 @@ void xsane_scan_dialog(void)
snprintf(buf, sizeof(buf), "Special format RGBA only supported in scan mode !!!");
xsane_back_gtk_error(buf, TRUE);
xsane_set_sensitivity(TRUE);
- return;
+ return FALSE;
}
#endif
@@ -1858,7 +1929,7 @@ void xsane_scan_dialog(void)
snprintf(buf, sizeof(buf), "Image data of type SANE_FRAME_RGBA\ncan only be saved in rgba or png format");
xsane_back_gtk_error(buf, TRUE);
xsane_set_sensitivity(TRUE);
- return;
+ return FALSE;
}
}
#endif
@@ -1886,7 +1957,7 @@ void xsane_scan_dialog(void)
if (xsane_back_gtk_decision(ERR_HEADER_INFO, (gchar **) info_xpm, buf, BUTTON_REDUCE, BUTTON_CANCEL, TRUE /* wait */) == FALSE)
{
xsane_set_sensitivity(TRUE);
- return;
+ return FALSE;
}
xsane.reduce_16bit_to_8bit = TRUE;
}
@@ -1895,7 +1966,7 @@ void xsane_scan_dialog(void)
snprintf(buf, sizeof(buf), ERR_GIMP_BAD_DEPTH, xsane.param.depth);
xsane_back_gtk_error(buf, TRUE);
xsane_set_sensitivity(TRUE);
- return;
+ return FALSE;
}
}
}
@@ -2060,6 +2131,7 @@ void xsane_scan_dialog(void)
xsane.scanning = TRUE; /* set marker that scan has been initiated */
xsane_start_scan();
+ return FALSE;
}
/* ---------------------------------------------------------------------------------------------------------------------- */
diff --git a/src/xsane-scan.h b/src/xsane-scan.h
index 3cacb55..b46d5e0 100644
--- a/src/xsane-scan.h
+++ b/src/xsane-scan.h
@@ -28,6 +28,6 @@
extern void xsane_scan_done(SANE_Status status);
extern void xsane_cancel(void);
-extern void xsane_scan_dialog(void);
+extern gint xsane_scan_dialog(gpointer *data);
/* ---------------------------------------------------------------------------------------------------------------------- */
diff --git a/src/xsane-setup.c b/src/xsane-setup.c
index b420643..f97e7ef 100644
--- a/src/xsane-setup.c
+++ b/src/xsane-setup.c
@@ -31,6 +31,7 @@
#include "xsane-save.h"
#include "xsane-gamma.h"
#include "xsane-batch-scan.h"
+#include "xsane-setup.h"
#ifdef HAVE_LIBPNG
#ifdef HAVE_LIBZ
@@ -72,21 +73,22 @@ static void xsane_setup_display_apply_changes(GtkWidget *widget, gpointer data);
static void xsane_setup_saving_apply_changes(GtkWidget *widget, gpointer data);
static void xsane_setup_image_apply_changes(GtkWidget *widget, gpointer data);
static void xsane_setup_fax_apply_changes(GtkWidget *widget, gpointer data);
-#ifdef XSANE_ACTIVATE_MAIL
-static void xsane_setup_mail_apply_changes(GtkWidget *widget, gpointer data);
+#ifdef XSANE_ACTIVATE_EMAIL
+static void xsane_setup_email_apply_changes(GtkWidget *widget, gpointer data);
#endif
static void xsane_setup_ocr_apply_changes(GtkWidget *widget, gpointer data);
static void xsane_setup_options_ok_callback(GtkWidget *widget, gpointer data);
static void xsane_printer_notebook(GtkWidget *notebook);
static void xsane_saving_notebook(GtkWidget *notebook);
-static void xsane_image_notebook(GtkWidget *notebook);
+static void xsane_filetype_notebook(GtkWidget *notebook);
static void xsane_fax_notebook(GtkWidget *notebook);
-#ifdef XSANE_ACTIVATE_MAIL
-static void xsane_mail_notebook(GtkWidget *notebook);
+#ifdef XSANE_ACTIVATE_EMAIL
+static void xsane_email_notebook(GtkWidget *notebook);
#endif
static void xsane_display_notebook(GtkWidget *notebook);
static void xsane_enhance_notebook_sensitivity(int lineart_mode);
+static void xsane_setup_authentication_type_callback(GtkWidget *widget, gpointer data);
static void xsane_setup_show_range_mode_callback(GtkWidget *widget, gpointer data);
static void xsane_setup_lineart_mode_callback(GtkWidget *widget, gpointer data);
static void xsane_enhance_notebook(GtkWidget *notebook);
@@ -133,6 +135,7 @@ void xsane_new_printer(void)
preferences.printer[preferences.printernr]->gamma_red = 1.0;
preferences.printer[preferences.printernr]->gamma_green = 1.0;
preferences.printer[preferences.printernr]->gamma_blue = 1.0;
+ preferences.printer[preferences.printernr]->ps_flatdecoded = 1;
}
else
{
@@ -272,6 +275,9 @@ static void xsane_setup_printer_update()
gtk_entry_set_text(GTK_ENTRY(xsane_setup.printer_gamma_green_entry), buf);
snprintf(buf, sizeof(buf), "%1.2f", preferences.printer[preferences.printernr]->gamma_blue);
gtk_entry_set_text(GTK_ENTRY(xsane_setup.printer_gamma_blue_entry), buf);
+#ifdef HAVE_LIBZ
+ gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(xsane_setup.printer_ps_flatdecoded_button), preferences.printer[preferences.printernr]->ps_flatdecoded);
+#endif
}
/* ---------------------------------------------------------------------------------------------------------------------- */
@@ -348,6 +354,10 @@ static void xsane_setup_printer_apply_changes(GtkWidget *widget, gpointer data)
xsane_update_double(xsane_setup.printer_gamma_green_entry, &preferences.printer[preferences.printernr]->gamma_green);
xsane_update_double(xsane_setup.printer_gamma_blue_entry, &preferences.printer[preferences.printernr]->gamma_blue);
+#ifdef HAVE_LIBZ
+ xsane_update_bool(xsane_setup.printer_ps_flatdecoded_button, &preferences.printer[preferences.printernr]->ps_flatdecoded);
+#endif
+
if (option_menu)
{
xsane_setup_printer_menu_build(option_menu);
@@ -509,31 +519,6 @@ static void xsane_setup_enhance_apply_changes(GtkWidget *widget, gpointer data)
xsane.grayscale_scanmode = strdup(xsane_setup.grayscale_scanmode);
}
-
- if (xsane.adf_scansource)
- {
- if (xsane_setup.adf_scansource)
- {
- device_options_changed |= (strcmp(xsane_setup.adf_scansource, xsane.adf_scansource));
- }
- else
- {
- device_options_changed |= 1;
- }
-
- free((void *) xsane.adf_scansource);
- xsane.adf_scansource = NULL;
- }
- else if (xsane_setup.adf_scansource)
- {
- device_options_changed |= 1;
- }
-
- if (xsane_setup.adf_scansource)
- {
- xsane.adf_scansource = strdup(xsane_setup.adf_scansource);
- }
-
preferences.preview_pipette_range = xsane_setup.preview_pipette_range;
xsane_update_bool(xsane_setup.auto_enhance_gamma_button, &preferences.auto_enhance_gamma);
@@ -597,18 +582,24 @@ static void xsane_setup_image_apply_changes(GtkWidget *widget, gpointer data)
#ifdef HAVE_LIBPNG
#ifdef HAVE_LIBZ
- xsane_update_scale(xsane_setup.pnm_image_compression_scale, &preferences.png_compression);
+ xsane_update_scale(xsane_setup.png_image_compression_scale, &preferences.png_compression);
#endif
#endif
#ifdef HAVE_LIBTIFF
+ xsane_update_scale(xsane_setup.tiff_image_zip_compression_scale, &preferences.tiff_zip_compression);
preferences.tiff_compression16_nr = xsane_setup.tiff_compression16_nr;
preferences.tiff_compression8_nr = xsane_setup.tiff_compression8_nr;
preferences.tiff_compression1_nr = xsane_setup.tiff_compression1_nr;
#endif
- xsane_update_bool(xsane_setup.save_pnm16_as_ascii_button, &preferences.save_pnm16_as_ascii);
xsane_update_bool(xsane_setup.reduce_16bit_to_8bit_button, &preferences.reduce_16bit_to_8bit);
+ xsane_update_bool(xsane_setup.save_pnm16_as_ascii_button, &preferences.save_pnm16_as_ascii);
+
+#ifdef HAVE_LIBZ
+ xsane_update_bool(xsane_setup.save_ps_flatdecoded_button, &preferences.save_ps_flatdecoded);
+ xsane_update_bool(xsane_setup.save_pdf_flatdecoded_button, &preferences.save_pdf_flatdecoded);
+#endif
xsane_define_maximum_output_size();
}
@@ -635,36 +626,41 @@ static void xsane_setup_fax_apply_changes(GtkWidget *widget, gpointer data)
xsane_update_geometry_double(xsane_setup.fax_width_entry, &preferences.fax_width, preferences.length_unit);
xsane_update_geometry_double(xsane_setup.fax_height_entry, &preferences.fax_height, preferences.length_unit);
+#ifdef HAVE_LIBZ
+ xsane_update_bool(xsane_setup.fax_ps_flatdecoded_button, &preferences.fax_ps_flatdecoded);
+#endif
+
xsane_define_maximum_output_size();
}
/* ---------------------------------------------------------------------------------------------------------------------- */
-#ifdef XSANE_ACTIVATE_MAIL
-static void xsane_setup_mail_apply_changes(GtkWidget *widget, gpointer data)
+#ifdef XSANE_ACTIVATE_EMAIL
+static void xsane_setup_email_apply_changes(GtkWidget *widget, gpointer data)
{
int i;
- DBG(DBG_proc, "xsane_setup_mail_apply_changes\n");
+ DBG(DBG_proc, "xsane_setup_email_apply_changes\n");
- preferences.mail_from = strdup(gtk_entry_get_text(GTK_ENTRY(xsane_setup.mail_from_entry)));
- preferences.mail_reply_to = strdup(gtk_entry_get_text(GTK_ENTRY(xsane_setup.mail_reply_to_entry)));
- preferences.mail_smtp_server = strdup(gtk_entry_get_text(GTK_ENTRY(xsane_setup.mail_smtp_server_entry)));
- preferences.mail_pop3_server = strdup(gtk_entry_get_text(GTK_ENTRY(xsane_setup.mail_pop3_server_entry)));
- preferences.mail_pop3_user = strdup(gtk_entry_get_text(GTK_ENTRY(xsane_setup.mail_pop3_user_entry)));
- preferences.mail_pop3_pass = strdup(gtk_entry_get_text(GTK_ENTRY(xsane_setup.mail_pop3_pass_entry)));
- preferences.mail_viewer = strdup(gtk_entry_get_text(GTK_ENTRY(xsane_setup.mail_viewer_entry)));
+ preferences.email_from = strdup(gtk_entry_get_text(GTK_ENTRY(xsane_setup.email_from_entry)));
+ preferences.email_reply_to = strdup(gtk_entry_get_text(GTK_ENTRY(xsane_setup.email_reply_to_entry)));
+ preferences.email_smtp_server = strdup(gtk_entry_get_text(GTK_ENTRY(xsane_setup.email_smtp_server_entry)));
+ preferences.email_auth_user = strdup(gtk_entry_get_text(GTK_ENTRY(xsane_setup.email_auth_user_entry)));
+ preferences.email_auth_pass = strdup(gtk_entry_get_text(GTK_ENTRY(xsane_setup.email_auth_pass_entry)));
+ preferences.email_pop3_server = strdup(gtk_entry_get_text(GTK_ENTRY(xsane_setup.email_pop3_server_entry)));
/* make sure password is not stored in ascii text */
/* this is very simple but better than nothing */
- for (i=0; i<strlen(preferences.mail_pop3_pass); i++)
+ for (i=0; i<strlen(preferences.email_auth_pass); i++)
{
- preferences.mail_pop3_pass[i] ^= 0x53;
+ preferences.email_auth_pass[i] ^= 0x53;
}
- xsane_update_bool(xsane_setup.mail_pop3_authentification_entry, &preferences.mail_pop3_authentification);
- xsane_update_int(xsane_setup.mail_smtp_port_entry, &preferences.mail_smtp_port);
- xsane_update_int(xsane_setup.mail_pop3_port_entry, &preferences.mail_pop3_port);
+// xsane_update_bool(xsane_setup.email_authentication_entry, &preferences.email_authentication);
+ xsane_update_int(xsane_setup.email_smtp_port_entry, &preferences.email_smtp_port);
+ xsane_update_int(xsane_setup.email_pop3_port_entry, &preferences.email_pop3_port);
+
+ preferences.email_authentication = xsane_setup.email_authentication;
}
#endif
@@ -719,8 +715,8 @@ static void xsane_setup_options_ok_callback(GtkWidget *widget, gpointer data)
xsane_setup_saving_apply_changes(0, 0);
xsane_setup_image_apply_changes(0, 0);
xsane_setup_fax_apply_changes(0, 0);
-#ifdef XSANE_ACTIVATE_MAIL
- xsane_setup_mail_apply_changes(0, 0);
+#ifdef XSANE_ACTIVATE_EMAIL
+ xsane_setup_email_apply_changes(0, 0);
#endif
xsane_setup_ocr_apply_changes(0, 0);
@@ -730,13 +726,6 @@ static void xsane_setup_options_ok_callback(GtkWidget *widget, gpointer data)
xsane_setup.grayscale_scanmode = NULL;
}
- if (xsane_setup.adf_scansource)
- {
- free((void *) xsane_setup.adf_scansource);
- xsane_setup.adf_scansource = NULL;
- }
-
-
xsane_pref_save();
gtk_widget_destroy((GtkWidget *)data); /* => xsane_destroy_setup_dialog_callback */
@@ -1285,6 +1274,25 @@ static void xsane_printer_notebook(GtkWidget *notebook)
xsane_setup.printer_gamma_blue_entry = text;
+
+#ifdef HAVE_LIBZ
+ xsane_separator_new(vbox, 2);
+
+
+
+ /* flatdecoded = ps level 3 */
+ hbox = gtk_hbox_new(/* homogeneous */ FALSE, 0);
+ gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 2);
+ button = gtk_check_button_new_with_label(TEXT_SETUP_PRINTER_PS_FLATDECODED);
+ xsane_back_gtk_set_tooltip(xsane.tooltips, button, DESC_PRINTER_PS_FLATDECODED);
+ gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button), preferences.printer[preferences.printernr]->ps_flatdecoded);
+ gtk_box_pack_start(GTK_BOX(hbox), button, TRUE, TRUE, 2);
+ gtk_widget_show(button);
+ gtk_widget_show(hbox);
+ xsane_setup.printer_ps_flatdecoded_button = button;
+#endif
+
+
xsane_separator_new(vbox, 4);
/* "apply" "add printer" "delete printer" */
@@ -1506,12 +1514,12 @@ static void xsane_saving_notebook(GtkWidget *notebook)
/* ---------------------------------------------------------------------------------------------------------------------- */
-static void xsane_image_notebook(GtkWidget *notebook)
+static void xsane_filetype_notebook(GtkWidget *notebook)
{
GtkWidget *setup_vbox, *vbox, *hbox, *button, *label, *frame;
+#ifdef HAVE_LIBTIFF
int i, select = 1;
-#ifdef HAVE_LIBTIFF
GtkWidget *tiff_compression_option_menu, *tiff_compression_menu, *tiff_compression_item;
typedef struct tiff_compression_t
@@ -1520,8 +1528,8 @@ static void xsane_image_notebook(GtkWidget *notebook)
int number;
} tiff_compression;
-#define TIFF_COMPRESSION16_NUMBER 2
-#define TIFF_COMPRESSION8_NUMBER 3
+#define TIFF_COMPRESSION16_NUMBER 3
+#define TIFF_COMPRESSION8_NUMBER 4
#define TIFF_COMPRESSION1_NUMBER 6
tiff_compression tiff_compression16_strings[TIFF_COMPRESSION16_NUMBER];
@@ -1532,6 +1540,8 @@ static void xsane_image_notebook(GtkWidget *notebook)
tiff_compression16_strings[0].number = COMPRESSION_NONE;
tiff_compression16_strings[1].name = MENU_ITEM_TIFF_COMP_PACKBITS;
tiff_compression16_strings[1].number = COMPRESSION_PACKBITS;
+ tiff_compression16_strings[2].name = MENU_ITEM_TIFF_COMP_DEFLATE;
+ tiff_compression16_strings[2].number = COMPRESSION_DEFLATE;
tiff_compression8_strings[0].name = MENU_ITEM_TIFF_COMP_NONE;
tiff_compression8_strings[0].number = COMPRESSION_NONE;
@@ -1539,6 +1549,8 @@ static void xsane_image_notebook(GtkWidget *notebook)
tiff_compression8_strings[1].number = COMPRESSION_JPEG;
tiff_compression8_strings[2].name = MENU_ITEM_TIFF_COMP_PACKBITS;
tiff_compression8_strings[2].number = COMPRESSION_PACKBITS;
+ tiff_compression8_strings[3].name = MENU_ITEM_TIFF_COMP_DEFLATE;
+ tiff_compression8_strings[3].number = COMPRESSION_DEFLATE;
tiff_compression1_strings[0].name = MENU_ITEM_TIFF_COMP_NONE;
tiff_compression1_strings[0].number = COMPRESSION_NONE;
@@ -1555,12 +1567,12 @@ static void xsane_image_notebook(GtkWidget *notebook)
#endif /* HAVE_LIBTIFF */
- DBG(DBG_proc, "xsane_image_notebook\n");
+ DBG(DBG_proc, "xsane_filetype_notebook\n");
/* Image options notebook page */
setup_vbox = gtk_vbox_new(FALSE, 5);
- label = gtk_label_new(NOTEBOOK_IMAGE_OPTIONS);
+ label = gtk_label_new(NOTEBOOK_FILETYPE_OPTIONS);
gtk_notebook_append_page(GTK_NOTEBOOK(notebook), setup_vbox, label);
gtk_widget_show(setup_vbox);
@@ -1575,6 +1587,21 @@ static void xsane_image_notebook(GtkWidget *notebook)
gtk_widget_show(vbox);
+ /* reduce 16bit to 8bit */
+ hbox = gtk_hbox_new(/* homogeneous */ FALSE, 0);
+ gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 2);
+ button = gtk_check_button_new_with_label(RADIO_BUTTON_REDUCE_16BIT_TO_8BIT);
+ xsane_back_gtk_set_tooltip(xsane.tooltips, button, DESC_REDUCE_16BIT_TO_8BIT);
+ gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button), preferences.reduce_16bit_to_8bit);
+ gtk_box_pack_start(GTK_BOX(hbox), button, TRUE, TRUE, 2);
+ gtk_widget_show(button);
+ gtk_widget_show(hbox);
+ xsane_setup.reduce_16bit_to_8bit_button = button;
+
+
+ xsane_separator_new(vbox, 4);
+
+
/* save pnm16 as ascii */
hbox = gtk_hbox_new(/* homogeneous */ FALSE, 0);
gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 2);
@@ -1586,16 +1613,31 @@ static void xsane_image_notebook(GtkWidget *notebook)
gtk_widget_show(hbox);
xsane_setup.save_pnm16_as_ascii_button = button;
- /* reduce 16bit to 8bit */
+
+#ifdef HAVE_LIBZ
+ /* save ps with zlib compression / flatdecode = ps level 3 */
hbox = gtk_hbox_new(/* homogeneous */ FALSE, 0);
gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 2);
- button = gtk_check_button_new_with_label(RADIO_BUTTON_REDUCE_16BIT_TO_8BIT);
- xsane_back_gtk_set_tooltip(xsane.tooltips, button, DESC_REDUCE_16BIT_TO_8BIT);
- gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button), preferences.reduce_16bit_to_8bit);
+ button = gtk_check_button_new_with_label(RADIO_BUTTON_SAVE_PS_FLATDECODED);
+ xsane_back_gtk_set_tooltip(xsane.tooltips, button, DESC_SAVE_PS_FLATDECODED);
+ gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button), preferences.save_ps_flatdecoded);
gtk_box_pack_start(GTK_BOX(hbox), button, TRUE, TRUE, 2);
gtk_widget_show(button);
gtk_widget_show(hbox);
- xsane_setup.reduce_16bit_to_8bit_button = button;
+ xsane_setup.save_ps_flatdecoded_button = button;
+
+
+ /* save pdf with zlib compression / flatdecode */
+ hbox = gtk_hbox_new(/* homogeneous */ FALSE, 0);
+ gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 2);
+ button = gtk_check_button_new_with_label(RADIO_BUTTON_SAVE_PDF_FLATDECODED);
+ xsane_back_gtk_set_tooltip(xsane.tooltips, button, DESC_SAVE_PDF_FLATDECODED);
+ gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button), preferences.save_pdf_flatdecoded);
+ gtk_box_pack_start(GTK_BOX(hbox), button, TRUE, TRUE, 2);
+ gtk_widget_show(button);
+ gtk_widget_show(hbox);
+ xsane_setup.save_pdf_flatdecoded_button = button;
+#endif
#ifdef HAVE_LIBJPEG
@@ -1625,11 +1667,14 @@ static void xsane_image_notebook(GtkWidget *notebook)
#ifdef HAVE_LIBPNG
#ifdef HAVE_LIBZ
xsane_range_new(GTK_BOX(vbox), TEXT_SETUP_PNG_COMPRESSION, DESC_PNG_COMPRESSION, 0.0, Z_BEST_COMPRESSION, 1.0, 10.0, 0,
- &preferences.png_compression, (GtkObject **) &xsane_setup.pnm_image_compression_scale, 0, TRUE);
+ &preferences.png_compression, (GtkObject **) &xsane_setup.png_image_compression_scale, 0, TRUE);
#endif
#endif
#ifdef HAVE_LIBTIFF
+ xsane_range_new(GTK_BOX(vbox), TEXT_SETUP_TIFF_ZIP_COMPRESSION, DESC_TIFF_ZIP_COMPRESSION, 1.0, 9.0, 1.0, 6.0, 0,
+ &preferences.tiff_zip_compression, (GtkObject **) &xsane_setup.tiff_image_zip_compression_scale, 0, TRUE);
+
/* TIFF 16 BIT IMAGES COMPRESSION */
hbox = gtk_hbox_new(FALSE, 2);
@@ -2033,8 +2078,27 @@ static void xsane_fax_notebook(GtkWidget *notebook)
gtk_widget_show(hbox);
xsane_setup.fax_bottomoffset_entry = text;
+
+#ifdef HAVE_LIBZ
xsane_separator_new(vbox, 4);
+
+ /* flatdecoded = ps level 3 */
+ hbox = gtk_hbox_new(/* homogeneous */ FALSE, 0);
+ gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 2);
+ button = gtk_check_button_new_with_label(TEXT_SETUP_FAX_PS_FLATDECODED);
+ xsane_back_gtk_set_tooltip(xsane.tooltips, button, DESC_FAX_PS_FLATDECODED);
+ gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button), preferences.fax_ps_flatdecoded);
+ gtk_box_pack_start(GTK_BOX(hbox), button, TRUE, TRUE, 2);
+ gtk_widget_show(button);
+ gtk_widget_show(hbox);
+ xsane_setup.fax_ps_flatdecoded_button = button;
+#endif
+
+
+ xsane_separator_new(vbox, 4);
+
+
/* apply button */
hbox = gtk_hbox_new(/* homogeneous */ FALSE, 0);
@@ -2054,30 +2118,32 @@ static void xsane_fax_notebook(GtkWidget *notebook)
/* ---------------------------------------------------------------------------------------------------------------------- */
-static void xsane_setup_pop3_authentification_callback(GtkWidget *widget, gpointer data)
-{
- GtkWidget *pop3_vbox = (GtkWidget *) data;
+#ifdef XSANE_ACTIVATE_EMAIL
- gtk_widget_set_sensitive(pop3_vbox, (GTK_TOGGLE_BUTTON(widget)->active != 0));
-}
+static void xsane_email_notebook(GtkWidget *notebook)
+{
+ typedef struct show_range_mode_t
+ {
+ char *name;
+ int number;
+ } authentication_type;
-/* ---------------------------------------------------------------------------------------------------------------------- */
+#define AUTHENTICATION_NUMBER 4
-#ifdef XSANE_ACTIVATE_MAIL
-static void xsane_mail_notebook(GtkWidget *notebook)
-{
GtkWidget *setup_vbox, *vbox, *pop3_vbox, *hbox, *button, *label, *text, *frame;
+ GtkWidget *authentication_option_menu, *authentication_menu, *authentication_menu_item;
char buf[64];
char *password;
- int i;
+ authentication_type authentication_strings[AUTHENTICATION_NUMBER];
+ int i, select = 0;
- DBG(DBG_proc, "xsane_mail_notebook\n");
+ DBG(DBG_proc, "xsane_email_notebook\n");
/* Mail options notebook page */
setup_vbox = gtk_vbox_new(FALSE, 5);
- label = gtk_label_new(NOTEBOOK_MAIL_OPTIONS);
+ label = gtk_label_new(NOTEBOOK_EMAIL_OPTIONS);
gtk_notebook_append_page(GTK_NOTEBOOK(notebook), setup_vbox, label);
gtk_widget_show(setup_vbox);
@@ -2096,36 +2162,36 @@ static void xsane_mail_notebook(GtkWidget *notebook)
hbox = gtk_hbox_new(/* homogeneous */ FALSE, 0);
gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 2);
- label = gtk_label_new(TEXT_SETUP_MAIL_FROM);
+ label = gtk_label_new(TEXT_SETUP_EMAIL_FROM);
gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 2);
gtk_widget_show(label);
text = gtk_entry_new();
- xsane_back_gtk_set_tooltip(xsane.tooltips, text, DESC_MAIL_FROM);
+ xsane_back_gtk_set_tooltip(xsane.tooltips, text, DESC_EMAIL_FROM);
gtk_widget_set_size_request(text, 250, -1);
- gtk_entry_set_text(GTK_ENTRY(text), (char *) preferences.mail_from);
+ gtk_entry_set_text(GTK_ENTRY(text), (char *) preferences.email_from);
gtk_box_pack_end(GTK_BOX(hbox), text, FALSE, FALSE, 2);
gtk_widget_show(text);
gtk_widget_show(hbox);
- xsane_setup.mail_from_entry = text;
+ xsane_setup.email_from_entry = text;
/* reply to */
hbox = gtk_hbox_new(/* homogeneous */ FALSE, 0);
gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 2);
- label = gtk_label_new(TEXT_SETUP_MAIL_REPLY_TO);
+ label = gtk_label_new(TEXT_SETUP_EMAIL_REPLY_TO);
gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 2);
gtk_widget_show(label);
text = gtk_entry_new();
- xsane_back_gtk_set_tooltip(xsane.tooltips, text, DESC_MAIL_REPLY_TO);
+ xsane_back_gtk_set_tooltip(xsane.tooltips, text, DESC_EMAIL_REPLY_TO);
gtk_widget_set_size_request(text, 250, -1);
- gtk_entry_set_text(GTK_ENTRY(text), (char *) preferences.mail_reply_to);
+ gtk_entry_set_text(GTK_ENTRY(text), (char *) preferences.email_reply_to);
gtk_box_pack_end(GTK_BOX(hbox), text, FALSE, FALSE, 2);
gtk_widget_show(text);
gtk_widget_show(hbox);
- xsane_setup.mail_reply_to_entry = text;
+ xsane_setup.email_reply_to_entry = text;
xsane_separator_new(vbox, 2);
@@ -2142,11 +2208,11 @@ static void xsane_mail_notebook(GtkWidget *notebook)
text = gtk_entry_new();
xsane_back_gtk_set_tooltip(xsane.tooltips, text, DESC_SMTP_SERVER);
gtk_widget_set_size_request(text, 250, -1);
- gtk_entry_set_text(GTK_ENTRY(text), (char *) preferences.mail_smtp_server);
+ gtk_entry_set_text(GTK_ENTRY(text), (char *) preferences.email_smtp_server);
gtk_box_pack_end(GTK_BOX(hbox), text, FALSE, FALSE, 2);
gtk_widget_show(text);
gtk_widget_show(hbox);
- xsane_setup.mail_smtp_server_entry = text;
+ xsane_setup.email_smtp_server_entry = text;
/* smtp port */
@@ -2160,12 +2226,12 @@ static void xsane_mail_notebook(GtkWidget *notebook)
text = gtk_entry_new();
xsane_back_gtk_set_tooltip(xsane.tooltips, text, DESC_SMTP_PORT);
gtk_widget_set_size_request(text, 50, -1);
- snprintf(buf, sizeof(buf), "%d", preferences.mail_smtp_port);
+ snprintf(buf, sizeof(buf), "%d", preferences.email_smtp_port);
gtk_entry_set_text(GTK_ENTRY(text), (char *) buf);
gtk_box_pack_end(GTK_BOX(hbox), text, FALSE, FALSE, 2);
gtk_widget_show(text);
gtk_widget_show(hbox);
- xsane_setup.mail_smtp_port_entry = text;
+ xsane_setup.email_smtp_port_entry = text;
xsane_separator_new(vbox, 2);
@@ -2175,79 +2241,72 @@ static void xsane_mail_notebook(GtkWidget *notebook)
pop3_vbox = gtk_vbox_new(FALSE, 5);
gtk_widget_show(pop3_vbox);
- /* pop3 authentification */
+ /* email authentication */
hbox = gtk_hbox_new(/* homogeneous */ FALSE, 0);
gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 2);
- button = gtk_check_button_new_with_label(RADIO_BUTTON_POP3_AUTHENTIFICATION);
- g_signal_connect(GTK_OBJECT(button), "toggled", (GtkSignalFunc) xsane_setup_pop3_authentification_callback, (void *) pop3_vbox);
- xsane_back_gtk_set_tooltip(xsane.tooltips, button, DESC_POP3_AUTHENTIFICATION);
- gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button), preferences.mail_pop3_authentification);
- gtk_box_pack_start(GTK_BOX(hbox), button, TRUE, TRUE, 2);
- gtk_widget_show(button);
- gtk_widget_show(hbox);
- xsane_setup.mail_pop3_authentification_entry = button;
-
- /* place vbox for pop3 settings after check_button */
- gtk_box_pack_start(GTK_BOX(vbox), pop3_vbox, FALSE, FALSE, 2);
- gtk_widget_set_sensitive(pop3_vbox, (GTK_TOGGLE_BUTTON(button)->active != 0));
-
- /* pop3 server */
- hbox = gtk_hbox_new(/* homogeneous */ FALSE, 0);
- gtk_box_pack_start(GTK_BOX(pop3_vbox), hbox, FALSE, FALSE, 2);
- label = gtk_label_new(TEXT_SETUP_POP3_SERVER);
+ label = gtk_label_new(TEXT_SETUP_EMAIL_AUTHENTICATION);
gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 2);
gtk_widget_show(label);
- text = gtk_entry_new();
- xsane_back_gtk_set_tooltip(xsane.tooltips, text, DESC_POP3_SERVER);
- gtk_widget_set_size_request(text, 250, -1);
- gtk_entry_set_text(GTK_ENTRY(text), (char *) preferences.mail_pop3_server);
- gtk_box_pack_end(GTK_BOX(hbox), text, FALSE, FALSE, 2);
- gtk_widget_show(text);
- gtk_widget_show(hbox);
- xsane_setup.mail_pop3_server_entry = text;
+ authentication_strings[0].name = MENU_ITEM_AUTH_NONE;
+ authentication_strings[0].number = EMAIL_AUTH_NONE;
+ authentication_strings[1].name = MENU_ITEM_AUTH_POP3;
+ authentication_strings[1].number = EMAIL_AUTH_POP3;
+ authentication_strings[2].name = MENU_ITEM_AUTH_ASMTP_PLAIN;
+ authentication_strings[2].number = EMAIL_AUTH_ASMTP_PLAIN;
+ authentication_strings[3].name = MENU_ITEM_AUTH_ASMTP_LOGIN;
+ authentication_strings[3].number = EMAIL_AUTH_ASMTP_LOGIN;
+#if 0
+ authentication_strings[4].name = MENU_ITEM_AUTH_ASMTP_CRAM_MD5;
+ authentication_strings[4].number = EMAIL_AUTH_ASMTP_CRAM_MD5;
+#endif
+ authentication_option_menu = gtk_option_menu_new();
+ xsane_back_gtk_set_tooltip(xsane.tooltips, authentication_option_menu, DESC_EMAIL_AUTHENTICATION);
+ gtk_box_pack_end(GTK_BOX(hbox), authentication_option_menu, FALSE, FALSE, 2);
+ gtk_widget_show(authentication_option_menu);
+ gtk_widget_show(hbox);
- /* pop3 port */
- hbox = gtk_hbox_new(/* homogeneous */ FALSE, 0);
- gtk_box_pack_start(GTK_BOX(pop3_vbox), hbox, FALSE, FALSE, 2);
+ authentication_menu = gtk_menu_new();
- label = gtk_label_new(TEXT_SETUP_POP3_PORT);
- gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 2);
- gtk_widget_show(label);
+ for (i=1; i <= AUTHENTICATION_NUMBER; i++)
+ {
+ authentication_menu_item = gtk_menu_item_new_with_label(authentication_strings[i-1].name);
+ gtk_container_add(GTK_CONTAINER(authentication_menu), authentication_menu_item);
+ g_signal_connect(GTK_OBJECT(authentication_menu_item), "activate", (GtkSignalFunc) xsane_setup_authentication_type_callback, (void *) authentication_strings[i-1].number);
+ gtk_widget_show(authentication_menu_item);
+ if (authentication_strings[i-1].number == preferences.email_authentication)
+ {
+ select = i-1;
+ }
+ }
- text = gtk_entry_new();
- xsane_back_gtk_set_tooltip(xsane.tooltips, text, DESC_POP3_PORT);
- gtk_widget_set_size_request(text, 50, -1);
- snprintf(buf, sizeof(buf), "%d", preferences.mail_pop3_port);
- gtk_entry_set_text(GTK_ENTRY(text), (char *) buf);
- gtk_box_pack_end(GTK_BOX(hbox), text, FALSE, FALSE, 2);
- gtk_widget_show(text);
- gtk_widget_show(hbox);
- xsane_setup.mail_pop3_port_entry = text;
+ gtk_option_menu_set_menu(GTK_OPTION_MENU(authentication_option_menu), authentication_menu);
+ gtk_option_menu_set_history(GTK_OPTION_MENU(authentication_option_menu), select);
+ xsane_setup.email_authentication = preferences.email_authentication;
- /* pop3 username */
+ /* email authorization username */
hbox = gtk_hbox_new(/* homogeneous */ FALSE, 0);
- gtk_box_pack_start(GTK_BOX(pop3_vbox), hbox, FALSE, FALSE, 2);
+ gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 2);
- label = gtk_label_new(TEXT_SETUP_POP3_USER);
+ label = gtk_label_new(TEXT_SETUP_EMAIL_AUTH_USER);
gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 2);
gtk_widget_show(label);
text = gtk_entry_new();
- xsane_back_gtk_set_tooltip(xsane.tooltips, text, DESC_POP3_USER);
+ xsane_back_gtk_set_tooltip(xsane.tooltips, text, DESC_EMAIL_AUTH_USER);
gtk_widget_set_size_request(text, 250, -1);
- gtk_entry_set_text(GTK_ENTRY(text), (char *) preferences.mail_pop3_user);
+ gtk_entry_set_text(GTK_ENTRY(text), (char *) preferences.email_auth_user);
gtk_box_pack_end(GTK_BOX(hbox), text, FALSE, FALSE, 2);
gtk_widget_show(text);
gtk_widget_show(hbox);
- xsane_setup.mail_pop3_user_entry = text;
+ xsane_setup.email_auth_user_entry = text;
- /* pop3 password */
- password = strdup(preferences.mail_pop3_pass);
+ /* email authorization password */
+ password = strdup(preferences.email_auth_pass);
for (i=0; i<strlen(password); i++)
{
@@ -2255,44 +2314,66 @@ static void xsane_mail_notebook(GtkWidget *notebook)
}
hbox = gtk_hbox_new(/* homogeneous */ FALSE, 0);
- gtk_box_pack_start(GTK_BOX(pop3_vbox), hbox, FALSE, FALSE, 2);
+ gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 2);
- label = gtk_label_new(TEXT_SETUP_POP3_PASS);
+ label = gtk_label_new(TEXT_SETUP_EMAIL_AUTH_PASS);
gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 2);
gtk_widget_show(label);
text = gtk_entry_new();
- xsane_back_gtk_set_tooltip(xsane.tooltips, text, DESC_POP3_PASS);
+ xsane_back_gtk_set_tooltip(xsane.tooltips, text, DESC_EMAIL_AUTH_PASS);
gtk_widget_set_size_request(text, 250, -1);
gtk_entry_set_text(GTK_ENTRY(text), (char *) password);
gtk_entry_set_visibility(GTK_ENTRY(text), 0);
gtk_box_pack_end(GTK_BOX(hbox), text, FALSE, FALSE, 2);
gtk_widget_show(text);
gtk_widget_show(hbox);
- xsane_setup.mail_pop3_pass_entry = text;
+ xsane_setup.email_auth_pass_entry = text;
free(password);
+ /* place vbox for pop3 settings after check_button */
+ gtk_box_pack_start(GTK_BOX(vbox), pop3_vbox, FALSE, FALSE, 2);
+ gtk_widget_set_sensitive(pop3_vbox, preferences.email_authentication == EMAIL_AUTH_POP3);
- xsane_separator_new(vbox, 2);
+ /* pop3 server */
+ hbox = gtk_hbox_new(/* homogeneous */ FALSE, 0);
+ gtk_box_pack_start(GTK_BOX(pop3_vbox), hbox, FALSE, FALSE, 2);
+ label = gtk_label_new(TEXT_SETUP_POP3_SERVER);
+ gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 2);
+ gtk_widget_show(label);
- /* mailviewer */
+ text = gtk_entry_new();
+ xsane_back_gtk_set_tooltip(xsane.tooltips, text, DESC_POP3_SERVER);
+ gtk_widget_set_size_request(text, 250, -1);
+ gtk_entry_set_text(GTK_ENTRY(text), (char *) preferences.email_pop3_server);
+ gtk_box_pack_end(GTK_BOX(hbox), text, FALSE, FALSE, 2);
+ gtk_widget_show(text);
+ gtk_widget_show(hbox);
+ xsane_setup.email_pop3_server_entry = text;
+
+
+ /* pop3 port */
hbox = gtk_hbox_new(/* homogeneous */ FALSE, 0);
- gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 2);
+ gtk_box_pack_start(GTK_BOX(pop3_vbox), hbox, FALSE, FALSE, 2);
- label = gtk_label_new(TEXT_SETUP_MAIL_VIEWER);
+ label = gtk_label_new(TEXT_SETUP_POP3_PORT);
gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 2);
gtk_widget_show(label);
text = gtk_entry_new();
- xsane_back_gtk_set_tooltip(xsane.tooltips, text, DESC_MAIL_VIEWER);
- gtk_widget_set_size_request(text, 250, -1);
- gtk_entry_set_text(GTK_ENTRY(text), (char *) preferences.mail_viewer);
+ xsane_back_gtk_set_tooltip(xsane.tooltips, text, DESC_POP3_PORT);
+ gtk_widget_set_size_request(text, 50, -1);
+ snprintf(buf, sizeof(buf), "%d", preferences.email_pop3_port);
+ gtk_entry_set_text(GTK_ENTRY(text), (char *) buf);
gtk_box_pack_end(GTK_BOX(hbox), text, FALSE, FALSE, 2);
gtk_widget_show(text);
gtk_widget_show(hbox);
- xsane_setup.mail_viewer_entry = text;
+ xsane_setup.email_pop3_port_entry = text;
+
+
+ xsane_setup.pop3_vbox = pop3_vbox;
xsane_separator_new(vbox, 4);
@@ -2307,7 +2388,7 @@ static void xsane_mail_notebook(GtkWidget *notebook)
#else
button = gtk_button_new_with_label(BUTTON_APPLY);
#endif
- g_signal_connect(GTK_OBJECT(button), "clicked", (GtkSignalFunc) xsane_setup_mail_apply_changes, NULL);
+ g_signal_connect(GTK_OBJECT(button), "clicked", (GtkSignalFunc) xsane_setup_email_apply_changes, NULL);
gtk_box_pack_start(GTK_BOX(hbox), button, TRUE, TRUE, 0);
gtk_widget_show(button);
@@ -2768,6 +2849,15 @@ static void xsane_enhance_notebook_sensitivity(int lineart_mode)
/* ---------------------------------------------------------------------------------------------------------------------- */
+static void xsane_setup_authentication_type_callback(GtkWidget *widget, gpointer data)
+{
+ xsane_setup.email_authentication = (int) data;
+
+ gtk_widget_set_sensitive(xsane_setup.pop3_vbox, (xsane_setup.email_authentication == EMAIL_AUTH_POP3));
+}
+
+/* ---------------------------------------------------------------------------------------------------------------------- */
+
static void xsane_setup_show_range_mode_callback(GtkWidget *widget, gpointer data)
{
xsane_setup.show_range_mode = (int) data;
@@ -2805,27 +2895,10 @@ static void xsane_setup_preview_pipette_range_callback(GtkWidget *widget, gpoint
/* ---------------------------------------------------------------------------------------------------------------------- */
-static void xsane_setup_adf_mode_callback(GtkWidget *widget, gpointer data)
-{
- if (xsane_setup.adf_scansource)
- {
- free(xsane_setup.adf_scansource);
- xsane_setup.adf_scansource = NULL;
- }
-
- if (data)
- {
- xsane_setup.adf_scansource = strdup( (char *) data);
- }
-}
-
-/* ---------------------------------------------------------------------------------------------------------------------- */
-
static void xsane_enhance_notebook(GtkWidget *notebook)
{
GtkWidget *setup_vbox, *vbox, *hbox, *button, *label, *text, *frame;
GtkWidget *lineart_mode_option_menu, *lineart_mode_menu, *lineart_mode_item;
- GtkWidget *adf_option_menu, *adf_menu, *adf_item;
GtkWidget *gray_option_menu, *gray_menu, *gray_item;
GtkWidget *preview_pipette_range_option_menu, *preview_pipette_range_menu, *preview_pipette_range_item;
const SANE_Option_Descriptor *opt;
@@ -3130,87 +3203,6 @@ static void xsane_enhance_notebook(GtkWidget *notebook)
xsane_separator_new(vbox, 4);
- /* ADF modus menu */
-
- hbox = gtk_hbox_new(FALSE, 2);
- gtk_container_set_border_width(GTK_CONTAINER(hbox), 2);
- gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0);
-
- label = gtk_label_new(TEXT_SETUP_ADF_MODE);
- gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 2);
- gtk_widget_show(label);
-
- if (xsane.adf_scansource)
- {
- xsane_setup.adf_scansource = strdup(xsane.adf_scansource);
- }
- else
- {
- xsane_setup.adf_scansource = NULL;
- }
-
- select = 0;
- adf_menu = gtk_menu_new();
-
- adf_item = gtk_menu_item_new_with_label(MENU_ITEM_SELECTION_NONE);
- gtk_container_add(GTK_CONTAINER(adf_menu), adf_item);
- g_signal_connect(GTK_OBJECT(adf_item), "activate", (GtkSignalFunc) xsane_setup_adf_mode_callback, NULL);
- gtk_widget_show(adf_item);
-
- opt = xsane_get_option_descriptor(xsane.dev, xsane.well_known.scansource);
- if (opt)
- {
- if (SANE_OPTION_IS_ACTIVE(opt->cap))
- {
- switch (opt->constraint_type)
- {
- case SANE_CONSTRAINT_STRING_LIST:
- {
- char *set;
- SANE_Status status;
-
- /* use a "list-selection" widget */
- set = malloc(opt->size);
- status = xsane_control_option(xsane.dev, xsane.well_known.scansource, SANE_ACTION_GET_VALUE, set, 0);
-
- for (i=0; opt->constraint.string_list[i]; i++)
- {
- adf_item = gtk_menu_item_new_with_label(_BGT(opt->constraint.string_list[i]));
- gtk_container_add(GTK_CONTAINER(adf_menu), adf_item);
- g_signal_connect(GTK_OBJECT(adf_item), "activate", (GtkSignalFunc) xsane_setup_adf_mode_callback, (void *) opt->constraint.string_list[i]);
-
- gtk_widget_show(adf_item);
-
- if (xsane.adf_scansource)
- {
- if (!strcmp(opt->constraint.string_list[i], xsane.adf_scansource))
- {
- select = i+1;
- }
- }
- }
- }
- break;
-
- default:
- DBG(DBG_error, "adf_scansource_selection: %s %d\n", ERR_UNKNOWN_CONSTRAINT_TYPE, opt->constraint_type);
- }
- }
- }
-
- adf_option_menu = gtk_option_menu_new();
- xsane_back_gtk_set_tooltip(xsane.tooltips, adf_option_menu, DESC_ADF_MODE);
- gtk_box_pack_end(GTK_BOX(hbox), adf_option_menu, FALSE, FALSE, 2);
- gtk_option_menu_set_menu(GTK_OPTION_MENU(adf_option_menu), adf_menu);
- gtk_option_menu_set_history(GTK_OPTION_MENU(adf_option_menu), select);
- gtk_widget_show(hbox);
-
- gtk_widget_show(adf_option_menu);
-
-
- xsane_separator_new(vbox, 4);
-
-
/* apply button */
hbox = gtk_hbox_new(/* homogeneous */ FALSE, 0);
@@ -3266,11 +3258,11 @@ void xsane_setup_dialog(GtkWidget *widget, gpointer data)
xsane_saving_notebook(notebook);
- xsane_image_notebook(notebook);
+ xsane_filetype_notebook(notebook);
xsane_printer_notebook(notebook);
xsane_fax_notebook(notebook);
-#ifdef XSANE_ACTIVATE_MAIL
- xsane_mail_notebook(notebook);
+#ifdef XSANE_ACTIVATE_EMAIL
+ xsane_email_notebook(notebook);
#endif
xsane_ocr_notebook(notebook);
xsane_display_notebook(notebook);
diff --git a/src/xsane-setup.h b/src/xsane-setup.h
index 06e2949..8055dfb 100644
--- a/src/xsane-setup.h
+++ b/src/xsane-setup.h
@@ -26,8 +26,12 @@
/* ---------------------------------------------------------------------------------------------------------------------- */
+#ifndef XSANE_SETUP_H
+# define XSANE_SETUP_H
+
extern void xsane_new_printer(void);
extern void xsane_update_int(GtkWidget *widget, int *val);
extern void xsane_setup_dialog(GtkWidget *widget, gpointer data);
+#endif
/* ---------------------------------------------------------------------------------------------------------------------- */
diff --git a/src/xsane-text.h b/src/xsane-text.h
index 3334f14..7614bfc 100644
--- a/src/xsane-text.h
+++ b/src/xsane-text.h
@@ -48,9 +48,10 @@
#define WINDOW_FAX_PROJECT _("fax project")
#define WINDOW_FAX_RENAME _("rename fax page")
#define WINDOW_FAX_INSERT _("insert ps-file into fax")
-#define WINDOW_MAIL_PROJECT _("mail project")
-#define WINDOW_MAIL_RENAME _("rename mail image")
-#define WINDOW_MAIL_INSERT _("insert file into mail")
+#define WINDOW_EMAIL_PROJECT _("E-mail project")
+#define WINDOW_EMAIL_RENAME _("rename e-mail image")
+#define WINDOW_EMAIL_INSERT _("insert file into e-mail")
+#define WINDOW_MULTIPAGE_PROJECT _("multipage project")
#define WINDOW_PRESET_AREA_RENAME _("rename preset area")
#define WINDOW_PRESET_AREA_ADD _("add preset area")
#define WINDOW_MEDIUM_RENAME _("rename medium")
@@ -134,6 +135,7 @@
#define BUTTON_FILE_INSERT _("Insert file")
#define BUTTON_CREATE_PROJECT _("Create project")
#define BUTTON_SEND_PROJECT _("Send project")
+#define BUTTON_SAVE_MULTIPAGE _("Save multipage file")
#define BUTTON_DELETE_PROJECT _("Delete project")
#define BUTTON_ADD_PRINTER _("Add printer")
#define BUTTON_DELETE_PRINTER _("Delete printer")
@@ -145,10 +147,12 @@
#define BUTTON_SCALE_BIND _("Bind scale")
#define RADIO_BUTTON_FINE_MODE _("Fine mode")
-#define RADIO_BUTTON_HTML_MAIL _("HTML mail")
+#define RADIO_BUTTON_HTML_EMAIL _("HTML e-mail")
#define RADIO_BUTTON_SAVE_DEVPREFS_AT_EXIT _("Save device preferences at exit")
#define RADIO_BUTTON_OVERWRITE_WARNING _("Overwrite warning")
#define RADIO_BUTTON_SKIP_EXISTING_NRS _("Skip existing filenames")
+#define RADIO_BUTTON_SAVE_PS_FLATDECODED _("Save postscript zlib compressed (ps level 3)")
+#define RADIO_BUTTON_SAVE_PDF_FLATDECODED _("Save PDF zlib compressed")
#define RADIO_BUTTON_SAVE_PNM16_AS_ASCII _("Save 16bit pnm in ascii format")
#define RADIO_BUTTON_REDUCE_16BIT_TO_8BIT _("Reduce 16 bit image to 8 bit")
#define RADIO_BUTTON_WINDOW_FIXED _("Main window size fixed")
@@ -157,14 +161,11 @@
#define RADIO_BUTTON_AUTOENHANCE_GAMMA _("Autoenhance gamma")
#define RADIO_BUTTON_PRESELECT_SCANAREA _("Preselect scanarea")
#define RADIO_BUTTON_AUTOCORRECT_COLORS _("Autocorrect colors")
-#define RADIO_BUTTON_POP3_AUTHENTIFICATION _("POP3 authentification")
#define RADIO_BUTTON_OCR_USE_GUI_PIPE _("Use GUI progress pipe")
#define TEXT_SCANNING_DEVICES _("scanning for devices")
#define TEXT_AVAILABLE_DEVICES _("Available devices:")
#define TEXT_XSANE_OPTIONS _("XSane options")
-#define TEXT_XSANE_MODE _("XSane mode")
-#define TEXT_FILENAME_COUNTER_STEP _("Step")
#define TEXT_FILETYPE _("Type")
#define TEXT_SCANNER_BACKEND _("Scanner and backend:")
#define TEXT_VENDOR _("Vendor:")
@@ -219,7 +220,7 @@
"This program is distributed in the hope that it will be useful, but\n" \
"WITHOUT ANY WARRANTY; without even the implied warranty of\n" \
"MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n")
-#define TEXT_EMAIL _("Email:")
+#define TEXT_EMAIL_ADR _("E-mail:")
#define TEXT_HOMEPAGE _("Homepage:")
#define TEXT_FILE _("File:")
#define TEXT_TRANSLATION _("Translation:")
@@ -227,19 +228,22 @@
/* Please translate this to something like */
/* translation to YOUR LANGUAGE\n */
/* by YOUR NAME\n */
-/* Email: your.name@yourdomain.com\n */
+/* E-mail: your.name@yourdomain.com\n */
#define TEXT_TRANSLATION_INFO _("untranslated original english text\n" \
"by Oliver Rauch\n" \
- "Email: Oliver.Rauch@rauch-domain.de\n")
+ "E-mail: Oliver.Rauch@rauch-domain.de\n")
#define TEXT_INFO_BOX _("0x0: 0KB")
#define TEXT_ADF_PAGES_SCANNED _("Scanned pages: ")
-#define TEXT_MAIL_TEXT _("Email text:")
+#define TEXT_EMAIL_TEXT _("E-mail text:")
#define TEXT_ATTACHMENTS _("Attachments:")
-#define TEXT_MAIL_STATUS _("Project status:")
-#define TEXT_MAIL_FILETYPE _("Mail image filetype:")
+#define TEXT_EMAIL_STATUS _("Project status:")
+#define TEXT_EMAIL_FILETYPE _("E-mail image filetype:")
+
+#define TEXT_PAGES _("Pages:")
+#define TEXT_MULTIPAGE_FILETYPE _("Multipage document filetype:")
#define TEXT_MEDIUM_DEFINITION_NAME _("Medium Name:")
@@ -270,12 +274,14 @@
#define TEXT_SETUP_PRINTER_GAMMA_RED _("Printer gamma red:")
#define TEXT_SETUP_PRINTER_GAMMA_GREEN _("Printer gamma green:")
#define TEXT_SETUP_PRINTER_GAMMA_BLUE _("Printer gamma blue:")
+#define TEXT_SETUP_PRINTER_PS_FLATDECODED _("Create zlib compressed postscript image (ps level 3) for printing")
#define TEXT_SETUP_TMP_PATH _("Temporary directory")
#define TEXT_SETUP_IMAGE_PERMISSION _("Image-file permissions")
#define TEXT_SETUP_DIR_PERMISSION _("Directory permissions")
#define TEXT_SETUP_JPEG_QUALITY _("JPEG image quality")
#define TEXT_SETUP_PNG_COMPRESSION _("PNG image compression")
#define TEXT_SETUP_FILENAME_COUNTER_LEN _("Filename counter length")
+#define TEXT_SETUP_TIFF_ZIP_COMPRESSION _("TIFF zip compression rate")
#define TEXT_SETUP_TIFF_COMPRESSION_16 _("TIFF 16 bit image compression")
#define TEXT_SETUP_TIFF_COMPRESSION_8 _("TIFF 8 bit image compression")
#define TEXT_SETUP_TIFF_COMPRESSION_1 _("TIFF lineart image compression")
@@ -286,7 +292,6 @@
#define TEXT_SETUP_PREVIEW_GAMMA_GREEN _("Preview gamma green:")
#define TEXT_SETUP_PREVIEW_GAMMA_BLUE _("Preview gamma blue:")
#define TEXT_SETUP_LINEART_MODE _("Threshold option:")
-#define TEXT_SETUP_ADF_MODE _("Automatic Document Feeder Modus:")
#define TEXT_SETUP_PREVIEW_PIPETTE_RANGE _("Preview pipette range")
#define TEXT_SETUP_THRESHOLD_MIN _("Threshold minimum:")
#define TEXT_SETUP_THRESHOLD_MAX _("Threshold maximum:")
@@ -305,15 +310,16 @@
#define TEXT_SETUP_FAX_HEIGHT _("Height")
#define TEXT_SETUP_FAX_LEFT _("Left offset")
#define TEXT_SETUP_FAX_BOTTOM _("Bottom offset")
+#define TEXT_SETUP_FAX_PS_FLATDECODED _("Create zlib compressed postscript image (ps level 3) for fax")
#define TEXT_SETUP_SMTP_SERVER _("SMTP server:")
#define TEXT_SETUP_SMTP_PORT _("SMTP port:")
-#define TEXT_SETUP_MAIL_FROM _("From:")
-#define TEXT_SETUP_MAIL_REPLY_TO _("Reply to:")
+#define TEXT_SETUP_EMAIL_FROM _("From:")
+#define TEXT_SETUP_EMAIL_REPLY_TO _("Reply to:")
+#define TEXT_SETUP_EMAIL_AUTHENTICATION _("E-mail authentication")
+#define TEXT_SETUP_EMAIL_AUTH_USER _("User:")
+#define TEXT_SETUP_EMAIL_AUTH_PASS _("Password:")
#define TEXT_SETUP_POP3_SERVER _("POP3 server:")
#define TEXT_SETUP_POP3_PORT _("POP3 port:")
-#define TEXT_SETUP_POP3_USER _("POP3 user:")
-#define TEXT_SETUP_POP3_PASS _("POP3 password:")
-#define TEXT_SETUP_MAIL_VIEWER _("Viewer (png):")
#define TEXT_SETUP_OCR_COMMAND _("OCR Command:")
#define TEXT_SETUP_OCR_INPUTFILE_OPT _("Inputfile option:")
#define TEXT_SETUP_OCR_OUTPUTFILE_OPT _("Outputfile option:")
@@ -326,10 +332,10 @@
#define TEXT_NEW_MEDIA_NAME _("new media")
#define NOTEBOOK_SAVING_OPTIONS _("Save")
-#define NOTEBOOK_IMAGE_OPTIONS _("Image")
+#define NOTEBOOK_FILETYPE_OPTIONS _("Filetype")
#define NOTEBOOK_COPY_OPTIONS _("Copy")
#define NOTEBOOK_FAX_OPTIONS _("Fax")
-#define NOTEBOOK_MAIL_OPTIONS _("Mail")
+#define NOTEBOOK_EMAIL_OPTIONS _("E-mail")
#define NOTEBOOK_OCR_OPTIONS _("OCR")
#define NOTEBOOK_DISPLAY_OPTIONS _("Display")
#define NOTEBOOK_ENHANCE_OPTIONS _("Enhancement")
@@ -337,8 +343,9 @@
#define MENU_ITEM_SAVE _("Save")
#define MENU_ITEM_VIEWER _("Viewer")
#define MENU_ITEM_COPY _("Copy")
+#define MENU_ITEM_MULTIPAGE _("Multipage")
#define MENU_ITEM_FAX _("Fax")
-#define MENU_ITEM_MAIL _("Email")
+#define MENU_ITEM_EMAIL _("E-mail")
#define MENU_ITEM_SHOW_TOOLTIPS _("Show tooltips")
#define MENU_ITEM_SHOW_PREVIEW _("Show preview")
@@ -379,6 +386,7 @@
#define MENU_ITEM_TIFF_COMP_CCITFAX4 _("CCITT Group 4 Fax compression")
#define MENU_ITEM_TIFF_COMP_JPEG _("JPEG DCT compression")
#define MENU_ITEM_TIFF_COMP_PACKBITS _("pack bits")
+#define MENU_ITEM_TIFF_COMP_DEFLATE _("deflate")
#define MENU_ITEM_RANGE_SCALE _("Slider (Scale)")
#define MENU_ITEM_RANGE_SCROLLBAR _("Slider (Scrollbar)")
@@ -401,8 +409,15 @@
#define MENU_ITEM_MOVE_UP _("Move item up")
#define MENU_ITEM_MOVE_DWN _("Move item down")
+#define MENU_ITEM_AUTH_NONE _("no authentication")
+#define MENU_ITEM_AUTH_POP3 _("POP3 before SMTP")
+#define MENU_ITEM_AUTH_ASMTP_PLAIN _("ASMTP Plain")
+#define MENU_ITEM_AUTH_ASMTP_LOGIN _("ASMTP Login")
+#define MENU_ITEM_AUTH_ASMTP_CRAM_MD5 _("ASMTP CRAM-MD5")
+
#define PROGRESS_SCANNING _("Scanning")
#define PROGRESS_RECEIVING_FRAME_DATA _("Receiving %s data")
+#define PROGRESS_PAGE _("page")
#define PROGRESS_TRANSFERING_DATA _("Transfering image")
#define PROGRESS_ROTATING_DATA _("Rotating image")
@@ -420,8 +435,8 @@
#define DESC_SCAN_CANCEL _("Cancel scan <ESC>")
#define DESC_PREVIEW_ACQUIRE _("Acquire preview scan <Alt-p>")
#define DESC_PREVIEW_CANCEL _("Cancel preview scan <Alt-ESC>")
-#define DESC_XSANE_MODE _("save-<Ctrl-s>, view-<Ctrl-v>, photocopy-<Ctrl-c>, " \
- "fax-<Ctrl-f> or mail-<Ctrl-m>")
+#define DESC_XSANE_MODE _("viewer-<Ctrl-v>, save-<Ctrl-s>, photocopy-<Ctrl-c>, " \
+ "multipage-<Ctrl-m>, fax-<Ctrl-f> or e-mail-<Ctrl-e>")
#define DESC_XSANE_MEDIUM _("Select source medium type.\n" \
"To rename, reorder or delete an entry use context menu (right mouse button).\n"\
"To create a medium enable the option edit medium definition in preferences menu.")
@@ -433,11 +448,13 @@
#define DESC_FAXPROJECT _("Enter name of fax project")
#define DESC_FAXPAGENAME _("Enter new name for faxpage")
#define DESC_FAXRECEIVER _("Enter receiver phone number or address")
-#define DESC_MAILPROJECT _("Enter name of mail project")
-#define DESC_MAILIMAGENAME _("Enter new name for mail image")
-#define DESC_MAILRECEIVER _("Enter email address")
-#define DESC_MAILSUBJECT _("Enter subject of email")
-#define DESC_MAIL_FILETYPE _("Select filetype for image attachments")
+#define DESC_EMAIL_PROJECT _("Enter name of e-mail project")
+#define DESC_EMAIL_IMAGENAME _("Enter new name for e-mail image")
+#define DESC_EMAIL_RECEIVER _("Enter e-mail address")
+#define DESC_EMAIL_SUBJECT _("Enter subject of e-mail")
+#define DESC_EMAIL_FILETYPE _("Select filetype for image attachments")
+#define DESC_MULTIPAGE_PROJECT _("Enter name of multipage project")
+#define DESC_MULTIPAGE_FILETYPE _("Select filetype for multipage file")
#define DESC_PRESET_AREA_RENAME _("Enter new name for preset area")
#define DESC_PRESET_AREA_ADD _("Enter name for new preset area")
#define DESC_MEDIUM_RENAME _("Enter new name for medium definition")
@@ -508,17 +525,23 @@
#define DESC_PRINTER_GAMMA_RED _("Additional gamma value for red component for photocopy")
#define DESC_PRINTER_GAMMA_GREEN _("Additional gamma value for green component for photocopy")
#define DESC_PRINTER_GAMMA_BLUE _("Additional gamma value for blue component for photocopy")
+#define DESC_PRINTER_PS_FLATDECODED _("Create zlib compressed postscript image for printer (flatdecode).\n" \
+ "The printer has to understand postscript level 3!")
#define DESC_TMP_PATH _("Path to temp directory")
#define DESC_BUTTON_TMP_PATH_BROWSE _("Browse for temporary directory")
#define DESC_JPEG_QUALITY _("Quality in percent if image is saved as jpeg or tiff with jpeg compression")
#define DESC_PNG_COMPRESSION _("Compression if image is saved as png")
#define DESC_FILENAME_COUNTER_LEN _("Minimum length of counter in filename")
+#define DESC_TIFF_ZIP_COMPRESSION _("Compression rate for zip compressed tiff (deflate)")
#define DESC_TIFF_COMPRESSION_16 _("Compression type if 16 bit image is saved as tiff")
#define DESC_TIFF_COMPRESSION_8 _("Compression type if 8 bit image is saved as tiff")
#define DESC_TIFF_COMPRESSION_1 _("Compression type if lineart image is saved as tiff")
#define DESC_SAVE_DEVPREFS_AT_EXIT _("Save device dependant preferences in default file at exit of xsane")
#define DESC_OVERWRITE_WARNING _("Warn before overwriting an existing file")
#define DESC_SKIP_EXISTING _("If filename counter is automatically increased, used numbers are skipped")
+#define DESC_SAVE_PS_FLATDECODED _("compress postscript image with zlib algorithm (flatdecode). " \
+ "When you want to print such a file your printer has to understand postscript level 3")
+#define DESC_SAVE_PDF_FLATDECODED _("compress PDF image with zlib algorithm (flatdecode).")
#define DESC_SAVE_PNM16_AS_ASCII _("When a 16 bit image shall be saved in pnm format then use ascii format " \
"instead of binary format. The binary format is a new format that is not " \
"supported by all programs. The ascii format is supported by more programs " \
@@ -545,8 +568,7 @@
#define DESC_PREVIEW_THRESHOLD_MAX _("The scanner's maximum threshold level in %")
#define DESC_PREVIEW_THRESHOLD_MUL _("Multiplier to make XSane threshold range and scanner threshold range the same")
#define DESC_PREVIEW_THRESHOLD_OFF _("Offset to make XSane threshold range and scanner threshold range the same")
-#define DESC_ADF_MODE _("Select scansource for Automatic Document feeder. " \
- "If this scansource is selected XSane scans until \"out of paper\" or error.")
+#define DESC_ADF_PAGES_MAX _("Number of pages to scan")
#define DESC_PREVIEW_PIPETTE_RANGE _("dimension of square that is used to average color for pipette function")
#define DESC_DOC_VIEWER _("Enter command to be executed to display helpfiles, must be a html-viewer!")
#define DESC_AUTOENHANCE_GAMMA _("Change gamma value when autoenhancement button is pressed")
@@ -564,17 +586,17 @@
#define DESC_FAX_HEIGHT _("Height of printable area")
#define DESC_FAX_LEFTOFFSET _("Left offset from the edge of the paper to the printable area")
#define DESC_FAX_BOTTOMOFFSET _("Bottom offset from the edge of the paper to the printable area")
+#define DESC_FAX_PS_FLATDECODED _("Create zlib compressed postscript image for fax (flatdecode)")
#define DESC_SMTP_SERVER _("IP Address or Domain name of SMTP server")
#define DESC_SMTP_PORT _("port to connect to SMTP server")
-#define DESC_MAIL_FROM _("enter your email address")
-#define DESC_MAIL_REPLY_TO _("enter email address for replied emails")
-#define DESC_POP3_AUTHENTIFICATION _("Authentificate at POP3 server before sending mail")
+#define DESC_EMAIL_FROM _("enter your e-mail address")
+#define DESC_EMAIL_REPLY_TO _("enter e-mail address for replied e-mails")
+#define DESC_EMAIL_AUTHENTICATION _("Type of authentication before sending e-mail")
+#define DESC_EMAIL_AUTH_USER _("user name for e-mail server")
+#define DESC_EMAIL_AUTH_PASS _("password for e-mail server")
#define DESC_POP3_SERVER _("IP Address or Domain name of POP3 server")
#define DESC_POP3_PORT _("port to connect to POP3 server")
-#define DESC_POP3_USER _("user name for POP3 server")
-#define DESC_POP3_PASS _("password for POP3 server")
-#define DESC_MAIL_VIEWER _("Enter command to be executed to view a mail image")
-#define DESC_HTML_MAIL _("Mail is sent in html mode, place image with: <IMAGE>")
+#define DESC_HTML_EMAIL _("E-mail is sent in html mode, place image with: <IMAGE>")
#define DESC_OCR_COMMAND _("Enter command to start ocr program")
#define DESC_OCR_INPUTFILE_OPT _("Enter option of the ocr program to define input file")
#define DESC_OCR_OUTPUTFILE_OPT _("Enter option of the ocr program to define output file")
@@ -639,7 +661,10 @@
#define ERR_HOME_DIR _("Failed to determine home directory:")
#define ERR_CHANGE_WORKING_DIR _("Failed to change working directory to")
#define ERR_FILENAME_TOO_LONG _("Filename too long")
-#define ERR_CREATE_TEMP_FILE _("Could not create temporary file")
+#define ERR_CREATE_TEMP_FILE _("Could not create temporary file.\n\
+Open Menue Preferences->Setup Tab Save and\n\
+select a temporary directory where you have\n\
+write permissions." )
#define ERR_SET_OPTION _("Failed to set value of option")
#define ERR_GET_OPTION _("Failed to obtain value of option")
#define ERR_OPTION_COUNT _("Error obtaining option count")
@@ -670,7 +695,6 @@
#define ERR_FAILED_EXEC_DOC_VIEWER _("Failed to execute documentation viewer:")
#define ERR_FAILED_EXEC_FAX_VIEWER _("Failed to execute fax viewer:")
#define ERR_FAILED_EXEC_FAX_CMD _("Failed to execute fax command:")
-#define ERR_FAILED_EXEC_MAIL_VIEWER _("Failed to execute mail image viewer:")
#define ERR_FAILED_EXEC_OCR_CMD _("Failed to execute ocr command:")
#define ERR_BAD_FRAME_FORMAT _("bad frame format")
#define ERR_FAILED_SET_RESOLUTION _("unable to set resolution")
@@ -686,9 +710,6 @@
#define ERR_PREVIEW_BAD_DEPTH _("Preview cannot handle bit depth")
#define ERR_GIMP_SUPPORT_MISSING _("GIMP support missing")
-#define ERR_CREATE_PREVIEW_FILE _("Could not create temporary preview files")
-#define ERR_CREATE_PREVIEW_FILENAME _("Could not create filenames for preview files")
-
#define ERR_CREATE_FAX_PROJECT _("Could not create faxproject")
#define WARN_COUNTER_UNDERRUN _("Filename counter underrun")
@@ -738,8 +759,9 @@ The format of [DEVICE] is backendname:devicefile (e.g. umax:/dev/scanner).\n\
-V, --viewer start with viewer-mode active (default)\n\
-s, --save start with save-mode active\n\
-c, --copy start with copy-mode active\n\
+ -m, --multipage start with multipage-mode active\n\
-f, --fax start with fax-mode active\n\
- -m, --mail start with mail-mode active\n\
+ -e, --email start with e-mail-mode active\n\
-n, --no-mode-selection disable menu for XSane mode selection\n\
\n\
-F, --Fixed fixed main window size (overwrite preferences value)\n\
@@ -805,22 +827,26 @@ The format of [DEVICE] is backendname:devicefile (e.g. umax:/dev/scanner).\n\
#define MENU_ITEM_MEDIUM_KONICA_NEG_VX_100 N_("Konica negative VX 100")
#define MENU_ITEM_MEDIUM_ROSSMANN_NEG_HR_100 N_("Rossmann negative HR 100")
-#define TEXT_MAIL_STATUS_NOT_CREATED N_("Mail project not created")
-#define TEXT_MAIL_STATUS_CREATED N_("Mail project created")
-#define TEXT_MAIL_STATUS_CHANGED N_("Mail project changed")
-#define TEXT_MAIL_STATUS_ERR_READ_PROJECT N_("Error reading mailproject")
-#define TEXT_MAIL_STATUS_POP3_CONNECTION_FAILED N_("POP3 connection failed")
-#define TEXT_MAIL_STATUS_POP3_LOGIN_FAILED N_("POP3 login failed")
-#define TEXT_MAIL_STATUS_SMTP_CONNECTION_FAILED N_("SMTP connection failed")
-#define TEXT_MAIL_STATUS_SMTP_ERR_FROM N_("From entry not accepted")
-#define TEXT_MAIL_STATUS_SMTP_ERR_RCPT N_("Receiver entry not accepted")
-#define TEXT_MAIL_STATUS_SMTP_ERR_DATA N_("Mail data not accepted")
-#define TEXT_MAIL_STATUS_SENDING N_("Sending mail")
-#define TEXT_MAIL_STATUS_SENT N_("Mail has been sent")
-
-#define TEXT_FAX_STATUS_NOT_CREATED N_("Fax project not created")
-#define TEXT_FAX_STATUS_CREATED N_("Fax project created")
-#define TEXT_FAX_STATUS_CHANGED N_("Fax project changed")
+#define TEXT_PROJECT_STATUS_NOT_CREATED N_("Project not created")
+#define TEXT_PROJECT_STATUS_CREATED N_("Project created")
+#define TEXT_PROJECT_STATUS_CHANGED N_("Project changed")
+#define TEXT_PROJECT_STATUS_ERR_READ_PROJECT N_("Error reading project")
+
+#define TEXT_PROJECT_STATUS_FILE_SAVING_ERROR N_("Error saving file")
+#define TEXT_PROJECT_STATUS_FILE_SAVING N_("Saving file")
+#define TEXT_PROJECT_STATUS_FILE_SAVING_ABORTED N_("Aborted saving file")
+#define TEXT_PROJECT_STATUS_FILE_SAVED N_("File has been saved")
+
+#define TEXT_EMAIL_STATUS_POP3_CONNECTION_FAILED N_("POP3 connection failed")
+#define TEXT_EMAIL_STATUS_POP3_LOGIN_FAILED N_("POP3 login failed")
+#define TEXT_EMAIL_STATUS_ASMTP_AUTH_FAILED N_("ASMTP authentication failed")
+#define TEXT_EMAIL_STATUS_SMTP_CONNECTION_FAILED N_("SMTP connection failed")
+#define TEXT_EMAIL_STATUS_SMTP_ERR_FROM N_("From entry not accepted")
+#define TEXT_EMAIL_STATUS_SMTP_ERR_RCPT N_("Receiver entry not accepted")
+#define TEXT_EMAIL_STATUS_SMTP_ERR_DATA N_("E-mail data not accepted")
+#define TEXT_EMAIL_STATUS_SENDING N_("Sending e-mail")
+#define TEXT_EMAIL_STATUS_SENT N_("E-mail has been sent")
+
#define TEXT_FAX_STATUS_QUEUEING_FAX N_("Queueing Fax")
#define TEXT_FAX_STATUS_FAX_QUEUED N_("Fax is queued")
#endif
diff --git a/src/xsane-viewer.c b/src/xsane-viewer.c
index 6a58f8b..718ab6d 100644
--- a/src/xsane-viewer.c
+++ b/src/xsane-viewer.c
@@ -65,7 +65,8 @@ static GtkWidget *xsane_viewer_file_build_menu(Viewer *v);
static GtkWidget *xsane_viewer_edit_build_menu(Viewer *v);
static GtkWidget *xsane_viewer_filters_build_menu(Viewer *v);
static int xsane_viewer_read_image(Viewer *v);
-Viewer *xsane_viewer_new(char *filename, int allow_reduction_to_lineart, char *output_filename, viewer_modification allow_modification);
+Viewer *xsane_viewer_new(char *filename, char *selection_filetype, int allow_reduction_to_lineart,
+ char *output_filename, viewer_modification allow_modification, int image_saved);
/* ---------------------------------------------------------------------------------------------------------------------- */
@@ -281,7 +282,7 @@ static void xsane_viewer_save_callback(GtkWidget *window, gpointer data)
snprintf(windowname, sizeof(windowname), "%s %s %s", xsane.prog_name, WINDOW_VIEWER_OUTPUT_FILENAME, xsane.device_text);
umask((mode_t) preferences.directory_umask); /* define new file permissions */
- abort = xsane_back_gtk_get_filename(windowname, outputfilename, sizeof(outputfilename), outputfilename, &preferences.filetype, TRUE, TRUE, FALSE, TRUE);
+ abort = xsane_back_gtk_get_filename(windowname, outputfilename, sizeof(outputfilename), outputfilename, &v->selection_filetype, TRUE, TRUE, FALSE, TRUE);
umask(XSANE_DEFAULT_UMASK); /* define new file permissions */
if (abort)
@@ -297,9 +298,14 @@ static void xsane_viewer_save_callback(GtkWidget *window, gpointer data)
}
v->output_filename = strdup(outputfilename);
+
+#if 0
+ /* to be removed */
xsane_update_counter_in_filename(&v->output_filename, FALSE, 0, preferences.filename_counter_len); /* set correct counter length */
+#endif
- if (preferences.overwrite_warning) /* test if filename already used */
+
+ if ((preferences.overwrite_warning) && (!v->keep_viewer_pnm_format)) /* test if filename already used when filename can be changed by user */
{
FILE *testfile;
@@ -320,9 +326,10 @@ static void xsane_viewer_save_callback(GtkWidget *window, gpointer data)
inputfilename = strdup(v->filename);
- output_format = xsane_identify_output_format(v->output_filename, preferences.filetype, 0);
+ output_format = xsane_identify_output_format(v->output_filename, v->selection_filetype, 0);
- if ((!v->allow_reduction_to_lineart) && (output_format == XSANE_PNM)) /* save PNM but do not reduce to lineart (if lineart) */
+ if (((!v->allow_reduction_to_lineart) && (output_format == XSANE_PNM)) || /* save PNM but do not reduce to lineart (if lineart) */
+ (v->keep_viewer_pnm_format)) /* we have to make sure that we save in viewer pnm format */
{
if (xsane_create_secure_file(v->output_filename)) /* remove possibly existing symbolic links for security */
{
@@ -352,7 +359,21 @@ static void xsane_viewer_save_callback(GtkWidget *window, gpointer data)
snprintf(buf, sizeof(buf), "%s %s - %s", WINDOW_VIEWER, v->last_saved_filename, xsane.device_text);
gtk_window_set_title(GTK_WINDOW(v->top), buf);
- xsane_update_counter_in_filename(&v->output_filename, preferences.skip_existing_numbers, 1, preferences.filename_counter_len);
+ if (xsane.print_filenames) /* print created filenames to stdout? */
+ {
+ if (v->output_filename[0] != '/') /* relative path */
+ {
+ char pathname[512];
+ getcwd(pathname, sizeof(pathname));
+ printf("XSANE_IMAGE_FILENAME: %s/%s\n", pathname, v->output_filename);
+ fflush(stdout);
+ }
+ else /* absolute path */
+ {
+ printf("XSANE_IMAGE_FILENAME: %s\n", v->output_filename);
+ fflush(stdout);
+ }
+ }
xsane_viewer_set_sensitivity(v, TRUE);
}
@@ -437,11 +458,11 @@ static void xsane_viewer_clone_callback(GtkWidget *window, gpointer data)
{
char buf[256];
snprintf(buf, sizeof(buf), "%s%s", FILENAME_PREFIX_CLONE_OF, v->last_saved_filename);
- xsane_viewer_new(outfilename, v->allow_reduction_to_lineart, buf, v->allow_modification);
+ xsane_viewer_new(outfilename, v->selection_filetype, v->allow_reduction_to_lineart, buf, v->allow_modification, IMAGE_NOT_SAVED);
}
else
{
- xsane_viewer_new(outfilename, v->allow_reduction_to_lineart, NULL, v->allow_modification);
+ xsane_viewer_new(outfilename, v->selection_filetype, v->allow_reduction_to_lineart, NULL, v->allow_modification, IMAGE_NOT_SAVED);
}
}
@@ -1783,6 +1804,11 @@ static int xsane_viewer_read_image(Viewer *v)
size *= 2.0;
}
+ if ((v->allow_reduction_to_lineart) && (image_info.reduce_to_lineart))
+ {
+ size /= 8.0;
+ }
+
size_unit = "B";
if (size >= 1024 * 1024)
@@ -1796,7 +1822,7 @@ static int xsane_viewer_read_image(Viewer *v)
size_unit = "KB";
}
- if (v->allow_reduction_to_lineart)
+ if ((v->allow_reduction_to_lineart) && (image_info.reduce_to_lineart))
{
snprintf(buf, sizeof(buf), TEXT_VIEWER_IMAGE_INFO, image_info.image_width, image_info.image_height, 1, image_info.colors,
image_info.resolution_x, image_info.resolution_y, size, size_unit);
@@ -1841,7 +1867,8 @@ static int xsane_viewer_read_image(Viewer *v)
/* ---------------------------------------------------------------------------------------------------------------------- */
-Viewer *xsane_viewer_new(char *filename, int allow_reduction_to_lineart, char *output_filename, viewer_modification allow_modification)
+Viewer *xsane_viewer_new(char *filename, char *selection_filetype, int allow_reduction_to_lineart,
+ char *output_filename, viewer_modification allow_modification, int image_saved)
{
char buf[256];
Viewer *v;
@@ -1866,14 +1893,25 @@ Viewer *xsane_viewer_new(char *filename, int allow_reduction_to_lineart, char *o
v->undo_filename = NULL;
v->allow_reduction_to_lineart = allow_reduction_to_lineart;
v->zoom = 1.0;
- v->image_saved = FALSE;
+ v->image_saved = image_saved;
+ v->keep_viewer_pnm_format = FALSE;
v->allow_modification = allow_modification;
v->next_viewer = xsane.viewer_list;
+ if (selection_filetype)
+ {
+ v->selection_filetype = strdup(selection_filetype);
+ }
+ else
+ {
+ v->selection_filetype = NULL;
+ }
+
xsane.viewer_list = v;
- if (v->allow_modification == VIEWER_NO_MODIFICATION)
+ if (v->allow_modification != VIEWER_FULL_MODIFICATION)
{
- v->image_saved = TRUE;
+ v->keep_viewer_pnm_format = TRUE;
+ v->last_saved_filename = strdup(output_filename); /* output_filename MUST be defined in this case */
}
if (output_filename)
diff --git a/src/xsane-viewer.h b/src/xsane-viewer.h
index 31d87bc..373fd31 100644
--- a/src/xsane-viewer.h
+++ b/src/xsane-viewer.h
@@ -45,8 +45,10 @@ typedef struct Viewer
char *output_filename;
char *last_saved_filename;
char *undo_filename;
+ char *selection_filetype;
int allow_reduction_to_lineart;
+ int keep_viewer_pnm_format;
float zoom;
int image_saved;
int cancel_save;
@@ -102,6 +104,7 @@ typedef struct Viewer
}
Viewer;
-extern Viewer *xsane_viewer_new(char *filename, int reduce_to_lineart, char *output_filename, viewer_modification allow_modification);
+extern Viewer *xsane_viewer_new(char *filename, char *selection_filetype, int allow_reduction_to_lineart,
+ char *output_filename, viewer_modification allow_modification, int image_saved);
#endif
diff --git a/src/xsane.c b/src/xsane.c
index 30e093c..279df23 100644
--- a/src/xsane.c
+++ b/src/xsane.c
@@ -30,6 +30,9 @@
#include "xsane-gamma.h"
#include "xsane-setup.h"
#include "xsane-scan.h"
+#include "xsane-multipage-project.h"
+#include "xsane-fax-project.h"
+#include "xsane-email-project.h"
#include "xsane-rc-io.h"
#include "xsane-device-preferences.h"
#include "xsane-preferences.h"
@@ -57,8 +60,9 @@ struct option long_options[] =
{"viewer", no_argument, 0, 'V'},
{"copy", no_argument, 0, 'c'},
{"fax", no_argument, 0, 'f'},
-#ifdef XSANE_ACTIVATE_MAIL
- {"mail", no_argument, 0, 'm'},
+ {"multipage", no_argument, 0, 'm'},
+#ifdef XSANE_ACTIVATE_EMAIL
+ {"email", no_argument, 0, 'e'},
#endif
{"no-mode-selection", no_argument, 0, 'n'},
{"Fixed", no_argument, 0, 'F'},
@@ -114,7 +118,6 @@ static const Preferences_medium_t pref_default_medium[]=
int DBG_LEVEL = 0;
static guint xsane_resolution_timer = 0;
-static guint xsane_mail_send_timer = 0;
/* ---------------------------------------------------------------------------------------------------------------------- */
@@ -122,7 +125,7 @@ struct Xsane xsane; /* most xsane dependant values */
/* ---------------------------------------------------------------------------------------------------------------------- */
-int xsane_scanmode_number[] = { XSANE_VIEWER, XSANE_SAVE, XSANE_COPY, XSANE_FAX, XSANE_MAIL };
+int xsane_scanmode_number[] = { XSANE_VIEWER, XSANE_SAVE, XSANE_COPY, XSANE_MULTIPAGE, XSANE_FAX, XSANE_EMAIL };
/* ---------------------------------------------------------------------------------------------------------------------- */
@@ -138,7 +141,6 @@ int xsane_scanmode_number[] = { XSANE_VIEWER, XSANE_SAVE, XSANE_COPY, XSANE_FAX,
/* forward declarations: */
-static int xsane_option_defined(char *string);
static void xsane_zoom_update(GtkAdjustment *adj_data, double *val);
static void xsane_resolution_scale_update(GtkAdjustment *adj_data, double *val);
static void xsane_threshold_changed(void);
@@ -179,51 +181,6 @@ static gint xsane_close_info_callback(GtkWidget *widget, gpointer data);
static void xsane_info_dialog(GtkWidget *widget, gpointer data);
static void xsane_about_dialog(GtkWidget *widget, gpointer data);
static void xsane_about_translation_dialog(GtkWidget *widget, gpointer data);
-static gint xsane_fax_dialog_delete();
-static void xsane_fax_dialog(void);
-static void xsane_fax_dialog_close(void);
-static void xsane_fax_receiver_changed_callback(GtkWidget *widget, gpointer data);
-static void xsane_fax_project_changed_callback(GtkWidget *widget, gpointer data);
-static void xsane_fax_fine_mode_callback(GtkWidget *widget);
-static void xsane_fax_project_update_project_status();
-void xsane_fax_project_save(void);
-static void xsane_fax_project_load(void);
-static void xsane_fax_project_delete(void);
-static void xsane_fax_project_create(void);
-static void xsane_list_entrys_swap(GtkWidget *list_item_1, GtkWidget *list_item_2);
-static void xsane_fax_entry_move_up_callback(GtkWidget *widget, gpointer list);
-static void xsane_fax_entry_move_down_callback(GtkWidget *widget, gpointer list);
-static void xsane_fax_entry_rename_callback(GtkWidget *widget, gpointer list);
-static void xsane_fax_entry_insert_callback(GtkWidget *widget, gpointer list);
-static void xsane_fax_entry_delete_callback(GtkWidget *widget, gpointer list);
-static void xsane_fax_show_callback(GtkWidget *widget, gpointer data);
-static void xsane_fax_send(void);
-#ifdef XSANE_ACTIVATE_MAIL
-static gint xsane_mail_dialog_delete();
-static void xsane_mail_filetype_callback(GtkWidget *filetype_option_menu, char *filetype);
-static void xsane_mail_dialog(void);
-static void xsane_mail_dialog_close(void);
-static void xsane_mail_receiver_changed_callback(GtkWidget *widget, gpointer data);
-static void xsane_mail_subject_changed_callback(GtkWidget *widget, gpointer data);
-static void xsane_mail_project_changed_callback(GtkWidget *widget, gpointer data);
-static void xsane_mail_html_mode_callback(GtkWidget *widget);
-void xsane_mail_project_save(void);
-static void xsane_mail_project_display_status(void);
-static void xsane_mail_project_load(void);
-static void xsane_mail_project_delete(void);
-static void xsane_mail_project_update_project_status();
-static void xsane_mail_project_create(void);
-static void xsane_mail_entry_move_up_callback(GtkWidget *widget, gpointer list);
-static void xsane_mail_entry_move_down_callback(GtkWidget *widget, gpointer list);
-static void xsane_mail_entry_rename_callback(GtkWidget *widget, gpointer list);
-static void xsane_mail_entry_delete_callback(GtkWidget *widget, gpointer list);
-static void xsane_mail_show_callback(GtkWidget *widget, gpointer data);
-#if 0
-static void xsane_mail_edit_callback(GtkWidget *widget, gpointer data);
-#endif
-static void xsane_mail_send_process(void);
-static void xsane_mail_send(void);
-#endif
static void xsane_pref_toggle_tooltips(GtkWidget *widget, gpointer data);
static void xsane_show_eula(GtkWidget *widget, gpointer data);
static void xsane_show_gpl(GtkWidget *widget, gpointer data);
@@ -260,24 +217,6 @@ void xsane_debug_message(int level, const char *fmt, ...)
/* ---------------------------------------------------------------------------------------------------------------------- */
-static int xsane_option_defined(char *string)
-{
- if (string)
- {
- while (*string == ' ') /* skip spaces */
- {
- string++;
- }
- if (*string != 0)
- {
- return 1;
- }
- }
- return 0;
-}
-
-/* ---------------------------------------------------------------------------------------------------------------------- */
-
static void xsane_threshold_changed()
{
DBG(DBG_proc, "xsane_threshold_changed\n");
@@ -328,7 +267,11 @@ static void xsane_set_modus_defaults(void)
{
DBG(DBG_proc, "xsane_set_modus_defaults\n");
- switch(xsane.xsane_mode)
+ if (xsane.mode == XSANE_GIMP_EXTENSION)
+ {
+ xsane_define_maximum_output_size();
+ }
+ else switch(xsane.xsane_mode)
{
case XSANE_VIEWER:
xsane_define_maximum_output_size();
@@ -383,7 +326,7 @@ static void xsane_set_modus_defaults(void)
preview_select_full_preview_area(xsane.preview);
break;
- case XSANE_MAIL:
+ case XSANE_EMAIL:
xsane_define_maximum_output_size();
break;
@@ -401,32 +344,26 @@ static void xsane_modus_callback(GtkWidget *xsane_parent, int *num)
xsane.xsane_mode = *num;
preferences.xsane_mode = *num;
- xsane_set_modus_defaults(); /* set defaults and maximum output size */
- xsane_refresh_dialog();
-
if ((xsane.xsane_mode == XSANE_SAVE) || (xsane.xsane_mode == XSANE_VIEWER) || (xsane.xsane_mode == XSANE_COPY))
{
gtk_widget_set_sensitive(GTK_WIDGET(xsane.start_button), TRUE);
}
- if (xsane.xsane_mode != XSANE_FAX)
+#ifdef XSANE_ACTIVATE_EMAIL
+ if (xsane.xsane_mode != XSANE_EMAIL)
{
- xsane_fax_dialog_close();
- }
-
-#ifdef XSANE_ACTIVATE_MAIL
- if (xsane.xsane_mode != XSANE_MAIL)
- {
- if (xsane.mail_project_save)
+ if (xsane.email_project_save)
{
- xsane.mail_project_save = 0;
- xsane_mail_project_save();
+ xsane.email_project_save = 0;
+ xsane_email_project_save();
}
-
- xsane_mail_dialog_close();
}
#endif
+ xsane_project_dialog_close(); /* close project dialog when one is open */
+ xsane_set_modus_defaults(); /* set defaults and maximum output size */
+ xsane_refresh_dialog();
+
/* make sure dialogs are rebuild, otherwise we can get in trouble */
while (gtk_events_pending())
{
@@ -551,11 +488,11 @@ static void xsane_show_standard_options_callback(GtkWidget * widget)
preferences.show_standard_options = (GTK_CHECK_MENU_ITEM(widget)->active != 0);
if (preferences.show_standard_options)
{
- gtk_widget_show(xsane.standard_options_shell);
+ gtk_widget_show(xsane.standard_options_dialog);
}
else
{
- gtk_widget_hide(xsane.standard_options_shell);
+ gtk_widget_hide(xsane.standard_options_dialog);
}
}
@@ -568,11 +505,11 @@ static void xsane_show_advanced_options_callback(GtkWidget * widget)
preferences.show_advanced_options = (GTK_CHECK_MENU_ITEM(widget)->active != 0);
if (preferences.show_advanced_options)
{
- gtk_widget_show(xsane.advanced_options_shell);
+ gtk_widget_show(xsane.advanced_options_dialog);
}
else
{
- gtk_widget_hide(xsane.advanced_options_shell);
+ gtk_widget_hide(xsane.advanced_options_dialog);
}
}
@@ -1243,20 +1180,32 @@ static void xsane_scanmode_menu_callback(GtkWidget *widget, gpointer data)
/* ---------------------------------------------------------------------------------------------------------------------- */
+static void xsane_adf_pages_max_callback(GtkWidget *widget, gpointer data)
+{
+ xsane_update_int(xsane.adf_pages_max_entry, &preferences.adf_pages_max); /* get adf pages maximum */
+}
+
+/* ---------------------------------------------------------------------------------------------------------------------- */
+
GtkWidget *xsane_update_xsane_callback() /* creates the XSane option window */
{
+ GtkWidget *hbox;
GtkWidget *xsane_vbox, *xsane_hbox;
GtkWidget *xsane_modus_menu;
GtkWidget *xsane_modus_item;
GtkWidget *xsane_modus_option_menu;
GtkWidget *xsane_vbox_xsane_modus;
- GtkWidget *xsane_hbox_xsane_modus;
- GtkWidget *xsane_label;
- GtkWidget *xsane_text;
+ GtkWidget *xsane_spinbutton;
GtkWidget *xsane_hbox_xsane_enhancement;
GtkWidget *xsane_frame;
+ GtkWidget *xsane_medium_option_menu, *xsane_medium_menu, *xsane_medium_item;
GtkWidget *button;
- gchar buf[256];
+ GtkWidget *pixmapwidget;
+ GdkBitmap *mask;
+ GdkPixmap *pixmap;
+ GtkObject *adjustment;
+ const SANE_Option_Descriptor *opt;
+ int i;
DBG(DBG_proc, "xsane_update_xsane_callback\n");
@@ -1278,8 +1227,7 @@ GtkWidget *xsane_update_xsane_callback() /* creates the XSane option window */
gtk_box_pack_start(GTK_BOX(xsane_vbox), xsane_frame, TRUE, TRUE, 0); /* sizeable framehight */
gtk_widget_show(xsane_frame);
-/* xsane_vbox_xsane_modus = gtk_vbox_new(FALSE, 5); */
- xsane_vbox_xsane_modus = gtk_vbox_new(FALSE, 1);
+ xsane_vbox_xsane_modus = gtk_vbox_new(FALSE, 1);
gtk_container_add(GTK_CONTAINER(xsane_frame), xsane_vbox_xsane_modus);
gtk_widget_show(xsane_vbox_xsane_modus);
@@ -1287,13 +1235,26 @@ GtkWidget *xsane_update_xsane_callback() /* creates the XSane option window */
if ( (xsane.mode == XSANE_STANDALONE) && (xsane.mode_selection) ) /* display xsane mode selection menu */
{
- xsane_hbox_xsane_modus = gtk_hbox_new(FALSE, 2);
- gtk_container_set_border_width(GTK_CONTAINER(xsane_hbox_xsane_modus), 2);
- gtk_box_pack_start(GTK_BOX(xsane_vbox_xsane_modus), xsane_hbox_xsane_modus, FALSE, FALSE, 0);
+ hbox = gtk_hbox_new(FALSE, 2);
+ gtk_container_set_border_width(GTK_CONTAINER(hbox), 2);
+ gtk_box_pack_start(GTK_BOX(xsane_vbox_xsane_modus), hbox, FALSE, FALSE, 1);
- xsane_label = gtk_label_new(TEXT_XSANE_MODE);
- gtk_box_pack_start(GTK_BOX(xsane_hbox_xsane_modus), xsane_label, FALSE, FALSE, 2);
- gtk_widget_show(xsane_label);
+ pixmap = gdk_pixmap_create_from_xpm_d(xsane.histogram_dialog->window, &mask, xsane.bg_trans, (gchar **) adf_xpm);
+ pixmapwidget = gtk_image_new_from_pixmap(pixmap, mask);
+ gtk_box_pack_start(GTK_BOX(hbox), pixmapwidget, FALSE, FALSE, 2);
+ gdk_drawable_unref(pixmap);
+ gtk_widget_show(pixmapwidget);
+
+ /* adf pages maximum */
+ adjustment = gtk_adjustment_new(preferences.adf_pages_max, 1, 9999, 1, 10, 1);
+ xsane_spinbutton = gtk_spin_button_new(GTK_ADJUSTMENT(adjustment), 0, 0);
+ gtk_widget_set_size_request(xsane_spinbutton, 55, -1);
+ gtk_spin_button_set_wrap(GTK_SPIN_BUTTON(xsane_spinbutton), FALSE);
+ xsane_back_gtk_set_tooltip(xsane.tooltips, xsane_spinbutton, DESC_ADF_PAGES_MAX);
+ g_signal_connect(GTK_OBJECT(xsane_spinbutton), "changed", (GtkSignalFunc) xsane_adf_pages_max_callback, NULL);
+ xsane.adf_pages_max_entry = xsane_spinbutton;
+ gtk_box_pack_start(GTK_BOX(hbox), xsane_spinbutton, FALSE, FALSE, 10);
+ gtk_widget_show(xsane_spinbutton);
xsane_modus_menu = gtk_menu_new();
@@ -1319,184 +1280,50 @@ GtkWidget *xsane_update_xsane_callback() /* creates the XSane option window */
g_signal_connect(GTK_OBJECT(xsane_modus_item), "activate", (GtkSignalFunc) xsane_modus_callback, &xsane_scanmode_number[XSANE_COPY]);
gtk_widget_show(xsane_modus_item);
+ xsane_modus_item = gtk_menu_item_new_with_label(MENU_ITEM_MULTIPAGE);
+ gtk_widget_add_accelerator(xsane_modus_item, "activate", xsane.accelerator_group, GDK_M, GDK_CONTROL_MASK, DEF_GTK_MENU_ACCEL_VISIBLE | DEF_GTK_ACCEL_LOCKED);
+ gtk_container_add(GTK_CONTAINER(xsane_modus_menu), xsane_modus_item);
+ g_signal_connect(GTK_OBJECT(xsane_modus_item), "activate", (GtkSignalFunc) xsane_modus_callback, &xsane_scanmode_number[XSANE_MULTIPAGE]);
+ gtk_widget_show(xsane_modus_item);
+
xsane_modus_item = gtk_menu_item_new_with_label(MENU_ITEM_FAX);
gtk_widget_add_accelerator(xsane_modus_item, "activate", xsane.accelerator_group, GDK_F, GDK_CONTROL_MASK, DEF_GTK_MENU_ACCEL_VISIBLE | DEF_GTK_ACCEL_LOCKED);
gtk_container_add(GTK_CONTAINER(xsane_modus_menu), xsane_modus_item);
g_signal_connect(GTK_OBJECT(xsane_modus_item), "activate", (GtkSignalFunc) xsane_modus_callback, &xsane_scanmode_number[XSANE_FAX]);
gtk_widget_show(xsane_modus_item);
-#ifdef XSANE_ACTIVATE_MAIL
- xsane_modus_item = gtk_menu_item_new_with_label(MENU_ITEM_MAIL);
- gtk_widget_add_accelerator(xsane_modus_item, "activate", xsane.accelerator_group, GDK_M, GDK_CONTROL_MASK, DEF_GTK_MENU_ACCEL_VISIBLE | DEF_GTK_ACCEL_LOCKED);
+#ifdef XSANE_ACTIVATE_EMAIL
+ xsane_modus_item = gtk_menu_item_new_with_label(MENU_ITEM_EMAIL);
+ gtk_widget_add_accelerator(xsane_modus_item, "activate", xsane.accelerator_group, GDK_E, GDK_CONTROL_MASK, DEF_GTK_MENU_ACCEL_VISIBLE | DEF_GTK_ACCEL_LOCKED);
gtk_container_add(GTK_CONTAINER(xsane_modus_menu), xsane_modus_item);
- g_signal_connect(GTK_OBJECT(xsane_modus_item), "activate", (GtkSignalFunc) xsane_modus_callback, &xsane_scanmode_number[XSANE_MAIL]);
+ g_signal_connect(GTK_OBJECT(xsane_modus_item), "activate", (GtkSignalFunc) xsane_modus_callback, &xsane_scanmode_number[XSANE_EMAIL]);
gtk_widget_show(xsane_modus_item);
#endif
xsane_modus_option_menu = gtk_option_menu_new();
xsane_back_gtk_set_tooltip(xsane.tooltips, xsane_modus_option_menu, DESC_XSANE_MODE);
- gtk_box_pack_end(GTK_BOX(xsane_hbox_xsane_modus), xsane_modus_option_menu, FALSE, FALSE, 2);
+ gtk_box_pack_end(GTK_BOX(hbox), xsane_modus_option_menu, FALSE, FALSE, 2);
gtk_option_menu_set_menu(GTK_OPTION_MENU(xsane_modus_option_menu), xsane_modus_menu);
gtk_option_menu_set_history(GTK_OPTION_MENU(xsane_modus_option_menu), xsane.xsane_mode);
gtk_widget_show(xsane_modus_option_menu);
- gtk_widget_show(xsane_hbox_xsane_modus);
-
- xsane.xsanemode_widget = xsane_modus_option_menu;
- }
-
- {
- GtkWidget *pixmapwidget;
- GdkBitmap *mask;
- GdkPixmap *pixmap;
- GtkWidget *hbox;
- GtkWidget *xsane_medium_option_menu, *xsane_medium_menu, *xsane_medium_item;
- const SANE_Option_Descriptor *opt;
- int i;
-
-
- /* scanmode */
- opt = xsane_get_option_descriptor(xsane.dev, xsane.well_known.scanmode);
- if (opt)
- {
- if (SANE_OPTION_IS_ACTIVE(opt->cap))
- {
- hbox = gtk_hbox_new(FALSE, 2);
- gtk_container_set_border_width(GTK_CONTAINER(hbox), 2);
- gtk_box_pack_start(GTK_BOX(xsane_vbox_xsane_modus), hbox, FALSE, FALSE, 2);
-
- pixmap = gdk_pixmap_create_from_xpm_d(xsane.histogram_dialog->window, &mask, xsane.bg_trans, (gchar **) colormode_xpm);
- pixmapwidget = gtk_image_new_from_pixmap(pixmap, mask);
- gtk_box_pack_start(GTK_BOX(hbox), pixmapwidget, FALSE, FALSE, 2);
- gdk_drawable_unref(pixmap);
- gtk_widget_show(pixmapwidget);
-
- switch (opt->constraint_type)
- {
- case SANE_CONSTRAINT_STRING_LIST:
- {
- char *set;
- SANE_Status status;
-
- /* use a "list-selection" widget */
- set = malloc(opt->size);
- status = xsane_control_option(xsane.dev, xsane.well_known.scanmode, SANE_ACTION_GET_VALUE, set, 0);
-
- xsane_option_menu_new(hbox, (char **) opt->constraint.string_list, set, xsane.well_known.scanmode,
- _BGT(opt->desc), xsane_scanmode_menu_callback, SANE_OPTION_IS_SETTABLE(opt->cap), 0);
- }
- break;
-
- default:
- DBG(DBG_error, "scanmode_selection: %s %d\n", ERR_UNKNOWN_TYPE, opt->type);
- }
- gtk_widget_show(hbox);
- }
- }
-
-
- /* input selection */
- opt = xsane_get_option_descriptor(xsane.dev, xsane.well_known.scansource);
- if (opt)
- {
- if (SANE_OPTION_IS_ACTIVE(opt->cap))
- {
- hbox = gtk_hbox_new(FALSE, 2);
- gtk_container_set_border_width(GTK_CONTAINER(hbox), 2);
- gtk_box_pack_start(GTK_BOX(xsane_vbox_xsane_modus), hbox, FALSE, FALSE, 2);
-
- pixmap = gdk_pixmap_create_from_xpm_d(xsane.histogram_dialog->window, &mask, xsane.bg_trans, (gchar **) scanner_xpm);
- pixmapwidget = gtk_image_new_from_pixmap(pixmap, mask);
- gtk_box_pack_start(GTK_BOX(hbox), pixmapwidget, FALSE, FALSE, 2);
- gdk_drawable_unref(pixmap);
- gtk_widget_show(pixmapwidget);
-
- switch (opt->constraint_type)
- {
- case SANE_CONSTRAINT_STRING_LIST:
- {
- char *set;
- SANE_Status status;
-
- /* use a "list-selection" widget */
- set = malloc(opt->size);
- status = xsane_control_option(xsane.dev, xsane.well_known.scansource, SANE_ACTION_GET_VALUE, set, 0);
-
- xsane_option_menu_new(hbox, (char **) opt->constraint.string_list, set, xsane.well_known.scansource,
- _BGT(opt->desc), 0, SANE_OPTION_IS_SETTABLE(opt->cap), 0);
- }
- break;
-
- default:
- DBG(DBG_error, "scansource_selection: %s %d\n", ERR_UNKNOWN_CONSTRAINT_TYPE, opt->constraint_type);
- }
- gtk_widget_show(hbox);
- }
- }
-
-
- if (xsane.param.depth != 1) /* show medium selection of not lineart mode */
- {
- /* medium selection */
- hbox = gtk_hbox_new(FALSE, 2);
- gtk_container_set_border_width(GTK_CONTAINER(hbox), 2);
- gtk_box_pack_start(GTK_BOX(xsane_vbox_xsane_modus), hbox, FALSE, FALSE, 2);
-
- if (xsane.medium_calibration)
- {
- pixmap = gdk_pixmap_create_from_xpm_d(xsane.histogram_dialog->window, &mask, xsane.bg_trans, (gchar **) medium_edit_xpm);
- }
- else
- {
- pixmap = gdk_pixmap_create_from_xpm_d(xsane.histogram_dialog->window, &mask, xsane.bg_trans, (gchar **) medium_xpm);
- }
- pixmapwidget = gtk_image_new_from_pixmap(pixmap, mask);
- gtk_box_pack_start(GTK_BOX(hbox), pixmapwidget, FALSE, FALSE, 2);
- gdk_drawable_unref(pixmap);
- gtk_widget_show(pixmapwidget);
-
- xsane_medium_menu = gtk_menu_new();
-
- for (i=0; i<preferences.medium_definitions; i++)
- {
- xsane_medium_item = gtk_menu_item_new_with_label(preferences.medium[i]->name);
- gtk_menu_append(GTK_MENU(xsane_medium_menu), xsane_medium_item);
- g_signal_connect(GTK_OBJECT(xsane_medium_item), "button_press_event", (GtkSignalFunc) xsane_medium_context_menu_callback, (void *) i);
- g_signal_connect(GTK_OBJECT(xsane_medium_item), "activate", (GtkSignalFunc) xsane_set_medium_callback, (void *) i);
- gtk_object_set_data(GTK_OBJECT(xsane_medium_item), "Selection", (void *) i);
-
- gtk_widget_show(xsane_medium_item);
- }
-
- gtk_widget_show(xsane_medium_menu);
- xsane_medium_option_menu = gtk_option_menu_new();
- xsane_back_gtk_set_tooltip(xsane.tooltips, xsane_medium_option_menu, DESC_XSANE_MEDIUM);
- gtk_box_pack_end(GTK_BOX(hbox), xsane_medium_option_menu, FALSE, FALSE, 2);
- gtk_option_menu_set_menu(GTK_OPTION_MENU(xsane_medium_option_menu), xsane_medium_menu);
- gtk_option_menu_set_history(GTK_OPTION_MENU(xsane_medium_option_menu), preferences.medium_nr);
- gtk_widget_show(xsane_medium_option_menu);
- gtk_widget_show(hbox);
+ pixmap = gdk_pixmap_create_from_xpm_d(xsane.histogram_dialog->window, &mask, xsane.bg_trans, (gchar **) target_xpm); /* XSANE_MODE */
+ pixmapwidget = gtk_image_new_from_pixmap(pixmap, mask);
+ gtk_box_pack_end(GTK_BOX(hbox), pixmapwidget, FALSE, FALSE, 2);
+ gdk_drawable_unref(pixmap);
+ gtk_widget_show(pixmapwidget);
- xsane.medium_widget = xsane_medium_option_menu;
+ gtk_widget_show(hbox);
- if (xsane.medium_calibration) /* are we running in medium calibration mode? */
- {
- xsane_apply_medium_definition_as_enhancement(preferences.medium[preferences.medium_nr]);
- xsane_set_medium(NULL);
- }
- else
- {
- xsane_set_medium(preferences.medium[preferences.medium_nr]);
- }
- }
- else /* no medium selextion for lineart mode: use Full range gamma curve */
- {
- xsane_set_medium(preferences.medium[0]); /* make sure Full range is active */
- }
+ xsane.xsanemode_widget = xsane_modus_option_menu;
}
+#if 0
if (xsane.xsane_mode == XSANE_SAVE)
+#else
+ if ( (xsane.xsane_mode == XSANE_SAVE) || (xsane.xsane_mode == XSANE_VIEWER) )
+#endif
{
xsane.copy_number_entry = NULL;
@@ -1505,29 +1332,10 @@ GtkWidget *xsane_update_xsane_callback() /* creates the XSane option window */
xsane_outputfilename_new(xsane_vbox_xsane_modus); /* create filename box, step and type menu */
}
}
-
- if ( (xsane.xsane_mode == XSANE_SAVE) || (xsane.xsane_mode == XSANE_VIEWER) )
- {
- /* resolution selection */
- if (!xsane_resolution_widget_new(xsane_vbox_xsane_modus, xsane.well_known.dpi_x, &xsane.resolution_x, resolution_x_xpm,
- DESC_RESOLUTION_X, XSANE_GTK_NAME_X_RESOLUTION)) /* draw x resolution widget if possible */
- {
- xsane_resolution_widget_new(xsane_vbox_xsane_modus, xsane.well_known.dpi_y, &xsane.resolution_y, resolution_y_xpm,
- DESC_RESOLUTION_Y, XSANE_GTK_NAME_Y_RESOLUTION); /* ok, also draw y resolution widget */
- }
- else /* no x resolution, so lets draw common resolution widget */
- {
- xsane_resolution_widget_new(xsane_vbox_xsane_modus, xsane.well_known.dpi, &xsane.resolution, resolution_xpm,
- DESC_RESOLUTION, XSANE_GTK_NAME_RESOLUTION);
- }
- }
else if (xsane.xsane_mode == XSANE_COPY)
{
- GtkWidget *pixmapwidget, *hbox, *xsane_printer_option_menu, *xsane_printer_menu, *xsane_printer_item;
- GdkBitmap *mask;
- GdkPixmap *pixmap;
+ GtkWidget *xsane_printer_option_menu, *xsane_printer_menu, *xsane_printer_item;
GtkWidget *paper_orientation_option_menu, *paper_orientation_menu, *paper_orientation_item;
- int i;
hbox = gtk_hbox_new(FALSE, 2);
gtk_container_set_border_width(GTK_CONTAINER(hbox), 2);
@@ -1655,16 +1463,176 @@ GtkWidget *xsane_update_xsane_callback() /* creates the XSane option window */
gtk_option_menu_set_history(GTK_OPTION_MENU(xsane_printer_option_menu), preferences.printernr);
/* number of copies */
- xsane_text = gtk_entry_new();
- xsane_back_gtk_set_tooltip(xsane.tooltips, xsane_text, DESC_COPY_NUMBER);
- gtk_widget_set_size_request(xsane_text, 25, -1);
- snprintf(buf, sizeof(buf), "%d", xsane.copy_number);
- gtk_entry_set_text(GTK_ENTRY(xsane_text), (char *) buf);
- gtk_box_pack_end(GTK_BOX(hbox), xsane_text, FALSE, FALSE, 10);
- gtk_widget_show(xsane_text);
+ adjustment = gtk_adjustment_new(xsane.copy_number, 1, 99, 1, 10, 1);
+ xsane_spinbutton = gtk_spin_button_new(GTK_ADJUSTMENT(adjustment), 0, 0);
+ gtk_widget_set_size_request(xsane_spinbutton, 40, -1);
+ gtk_spin_button_set_wrap(GTK_SPIN_BUTTON(xsane_spinbutton), FALSE);
+ xsane_back_gtk_set_tooltip(xsane.tooltips, xsane_spinbutton, DESC_COPY_NUMBER);
+ xsane.copy_number_entry = xsane_spinbutton;
+ gtk_box_pack_start(GTK_BOX(hbox), xsane_spinbutton, FALSE, FALSE, 10);
+ gtk_widget_show(xsane_spinbutton);
+ }
+
+
+ /* input selection */
+ opt = xsane_get_option_descriptor(xsane.dev, xsane.well_known.scansource);
+ if (opt)
+ {
+ if (SANE_OPTION_IS_ACTIVE(opt->cap))
+ {
+ hbox = gtk_hbox_new(FALSE, 2);
+ gtk_container_set_border_width(GTK_CONTAINER(hbox), 2);
+ gtk_box_pack_start(GTK_BOX(xsane_vbox_xsane_modus), hbox, FALSE, FALSE, 1);
+
+ pixmap = gdk_pixmap_create_from_xpm_d(xsane.histogram_dialog->window, &mask, xsane.bg_trans, (gchar **) scanner_xpm);
+ pixmapwidget = gtk_image_new_from_pixmap(pixmap, mask);
+ gtk_box_pack_start(GTK_BOX(hbox), pixmapwidget, FALSE, FALSE, 2);
+ gdk_drawable_unref(pixmap);
+ gtk_widget_show(pixmapwidget);
+
+ switch (opt->constraint_type)
+ {
+ case SANE_CONSTRAINT_STRING_LIST:
+ {
+ char *set;
+ SANE_Status status;
+
+ /* use a "list-selection" widget */
+ set = malloc(opt->size);
+ status = xsane_control_option(xsane.dev, xsane.well_known.scansource, SANE_ACTION_GET_VALUE, set, 0);
+
+ xsane_option_menu_new(hbox, (char **) opt->constraint.string_list, set, xsane.well_known.scansource,
+ _BGT(opt->desc), 0, SANE_OPTION_IS_SETTABLE(opt->cap), 0);
+ }
+ break;
+
+ default:
+ DBG(DBG_error, "scansource_selection: %s %d\n", ERR_UNKNOWN_CONSTRAINT_TYPE, opt->constraint_type);
+ }
+ gtk_widget_show(hbox);
+ }
+ }
+
+
+ /* scanmode */
+ opt = xsane_get_option_descriptor(xsane.dev, xsane.well_known.scanmode);
+ if (opt)
+ {
+ if (SANE_OPTION_IS_ACTIVE(opt->cap))
+ {
+ hbox = gtk_hbox_new(FALSE, 2);
+ gtk_container_set_border_width(GTK_CONTAINER(hbox), 2);
+ gtk_box_pack_start(GTK_BOX(xsane_vbox_xsane_modus), hbox, FALSE, FALSE, 1);
+
+ pixmap = gdk_pixmap_create_from_xpm_d(xsane.histogram_dialog->window, &mask, xsane.bg_trans, (gchar **) colormode_xpm);
+ pixmapwidget = gtk_image_new_from_pixmap(pixmap, mask);
+ gtk_box_pack_start(GTK_BOX(hbox), pixmapwidget, FALSE, FALSE, 2);
+ gdk_drawable_unref(pixmap);
+ gtk_widget_show(pixmapwidget);
+
+ switch (opt->constraint_type)
+ {
+ case SANE_CONSTRAINT_STRING_LIST:
+ {
+ char *set;
+ SANE_Status status;
+
+ /* use a "list-selection" widget */
+ set = malloc(opt->size);
+ status = xsane_control_option(xsane.dev, xsane.well_known.scanmode, SANE_ACTION_GET_VALUE, set, 0);
+
+ xsane_option_menu_new(hbox, (char **) opt->constraint.string_list, set, xsane.well_known.scanmode,
+ _BGT(opt->desc), xsane_scanmode_menu_callback, SANE_OPTION_IS_SETTABLE(opt->cap), 0);
+ }
+ break;
+
+ default:
+ DBG(DBG_error, "scanmode_selection: %s %d\n", ERR_UNKNOWN_TYPE, opt->type);
+ }
+
+ gtk_widget_show(hbox);
+ }
+ }
+
+
+ if (xsane.param.depth != 1) /* show medium selection of not lineart mode */
+ {
+ /* medium selection */
+ hbox = gtk_hbox_new(FALSE, 2);
+ gtk_container_set_border_width(GTK_CONTAINER(hbox), 2);
+ gtk_box_pack_start(GTK_BOX(xsane_vbox_xsane_modus), hbox, FALSE, FALSE, 1);
+
+ if (xsane.medium_calibration)
+ {
+ pixmap = gdk_pixmap_create_from_xpm_d(xsane.histogram_dialog->window, &mask, xsane.bg_trans, (gchar **) medium_edit_xpm);
+ }
+ else
+ {
+ pixmap = gdk_pixmap_create_from_xpm_d(xsane.histogram_dialog->window, &mask, xsane.bg_trans, (gchar **) medium_xpm);
+ }
+ pixmapwidget = gtk_image_new_from_pixmap(pixmap, mask);
+ gtk_box_pack_start(GTK_BOX(hbox), pixmapwidget, FALSE, FALSE, 2);
+ gdk_drawable_unref(pixmap);
+ gtk_widget_show(pixmapwidget);
+
+ xsane_medium_menu = gtk_menu_new();
+
+ for (i=0; i<preferences.medium_definitions; i++)
+ {
+ xsane_medium_item = gtk_menu_item_new_with_label(preferences.medium[i]->name);
+ gtk_menu_append(GTK_MENU(xsane_medium_menu), xsane_medium_item);
+ g_signal_connect(GTK_OBJECT(xsane_medium_item), "button_press_event", (GtkSignalFunc) xsane_medium_context_menu_callback, (void *) i);
+ g_signal_connect(GTK_OBJECT(xsane_medium_item), "activate", (GtkSignalFunc) xsane_set_medium_callback, (void *) i);
+ gtk_object_set_data(GTK_OBJECT(xsane_medium_item), "Selection", (void *) i);
+
+ gtk_widget_show(xsane_medium_item);
+ }
+
+ gtk_widget_show(xsane_medium_menu);
+
+ xsane_medium_option_menu = gtk_option_menu_new();
+ xsane_back_gtk_set_tooltip(xsane.tooltips, xsane_medium_option_menu, DESC_XSANE_MEDIUM);
+ gtk_box_pack_end(GTK_BOX(hbox), xsane_medium_option_menu, FALSE, FALSE, 2);
+ gtk_option_menu_set_menu(GTK_OPTION_MENU(xsane_medium_option_menu), xsane_medium_menu);
+ gtk_option_menu_set_history(GTK_OPTION_MENU(xsane_medium_option_menu), preferences.medium_nr);
+ gtk_widget_show(xsane_medium_option_menu);
+ xsane.medium_widget = xsane_medium_option_menu;
+
gtk_widget_show(hbox);
- xsane.copy_number_entry = xsane_text;
+ if (xsane.medium_calibration) /* are we running in medium calibration mode? */
+ {
+ xsane_apply_medium_definition_as_enhancement(preferences.medium[preferences.medium_nr]);
+ xsane_set_medium(NULL);
+ }
+ else
+ {
+ xsane_set_medium(preferences.medium[preferences.medium_nr]);
+ }
+ }
+ else /* no medium selextion for lineart mode: use Full range gamma curve */
+ {
+ xsane_set_medium(preferences.medium[0]); /* make sure Full range is active */
+ }
+
+
+ if ( (xsane.xsane_mode == XSANE_SAVE) || (xsane.xsane_mode == XSANE_VIEWER) )
+ {
+ /* resolution selection */
+ if (!xsane_resolution_widget_new(xsane_vbox_xsane_modus, xsane.well_known.dpi_x, &xsane.resolution_x, resolution_x_xpm,
+ DESC_RESOLUTION_X, XSANE_GTK_NAME_X_RESOLUTION)) /* draw x resolution widget if possible */
+ {
+ xsane_resolution_widget_new(xsane_vbox_xsane_modus, xsane.well_known.dpi_y, &xsane.resolution_y, resolution_y_xpm,
+ DESC_RESOLUTION_Y, XSANE_GTK_NAME_Y_RESOLUTION); /* ok, also draw y resolution widget */
+ }
+ else /* no x resolution, so lets draw common resolution widget */
+ {
+ xsane_resolution_widget_new(xsane_vbox_xsane_modus, xsane.well_known.dpi, &xsane.resolution, resolution_xpm,
+ DESC_RESOLUTION, XSANE_GTK_NAME_RESOLUTION);
+ }
+ }
+ else if (xsane.xsane_mode == XSANE_COPY)
+ {
/* zoom selection */
if (!xsane_zoom_widget_new(xsane_vbox_xsane_modus, xsane.well_known.dpi_x, &xsane.zoom_x,
xsane.resolution_x, zoom_x_xpm, DESC_ZOOM_X))
@@ -1678,6 +1646,25 @@ GtkWidget *xsane_update_xsane_callback() /* creates the XSane option window */
xsane.resolution, zoom_xpm, DESC_ZOOM);
}
}
+ else if (xsane.xsane_mode == XSANE_MULTIPAGE)
+ {
+ xsane.copy_number_entry = NULL;
+
+ /* resolution selection */
+ if (!xsane_resolution_widget_new(xsane_vbox_xsane_modus, xsane.well_known.dpi_x, &xsane.resolution_x, resolution_x_xpm,
+ DESC_RESOLUTION_X, XSANE_GTK_NAME_X_RESOLUTION)) /* draw x resolution widget if possible */
+ {
+ xsane_resolution_widget_new(xsane_vbox_xsane_modus, xsane.well_known.dpi_y, &xsane.resolution_y, resolution_y_xpm,
+ DESC_RESOLUTION_Y, XSANE_GTK_NAME_Y_RESOLUTION); /* ok, also draw y resolution widget */
+ }
+ else /* no x resolution, so lets draw common resolution widget */
+ {
+ xsane_resolution_widget_new(xsane_vbox_xsane_modus, xsane.well_known.dpi, &xsane.resolution, resolution_xpm,
+ DESC_RESOLUTION, XSANE_GTK_NAME_RESOLUTION);
+ }
+
+ xsane_multipage_dialog();
+ }
else if (xsane.xsane_mode == XSANE_FAX)
{
xsane.copy_number_entry = NULL;
@@ -1689,8 +1676,8 @@ GtkWidget *xsane_update_xsane_callback() /* creates the XSane option window */
xsane_fax_dialog();
}
-#ifdef XSANE_ACTIVATE_MAIL
- else if (xsane.xsane_mode == XSANE_MAIL)
+#ifdef XSANE_ACTIVATE_EMAIL
+ else if (xsane.xsane_mode == XSANE_EMAIL)
{
xsane.copy_number_entry = NULL;
@@ -1707,7 +1694,7 @@ GtkWidget *xsane_update_xsane_callback() /* creates the XSane option window */
DESC_RESOLUTION, XSANE_GTK_NAME_RESOLUTION);
}
- xsane_mail_dialog();
+ xsane_email_dialog();
}
#endif
@@ -2043,53 +2030,58 @@ static int xsane_pref_restore(void)
preferences.fax_fine_option = strdup(FAXFINEOPT);
}
-#ifdef XSANE_ACTIVATE_MAIL
- if (!preferences.mail_smtp_server)
+ if (!preferences.fax_viewer)
{
- preferences.mail_smtp_server = strdup("");
+ preferences.fax_viewer = strdup(FAXVIEWER);
}
- if (!preferences.mail_from)
+#ifdef XSANE_ACTIVATE_EMAIL
+ if (!preferences.email_smtp_server)
{
- preferences.mail_from = strdup("");
+ preferences.email_smtp_server = strdup("");
}
- if (!preferences.mail_reply_to)
+ if (!preferences.email_from)
{
- preferences.mail_reply_to = strdup("");
+ preferences.email_from = strdup("");
}
- if (!preferences.mail_pop3_server)
+ if (!preferences.email_reply_to)
{
- preferences.mail_pop3_server = strdup("");
+ preferences.email_reply_to = strdup("");
}
- if (!preferences.mail_pop3_user)
+ if (!preferences.email_pop3_server)
{
- preferences.mail_pop3_user = strdup("");
+ preferences.email_pop3_server = strdup("");
}
- if (!preferences.mail_pop3_pass)
+ if (!preferences.email_auth_user)
{
- preferences.mail_pop3_pass = strdup("");
+ preferences.email_auth_user = strdup("");
}
- if (!preferences.mail_project)
+ if (!preferences.email_auth_pass)
{
- preferences.mail_project = strdup(MAILPROJECT);
+ preferences.email_auth_pass = strdup("");
}
- if (!preferences.mail_viewer)
+ if (!preferences.email_project)
{
- preferences.mail_viewer = strdup(MAILVIEWER);
+ preferences.email_project = strdup(EMAILPROJECT);
}
- if (!preferences.mail_filetype)
+ if (!preferences.email_filetype)
{
- preferences.mail_filetype = strdup(XSANE_DEFAULT_MAILTYPE);
+ preferences.email_filetype = strdup(XSANE_DEFAULT_EMAIL_TYPE);
}
#endif
+ if (!preferences.multipage_project)
+ {
+ preferences.multipage_project = strdup(MULTIPAGEPROJECT);
+ }
+
if (!preferences.ocr_command)
{
preferences.ocr_command = strdup(OCRCOMMAND);
@@ -2225,20 +2217,6 @@ static RETSIGTYPE xsane_quit_handler(int signal)
/* ---------------------------------------------------------------------------------------------------------------------- */
-void xsane_add_process_to_list(pid_t pid)
-{
- XsaneChildprocess *newprocess;
-
- DBG(DBG_proc, "xsane_add_process_to_list(%d)\n", pid);
-
- newprocess = malloc(sizeof(XsaneChildprocess));
- newprocess->pid = pid;
- newprocess->next = xsane.childprocess_list;
- xsane.childprocess_list = newprocess;
-}
-
-/* ---------------------------------------------------------------------------------------------------------------------- */
-
static RETSIGTYPE xsane_sigchld_handler(int signal)
{
int status;
@@ -2304,11 +2282,11 @@ static void xsane_quit(void)
preview_destroy(preview);
}
-#ifdef XSANE_ACTIVATE_MAIL
- if (xsane.mail_project_save)
+#ifdef XSANE_ACTIVATE_EMAIL
+ if (xsane.email_project_save)
{
- xsane.mail_project_save = 0;
- xsane_mail_project_save();
+ xsane.email_project_save = 0;
+ xsane_email_project_save();
}
#endif
@@ -2380,6 +2358,12 @@ static gint xsane_standard_option_win_delete(GtkWidget *widget, gpointer data)
{
DBG(DBG_proc, "xsane_standard_option_win_delete\n");
+ if (preferences.show_standard_options)
+ {
+ xsane_window_get_position(xsane.standard_options_dialog, &xsane.standard_options_dialog_posx, &xsane.standard_options_dialog_posy);
+ gtk_window_move(GTK_WINDOW(xsane.standard_options_dialog), xsane.standard_options_dialog_posx, xsane.standard_options_dialog_posy);
+ }
+
gtk_widget_hide(widget);
preferences.show_standard_options = FALSE;
gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(xsane.show_standard_options_widget), preferences.show_standard_options);
@@ -2392,6 +2376,12 @@ static gint xsane_advanced_option_win_delete(GtkWidget *widget, gpointer data)
{
DBG(DBG_proc, "xsane_advanced_option_win_delete\n");
+ if (preferences.show_advanced_options)
+ {
+ xsane_window_get_position(xsane.advanced_options_dialog, &xsane.advanced_options_dialog_posx, &xsane.advanced_options_dialog_posy);
+ gtk_window_move(GTK_WINDOW(xsane.advanced_options_dialog), xsane.advanced_options_dialog_posx, xsane.advanced_options_dialog_posy);
+ }
+
gtk_widget_hide(widget);
preferences.show_advanced_options = FALSE;
gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(xsane.show_advanced_options_widget), preferences.show_advanced_options);
@@ -3409,7 +3399,7 @@ static void xsane_about_dialog(GtkWidget *widget, gpointer data)
TEXT_VERSION, XSANE_VERSION,
XSANE_COPYRIGHT_SIGN, XSANE_COPYRIGHT_TXT,
TEXT_HOMEPAGE, XSANE_HOMEPAGE,
- TEXT_EMAIL, XSANE_EMAIL);
+ TEXT_EMAIL_ADR, XSANE_EMAIL_ADR);
label = gtk_label_new(buf);
gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, FALSE, 0);
@@ -3531,3142 +3521,6 @@ static void xsane_about_translation_dialog(GtkWidget *widget, gpointer data)
/* ---------------------------------------------------------------------------------------------------------------------- */
-static gint xsane_fax_dialog_delete()
-{
- return TRUE;
-}
-
-/* ---------------------------------------------------------------------------------------------------------------------- */
-
-static void xsane_fax_dialog()
-{
- GtkWidget *fax_dialog, *fax_scan_vbox, *fax_project_vbox, *hbox, *fax_project_exists_hbox, *button;
- GtkWidget *scrolled_window, *list;
- char buf[64];
- GtkWidget *pixmapwidget, *text;
- GdkBitmap *mask;
- GdkPixmap *pixmap;
-
- DBG(DBG_proc, "xsane_fax_dialog\n");
-
- if (xsane.fax_dialog)
- {
- return; /* window already is open */
- }
-
- /* GTK_WINDOW_TOPLEVEL looks better but does not place it nice*/
- fax_dialog = gtk_window_new(GTK_WINDOW_TOPLEVEL);
-
- snprintf(buf, sizeof(buf), "%s %s", xsane.prog_name, WINDOW_FAX_PROJECT);
- gtk_window_set_title(GTK_WINDOW(fax_dialog), buf);
- g_signal_connect(GTK_OBJECT(fax_dialog), "delete_event", (GtkSignalFunc) xsane_fax_dialog_delete, NULL);
- xsane_set_window_icon(fax_dialog, 0);
- gtk_window_add_accel_group(GTK_WINDOW(fax_dialog), xsane.accelerator_group);
-
- /* set the main vbox */
- fax_scan_vbox = gtk_vbox_new(FALSE, 0);
- gtk_container_set_border_width(GTK_CONTAINER(fax_scan_vbox), 0);
- gtk_container_add(GTK_CONTAINER(fax_dialog), fax_scan_vbox);
- gtk_widget_show(fax_scan_vbox);
-
- /* fax project */
-
- hbox = gtk_hbox_new(FALSE, 2);
- gtk_container_set_border_width(GTK_CONTAINER(hbox), 2);
- gtk_box_pack_start(GTK_BOX(fax_scan_vbox), hbox, FALSE, FALSE, 2);
-
- pixmap = gdk_pixmap_create_from_xpm_d(xsane.shell->window, &mask, xsane.bg_trans, (gchar **) fax_xpm);
- pixmapwidget = gtk_image_new_from_pixmap(pixmap, mask);
- gtk_box_pack_start(GTK_BOX(hbox), pixmapwidget, FALSE, FALSE, 2);
- gdk_drawable_unref(pixmap);
-
- text = gtk_entry_new();
- xsane_back_gtk_set_tooltip(xsane.tooltips, text, DESC_FAXPROJECT);
- gtk_entry_set_max_length(GTK_ENTRY(text), 128);
- gtk_entry_set_text(GTK_ENTRY(text), (char *) preferences.fax_project);
- gtk_box_pack_start(GTK_BOX(hbox), text, TRUE, TRUE, 4);
- g_signal_connect(GTK_OBJECT(text), "changed", (GtkSignalFunc) xsane_fax_project_changed_callback, NULL);
-
- xsane.fax_project_entry = text;
- xsane.fax_project_entry_box = hbox;
-
- gtk_widget_show(pixmapwidget);
- gtk_widget_show(text);
- gtk_widget_show(hbox);
-
- fax_project_vbox = gtk_vbox_new(/* homogeneous */ FALSE, 0);
- gtk_box_pack_start(GTK_BOX(fax_scan_vbox), fax_project_vbox, TRUE, TRUE, 0);
- gtk_widget_show(fax_project_vbox);
-
- /* fax receiver */
-
- hbox = gtk_hbox_new(FALSE, 2);
- gtk_container_set_border_width(GTK_CONTAINER(hbox), 2);
- gtk_box_pack_start(GTK_BOX(fax_project_vbox), hbox, FALSE, FALSE, 2);
-
- gtk_widget_realize(fax_dialog);
-
- pixmap = gdk_pixmap_create_from_xpm_d(fax_dialog->window, &mask, xsane.bg_trans, (gchar **) faxreceiver_xpm);
- pixmapwidget = gtk_image_new_from_pixmap(pixmap, mask);
- gtk_box_pack_start(GTK_BOX(hbox), pixmapwidget, FALSE, FALSE, 2);
- gdk_drawable_unref(pixmap);
-
- text = gtk_entry_new();
- xsane_back_gtk_set_tooltip(xsane.tooltips, text, DESC_FAXRECEIVER);
- gtk_entry_set_max_length(GTK_ENTRY(text), 128);
- gtk_box_pack_start(GTK_BOX(hbox), text, TRUE, TRUE, 4);
- g_signal_connect(GTK_OBJECT(text), "changed", (GtkSignalFunc) xsane_fax_receiver_changed_callback, NULL);
-
- xsane.fax_receiver_entry = text;
-
- gtk_widget_show(pixmapwidget);
- gtk_widget_show(text);
- gtk_widget_show(hbox);
-
- /* fine mode */
- button = gtk_check_button_new_with_label(RADIO_BUTTON_FINE_MODE);
- xsane_back_gtk_set_tooltip(xsane.tooltips, button, DESC_FAX_FINE_MODE);
- gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button), preferences.fax_fine_mode);
- gtk_box_pack_start(GTK_BOX(fax_project_vbox), button, FALSE, FALSE, 2);
- gtk_widget_show(button);
- g_signal_connect(GTK_OBJECT(button), "clicked", (GtkSignalFunc) xsane_fax_fine_mode_callback, NULL);
-
-
- scrolled_window = gtk_scrolled_window_new(0, 0);
- gtk_widget_set_size_request(scrolled_window, 200, 100);
- gtk_container_add(GTK_CONTAINER(fax_project_vbox), scrolled_window);
- gtk_widget_show(scrolled_window);
-
- list = gtk_list_new();
-/* gtk_list_set_selection_mode(list, GTK_SELECTION_BROWSE); */
-
- gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(scrolled_window), list);
-
- gtk_widget_show(list);
-
- xsane.fax_list = list;
-
-
- hbox = gtk_hbox_new(FALSE, 2);
- gtk_container_set_border_width(GTK_CONTAINER(hbox), 2);
- gtk_box_pack_start(GTK_BOX(fax_project_vbox), hbox, FALSE, FALSE, 2);
-
- button = gtk_button_new_with_label(BUTTON_FILE_INSERT);
- g_signal_connect(GTK_OBJECT(button), "clicked", (GtkSignalFunc) xsane_fax_entry_insert_callback, list);
- gtk_box_pack_start(GTK_BOX(hbox), button, TRUE, TRUE, 0);
- gtk_widget_show(button);
-
- button = gtk_button_new_with_label(BUTTON_PAGE_SHOW);
- g_signal_connect(GTK_OBJECT(button), "clicked", (GtkSignalFunc) xsane_fax_show_callback, list);
- gtk_box_pack_start(GTK_BOX(hbox), button, TRUE, TRUE, 0);
- gtk_widget_show(button);
-
- button = gtk_button_new_with_label(BUTTON_PAGE_RENAME);
- g_signal_connect(GTK_OBJECT(button), "clicked", (GtkSignalFunc) xsane_fax_entry_rename_callback, list);
- gtk_box_pack_start(GTK_BOX(hbox), button, TRUE, TRUE, 0);
- gtk_widget_show(button);
-
- button = gtk_button_new_with_label(BUTTON_PAGE_DELETE);
- g_signal_connect(GTK_OBJECT(button), "clicked", (GtkSignalFunc) xsane_fax_entry_delete_callback, list);
- gtk_box_pack_start(GTK_BOX(hbox), button, TRUE, TRUE, 0);
- gtk_widget_show(button);
-
- xsane_button_new_with_pixmap(fax_dialog->window, hbox, move_up_xpm, 0, (GtkSignalFunc) xsane_fax_entry_move_up_callback, list);
- xsane_button_new_with_pixmap(fax_dialog->window, hbox, move_down_xpm, 0, (GtkSignalFunc) xsane_fax_entry_move_down_callback, list);
-
- gtk_widget_show(hbox);
-
- xsane.fax_project_box = fax_project_vbox;
-
- /* set the main hbox */
- hbox = gtk_hbox_new(FALSE, 0);
- xsane_separator_new(fax_project_vbox, 2);
- gtk_box_pack_end(GTK_BOX(fax_scan_vbox), hbox, FALSE, FALSE, 5);
- gtk_container_set_border_width(GTK_CONTAINER(hbox), 5);
- gtk_widget_show(hbox);
-
-
- fax_project_exists_hbox = gtk_hbox_new(FALSE, 2);
- gtk_box_pack_start(GTK_BOX(hbox), fax_project_exists_hbox, TRUE, TRUE, 0);
-
- button = gtk_button_new_with_label(BUTTON_SEND_PROJECT);
- g_signal_connect(GTK_OBJECT(button), "clicked", (GtkSignalFunc) xsane_fax_send, NULL);
- gtk_box_pack_start(GTK_BOX(fax_project_exists_hbox), button, TRUE, TRUE, 0);
- gtk_widget_show(button);
-
- button = gtk_button_new_with_label(BUTTON_DELETE_PROJECT);
- g_signal_connect(GTK_OBJECT(button), "clicked", (GtkSignalFunc) xsane_fax_project_delete, NULL);
- gtk_box_pack_start(GTK_BOX(fax_project_exists_hbox), button, TRUE, TRUE, 0);
- gtk_widget_show(button);
-
- gtk_widget_show(fax_project_exists_hbox);
- xsane.fax_project_exists = fax_project_exists_hbox;
-
- button = gtk_button_new_with_label(BUTTON_CREATE_PROJECT);
- g_signal_connect(GTK_OBJECT(button), "clicked", (GtkSignalFunc) xsane_fax_project_create, NULL);
- gtk_box_pack_start(GTK_BOX(hbox), button, TRUE, TRUE, 0);
- xsane.fax_project_not_exists = button;
-
- /* progress bar */
- xsane.fax_progress_bar = (GtkProgressBar *) gtk_progress_bar_new();
- gtk_box_pack_start(GTK_BOX(fax_scan_vbox), (GtkWidget *) xsane.fax_progress_bar, FALSE, FALSE, 0);
- gtk_progress_set_show_text(GTK_PROGRESS(xsane.fax_progress_bar), TRUE);
- gtk_progress_set_format_string(GTK_PROGRESS(xsane.fax_progress_bar), "");
- gtk_widget_show(GTK_WIDGET(xsane.fax_progress_bar));
-
-
- xsane.fax_dialog = fax_dialog;
-
- xsane_fax_project_load();
-
- gtk_widget_show(fax_dialog);
-}
-
-/* ---------------------------------------------------------------------------------------------------------------------- */
-
-static void xsane_fax_dialog_close()
-{
- DBG(DBG_proc, "xsane_fax_dialog_close\n");
-
- if (xsane.fax_dialog == NULL)
- {
- return;
- }
-
- gtk_widget_destroy(xsane.fax_dialog);
-
- xsane.fax_dialog = NULL;
- xsane.fax_list = NULL;
-}
-
-/* ---------------------------------------------------------------------------------------------------------------------- */
-
-static void xsane_fax_project_load()
-{
- FILE *projectfile;
- char page[256];
- char filename[PATH_MAX];
- GtkWidget *list_item;
- int i;
- int c;
-
- DBG(DBG_proc, "xsane_fax_project_load\n");
-
- if (xsane.fax_status)
- {
- free(xsane.fax_status);
- xsane.fax_status = NULL;
- }
-
- if (xsane.fax_receiver)
- {
- free(xsane.fax_receiver);
- xsane.fax_receiver = NULL;
- }
-
- g_signal_handlers_disconnect_by_func(GTK_OBJECT(xsane.fax_receiver_entry), GTK_SIGNAL_FUNC(xsane_fax_receiver_changed_callback), 0);
- gtk_list_remove_items(GTK_LIST(xsane.fax_list), GTK_LIST(xsane.fax_list)->children);
-
- snprintf(filename, sizeof(filename), "%s/xsane-fax-list", preferences.fax_project);
- projectfile = fopen(filename, "rb"); /* read binary (b for win32) */
-
- if ((!projectfile) || (feof(projectfile)))
- {
- xsane.fax_status=strdup(TEXT_FAX_STATUS_NOT_CREATED);
-
- snprintf(filename, sizeof(filename), "%s/page-1.pnm", preferences.fax_project);
- xsane.fax_filename=strdup(filename);
- xsane_update_counter_in_filename(&xsane.fax_filename, FALSE, 0, preferences.filename_counter_len); /* correct counter len */
-
- xsane.fax_receiver=strdup("");
- gtk_entry_set_text(GTK_ENTRY(xsane.fax_receiver_entry), (char *) xsane.fax_receiver);
-
- gtk_widget_set_sensitive(xsane.fax_project_box, FALSE);
- gtk_widget_hide(xsane.fax_project_exists);
- gtk_widget_show(xsane.fax_project_not_exists);
- gtk_widget_set_sensitive(GTK_WIDGET(xsane.start_button), FALSE);
- }
- else
- {
- i=0;
- c=0;
- while ((i<255) && (c != 10) && (c != EOF)) /* first line is receiver phone number or address */
- {
- c = fgetc(projectfile);
- page[i++] = c;
- }
- page[i-1] = 0;
- if (strchr(page, '@'))
- {
- *strchr(page, '@') = 0;
- }
- xsane.fax_status = strdup(page);
-
- i=0;
- c=0;
- while ((i<255) && (c != 10) && (c != EOF)) /* first line is receiver phone number or address */
- {
- c = fgetc(projectfile);
- page[i++] = c;
- }
- page[i-1] = 0;
-
- xsane.fax_receiver=strdup(page);
- gtk_entry_set_text(GTK_ENTRY(xsane.fax_receiver_entry), (char *) xsane.fax_receiver);
-
-
- i=0;
- c=0;
- while ((i<255) && (c != 10) && (c != EOF)) /* second line is next fax filename */
- {
- c = fgetc(projectfile);
- page[i++] = c;
- }
- page[i-1] = 0;
-
- snprintf(filename, sizeof(filename), "%s/%s", preferences.fax_project, page);
- xsane.fax_filename=strdup(filename);
-
- while (!feof(projectfile))
- {
- i=0;
- c=0;
-
- while ((i<255) && (c != 10) && (c != EOF))
- {
- c = fgetc(projectfile);
- page[i++] = c;
- }
- page[i-1]=0;
-
- if (c > 1)
- {
- char *type;
- char *extension;
-
- extension = strrchr(page, '.');
- if (extension)
- {
- type = strdup(extension);
- *extension = 0;
- }
- else
- {
- type = strdup("");
- }
-
- list_item = gtk_list_item_new_with_label(page);
- gtk_object_set_data(GTK_OBJECT(list_item), "list_item_data", strdup(page));
- gtk_object_set_data(GTK_OBJECT(list_item), "list_item_type", strdup(type));
- gtk_container_add(GTK_CONTAINER(xsane.fax_list), list_item);
- gtk_widget_show(list_item);
- }
- }
- gtk_widget_set_sensitive(xsane.fax_project_box, TRUE);
- gtk_widget_show(xsane.fax_project_exists);
- gtk_widget_hide(xsane.fax_project_not_exists);
- gtk_widget_set_sensitive(GTK_WIDGET(xsane.start_button), TRUE);
- }
-
- if (projectfile)
- {
- fclose(projectfile);
- }
-
- g_signal_connect(GTK_OBJECT(xsane.fax_receiver_entry), "changed", (GtkSignalFunc) xsane_fax_receiver_changed_callback, NULL);
-
- gtk_progress_set_format_string(GTK_PROGRESS(xsane.fax_progress_bar), _(xsane.fax_status));
- gtk_progress_bar_update(GTK_PROGRESS_BAR(xsane.fax_progress_bar), 0.0);
-}
-
-/* ---------------------------------------------------------------------------------------------------------------------- */
-
-static void xsane_fax_project_delete()
-{
- char *page;
- char file[256];
- GList *list = (GList *) GTK_LIST(xsane.fax_list)->children;
- GtkObject *list_item;
-
- DBG(DBG_proc, "xsane_fax_project_delete\n");
-
- while (list)
- {
- list_item = GTK_OBJECT(list->data);
- page = strdup((char *) gtk_object_get_data(list_item, "list_item_data"));
- xsane_convert_text_to_filename(&page);
- snprintf(file, sizeof(file), "%s/%s.pnm", preferences.fax_project, page);
- free(page);
- remove(file);
- list = list->next;
- }
- snprintf(file, sizeof(file), "%s/xsane-fax-list", preferences.fax_project);
- remove(file);
- snprintf(file, sizeof(file), "%s", preferences.fax_project);
- rmdir(file);
-
- xsane_fax_project_load();
-}
-
-/* ---------------------------------------------------------------------------------------------------------------------- */
-
-static void xsane_fax_project_update_project_status()
-{
- FILE *projectfile;
- char filename[PATH_MAX];
- char buf[256];
-
- snprintf(filename, sizeof(filename), "%s/xsane-fax-list", preferences.fax_project);
- projectfile = fopen(filename, "r+b"); /* r+ = read and write, position = start of file */
-
- snprintf(buf, 32, "%s@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@", xsane.fax_status); /* fill 32 characters status line */
- fprintf(projectfile, "%s\n", buf); /* first line is status of mail */
-
- fclose(projectfile);
-}
-
-/* ---------------------------------------------------------------------------------------------------------------------- */
-
-void xsane_fax_project_save()
-{
- FILE *projectfile;
- char *page;
- char *type;
- char filename[256];
- GList *list = (GList *) GTK_LIST(xsane.fax_list)->children;
- GtkObject *list_item;
-
- DBG(DBG_proc, "xsane_fax_project_save\n");
-
- umask((mode_t) preferences.directory_umask); /* define new file permissions */
- mkdir(preferences.fax_project, 0777); /* make sure directory exists */
-
- snprintf(filename, sizeof(filename), "%s/xsane-fax-list", preferences.fax_project);
-
- if (xsane_create_secure_file(filename)) /* remove possibly existing symbolic links for security
-*/
- {
- char buf[256];
-
- snprintf(buf, sizeof(buf), "%s %s %s\n", ERR_DURING_SAVE, ERR_CREATE_SECURE_FILE, filename);
- xsane_back_gtk_error(buf, TRUE);
- return; /* error */
- }
- projectfile = fopen(filename, "wb"); /* write binary (b for win32) */
-
- if (!projectfile)
- {
- xsane_back_gtk_error(ERR_CREATE_FAX_PROJECT, TRUE);
-
- return;
- }
-
- if (xsane.fax_status)
- {
- char buf[256];
-
- snprintf(buf, 32, "%s@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@", xsane.fax_status); /* fill 32 characters status line */
- fprintf(projectfile, "%s\n", buf); /* first line is status of mail */
- gtk_progress_set_format_string(GTK_PROGRESS(xsane.fax_progress_bar), _(xsane.fax_status));
- gtk_progress_bar_update(GTK_PROGRESS_BAR(xsane.fax_progress_bar), 0.0);
- }
- else
- {
- fprintf(projectfile, " \n"); /* no mail status */
- gtk_progress_set_format_string(GTK_PROGRESS(xsane.fax_progress_bar), "");
- gtk_progress_bar_update(GTK_PROGRESS_BAR(xsane.fax_progress_bar), 0.0);
- }
-
- if (xsane.fax_receiver)
- {
- fprintf(projectfile, "%s\n", xsane.fax_receiver); /* first line is receiver phone number or address */
- }
- else
- {
- fprintf(projectfile, "\n");
- }
-
- if (xsane.fax_filename)
- {
- fprintf(projectfile, "%s\n", strrchr(xsane.fax_filename, '/')+1); /* second line is next fax filename */
- }
- else
- {
- fprintf(projectfile, "\n");
- }
-
-
- while (list)
- {
- list_item = GTK_OBJECT(list->data);
- page = (char *) gtk_object_get_data(list_item, "list_item_data");
- type = (char *) gtk_object_get_data(list_item, "list_item_type");
- fprintf(projectfile, "%s%s\n", page, type);
- list = list->next;
- }
- fclose(projectfile);
-}
-
-/* ---------------------------------------------------------------------------------------------------------------------- */
-
-static void xsane_fax_project_create()
-{
- DBG(DBG_proc, "xsane_fax_project_create\n");
-
- if (strlen(preferences.fax_project))
- {
- if (xsane.fax_status)
- {
- free(xsane.fax_status);
- }
- xsane.fax_status = strdup(TEXT_FAX_STATUS_CREATED);
- xsane_fax_project_save();
- xsane_fax_project_load();
- }
-}
-
-/* ---------------------------------------------------------------------------------------------------------------------- */
-
-static void xsane_fax_receiver_changed_callback(GtkWidget *widget, gpointer data)
-{
- DBG(DBG_proc, "xsane_fax_receiver_changed_callback\n");
-
- if (xsane.fax_status)
- {
- free(xsane.fax_status);
- }
- xsane.fax_status = strdup(TEXT_FAX_STATUS_CHANGED);
-
- if (xsane.fax_receiver)
- {
- free((void *) xsane.fax_receiver);
- }
- xsane.fax_receiver = strdup(gtk_entry_get_text(GTK_ENTRY(widget)));
-
- xsane_fax_project_save();
-
- gtk_progress_set_format_string(GTK_PROGRESS(xsane.fax_progress_bar), _(xsane.fax_status));
- gtk_progress_bar_update(GTK_PROGRESS_BAR(xsane.fax_progress_bar), 0.0);
-}
-
-/* ---------------------------------------------------------------------------------------------------------------------- */
-
-static void xsane_fax_project_changed_callback(GtkWidget *widget, gpointer data)
-{
- DBG(DBG_proc, "xsane_fax_project_changed_callback\n");
-
- if (preferences.fax_project)
- {
- free((void *) preferences.fax_project);
- }
- preferences.fax_project = strdup(gtk_entry_get_text(GTK_ENTRY(widget)));
-
- xsane_fax_project_load();
-}
-
-/* ---------------------------------------------------------------------------------------------------------------------- */
-
-static void xsane_fax_fine_mode_callback(GtkWidget * widget)
-{
- DBG(DBG_proc, "xsane_fax_fine_mode_callback\n");
-
- preferences.fax_fine_mode = (GTK_TOGGLE_BUTTON(widget)->active != 0);
-}
-
-/* ---------------------------------------------------------------------------------------------------------------------- */
-
-static void xsane_list_entrys_swap(GtkWidget *list_item_1, GtkWidget *list_item_2)
-{
- char *page1;
- char *page2;
- char *type1;
- char *type2;
-
- DBG(DBG_proc, "xsane_list_entrys_swap\n");
-
- page1 = (char *) gtk_object_get_data(GTK_OBJECT(list_item_1), "list_item_data");
- type1 = (char *) gtk_object_get_data(GTK_OBJECT(list_item_1), "list_item_type");
- page2 = (char *) gtk_object_get_data(GTK_OBJECT(list_item_2), "list_item_data");
- type2 = (char *) gtk_object_get_data(GTK_OBJECT(list_item_2), "list_item_type");
-
- gtk_label_set(GTK_LABEL(gtk_container_children(GTK_CONTAINER(list_item_1))->data), page2);
- gtk_label_set(GTK_LABEL(gtk_container_children(GTK_CONTAINER(list_item_2))->data), page1);
- gtk_object_set_data(GTK_OBJECT(list_item_1), "list_item_data", page2);
- gtk_object_set_data(GTK_OBJECT(list_item_1), "list_item_type", type2);
- gtk_object_set_data(GTK_OBJECT(list_item_2), "list_item_data", page1);
- gtk_object_set_data(GTK_OBJECT(list_item_2), "list_item_type", type1);
-}
-
-/* ---------------------------------------------------------------------------------------------------------------------- */
-
-static void xsane_fax_entry_move_up_callback(GtkWidget *widget, gpointer list)
-{
- GList *select;
- GList *item = GTK_LIST(list)->children;
- GtkWidget *list_item_1;
- GtkWidget *list_item_2;
- int position;
- int newpos;
-
- DBG(DBG_proc, "xsane_fax_entry_move_up\n");
-
- select = GTK_LIST(list)->selection;
- if (select)
- {
- list_item_1 = select->data;
-
- position = gtk_list_child_position(GTK_LIST(list), list_item_1);
- position--; /* move up */
- newpos = position;
-
- if (position >= 0)
- {
- while (position>0)
- {
- item = item->next;
- position--;
- }
-
- list_item_2 = item->data;
- if (list_item_2)
- {
- xsane_list_entrys_swap(list_item_1, list_item_2);
- gtk_list_select_item(GTK_LIST(list), newpos);
- xsane_fax_project_save();
- }
- }
- }
-}
-
-/* ---------------------------------------------------------------------------------------------------------------------- */
-
-static void xsane_fax_entry_move_down_callback(GtkWidget *widget, gpointer list)
-{
- GList *select;
- GList *item = GTK_LIST(list)->children;
- GtkWidget *list_item_1;
- GtkWidget *list_item_2;
- int position;
- int newpos;
-
- DBG(DBG_proc, "xsane_fax_entry_move_down\n");
-
- select = GTK_LIST(list)->selection;
- if (select)
- {
- list_item_1 = select->data;
-
- position = gtk_list_child_position(GTK_LIST(list), list_item_1);
- position++; /* move down */
- newpos = position;
-
- while ((position>0) && (item))
- {
- item = item->next;
- position--;
- }
-
- if (item)
- {
- list_item_2 = item->data;
- if (list_item_2)
- {
- xsane_list_entrys_swap(list_item_1, list_item_2);
- gtk_list_select_item(GTK_LIST(list), newpos);
- xsane_fax_project_save();
- }
- }
- }
-}
-
-/* ---------------------------------------------------------------------------------------------------------------------- */
-
-int xsane_fax_entry_rename;
-
-static void xsane_fax_entry_rename_button_callback(GtkWidget *widget, gpointer data)
-{
- DBG(DBG_proc, "xsane_fax_entry_rename\n");
-
- xsane_fax_entry_rename = (int) data;
-}
-
-/* ---------------------------------------------------------------------------------------------------------------------- */
-
-static void xsane_fax_entry_rename_callback(GtkWidget *widget, gpointer list)
-{
- GtkWidget *list_item;
- GList *select;
- char *oldpage;
- char *newpage;
- char *type;
- char oldfile[256];
- char newfile[256];
-
- DBG(DBG_proc, "xsane_fax_entry_rename_callback\n");
-
- select = GTK_LIST(list)->selection;
- if (select)
- {
- GtkWidget *rename_dialog;
- GtkWidget *text;
- GtkWidget *button;
- GtkWidget *vbox, *hbox;
- char filename[PATH_MAX];
-
- list_item = select->data;
- oldpage = strdup((char *) gtk_object_get_data(GTK_OBJECT(list_item), "list_item_data"));
- type = strdup((char *) gtk_object_get_data(GTK_OBJECT(list_item), "list_item_type"));
-
- xsane_set_sensitivity(FALSE);
-
- rename_dialog = gtk_window_new(GTK_WINDOW_TOPLEVEL);
- xsane_set_window_icon(rename_dialog, 0);
-
- /* set the main vbox */
- vbox = gtk_vbox_new(FALSE, 0);
- gtk_container_set_border_width(GTK_CONTAINER(vbox), 0);
- gtk_container_add(GTK_CONTAINER(rename_dialog), vbox);
- gtk_widget_show(vbox);
-
- /* set the main hbox */
- hbox = gtk_hbox_new(FALSE, 0);
- xsane_separator_new(vbox, 2);
- gtk_box_pack_end(GTK_BOX(vbox), hbox, FALSE, FALSE, 5);
- gtk_container_set_border_width(GTK_CONTAINER(hbox), 5);
- gtk_widget_show(hbox);
-
- gtk_window_set_position(GTK_WINDOW(rename_dialog), GTK_WIN_POS_CENTER);
- gtk_window_set_resizable(GTK_WINDOW(rename_dialog), FALSE);
- snprintf(filename, sizeof(filename), "%s %s", xsane.prog_name, WINDOW_FAX_RENAME);
- gtk_window_set_title(GTK_WINDOW(rename_dialog), filename);
- g_signal_connect(GTK_OBJECT(rename_dialog), "delete_event", (GtkSignalFunc) xsane_fax_entry_rename_button_callback,(void *) -1);
- gtk_widget_show(rename_dialog);
-
- text = gtk_entry_new();
- xsane_back_gtk_set_tooltip(xsane.tooltips, text, DESC_FAXPAGENAME);
- gtk_entry_set_max_length(GTK_ENTRY(text), 64);
- gtk_entry_set_text(GTK_ENTRY(text), oldpage);
- gtk_widget_set_size_request(text, 300, -1);
- gtk_box_pack_start(GTK_BOX(vbox), text, TRUE, TRUE, 4);
- gtk_widget_show(text);
-
-
-#ifdef HAVE_GTK2
- button = gtk_button_new_from_stock(GTK_STOCK_OK);
-#else
- button = gtk_button_new_with_label(BUTTON_OK);
-#endif
- g_signal_connect(GTK_OBJECT(button), "clicked", (GtkSignalFunc) xsane_fax_entry_rename_button_callback, (void *) 1);
- gtk_box_pack_start(GTK_BOX(hbox), button, TRUE, TRUE, 0);
- gtk_widget_show(button);
-
-#ifdef HAVE_GTK2
- button = gtk_button_new_from_stock(GTK_STOCK_CANCEL);
-#else
- button = gtk_button_new_with_label(BUTTON_CANCEL);
-#endif
- g_signal_connect(GTK_OBJECT(button), "clicked", (GtkSignalFunc) xsane_fax_entry_rename_button_callback, (void *) -1);
- gtk_box_pack_start(GTK_BOX(hbox), button, TRUE, TRUE, 0);
- gtk_widget_show(button);
-
-
- xsane_fax_entry_rename = 0;
-
- while (xsane_fax_entry_rename == 0)
- {
- while (gtk_events_pending())
- {
- gtk_main_iteration();
- }
- }
-
- newpage = strdup(gtk_entry_get_text(GTK_ENTRY(text)));
-
- if (xsane_fax_entry_rename == 1)
- {
- gtk_label_set(GTK_LABEL(gtk_container_children(GTK_CONTAINER(list_item))->data), newpage);
- gtk_object_set_data(GTK_OBJECT(list_item), "list_item_data", strdup(newpage));
-
- xsane_convert_text_to_filename(&oldpage);
- xsane_convert_text_to_filename(&newpage);
- snprintf(oldfile, sizeof(oldfile), "%s/%s%s", preferences.fax_project, oldpage, type);
- snprintf(newfile, sizeof(newfile), "%s/%s%s", preferences.fax_project, newpage, type);
-
- rename(oldfile, newfile);
-
- xsane_fax_project_save();
- }
-
- free(oldpage);
- free(newpage);
- free(type);
-
- gtk_widget_destroy(rename_dialog);
-
- xsane_set_sensitivity(TRUE);
- }
-}
-
-/* ---------------------------------------------------------------------------------------------------------------------- */
-
-static void xsane_fax_entry_insert_callback(GtkWidget *widget, gpointer list)
-{
- GtkWidget *list_item;
- char filename[PATH_MAX];
- char windowname[255];
-
- DBG(DBG_proc, "xsane_fax_entry_insert_callback\n");
-
- xsane_set_sensitivity(FALSE);
-
- snprintf(windowname, sizeof(windowname), "%s %s %s", xsane.prog_name, WINDOW_FAX_INSERT, preferences.fax_project);
- filename[0] = 0;
-
- umask((mode_t) preferences.directory_umask); /* define new file permissions */
-
- if (!xsane_back_gtk_get_filename(windowname, filename, sizeof(filename), filename, NULL, TRUE, FALSE, FALSE, FALSE)) /* filename is selected */
- {
- FILE *sourcefile;
-
- sourcefile = fopen(filename, "rb"); /* read binary (b for win32) */
- if (sourcefile) /* file exists */
- {
- char buf[1024];
-
- fgets(buf, sizeof(buf), sourcefile);
-
- if (!strncmp("%!PS", buf, 4))
- {
- FILE *destfile;
- char destpath[PATH_MAX];
- char *destfilename;
- char *destfiletype;
- char *extension;
-
- destfilename = strdup(strrchr(filename, '/')+1);
- extension = strrchr(destfilename, '.');
- if (extension)
- {
- destfiletype = strdup(extension);
- *extension = 0;
- }
- else
- {
- destfiletype = strdup("");
- }
-
- snprintf(destpath, sizeof(destpath), "%s/%s%s", preferences.fax_project, destfilename, destfiletype);
- /* copy file to project directory */
- if (xsane_create_secure_file(destpath)) /* remove possibly existing symbolic links for security
-*/
- {
- fclose(sourcefile);
- snprintf(buf, sizeof(buf), "%s %s %s\n", ERR_DURING_SAVE, ERR_CREATE_SECURE_FILE, destpath);
- xsane_back_gtk_error(buf, TRUE);
- return; /* error */
- }
-
- destfile = fopen(destpath, "wb"); /* write binary (b for win32) */
-
- if (destfile) /* file is created */
- {
- fprintf(destfile, "%s\n", buf);
-
- while (!feof(sourcefile))
- {
- fgets(buf, sizeof(buf), sourcefile);
- fprintf(destfile, "%s", buf);
- }
-
- fclose(destfile);
-
-
- /* add filename to fax page list */
- list_item = gtk_list_item_new_with_label(destfilename);
- gtk_object_set_data(GTK_OBJECT(list_item), "list_item_data", strdup(destfilename));
- gtk_object_set_data(GTK_OBJECT(list_item), "list_item_type", strdup(destfiletype));
- gtk_container_add(GTK_CONTAINER(xsane.fax_list), list_item);
- gtk_widget_show(list_item);
-
- xsane_update_counter_in_filename(&xsane.fax_filename, TRUE, 1, preferences.filename_counter_len);
- xsane_fax_project_save();
- free(destfilename);
- }
- else /* file could not be created */
- {
- snprintf(buf, sizeof(buf), "%s %s", ERR_OPEN_FAILED, filename);
- xsane_back_gtk_decision(ERR_HEADER_ERROR, (gchar **) error_xpm, buf, BUTTON_OK, NULL, TRUE /* wait */);
- }
- }
- else
- {
- snprintf(buf, sizeof(buf), ERR_FILE_NOT_POSTSCRIPT, filename);
- xsane_back_gtk_decision(ERR_HEADER_ERROR, (gchar **) error_xpm, buf, BUTTON_OK, NULL, TRUE /* wait */);
- }
-
- fclose(sourcefile);
- }
- else
- {
- char buf[256];
- snprintf(buf, sizeof(buf), ERR_FILE_NOT_EXISTS, filename);
- xsane_back_gtk_decision(ERR_HEADER_ERROR, (gchar **) error_xpm, buf, BUTTON_OK, NULL, TRUE /* wait */);
- }
- }
-
- umask(XSANE_DEFAULT_UMASK); /* define new file permissions */
-
- xsane_set_sensitivity(TRUE);
-}
-
-/* ---------------------------------------------------------------------------------------------------------------------- */
-
-static void xsane_fax_entry_delete_callback(GtkWidget *widget, gpointer list)
-{
- GtkObject *list_item;
- GList *select;
- char *page;
- char *type;
- char filename[PATH_MAX];
-
- DBG(DBG_proc, "xsane_fax_entry_delete_callback\n");
-
- select = GTK_LIST(list)->selection;
- if (select)
- {
- list_item = GTK_OBJECT(select->data);
- page = strdup((char *) gtk_object_get_data(list_item, "list_item_data"));
- type = strdup((char *) gtk_object_get_data(list_item, "list_item_type"));
- xsane_convert_text_to_filename(&page);
- snprintf(filename, sizeof(filename), "%s/%s%s", preferences.fax_project, page, type);
- free(page);
- free(type);
- remove(filename);
- gtk_widget_destroy(GTK_WIDGET(list_item));
- xsane_fax_project_save();
- }
-}
-
-/* ---------------------------------------------------------------------------------------------------------------------- */
-
-static void xsane_fax_show_callback(GtkWidget *widget, gpointer list)
-{
- GtkObject *list_item;
- GList *select;
- char *page;
- char *type;
- char filename[256];
-
- DBG(DBG_proc, "xsane_fax_entry_show_callback\n");
-
- select = GTK_LIST(list)->selection;
- if (select)
- {
- list_item = GTK_OBJECT(select->data);
- page = strdup((char *) gtk_object_get_data(list_item, "list_item_data"));
- type = strdup((char *) gtk_object_get_data(list_item, "list_item_type"));
- xsane_convert_text_to_filename(&page);
- snprintf(filename, sizeof(filename), "%s/%s%s", preferences.fax_project, page, type);
-
- if (!strncmp(type, ".pnm", 4))
- {
- /* when we do not allow any modification then we can work with the original file */
- /* so we do not have to copy the image into a dummy file here! */
-
- xsane_viewer_new(filename, FALSE, filename, VIEWER_NO_MODIFICATION);
- }
- else if (!strncmp(type, ".ps", 3))
- {
- char *arg[100];
- int argnr;
- pid_t pid;
-
- argnr = xsane_parse_options(preferences.fax_viewer, arg);
- arg[argnr++] = filename;
- arg[argnr] = 0;
-
- pid = fork();
-
- if (pid == 0) /* new process */
- {
- FILE *ipc_file = NULL;
-
- if (xsane.ipc_pipefd[0])
- {
- close(xsane.ipc_pipefd[0]); /* close reading end of pipe */
- ipc_file = fdopen(xsane.ipc_pipefd[1], "w");
- }
-
- DBG(DBG_info, "trying to change user id fo new subprocess:\n");
- DBG(DBG_info, "old effective uid = %d\n", (int) geteuid());
- setuid(getuid());
- DBG(DBG_info, "new effective uid = %d\n", (int) geteuid());
-
- execvp(arg[0], arg); /* does not return if successfully */
- DBG(DBG_error, "%s %s\n", ERR_FAILED_EXEC_FAX_VIEWER, preferences.fax_viewer);
-
- /* send error message via IPC pipe to parent process */
- if (ipc_file)
- {
- fprintf(ipc_file, "%s %s:\n%s", ERR_FAILED_EXEC_FAX_VIEWER, preferences.fax_viewer, strerror(errno));
- fflush(ipc_file); /* make sure message is displayed */
- fclose(ipc_file);
- }
-
- _exit(0); /* do not use exit() here! otherwise gtk gets in trouble */
- }
- else /* parent process */
- {
- xsane_add_process_to_list(pid); /* add pid to child process list */
- }
- }
-
- free(page);
- free(type);
- }
-}
-
-/* ---------------------------------------------------------------------------------------------------------------------- */
-
-static int xsane_fax_convert_pnm_to_ps(char *source_filename, char *fax_filename)
-{
- FILE *outfile;
- FILE *infile;
- Image_info image_info;
- char buf[256];
- int cancel_save;
-
- /* open progressbar */
- snprintf(buf, sizeof(buf), "%s - %s", PROGRESS_CONVERTING_DATA, source_filename);
- gtk_progress_set_format_string(GTK_PROGRESS(xsane.fax_progress_bar), buf);
- gtk_progress_bar_update(GTK_PROGRESS_BAR(xsane.fax_progress_bar), 0.0);
-
- while (gtk_events_pending())
- {
- DBG(DBG_info, "calling gtk_main_iteration\n");
- gtk_main_iteration();
- }
-
- infile = fopen(source_filename, "rb"); /* read binary (b for win32) */
- if (infile != 0)
- {
- xsane_read_pnm_header(infile, &image_info);
-
- umask((mode_t) preferences.image_umask); /* define image file permissions */
- outfile = fopen(fax_filename, "wb"); /* b = binary mode for win32 */
- umask(XSANE_DEFAULT_UMASK); /* define new file permissions */
- if (outfile != 0)
- {
- float imagewidth, imageheight;
-
- imagewidth = 72.0 * image_info.image_width /image_info.resolution_x; /* width in 1/72 inch */
- imageheight = 72.0 * image_info.image_height/image_info.resolution_y; /* height in 1/72 inch */
-
- DBG(DBG_info, "imagewidth = %f 1/72 inch\n", imagewidth);
- DBG(DBG_info, "imageheight = %f 1/72 inch\n", imageheight);
-
- xsane_save_ps(outfile, infile,
- &image_info,
- imagewidth, imageheight,
- preferences.fax_leftoffset * 72.0/MM_PER_INCH, /* paper_left_margin */
- preferences.fax_bottomoffset * 72.0/MM_PER_INCH, /* paper_bottom_margin */
- preferences.fax_width * 72.0/MM_PER_INCH, /* paper_width */
- preferences.fax_height * 72.0/MM_PER_INCH, /* paper_height */
- 0 /* portrait top left */,
- xsane.fax_progress_bar,
- &cancel_save);
- fclose(outfile);
- }
- else
- {
- char buf[256];
-
- DBG(DBG_info, "open of faxfile `%s'failed : %s\n", fax_filename, strerror(errno));
-
- snprintf(buf, sizeof(buf), "%s `%s': %s", ERR_OPEN_FAILED, fax_filename, strerror(errno));
- xsane_back_gtk_error(buf, TRUE);
- }
-
- fclose(infile);
- }
- else
- {
- char buf[256];
-
- DBG(DBG_info, "open of faxfile `%s'failed : %s\n", source_filename, strerror(errno));
-
- snprintf(buf, sizeof(buf), "%s `%s': %s", ERR_OPEN_FAILED, source_filename, strerror(errno));
- xsane_back_gtk_error(buf, TRUE);
- }
-
- gtk_progress_set_format_string(GTK_PROGRESS(xsane.fax_progress_bar), "");
- gtk_progress_bar_update(GTK_PROGRESS_BAR(xsane.fax_progress_bar), 0.0);
-
- while (gtk_events_pending())
- {
- DBG(DBG_info, "calling gtk_main_iteration\n");
- gtk_main_iteration();
- }
-
- return 0;
-}
-
-/* ---------------------------------------------------------------------------------------------------------------------- */
-
-static void xsane_fax_send()
-{
- char *page;
- char *type;
- char *fax_type=".ps";
- GList *list = (GList *) GTK_LIST(xsane.fax_list)->children;
- GtkObject *list_item;
- pid_t pid;
- char *arg[1000];
- char buf[256];
- char source_filename[PATH_MAX];
- char fax_filename[PATH_MAX];
- int argnr = 0;
- int i;
-
- DBG(DBG_proc, "xsane_fax_send\n");
-
- if (list)
- {
- if (!xsane_option_defined(xsane.fax_receiver))
- {
- snprintf(buf, sizeof(buf), "%s\n", ERR_SENDFAX_RECEIVER_MISSING);
- xsane_back_gtk_error(buf, TRUE);
- return;
- }
-
- xsane_set_sensitivity(FALSE);
- /* gtk_widget_set_sensitive(xsane.fax_dialog, FALSE); */
-
- argnr = xsane_parse_options(preferences.fax_command, arg);
-
- if (preferences.fax_fine_mode) /* fine mode */
- {
- if (xsane_option_defined(preferences.fax_fine_option))
- {
- arg[argnr++] = strdup(preferences.fax_fine_option);
- }
- }
- else /* normal mode */
- {
- if (xsane_option_defined(preferences.fax_normal_option))
- {
- arg[argnr++] = strdup(preferences.fax_normal_option);
- }
- }
-
- if (xsane_option_defined(preferences.fax_receiver_option))
- {
- arg[argnr++] = strdup(preferences.fax_receiver_option);
- }
- arg[argnr++] = strdup(xsane.fax_receiver);
-
- if (xsane_option_defined(preferences.fax_postscript_option))
- {
- arg[argnr++] = strdup(preferences.fax_postscript_option);
- }
-
- while ((list) && (argnr<999)) /* add pages to options */
- {
- list_item = GTK_OBJECT(list->data);
- page = strdup((char *) gtk_object_get_data(list_item, "list_item_data"));
- type = strdup((char *) gtk_object_get_data(list_item, "list_item_type"));
- xsane_convert_text_to_filename(&page);
- snprintf(source_filename, sizeof(source_filename), "%s/%s%s", preferences.fax_project, page, type);
- snprintf(fax_filename, sizeof(fax_filename), "%s/%s-fax%s", preferences.fax_project, page, fax_type);
- if (xsane_create_secure_file(fax_filename)) /* remove possibly existing symbolic links for security */
- {
- char buf[256];
-
- snprintf(buf, sizeof(buf), "%s %s %s\n", ERR_DURING_SAVE, ERR_CREATE_SECURE_FILE, fax_filename);
- xsane_back_gtk_error(buf, TRUE);
- return; /* error */
- }
-
- if (!strncmp(type, ".pnm", 4))
- {
- DBG(DBG_info, "converting %s to %s\n", source_filename, fax_filename);
- xsane_fax_convert_pnm_to_ps(source_filename, fax_filename);
- }
- else if (!strncmp(type, ".ps", 3))
- {
- int cancel_save = 0;
- xsane_copy_file_by_name(fax_filename, source_filename, xsane.fax_progress_bar, &cancel_save);
- }
- arg[argnr++] = strdup(fax_filename);
- list = list->next;
- free(page);
- free(type);
- }
-
- arg[argnr] = 0;
-
- pid = fork();
-
- if (pid == 0) /* new process */
- {
- FILE *ipc_file = NULL;
-
- if (xsane.ipc_pipefd[0])
- {
- close(xsane.ipc_pipefd[0]); /* close reading end of pipe */
- ipc_file = fdopen(xsane.ipc_pipefd[1], "w");
- }
-
- DBG(DBG_info, "trying to change user id for new subprocess:\n");
- DBG(DBG_info, "old effective uid = %d\n", (int) geteuid());
- setuid(getuid());
- DBG(DBG_info, "new effective uid = %d\n", (int) geteuid());
-
- execvp(arg[0], arg); /* does not return if successfully */
- DBG(DBG_error, "%s %s\n", ERR_FAILED_EXEC_FAX_CMD, preferences.fax_command);
-
- /* send error message via IPC pipe to parent process */
- if (ipc_file)
- {
- fprintf(ipc_file, "%s %s:\n%s", ERR_FAILED_EXEC_FAX_CMD, preferences.fax_command, strerror(errno));
- fflush(ipc_file); /* make sure message is displayed */
- fclose(ipc_file);
- }
-
- _exit(0); /* do not use exit() here! otherwise gtk gets in trouble */
- }
- else /* parent process */
- {
- xsane_add_process_to_list(pid); /* add pid to child process list */
- }
-
- for (i=0; i<argnr; i++)
- {
- free(arg[i]);
- }
-
- if (xsane.fax_status)
- {
- free(xsane.fax_status);
- }
- xsane.fax_status = strdup(TEXT_FAX_STATUS_QUEUEING_FAX);
- xsane_fax_project_update_project_status();
- gtk_progress_set_format_string(GTK_PROGRESS(xsane.fax_progress_bar), _(xsane.fax_status));
- gtk_progress_bar_update(GTK_PROGRESS_BAR(xsane.fax_progress_bar), 0.0);
-
- while (pid)
- {
- int status = 0;
- pid_t pid_status = waitpid(pid, &status, WNOHANG);
-
- if ( (pid_status < 0 ) || (pid == pid_status) )
- {
- pid = 0; /* ok, child process has terminated */
- }
-
- while (gtk_events_pending())
- {
- gtk_main_iteration();
- }
- }
-
- /* delete created fax files */
- list = (GList *) GTK_LIST(xsane.fax_list)->children;
- while (list)
- {
- list_item = GTK_OBJECT(list->data);
- page = strdup((char *) gtk_object_get_data(list_item, "list_item_data"));
- xsane_convert_text_to_filename(&page);
- snprintf(fax_filename, sizeof(fax_filename), "%s/%s-fax%s", preferences.fax_project, page, fax_type);
- free(page);
-
- DBG(DBG_info, "removing %s\n", fax_filename);
- remove(fax_filename);
-
- list = list->next;
- }
-
- xsane.fax_status = strdup(TEXT_FAX_STATUS_FAX_QUEUED);
- xsane_fax_project_update_project_status();
- gtk_progress_set_format_string(GTK_PROGRESS(xsane.fax_progress_bar), _(xsane.fax_status));
- gtk_progress_bar_update(GTK_PROGRESS_BAR(xsane.fax_progress_bar), 0.0);
-
- xsane_set_sensitivity(TRUE);
-
- /* gtk_widget_set_sensitive(xsane.fax_dialog, TRUE); */
- }
-
- DBG(DBG_info, "xsane_fax_send: done\n");
-}
-
-/* ---------------------------------------------------------------------------------------------------------------------- */
-#ifdef XSANE_ACTIVATE_MAIL
-
-static gint xsane_mail_dialog_delete()
-{
- return TRUE;
-}
-
-/* ---------------------------------------------------------------------------------------------------------------------- */
-
-static void xsane_mail_filetype_callback(GtkWidget *filetype_option_menu, char *filetype)
-{
- DBG(DBG_proc, "xsane_mail_filetype_callback(%s)\n", filetype);
-
- if (preferences.mail_filetype)
- {
- free(preferences.mail_filetype);
- }
- preferences.mail_filetype = strdup(filetype);
-}
-
-/* ---------------------------------------------------------------------------------------------------------------------- */
-
-static void xsane_mail_dialog()
-{
- GtkWidget *mail_dialog, *mail_scan_vbox, *mail_project_vbox;
- GtkWidget *mail_project_exists_hbox, *button;
- GtkWidget *hbox;
- GtkWidget *scrolled_window, *list;
- GtkWidget *pixmapwidget, *text;
- GtkWidget *attachment_frame, *text_frame;
- GtkWidget *label;
- GtkWidget *filetype_menu, *filetype_item;
- GtkWidget *filetype_option_menu;
- GdkPixmap *pixmap;
- GdkBitmap *mask;
- char buf[64];
- int filetype_nr;
- int select_item;
-
- DBG(DBG_proc, "xsane_mail_dialog\n");
-
- if (xsane.mail_dialog)
- {
- return; /* window already is open */
- }
-
- /* GTK_WINDOW_TOPLEVEL looks better but does not place it nice*/
- mail_dialog = gtk_window_new(GTK_WINDOW_TOPLEVEL);
-
- snprintf(buf, sizeof(buf), "%s %s", xsane.prog_name, WINDOW_MAIL_PROJECT);
- gtk_window_set_title(GTK_WINDOW(mail_dialog), buf);
- g_signal_connect(GTK_OBJECT(mail_dialog), "delete_event", (GtkSignalFunc) xsane_mail_dialog_delete, NULL);
- xsane_set_window_icon(mail_dialog, 0);
- gtk_window_add_accel_group(GTK_WINDOW(mail_dialog), xsane.accelerator_group);
-
- /* set the main vbox */
- mail_scan_vbox = gtk_vbox_new(FALSE, 0);
- gtk_container_set_border_width(GTK_CONTAINER(mail_scan_vbox), 0);
- gtk_container_add(GTK_CONTAINER(mail_dialog), mail_scan_vbox);
- gtk_widget_show(mail_scan_vbox);
-
-
- /* mail project */
- hbox = gtk_hbox_new(FALSE, 2);
- gtk_container_set_border_width(GTK_CONTAINER(hbox), 2);
- gtk_box_pack_start(GTK_BOX(mail_scan_vbox), hbox, FALSE, FALSE, 2);
-
- pixmap = gdk_pixmap_create_from_xpm_d(xsane.shell->window, &mask, xsane.bg_trans, (gchar **) mail_xpm);
- pixmapwidget = gtk_image_new_from_pixmap(pixmap, mask);
- gtk_box_pack_start(GTK_BOX(hbox), pixmapwidget, FALSE, FALSE, 2);
- gdk_drawable_unref(pixmap);
-
- text = gtk_entry_new();
- xsane_back_gtk_set_tooltip(xsane.tooltips, text, DESC_MAILPROJECT);
- gtk_entry_set_max_length(GTK_ENTRY(text), 128);
- gtk_entry_set_text(GTK_ENTRY(text), (char *) preferences.mail_project);
- gtk_box_pack_start(GTK_BOX(hbox), text, TRUE, TRUE, 4);
- g_signal_connect(GTK_OBJECT(text), "changed", (GtkSignalFunc) xsane_mail_project_changed_callback, NULL);
-
- xsane.mail_project_entry = text;
- xsane.mail_project_entry_box = hbox;
-
- gtk_widget_show(pixmapwidget);
- gtk_widget_show(text);
- gtk_widget_show(hbox);
-
- mail_project_vbox = gtk_vbox_new(/* homogeneous */ FALSE, 0);
- gtk_box_pack_start(GTK_BOX(mail_scan_vbox), mail_project_vbox, TRUE, TRUE, 0);
- gtk_widget_show(mail_project_vbox);
-
-
- /* mail receiver */
- hbox = gtk_hbox_new(FALSE, 2);
- gtk_container_set_border_width(GTK_CONTAINER(hbox), 2);
- gtk_box_pack_start(GTK_BOX(mail_project_vbox), hbox, FALSE, FALSE, 2);
-
- gtk_widget_realize(mail_dialog);
-
- pixmap = gdk_pixmap_create_from_xpm_d(mail_dialog->window, &mask, xsane.bg_trans, (gchar **) mailreceiver_xpm);
- pixmapwidget = gtk_image_new_from_pixmap(pixmap, mask);
- gtk_box_pack_start(GTK_BOX(hbox), pixmapwidget, FALSE, FALSE, 2);
- gdk_drawable_unref(pixmap);
-
- text = gtk_entry_new();
- gtk_entry_set_max_length(GTK_ENTRY(text), 128);
- xsane_back_gtk_set_tooltip(xsane.tooltips, text, DESC_MAILRECEIVER);
- gtk_box_pack_start(GTK_BOX(hbox), text, TRUE, TRUE, 4);
- g_signal_connect(GTK_OBJECT(text), "changed", (GtkSignalFunc) xsane_mail_receiver_changed_callback, NULL);
-
- xsane.mail_receiver_entry = text;
-
- gtk_widget_show(pixmapwidget);
- gtk_widget_show(text);
- gtk_widget_show(hbox);
-
-
- /* subject */
- hbox = gtk_hbox_new(FALSE, 2);
- gtk_container_set_border_width(GTK_CONTAINER(hbox), 2);
- gtk_box_pack_start(GTK_BOX(mail_project_vbox), hbox, FALSE, FALSE, 2);
-
- gtk_widget_realize(mail_dialog);
-
- pixmap = gdk_pixmap_create_from_xpm_d(mail_dialog->window, &mask, xsane.bg_trans, (gchar **) subject_xpm);
- pixmapwidget = gtk_image_new_from_pixmap(pixmap, mask);
- gtk_box_pack_start(GTK_BOX(hbox), pixmapwidget, FALSE, FALSE, 2);
- gdk_drawable_unref(pixmap);
-
- text = gtk_entry_new();
- xsane_back_gtk_set_tooltip(xsane.tooltips, text, DESC_MAILSUBJECT);
- gtk_entry_set_max_length(GTK_ENTRY(text), 128);
- gtk_box_pack_start(GTK_BOX(hbox), text, TRUE, TRUE, 4);
- g_signal_connect(GTK_OBJECT(text), "changed", (GtkSignalFunc) xsane_mail_subject_changed_callback, NULL);
-
- xsane.mail_subject_entry = text;
-
- gtk_widget_show(pixmapwidget);
- gtk_widget_show(text);
- gtk_widget_show(hbox);
-
-
- /* email text frame */
- text_frame = gtk_frame_new(TEXT_MAIL_TEXT);
- gtk_box_pack_start(GTK_BOX(mail_project_vbox), text_frame, TRUE, TRUE, 2);
- gtk_widget_show(text_frame);
-
- /* email text box */
- hbox = gtk_hbox_new(FALSE, 2);
- gtk_container_set_border_width(GTK_CONTAINER(hbox), 4);
- gtk_container_add(GTK_CONTAINER(text_frame), hbox);
- gtk_widget_show(hbox);
-
-#ifdef HAVE_GTK_TEXT_VIEW_H
- {
- GtkWidget *scrolled_window, *text_view, *text_buffer;
-
- /* create a scrolled window to get a vertical scrollbar */
- scrolled_window = gtk_scrolled_window_new(NULL, NULL);
- gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolled_window), GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
- gtk_container_add(GTK_CONTAINER(hbox), scrolled_window);
- gtk_widget_show(scrolled_window);
-
- /* create the gtk_text_view widget */
- text_view = gtk_text_view_new();
- gtk_text_view_set_editable(GTK_TEXT_VIEW(text_view), TRUE);
- gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW(text_view), GTK_WRAP_WORD);
- gtk_container_add(GTK_CONTAINER(scrolled_window), text_view);
- gtk_widget_show(text_view);
-
- /* get the text_buffer widget and insert the text from file */
- text_buffer = (GtkWidget *) gtk_text_view_get_buffer(GTK_TEXT_VIEW(text_view));
-
- xsane.mail_text_widget = text_buffer;
- }
-#else
- {
- GtkWidget *vscrollbar;
-
- /* Create the GtkText widget */
- text = gtk_text_new(NULL, NULL);
- gtk_text_set_editable(GTK_TEXT(text), TRUE); /* text is editable */
- gtk_text_set_word_wrap(GTK_TEXT(text), TRUE); /* wrap complete words */
- gtk_box_pack_start(GTK_BOX(hbox), text, TRUE, TRUE, 0);
- gtk_widget_show(text);
- xsane.mail_text_widget = text;
-
- /* Add a vertical scrollbar to the GtkText widget */
- vscrollbar = gtk_vscrollbar_new(GTK_TEXT(text)->vadj);
- gtk_box_pack_start(GTK_BOX(hbox), vscrollbar, FALSE, FALSE, 0);
- gtk_widget_show(vscrollbar);
- }
-#endif
-
-
- /* html mail */
- button = gtk_check_button_new_with_label(RADIO_BUTTON_HTML_MAIL);
- xsane_back_gtk_set_tooltip(xsane.tooltips, button, DESC_HTML_MAIL);
- gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button), xsane.mail_html_mode);
- gtk_box_pack_start(GTK_BOX(mail_project_vbox), button, FALSE, FALSE, 2);
- gtk_widget_show(button);
- g_signal_connect(GTK_OBJECT(button), "clicked", (GtkSignalFunc) xsane_mail_html_mode_callback, NULL);
- xsane.mail_html_mode_widget = button;
-
- xsane_separator_new(mail_scan_vbox, 2);
-
- /* FILETYPE MENU */
- /* button box, active when project exists */
- hbox = gtk_hbox_new(FALSE, 2);
- gtk_container_set_border_width(GTK_CONTAINER(hbox), 2);
- gtk_box_pack_start(GTK_BOX(mail_project_vbox), hbox, FALSE, FALSE, 2);
- gtk_widget_show(hbox);
-
- filetype_menu = gtk_menu_new();
-
- filetype_nr = -1;
- select_item = 0;
-
-#ifdef HAVE_LIBJPEG
- filetype_item = gtk_menu_item_new_with_label(MENU_ITEM_FILETYPE_JPEG);
- gtk_container_add(GTK_CONTAINER(filetype_menu), filetype_item);
- g_signal_connect(GTK_OBJECT(filetype_item), "activate", (GtkSignalFunc) xsane_mail_filetype_callback, (void *) XSANE_FILETYPE_JPEG);
- gtk_widget_show(filetype_item);
- filetype_nr++;
- if ( (preferences.mail_filetype) && (!strcasecmp(preferences.mail_filetype, XSANE_FILETYPE_JPEG)) )
- {
- select_item = filetype_nr;
- }
-#endif
-
-
- filetype_item = gtk_menu_item_new_with_label(MENU_ITEM_FILETYPE_PDF);
- gtk_container_add(GTK_CONTAINER(filetype_menu), filetype_item);
- g_signal_connect(GTK_OBJECT(filetype_item), "activate", (GtkSignalFunc) xsane_mail_filetype_callback, (void *) XSANE_FILETYPE_PDF);
- gtk_widget_show(filetype_item);
- filetype_nr++;
- if ( (preferences.mail_filetype) && (!strcasecmp(preferences.mail_filetype, XSANE_FILETYPE_PDF)) )
- {
- select_item = filetype_nr;
- }
-
-
-#ifdef HAVE_LIBPNG
-#ifdef HAVE_LIBZ
- filetype_item = gtk_menu_item_new_with_label(MENU_ITEM_FILETYPE_PNG);
- gtk_container_add(GTK_CONTAINER(filetype_menu), filetype_item);
- g_signal_connect(GTK_OBJECT(filetype_item), "activate", (GtkSignalFunc) xsane_mail_filetype_callback, (void *) XSANE_FILETYPE_PNG);
- gtk_widget_show(filetype_item);
- filetype_nr++;
- if ( (preferences.mail_filetype) && (!strcasecmp(preferences.mail_filetype, XSANE_FILETYPE_PNG)) )
- {
- select_item = filetype_nr;
- }
-#endif
-#endif
-
- filetype_item = gtk_menu_item_new_with_label(MENU_ITEM_FILETYPE_PS);
- gtk_container_add(GTK_CONTAINER(filetype_menu), filetype_item);
- g_signal_connect(GTK_OBJECT(filetype_item), "activate", (GtkSignalFunc) xsane_mail_filetype_callback, (void *) XSANE_FILETYPE_PS);
- gtk_widget_show(filetype_item);
- filetype_nr++;
- if ( (preferences.mail_filetype) && (!strcasecmp(preferences.mail_filetype, XSANE_FILETYPE_PS)) )
- {
- select_item = filetype_nr;
- }
-
-
-#ifdef HAVE_LIBTIFF
- filetype_item = gtk_menu_item_new_with_label(MENU_ITEM_FILETYPE_TIFF);
- gtk_container_add(GTK_CONTAINER(filetype_menu), filetype_item);
- g_signal_connect(GTK_OBJECT(filetype_item), "activate", (GtkSignalFunc) xsane_mail_filetype_callback, (void *) XSANE_FILETYPE_TIFF);
- gtk_widget_show(filetype_item);
- filetype_nr++;
- if ( (preferences.mail_filetype) && (!strcasecmp(preferences.mail_filetype, XSANE_FILETYPE_TIFF)) )
- {
- select_item = filetype_nr;
- }
-#endif
-
- label = gtk_label_new(TEXT_MAIL_FILETYPE);
- gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 2);
- gtk_widget_show(label);
-
- filetype_option_menu = gtk_option_menu_new();
- xsane_back_gtk_set_tooltip(xsane.tooltips, filetype_option_menu, DESC_MAIL_FILETYPE);
- gtk_option_menu_set_menu(GTK_OPTION_MENU(filetype_option_menu), filetype_menu);
- if (select_item >= 0)
- {
- gtk_option_menu_set_history(GTK_OPTION_MENU(filetype_option_menu), select_item);
- }
- gtk_box_pack_end(GTK_BOX(hbox), filetype_option_menu, FALSE, FALSE, 2);
- gtk_widget_show(filetype_menu);
- gtk_widget_show(filetype_option_menu);
-
-
- /* attachment frame */
- attachment_frame = gtk_frame_new(TEXT_ATTACHMENTS);
- gtk_box_pack_start(GTK_BOX(mail_project_vbox), attachment_frame, FALSE, FALSE, 2);
- gtk_widget_show(attachment_frame);
-
- /* attachment list */
- scrolled_window = gtk_scrolled_window_new(0, 0);
- gtk_widget_set_size_request(scrolled_window, 200, 100);
- gtk_container_add(GTK_CONTAINER(attachment_frame), scrolled_window);
- gtk_widget_show(scrolled_window);
-
- list = gtk_list_new();
-/* gtk_list_set_selection_mode(list, GTK_SELECTION_BROWSE); */
-
- gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(scrolled_window), list);
- gtk_widget_show(list);
- xsane.mail_list = list;
-
-
- /* button box, active when project exists */
- hbox = gtk_hbox_new(FALSE, 2);
- gtk_container_set_border_width(GTK_CONTAINER(hbox), 2);
- gtk_box_pack_start(GTK_BOX(mail_project_vbox), hbox, FALSE, FALSE, 2);
-
- button = gtk_button_new_with_label(BUTTON_IMAGE_SHOW);
- g_signal_connect(GTK_OBJECT(button), "clicked", (GtkSignalFunc) xsane_mail_show_callback, list);
- gtk_box_pack_start(GTK_BOX(hbox), button, TRUE, TRUE, 0);
- gtk_widget_show(button);
-
-#if 0
- /* before we enable the edit function we have to make sure that the rename function
- does also rename the image name of the opened viewer */
- button = gtk_button_new_with_label(BUTTON_IMAGE_EDIT);
- g_signal_connect(GTK_OBJECT(button), "clicked", (GtkSignalFunc) xsane_mail_edit_callback, list);
- gtk_box_pack_start(GTK_BOX(hbox), button, TRUE, TRUE, 0);
- gtk_widget_show(button);
-#endif
-
- button = gtk_button_new_with_label(BUTTON_IMAGE_RENAME);
- g_signal_connect(GTK_OBJECT(button), "clicked", (GtkSignalFunc) xsane_mail_entry_rename_callback, list);
- gtk_box_pack_start(GTK_BOX(hbox), button, TRUE, TRUE, 0);
- gtk_widget_show(button);
-
- button = gtk_button_new_with_label(BUTTON_IMAGE_DELETE);
- g_signal_connect(GTK_OBJECT(button), "clicked", (GtkSignalFunc) xsane_mail_entry_delete_callback, list);
- gtk_box_pack_start(GTK_BOX(hbox), button, TRUE, TRUE, 0);
- gtk_widget_show(button);
-
- xsane_button_new_with_pixmap(mail_dialog->window, hbox, move_up_xpm, 0, (GtkSignalFunc) xsane_mail_entry_move_up_callback, list);
- xsane_button_new_with_pixmap(mail_dialog->window, hbox, move_down_xpm, 0, (GtkSignalFunc) xsane_mail_entry_move_down_callback, list);
-
- gtk_widget_show(hbox);
-
- xsane.mail_project_box = mail_project_vbox;
-
- xsane_separator_new(mail_scan_vbox, 2);
-
-
- /* set the main hbox */
- hbox = gtk_hbox_new(FALSE, 0);
- xsane_separator_new(mail_project_vbox, 2);
- gtk_box_pack_end(GTK_BOX(mail_scan_vbox), hbox, FALSE, FALSE, 5);
- gtk_container_set_border_width(GTK_CONTAINER(hbox), 5);
- gtk_widget_show(hbox);
-
-
- mail_project_exists_hbox = gtk_hbox_new(FALSE, 2);
- gtk_box_pack_start(GTK_BOX(hbox), mail_project_exists_hbox, TRUE, TRUE, 0);
-
- button = gtk_button_new_with_label(BUTTON_SEND_PROJECT);
- g_signal_connect(GTK_OBJECT(button), "clicked", (GtkSignalFunc) xsane_mail_send, NULL);
- gtk_box_pack_start(GTK_BOX(mail_project_exists_hbox), button, TRUE, TRUE, 0);
- gtk_widget_show(button);
-
- button = gtk_button_new_with_label(BUTTON_DELETE_PROJECT);
- g_signal_connect(GTK_OBJECT(button), "clicked", (GtkSignalFunc) xsane_mail_project_delete, NULL);
- gtk_box_pack_start(GTK_BOX(mail_project_exists_hbox), button, TRUE, TRUE, 0);
- gtk_widget_show(button);
-
- gtk_widget_show(mail_project_exists_hbox);
- xsane.mail_project_exists = mail_project_exists_hbox;
-
- button = gtk_button_new_with_label(BUTTON_CREATE_PROJECT);
- g_signal_connect(GTK_OBJECT(button), "clicked", (GtkSignalFunc) xsane_mail_project_create, NULL);
- gtk_box_pack_start(GTK_BOX(hbox), button, TRUE, TRUE, 0);
- xsane.mail_project_not_exists = button;
-
- /* progress bar */
- xsane.mail_progress_bar = (GtkProgressBar *) gtk_progress_bar_new();
- gtk_box_pack_start(GTK_BOX(mail_scan_vbox), (GtkWidget *) xsane.mail_progress_bar, FALSE, FALSE, 0);
- gtk_progress_set_show_text(GTK_PROGRESS(xsane.mail_progress_bar), TRUE);
- gtk_progress_set_format_string(GTK_PROGRESS(xsane.mail_progress_bar), "");
- gtk_widget_show(GTK_WIDGET(xsane.mail_progress_bar));
-
-
- xsane.mail_dialog = mail_dialog;
-
- xsane_mail_project_load();
-
- gtk_widget_show(mail_dialog);
-}
-
-/* ---------------------------------------------------------------------------------------------------------------------- */
-
-static void xsane_mail_dialog_close()
-{
- DBG(DBG_proc, "xsane_mail_dialog_close\n");
-
- if (xsane.mail_dialog == NULL)
- {
- return;
- }
-
- gtk_widget_destroy(xsane.mail_dialog);
-
- xsane.mail_dialog = NULL;
- xsane.mail_list = NULL;
- xsane.mail_progress_bar = NULL;
-}
-
-/* ---------------------------------------------------------------------------------------------------------------------- */
-
-static void xsane_mail_project_set_sensitive(int sensitive)
-{
- gtk_widget_set_sensitive(xsane.mail_project_box, sensitive);
- gtk_widget_set_sensitive(xsane.mail_project_exists, sensitive);
-}
-
-/* ---------------------------------------------------------------------------------------------------------------------- */
-
-static void xsane_mail_project_display_status()
-{
- FILE *lockfile;
- char buf[256];
- char filename[PATH_MAX];
- int val;
- int i, c;
-
- DBG(DBG_proc, "xsane_mail_project_display_status\n");
-
- snprintf(filename, sizeof(filename), "%s/lockfile", preferences.mail_project);
- lockfile = fopen(filename, "rb"); /* read binary (b for win32) */
-
- if (lockfile)
- {
- i=0;
- c=0;
- while ((i<255) && (c != 10) && (c != EOF)) /* first line is mail status */
- {
- c = fgetc(lockfile);
- buf[i++] = c;
- }
- buf[i-1] = 0;
-
- fscanf(lockfile, "%d\n", &val);
-
- fclose(lockfile);
-
- if ( (!strcmp(buf, TEXT_MAIL_STATUS_SENDING)) ||
- (!strcmp(buf, TEXT_MAIL_STATUS_SENT)) ||
- (!strcmp(buf, TEXT_MAIL_STATUS_ERR_READ_PROJECT)) ||
- (!strcmp(buf, TEXT_MAIL_STATUS_POP3_CONNECTION_FAILED)) ||
- (!strcmp(buf, TEXT_MAIL_STATUS_POP3_LOGIN_FAILED)) ||
- (!strcmp(buf, TEXT_MAIL_STATUS_SMTP_CONNECTION_FAILED)) ||
- (!strcmp(buf, TEXT_MAIL_STATUS_SMTP_ERR_FROM)) ||
- (!strcmp(buf, TEXT_MAIL_STATUS_SMTP_ERR_RCPT)) ||
- (!strcmp(buf, TEXT_MAIL_STATUS_SMTP_ERR_DATA)) ||
- (!strcmp(buf, TEXT_MAIL_STATUS_SENT)) )
- {
- if (strcmp(xsane.mail_status, buf))
- {
- if (xsane.mail_status)
- {
- free(xsane.mail_status);
- }
- xsane.mail_status = strdup(buf);
-
- if (xsane.mail_progress_bar)
- {
- gtk_progress_set_format_string(GTK_PROGRESS(xsane.mail_progress_bar), _(xsane.mail_status));
- }
- }
-
- xsane.mail_progress_val = val / 100.0;
- if (xsane.mail_progress_bar)
- {
- gtk_progress_bar_update(GTK_PROGRESS_BAR(xsane.mail_progress_bar), xsane.mail_progress_val);
- }
-
- DBG(DBG_info, "reading from lockfile: mail_status %s, mail_progress_val %1.3f\n" , xsane.mail_status, xsane.mail_progress_val);
-
- if (strcmp(xsane.mail_status, TEXT_MAIL_STATUS_SENDING)) /* not sending */
- {
- DBG(DBG_info, "removing %s\n", filename);
- remove(filename); /* remove lockfile */
-
- xsane.mail_progress_val = 0.0;
-
- xsane_mail_project_update_project_status();
-
- if (xsane.mail_dialog)
- {
- xsane_mail_project_load();
-
- xsane_mail_project_set_sensitive(TRUE);
- gtk_widget_set_sensitive(GTK_WIDGET(xsane.start_button), TRUE);
- }
- }
- }
- }
- else
- {
- DBG(DBG_info, "no lockfile present\n");
- if (xsane.mail_progress_bar)
- {
- gtk_progress_set_format_string(GTK_PROGRESS(xsane.mail_progress_bar), _(xsane.mail_status));
- gtk_progress_bar_update(GTK_PROGRESS_BAR(xsane.mail_progress_bar), xsane.mail_progress_val);
- }
-
- while (gtk_events_pending())
- {
- gtk_main_iteration();
- }
- }
-}
-
-/* ---------------------------------------------------------------------------------------------------------------------- */
-
-static gint xsane_mail_send_timer_callback(gpointer data)
-{
- xsane_mail_project_display_status();
-
- if (strcmp(xsane.mail_status, TEXT_MAIL_STATUS_SENDING)) /* not sending */
- {
- if (xsane_mail_send_timer)
- {
- DBG(DBG_info, "disabling mail send timer\n");
- xsane_mail_send_timer = 0;
- }
- }
-
- return xsane_mail_send_timer;
-}
-
-/* ---------------------------------------------------------------------------------------------------------------------- */
-
-static void xsane_mail_project_load()
-{
- FILE *projectfile;
- char page[256];
- char *type;
- char *extension;
- char buf[256];
- char filename[PATH_MAX];
- GtkWidget *list_item;
- int i;
- int c;
-
- DBG(DBG_proc, "xsane_mail_project_load\n");
-
- if (xsane.mail_status)
- {
- free(xsane.mail_status);
- xsane.mail_status = NULL;
- }
-
- if (xsane.mail_receiver)
- {
- free(xsane.mail_receiver);
- xsane.mail_receiver = NULL;
- }
-
- if (xsane.mail_filename)
- {
- free(xsane.mail_filename);
- xsane.mail_filename = NULL;
- }
-
- if (xsane.mail_subject)
- {
- free(xsane.mail_subject);
- xsane.mail_subject = NULL;
- }
-
- g_signal_handlers_disconnect_by_func(GTK_OBJECT(xsane.mail_receiver_entry), GTK_SIGNAL_FUNC(xsane_mail_receiver_changed_callback), 0);
- g_signal_handlers_disconnect_by_func(GTK_OBJECT(xsane.mail_subject_entry), GTK_SIGNAL_FUNC(xsane_mail_subject_changed_callback), 0);
- g_signal_handlers_disconnect_by_func(GTK_OBJECT(xsane.mail_html_mode_widget), GTK_SIGNAL_FUNC(xsane_mail_html_mode_callback), 0);
-
-#ifdef HAVE_GTK_TEXT_VIEW_H
- gtk_text_buffer_set_text(GTK_TEXT_BUFFER(xsane.mail_text_widget), "", 0);
-#else
- gtk_text_set_point(GTK_TEXT(xsane.mail_text_widget), 0);
- gtk_text_forward_delete(GTK_TEXT(xsane.mail_text_widget), gtk_text_get_length(GTK_TEXT(xsane.mail_text_widget)));
-#endif
- gtk_list_remove_items(GTK_LIST(xsane.mail_list), GTK_LIST(xsane.mail_list)->children);
-
- snprintf(filename, sizeof(filename), "%s/xsane-mail-list", preferences.mail_project);
- projectfile = fopen(filename, "rb"); /* read binary (b for win32) */
-
- if ((!projectfile) || (feof(projectfile)))
- {
- snprintf(filename, sizeof(filename), "%s/image-1.pnm", preferences.mail_project);
- xsane.mail_filename=strdup(filename);
- xsane_update_counter_in_filename(&xsane.mail_filename, FALSE, 0, preferences.filename_counter_len); /* correct counter len */
-
- xsane.mail_status=strdup(TEXT_MAIL_STATUS_NOT_CREATED);
- xsane.mail_progress_val = 0.0;
-
- xsane.mail_receiver=strdup("");
- gtk_entry_set_text(GTK_ENTRY(xsane.mail_receiver_entry), (char *) xsane.mail_receiver);
-
- xsane.mail_subject=strdup("");
- gtk_entry_set_text(GTK_ENTRY(xsane.mail_subject_entry), (char *) xsane.mail_subject);
-
- gtk_widget_hide(xsane.mail_project_exists);
- gtk_widget_show(xsane.mail_project_not_exists);
-
- gtk_widget_set_sensitive(xsane.mail_project_box, FALSE);
- gtk_widget_set_sensitive(xsane.mail_project_exists, FALSE);
- /* do not change sensitivity of mail_project_entry_box here !!! */
- gtk_widget_set_sensitive(GTK_WIDGET(xsane.start_button), FALSE);
-
- xsane.mail_project_save = 0;
- }
- else
- {
- i=0;
- c=0;
- while ((i<255) && (c != 10) && (c != EOF)) /* first line is mail status */
- {
- c = fgetc(projectfile);
- page[i++] = c;
- }
- page[i-1] = 0;
- if (strchr(page, '@'))
- {
- *strchr(page, '@') = 0;
- }
-
- if (xsane.mail_status)
- {
- free(xsane.mail_status);
- }
- xsane.mail_status = strdup(page);
- xsane.mail_progress_val = 0.0;
-
-
- i=0;
- c=0;
- while ((i<255) && (c != 10) && (c != EOF)) /* second line is email address */
- {
- c = fgetc(projectfile);
- page[i++] = c;
- }
- page[i-1] = 0;
-
- xsane.mail_receiver=strdup(page);
- gtk_entry_set_text(GTK_ENTRY(xsane.mail_receiver_entry), (char *) xsane.mail_receiver);
-
-
- i=0;
- c=0;
- while ((i<255) && (c != 10) && (c != EOF)) /* third line is next mail filename */
- {
- c = fgetc(projectfile);
- page[i++] = c;
- }
- page[i-1] = 0;
-
- snprintf(filename, sizeof(filename), "%s/%s", preferences.mail_project, page);
- xsane.mail_filename=strdup(filename);
-
-
- i=0;
- c=0;
- while ((i<255) && (c != 10) && (c != EOF)) /* fourth line is subject */
- {
- c = fgetc(projectfile);
- page[i++] = c;
- }
- page[i-1] = 0;
-
- xsane.mail_subject=strdup(page);
- gtk_entry_set_text(GTK_ENTRY(xsane.mail_subject_entry), (char *) xsane.mail_subject);
-
-
- i=0;
- c=0;
- while ((i<255) && (c != 10) && (c != EOF)) /* fifth line is html/ascii */
- {
- c = fgetc(projectfile);
- page[i++] = c;
- }
- page[i-1] = 0;
-
- if (!strcasecmp("html", page))
- {
- xsane.mail_html_mode = 1;
- }
- else
- {
- xsane.mail_html_mode = 0;
- }
-
- gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(xsane.mail_html_mode_widget), xsane.mail_html_mode);
-
-
- while (!feof(projectfile))
- {
- i=0;
- c=0;
-
- while ((i<255) && (c != 10) && (c != EOF))
- {
- c = fgetc(projectfile);
- page[i++] = c;
- }
- page[i-1]=0;
-
- if (!strcmp("mailtext:", page))
- {
- break; /* mailtext follows */
- }
-
- extension = strrchr(page, '.');
- if (extension)
- {
- type = strdup(extension);
- *extension = 0;
- }
- else
- {
- type = strdup("");
- }
-
- if (c > 1)
- {
- list_item = gtk_list_item_new_with_label(page);
- gtk_object_set_data(GTK_OBJECT(list_item), "list_item_data", strdup(page));
- gtk_object_set_data(GTK_OBJECT(list_item), "list_item_type", strdup(type));
- gtk_container_add(GTK_CONTAINER(xsane.mail_list), list_item);
- gtk_widget_show(list_item);
- }
- }
-
- while (!feof(projectfile))
- {
- i = fread(buf, 1, sizeof(buf), projectfile);
-#ifdef HAVE_GTK_TEXT_VIEW_H
- gtk_text_buffer_insert_at_cursor(GTK_TEXT_BUFFER(xsane.mail_text_widget), buf, i);
-#else
- gtk_text_insert(GTK_TEXT(xsane.mail_text_widget), NULL, NULL, NULL, buf, i);
-#endif
- }
-
- if (!strcmp(xsane.mail_status, TEXT_MAIL_STATUS_SENDING)) /* mail project is locked (sending) */
- {
- xsane_mail_project_set_sensitive(FALSE);
- gtk_widget_set_sensitive(xsane.mail_project_entry_box, TRUE);
- gtk_widget_set_sensitive(GTK_WIDGET(xsane.start_button), FALSE);
-
- if (xsane_mail_send_timer == 0)
- {
- xsane_mail_send_timer = gtk_timeout_add(100, (GtkFunction) xsane_mail_send_timer_callback, NULL);
- DBG(DBG_info, "enabling mail send timer (%d)\n", xsane_mail_send_timer);
- }
- }
- else
- {
- xsane_mail_project_set_sensitive(TRUE);
- gtk_widget_set_sensitive(xsane.mail_project_entry_box, TRUE);
- gtk_widget_set_sensitive(GTK_WIDGET(xsane.start_button), TRUE);
- }
-
- gtk_widget_show(xsane.mail_project_exists);
- gtk_widget_hide(xsane.mail_project_not_exists);
-
- xsane.mail_project_save = 1;
- }
-
- if (projectfile)
- {
- fclose(projectfile);
- }
-
- gtk_progress_set_format_string(GTK_PROGRESS(xsane.mail_progress_bar), _(xsane.mail_status));
- gtk_progress_bar_update(GTK_PROGRESS_BAR(xsane.mail_progress_bar), xsane.mail_progress_val);
-
- xsane_mail_project_display_status();
-
- g_signal_connect(GTK_OBJECT(xsane.mail_html_mode_widget), "clicked", (GtkSignalFunc) xsane_mail_html_mode_callback, NULL);
- g_signal_connect(GTK_OBJECT(xsane.mail_receiver_entry), "changed", (GtkSignalFunc) xsane_mail_receiver_changed_callback, NULL);
- g_signal_connect(GTK_OBJECT(xsane.mail_subject_entry), "changed", (GtkSignalFunc) xsane_mail_subject_changed_callback, NULL);
-}
-
-/* ---------------------------------------------------------------------------------------------------------------------- */
-
-static void xsane_mail_project_delete()
-{
- char *page;
- char *type;
- char file[256];
- GList *list = (GList *) GTK_LIST(xsane.mail_list)->children;
- GtkObject *list_item;
-
- DBG(DBG_proc, "xsane_mail_project_delete\n");
-
- while (list)
- {
- list_item = GTK_OBJECT(list->data);
- page = strdup((char *) gtk_object_get_data(list_item, "list_item_data"));
- type = strdup((char *) gtk_object_get_data(list_item, "list_item_type"));
- xsane_convert_text_to_filename(&page);
- snprintf(file, sizeof(file), "%s/%s%s", preferences.mail_project, page, type);
- free(page);
- free(type);
- remove(file);
- list = list->next;
- }
- snprintf(file, sizeof(file), "%s/xsane-mail-list", preferences.mail_project);
- remove(file);
- snprintf(file, sizeof(file), "%s", preferences.mail_project);
- rmdir(file);
-
- xsane_mail_project_load();
-}
-
-/* ---------------------------------------------------------------------------------------------------------------------- */
-
-static void xsane_mail_project_update_project_status()
-{
- FILE *projectfile;
- char filename[PATH_MAX];
- char buf[256];
-
- snprintf(filename, sizeof(filename), "%s/xsane-mail-list", preferences.mail_project);
- projectfile = fopen(filename, "r+b"); /* r+ = read and write, position = start of file */
-
- snprintf(buf, 32, "%s@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@", xsane.mail_status); /* fill 32 characters status line */
- fprintf(projectfile, "%s\n", buf); /* first line is status of mail */
-
- fclose(projectfile);
-}
-
-/* ---------------------------------------------------------------------------------------------------------------------- */
-
-void xsane_mail_project_save()
-{
- FILE *projectfile;
- GList *list = (GList *) GTK_LIST(xsane.mail_list)->children;
- GtkObject *list_item;
- char *page;
- char *type;
- gchar *mail_text;
- char filename[256];
-
- DBG(DBG_proc, "xsane_mail_project_save\n");
-
- umask((mode_t) preferences.directory_umask); /* define new file permissions */
- mkdir(preferences.mail_project, 0777); /* make sure directory exists */
-
- snprintf(filename, sizeof(filename), "%s/xsane-mail-list", preferences.mail_project);
-
- if (xsane_create_secure_file(filename)) /* remove possibly existing symbolic links for security */
- {
- char buf[256];
-
- snprintf(buf, sizeof(buf), "%s %s %s\n", ERR_DURING_SAVE, ERR_CREATE_SECURE_FILE, filename);
- xsane_back_gtk_error(buf, TRUE);
- return; /* error */
- }
-
- projectfile = fopen(filename, "wb"); /* write binary (b for win32) */
-
- if (xsane.mail_status)
- {
- char buf[256];
-
- snprintf(buf, 32, "%s@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@", xsane.mail_status); /* fill 32 characters status line */
- fprintf(projectfile, "%s\n", buf); /* first line is status of mail */
- gtk_progress_set_format_string(GTK_PROGRESS(xsane.mail_progress_bar), _(xsane.mail_status));
- gtk_progress_bar_update(GTK_PROGRESS_BAR(xsane.mail_progress_bar), 0.0);
- }
- else
- {
- fprintf(projectfile, " \n"); /* no mail status */
- gtk_progress_set_format_string(GTK_PROGRESS(xsane.mail_progress_bar), "");
- gtk_progress_bar_update(GTK_PROGRESS_BAR(xsane.mail_progress_bar), 0.0);
- }
-
- if (xsane.mail_receiver)
- {
- fprintf(projectfile, "%s\n", xsane.mail_receiver); /* second line is receiver phone number or address */
- }
- else
- {
- fprintf(projectfile, "\n");
- }
-
- if (xsane.mail_filename)
- {
- fprintf(projectfile, "%s\n", strrchr(xsane.mail_filename, '/')+1); /* third line is next mail filename */
- }
- else
- {
- fprintf(projectfile, "\n");
- }
-
- if (xsane.mail_subject)
- {
- fprintf(projectfile, "%s\n", xsane.mail_subject); /* fourth line is subject */
- }
- else
- {
- fprintf(projectfile, "\n");
- }
-
- if (xsane.mail_html_mode) /* fith line is mode html/ascii */
- {
- fprintf(projectfile, "html\n");
- }
- else
- {
- fprintf(projectfile, "ascii\n");
- }
-
-
- while (list)
- {
- list_item = GTK_OBJECT(list->data);
- page = (char *) gtk_object_get_data(list_item, "list_item_data");
- type = (char *) gtk_object_get_data(list_item, "list_item_type");
- fprintf(projectfile, "%s%s\n", page, type);
- list = list->next;
- }
-
- /* save mail text */
- fprintf(projectfile, "mailtext:\n");
-#ifdef HAVE_GTK_TEXT_VIEW_H
- {
- GtkTextIter start, end;
-
- gtk_text_buffer_get_start_iter(GTK_TEXT_BUFFER(xsane.mail_text_widget), &start);
- gtk_text_buffer_get_end_iter(GTK_TEXT_BUFFER(xsane.mail_text_widget), &end);
- mail_text = gtk_text_buffer_get_text(GTK_TEXT_BUFFER(xsane.mail_text_widget), &start, &end, FALSE);
- }
-#else
- mail_text = gtk_editable_get_chars(GTK_EDITABLE(xsane.mail_text_widget), 0, -1);
-#endif
- fprintf(projectfile, "%s", mail_text);
-
- fclose(projectfile);
-}
-
-/* ---------------------------------------------------------------------------------------------------------------------- */
-
-static void xsane_mail_project_create()
-{
- DBG(DBG_proc, "xsane_mail_project_create\n");
-
- if (strlen(preferences.mail_project))
- {
- if (xsane.mail_status)
- {
- free(xsane.mail_status);
- }
- xsane.mail_status = strdup(TEXT_MAIL_STATUS_CREATED);
- xsane_mail_project_save();
- xsane_mail_project_load();
- }
-}
-
-/* ---------------------------------------------------------------------------------------------------------------------- */
-
-static void xsane_mail_receiver_changed_callback(GtkWidget *widget, gpointer data)
-{
- DBG(DBG_proc, "xsane_mail_receiver_changed_callback\n");
-
- if (xsane.mail_receiver)
- {
- free((void *) xsane.mail_receiver);
- }
- xsane.mail_receiver = strdup(gtk_entry_get_text(GTK_ENTRY(widget)));
-
- if (xsane.mail_status)
- {
- free(xsane.mail_status);
- }
- xsane.mail_status = strdup(TEXT_MAIL_STATUS_CHANGED);
- xsane.mail_project_save = 1;
- xsane_mail_project_display_status();
-}
-
-/* ---------------------------------------------------------------------------------------------------------------------- */
-
-static void xsane_mail_subject_changed_callback(GtkWidget *widget, gpointer data)
-{
- DBG(DBG_proc, "xsane_mail_subject_changed_callback\n");
-
- if (xsane.mail_subject)
- {
- free((void *) xsane.mail_subject);
- }
- xsane.mail_subject = strdup(gtk_entry_get_text(GTK_ENTRY(widget)));
-
- if (xsane.mail_status)
- {
- free(xsane.mail_status);
- }
- xsane.mail_status = strdup(TEXT_MAIL_STATUS_CHANGED);
- xsane.mail_project_save = 1;
- xsane_mail_project_display_status();
-}
-
-/* ---------------------------------------------------------------------------------------------------------------------- */
-
-static void xsane_mail_project_changed_callback(GtkWidget *widget, gpointer data)
-{
- DBG(DBG_proc, "xsane_mail_project_changed_callback\n");
-
- if (xsane.mail_project_save)
- {
- xsane.mail_project_save = 0;
- xsane_mail_project_save();
- }
-
- if (preferences.mail_project)
- {
- free((void *) preferences.mail_project);
- }
- preferences.mail_project = strdup(gtk_entry_get_text(GTK_ENTRY(widget)));
-
- xsane_mail_project_load();
-}
-
-/* ---------------------------------------------------------------------------------------------------------------------- */
-
-static void xsane_mail_html_mode_callback(GtkWidget * widget)
-{
- DBG(DBG_proc, "xsane_mail_html_mode_callback\n");
-
- xsane.mail_html_mode = (GTK_TOGGLE_BUTTON(widget)->active != 0);
-
- /* we can save it because this routine is only called when the project already exists */
- if (xsane.mail_status)
- {
- free(xsane.mail_status);
- }
- xsane.mail_status = strdup(TEXT_MAIL_STATUS_CHANGED);
- xsane.mail_project_save = 1;
- xsane_mail_project_display_status();
-}
-
-/* ---------------------------------------------------------------------------------------------------------------------- */
-
-static void xsane_mail_entry_move_up_callback(GtkWidget *widget, gpointer list)
-{
- GList *select;
- GList *item = GTK_LIST(list)->children;
- GtkWidget *list_item_1;
- GtkWidget *list_item_2;
- int position;
- int newpos;
-
- DBG(DBG_proc, "xsane_mail_entry_move_up\n");
-
- select = GTK_LIST(list)->selection;
- if (select)
- {
- list_item_1 = select->data;
-
- position = gtk_list_child_position(GTK_LIST(list), list_item_1);
- position--; /* move up */
- newpos = position;
-
- if (position >= 0)
- {
- while (position>0)
- {
- item = item->next;
- position--;
- }
-
- list_item_2 = item->data;
- if (list_item_2)
- {
- xsane_list_entrys_swap(list_item_1, list_item_2);
- gtk_list_select_item(GTK_LIST(list), newpos);
-
- if (xsane.mail_status)
- {
- free(xsane.mail_status);
- }
- xsane.mail_status = strdup(TEXT_MAIL_STATUS_CHANGED);
- xsane_mail_project_save();
- }
- }
- }
-}
-
-/* ---------------------------------------------------------------------------------------------------------------------- */
-
-static void xsane_mail_entry_move_down_callback(GtkWidget *widget, gpointer list)
-{
- GList *select;
- GList *item = GTK_LIST(list)->children;
- GtkWidget *list_item_1;
- GtkWidget *list_item_2;
- int position;
- int newpos;
-
- DBG(DBG_proc, "xsane_mail_entry_move_down\n");
-
- select = GTK_LIST(list)->selection;
- if (select)
- {
- list_item_1 = select->data;
-
- position = gtk_list_child_position(GTK_LIST(list), list_item_1);
- position++; /* move down */
- newpos = position;
-
- while ((position>0) && (item))
- {
- item = item->next;
- position--;
- }
-
- if (item)
- {
- list_item_2 = item->data;
- if (list_item_2)
- {
- xsane_list_entrys_swap(list_item_1, list_item_2);
- gtk_list_select_item(GTK_LIST(list), newpos);
-
- if (xsane.mail_status)
- {
- free(xsane.mail_status);
- }
- xsane.mail_status = strdup(TEXT_MAIL_STATUS_CHANGED);
- xsane_mail_project_save();
- }
- }
- }
-}
-
-/* ---------------------------------------------------------------------------------------------------------------------- */
-
-int xsane_mail_entry_rename;
-
-static void xsane_mail_entry_rename_button_callback(GtkWidget *widget, gpointer data)
-{
- DBG(DBG_proc, "xsane_mail_entry_rename\n");
-
- xsane_mail_entry_rename = (int) data;
-}
-
-/* ---------------------------------------------------------------------------------------------------------------------- */
-
-static void xsane_mail_entry_rename_callback(GtkWidget *widget, gpointer list)
-{
- GtkWidget *list_item;
- GList *select;
- char *oldpage;
- char *newpage;
- char *type;
- char oldfile[256];
- char newfile[256];
-
- DBG(DBG_proc, "xsane_mail_entry_rename_callback\n");
-
- select = GTK_LIST(list)->selection;
- if (select)
- {
- GtkWidget *rename_dialog;
- GtkWidget *text;
- GtkWidget *button;
- GtkWidget *vbox, *hbox;
- char filename[PATH_MAX];
-
- list_item = select->data;
- oldpage = strdup((char *) gtk_object_get_data(GTK_OBJECT(list_item), "list_item_data"));
- type = strdup((char *) gtk_object_get_data(GTK_OBJECT(list_item), "list_item_type"));
-
- xsane_set_sensitivity(FALSE);
-
- rename_dialog = gtk_window_new(GTK_WINDOW_TOPLEVEL);
- xsane_set_window_icon(rename_dialog, 0);
-
- /* set the main vbox */
- vbox = gtk_vbox_new(FALSE, 0);
- gtk_container_set_border_width(GTK_CONTAINER(vbox), 0);
- gtk_container_add(GTK_CONTAINER(rename_dialog), vbox);
- gtk_widget_show(vbox);
-
- /* set the main hbox */
- hbox = gtk_hbox_new(FALSE, 0);
- xsane_separator_new(vbox, 2);
- gtk_box_pack_end(GTK_BOX(vbox), hbox, FALSE, FALSE, 5);
- gtk_container_set_border_width(GTK_CONTAINER(hbox), 5);
- gtk_widget_show(hbox);
-
- gtk_window_set_position(GTK_WINDOW(rename_dialog), GTK_WIN_POS_CENTER);
- gtk_window_set_resizable(GTK_WINDOW(rename_dialog), FALSE);
- snprintf(filename, sizeof(filename), "%s %s", xsane.prog_name, WINDOW_MAIL_RENAME);
- gtk_window_set_title(GTK_WINDOW(rename_dialog), filename);
- g_signal_connect(GTK_OBJECT(rename_dialog), "delete_event", (GtkSignalFunc) xsane_mail_entry_rename_button_callback, (void *) -1);
- gtk_widget_show(rename_dialog);
-
- text = gtk_entry_new();
- xsane_back_gtk_set_tooltip(xsane.tooltips, text, DESC_MAILIMAGENAME);
- gtk_entry_set_max_length(GTK_ENTRY(text), 64);
- gtk_entry_set_text(GTK_ENTRY(text), oldpage);
- gtk_widget_set_size_request(text, 300, -1);
- gtk_box_pack_start(GTK_BOX(vbox), text, TRUE, TRUE, 4);
- gtk_widget_show(text);
-
-
-#ifdef HAVE_GTK2
- button = gtk_button_new_from_stock(GTK_STOCK_OK);
-#else
- button = gtk_button_new_with_label(BUTTON_OK);
-#endif
- g_signal_connect(GTK_OBJECT(button), "clicked", (GtkSignalFunc) xsane_mail_entry_rename_button_callback, (void *) 1);
- gtk_box_pack_start(GTK_BOX(hbox), button, TRUE, TRUE, 0);
- gtk_widget_show(button);
-
-#ifdef HAVE_GTK2
- button = gtk_button_new_from_stock(GTK_STOCK_CANCEL);
-#else
- button = gtk_button_new_with_label(BUTTON_CANCEL);
-#endif
- g_signal_connect(GTK_OBJECT(button), "clicked", (GtkSignalFunc) xsane_mail_entry_rename_button_callback,(void *) -1);
- gtk_box_pack_start(GTK_BOX(hbox), button, TRUE, TRUE, 0);
- gtk_widget_show(button);
-
-
- xsane_mail_entry_rename = 0;
-
- while (xsane_mail_entry_rename == 0)
- {
- while (gtk_events_pending())
- {
- gtk_main_iteration();
- }
- }
-
- newpage = strdup(gtk_entry_get_text(GTK_ENTRY(text)));
-
- if (xsane_mail_entry_rename == 1)
- {
- gtk_label_set(GTK_LABEL(gtk_container_children(GTK_CONTAINER(list_item))->data), newpage);
- gtk_object_set_data(GTK_OBJECT(list_item), "list_item_data", strdup(newpage));
-
- xsane_convert_text_to_filename(&oldpage);
- xsane_convert_text_to_filename(&newpage);
- snprintf(oldfile, sizeof(oldfile), "%s/%s%s", preferences.mail_project, oldpage, type);
- snprintf(newfile, sizeof(newfile), "%s/%s%s", preferences.mail_project, newpage, type);
-
- rename(oldfile, newfile);
-
- if (xsane.mail_status)
- {
- free(xsane.mail_status);
- }
- xsane.mail_status = strdup(TEXT_MAIL_STATUS_CHANGED);
- xsane_mail_project_save();
- }
-
- free(oldpage);
- free(newpage);
-
- gtk_widget_destroy(rename_dialog);
-
- xsane_set_sensitivity(TRUE);
- }
-}
-
-/* ---------------------------------------------------------------------------------------------------------------------- */
-
-static void xsane_mail_entry_delete_callback(GtkWidget *widget, gpointer list)
-{
- GtkObject *list_item;
- GList *select;
- char *page;
- char *type;
- char file[256];
-
- DBG(DBG_proc, "xsane_mail_entry_delete_callback\n");
-
- select = GTK_LIST(list)->selection;
- if (select)
- {
- list_item = GTK_OBJECT(select->data);
- page = strdup((char *) gtk_object_get_data(list_item, "list_item_data"));
- type = strdup((char *) gtk_object_get_data(list_item, "list_item_type"));
- xsane_convert_text_to_filename(&page);
- snprintf(file, sizeof(file), "%s/%s%s", preferences.mail_project, page, type);
- free(page);
- free(type);
- remove(file);
- gtk_widget_destroy(GTK_WIDGET(list_item));
-
- if (xsane.mail_status)
- {
- free(xsane.mail_status);
- }
- xsane.mail_status = strdup(TEXT_MAIL_STATUS_CHANGED);
- xsane_mail_project_save();
- }
-}
-
-/* ---------------------------------------------------------------------------------------------------------------------- */
-
-static void xsane_mail_show_callback(GtkWidget *widget, gpointer list)
-{
- GtkObject *list_item;
- GList *select;
- char *page;
- char *type;
- char filename[256];
-
- DBG(DBG_proc, "xsane_mail_entry_show_callback\n");
-
- select = GTK_LIST(list)->selection;
- if (select)
- {
- list_item = GTK_OBJECT(select->data);
- page = strdup((char *) gtk_object_get_data(list_item, "list_item_data"));
- type = strdup((char *) gtk_object_get_data(list_item, "list_item_type"));
- xsane_convert_text_to_filename(&page);
- snprintf(filename, sizeof(filename), "%s/%s%s", preferences.mail_project, page, type);
- free(page);
- free(type);
-
- xsane_viewer_new(filename, FALSE, filename, VIEWER_NO_MODIFICATION);
- }
-}
-
-/* ---------------------------------------------------------------------------------------------------------------------- */
-
-#if 0
-static void xsane_mail_edit_callback(GtkWidget *widget, gpointer list)
-{
- GtkObject *list_item;
- GList *select;
- char *page;
- char *type;
- char filename[256];
- FILE *outfile;
- FILE *infile;
- char outfilename[256];
- Image_info image_info;
- int cancel_save;
-
- DBG(DBG_proc, "xsane_mail_entry_show_callback\n");
-
- select = GTK_LIST(list)->selection;
- if (select)
- {
- list_item = GTK_OBJECT(select->data);
- page = strdup((char *) gtk_object_get_data(list_item, "list_item_data"));
- type = strdup((char *) gtk_object_get_data(list_item, "list_item_type"));
- xsane_convert_text_to_filename(&page);
- snprintf(filename, sizeof(filename), "%s/%s%s", preferences.mail_project, page, type);
- free(page);
- free(type);
-
-
- infile = fopen(filename, "rb");
- if (!infile)
- {
- DBG(DBG_error, "could not load file %s\n", filename);
- return;
- }
-
- xsane_read_pnm_header(infile, &image_info);
-
- DBG(DBG_info, "copying image %s with geometry: %d x %d x %d, %d colors\n", filename, image_info.image_width, image_info.image_height, image_info.depth, image_info.colors);
-
- xsane_back_gtk_make_path(sizeof(outfilename), outfilename, 0, 0, "xsane-viewer-", xsane.dev_name, ".pnm", XSANE_PATH_TMP);
-
- outfile = fopen(outfilename, "wb");
- if (!outfile)
- {
- DBG(DBG_error, "could not save file %s\n", outfilename);
- return;
- }
-
- gtk_progress_set_format_string(GTK_PROGRESS(xsane.mail_progress_bar), PROGRESS_CLONING_DATA);
- gtk_progress_bar_update(GTK_PROGRESS_BAR(xsane.mail_progress_bar), 0.0);
-
- xsane_save_rotate_image(outfile, infile, &image_info, 0, xsane.mail_progress_bar, &cancel_save);
-
- fclose(infile);
- fclose(outfile);
-
- gtk_progress_set_format_string(GTK_PROGRESS(xsane.mail_progress_bar), "");
- gtk_progress_bar_update(GTK_PROGRESS_BAR(xsane.mail_progress_bar), 0.0);
-
- xsane_viewer_new(outfilename, FALSE, filename, VIEWER_NO_NAME_MODIFICATION);
- }
-}
-#endif
-
-/* ---------------------------------------------------------------------------------------------------------------------- */
-
-static void xsane_create_mail(int fd)
-{
- FILE *attachment_file;
- FILE *projectfile;
- char *boundary="-----partseparator";
- char *image_filename;
- char *mail_text = NULL;
- char *mail_text_pos = NULL;
- char **attachment_filename = NULL;
- char *mime_type = NULL;
- char buf[256];
- char filename[256];
- char content_id[256];
- char image[256];
- int i, j;
- int c;
- int attachments = 0;
- int use_attachment = 0;
- int mail_text_size = 0;
- int display_images_inline = FALSE;
-
- DBG(DBG_proc, "xsane_create_mail\n");
-
- snprintf(filename, sizeof(filename), "%s/xsane-mail-list", preferences.mail_project);
- projectfile = fopen(filename, "rb"); /* read binary (b for win32) */
-
- if ((!projectfile) || (feof(projectfile)))
- {
- DBG(DBG_error, "could not open mail project file %s\n", filename);
-
- if (xsane.mail_status)
- {
- free(xsane.mail_status);
- }
- xsane.mail_status = strdup(TEXT_MAIL_STATUS_ERR_READ_PROJECT);
- xsane.mail_progress_val = 0.0;
- xsane_front_gtk_mail_project_update_lockfile_status();
-
- return;
- }
-
- for (i=0; i<5; i++) /* skip 5 lines */
- {
- j=0;
- c=0;
- while ((j<255) && (c != 10) && (c != EOF)) /* first line is mail status */
- {
- c = fgetc(projectfile);
- j++;
- }
- }
-
- if (!strcmp(preferences.mail_filetype, XSANE_FILETYPE_PNG))
- {
- mime_type = "image/png";
- display_images_inline = TRUE;
- }
- else if (!strcmp(preferences.mail_filetype, XSANE_FILETYPE_JPEG))
- {
- mime_type = "image/jpeg";
- display_images_inline = TRUE;
- }
- else if (!strcmp(preferences.mail_filetype, XSANE_FILETYPE_TIFF))
- {
- mime_type = "image/tiff";
- display_images_inline = TRUE;
- }
- else if (!strcmp(preferences.mail_filetype, XSANE_FILETYPE_PDF))
- {
- mime_type = "doc/pdf";
- display_images_inline = FALSE;
- }
- else if (!strcmp(preferences.mail_filetype, XSANE_FILETYPE_PS))
- {
- mime_type = "doc/postscript";
- display_images_inline = FALSE;
- }
- else
- {
- mime_type = "doc/unknown";
- display_images_inline = FALSE;
- }
-
- DBG(DBG_info, "reading list of attachments:\n");
- /* read list of attachments */
- while (!feof(projectfile))
- {
- /* read next attachment line */
- i=0;
- c=0;
- while ((i<255) && (c != 10) && (c != EOF))
- {
- c = fgetc(projectfile);
- image[i++] = c;
- }
- image[i-1]=0;
-
- if (strcmp("mailtext:", image) && (c > 1))
- {
- char imagename[256];
- char *filename;
- char *extension;
-
- DBG(DBG_info, " - %s\n", image);
-
- extension = strrchr(image, '.');
- if (extension)
- {
- *extension = 0;
- }
-
- snprintf(imagename, sizeof(imagename), "%s%s", image, preferences.mail_filetype);
- filename=strdup(imagename);
- xsane_convert_text_to_filename(&filename);
- attachment_filename = realloc(attachment_filename, (attachments+1)*sizeof(void *));
- attachment_filename[attachments++] = strdup(filename);
- free(filename);
- }
- else
- {
- break;
- }
- }
-
- /* read mail text */
- while (!feof(projectfile))
- {
- mail_text = realloc(mail_text, mail_text_size+1025); /* increase mail_text by 1KB */
- mail_text_size += fread(mail_text+mail_text_size, 1, 1024, projectfile); /* read next KB */
- }
- DBG(DBG_info, "%d bytes mailtext read\n", mail_text_size);
-
- *(mail_text + mail_text_size) = 0; /* set end of text marker */
- mail_text_pos = mail_text;
-
- if (xsane.mail_html_mode) /* create html mail */
- {
- DBG(DBG_info, "sending mail in html format\n");
-
- write_mail_header(fd, preferences.mail_from, preferences.mail_reply_to, xsane.mail_receiver, xsane.mail_subject, boundary, 1 /* related */);
- write_mail_mime_html(fd, boundary);
-
- DBG(DBG_info, "sending mail text\n");
- while (*mail_text_pos != 0)
- {
- if (!strncasecmp("<image>", mail_text_pos, 7)) /* insert image */
- {
- mail_text_pos += 6; /* <image> is 7 characters, 6 additional ones */
-
- if (use_attachment < attachments)
- {
- image_filename = attachment_filename[use_attachment++];
- DBG(DBG_info, "inserting image cid for %s\n", image_filename);
- snprintf(content_id, sizeof(content_id), "%s", image_filename); /* content_id */
-
- /* doc files like ps and pdf can not be displayed inline in html mail */
- if (display_images_inline)
- {
- snprintf(buf, sizeof(buf), "<p><img SRC=\"cid:%s\">\n", content_id);
- }
- write(fd, buf, strlen(buf));
- }
- else /* more images selected than available */
- {
- }
- }
- else if (*mail_text_pos == 10) /* new line */
- {
- snprintf(buf, sizeof(buf), "<br>\n");
- write(fd, buf, strlen(buf));
- }
- else
- {
- write(fd, mail_text_pos, 1);
- }
- mail_text_pos++;
- }
-
- while (use_attachment < attachments) /* append not already referenced images */
- {
- image_filename = attachment_filename[use_attachment++];
- DBG(DBG_info, "appending image cid for %s\n", image_filename);
- snprintf(content_id, sizeof(content_id), "%s", image_filename); /* content_id */
-
- /* doc files like ps and pdf can not be displayed inline in html mail */
- if (display_images_inline)
- {
- snprintf(buf, sizeof(buf), "<p><img SRC=\"cid:%s\">\n", content_id);
- }
- write(fd, buf, strlen(buf));
- }
-
- snprintf(buf, sizeof(buf), "</html>\n");
- write(fd, buf, strlen(buf));
-
-
- for (i=0; i<attachments; i++)
- {
- image_filename = attachment_filename[i];
- snprintf(content_id, sizeof(content_id), "%s", image_filename); /* content_id */
- snprintf(filename, sizeof(filename), "%s/mail-%s", preferences.mail_project, image_filename);
- attachment_file = fopen(filename, "rb"); /* read, b=binary for win32 */
-
- if (attachment_file)
- {
- DBG(DBG_info, "attaching file \"%s\" as \"%s\" with type %s\n", filename, image_filename, preferences.mail_filetype);
- write_mail_attach_image(fd, boundary, content_id, mime_type, attachment_file, image_filename);
-
- remove(filename);
- }
- else /* could not open attachment file */
- {
- DBG(DBG_error, "could not open attachment file \"%s\"\n", filename);
- }
-
- free(attachment_filename[i]);
- }
- free(attachment_filename);
-
- write_mail_footer(fd, boundary);
- }
- else /* ascii mail */
- {
- DBG(DBG_info, "sending mail in ascii format\n");
-
- write_mail_header(fd, preferences.mail_from, preferences.mail_reply_to, xsane.mail_receiver, xsane.mail_subject, boundary, 0 /* not related */);
- write_mail_mime_ascii(fd, boundary);
-
- write(fd, mail_text, strlen(mail_text));
- write(fd, "\n\n", 2);
-
- for (i=0; i<attachments; i++)
- {
- image_filename = strdup(attachment_filename[i]);
- snprintf(content_id, sizeof(content_id), "%s", image_filename); /* content_id */
- snprintf(filename, sizeof(filename), "%s/mail-%s", preferences.mail_project, image_filename);
- attachment_file = fopen(filename, "rb"); /* read, b=binary for win32 */
-
- if (attachment_file)
- {
- DBG(DBG_info, "attaching file \"%s\" as \"%s\" with type %s\n", filename, image_filename, preferences.mail_filetype);
- write_mail_attach_image(fd, boundary, content_id, mime_type, attachment_file, image_filename);
-
- remove(filename);
- }
- else /* could not open attachment file */
- {
- DBG(DBG_error, "could not oppen attachment png file \"%s\"\n", filename);
- }
-
- free(image_filename);
- free(attachment_filename[i]);
- }
- free(attachment_filename);
-
- write_mail_footer(fd, boundary);
- }
-
- free(mail_text);
-
- if (projectfile)
- {
- fclose(projectfile);
- }
-}
-
-/* ---------------------------------------------------------------------------------------------------------------------- */
-
-static void xsane_mail_send_process()
-{
- int fd_socket;
- int status;
-
- DBG(DBG_proc, "xsane_mail_send_process\n");
-
- /* pop3 authentification */
- if (preferences.mail_pop3_authentification)
- {
- char *password;
- int i;
-
- fd_socket = open_socket(preferences.mail_pop3_server, preferences.mail_pop3_port);
-
- if (fd_socket < 0) /* could not open socket */
- {
- if (xsane.mail_status)
- {
- free(xsane.mail_status);
- }
- xsane.mail_status = strdup(TEXT_MAIL_STATUS_POP3_CONNECTION_FAILED);
- xsane.mail_progress_val = 0.0;
- xsane_front_gtk_mail_project_update_lockfile_status();
-
- return;
- }
-
- password = strdup(preferences.mail_pop3_pass);
-
- for (i=0; i<strlen(password); i++)
- {
- password[i] ^= 0x53;
- }
-
- status = pop3_login(fd_socket, preferences.mail_pop3_user, password);
-
- free(password);
-
- close(fd_socket);
-
- if (status == -1)
- {
- if (xsane.mail_status)
- {
- free(xsane.mail_status);
- }
- xsane.mail_status = strdup(TEXT_MAIL_STATUS_POP3_LOGIN_FAILED);
- xsane.mail_progress_val = 0.0;
- xsane_front_gtk_mail_project_update_lockfile_status();
-
- return;
- }
- }
-
- DBG(DBG_info, "POP3 authentification done\n");
-
-
- /* smtp mail */
- fd_socket = open_socket(preferences.mail_smtp_server, preferences.mail_smtp_port);
-
- if (fd_socket < 0) /* could not open socket */
- {
- if (xsane.mail_status)
- {
- free(xsane.mail_status);
- }
- xsane.mail_status = strdup(TEXT_MAIL_STATUS_SMTP_CONNECTION_FAILED);
- xsane.mail_progress_val = 0.0;
- xsane_front_gtk_mail_project_update_lockfile_status();
-
- return;
- }
-
- status = write_smtp_header(fd_socket, preferences.mail_from, xsane.mail_receiver);
- if (status == -1)
- {
- return;
- }
-
- xsane_create_mail(fd_socket); /* create mail and write to socket */
-
- write_smtp_footer(fd_socket);
-
- close(fd_socket);
-
- if (xsane.mail_status)
- {
- free(xsane.mail_status);
- }
- xsane.mail_status = strdup(TEXT_MAIL_STATUS_SENT);
- xsane.mail_progress_val = 1.0;
- xsane_front_gtk_mail_project_update_lockfile_status();
- _exit(0);
-}
-
-/* ---------------------------------------------------------------------------------------------------------------------- */
-
-static void xsane_mail_send()
-{
- pid_t pid;
- char *image;
- char *type;
- GList *list = (GList *) GTK_LIST(xsane.mail_list)->children;
- GtkObject *list_item;
- char source_filename[PATH_MAX];
- char mail_filename[PATH_MAX];
- int output_format;
- int cancel_save = 0;
-
- DBG(DBG_proc, "xsane_mail_send\n");
-
- xsane_set_sensitivity(FALSE); /* do not allow changing xsane mode */
-
- while (gtk_events_pending())
- {
- DBG(DBG_info, "calling gtk_main_iteration\n");
- gtk_main_iteration();
- }
-
- if (xsane.mail_project_save)
- {
- xsane.mail_project_save = 0;
- xsane_mail_project_save();
- }
-
- xsane.mail_progress_size = 0;
- xsane.mail_progress_bytes = 0;
-
- while (list)
- {
- list_item = GTK_OBJECT(list->data);
- image = strdup((char *) gtk_object_get_data(list_item, "list_item_data"));
- type = strdup((char *) gtk_object_get_data(list_item, "list_item_type"));
- xsane_convert_text_to_filename(&image);
- snprintf(source_filename, sizeof(source_filename), "%s/%s%s", preferences.mail_project, image, type);
- snprintf(mail_filename, sizeof(mail_filename), "%s/mail-%s%s", preferences.mail_project, image, preferences.mail_filetype);
- free(image);
- free(type);
- DBG(DBG_info, "converting %s to %s\n", source_filename, mail_filename);
- output_format = xsane_identify_output_format(mail_filename, NULL, NULL);
- xsane_save_image_as(mail_filename, source_filename, output_format, xsane.mail_progress_bar, &cancel_save);
- list = list->next;
- xsane.mail_progress_size += xsane_get_filesize(mail_filename);
- }
-
-
- if (xsane.mail_status)
- {
- free(xsane.mail_status);
- }
- xsane.mail_status = strdup(TEXT_MAIL_STATUS_SENDING);
- xsane.mail_progress_val = 0.0;
- xsane_mail_project_display_status(); /* display status before creating lockfile! */
- xsane_front_gtk_mail_project_update_lockfile_status(); /* create lockfile and update status */
-
- pid = fork();
-
- if (pid == 0) /* new process */
- {
- FILE *ipc_file = NULL;
-
- if (xsane.ipc_pipefd[0])
- {
- close(xsane.ipc_pipefd[0]); /* close reading end of pipe */
- ipc_file = fdopen(xsane.ipc_pipefd[1], "w");
- }
-
- DBG(DBG_info, "trying to change user id for new subprocess:\n");
- DBG(DBG_info, "old effective uid = %d\n", (int) geteuid());
- setuid(getuid());
- DBG(DBG_info, "new effective uid = %d\n", (int) geteuid());
-
- xsane_mail_send_process();
-
- _exit(0); /* do not use exit() here! otherwise gtk gets in trouble */
- }
- else /* parent process */
- {
- xsane_add_process_to_list(pid); /* add pid to child process list */
- }
-
- xsane_mail_send_timer = gtk_timeout_add(100, (GtkFunction) xsane_mail_send_timer_callback, NULL);
- DBG(DBG_info, "enabling mail send timer (%d)\n", xsane_mail_send_timer);
-
- xsane_set_sensitivity(TRUE); /* allow changing xsane mode */
-#if 0
- gtk_widget_set_sensitive(xsane.mail_project_entry_box, TRUE);
- gtk_widget_set_sensitive(GTK_WIDGET(xsane.start_button), FALSE);
- gtk_widget_set_sensitive(xsane.mail_project_box, FALSE);
-#endif
- xsane_mail_project_set_sensitive(FALSE);
-}
-
-#endif
-/* ---------------------------------------------------------------------------------------------------------------------- */
-
static void xsane_pref_toggle_tooltips(GtkWidget *widget, gpointer data)
{
DBG(DBG_proc, "xsane_pref_toggle_tooltips\n");
@@ -6764,7 +3618,7 @@ static void xsane_show_doc_via_nsr(GtkWidget *widget, gpointer data) /* show via
}
else /* parent process */
{
- xsane_add_process_to_list(pid); /* add pid to child process list */
+ xsane_front_gtk_add_process_to_list(pid); /* add pid to child process list */
}
}
else /* netscape not running */
@@ -6806,7 +3660,7 @@ static void xsane_show_doc_via_nsr(GtkWidget *widget, gpointer data) /* show via
}
else /* parent process */
{
- xsane_add_process_to_list(pid); /* add pid to child process list */
+ xsane_front_gtk_add_process_to_list(pid); /* add pid to child process list */
}
}
@@ -6822,7 +3676,6 @@ static void xsane_show_doc_via_nsr(GtkWidget *widget, gpointer data) /* show via
static char **xsane_parse_command(char *command_line, char *url)
{
char **argv = NULL;
- //char *command = strdup(command_line);
char command[1024];
char *command_pos = command;
char *arg_end;
@@ -6929,7 +3782,7 @@ static void xsane_show_doc(GtkWidget *widget, gpointer data)
}
else /* parent process */
{
- xsane_add_process_to_list(pid); /* add pid to child process list */
+ xsane_front_gtk_add_process_to_list(pid); /* add pid to child process list */
}
}
}
@@ -6939,7 +3792,7 @@ static void xsane_show_doc(GtkWidget *widget, gpointer data)
static void xsane_scan_callback(void)
{
xsane.scan_rotation = xsane.preview->rotation;
- xsane_scan_dialog();
+ xsane_scan_dialog(NULL);
}
/* ---------------------------------------------------------------------------------------------------------------------- */
@@ -6976,6 +3829,7 @@ static GtkWidget *xsane_view_build_menu(void)
gtk_widget_add_accelerator(xsane.show_resolution_list_widget, "activate", xsane.accelerator_group, GDK_L, GDK_CONTROL_MASK, GTK_ACCEL_VISIBLE | DEF_GTK_ACCEL_LOCKED);
gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(xsane.show_resolution_list_widget), preferences.show_resolution_list);
gtk_menu_append(GTK_MENU(menu), xsane.show_resolution_list_widget);
+ gtk_widget_set_sensitive(xsane.show_resolution_list_widget, FALSE); /* we only make it active when we have a resolution range */
gtk_widget_show(xsane.show_resolution_list_widget);
g_signal_connect(GTK_OBJECT(xsane.show_resolution_list_widget), "toggled", (GtkSignalFunc) xsane_show_resolution_list_callback, NULL);
@@ -7858,10 +4712,10 @@ void xsane_panel_build()
/* connect to backend and create main dialogs:
- sane_open
- - create dialog xsane.shell
+ - create dialog xsane.dialog
- build menues
- - create dialog xsane.standard_options_shell
- - create dialog xsane.advanced_options_shell
+ - create dialog xsane.standard_options_dialog
+ - create dialog xsane.advanced_options_dialog
- create tooltip style
- create dialog xsane.histogram_dialog
- create dialog xsane.gamma_dialog
@@ -8007,23 +4861,23 @@ static void xsane_device_dialog(void)
/* create the xsane dialog box */
- xsane.shell = gtk_window_new(GTK_WINDOW_TOPLEVEL);
- gtk_window_move(GTK_WINDOW(xsane.shell), XSANE_SHELL_POS_X, XSANE_SHELL_POS_Y);
+ xsane.dialog = gtk_window_new(GTK_WINDOW_TOPLEVEL);
+ gtk_window_move(GTK_WINDOW(xsane.dialog), XSANE_DIALOG_POS_X, XSANE_DIALOG_POS_Y);
sprintf(windowname, "%s %s %s", xsane.prog_name, XSANE_VERSION, xsane.device_text);
- gtk_window_set_title(GTK_WINDOW(xsane.shell), (char *) windowname);
- g_signal_connect(GTK_OBJECT(xsane.shell), "delete_event", GTK_SIGNAL_FUNC(xsane_scan_win_delete), NULL);
+ gtk_window_set_title(GTK_WINDOW(xsane.dialog), (char *) windowname);
+ g_signal_connect(GTK_OBJECT(xsane.dialog), "delete_event", GTK_SIGNAL_FUNC(xsane_scan_win_delete), NULL);
- xsane_set_window_icon(xsane.shell, 0);
+ xsane_set_window_icon(xsane.dialog, 0);
/* create the xsane main window accelerator table */
xsane.accelerator_group = gtk_accel_group_new();
- gtk_window_add_accel_group(GTK_WINDOW(xsane.shell), xsane.accelerator_group);
+ gtk_window_add_accel_group(GTK_WINDOW(xsane.dialog), xsane.accelerator_group);
/* set the main vbox */
xsane_window = gtk_vbox_new(FALSE, 0);
gtk_container_set_border_width(GTK_CONTAINER(xsane_window), 0);
- gtk_container_add(GTK_CONTAINER(xsane.shell), xsane_window);
+ gtk_container_add(GTK_CONTAINER(xsane.dialog), xsane_window);
gtk_widget_show(xsane_window);
/* create the menubar */
@@ -8075,7 +4929,7 @@ static void xsane_device_dialog(void)
if (xsane.main_window_fixed) /* fixed window: use it like it is */
{
/* shrink grow auto_shrink */
- gtk_window_set_resizable(GTK_WINDOW(xsane.shell), FALSE);
+ gtk_window_set_resizable(GTK_WINDOW(xsane.dialog), FALSE);
xsane_vbox_main = gtk_vbox_new(TRUE, 5); /* we need this to set the wanted borders */
gtk_container_set_border_width(GTK_CONTAINER(xsane_vbox_main), 5);
@@ -8083,10 +4937,10 @@ static void xsane_device_dialog(void)
}
else /* scrolled window: create a scrolled window and put it into the xsane dialog box */
{
- gtk_window_set_default_size(GTK_WINDOW(xsane.shell), XSANE_SHELL_WIDTH, XSANE_SHELL_HEIGHT); /* set default size */
+ gtk_window_set_default_size(GTK_WINDOW(xsane.dialog), XSANE_DIALOG_WIDTH, XSANE_DIALOG_HEIGHT); /* set default size */
/* shrink grow auto_shrink */
- gtk_window_set_resizable(GTK_WINDOW(xsane.shell), TRUE); /* allow resizing */
+ gtk_window_set_resizable(GTK_WINDOW(xsane.dialog), TRUE); /* allow resizing */
xsane.main_dialog_scrolled = gtk_scrolled_window_new(0, 0);
gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(xsane.main_dialog_scrolled), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
@@ -8108,30 +4962,30 @@ static void xsane_device_dialog(void)
#if 0
/* add vendor`s logo */
- xsane_vendor_pixmap_new(xsane.shell->window, xsane_window);
+ xsane_vendor_pixmap_new(xsane.dialog->window, xsane_window);
#endif
/* create the scanner standard options dialog box */
- xsane.standard_options_shell = gtk_window_new(GTK_WINDOW_TOPLEVEL);
- gtk_window_move(GTK_WINDOW(xsane.standard_options_shell), XSANE_STD_OPTIONS_POS_X, XSANE_STD_OPTIONS_POS_Y);
+ xsane.standard_options_dialog = gtk_window_new(GTK_WINDOW_TOPLEVEL);
+ gtk_window_move(GTK_WINDOW(xsane.standard_options_dialog), XSANE_STD_OPTIONS_DIALOG_POS_X, XSANE_STD_OPTIONS_DIALOG_POS_Y);
sprintf(windowname, "%s %s", WINDOW_STANDARD_OPTIONS, xsane.device_text);
- gtk_window_set_title(GTK_WINDOW(xsane.standard_options_shell), (char *) windowname);
+ gtk_window_set_title(GTK_WINDOW(xsane.standard_options_dialog), (char *) windowname);
- gtk_window_set_resizable(GTK_WINDOW(xsane.standard_options_shell), FALSE);
- g_signal_connect(GTK_OBJECT(xsane.standard_options_shell), "delete_event", GTK_SIGNAL_FUNC(xsane_standard_option_win_delete), NULL);
+ gtk_window_set_resizable(GTK_WINDOW(xsane.standard_options_dialog), FALSE);
+ g_signal_connect(GTK_OBJECT(xsane.standard_options_dialog), "delete_event", GTK_SIGNAL_FUNC(xsane_standard_option_win_delete), NULL);
- xsane_set_window_icon(xsane.standard_options_shell, 0);
- gtk_window_add_accel_group(GTK_WINDOW(xsane.standard_options_shell), xsane.accelerator_group);
+ xsane_set_window_icon(xsane.standard_options_dialog, 0);
+ gtk_window_add_accel_group(GTK_WINDOW(xsane.standard_options_dialog), xsane.accelerator_group);
xsane_vbox_standard = gtk_vbox_new(FALSE, 5); /* has been TRUE before I added backend pixmap */
gtk_container_set_border_width(GTK_CONTAINER(xsane_vbox_standard), 5);
- gtk_container_add(GTK_CONTAINER(xsane.standard_options_shell), xsane_vbox_standard);
+ gtk_container_add(GTK_CONTAINER(xsane.standard_options_dialog), xsane_vbox_standard);
gtk_widget_show(xsane_vbox_standard);
/* add vendor`s logo */
- xsane_vendor_pixmap_new(xsane.standard_options_shell->window, xsane_vbox_standard);
+ xsane_vendor_pixmap_new(xsane.standard_options_dialog->window, xsane_vbox_standard);
/* create a subwindow so the standard dialog keeps its position on rebuilds: */
xsane.standard_window = gtk_hbox_new(/* homogeneous */ FALSE, 0);
@@ -8141,24 +4995,24 @@ static void xsane_device_dialog(void)
/* create the scanner advanced options dialog box */
- xsane.advanced_options_shell = gtk_window_new(GTK_WINDOW_TOPLEVEL);
- gtk_window_move(GTK_WINDOW(xsane.advanced_options_shell), XSANE_ADV_OPTIONS_POS_X, XSANE_ADV_OPTIONS_POS_Y);
+ xsane.advanced_options_dialog = gtk_window_new(GTK_WINDOW_TOPLEVEL);
+ gtk_window_move(GTK_WINDOW(xsane.advanced_options_dialog), XSANE_ADV_OPTIONS_DIALOG_POS_X, XSANE_ADV_OPTIONS_DIALOG_POS_Y);
sprintf(windowname, "%s %s",WINDOW_ADVANCED_OPTIONS, xsane.device_text);
- gtk_window_set_title(GTK_WINDOW(xsane.advanced_options_shell), (char *) windowname);
+ gtk_window_set_title(GTK_WINDOW(xsane.advanced_options_dialog), (char *) windowname);
- gtk_window_set_resizable(GTK_WINDOW(xsane.advanced_options_shell), FALSE);
- g_signal_connect(GTK_OBJECT(xsane.advanced_options_shell), "delete_event", GTK_SIGNAL_FUNC(xsane_advanced_option_win_delete), NULL);
+ gtk_window_set_resizable(GTK_WINDOW(xsane.advanced_options_dialog), FALSE);
+ g_signal_connect(GTK_OBJECT(xsane.advanced_options_dialog), "delete_event", GTK_SIGNAL_FUNC(xsane_advanced_option_win_delete), NULL);
- xsane_set_window_icon(xsane.advanced_options_shell, 0);
- gtk_window_add_accel_group(GTK_WINDOW(xsane.advanced_options_shell), xsane.accelerator_group);
+ xsane_set_window_icon(xsane.advanced_options_dialog, 0);
+ gtk_window_add_accel_group(GTK_WINDOW(xsane.advanced_options_dialog), xsane.accelerator_group);
xsane_vbox_advanced = gtk_vbox_new(FALSE, 5); /* has been TRUE before I added backend pixmap */
gtk_container_set_border_width(GTK_CONTAINER(xsane_vbox_advanced), 5);
- gtk_container_add(GTK_CONTAINER(xsane.advanced_options_shell), xsane_vbox_advanced);
+ gtk_container_add(GTK_CONTAINER(xsane.advanced_options_dialog), xsane_vbox_advanced);
gtk_widget_show(xsane_vbox_advanced);
/* add vendorīs logo */
- xsane_vendor_pixmap_new(xsane.advanced_options_shell->window, xsane_vbox_advanced);
+ xsane_vendor_pixmap_new(xsane.advanced_options_dialog->window, xsane_vbox_advanced);
/* create a subwindow so the advanced dialog keeps its position on rebuilds: */
xsane.advanced_window = gtk_hbox_new(/* homogeneous */ FALSE, 0);
@@ -8180,11 +5034,11 @@ static void xsane_device_dialog(void)
if (xsane.main_window_fixed)
{
- gtk_widget_realize(xsane.shell);
+ gtk_widget_realize(xsane.dialog);
}
else
{
- gtk_widget_show(xsane.shell);
+ gtk_widget_show(xsane.dialog);
/* the disadavantage of this is that the main window does
not have the focus when every window is shown */
}
@@ -8194,7 +5048,7 @@ static void xsane_device_dialog(void)
/* define tooltips colors */
xsane.tooltips = gtk_tooltips_new();
- colormap = gdk_drawable_get_colormap(xsane.shell->window);
+ colormap = gdk_drawable_get_colormap(xsane.dialog->window);
/* use black as foreground: */
xsane.tooltips_fg.red = 0;
@@ -8306,17 +5160,17 @@ static void xsane_device_dialog(void)
xsane_update_param(0);
xsane_update_gamma_curve(TRUE);
- gtk_widget_realize(xsane.standard_options_shell); /* is needed for saving window geometry */
- gtk_widget_realize(xsane.advanced_options_shell);
+ gtk_widget_realize(xsane.standard_options_dialog); /* is needed for saving window geometry */
+ gtk_widget_realize(xsane.advanced_options_dialog);
if (preferences.show_standard_options)
{
- gtk_widget_show(xsane.standard_options_shell);
+ gtk_widget_show(xsane.standard_options_dialog);
}
if (preferences.show_advanced_options)
{
- gtk_widget_show(xsane.advanced_options_shell);
+ gtk_widget_show(xsane.advanced_options_dialog);
}
if (preferences.show_batch_scan)
@@ -8324,7 +5178,7 @@ static void xsane_device_dialog(void)
gtk_widget_show(xsane.batch_scan_dialog);
}
- gtk_widget_show(xsane.shell); /* call as last so focus is on it */
+ gtk_widget_show(xsane.dialog); /* call as last so focus is on it */
while (gtk_events_pending())
{
@@ -8659,7 +5513,7 @@ static int xsane_init(int argc, char **argv)
{
int ch;
- while((ch = getopt_long(argc, argv, "cd:fghlmnpsvFN:RV", long_options, 0)) != EOF)
+ while((ch = getopt_long(argc, argv, "cd:efghlmnpsvFN:RV", long_options, 0)) != EOF)
{
switch(ch)
{
@@ -8675,7 +5529,7 @@ static int xsane_init(int argc, char **argv)
case 'v': /* --version */
g_print("%s-%s %s %s\n", xsane.prog_name, XSANE_VERSION, XSANE_COPYRIGHT_SIGN, XSANE_COPYRIGHT_TXT);
- g_print(" %s %s\n", TEXT_EMAIL, XSANE_EMAIL);
+ g_print(" %s %s\n", TEXT_EMAIL_ADR, XSANE_EMAIL_ADR);
g_print(" %s %s\n", TEXT_PACKAGE, XSANE_PACKAGE_VERSION);
g_print(" %s%d.%d.%d\n", TEXT_GTK_VERSION, GTK_MAJOR_VERSION, GTK_MINOR_VERSION, GTK_MICRO_VERSION);
@@ -8750,8 +5604,12 @@ static int xsane_init(int argc, char **argv)
xsane.xsane_mode = XSANE_FAX;
break;
- case 'm': /* --mail */
- xsane.xsane_mode = XSANE_MAIL;
+ case 'm': /* --multipage */
+ xsane.xsane_mode = XSANE_MULTIPAGE;
+ break;
+
+ case 'e': /* --email */
+ xsane.xsane_mode = XSANE_EMAIL;
break;
case 'n': /* --No-mode-selection */
@@ -9162,8 +6020,10 @@ int main(int argc, char **argv)
#endif
#ifdef HAVE_OS2_H
+# ifndef HAVE_GTK2
/* don`t know why, but os2 does need this one, a bit different to WIN32 */
set_gimp_PLUG_IN_INFO(&PLUG_IN_INFO);
+# endif
#endif
#ifdef HAVE_GIMP_2
diff --git a/src/xsane.h b/src/xsane.h
index 339cb49..abf8447 100644
--- a/src/xsane.h
+++ b/src/xsane.h
@@ -85,11 +85,11 @@
/* ---------------------------------------------------------------------------------------------------------------------- */
-#define XSANE_VERSION "0.98"
+#define XSANE_VERSION "0.99"
#define XSANE_AUTHOR "Oliver Rauch"
#define XSANE_COPYRIGHT "Oliver Rauch"
#define XSANE_DATE "1998-2005"
-#define XSANE_EMAIL "Oliver.Rauch@xsane.org"
+#define XSANE_EMAIL_ADR "Oliver.Rauch@xsane.org"
#define XSANE_HOMEPAGE "http://www.xsane.org"
#define XSANE_COPYRIGHT_TXT XSANE_DATE " " XSANE_COPYRIGHT
@@ -103,34 +103,46 @@
#define XSANE_DEFAULT_DEVICE "SANE_DEFAULT_DEVICE"
#define XSANE_3PASS_BUFFER_RGB_SIZE 1024
+#ifndef M_PI_2
+# define M_PI_2 1.57079632679489661923  /* pi/2 */
+#endif
+
#ifdef HAVE_WINDOWS_H
-# define BUGGY_GDK_INPUT_EXCEPTION
# define _WIN32
#endif
+#ifdef _WIN32
+# define BUGGY_GDK_INPUT_EXCEPTION
+#endif
+
+#ifdef HAVE_OS2_H
+# define BUGGY_GDK_INPUT_EXCEPTION
+# define strcasecmp stricmp
+#endif
+
#ifdef HAVE_LIBPNG
#ifdef HAVE_LIBZ
-# define XSANE_DEFAULT_MAILTYPE XSANE_FILETYPE_PNG
-# define XSANE_ACTIVATE_MAIL
+# define XSANE_DEFAULT_EMAIL_TYPE XSANE_FILETYPE_PNG
+# define XSANE_ACTIVATE_EMAIL
#endif
#endif
-#ifndef XSANE_DEFAULT_MAILTYPE
+#ifndef XSANE_DEFAULT_EMAIL_TYPE
#ifdef HAVE_LIBJPEG
-# define XSANE_DEFAULT_MAILTYPE XSANE_FILETYPE_JPEG
-# define XSANE_ACTIVATE_MAIL
+# define XSANE_DEFAULT_EMAIL_TYPE XSANE_FILETYPE_JPEG
+# define XSANE_ACTIVATE_EMAIL
#endif
#endif
-#ifndef XSANE_DEFAULT_MAILTYPE
+#ifndef XSANE_DEFAULT_EMAIL_TYPE
#ifdef HAVE_LIBTIFF
-# define XSANE_DEFAULT_MAILTYPE XSANE_FILETYPE_TIFF
-# define XSANE_ACTIVATE_MAIL
+# define XSANE_DEFAULT_EMAIL_TYPE XSANE_FILETYPE_TIFF
+# define XSANE_ACTIVATE_EMAIL
#endif
#endif
-#ifndef XSANE_DEFAULT_MAILTYPE
-# define XSANE_DEFAULT_MAILTYPE XSANE_FILETYPE_PNM
+#ifndef XSANE_DEFAULT_EMAIL_TYPE
+# define XSANE_DEFAULT_EMAIL_TYPE XSANE_FILETYPE_PNM
#endif
@@ -237,6 +249,11 @@
/* ---------------------------------------------------------------------------------------------------------------------- */
+#define IMAGE_SAVED TRUE
+#define IMAGE_NOT_SAVED FALSE
+
+/* ---------------------------------------------------------------------------------------------------------------------- */
+
#include "xsane-text.h"
#include "xsane-fixedtext.h"
#include "xsane-icons.h"
@@ -281,12 +298,6 @@
/* ---------------------------------------------------------------------------------------------------------------------- */
-#ifdef HAVE_OS2_H
-# define strcasecmp stricmp
-#endif
-
-/* ---------------------------------------------------------------------------------------------------------------------- */
-
enum
{
XSANE_PATH_LOCAL_SANE = 0,
@@ -432,15 +443,36 @@ Image_info;
/* ---------------------------------------------------------------------------------------------------------------------- */
-enum { XSANE_VIEWER, XSANE_SAVE, XSANE_COPY, XSANE_FAX, XSANE_MAIL };
-enum { XSANE_LINEART_STANDARD, XSANE_LINEART_XSANE, XSANE_LINEART_GRAYSCALE };
+enum
+{
+ XSANE_VIEWER,
+ XSANE_SAVE,
+ XSANE_COPY,
+ XSANE_MULTIPAGE,
+ XSANE_FAX,
+ XSANE_EMAIL
+};
+
+enum
+{
+ XSANE_LINEART_STANDARD,
+ XSANE_LINEART_XSANE,
+ XSANE_LINEART_GRAYSCALE
+};
+enum
+{
+ EMAIL_AUTH_NONE = 0,
+ EMAIL_AUTH_POP3,
+ EMAIL_AUTH_ASMTP_PLAIN,
+ EMAIL_AUTH_ASMTP_LOGIN,
+ EMAIL_AUTH_ASMTP_CRAM_MD5
+};
+
/* ---------------------------------------------------------------------------------------------------------------------- */
extern void xsane_pref_save(void);
extern void xsane_interface(int argc, char **argv);
-extern void xsane_fax_project_save(void);
-extern void xsane_mail_project_save(void);
extern void xsane_batch_scan_add(void);
/* ---------------------------------------------------------------------------------------------------------------------- */
@@ -464,10 +496,11 @@ extern void xsane_batch_scan_add(void);
#define FAXPOSTSCRIPTOPT ""
#define FAXNORMALOPT "-l"
#define FAXFINEOPT "-m"
+#define FAXVIEWER "ghostscript"
#define FAXCONVERTPSTOPNM "gs -dNOPAUSE -dBATCH -q -r204 -sDEVICE=pnm -sOutputFile="
-#define MAILPROJECT "mailproject"
-#define MAILCOMMAND "sendmail"
-#define MAILVIEWER "xv"
+#define EMAILPROJECT "emailproject"
+#define EMAILCOMMAND "sendmail"
+#define MULTIPAGEPROJECT "multipageproject"
#define OCRCOMMAND "gocr"
#define OCRINPUTFILEOPT "-i"
#define OCROUTPUTFILEOPT "-o"
@@ -489,26 +522,28 @@ extern void xsane_batch_scan_add(void);
#define XSANE_GAMMA_MIN 0.3
#define XSANE_GAMMA_MAX 3.0
-#define HIST_WIDTH 256
-#define HIST_HEIGHT 100
-#define XSANE_SHELL_WIDTH 296
-#define XSANE_SHELL_HEIGHT 451
-#define XSANE_SHELL_POS_X 1
-#define XSANE_SHELL_POS_Y 50
-#define XSANE_HISTOGRAM_POS_X 280
-#define XSANE_HISTOGRAM_POS_Y 50
-#define XSANE_GAMMA_POS_X 280
-#define XSANE_GAMMA_POS_Y 420
-#define XSANE_BATCH_POS_X 480
-#define XSANE_BATCH_POS_Y 420
-#define XSANE_STD_OPTIONS_POS_X 1
-#define XSANE_STD_OPTIONS_POS_Y 400
-#define XSANE_ADV_OPTIONS_POS_X 280
-#define XSANE_ADV_OPTIONS_POS_Y 420
-#define XSANE_PREVIEW_POS_X 560
-#define XSANE_PREVIEW_POS_Y 50
-#define XSANE_PREVIEW_WIDTH 100
-#define XSANE_PREVIEW_HEIGHT 100
+#define HIST_WIDTH 256
+#define HIST_HEIGHT 100
+#define XSANE_DIALOG_WIDTH 296
+#define XSANE_DIALOG_HEIGHT 451
+#define XSANE_DIALOG_POS_X 1
+#define XSANE_DIALOG_POS_Y 50
+#define XSANE_HISTOGRAM_DIALOG_POS_X 280
+#define XSANE_HISTOGRAM_DIALOG_POS_Y 50
+#define XSANE_PROJECT_DIALOG_POS_X 280
+#define XSANE_PROJECT_DIALOG_POS_Y 425
+#define XSANE_GAMMA_DIALOG_POS_X 280
+#define XSANE_GAMMA_DIALOG_POS_Y 420
+#define XSANE_BATCH_DIALOG_POS_X 480
+#define XSANE_BATCH_DIALOG_POS_Y 420
+#define XSANE_STD_OPTIONS_DIALOG_POS_X 1
+#define XSANE_STD_OPTIONS_DIALOG_POS_Y 400
+#define XSANE_ADV_OPTIONS_DIALOG_POS_X 280
+#define XSANE_ADV_OPTIONS_DIALOG_POS_Y 420
+#define XSANE_PREVIEW_DIALOG_POS_X 560
+#define XSANE_PREVIEW_DIALOG_POS_Y 50
+#define XSANE_PREVIEW_DIALOG_WIDTH 100
+#define XSANE_PREVIEW_DIALOG_HEIGHT 100
#define XSANE_SLIDER_ACTIVE 0
#define XSANE_SLIDER_INACTIVE 4
@@ -634,10 +669,10 @@ typedef struct Xsane
/* dialogs */
- GtkWidget *shell;
+ GtkWidget *dialog;
GtkWidget *menubar;
- GtkWidget *standard_options_shell;
- GtkWidget *advanced_options_shell;
+ GtkWidget *standard_options_dialog;
+ GtkWidget *advanced_options_dialog;
GtkWidget *main_dialog_scrolled;
GtkWidget *histogram_dialog;
GtkWidget *gamma_dialog;
@@ -648,28 +683,21 @@ typedef struct Xsane
GtkWidget *batch_scan_list;
GtkAdjustment *batch_scan_vadjustment;
- GtkWidget *fax_dialog;
- GtkWidget *fax_list;
- GtkWidget *fax_project_box;
- GtkWidget *fax_project_exists;
- GtkWidget *fax_project_not_exists;
- GtkWidget *fax_project_entry;
- GtkWidget *fax_project_entry_box;
+ GtkWidget *project_dialog;
+ GtkWidget *project_list;
+ GtkWidget *project_box;
+ GtkWidget *project_exists;
+ GtkWidget *project_not_exists;
+ GtkWidget *project_entry;
+ GtkWidget *project_entry_box;
+ GtkProgressBar *project_progress_bar;
+
GtkWidget *fax_receiver_entry;
- GtkProgressBar *fax_progress_bar;
-
- GtkWidget *mail_dialog;
- GtkWidget *mail_list;
- GtkWidget *mail_project_box;
- GtkWidget *mail_project_exists;
- GtkWidget *mail_project_not_exists;
- GtkWidget *mail_project_entry;
- GtkWidget *mail_project_entry_box;
- GtkWidget *mail_receiver_entry;
- GtkWidget *mail_subject_entry;
- GtkWidget *mail_text_widget;
- GtkWidget *mail_html_mode_widget;
- GtkProgressBar *mail_progress_bar;
+
+ GtkWidget *email_receiver_entry;
+ GtkWidget *email_subject_entry;
+ GtkWidget *email_text_widget;
+ GtkWidget *email_html_mode_widget;
GdkPixmap *window_icon_pixmap;
GdkBitmap *window_icon_mask;
@@ -807,10 +835,11 @@ typedef struct Xsane
SANE_Bool scanner_gamma_color;
SANE_Bool scanner_gamma_gray;
- int mail_project_save;
- int mail_html_mode;
+ int email_project_save;
+ int email_html_mode;
GtkWidget *outputfilename_entry;
+ GtkWidget *adf_pages_max_entry;
GtkWidget *copy_number_entry;
gfloat *free_gamma_data, *free_gamma_data_red, *free_gamma_data_green, *free_gamma_data_blue;
@@ -823,13 +852,16 @@ typedef struct Xsane
char *fax_filename;
char *fax_receiver;
- float mail_progress_val;
- int mail_progress_size;
- int mail_progress_bytes;
- char *mail_status;
- char *mail_filename;
- char *mail_receiver;
- char *mail_subject;
+ float email_progress_val;
+ int email_progress_size;
+ int email_progress_bytes;
+ char *email_status;
+ char *email_filename;
+ char *email_receiver;
+ char *email_subject;
+
+ char *multipage_status;
+ char *multipage_filename;
int block_update_param;
int block_enhancement_update;
@@ -847,14 +879,16 @@ typedef struct Xsane
rc_io-routintes that are based on double, int, ... */
/* window position and geometry */
- int shell_posx;
- int shell_posy;
- int shell_height;
- int shell_width;
- int standard_options_shell_posx;
- int standard_options_shell_posy;
- int advanced_options_shell_posx;
- int advanced_options_shell_posy;
+ int dialog_posx;
+ int dialog_posy;
+ int dialog_height;
+ int dialog_width;
+ int project_dialog_posx;
+ int project_dialog_posy;
+ int standard_options_dialog_posx;
+ int standard_options_dialog_posy;
+ int advanced_options_dialog_posx;
+ int advanced_options_dialog_posy;
int histogram_dialog_posx;
int histogram_dialog_posy;
int gamma_dialog_posx;
@@ -914,7 +948,6 @@ typedef struct Xsane
int print_filenames;
int force_filename;
char *external_filename;
- char *adf_scansource;
/* -------------------------------------------------- */
@@ -943,13 +976,17 @@ typedef struct XsaneSetup
GtkWidget *printer_gamma_blue_entry;
GtkWidget *printer_width_entry;
GtkWidget *printer_height_entry;
+ GtkWidget *printer_ps_flatdecoded_button;
GtkWidget *jpeg_image_quality_scale;
- GtkWidget *pnm_image_compression_scale;
+ GtkWidget *png_image_compression_scale;
+ GtkWidget *tiff_image_zip_compression_scale;
GtkWidget *save_devprefs_at_exit_button;
GtkWidget *overwrite_warning_button;
GtkWidget *increase_filename_counter_button;
GtkWidget *skip_existing_numbers_button;
+ GtkWidget *save_ps_flatdecoded_button;
+ GtkWidget *save_pdf_flatdecoded_button;
GtkWidget *save_pnm16_as_ascii_button;
GtkWidget *reduce_16bit_to_8bit_button;
@@ -983,18 +1020,19 @@ typedef struct XsaneSetup
GtkWidget *fax_leftoffset_entry;
GtkWidget *fax_bottomoffset_entry;
GtkWidget *fax_height_entry;
+ GtkWidget *fax_ps_flatdecoded_button;
+
GtkWidget *tmp_path_entry;
- GtkWidget *mail_smtp_server_entry;
- GtkWidget *mail_smtp_port_entry;
- GtkWidget *mail_from_entry;
- GtkWidget *mail_reply_to_entry;
- GtkWidget *mail_pop3_authentification_entry;
- GtkWidget *mail_pop3_server_entry;
- GtkWidget *mail_pop3_port_entry;
- GtkWidget *mail_pop3_user_entry;
- GtkWidget *mail_pop3_pass_entry;
- GtkWidget *mail_viewer_entry;
+ GtkWidget *email_smtp_server_entry;
+ GtkWidget *email_smtp_port_entry;
+ GtkWidget *email_from_entry;
+ GtkWidget *email_reply_to_entry;
+ GtkWidget *email_auth_user_entry;
+ GtkWidget *email_auth_pass_entry;
+ GtkWidget *email_pop3_server_entry;
+ GtkWidget *email_pop3_port_entry;
+ GtkWidget *pop3_vbox;
GtkWidget *ocr_command_entry;
GtkWidget *ocr_inputfile_option_entry;
@@ -1009,6 +1047,8 @@ typedef struct XsaneSetup
int tiff_compression8_nr;
int tiff_compression1_nr;
+ int email_authentication;
+
int show_range_mode;
int lineart_mode;