summaryrefslogtreecommitdiff
path: root/frontend/xsane.c
diff options
context:
space:
mode:
Diffstat (limited to 'frontend/xsane.c')
-rw-r--r--frontend/xsane.c4794
1 files changed, 4794 insertions, 0 deletions
diff --git a/frontend/xsane.c b/frontend/xsane.c
new file mode 100644
index 0000000..6302168
--- /dev/null
+++ b/frontend/xsane.c
@@ -0,0 +1,4794 @@
+/* xsane -- a graphical (X11, gtk) scanner-oriented SANE frontend
+
+ xsane.c
+
+ Oliver Rauch <Oliver.Rauch@Wolfsburg.DE>
+ Copyright (C) 1998-2000 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"
+
+#ifdef HAVE_LIBPNG
+#ifdef HAVE_LIBZ
+#include <png.h>
+#include <zlib.h>
+#endif
+#endif
+
+/* ---------------------------------------------------------------------------------------------------------------------- */
+
+struct option long_options[] =
+{
+ {"help", no_argument, 0, 'h'},
+ {"version", no_argument, 0, 'v'},
+ {"device-settings", required_argument, 0, 'd'},
+ {"scan", no_argument, 0, 's'},
+ {"copy", no_argument, 0, 'c'},
+ {"no-mode-selection", no_argument, 0, 'n'},
+ {"fax", no_argument, 0, 'f'},
+ {"Fixed", no_argument, 0, 'F'},
+ {"Resizeable", no_argument, 0, 'R'},
+ {0, }
+};
+
+/* ---------------------------------------------------------------------------------------------------------------------- */
+
+int xsane_back_gtk_message_dialog_active = 0;
+
+/* ---------------------------------------------------------------------------------------------------------------------- */
+
+const char *prog_name = 0;
+const char *device_text = 0;
+GtkWidget *choose_device_dialog = 0;
+GSGDialog *dialog = 0;
+const SANE_Device **devlist = 0;
+gint seldev = -1; /* The selected device */
+gint ndevs; /* The number of available devices */
+struct Xsane xsane;
+
+/* ---------------------------------------------------------------------------------------------------------------------- */
+
+int xsane_scanmode_number[] = { XSANE_SCAN, XSANE_COPY, XSANE_FAX };
+
+/* ---------------------------------------------------------------------------------------------------------------------- */
+
+#define XSANE_GTK_NAME_RESOLUTION "GtkMenuResolution"
+#define XSANE_GTK_NAME_X_RESOLUTION "GtkMenuXResolution"
+#define XSANE_GTK_NAME_Y_RESOLUTION "GtkMenuYResolution"
+
+#define XSANE_GTK_NAME_ZOOM "GtkMenuZoom"
+#define XSANE_GTK_NAME_X_ZOOM "GtkMenuXZoom"
+#define XSANE_GTK_NAME_Y_ZOOM "GtkMenuYZoom"
+
+/* ---------------------------------------------------------------------------------------------------------------------- */
+
+/* forward declarations: */
+
+static int xsane_option_defined(char *string);
+static int xsane_parse_options(char *options, char *argv[]);
+static void xsane_update_param(GSGDialog *dialog, void *arg);
+static void xsane_zoom_update(GtkAdjustment *adj_data, double *val);
+static void xsane_resolution_scale_update(GtkAdjustment *adj_data, double *val);
+static void xsane_gamma_changed(GtkAdjustment *adj_data, double *val);
+static void xsane_modus_callback(GtkWidget *xsane_parent, int *num);
+static void xsane_filetype_callback(GtkWidget *widget, gpointer data);
+static void xsane_outputfilename_changed_callback(GtkWidget *widget, gpointer data);
+static void xsane_browse_filename_callback(GtkWidget *widget, gpointer data);
+static void xsane_outputfilename_new(GtkWidget *vbox);
+static void xsane_faxreceiver_changed_callback(GtkWidget *widget, gpointer data);
+static void xsane_faxproject_changed_callback(GtkWidget *widget, gpointer data);
+static void xsane_fax_fine_mode_callback(GtkWidget * widget);
+static void xsane_enhancement_rgb_default_callback(GtkWidget * widget);
+static void xsane_enhancement_negative_callback(GtkWidget * widget);
+static void xsane_auto_enhancement_callback(GtkWidget * widget);
+static void xsane_show_standard_options_callback(GtkWidget * widget);
+static void xsane_show_advanced_options_callback(GtkWidget * widget);
+static void xsane_show_histogram_callback(GtkWidget * widget);
+static void xsane_printer_callback(GtkWidget *widget, gpointer data);
+static void xsane_update_preview(GSGDialog *dialog, void *arg);
+void xsane_pref_save(void);
+static void xsane_pref_restore(void);
+static void xsane_quit(void);
+static void xsane_exit(void);
+static gint xsane_standard_option_win_delete(GtkWidget *widget, gpointer data);
+static gint xsane_advanced_option_win_delete(GtkWidget *widget, gpointer data);
+static gint xsane_scan_win_delete(GtkWidget *w, gpointer data);
+static gint xsane_preview_window_destroyed(GtkWidget *widget, gpointer call_data);
+static void xsane_show_preview_callback(GtkWidget * widget, gpointer call_data);
+static GtkWidget *xsane_files_build_menu(void);
+static void xsane_set_pref_unit_callback(GtkWidget *widget, gpointer data);
+static void xsane_set_update_policy_callback(GtkWidget *widget, gpointer data);
+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 SANE_Status xsane_get_area_value(int option, float *val, SANE_Int *unit);
+#ifdef XSANE_TEST
+static void xsane_batch_scan_delete_callback(GtkWidget *widget, gpointer list);
+static void xsane_batch_scan_add_callback(GtkWidget *widget, gpointer list);
+static void xsane_batch_scan_dialog(GtkWidget *widget, gpointer data);
+#endif
+static void xsane_fax_dialog(void);
+static void xsane_fax_dialog_close(void);
+static void xsane_fax_project_delete(void);
+void xsane_fax_project_save(void);
+static void xsane_fax_project_load(void);
+static void xsane_fax_project_create(void);
+static void xsane_pref_toggle_tooltips(GtkWidget *widget, gpointer data);
+static void xsane_show_doc(GtkWidget *widget, gpointer data);
+static void xsane_fax_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_delete_callback(GtkWidget *widget, gpointer list);
+static void xsane_fax_show_callback(GtkWidget *widget, gpointer data);
+static void xsane_fax_send(void);
+static GtkWidget *xsane_view_build_menu(void);
+static GtkWidget *xsane_pref_build_menu(void);
+static GtkWidget *xsane_help_build_menu(void);
+static void xsane_device_dialog(void);
+static void xsane_choose_dialog_ok_callback(void);
+static void xsane_select_device_by_key_callback(GtkWidget * widget, gpointer data);
+static void xsane_select_device_by_mouse_callback(GtkWidget * widget, GdkEventButton *event, gpointer data);
+static gint32 xsane_choose_device(void);
+static void xsane_usage(void);
+static void xsane_init(int argc, char **argv);
+void xsane_interface(int argc, char **argv);
+int main(int argc, char ** argv);
+
+/* ---------------------------------------------------------------------------------------------------------------------- */
+
+static int xsane_option_defined(char *string)
+{
+ if (string)
+ {
+ while (*string == ' ') /* skip spaces */
+ {
+ string++;
+ }
+ if (*string != 0)
+ {
+ return 1;
+ }
+ }
+ return 0;
+}
+
+/* ---------------------------------------------------------------------------------------------------------------------- */
+
+static int xsane_parse_options(char *options, char *argv[])
+{
+ int optpos = 0;
+ int bufpos = 0;
+ int arg = 0;
+ char buf[256];
+
+ while (options[optpos] != 0)
+ {
+ switch(options[optpos])
+ {
+ case ' ':
+ buf[bufpos] = 0;
+ argv[arg++] = strdup(buf);
+ bufpos = 0;
+ optpos++;
+ break;
+
+ case '\"':
+ optpos++; /* skip " */
+ while ((options[optpos] != 0) && (options[optpos] != '\"'))
+ {
+ buf[bufpos++] = options[optpos++];
+ }
+ optpos++; /* skip " */
+ break;
+
+ default:
+ buf[bufpos++] = options[optpos++];
+ break;
+ }
+ }
+ buf[bufpos] = 0;
+ argv[arg++] = strdup(buf);
+ return arg;
+}
+
+/* ---------------------------------------------------------------------------------------------------------------------- */
+
+/* Update the info line with the latest size information and update histogram. */
+static void xsane_update_param(GSGDialog *dialog, void *arg)
+{
+ SANE_Parameters params;
+ gchar buf[200];
+
+ if (!xsane.info_label)
+ {
+ return;
+ }
+
+ if (xsane.block_update_param) /* if we change more than one value, we only want to update all once */
+ {
+ return;
+ }
+
+ if (sane_get_parameters(xsane_back_gtk_dialog_get_device(dialog), &params) == SANE_STATUS_GOOD)
+ {
+ float size = params.bytes_per_line * params.lines;
+ const char *unit = "B";
+
+ if (params.format >= SANE_FRAME_RED && params.format <= SANE_FRAME_BLUE)
+ {
+ size *= 3.0;
+ }
+
+ if (size >= 1024.0 * 1024.0)
+ {
+ size /= 1024.0 * 1024.0;
+ unit = "MB";
+ }
+ else if (size >= 1024.0)
+ {
+ size /= 1024.0;
+ unit = "KB";
+ }
+ snprintf(buf, sizeof(buf), "(%d x %d): %5.1f %s", params.pixels_per_line, params.lines, size, unit);
+
+ if (params.format == SANE_FRAME_GRAY)
+ {
+ xsane.xsane_color = 0;
+ }
+#ifdef SUPPORT_RGBA
+ else if (params.format == SANE_FRAME_RGBA)
+ {
+ xsane.xsane_color = 4;
+ }
+#endif
+ else /* RGB */
+ {
+ xsane.xsane_color = 3;
+ }
+ }
+ else
+ {
+ snprintf(buf, sizeof(buf), TEXT_INVALID_PARAMS);
+ }
+
+ gtk_label_set(GTK_LABEL(xsane.info_label), buf);
+
+
+ if (xsane.preview)
+ {
+ preview_update_surface(xsane.preview, 0);
+ }
+
+ xsane_update_histogram();
+}
+
+/* ---------------------------------------------------------------------------------------------------------------------- */
+
+static void xsane_gamma_changed(GtkAdjustment *adj_data, double *val)
+{
+ *val = adj_data->value;
+ xsane_enhancement_by_gamma();
+}
+
+/* ---------------------------------------------------------------------------------------------------------------------- */
+
+static void xsane_modus_callback(GtkWidget *xsane_parent, int *num)
+{
+
+ if (xsane.filetype) /* add extension to filename */
+ {
+ char buffer[256];
+
+ snprintf(buffer, sizeof(buffer), "%s%s", preferences.filename, xsane.filetype);
+ free(preferences.filename);
+ free(xsane.filetype);
+ xsane.filetype = 0;
+ preferences.filename = strdup(buffer);
+ }
+
+ xsane.xsane_mode = *num;
+ xsane_refresh_dialog(dialog);
+
+ if (xsane.xsane_mode != XSANE_FAX)
+ {
+ xsane_fax_dialog_close();
+ gtk_widget_set_sensitive(GTK_WIDGET(xsane.start_button), TRUE);
+ }
+
+ xsane_define_maximum_output_size();
+}
+
+/* ---------------------------------------------------------------------------------------------------------------------- */
+
+static void xsane_filetype_callback(GtkWidget *widget, gpointer data)
+{
+ if (data)
+ {
+ char *extension, *filename;
+
+ extension = strrchr(preferences.filename, '.');
+
+ if ((extension) && (extension != preferences.filename))
+ {
+ if ( (!strcasecmp(extension, ".pnm")) || (!strcasecmp(extension, ".raw"))
+ || (!strcasecmp(extension, ".png")) || (!strcasecmp(extension, ".ps"))
+ || (!strcasecmp(extension, ".rgba"))
+ || (!strcasecmp(extension, ".tiff")) || (!strcasecmp(extension, ".tif"))
+ || (!strcasecmp(extension, ".jpg")) || (!strcasecmp(extension, ".jpeg"))
+ ) /* remove filetype extension */
+ {
+ filename = preferences.filename;
+ *extension = 0; /* remove extension */
+ preferences.filename = strdup(filename); /* filename without extension */
+ free(filename); /* free unused memory */
+ }
+ }
+ }
+ else if (xsane.filetype)
+ {
+ char buffer[256];
+
+ snprintf(buffer, sizeof(buffer), "%s%s", preferences.filename, xsane.filetype);
+ free(preferences.filename);
+ free(xsane.filetype);
+ xsane.filetype = 0;
+ preferences.filename = strdup(buffer);
+ }
+
+ if (data)
+ {
+ xsane.filetype = strdup((char *) data); /* set extension for filename */
+ }
+
+ gtk_entry_set_text(GTK_ENTRY(xsane.outputfilename_entry), preferences.filename);
+}
+
+/* ---------------------------------------------------------------------------------------------------------------------- */
+
+static void xsane_outputfilename_changed_callback(GtkWidget *widget, gpointer data)
+{
+ if (preferences.filename)
+ {
+ free((void *) preferences.filename);
+ }
+ preferences.filename = strdup(gtk_entry_get_text(GTK_ENTRY(widget)));
+}
+
+/* ----------------------------------------------------------------------------------------------------------------- */
+
+static void xsane_browse_filename_callback(GtkWidget *widget, gpointer data)
+{
+ char filename[1024];
+ char windowname[256];
+
+ xsane_set_sensitivity(FALSE);
+
+ if (xsane.filetype) /* set filetype to "by ext." */
+ {
+ char buffer[256];
+
+ snprintf(buffer, sizeof(buffer), "%s%s", preferences.filename, xsane.filetype);
+ free(preferences.filename);
+ free(xsane.filetype);
+ xsane.filetype = 0;
+ preferences.filename = strdup(buffer);
+ }
+
+ if (preferences.filename) /* make sure a correct filename is defined */
+ {
+ strncpy(filename, preferences.filename, sizeof(filename));
+ filename[sizeof(filename) - 1] = '\0';
+ }
+ else /* no filename given, take standard filename */
+ {
+ strcpy(filename, OUTFILENAME);
+ }
+
+ snprintf(windowname, sizeof(windowname), "%s %s %s", prog_name, WINDOW_OUTPUT_FILENAME, device_text);
+
+ umask(preferences.directory_umask); /* define new file permissions */
+ xsane_back_gtk_get_filename(windowname, filename, sizeof(filename), filename, TRUE);
+ umask(XSANE_DEFAULT_UMASK); /* define new file permissions */
+
+ gtk_entry_set_text(GTK_ENTRY(xsane.outputfilename_entry), filename);
+
+ if (preferences.filename)
+ {
+ free((void *) preferences.filename);
+ }
+
+ xsane_set_sensitivity(TRUE);
+
+ preferences.filename = strdup(filename);
+
+ gtk_option_menu_set_history(GTK_OPTION_MENU(xsane.filetype_option_menu), 0); /* set menu to "by ext" */
+}
+
+/* ---------------------------------------------------------------------------------------------------------------------- */
+
+static void xsane_outputfilename_new(GtkWidget *vbox)
+{
+ GtkWidget *hbox;
+ GtkWidget *text;
+ GtkWidget *button;
+ GtkWidget *xsane_filetype_menu, *xsane_filetype_item;
+
+ 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);
+
+ button = xsane_button_new_with_pixmap(hbox, file_xpm, DESC_BROWSE_FILENAME, (GtkSignalFunc) xsane_browse_filename_callback, 0);
+
+ text = gtk_entry_new_with_max_length(255);
+ gtk_widget_set_usize(text, 80, 0); /* set minimum size */
+ xsane_back_gtk_set_tooltip(dialog->tooltips, text, DESC_FILENAME);
+ gtk_entry_set_text(GTK_ENTRY(text), (char *) preferences.filename);
+ gtk_box_pack_start(GTK_BOX(hbox), text, TRUE, TRUE, 4);
+ gtk_signal_connect(GTK_OBJECT(text), "changed", (GtkSignalFunc) xsane_outputfilename_changed_callback, 0);
+
+ xsane.outputfilename_entry = text;
+
+ xsane_filetype_menu = gtk_menu_new();
+
+ xsane_filetype_item = gtk_menu_item_new_with_label(MENU_ITEM_FILETYPE_BY_EXT);
+ gtk_container_add(GTK_CONTAINER(xsane_filetype_menu), xsane_filetype_item);
+ gtk_signal_connect(GTK_OBJECT(xsane_filetype_item), "activate",
+ (GtkSignalFunc) xsane_filetype_callback, NULL);
+ gtk_widget_show(xsane_filetype_item);
+
+#ifdef HAVE_LIBJPEG
+ xsane_filetype_item = gtk_menu_item_new_with_label(MENU_ITEM_FILETYPE_JPEG);
+ gtk_container_add(GTK_CONTAINER(xsane_filetype_menu), xsane_filetype_item);
+ gtk_signal_connect(GTK_OBJECT(xsane_filetype_item), "activate",
+ (GtkSignalFunc) xsane_filetype_callback, MENU_ITEM_FILETYPE_JPEG);
+ gtk_widget_show(xsane_filetype_item);
+#endif
+
+#ifdef HAVE_LIBPNG
+#ifdef HAVE_LIBZ
+ xsane_filetype_item = gtk_menu_item_new_with_label(MENU_ITEM_FILETYPE_PNG);
+ gtk_container_add(GTK_CONTAINER(xsane_filetype_menu), xsane_filetype_item);
+ gtk_signal_connect(GTK_OBJECT(xsane_filetype_item), "activate",
+ (GtkSignalFunc) xsane_filetype_callback, MENU_ITEM_FILETYPE_PNG);
+ gtk_widget_show(xsane_filetype_item);
+#endif
+#endif
+
+ xsane_filetype_item = gtk_menu_item_new_with_label(MENU_ITEM_FILETYPE_PNM);
+ gtk_container_add(GTK_CONTAINER(xsane_filetype_menu), xsane_filetype_item);
+ gtk_signal_connect(GTK_OBJECT(xsane_filetype_item), "activate",
+ (GtkSignalFunc) xsane_filetype_callback, MENU_ITEM_FILETYPE_PNM);
+ gtk_widget_show(xsane_filetype_item);
+
+ xsane_filetype_item = gtk_menu_item_new_with_label(MENU_ITEM_FILETYPE_PS);
+ gtk_container_add(GTK_CONTAINER(xsane_filetype_menu), xsane_filetype_item);
+ gtk_signal_connect(GTK_OBJECT(xsane_filetype_item), "activate",
+ (GtkSignalFunc) xsane_filetype_callback, MENU_ITEM_FILETYPE_PS);
+ gtk_widget_show(xsane_filetype_item);
+
+ xsane_filetype_item = gtk_menu_item_new_with_label(MENU_ITEM_FILETYPE_RAW);
+ gtk_container_add(GTK_CONTAINER(xsane_filetype_menu), xsane_filetype_item);
+ gtk_signal_connect(GTK_OBJECT(xsane_filetype_item), "activate",
+ (GtkSignalFunc) xsane_filetype_callback, MENU_ITEM_FILETYPE_RAW);
+ gtk_widget_show(xsane_filetype_item);
+
+#ifdef HAVE_LIBTIFF
+ xsane_filetype_item = gtk_menu_item_new_with_label(MENU_ITEM_FILETYPE_TIFF);
+ gtk_container_add(GTK_CONTAINER(xsane_filetype_menu), xsane_filetype_item);
+ gtk_signal_connect(GTK_OBJECT(xsane_filetype_item), "activate",
+ (GtkSignalFunc) xsane_filetype_callback, MENU_ITEM_FILETYPE_TIFF);
+ gtk_widget_show(xsane_filetype_item);
+#endif
+
+ xsane.filetype_option_menu = gtk_option_menu_new();
+ xsane_back_gtk_set_tooltip(dialog->tooltips, xsane.filetype_option_menu, DESC_FILETYPE);
+ gtk_box_pack_end(GTK_BOX(hbox), xsane.filetype_option_menu, FALSE, FALSE, 2);
+ gtk_option_menu_set_menu(GTK_OPTION_MENU(xsane.filetype_option_menu), xsane_filetype_menu);
+ gtk_option_menu_set_history(GTK_OPTION_MENU(xsane.filetype_option_menu), 0);
+ gtk_widget_show(xsane.filetype_option_menu);
+
+ gtk_widget_show(text);
+ gtk_widget_show(hbox);
+}
+
+/* ---------------------------------------------------------------------------------------------------------------------- */
+
+static void xsane_faxreceiver_changed_callback(GtkWidget *widget, gpointer data)
+{
+ if (xsane.fax_receiver)
+ {
+ free((void *) xsane.fax_receiver);
+ }
+ xsane.fax_receiver = strdup(gtk_entry_get_text(GTK_ENTRY(widget)));
+
+ xsane_fax_project_save();
+}
+
+/* ---------------------------------------------------------------------------------------------------------------------- */
+
+static void xsane_faxproject_changed_callback(GtkWidget *widget, gpointer data)
+{
+ 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)
+{
+ xsane.fax_fine_mode = (GTK_TOGGLE_BUTTON(widget)->active != 0);
+
+ if (xsane.fax_fine_mode)
+ {
+ xsane.resolution = 196;
+ xsane.resolution_x = 98;
+ xsane.resolution_y = 196;
+ }
+ else
+ {
+ xsane.resolution = 98;
+ xsane.resolution_x = 98;
+ xsane.resolution_y = 98;
+ }
+
+ xsane_set_all_resolutions();
+
+ xsane_update_param(dialog, 0);
+}
+
+/* ---------------------------------------------------------------------------------------------------------------------- */
+
+static void xsane_enhancement_rgb_default_callback(GtkWidget * widget)
+{
+ xsane.enhancement_rgb_default = (GTK_TOGGLE_BUTTON(widget)->active != 0);
+
+ if (xsane.enhancement_rgb_default)
+ {
+ xsane.gamma_red = 1.0;
+ xsane.gamma_green = 1.0;
+ xsane.gamma_blue = 1.0;
+
+ xsane.brightness_red = 0.0;
+ xsane.brightness_green = 0.0;
+ xsane.brightness_blue = 0.0;
+
+ xsane.contrast_red = 0.0;
+ xsane.contrast_green = 0.0;
+ xsane.contrast_blue = 0.0;
+
+ xsane.slider_red.value[0] = 0.0;
+ xsane.slider_red.value[1] = 50.0;
+ xsane.slider_red.value[2] = 100.0;
+
+ xsane.slider_green.value[0] = 0.0;
+ xsane.slider_green.value[1] = 50.0;
+ xsane.slider_green.value[2] = 100.0;
+
+ xsane.slider_blue.value[0] = 0.0;
+ xsane.slider_blue.value[1] = 50.0;
+ xsane.slider_blue.value[2] = 100.0;
+ }
+ else
+ {
+ xsane.slider_red.value[0] = xsane.slider_gray.value[0];
+ xsane.slider_red.value[1] = xsane.slider_gray.value[1];
+ xsane.slider_red.value[2] = xsane.slider_gray.value[2];
+
+ xsane.slider_green.value[0] = xsane.slider_gray.value[0];
+ xsane.slider_green.value[1] = xsane.slider_gray.value[1];
+ xsane.slider_green.value[2] = xsane.slider_gray.value[2];
+
+ xsane.slider_blue.value[0] = xsane.slider_gray.value[0];
+ xsane.slider_blue.value[1] = xsane.slider_gray.value[1];
+ xsane.slider_blue.value[2] = xsane.slider_gray.value[2];
+ }
+
+ xsane_update_sliders();
+ xsane_update_gamma();
+ xsane_refresh_dialog(dialog);
+}
+
+/* ---------------------------------------------------------------------------------------------------------------------- */
+
+static void xsane_enhancement_negative_callback(GtkWidget * widget)
+{
+ double v0;
+
+ if (xsane.negative != (GTK_TOGGLE_BUTTON(widget)->active != 0));
+ {
+ v0 = xsane.slider_gray.value[0];
+ xsane.slider_gray.value[0] = 100.0 - xsane.slider_gray.value[2];
+ xsane.slider_gray.value[1] = 100.0 - xsane.slider_gray.value[1];
+ xsane.slider_gray.value[2] = 100.0 - v0;
+
+ if (!xsane.enhancement_rgb_default)
+ {
+ v0 = xsane.slider_red.value[0];
+ xsane.slider_red.value[0] = 100.0 - xsane.slider_red.value[2];
+ xsane.slider_red.value[1] = 100.0 - xsane.slider_red.value[1];
+ xsane.slider_red.value[2] = 100.0 - v0;
+
+ v0 = xsane.slider_green.value[0];
+ xsane.slider_green.value[0] = 100.0 - xsane.slider_green.value[2];
+ xsane.slider_green.value[1] = 100.0 - xsane.slider_green.value[1];
+ xsane.slider_green.value[2] = 100.0 - v0;
+
+ v0 = xsane.slider_blue.value[0];
+ xsane.slider_blue.value[0] = 100.0 - xsane.slider_blue.value[2];
+ xsane.slider_blue.value[1] = 100.0 - xsane.slider_blue.value[1];
+ xsane.slider_blue.value[2] = 100.0 - v0;
+ }
+ }
+
+ xsane.negative = (GTK_TOGGLE_BUTTON(widget)->active != 0);
+
+ xsane_update_sliders();
+ xsane_enhancement_by_histogram();
+ xsane_update_gamma();
+}
+
+/* ---------------------------------------------------------------------------------------------------------------------- */
+
+static void xsane_auto_enhancement_callback(GtkWidget * widget)
+{
+ xsane_calculate_histogram();
+
+ xsane.slider_gray.value[0] = xsane.auto_black;
+ xsane.slider_gray.value[1] = xsane.auto_gray;
+ xsane.slider_gray.value[2] = xsane.auto_white;
+
+ if (xsane.enhancement_rgb_default) /* set same values for color components */
+ {
+ xsane.slider_red.value[0] = xsane.auto_black;
+ xsane.slider_red.value[1] = xsane.auto_gray;
+ xsane.slider_red.value[2] = xsane.auto_white;
+
+ xsane.slider_green.value[0] = xsane.auto_black;
+ xsane.slider_green.value[1] = xsane.auto_gray;
+ xsane.slider_green.value[2] = xsane.auto_white;
+
+ xsane.slider_blue.value[0] = xsane.auto_black;
+ xsane.slider_blue.value[1] = xsane.auto_gray;
+ xsane.slider_blue.value[2] = xsane.auto_white;
+ }
+ else /* set different values for each color component */
+ {
+ xsane.slider_red.value[0] = xsane.auto_black_red;
+ xsane.slider_red.value[1] = xsane.auto_gray_red;
+ xsane.slider_red.value[2] = xsane.auto_white_red;
+
+ xsane.slider_green.value[0] = xsane.auto_black_green;
+ xsane.slider_green.value[1] = xsane.auto_gray_green;
+ xsane.slider_green.value[2] = xsane.auto_white_green;
+
+ xsane.slider_blue.value[0] = xsane.auto_black_blue;
+ xsane.slider_blue.value[1] = xsane.auto_gray_blue;
+ xsane.slider_blue.value[2] = xsane.auto_white_blue;
+ }
+
+ xsane_enhancement_by_histogram();
+}
+
+/* ---------------------------------------------------------------------------------------------------------------------- */
+
+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);
+ }
+ else
+ {
+ gtk_widget_hide(xsane.standard_options_shell);
+ }
+}
+
+/* ---------------------------------------------------------------------------------------------------------------------- */
+
+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);
+ }
+ else
+ {
+ gtk_widget_hide(xsane.advanced_options_shell);
+ }
+}
+
+/* ---------------------------------------------------------------------------------------------------------------------- */
+
+static void xsane_show_resolution_list_callback(GtkWidget *widget)
+{
+ preferences.show_resolution_list = (GTK_CHECK_MENU_ITEM(widget)->active != 0);
+ xsane_refresh_dialog(0);
+}
+
+/* ---------------------------------------------------------------------------------------------------------------------- */
+
+static void xsane_page_rotate_callback(GtkWidget *widget)
+{
+ preferences.psrotate = (GTK_CHECK_MENU_ITEM(widget)->active != 0);
+ xsane_define_maximum_output_size();
+}
+
+/* ---------------------------------------------------------------------------------------------------------------------- */
+
+static void xsane_show_histogram_callback(GtkWidget * widget)
+{
+ preferences.show_histogram = (GTK_CHECK_MENU_ITEM(widget)->active != 0);
+ if (preferences.show_histogram)
+ {
+ xsane_update_histogram();
+ gtk_widget_show(xsane.histogram_dialog);
+ }
+ else
+ {
+ gtk_widget_hide(xsane.histogram_dialog);
+ }
+}
+
+/* ---------------------------------------------------------------------------------------------------------------------- */
+
+static void xsane_printer_callback(GtkWidget *widget, gpointer data)
+{
+ preferences.printernr = (int) data;
+ xsane_back_gtk_refresh_dialog(dialog);
+ xsane_define_maximum_output_size();
+}
+
+/* ---------------------------------------------------------------------------------------------------------------------- */
+
+static void xsane_resolution_scale_update(GtkAdjustment *adj_data, double *val)
+{
+#if 1
+/* gtk does not make sure that the value is quantisized correct */
+ float diff, old, new, quant;
+
+ quant = adj_data->step_increment;
+
+ if (quant != 0)
+ {
+ new = adj_data->value;
+ old = *val;
+ diff = quant*((int) ((new - old)/quant));
+
+ *val = old + diff;
+ adj_data->value = *val;
+ }
+#else
+ *val = adj_data->value;
+#endif
+
+ xsane_set_all_resolutions();
+
+ xsane_update_param(dialog, 0);
+ xsane.zoom = xsane.resolution / preferences.printer[preferences.printernr]->resolution;
+ xsane.zoom_x = xsane.resolution_x / preferences.printer[preferences.printernr]->resolution;
+ xsane.zoom_y = xsane.resolution_y / preferences.printer[preferences.printernr]->resolution;
+}
+
+/* ---------------------------------------------------------------------------------------------------------------------- */
+
+static void xsane_resolution_list_callback(GtkWidget *widget, gpointer data)
+{
+ GSGMenuItem *menu_item = data;
+ GSGDialogElement *elem = menu_item->elem;
+ GSGDialog *dialog = elem->dialog;
+ SANE_Word val;
+ gchar *name = gtk_widget_get_name(widget->parent);
+
+ sscanf(menu_item->label, "%d", &val);
+
+ if (!strcmp(name, XSANE_GTK_NAME_RESOLUTION))
+ {
+ xsane.resolution = val;
+ xsane.resolution_x = val;
+ xsane.resolution_y = val;
+
+ xsane_set_resolution(dialog->well_known.dpi, xsane.resolution);
+ xsane_set_resolution(dialog->well_known.dpi_x, xsane.resolution_x);
+ xsane_set_resolution(dialog->well_known.dpi_y, xsane.resolution_y);
+
+ xsane.zoom = xsane.resolution / preferences.printer[preferences.printernr]->resolution;
+ xsane.zoom_x = xsane.resolution_x / preferences.printer[preferences.printernr]->resolution;
+ xsane.zoom_y = xsane.resolution_y / preferences.printer[preferences.printernr]->resolution;
+ }
+ else if (!strcmp(name, XSANE_GTK_NAME_X_RESOLUTION))
+ {
+ xsane.resolution = val;
+ xsane.resolution_x = val;
+ xsane_set_resolution(dialog->well_known.dpi_x, xsane.resolution_x);
+ xsane.zoom = xsane.resolution / preferences.printer[preferences.printernr]->resolution;
+ }
+ else if (!strcmp(name, XSANE_GTK_NAME_Y_RESOLUTION))
+ {
+ xsane.resolution_y = val;
+ xsane_set_resolution(dialog->well_known.dpi_y, xsane.resolution_y);
+ xsane.zoom = xsane.resolution / preferences.printer[preferences.printernr]->resolution;
+ }
+
+ xsane_update_param(dialog, 0);
+}
+
+/* ---------------------------------------------------------------------------------------------------------------------- */
+
+static int xsane_resolution_widget_new(GtkWidget *parent, int well_known_option, double *resolution, const char *image_xpm[],
+ const gchar *desc, const gchar *widget_name)
+{
+ GtkObject *resolution_widget;
+ const SANE_Option_Descriptor *opt;
+
+ opt = sane_get_option_descriptor(dialog->dev, well_known_option);
+
+ if (!opt)
+ {
+ return -1; /* options does not exist */
+ }
+ else
+ {
+ if (SANE_OPTION_IS_ACTIVE(opt->cap))
+ {
+ switch (opt->constraint_type)
+ {
+ case SANE_CONSTRAINT_RANGE:
+ {
+ SANE_Word quant=0;
+ SANE_Word min=0;
+ SANE_Word max=0;
+ SANE_Word val=0;
+
+ gtk_widget_set_sensitive(xsane.show_resolution_list_widget, TRUE);
+ sane_control_option(dialog->dev, well_known_option, SANE_ACTION_GET_VALUE, &val, 0);
+
+ switch (opt->type)
+ {
+ case SANE_TYPE_INT:
+ min = opt->constraint.range->min;
+ max = opt->constraint.range->max;
+ quant = opt->constraint.range->quant;
+ break;
+
+ case SANE_TYPE_FIXED:
+ min = SANE_UNFIX(opt->constraint.range->min);
+ max = SANE_UNFIX(opt->constraint.range->max);
+ quant = SANE_UNFIX(opt->constraint.range->quant);
+ val = SANE_UNFIX(val);
+ break;
+
+ default:
+ fprintf(stderr, "zoom_scale_update: %s %d\n", ERR_UNKNOWN_TYPE, opt->type);
+ }
+
+ if (quant == 0)
+ {
+ quant = 1;
+ }
+
+ if (!(*resolution)) /* no prefered value */
+ {
+ *resolution = val; /* set backend predefined value */
+ }
+
+ if (!preferences.show_resolution_list) /* user wants slider */
+ {
+ xsane_scale_new_with_pixmap(GTK_BOX(parent), image_xpm, desc,
+ min, max, quant, quant, 0.0, 0, resolution, &resolution_widget,
+ well_known_option, xsane_resolution_scale_update, SANE_OPTION_IS_SETTABLE(opt->cap));
+ }
+ else /* user wants list instead of slider */
+ {
+ SANE_Int max_items = 20;
+ char **str_list;
+ char str[16];
+ int i;
+ int j = 0;
+ SANE_Word wanted_res;
+ SANE_Word val = max;
+ int res = max;
+ double mul;
+
+ sane_control_option(dialog->dev, well_known_option, SANE_ACTION_GET_VALUE, &wanted_res, 0);
+ if (opt->type == SANE_TYPE_FIXED)
+ {
+ wanted_res = (int) SANE_UNFIX(wanted_res);
+ }
+
+ if (*resolution) /* prefered value */
+ {
+ wanted_res = *resolution; /* set frontend prefered value */
+ }
+
+ str_list = malloc((max_items + 1) * sizeof(str_list[0]));
+
+ sprintf(str, "%d", max);
+ str_list[j++] = strdup(str);
+
+ i=9;
+ while ((j < max_items) && (res > 50) && (res > min) && (i > 0))
+ {
+ mul = ((double) i) / (i+1);
+ res = (int) (max * mul);
+ if (res/mul == max)
+ {
+ sprintf(str, "%d", res);
+ str_list[j++] = strdup(str);
+ if (res >= wanted_res)
+ {
+ val = res;
+ }
+ }
+ i--;
+ }
+
+ i = 3;
+ while ((j < max_items) && (res > 50) && (res > min))
+ {
+ mul = 1.0/i;
+ res = max * mul;
+ if (res/mul == max)
+ {
+ sprintf(str, "%d", res);
+ str_list[j++] = strdup(str);
+ if (res >= wanted_res)
+ {
+ val = res;
+ }
+ }
+ i++;
+ }
+
+ str_list[j] = 0;
+ sprintf(str, "%d", (int) val);
+
+ xsane_option_menu_new_with_pixmap(GTK_BOX(parent), image_xpm, desc, str_list, str, &resolution_widget, well_known_option,
+ xsane_resolution_list_callback, SANE_OPTION_IS_SETTABLE(opt->cap), widget_name);
+
+ free(str_list);
+ *resolution = val;
+ xsane_set_resolution(well_known_option, *resolution);
+ }
+ }
+ break;
+
+ case SANE_CONSTRAINT_WORD_LIST:
+ {
+ /* use a "list-selection" widget */
+ SANE_Int items;
+ char **str_list;
+ char str[16];
+ int j;
+ SANE_Word val=0;
+
+ gtk_widget_set_sensitive(xsane.show_resolution_list_widget, FALSE);
+
+ items = opt->constraint.word_list[0];
+ str_list = malloc((items + 1) * sizeof(str_list[0]));
+ switch (opt->type)
+ {
+ case SANE_TYPE_INT:
+ for (j = 0; j < items; ++j)
+ {
+ sprintf(str, "%d", opt->constraint.word_list[j + 1]);
+ str_list[j] = strdup(str);
+ }
+ str_list[j] = 0;
+ sane_control_option(dialog->dev, well_known_option, SANE_ACTION_GET_VALUE, &val, 0);
+ sprintf(str, "%d", (int) val);
+ break;
+
+ case SANE_TYPE_FIXED:
+ for (j = 0; j < items; ++j)
+ {
+ sprintf(str, "%d", (int) SANE_UNFIX(opt->constraint.word_list[j + 1]));
+ str_list[j] = strdup(str);
+ }
+ str_list[j] = 0;
+ sane_control_option(dialog->dev, well_known_option, SANE_ACTION_GET_VALUE, &val, 0);
+ sprintf(str, "%d", (int) SANE_UNFIX(val));
+ break;
+
+ default:
+ fprintf(stderr, "resolution_word_list_creation: %s %d\n", ERR_UNKNOWN_TYPE, opt->type);
+ }
+
+
+ xsane_option_menu_new_with_pixmap(GTK_BOX(parent), image_xpm, desc,
+ str_list, str, &resolution_widget, well_known_option,
+ xsane_resolution_list_callback, SANE_OPTION_IS_SETTABLE(opt->cap), widget_name);
+ free(str_list);
+ }
+ break;
+
+ default:
+ break;
+ } /* constraint type */
+
+ return 0; /* everything is ok */
+
+ } /* if resolution option active */
+
+ return 1; /* not active */
+
+ } /* if (opt) */
+}
+
+/* ---------------------------------------------------------------------------------------------------------------------- */
+
+static void xsane_zoom_update(GtkAdjustment *adj_data, double *val)
+{
+ *val=adj_data->value;
+
+ /* update all resolutions */
+ xsane.resolution = xsane.zoom * preferences.printer[preferences.printernr]->resolution;
+ xsane.resolution_x = xsane.zoom_x * preferences.printer[preferences.printernr]->resolution;
+ xsane.resolution_y = xsane.zoom_y * preferences.printer[preferences.printernr]->resolution;
+
+ xsane_set_all_resolutions();
+
+ xsane_update_param(dialog, 0);
+
+ xsane_define_maximum_output_size();
+}
+
+/* ---------------------------------------------------------------------------------------------------------------------- */
+
+static int xsane_zoom_widget_new(GtkWidget *parent, int well_known_option, double *zoom, double resolution,
+ const char *image_xpm[], const gchar *desc)
+{
+ const SANE_Option_Descriptor *opt;
+ double output_resolution = preferences.printer[preferences.printernr]->resolution;
+
+ opt = sane_get_option_descriptor(dialog->dev, well_known_option);
+ if (!opt)
+ {
+ return -1; /* option not available */
+ }
+ else
+ {
+ if (SANE_OPTION_IS_ACTIVE(opt->cap))
+ {
+ double min = 0.0;
+ double max = 0.0;
+ SANE_Word val = 0.0;
+
+ sane_control_option(dialog->dev, well_known_option, SANE_ACTION_GET_VALUE, &val, 0);
+
+ switch (opt->constraint_type)
+ {
+ case SANE_CONSTRAINT_RANGE:
+ switch (opt->type)
+ {
+ case SANE_TYPE_INT:
+ min = ((double) opt->constraint.range->min) / output_resolution;
+ max = ((double) opt->constraint.range->max) / output_resolution;
+ break;
+
+ case SANE_TYPE_FIXED:
+ min = SANE_UNFIX(opt->constraint.range->min) / output_resolution;
+ max = SANE_UNFIX(opt->constraint.range->max) / output_resolution;
+ val = SANE_UNFIX(val);
+ break;
+
+ default:
+ fprintf(stderr, "zoom_scale_update: %s %d\n", ERR_UNKNOWN_TYPE, opt->type);
+ }
+ break;
+
+ case SANE_CONSTRAINT_WORD_LIST:
+ xsane_get_bounds(opt, &min, &max);
+ min = min / output_resolution;
+ max = max / output_resolution;
+ break;
+
+ default:
+ fprintf(stderr, "zoom_scale_update: %s %d\n", ERR_UNKNOWN_CONSTRAINT_TYPE, opt->constraint_type);
+ }
+
+ if (resolution == 0) /* no prefered value */
+ {
+ resolution = val; /* set backend predefined value */
+ }
+
+ *zoom = resolution / output_resolution;
+
+ xsane_scale_new_with_pixmap(GTK_BOX(parent), image_xpm, desc, min, max, 0.01, 0.01, 0.1, 2,
+ zoom, &xsane.zoom_widget, well_known_option, xsane_zoom_update,
+ SANE_OPTION_IS_SETTABLE(opt->cap));
+
+ return 0; /* everything is ok */
+ }
+ return 1; /* option not active */
+ }
+}
+
+/* ---------------------------------------------------------------------------------------------------------------------- */
+
+GtkWidget *xsane_update_xsane_callback()
+{
+ /* creates the XSane option window */
+
+ 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_hbox_xsane_enhancement;
+ GtkWidget *xsane_frame;
+ GtkWidget *xsane_button;
+ gchar buf[200];
+
+ /* xsane main options */
+
+ xsane_hbox = gtk_hbox_new(FALSE, 2);
+ gtk_widget_show(xsane_hbox);
+ xsane_vbox = gtk_vbox_new(/* homogeneous */ FALSE, 0);
+ gtk_widget_show(xsane_vbox);
+/* gtk_box_pack_start(GTK_BOX(xsane_hbox), xsane_vbox, FALSE, FALSE, 0); */ /* make scales fixed */
+ gtk_box_pack_start(GTK_BOX(xsane_hbox), xsane_vbox, TRUE, TRUE, 0); /* make scales sizeable */
+
+ /* XSane Frame */
+
+ xsane_frame = gtk_frame_new(TEXT_XSANE_OPTIONS);
+ gtk_container_set_border_width(GTK_CONTAINER(xsane_frame), 4);
+ gtk_frame_set_shadow_type(GTK_FRAME(xsane_frame), GTK_SHADOW_ETCHED_IN);
+/* gtk_box_pack_start(GTK_BOX(xsane_vbox), xsane_frame, FALSE, FALSE, 0); */ /* fixed frameheight */
+ 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);
+ gtk_container_add(GTK_CONTAINER(xsane_frame), xsane_vbox_xsane_modus);
+ gtk_widget_show(xsane_vbox_xsane_modus);
+
+/* scan copy fax selection */
+
+ 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);
+
+ 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);
+
+ xsane_modus_menu = gtk_menu_new();
+
+ xsane_modus_item = gtk_menu_item_new_with_label(MENU_ITEM_SCAN);
+ gtk_widget_set_usize(xsane_modus_item, 60, 0);
+ gtk_container_add(GTK_CONTAINER(xsane_modus_menu), xsane_modus_item);
+ gtk_signal_connect(GTK_OBJECT(xsane_modus_item), "activate",
+ (GtkSignalFunc) xsane_modus_callback, &xsane_scanmode_number[XSANE_SCAN]);
+ gtk_widget_show(xsane_modus_item);
+
+ xsane_modus_item = gtk_menu_item_new_with_label(MENU_ITEM_COPY);
+ gtk_container_add(GTK_CONTAINER(xsane_modus_menu), xsane_modus_item);
+ gtk_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_FAX);
+ gtk_container_add(GTK_CONTAINER(xsane_modus_menu), xsane_modus_item);
+ gtk_signal_connect(GTK_OBJECT(xsane_modus_item), "activate",
+ (GtkSignalFunc) xsane_modus_callback, &xsane_scanmode_number[XSANE_FAX]);
+ gtk_widget_show(xsane_modus_item);
+
+ xsane_modus_option_menu = gtk_option_menu_new();
+ xsane_back_gtk_set_tooltip(dialog->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_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);
+
+ dialog->xsanemode_widget = xsane_modus_option_menu;
+ }
+
+ {
+ GtkWidget *pixmapwidget;
+ GdkBitmap *mask;
+ GdkPixmap *pixmap;
+ GtkWidget *hbox;
+ const SANE_Option_Descriptor *opt;
+
+
+ /* colormode */
+ opt = sane_get_option_descriptor(dialog->dev, dialog->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_pixmap_new(pixmap, mask);
+ gtk_box_pack_start(GTK_BOX(hbox), pixmapwidget, FALSE, FALSE, 2);
+ gdk_pixmap_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 = sane_control_option(dialog->dev, dialog->well_known.scanmode, SANE_ACTION_GET_VALUE, set, 0);
+
+ xsane_option_menu_new(hbox, (char **) opt->constraint.string_list, set, dialog->well_known.scanmode,
+ _BGT(opt->desc), 0, SANE_OPTION_IS_SETTABLE(opt->cap), 0);
+ }
+ break;
+
+ default:
+ fprintf(stderr, "scanmode_selection: %s %d\n", ERR_UNKNOWN_TYPE, opt->type);
+ }
+ gtk_widget_show(hbox);
+ }
+ }
+
+
+ /* input selection */
+ opt = sane_get_option_descriptor(dialog->dev, dialog->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_pixmap_new(pixmap, mask);
+ gtk_box_pack_start(GTK_BOX(hbox), pixmapwidget, FALSE, FALSE, 2);
+ gdk_pixmap_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 = sane_control_option(dialog->dev, dialog->well_known.scansource, SANE_ACTION_GET_VALUE, set, 0);
+
+ xsane_option_menu_new(hbox, (char **) opt->constraint.string_list, set, dialog->well_known.scansource,
+ _BGT(opt->desc), 0, SANE_OPTION_IS_SETTABLE(opt->cap), 0);
+ }
+ break;
+
+ default:
+ fprintf(stderr, "scansource_selection: %s %d\n", ERR_UNKNOWN_TYPE, opt->type);
+ }
+ gtk_widget_show(hbox);
+ }
+ }
+
+ }
+
+ if (xsane.xsane_mode == XSANE_SCAN)
+ {
+ xsane.copy_number_entry = 0;
+
+ if (xsane.mode == XSANE_STANDALONE)
+ {
+ xsane_outputfilename_new(xsane_vbox_xsane_modus);
+ }
+
+ /* resolution selection */
+ if (!xsane_resolution_widget_new(xsane_vbox_xsane_modus, dialog->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, dialog->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, dialog->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;
+ int i;
+
+ 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 **) printer_xpm);
+ pixmapwidget = gtk_pixmap_new(pixmap, mask);
+ gtk_box_pack_start(GTK_BOX(hbox), pixmapwidget, FALSE, FALSE, 2);
+ gdk_pixmap_unref(pixmap);
+ gtk_widget_show(pixmapwidget);
+
+ xsane_printer_menu = gtk_menu_new();
+
+ for (i=0; i < preferences.printerdefinitions; i++)
+ {
+ xsane_printer_item = gtk_menu_item_new_with_label(preferences.printer[i]->name);
+ gtk_container_add(GTK_CONTAINER(xsane_printer_menu), xsane_printer_item);
+ gtk_signal_connect(GTK_OBJECT(xsane_printer_item), "activate", (GtkSignalFunc) xsane_printer_callback, (void *) i);
+ gtk_widget_show(xsane_printer_item);
+ }
+
+ xsane_printer_option_menu = gtk_option_menu_new();
+ xsane_back_gtk_set_tooltip(dialog->tooltips, xsane_printer_option_menu, DESC_PRINTER_SELECT);
+ gtk_box_pack_end(GTK_BOX(hbox), xsane_printer_option_menu, FALSE, FALSE, 2);
+ gtk_widget_show(xsane_printer_option_menu);
+ gtk_widget_show(hbox);
+
+ gtk_option_menu_set_menu(GTK_OPTION_MENU(xsane_printer_option_menu), xsane_printer_menu);
+ 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(dialog->tooltips, xsane_text, DESC_COPY_NUMBER);
+ gtk_widget_set_usize(xsane_text, 25, 0);
+ 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);
+ gtk_widget_show(hbox);
+ xsane.copy_number_entry = xsane_text;
+
+ /* zoom selection */
+ if (!xsane_zoom_widget_new(xsane_vbox_xsane_modus, dialog->well_known.dpi_x, &xsane.zoom_x,
+ xsane.resolution_x, zoom_x_xpm, DESC_ZOOM_X))
+ {
+ xsane_zoom_widget_new(xsane_vbox_xsane_modus, dialog->well_known.dpi_y, &xsane.zoom_y,
+ xsane.resolution_y, zoom_y_xpm, DESC_ZOOM_Y);
+ }
+ else
+ {
+ xsane_zoom_widget_new(xsane_vbox_xsane_modus, dialog->well_known.dpi, &xsane.zoom,
+ xsane.resolution, zoom_xpm, DESC_ZOOM);
+ }
+ }
+ else /* XSANE_FAX */
+ {
+ const SANE_Option_Descriptor *opt;
+
+ xsane.copy_number_entry = 0;
+ xsane.resolution = 98;
+ xsane.resolution_x = 98;
+ xsane.resolution_y = 98;
+
+ opt = sane_get_option_descriptor(dialog->dev, dialog->well_known.dpi);
+ if (!opt)
+ {
+ opt = sane_get_option_descriptor(dialog->dev, dialog->well_known.dpi_x);
+ }
+
+ if (opt)
+ {
+ if (SANE_OPTION_IS_ACTIVE(opt->cap))
+ {
+ xsane_button = gtk_check_button_new_with_label(RADIO_BUTTON_FINE_MODE);
+ xsane_back_gtk_set_tooltip(dialog->tooltips, xsane_button, DESC_FAX_FINE_MODE);
+ gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(xsane_button), xsane.fax_fine_mode);
+ gtk_box_pack_start(GTK_BOX(xsane_vbox_xsane_modus), xsane_button, FALSE, FALSE, 2);
+ gtk_widget_show(xsane_button);
+ gtk_signal_connect(GTK_OBJECT(xsane_button), "clicked", (GtkSignalFunc) xsane_fax_fine_mode_callback, 0);
+
+ if (xsane.fax_fine_mode)
+ {
+ xsane.resolution = 196;
+ xsane.resolution_x = 98;
+ xsane.resolution_y = 196;
+ }
+
+ xsane_set_all_resolutions();
+ }
+ }
+ xsane_fax_dialog();
+ }
+
+ /* test if scanner gamma table is selected */
+
+ xsane.scanner_gamma_gray = FALSE;
+ if (dialog->well_known.gamma_vector >0)
+ {
+ const SANE_Option_Descriptor *opt;
+
+ opt = sane_get_option_descriptor(dialog->dev, dialog->well_known.gamma_vector);
+ if (SANE_OPTION_IS_ACTIVE(opt->cap))
+ {
+ xsane.scanner_gamma_gray = TRUE;
+ }
+ }
+
+ xsane.scanner_gamma_color = FALSE;
+ if (dialog->well_known.gamma_vector_r >0)
+ {
+ const SANE_Option_Descriptor *opt;
+
+ opt = sane_get_option_descriptor(dialog->dev, dialog->well_known.gamma_vector_r);
+ if (SANE_OPTION_IS_ACTIVE(opt->cap))
+ {
+ xsane.scanner_gamma_color = TRUE;
+ }
+ }
+
+
+
+ /* XSane Frame Enhancement */
+
+ sane_get_parameters(dialog->dev, &xsane.param); /* update xsane.param */
+
+ if (xsane.param.depth == 1)
+ {
+ return(xsane_hbox);
+ }
+
+ xsane.slider_gray.active = XSANE_SLIDER_ACTIVE; /* mark slider active */
+
+ if ( (xsane.xsane_color) && (!xsane.enhancement_rgb_default) )
+ {
+ xsane_separator_new(xsane_vbox_xsane_modus, 2);
+ }
+
+ xsane_scale_new_with_pixmap(GTK_BOX(xsane_vbox_xsane_modus), Gamma_xpm, DESC_GAMMA,
+ XSANE_GAMMA_MIN, XSANE_GAMMA_MAX, 0.01, 0.01, 0.0, 2,
+ &xsane.gamma, &xsane.gamma_widget, 0, xsane_gamma_changed, TRUE);
+ if ( (xsane.xsane_color) && (!xsane.enhancement_rgb_default) )
+ {
+ xsane_scale_new_with_pixmap(GTK_BOX(xsane_vbox_xsane_modus), Gamma_red_xpm, DESC_GAMMA_R,
+ XSANE_GAMMA_MIN, XSANE_GAMMA_MAX, 0.01, 0.01, 0.0, 2,
+ &xsane.gamma_red , &xsane.gamma_red_widget, 0, xsane_gamma_changed, TRUE);
+ xsane_scale_new_with_pixmap(GTK_BOX(xsane_vbox_xsane_modus), Gamma_green_xpm, DESC_GAMMA_G,
+ XSANE_GAMMA_MIN, XSANE_GAMMA_MAX, 0.01, 0.01, 0.0, 2,
+ &xsane.gamma_green, &xsane.gamma_green_widget, 0, xsane_gamma_changed, TRUE);
+ xsane_scale_new_with_pixmap(GTK_BOX(xsane_vbox_xsane_modus), Gamma_blue_xpm, DESC_GAMMA_B,
+ XSANE_GAMMA_MIN, XSANE_GAMMA_MAX, 0.01, 0.01, 0.0, 2,
+ &xsane.gamma_blue , &xsane.gamma_blue_widget, 0, xsane_gamma_changed, TRUE);
+
+ xsane_separator_new(xsane_vbox_xsane_modus, 2);
+ }
+
+ xsane_scale_new_with_pixmap(GTK_BOX(xsane_vbox_xsane_modus), brightness_xpm, DESC_BRIGHTNESS,
+ XSANE_BRIGHTNESS_MIN, XSANE_BRIGHTNESS_MAX, 1.0, 1.0, 0.0, 0,
+ &xsane.brightness, &xsane.brightness_widget, 0, xsane_gamma_changed, TRUE);
+ if ( (xsane.xsane_color) && (!xsane.enhancement_rgb_default) )
+ {
+ xsane_scale_new_with_pixmap(GTK_BOX(xsane_vbox_xsane_modus), brightness_red_xpm, DESC_BRIGHTNESS_R,
+ XSANE_BRIGHTNESS_MIN, XSANE_BRIGHTNESS_MAX, 1.0, 1.0, 0.0, 0,
+ &xsane.brightness_red , &xsane.brightness_red_widget, 0, xsane_gamma_changed, TRUE);
+ xsane_scale_new_with_pixmap(GTK_BOX(xsane_vbox_xsane_modus), brightness_green_xpm, DESC_BRIGHTNESS_G,
+ XSANE_BRIGHTNESS_MIN, XSANE_BRIGHTNESS_MAX, 1.0, 1.0, 0.0, 0,
+ &xsane.brightness_green, &xsane.brightness_green_widget, 0, xsane_gamma_changed, TRUE);
+ xsane_scale_new_with_pixmap(GTK_BOX(xsane_vbox_xsane_modus), brightness_blue_xpm, DESC_BRIGHTNESS_B,
+ XSANE_BRIGHTNESS_MIN, XSANE_BRIGHTNESS_MAX, 1.0, 1.0, 0.0, 0,
+ &xsane.brightness_blue, &xsane.brightness_blue_widget, 0, xsane_gamma_changed, TRUE);
+
+ xsane_separator_new(xsane_vbox_xsane_modus, 2);
+ }
+
+ xsane_scale_new_with_pixmap(GTK_BOX(xsane_vbox_xsane_modus), contrast_xpm, DESC_CONTRAST,
+ XSANE_CONTRAST_GRAY_MIN, XSANE_CONTRAST_MAX, 1.0, 1.0, 0.0, 0,
+ &xsane.contrast, &xsane.contrast_widget, 0, xsane_gamma_changed, TRUE);
+ if ( (xsane.xsane_color) && (!xsane.enhancement_rgb_default) )
+ {
+ xsane_scale_new_with_pixmap(GTK_BOX(xsane_vbox_xsane_modus), contrast_red_xpm, DESC_CONTRAST_R,
+ XSANE_CONTRAST_MIN, XSANE_CONTRAST_MAX, 1.0, 1.0, 0.0, 0,
+ &xsane.contrast_red , &xsane.contrast_red_widget, 0, xsane_gamma_changed, TRUE);
+ xsane_scale_new_with_pixmap(GTK_BOX(xsane_vbox_xsane_modus), contrast_green_xpm, DESC_CONTRAST_G,
+ XSANE_CONTRAST_MIN, XSANE_CONTRAST_MAX, 1.0, 1.0, 0.0, 0,
+ &xsane.contrast_green, &xsane.contrast_green_widget, 0, xsane_gamma_changed, TRUE);
+ xsane_scale_new_with_pixmap(GTK_BOX(xsane_vbox_xsane_modus), contrast_blue_xpm, DESC_CONTRAST_B,
+ XSANE_CONTRAST_MIN, XSANE_CONTRAST_MAX, 1.0, 1.0, 0.0, 0,
+ &xsane.contrast_blue, &xsane.contrast_blue_widget, 0, xsane_gamma_changed, TRUE);
+ }
+
+ xsane_separator_new(xsane_vbox_xsane_modus, 2);
+
+ /* create lower button box (rgb default, negative ,... */
+ xsane_hbox_xsane_enhancement = gtk_hbox_new(TRUE, 4);
+ gtk_container_set_border_width(GTK_CONTAINER(xsane_hbox_xsane_enhancement), 4);
+ gtk_box_pack_start(GTK_BOX(xsane_vbox_xsane_modus), xsane_hbox_xsane_enhancement, FALSE, FALSE, 0);
+ gtk_widget_show(xsane_hbox_xsane_enhancement);
+
+ if (xsane.xsane_color)
+ {
+ xsane_toggle_button_new_with_pixmap(xsane_hbox_xsane_enhancement, rgb_default_xpm, DESC_RGB_DEFAULT,
+ &xsane.enhancement_rgb_default, xsane_enhancement_rgb_default_callback);
+ }
+
+ xsane_toggle_button_new_with_pixmap(xsane_hbox_xsane_enhancement, negative_xpm, DESC_NEGATIVE,
+ &xsane.negative, xsane_enhancement_negative_callback);
+
+ xsane_button_new_with_pixmap(xsane_hbox_xsane_enhancement, enhance_xpm, DESC_ENH_AUTO,
+ xsane_auto_enhancement_callback, 0);
+
+ xsane_button_new_with_pixmap(xsane_hbox_xsane_enhancement, default_enhancement_xpm, DESC_ENH_DEFAULT,
+ xsane_enhancement_restore_default, 0);
+
+ xsane_button_new_with_pixmap(xsane_hbox_xsane_enhancement, restore_enhancement_xpm, DESC_ENH_RESTORE,
+ xsane_enhancement_restore, 0);
+
+ xsane_button_new_with_pixmap(xsane_hbox_xsane_enhancement, store_enhancement_xpm, DESC_ENH_STORE,
+ xsane_enhancement_store, 0);
+
+ xsane_update_histogram();
+
+ return(xsane_hbox);
+}
+
+/* ---------------------------------------------------------------------------------------------------------------------- */
+
+static void xsane_update_preview(GSGDialog *dialog, void *arg)
+{
+ if (xsane.preview)
+ {
+ preview_update_surface(xsane.preview, 0);
+ }
+}
+
+/* ---------------------------------------------------------------------------------------------------------------------- */
+
+void xsane_pref_save(void)
+{
+ char filename[PATH_MAX];
+ int fd;
+
+ /* first save xsane-specific preferences: */
+ xsane_back_gtk_make_path(sizeof(filename), filename, "xsane", 0, "xsane", 0, ".rc", XSANE_PATH_LOCAL_SANE);
+ umask(XSANE_DEFAULT_UMASK); /* define new file permissions */
+ fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC, 0666);
+ if (fd < 0)
+ {
+ char buf[256];
+
+ snprintf(buf, sizeof(buf), "%s %s.", ERR_FAILED_CREATE_FILE, strerror(errno));
+ xsane_back_gtk_error(buf, TRUE);
+ return;
+ }
+ preferences_save(fd);
+ close(fd);
+}
+
+/* ---------------------------------------------------------------------------------------------------------------------- */
+
+static void xsane_pref_restore(void)
+{
+ char filename[PATH_MAX];
+ int fd;
+
+ xsane_back_gtk_make_path(sizeof(filename), filename, "xsane", 0, "xsane", 0, ".rc", XSANE_PATH_LOCAL_SANE);
+ fd = open(filename, O_RDONLY);
+
+ if (fd >= 0)
+ {
+ preferences_restore(fd);
+ close(fd);
+ }
+ else /* no local sane file, look for system file */
+ {
+ xsane_back_gtk_make_path(sizeof(filename), filename, "xsane", 0, "xsane", 0, ".rc", XSANE_PATH_SYSTEM);
+ fd = open(filename, O_RDONLY);
+
+ if (fd >= 0)
+ {
+ preferences_restore(fd);
+ close(fd);
+ }
+ }
+
+ if (!preferences.filename)
+ {
+ preferences.filename = strdup(OUTFILENAME);
+ }
+
+ if (preferences.printerdefinitions == 0)
+ {
+ xsane_new_printer();
+ }
+
+ if (!preferences.fax_project)
+ {
+ preferences.fax_project = strdup(FAXPROJECT);
+ }
+
+ if (!preferences.fax_command)
+ {
+ preferences.fax_command = strdup(FAXCOMMAND);
+ }
+
+ if (!preferences.fax_receiver_option)
+ {
+ preferences.fax_receiver_option = strdup(FAXRECEIVEROPT);
+ }
+
+ if (!preferences.fax_postscript_option)
+ {
+ preferences.fax_postscript_option = strdup(FAXPOSTSCRIPTOPT);
+ }
+
+ if (!preferences.fax_normal_option)
+ {
+ preferences.fax_normal_option = strdup(FAXNORMALOPT);
+ }
+
+ if (!preferences.fax_fine_option)
+ {
+ preferences.fax_fine_option = strdup(FAXFINEOPT);
+ }
+
+ if (!preferences.fax_viewer)
+ {
+ preferences.fax_viewer = strdup(FAXVIEWER);
+ }
+
+ if (!preferences.doc_viewer)
+ {
+ preferences.doc_viewer = strdup(DOCVIEWER);
+ }
+}
+
+/* ---------------------------------------------------------------------------------------------------------------------- */
+
+static void xsane_quit(void)
+{
+ if (xsane.preview)
+ {
+ Preview *preview = xsane.preview;
+ xsane.preview = 0;
+ preview_destroy(preview);
+ }
+
+ while (xsane_back_gtk_message_dialog_active)
+ {
+ gtk_main_iteration();
+ }
+
+ if (dialog && xsane_back_gtk_dialog_get_device(dialog))
+ {
+ sane_close(xsane_back_gtk_dialog_get_device(dialog));
+ }
+
+ sane_exit();
+ gtk_main_quit();
+
+ if (xsane.preview_gamma_data_red)
+ {
+ free(xsane.preview_gamma_data_red);
+ free(xsane.preview_gamma_data_green);
+ free(xsane.preview_gamma_data_blue);
+
+ xsane.preview_gamma_data_red = 0;
+ xsane.preview_gamma_data_green = 0;
+ xsane.preview_gamma_data_blue = 0;
+ }
+
+#ifdef HAVE_LIBGIMP_GIMP_H
+ if (xsane.mode == XSANE_GIMP_EXTENSION)
+ {
+ gimp_quit();
+ }
+#endif
+ exit(0);
+}
+
+/* ---------------------------------------------------------------------------------------------------------------------- */
+
+static void xsane_exit(void) /* this is called when xsane exits before gtk_main is called */
+{
+ while (xsane_back_gtk_message_dialog_active)
+ {
+ gtk_main_iteration();
+ }
+
+ sane_exit();
+
+#ifdef HAVE_LIBGIMP_GIMP_H
+ if (xsane.mode == XSANE_GIMP_EXTENSION)
+ {
+ gimp_quit();
+ }
+#endif
+ exit(0);
+}
+
+/* ---------------------------------------------------------------------------------------------------------------------- */
+
+static gint xsane_standard_option_win_delete(GtkWidget *widget, gpointer data)
+{
+ 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);
+ return TRUE;
+}
+
+/* ---------------------------------------------------------------------------------------------------------------------- */
+
+static gint xsane_advanced_option_win_delete(GtkWidget *widget, gpointer data)
+{
+ 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);
+ return TRUE;
+}
+
+/* ---------------------------------------------------------------------------------------------------------------------- */
+
+/* Invoked when window manager's "delete" (or "close") function is invoked. */
+static gint xsane_scan_win_delete(GtkWidget *w, gpointer data)
+{
+ xsane_scan_done(-1); /* stop scanner when still scanning */
+
+ if (xsane.filetype) /* add extension to filename */
+ {
+ char buffer[256];
+
+ snprintf(buffer, sizeof(buffer), "%s%s", preferences.filename, xsane.filetype);
+ free(preferences.filename);
+ free(xsane.filetype);
+ xsane.filetype = 0;
+ preferences.filename = strdup(buffer);
+ }
+
+ xsane_pref_save();
+ xsane_quit();
+ return FALSE;
+}
+
+/* ---------------------------------------------------------------------------------------------------------------------- */
+
+static gint xsane_preview_window_destroyed(GtkWidget *widget, gpointer call_data)
+{
+ gtk_widget_hide(widget);
+ xsane.show_preview = FALSE;
+ gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(xsane.show_preview_widget), FALSE);
+ return TRUE;
+}
+
+/* ---------------------------------------------------------------------------------------------------------------------- */
+
+static void xsane_show_preview_callback(GtkWidget * widget, gpointer call_data)
+{
+ if (GTK_CHECK_MENU_ITEM(widget)->active)
+ {
+ gtk_widget_show(xsane.preview->top);
+ xsane.show_preview = TRUE;
+ }
+ else
+ {
+ gtk_widget_hide(xsane.preview->top);
+ xsane.show_preview = FALSE;
+ }
+}
+
+/* ---------------------------------------------------------------------------------------------------------------------- */
+
+static GtkWidget *xsane_files_build_menu(void)
+{
+ GtkWidget *menu, *item;
+
+ menu = gtk_menu_new();
+
+ item = gtk_menu_item_new();
+ gtk_container_add(GTK_CONTAINER(menu), item);
+ gtk_widget_show(item);
+
+
+ /* XSane about dialog */
+
+ item = gtk_menu_item_new_with_label(MENU_ITEM_ABOUT);
+ gtk_menu_append(GTK_MENU(menu), item);
+ gtk_signal_connect(GTK_OBJECT(item), "activate", (GtkSignalFunc) xsane_about_dialog, 0);
+ gtk_widget_show(item);
+
+
+ /* XSane info dialog */
+
+ item = gtk_menu_item_new_with_label(MENU_ITEM_INFO);
+ gtk_menu_append(GTK_MENU(menu), item);
+ gtk_signal_connect(GTK_OBJECT(item), "activate", (GtkSignalFunc) xsane_info_dialog, 0);
+ gtk_widget_show(item);
+
+
+ /* Exit */
+
+ item = gtk_menu_item_new_with_label(MENU_ITEM_EXIT);
+ gtk_container_add(GTK_CONTAINER(menu), item);
+ gtk_signal_connect(GTK_OBJECT(item), "activate", (GtkSignalFunc) xsane_scan_win_delete, 0);
+ gtk_widget_show(item);
+
+ return menu;
+}
+
+/* ---------------------------------------------------------------------------------------------------------------------- */
+
+static void xsane_set_pref_unit_callback(GtkWidget *widget, gpointer data)
+{
+ const char *unit = data;
+ double unit_conversion_factor = 1.0;
+
+ gtk_signal_handler_block_by_func(GTK_OBJECT(xsane.length_unit_mm), (GtkSignalFunc) xsane_set_pref_unit_callback, "mm");
+ gtk_signal_handler_block_by_func(GTK_OBJECT(xsane.length_unit_cm), (GtkSignalFunc) xsane_set_pref_unit_callback, "cm");
+ gtk_signal_handler_block_by_func(GTK_OBJECT(xsane.length_unit_in), (GtkSignalFunc) xsane_set_pref_unit_callback, "in");
+
+ if (strcmp(unit, "mm") == 0)
+ {
+ gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(xsane.length_unit_mm), TRUE);
+ gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(xsane.length_unit_cm), FALSE);
+ gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(xsane.length_unit_in), FALSE);
+ }
+ else if (strcmp(unit, "cm") == 0)
+ {
+ unit_conversion_factor = 10.0;
+ gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(xsane.length_unit_mm), FALSE);
+ gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(xsane.length_unit_cm), TRUE);
+ gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(xsane.length_unit_in), FALSE);
+ }
+ else if (strcmp(unit, "in") == 0)
+ {
+ unit_conversion_factor = 25.4;
+ gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(xsane.length_unit_mm), FALSE);
+ gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(xsane.length_unit_cm), FALSE);
+ gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(xsane.length_unit_in), TRUE);
+ }
+
+ gtk_signal_handler_unblock_by_func(GTK_OBJECT(xsane.length_unit_mm), (GtkSignalFunc) xsane_set_pref_unit_callback, "mm");
+ gtk_signal_handler_unblock_by_func(GTK_OBJECT(xsane.length_unit_cm), (GtkSignalFunc) xsane_set_pref_unit_callback, "cm");
+ gtk_signal_handler_unblock_by_func(GTK_OBJECT(xsane.length_unit_in), (GtkSignalFunc) xsane_set_pref_unit_callback, "in");
+
+ preferences.length_unit = unit_conversion_factor;
+
+ xsane_refresh_dialog(dialog);
+ if (xsane.preview)
+ {
+ preview_area_resize(xsane.preview->window);
+ }
+
+ xsane_pref_save();
+}
+
+/* ---------------------------------------------------------------------------------------------------------------------- */
+
+static void xsane_set_update_policy_callback(GtkWidget *widget, gpointer data)
+{
+ GtkUpdateType policy = (GtkUpdateType) data;
+
+ gtk_signal_handler_block_by_func(GTK_OBJECT(xsane.update_policy_continu), (GtkSignalFunc) xsane_set_update_policy_callback,
+ (void *) GTK_UPDATE_CONTINUOUS);
+ gtk_signal_handler_block_by_func(GTK_OBJECT(xsane.update_policy_discont), (GtkSignalFunc) xsane_set_update_policy_callback,
+ (void *) GTK_UPDATE_DISCONTINUOUS);
+ gtk_signal_handler_block_by_func(GTK_OBJECT(xsane.update_policy_delayed), (GtkSignalFunc) xsane_set_update_policy_callback,
+ (void *) GTK_UPDATE_DELAYED);
+
+ if (policy == GTK_UPDATE_CONTINUOUS)
+ {
+ gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(xsane.update_policy_continu), TRUE);
+ gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(xsane.update_policy_discont), FALSE);
+ gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(xsane.update_policy_delayed), FALSE);
+ }
+ else if (policy == GTK_UPDATE_DISCONTINUOUS)
+ {
+ gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(xsane.update_policy_continu), FALSE);
+ gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(xsane.update_policy_discont), TRUE);
+ gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(xsane.update_policy_delayed), FALSE);
+ }
+ else if (policy == GTK_UPDATE_DELAYED)
+ {
+ gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(xsane.update_policy_continu), FALSE);
+ gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(xsane.update_policy_discont), FALSE);
+ gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(xsane.update_policy_delayed), TRUE);
+ }
+
+ gtk_signal_handler_unblock_by_func(GTK_OBJECT(xsane.update_policy_continu), (GtkSignalFunc) xsane_set_update_policy_callback,
+ (void *) GTK_UPDATE_CONTINUOUS);
+ gtk_signal_handler_unblock_by_func(GTK_OBJECT(xsane.update_policy_discont), (GtkSignalFunc) xsane_set_update_policy_callback,
+ (void *) GTK_UPDATE_DISCONTINUOUS);
+ gtk_signal_handler_unblock_by_func(GTK_OBJECT(xsane.update_policy_delayed), (GtkSignalFunc) xsane_set_update_policy_callback,
+ (void *) GTK_UPDATE_DELAYED);
+
+ preferences.gtk_update_policy = policy;
+ xsane_pref_save();
+
+ xsane_back_gtk_refresh_dialog(dialog);
+}
+
+/* ---------------------------------------------------------------------------------------------------------------------- */
+
+static gint xsane_close_info_callback(GtkWidget *widget, gpointer data)
+{
+ GtkWidget *dialog = data;
+
+ gtk_widget_destroy(dialog);
+
+ xsane_set_sensitivity(TRUE);
+
+ xsane_update_histogram();
+
+ return FALSE;
+}
+
+/* ---------------------------------------------------------------------------------------------------------------------- */
+
+static void xsane_info_dialog(GtkWidget *widget, gpointer data)
+{
+ GtkWidget *info_dialog, *vbox, *button, *label, *frame, *framebox, *hbox, *table;
+ char buf[256];
+ char *bufptr;
+
+ sane_get_parameters(dialog->dev, &xsane.param); /* update xsane.param */
+
+ info_dialog = gtk_window_new(GTK_WINDOW_DIALOG);
+ gtk_window_set_position(GTK_WINDOW(info_dialog), GTK_WIN_POS_CENTER);
+ gtk_window_set_policy(GTK_WINDOW(info_dialog), FALSE, FALSE, FALSE);
+ gtk_signal_connect(GTK_OBJECT(info_dialog), "destroy", GTK_SIGNAL_FUNC(xsane_close_info_callback), info_dialog);
+ snprintf(buf, sizeof(buf), "%s %s %s", prog_name, WINDOW_INFO, device_text);
+ gtk_window_set_title(GTK_WINDOW(info_dialog), buf);
+
+ xsane_set_window_icon(info_dialog, 0);
+
+ vbox = gtk_vbox_new(/* not homogeneous */ FALSE, 5);
+ gtk_container_add(GTK_CONTAINER(info_dialog), vbox);
+ gtk_widget_show(vbox);
+
+ frame = gtk_frame_new(TEXT_SCANNER_BACKEND);
+ gtk_frame_set_shadow_type(GTK_FRAME(frame), GTK_SHADOW_ETCHED_IN);
+ gtk_box_pack_start(GTK_BOX(vbox), frame, FALSE, FALSE, 5);
+ gtk_widget_show(frame);
+
+ framebox = gtk_vbox_new(/* not homogeneous */ FALSE, 0);
+ gtk_container_add(GTK_CONTAINER(frame), framebox);
+ gtk_widget_show(framebox);
+
+ hbox = gtk_hbox_new(/* homogeneous */ FALSE, 0);
+ gtk_box_pack_start(GTK_BOX(framebox), hbox, TRUE, TRUE, 5);
+ gtk_widget_show(hbox);
+
+ table = gtk_table_new(6, 2, FALSE);
+ gtk_box_pack_start(GTK_BOX(hbox), table, FALSE, FALSE, 5);
+ gtk_widget_show(table);
+
+ snprintf(buf, sizeof(buf), TEXT_VENDOR);
+ label = xsane_info_table_text_new(table, buf, 0, 0);
+ snprintf(buf, sizeof(buf), "%s", devlist[seldev]->vendor);
+ label = xsane_info_table_text_new(table, buf, 1, 0);
+
+ snprintf(buf, sizeof(buf), TEXT_MODEL);
+ label = xsane_info_table_text_new(table, buf, 0, 1);
+ snprintf(buf, sizeof(buf), "%s", devlist[seldev]->model);
+ label = xsane_info_table_text_new(table, buf, 1, 1);
+
+ snprintf(buf, sizeof(buf), TEXT_TYPE);
+ label = xsane_info_table_text_new(table, buf, 0, 2);
+ snprintf(buf, sizeof(buf), "%s", devlist[seldev]->type);
+ label = xsane_info_table_text_new(table, buf, 1, 2);
+
+ snprintf(buf, sizeof(buf), TEXT_DEVICE);
+ label = xsane_info_table_text_new(table, buf, 0, 3);
+ bufptr = strrchr(devlist[seldev]->name, ':');
+ if (bufptr)
+ {
+ snprintf(buf, sizeof(buf), "%s", bufptr+1);
+ }
+ else
+ {
+ snprintf(buf, sizeof(buf), devlist[seldev]->name);
+ }
+ label = xsane_info_table_text_new(table, buf, 1, 3);
+
+ snprintf(buf, sizeof(buf), "%s", devlist[seldev]->name);
+ bufptr = strrchr(buf, ':');
+ if (bufptr)
+ {
+ *bufptr = 0;
+ label = xsane_info_table_text_new(table, buf, 1, 4);
+ snprintf(buf, sizeof(buf), TEXT_LOADED_BACKEND);
+ label = xsane_info_table_text_new(table, buf, 0, 4);
+ }
+
+ snprintf(buf, sizeof(buf), TEXT_SANE_VERSION);
+ label = xsane_info_table_text_new(table, buf, 0, 5);
+ snprintf(buf, sizeof(buf), "%d.%d build %d",SANE_VERSION_MAJOR(xsane.sane_backend_versioncode),
+ SANE_VERSION_MINOR(xsane.sane_backend_versioncode),
+ SANE_VERSION_BUILD(xsane.sane_backend_versioncode));
+ label = xsane_info_table_text_new(table, buf, 1, 5);
+
+
+ frame = gtk_frame_new(TEXT_RECENT_VALUES);
+ gtk_frame_set_shadow_type(GTK_FRAME(frame), GTK_SHADOW_ETCHED_IN);
+ gtk_box_pack_start(GTK_BOX(vbox), frame, FALSE, FALSE, 5);
+ gtk_widget_show(frame);
+
+ framebox = gtk_vbox_new(/* not homogeneous */ FALSE, 0);
+ gtk_container_add(GTK_CONTAINER(frame), framebox);
+ gtk_widget_show(framebox);
+
+ hbox = gtk_hbox_new(/* homogeneous */ FALSE, 0);
+ gtk_box_pack_start(GTK_BOX(framebox), hbox, TRUE, TRUE, 5);
+ gtk_widget_show(hbox);
+
+ table = gtk_table_new(4, 2, FALSE);
+ gtk_box_pack_start(GTK_BOX(hbox), table, FALSE, FALSE, 5);
+ gtk_widget_show(table);
+
+ if ((xsane.xsane_color) && (xsane.scanner_gamma_color)) /* color gamma correction by scanner */
+ {
+ const SANE_Option_Descriptor *opt;
+
+ snprintf(buf, sizeof(buf), TEXT_GAMMA_CORR_BY);
+ label = xsane_info_table_text_new(table, buf, 0, 0);
+ snprintf(buf, sizeof(buf), TEXT_SCANNER);
+ label = xsane_info_table_text_new(table, buf, 1, 0);
+
+ opt = sane_get_option_descriptor(dialog->dev, dialog->well_known.gamma_vector_r);
+
+ snprintf(buf, sizeof(buf), TEXT_GAMMA_INPUT_DEPTH);
+ label = xsane_info_table_text_new(table, buf, 0, 1);
+ snprintf(buf, sizeof(buf), "%d bit", (int) (0.5 + log((double)opt->size / sizeof(opt->type)) / log(2.0)));
+ label = xsane_info_table_text_new(table, buf, 1, 1);
+
+ snprintf(buf, sizeof(buf), TEXT_GAMMA_OUTPUT_DEPTH);
+ label = xsane_info_table_text_new(table, buf, 0, 2);
+ snprintf(buf, sizeof(buf), "%d bit", (int) (0.5 + log(opt->constraint.range->max+1.0) / log(2.0)));
+ label = xsane_info_table_text_new(table, buf, 1, 2);
+ }
+ else if ((!xsane.xsane_color) && (xsane.scanner_gamma_gray)) /* gray gamma correction by scanner */
+ {
+ const SANE_Option_Descriptor *opt;
+
+ snprintf(buf, sizeof(buf), TEXT_GAMMA_CORR_BY);
+ label = xsane_info_table_text_new(table, buf, 0, 0);
+ snprintf(buf, sizeof(buf), TEXT_SCANNER);
+ label = xsane_info_table_text_new(table, buf, 1, 0);
+
+ opt = sane_get_option_descriptor(dialog->dev, dialog->well_known.gamma_vector);
+
+ snprintf(buf, sizeof(buf), TEXT_GAMMA_INPUT_DEPTH);
+ label = xsane_info_table_text_new(table, buf, 0, 1);
+ snprintf(buf, sizeof(buf), "%d bit", (int) (0.5 + log((double)opt->size / sizeof(opt->type)) / log(2.0)));
+ label = xsane_info_table_text_new(table, buf, 1, 1);
+
+ snprintf(buf, sizeof(buf), TEXT_GAMMA_OUTPUT_DEPTH);
+ label = xsane_info_table_text_new(table, buf, 0, 2);
+ snprintf(buf, sizeof(buf), "%d bit", (int) (0.5 + log(opt->constraint.range->max+1.0) / log(2.0)));
+ label = xsane_info_table_text_new(table, buf, 1, 2);
+ }
+ else if (xsane.param.depth != 1) /* gamma correction by xsane */
+ {
+ snprintf(buf, sizeof(buf), TEXT_GAMMA_CORR_BY);
+ label = xsane_info_table_text_new(table, buf, 0, 0);
+ snprintf(buf, sizeof(buf), TEXT_SOFTWARE_XSANE);
+ label = xsane_info_table_text_new(table, buf, 1, 0);
+
+ snprintf(buf, sizeof(buf), TEXT_GAMMA_INPUT_DEPTH);
+ label = xsane_info_table_text_new(table, buf, 0, 1);
+ snprintf(buf, sizeof(buf), "%d bit", xsane.param.depth);
+ label = xsane_info_table_text_new(table, buf, 1, 1);
+
+ snprintf(buf, sizeof(buf), TEXT_GAMMA_OUTPUT_DEPTH);
+ label = xsane_info_table_text_new(table, buf, 0, 2);
+/* snprintf(buf, sizeof(buf), "%d bit", 8); */
+ snprintf(buf, sizeof(buf), "%d bit", xsane.param.depth);
+ label = xsane_info_table_text_new(table, buf, 1, 2);
+ }
+ else /* no gamma enhancement */
+ {
+ snprintf(buf, sizeof(buf), TEXT_GAMMA_CORR_BY);
+ label = xsane_info_table_text_new(table, buf, 0, 0);
+ snprintf(buf, sizeof(buf), TEXT_NONE);
+ label = xsane_info_table_text_new(table, buf, 1, 0);
+
+ snprintf(buf, sizeof(buf), TEXT_GAMMA_INPUT_DEPTH);
+ label = xsane_info_table_text_new(table, buf, 0, 1);
+ snprintf(buf, sizeof(buf), TEXT_NONE);
+ label = xsane_info_table_text_new(table, buf, 1, 1);
+
+ snprintf(buf, sizeof(buf), TEXT_GAMMA_OUTPUT_DEPTH);
+ label = xsane_info_table_text_new(table, buf, 0, 2);
+ snprintf(buf, sizeof(buf), TEXT_NONE);
+ label = xsane_info_table_text_new(table, buf, 1, 2);
+ }
+
+ snprintf(buf, sizeof(buf), TEXT_SCANNER_OUTPUT_DEPTH);
+ label = xsane_info_table_text_new(table, buf, 0, 3);
+ snprintf(buf, sizeof(buf), "%d bit", xsane.param.depth);
+ label = xsane_info_table_text_new(table, buf, 1, 3);
+
+ frame = gtk_frame_new(TEXT_OUTPUT_FORMATS);
+ gtk_frame_set_shadow_type(GTK_FRAME(frame), GTK_SHADOW_ETCHED_IN);
+ gtk_box_pack_start(GTK_BOX(vbox), frame, FALSE, FALSE, 5);
+ gtk_widget_show(frame);
+
+ framebox = gtk_vbox_new(/* not homogeneous */ FALSE, 0);
+ gtk_container_add(GTK_CONTAINER(frame), framebox);
+ gtk_widget_show(framebox);
+
+ hbox = gtk_hbox_new(/* homogeneous */ FALSE, 0);
+ gtk_box_pack_start(GTK_BOX(framebox), hbox, TRUE, TRUE, 5);
+ gtk_widget_show(hbox);
+
+ table = gtk_table_new(2, 2, FALSE);
+ gtk_box_pack_start(GTK_BOX(hbox), table, FALSE, FALSE, 5);
+ gtk_widget_show(table);
+
+ snprintf(buf, sizeof(buf), TEXT_8BIT_FORMATS);
+ label = xsane_info_table_text_new(table, buf, 0, 0);
+
+ bufptr=buf;
+
+#ifdef HAVE_LIBJPEG
+ sprintf(bufptr, "JPEG, ");
+ bufptr += strlen(bufptr);
+#endif
+
+#ifdef HAVE_LIBPNG
+#ifdef HAVE_LIBZ
+ sprintf(bufptr, "PNG, ");
+ bufptr += strlen(bufptr);
+#endif
+#endif
+
+ sprintf(bufptr, "PNM, ");
+ bufptr += strlen(bufptr);
+
+ sprintf(bufptr, "PS, ");
+ bufptr += strlen(bufptr);
+
+#ifdef SUPPORT_RGBA
+ sprintf(bufptr, "RGBA, ");
+ bufptr += strlen(bufptr);
+#endif
+
+#ifdef HAVE_LIBTIFF
+ sprintf(bufptr, "TIFF, ");
+ bufptr += strlen(bufptr);
+#endif
+
+ bufptr--;
+ bufptr--;
+ *bufptr = 0; /* erase last comma */
+
+ label = xsane_info_table_text_new(table, buf, 1, 0);
+
+ snprintf(buf, sizeof(buf), TEXT_16BIT_FORMATS);
+ label = xsane_info_table_text_new(table, buf, 0, 1);
+
+ bufptr=buf;
+
+#ifdef HAVE_LIBPNG
+#ifdef HAVE_LIBZ
+ sprintf(bufptr, "PNG, ");
+ bufptr += strlen(bufptr);
+#endif
+#endif
+
+ sprintf(bufptr, "PNM, ");
+ bufptr += strlen(bufptr);
+
+ sprintf(bufptr, "RAW, ");
+ bufptr += strlen(bufptr);
+
+#ifdef SUPPORT_RGBA
+ sprintf(bufptr, "RGBA, ");
+ bufptr += strlen(bufptr);
+#endif
+
+ bufptr--;
+ bufptr--;
+ *bufptr = 0; /* erase last comma */
+
+ label = xsane_info_table_text_new(table, buf, 1, 1);
+
+/* gtk_label_set((GtkLabel *)label, "HALLO"); */
+
+ button = gtk_button_new_with_label(BUTTON_CLOSE);
+ gtk_signal_connect(GTK_OBJECT(button), "clicked", (GtkSignalFunc) xsane_close_info_callback, info_dialog);
+ gtk_box_pack_start(GTK_BOX(vbox), button, FALSE, FALSE, 0);
+ gtk_widget_show(button);
+
+ gtk_widget_show(info_dialog);
+
+ xsane_clear_histogram(&xsane.histogram_raw);
+ xsane_clear_histogram(&xsane.histogram_enh);
+
+ xsane_set_sensitivity(FALSE);
+}
+
+/* ---------------------------------------------------------------------------------------------------------------------- */
+
+static void xsane_about_dialog(GtkWidget *widget, gpointer data)
+{
+ GtkWidget *about_dialog, *vbox, *button, *label;
+ char buf[256];
+ GtkWidget *pixmapwidget;
+ GdkBitmap *mask;
+ GdkPixmap *pixmap;
+ GtkStyle *style;
+ GdkColor *bg_trans;
+
+
+ about_dialog = gtk_window_new(GTK_WINDOW_DIALOG);
+ gtk_window_set_position(GTK_WINDOW(about_dialog), GTK_WIN_POS_CENTER);
+ gtk_window_set_policy(GTK_WINDOW(about_dialog), FALSE, FALSE, FALSE);
+ gtk_signal_connect(GTK_OBJECT(about_dialog), "destroy", GTK_SIGNAL_FUNC(xsane_close_info_callback), about_dialog);
+ snprintf(buf, sizeof(buf), "%s %s", WINDOW_ABOUT, prog_name);
+ gtk_window_set_title(GTK_WINDOW(about_dialog), buf);
+
+ xsane_set_window_icon(about_dialog, 0);
+
+ vbox = gtk_vbox_new(/* not homogeneous */ FALSE, 5);
+ gtk_container_add(GTK_CONTAINER(about_dialog), vbox);
+ gtk_widget_show(vbox);
+
+ /* xsane logo */
+ gtk_widget_realize(about_dialog);
+
+ style = gtk_widget_get_style(about_dialog);
+ bg_trans = &style->bg[GTK_STATE_NORMAL];
+
+ snprintf(buf, sizeof(buf), "%s/xsane-logo.xpm", STRINGIFY(PATH_SANE_DATA_DIR));
+ pixmap = gdk_pixmap_create_from_xpm(about_dialog->window, &mask, bg_trans, buf);
+ pixmapwidget = gtk_pixmap_new(pixmap, mask);
+ gtk_box_pack_start(GTK_BOX(vbox), pixmapwidget, FALSE, FALSE, 2);
+ gtk_widget_show(pixmapwidget);
+ gdk_pixmap_unref(pixmap);
+
+ xsane_separator_new(vbox, 5);
+
+ snprintf(buf, sizeof(buf), "XSane %s %s\n", TEXT_VERSION, XSANE_VERSION);
+ label = gtk_label_new(buf);
+ gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, FALSE, 0);
+ gtk_widget_show(label);
+
+ snprintf(buf, sizeof(buf), "(c) %s %s\n", XSANE_DATE, XSANE_COPYRIGHT);
+ label = gtk_label_new(buf);
+ gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, FALSE, 0);
+ gtk_widget_show(label);
+
+ snprintf(buf, sizeof(buf), "%s %s\n", TEXT_EMAIL, XSANE_EMAIL);
+ label = gtk_label_new(buf);
+ gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, FALSE, 0);
+ gtk_widget_show(label);
+
+ button = gtk_button_new_with_label(BUTTON_CLOSE);
+ gtk_signal_connect(GTK_OBJECT(button), "clicked", (GtkSignalFunc) xsane_close_info_callback, about_dialog);
+ gtk_box_pack_start(GTK_BOX(vbox), button, FALSE, FALSE, 0);
+ gtk_widget_show(button);
+
+ gtk_widget_show(about_dialog);
+
+ xsane_clear_histogram(&xsane.histogram_raw);
+ xsane_clear_histogram(&xsane.histogram_enh);
+
+ xsane_set_sensitivity(FALSE);
+}
+
+/* ---------------------------------------------------------------------------------------------------------------------- */
+
+static SANE_Status xsane_get_area_value(int option, float *val, SANE_Int *unit)
+{
+ const SANE_Option_Descriptor *opt;
+ SANE_Handle dev;
+ SANE_Word word;
+
+ if (option <= 0)
+ {
+ return -1;
+ }
+
+ if (sane_control_option(dialog->dev, option, SANE_ACTION_GET_VALUE, &word, 0) == SANE_STATUS_GOOD)
+ {
+ dev = dialog->dev;
+ opt = sane_get_option_descriptor(dev, option);
+
+ if (unit)
+ {
+ *unit = opt->unit;
+ }
+
+ if (val)
+ {
+ if (opt->type == SANE_TYPE_FIXED)
+ {
+ *val = (float) word / 65536.0;
+ }
+ else
+ {
+ *val = (float) word;
+ }
+ }
+
+ return 0;
+ }
+ else if (val)
+ {
+ *val = 0;
+ }
+ return -2;
+}
+
+/* ---------------------------------------------------------------------------------------------------------------------- */
+
+#ifdef XSANE_TEST
+static void xsane_batch_scan_delete_callback(GtkWidget *widget, gpointer list)
+{
+ gtk_list_remove_items(GTK_LIST(list), GTK_LIST(list)->selection);
+}
+
+/* ---------------------------------------------------------------------------------------------------------------------- */
+
+static void xsane_batch_scan_add_callback(GtkWidget *widget, gpointer list)
+{
+ GtkWidget *list_item;
+ float tlx, tly, brx, bry;
+ SANE_Int unit;
+ char buf[255];
+
+
+ xsane_get_area_value(dialog->well_known.coord[0], &tlx, &unit);
+ xsane_get_area_value(dialog->well_known.coord[1], &tly, &unit);
+ xsane_get_area_value(dialog->well_known.coord[2], &brx, &unit);
+ xsane_get_area_value(dialog->well_known.coord[3], &bry, &unit);
+
+ if (unit == SANE_UNIT_MM)
+ {
+ snprintf(buf, sizeof(buf), " top left (%7.2fmm, %7.2fmm), bottom right (%7.2fmm, %7.2fmm)", tlx, tly, brx, bry);
+ }
+ else
+ {
+ snprintf(buf, sizeof(buf), " top left (%5.0fpx, %5.0fpx), bottom right (%5.0fpx, %5.0fpx)", tlx, tly, brx, bry);
+ }
+
+ list_item = gtk_list_item_new_with_label(buf);
+ gtk_object_set_data(GTK_OBJECT(list_item), "list_item_data", strdup(buf));
+ gtk_container_add(GTK_CONTAINER(list), list_item);
+ gtk_widget_show(list_item);
+}
+
+/* ---------------------------------------------------------------------------------------------------------------------- */
+
+static void xsane_batch_scan_dialog(GtkWidget *widget, gpointer data)
+{
+ GtkWidget *batch_scan_dialog, *batch_scan_vbox, *hbox, *button, *scrolled_window, *list;
+ char buf[64];
+
+ batch_scan_dialog = gtk_dialog_new();
+ snprintf(buf, sizeof(buf), "%s %s", prog_name, WINDOW_BATCH_SCAN);
+ gtk_window_set_title(GTK_WINDOW(batch_scan_dialog), buf);
+
+ batch_scan_vbox = GTK_DIALOG(batch_scan_dialog)->vbox;
+
+ scrolled_window = gtk_scrolled_window_new(0, 0);
+ gtk_widget_set_usize(scrolled_window, 400, 200);
+ gtk_container_add(GTK_CONTAINER(batch_scan_vbox), scrolled_window);
+ gtk_widget_show(scrolled_window);
+
+ list = gtk_list_new();
+
+ gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(scrolled_window), list);
+
+ gtk_widget_show(list);
+
+
+ /* fill in action area: */
+ hbox = GTK_DIALOG(batch_scan_dialog)->action_area;
+
+ button = gtk_button_new_with_label(BUTTON_OK);
+ GTK_WIDGET_SET_FLAGS(button, GTK_CAN_DEFAULT);
+ gtk_signal_connect(GTK_OBJECT(button), "clicked", (GtkSignalFunc) xsane_close_dialog_callback, batch_scan_dialog);
+ gtk_box_pack_start(GTK_BOX(hbox), button, TRUE, TRUE, 0);
+ gtk_widget_grab_default(button);
+ gtk_widget_show(button);
+
+ button = gtk_button_new_with_label(BUTTON_ADD_AREA);
+ gtk_signal_connect(GTK_OBJECT(button), "clicked", (GtkSignalFunc) xsane_batch_scan_add_callback, list);
+ gtk_box_pack_start(GTK_BOX(hbox), button, TRUE, TRUE, 0);
+ gtk_widget_show(button);
+
+ button = gtk_button_new_with_label(BUTTON_DELETE);
+ gtk_signal_connect(GTK_OBJECT(button), "clicked", (GtkSignalFunc) xsane_batch_scan_delete_callback, list);
+ gtk_box_pack_start(GTK_BOX(hbox), button, TRUE, TRUE, 0);
+ gtk_widget_show(button);
+
+ gtk_widget_show(batch_scan_dialog);
+}
+#endif
+
+/* ---------------------------------------------------------------------------------------------------------------------- */
+
+static void xsane_fax_dialog_delete()
+{
+}
+
+/* ---------------------------------------------------------------------------------------------------------------------- */
+
+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;
+
+
+ if (xsane.fax_dialog)
+ {
+ return; /* window already is open */
+ }
+
+ fax_dialog = gtk_dialog_new();
+ snprintf(buf, sizeof(buf), "%s %s", prog_name, WINDOW_FAX_PROJECT);
+ gtk_window_set_title(GTK_WINDOW(fax_dialog), buf);
+ gtk_signal_connect(GTK_OBJECT(fax_dialog), "delete_event", (GtkSignalFunc) xsane_fax_dialog_delete, 0);
+ xsane_set_window_icon(fax_dialog, 0);
+
+ fax_scan_vbox = GTK_DIALOG(fax_dialog)->vbox;
+
+ 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_pixmap_new(pixmap, mask);
+ gtk_box_pack_start(GTK_BOX(hbox), pixmapwidget, FALSE, FALSE, 2);
+ gdk_pixmap_unref(pixmap);
+
+ text = gtk_entry_new_with_max_length(128);
+ xsane_back_gtk_set_tooltip(dialog->tooltips, text, DESC_FAXPROJECT);
+ gtk_entry_set_text(GTK_ENTRY(text), (char *) preferences.fax_project);
+ gtk_box_pack_start(GTK_BOX(hbox), text, TRUE, TRUE, 4);
+ gtk_signal_connect(GTK_OBJECT(text), "changed", (GtkSignalFunc) xsane_faxproject_changed_callback, 0);
+
+ xsane.fax_project_entry = text;
+
+ 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);
+
+ 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_pixmap_new(pixmap, mask);
+ gtk_box_pack_start(GTK_BOX(hbox), pixmapwidget, FALSE, FALSE, 2);
+ gdk_pixmap_unref(pixmap);
+
+ text = gtk_entry_new_with_max_length(128);
+ xsane_back_gtk_set_tooltip(dialog->tooltips, text, DESC_FAXRECEIVER);
+ gtk_box_pack_start(GTK_BOX(hbox), text, TRUE, TRUE, 4);
+ gtk_signal_connect(GTK_OBJECT(text), "changed", (GtkSignalFunc) xsane_faxreceiver_changed_callback, 0);
+
+ xsane.fax_receiver_entry = text;
+
+ gtk_widget_show(pixmapwidget);
+ gtk_widget_show(text);
+ gtk_widget_show(hbox);
+
+
+ scrolled_window = gtk_scrolled_window_new(0, 0);
+ gtk_widget_set_usize(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_SHOW);
+ gtk_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_RENAME);
+ gtk_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_DELETE);
+ gtk_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(hbox, move_up_xpm, 0, (GtkSignalFunc) xsane_fax_entry_move_up_callback, list);
+ xsane_button_new_with_pixmap(hbox, move_down_xpm, 0, (GtkSignalFunc) xsane_fax_entry_move_down_callback, list);
+
+ gtk_widget_show(hbox);
+
+ xsane.fax_project_box = fax_project_vbox;
+
+ /* fill in action area: */
+ hbox = GTK_DIALOG(fax_dialog)->action_area;
+
+ 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);
+ gtk_signal_connect(GTK_OBJECT(button), "clicked", (GtkSignalFunc) xsane_fax_send, 0);
+ 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);
+ gtk_signal_connect(GTK_OBJECT(button), "clicked", (GtkSignalFunc) xsane_fax_project_delete, 0);
+ 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);
+ gtk_signal_connect(GTK_OBJECT(button), "clicked", (GtkSignalFunc) xsane_fax_project_create, 0);
+ gtk_box_pack_start(GTK_BOX(hbox), button, TRUE, TRUE, 0);
+ xsane.fax_project_not_exists = button;
+
+ xsane.fax_dialog = fax_dialog;
+
+ xsane_fax_project_load();
+
+ gtk_widget_show(fax_dialog);
+}
+
+/* ---------------------------------------------------------------------------------------------------------------------- */
+
+static void xsane_fax_dialog_close()
+{
+ if (xsane.fax_dialog == 0)
+ {
+ return;
+ }
+
+ gtk_widget_destroy(xsane.fax_dialog);
+
+ xsane.fax_dialog = 0;
+ xsane.fax_list = 0;
+}
+
+/* ---------------------------------------------------------------------------------------------------------------------- */
+
+static void xsane_fax_project_load()
+{
+ FILE *projectfile;
+ char page[256];
+ char buf[256];
+ GtkWidget *list_item;
+ int i;
+ char c;
+
+ gtk_signal_disconnect_by_func(GTK_OBJECT(xsane.fax_receiver_entry), GTK_SIGNAL_FUNC(xsane_faxreceiver_changed_callback), 0);
+ gtk_list_remove_items(GTK_LIST(xsane.fax_list), GTK_LIST(xsane.fax_list)->children);
+
+ snprintf(buf, sizeof(buf), "%s/project-list", preferences.fax_project);
+ projectfile = fopen(buf, "r");
+
+ if ((!projectfile) || (feof(projectfile)))
+ {
+ snprintf(buf, sizeof(buf), "%s/page-001.ps", preferences.fax_project);
+ xsane.fax_filename=strdup(buf);
+
+ 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;
+
+ 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(buf, sizeof(buf), "%s/%s", preferences.fax_project, page);
+ xsane.fax_filename=strdup(buf);
+
+ 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)
+ {
+ list_item = gtk_list_item_new_with_label(page);
+ gtk_object_set_data(GTK_OBJECT(list_item), "list_item_data", strdup(page));
+ 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);
+ }
+
+ gtk_signal_connect(GTK_OBJECT(xsane.fax_receiver_entry), "changed", (GtkSignalFunc) xsane_faxreceiver_changed_callback, 0);
+}
+
+/* ---------------------------------------------------------------------------------------------------------------------- */
+
+static void xsane_fax_project_delete()
+{
+ char *page;
+ char file[256];
+ GList *list = (GList *) GTK_LIST(xsane.fax_list)->children;
+ GtkObject *list_item;
+
+ 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.ps", preferences.fax_project, page);
+ free(page);
+ remove(file);
+ list = list->next;
+ }
+ snprintf(file, sizeof(file), "%s/project-list", preferences.fax_project);
+ remove(file);
+ snprintf(file, sizeof(file), "%s", preferences.fax_project);
+ rmdir(file);
+
+ xsane_fax_project_load();
+}
+
+/* ---------------------------------------------------------------------------------------------------------------------- */
+
+void xsane_fax_project_save()
+{
+ FILE *projectfile;
+ char *page;
+ char buf[256];
+ GList *list = (GList *) GTK_LIST(xsane.fax_list)->children;
+ GtkObject *list_item;
+
+ umask(preferences.directory_umask); /* define new file permissions */
+ mkdir(preferences.fax_project, 0777); /* make sure directory exists */
+
+ snprintf(buf, sizeof(buf), "%s/project-list", preferences.fax_project);
+ umask(preferences.image_umask); /* define image file permissions */
+ projectfile = fopen(buf, "w");
+ umask(XSANE_DEFAULT_UMASK); /* define new file permissions */
+
+ 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");
+ fprintf(projectfile, "%s\n", page);
+ list = list->next;
+ }
+ fclose(projectfile);
+}
+
+/* ---------------------------------------------------------------------------------------------------------------------- */
+
+static void xsane_fax_project_create()
+{
+ if (strlen(preferences.fax_project))
+ {
+ xsane_fax_project_save();
+ xsane_fax_project_load();
+ }
+}
+
+/* ---------------------------------------------------------------------------------------------------------------------- */
+
+static void xsane_pref_toggle_tooltips(GtkWidget *widget, gpointer data)
+{
+ preferences.tooltips_enabled = (GTK_CHECK_MENU_ITEM(widget)->active != 0);
+ xsane_back_gtk_set_tooltips(dialog, preferences.tooltips_enabled);
+ xsane_pref_save();
+}
+
+/* ---------------------------------------------------------------------------------------------------------------------- */
+
+static void xsane_show_doc_via_nsr(GtkWidget *widget, gpointer data) /* show via netscape remote */
+{
+ char *name = (char *) data;
+ char buf[256];
+ FILE *ns_pipe;
+ pid_t pid;
+ char *arg[3];
+
+ snprintf(buf, sizeof(buf), "netscape -no-about-splash -remote \"openFile(%s/%s-doc.html)\" 2>&1", STRINGIFY(PATH_SANE_DATA_DIR), name);
+ ns_pipe = popen(buf, "r");
+
+ if (ns_pipe)
+ {
+ while (!feof(ns_pipe))
+ {
+ while (gtk_events_pending())
+ {
+ gtk_main_iteration();
+ }
+ fgetc(ns_pipe); /* remove char from pipe */
+ }
+
+ while (gtk_events_pending())
+ {
+ gtk_main_iteration();
+ }
+
+ if (pclose(ns_pipe)) /* netscape not running, start it */
+ {
+ snprintf(buf, sizeof(buf), "%s/%s-doc.html", STRINGIFY(PATH_SANE_DATA_DIR), name);
+ arg[0] = "netscape";
+ arg[1] = buf;
+ arg[2] = 0;
+
+ pid = fork();
+
+ if (pid == 0) /* new process */
+ {
+ execvp(arg[0], arg); /* does not return if successfully */
+ fprintf(stderr, "%s %s\n", ERR_FAILD_EXEC_DOC_VIEWER, preferences.doc_viewer);
+ _exit(0); /* do not use exit() here! otherwise gtk gets in trouble */
+ }
+ }
+ }
+ else /* execution failed */
+ {
+ snprintf(buf, sizeof(buf), "%s", ERR_NETSCAPE_EXECUTE_FAIL);
+ xsane_back_gtk_error(buf, TRUE);
+ }
+
+ while (gtk_events_pending())
+ {
+ gtk_main_iteration();
+ }
+}
+
+/* ---------------------------------------------------------------------------------------------------------------------- */
+
+static void xsane_show_doc(GtkWidget *widget, gpointer data)
+{
+ char *name = (char *) data;
+ char buf[256];
+ pid_t pid;
+ char *arg[3];
+
+ if (!strcmp(preferences.doc_viewer, DOCVIEWERNETSCAPEREMOTE))
+ {
+ xsane_show_doc_via_nsr(widget, data);
+ }
+ else
+ {
+ snprintf(buf, sizeof(buf), "%s/%s-doc.html", STRINGIFY(PATH_SANE_DATA_DIR), name);
+ arg[0] = preferences.doc_viewer;
+ arg[1] = buf;
+ arg[2] = 0;
+
+ pid = fork();
+
+ if (pid == 0) /* new process */
+ {
+ execvp(arg[0], arg); /* does not return if successfully */
+ fprintf(stderr, "%s %s\n", ERR_FAILD_EXEC_DOC_VIEWER, preferences.doc_viewer);
+ _exit(0); /* do not use exit() here! otherwise gtk gets in trouble */
+ }
+ }
+}
+
+/* ---------------------------------------------------------------------------------------------------------------------- */
+
+static void xsane_fax_entrys_swap(GtkWidget *list_item_1, GtkWidget *list_item_2)
+{
+ char *text1;
+ char *text2;
+
+ text1 = (char *) gtk_object_get_data(GTK_OBJECT(list_item_1), "list_item_data");
+ text2 = (char *) gtk_object_get_data(GTK_OBJECT(list_item_2), "list_item_data");
+
+ gtk_label_set(GTK_LABEL(gtk_container_children(GTK_CONTAINER(list_item_1))->data), text2);
+ gtk_label_set(GTK_LABEL(gtk_container_children(GTK_CONTAINER(list_item_2))->data), text1);
+ gtk_object_set_data(GTK_OBJECT(list_item_1), "list_item_data", text2);
+ gtk_object_set_data(GTK_OBJECT(list_item_2), "list_item_data", text1);
+}
+
+/* ---------------------------------------------------------------------------------------------------------------------- */
+
+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;
+
+ 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_fax_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;
+
+ 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_fax_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)
+{
+ 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 oldfile[256];
+ char newfile[256];
+
+ select = GTK_LIST(list)->selection;
+ if (select)
+ {
+ GtkWidget *rename_dialog;
+ GtkWidget *text;
+ GtkWidget *button;
+ GtkWidget *vbox, *hbox;
+ char buf[256];
+
+ list_item = select->data;
+ oldpage = strdup((char *) gtk_object_get_data(GTK_OBJECT(list_item), "list_item_data"));
+
+ xsane_set_sensitivity(FALSE);
+
+ rename_dialog = gtk_dialog_new();
+ gtk_window_set_position(GTK_WINDOW(rename_dialog), GTK_WIN_POS_CENTER);
+ gtk_window_set_policy(GTK_WINDOW(rename_dialog), FALSE, FALSE, FALSE);
+ snprintf(buf, sizeof(buf), "%s %s", prog_name, WINDOW_FAX_RENAME);
+ gtk_window_set_title(GTK_WINDOW(rename_dialog), buf);
+ gtk_signal_connect(GTK_OBJECT(rename_dialog), "delete_event", (GtkSignalFunc) xsane_fax_entry_rename_button_callback, (void *) -1);
+ gtk_widget_show(rename_dialog);
+
+ vbox = GTK_DIALOG(rename_dialog)->vbox;
+
+ text = gtk_entry_new_with_max_length(64);
+ xsane_back_gtk_set_tooltip(dialog->tooltips, text, DESC_FAXPAGENAME);
+ gtk_entry_set_text(GTK_ENTRY(text), oldpage);
+ gtk_widget_set_usize(text, 300, 0);
+ gtk_box_pack_start(GTK_BOX(vbox), text, TRUE, TRUE, 4);
+ gtk_widget_show(text);
+
+
+ hbox = GTK_DIALOG(rename_dialog)->action_area;
+
+ button = gtk_button_new_with_label("OK");
+ gtk_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);
+
+ button = gtk_button_new_with_label("Cancel");
+ gtk_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.ps", preferences.fax_project, oldpage);
+ snprintf(newfile, sizeof(newfile), "%s/%s.ps", preferences.fax_project, newpage);
+
+ rename(oldfile, newfile);
+
+ xsane_fax_project_save();
+ }
+
+ free(oldpage);
+ free(newpage);
+
+ gtk_widget_destroy(rename_dialog);
+
+ xsane_set_sensitivity(TRUE);
+ }
+}
+
+/* ---------------------------------------------------------------------------------------------------------------------- */
+
+static void xsane_fax_entry_delete_callback(GtkWidget *widget, gpointer list)
+{
+ GtkObject *list_item;
+ GList *select;
+ char *page;
+ char file[256];
+
+ 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"));
+ xsane_convert_text_to_filename(&page);
+ snprintf(file, sizeof(file), "%s/%s.ps", preferences.fax_project, page);
+ free(page);
+ remove(file);
+ 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;
+ pid_t pid;
+ char *arg[100];
+ char *page;
+ char buf[256];
+ int argnr;
+
+ select = GTK_LIST(list)->selection;
+ if (select)
+ {
+ argnr = xsane_parse_options(preferences.fax_viewer, arg);
+
+ list_item = GTK_OBJECT(select->data);
+ page = (char *) gtk_object_get_data(list_item, "list_item_data");
+ page = strdup(page);
+ xsane_convert_text_to_filename(&page);
+ snprintf(buf, sizeof(buf), "%s/%s.ps", preferences.fax_project, page);
+ free(page);
+ arg[argnr++] = buf;
+ arg[argnr] = 0;
+
+ pid = fork();
+
+ if (pid == 0) /* new process */
+ {
+ execvp(arg[0], arg); /* does not return if successfully */
+ fprintf(stderr, "%s %s\n", ERR_FAILD_EXEC_FAX_VIEWER, preferences.fax_viewer);
+ _exit(0); /* do not use exit() here! otherwise gtk gets in trouble */
+ }
+ }
+}
+
+/* ---------------------------------------------------------------------------------------------------------------------- */
+
+static void xsane_fax_send()
+{
+ char *page;
+ GList *list = (GList *) GTK_LIST(xsane.fax_list)->children;
+ GtkObject *list_item;
+ pid_t pid;
+ char *arg[1000];
+ char buf[256];
+ int argnr = 0;
+ int i;
+
+ 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;
+ }
+
+ argnr = xsane_parse_options(preferences.fax_command, arg);
+
+ if (xsane.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"));
+ xsane_convert_text_to_filename(&page);
+ snprintf(buf, sizeof(buf), "%s/%s.ps", preferences.fax_project, page);
+ free(page);
+ arg[argnr++] = strdup(buf);
+ list = list->next;
+ }
+
+ arg[argnr] = 0;
+
+ pid = fork();
+
+ if (pid == 0) /* new process */
+ {
+ execvp(arg[0], arg); /* does not return if successfully */
+ fprintf(stderr, "%s %s\n", ERR_FAILED_EXEC_FAX_CMD, preferences.fax_command);
+ _exit(0); /* do not use exit() here! otherwise gtk gets in trouble */
+ }
+
+ for (i=0; i<argnr; i++)
+ {
+ free(arg[i]);
+ }
+ }
+}
+
+/* ---------------------------------------------------------------------------------------------------------------------- */
+
+static GtkWidget *xsane_view_build_menu(void)
+{
+ GtkWidget *menu, *item;
+
+ menu = gtk_menu_new();
+
+
+ /* show tooltips */
+
+ item = gtk_check_menu_item_new_with_label(MENU_ITEM_SHOW_TOOLTIPS);
+ gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(item), preferences.tooltips_enabled);
+ gtk_menu_append(GTK_MENU(menu), item);
+ gtk_widget_show(item);
+ gtk_signal_connect(GTK_OBJECT(item), "toggled", (GtkSignalFunc) xsane_pref_toggle_tooltips, 0);
+
+
+ /* insert separator: */
+
+ item = gtk_menu_item_new();
+ gtk_menu_append(GTK_MENU(menu), item);
+ gtk_widget_show(item);
+
+
+ /* show preview */
+
+ xsane.show_preview_widget = gtk_check_menu_item_new_with_label(MENU_ITEM_SHOW_PREVIEW);
+ gtk_menu_append(GTK_MENU(menu), xsane.show_preview_widget);
+ gtk_widget_show(xsane.show_preview_widget);
+ gtk_signal_connect(GTK_OBJECT(xsane.show_preview_widget), "toggled", (GtkSignalFunc) xsane_show_preview_callback, 0);
+
+ /* show histogram */
+
+ xsane.show_histogram_widget = gtk_check_menu_item_new_with_label(MENU_ITEM_SHOW_HISTOGRAM);
+ gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(xsane.show_histogram_widget), preferences.show_histogram);
+ gtk_menu_append(GTK_MENU(menu), xsane.show_histogram_widget);
+ gtk_widget_show(xsane.show_histogram_widget);
+ gtk_signal_connect(GTK_OBJECT(xsane.show_histogram_widget), "toggled", (GtkSignalFunc) xsane_show_histogram_callback, 0);
+
+
+ /* show standard options */
+
+ xsane.show_standard_options_widget = gtk_check_menu_item_new_with_label(MENU_ITEM_SHOW_STANDARDOPTIONS);
+ gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(xsane.show_standard_options_widget), preferences.show_standard_options);
+ gtk_menu_append(GTK_MENU(menu), xsane.show_standard_options_widget);
+ gtk_widget_show(xsane.show_standard_options_widget);
+ gtk_signal_connect(GTK_OBJECT(xsane.show_standard_options_widget), "toggled", (GtkSignalFunc) xsane_show_standard_options_callback, 0);
+
+
+ /* show advanced options */
+
+ xsane.show_advanced_options_widget = gtk_check_menu_item_new_with_label(MENU_ITEM_SHOW_ADVANCEDOPTIONS);
+ gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(xsane.show_advanced_options_widget), preferences.show_advanced_options);
+ gtk_menu_append(GTK_MENU(menu), xsane.show_advanced_options_widget);
+ gtk_widget_show(xsane.show_advanced_options_widget);
+ gtk_signal_connect(GTK_OBJECT(xsane.show_advanced_options_widget), "toggled",
+ (GtkSignalFunc) xsane_show_advanced_options_callback, 0);
+
+ return menu;
+}
+
+/* ---------------------------------------------------------------------------------------------------------------------- */
+
+static GtkWidget *xsane_pref_build_menu(void)
+{
+ GtkWidget *menu, *item, *submenu, *subitem;
+
+ menu = gtk_menu_new();
+
+
+ /* XSane setup dialog */
+
+ item = gtk_menu_item_new_with_label(MENU_ITEM_SETUP);
+ gtk_menu_append(GTK_MENU(menu), item);
+ gtk_signal_connect(GTK_OBJECT(item), "activate", (GtkSignalFunc) xsane_setup_dialog, 0);
+ gtk_widget_show(item);
+
+ /* insert separator: */
+
+ item = gtk_menu_item_new();
+ gtk_menu_append(GTK_MENU(menu), item);
+ gtk_widget_show(item);
+
+
+#ifdef XSANE_TEST
+ /* XSane batch scan dialog */
+
+ item = gtk_menu_item_new_with_label("Batch scan");
+ gtk_menu_append(GTK_MENU(menu), item);
+ gtk_signal_connect(GTK_OBJECT(item), "activate", (GtkSignalFunc) xsane_batch_scan_dialog, 0);
+ gtk_widget_show(item);
+
+ /* insert separator: */
+
+ item = gtk_menu_item_new();
+ gtk_menu_append(GTK_MENU(menu), item);
+ gtk_widget_show(item);
+#endif
+
+
+ /* length unit */
+
+ item = gtk_menu_item_new_with_label(MENU_ITEM_LENGTH_UNIT);
+ gtk_menu_append(GTK_MENU(menu), item);
+ gtk_widget_show(item);
+
+ submenu = gtk_menu_new();
+
+ subitem = gtk_check_menu_item_new_with_label(SUBMENU_ITEM_LENGTH_MILLIMETERS);
+ gtk_menu_append(GTK_MENU(submenu), subitem);
+ if (preferences.length_unit == 1.0)
+ {
+ gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(subitem), TRUE);
+ }
+ gtk_signal_connect(GTK_OBJECT(subitem), "activate", (GtkSignalFunc) xsane_set_pref_unit_callback, "mm");
+ gtk_widget_show(subitem);
+ xsane.length_unit_mm = subitem;
+
+ subitem = gtk_check_menu_item_new_with_label(SUBMENU_ITEM_LENGTH_CENTIMETERS);
+ gtk_menu_append(GTK_MENU(submenu), subitem);
+ if (preferences.length_unit == 10.0)
+ {
+ gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(subitem), TRUE);
+ }
+ gtk_signal_connect(GTK_OBJECT(subitem), "activate", (GtkSignalFunc) xsane_set_pref_unit_callback, "cm");
+ gtk_widget_show(subitem);
+ xsane.length_unit_cm = subitem;
+
+ subitem = gtk_check_menu_item_new_with_label(SUBMENU_ITEM_LENGTH_INCHES);
+ gtk_menu_append(GTK_MENU(submenu), subitem);
+ if (preferences.length_unit == 25.4)
+ {
+ gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(subitem), TRUE);
+ }
+ gtk_signal_connect(GTK_OBJECT(subitem), "activate", (GtkSignalFunc) xsane_set_pref_unit_callback, "in");
+ gtk_widget_show(subitem);
+ xsane.length_unit_in = subitem;
+
+ gtk_menu_item_set_submenu(GTK_MENU_ITEM(item), submenu);
+
+ xsane.length_unit_widget = item;
+
+
+ /* insert separator: */
+
+ item = gtk_menu_item_new();
+ gtk_menu_append(GTK_MENU(menu), item);
+ gtk_widget_show(item);
+
+ /* update policy */
+
+ item = gtk_menu_item_new_with_label(MENU_ITEM_UPDATE_POLICY);
+ gtk_menu_append(GTK_MENU(menu), item);
+ gtk_widget_show(item);
+
+ submenu = gtk_menu_new();
+
+ subitem = gtk_check_menu_item_new_with_label(SUBMENU_ITEM_POLICY_CONTINUOUS);
+ gtk_menu_append(GTK_MENU(submenu), subitem);
+ if (preferences.gtk_update_policy == GTK_UPDATE_CONTINUOUS)
+ {
+ gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(subitem), TRUE);
+ }
+ gtk_signal_connect(GTK_OBJECT(subitem), "activate", (GtkSignalFunc) xsane_set_update_policy_callback, (void *) GTK_UPDATE_CONTINUOUS);
+ gtk_widget_show(subitem);
+ xsane.update_policy_continu = subitem;
+
+ subitem = gtk_check_menu_item_new_with_label(SUBMENU_ITEM_POLICY_DISCONTINU);
+ gtk_menu_append(GTK_MENU(submenu), subitem);
+ if (preferences.gtk_update_policy == GTK_UPDATE_DISCONTINUOUS)
+ {
+ gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(subitem), TRUE);
+ }
+ gtk_signal_connect(GTK_OBJECT(subitem), "activate", (GtkSignalFunc) xsane_set_update_policy_callback, (void *) GTK_UPDATE_DISCONTINUOUS);
+ gtk_widget_show(subitem);
+ xsane.update_policy_discont = subitem;
+
+ subitem = gtk_check_menu_item_new_with_label(SUBMENU_ITEM_POLICY_DELAYED);
+ gtk_menu_append(GTK_MENU(submenu), subitem);
+ if (preferences.gtk_update_policy == GTK_UPDATE_DELAYED)
+ {
+ gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(subitem), TRUE);
+ }
+ gtk_signal_connect(GTK_OBJECT(subitem), "activate", (GtkSignalFunc) xsane_set_update_policy_callback, (void *) GTK_UPDATE_DELAYED);
+ gtk_widget_show(subitem);
+ xsane.update_policy_delayed = subitem;
+
+ gtk_menu_item_set_submenu(GTK_MENU_ITEM(item), submenu);
+
+
+ /* insert separator: */
+
+ item = gtk_menu_item_new();
+ gtk_menu_append(GTK_MENU(menu), item);
+ gtk_widget_show(item);
+
+
+ /* show resolution list */
+
+ xsane.show_resolution_list_widget = gtk_check_menu_item_new_with_label(MENU_ITEM_SHOW_RESOLUTIONLIST);
+ 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_show(xsane.show_resolution_list_widget);
+ gtk_signal_connect(GTK_OBJECT(xsane.show_resolution_list_widget), "toggled",
+ (GtkSignalFunc) xsane_show_resolution_list_callback, 0);
+
+
+ /* insert separator: */
+
+ item = gtk_menu_item_new();
+ gtk_menu_append(GTK_MENU(menu), item);
+ gtk_widget_show(item);
+
+
+ /* page orientation */
+
+ item = gtk_check_menu_item_new_with_label(MENU_ITEM_PAGE_ROTATE);
+ gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(item), preferences.psrotate);
+ gtk_menu_append(GTK_MENU(menu), item);
+ gtk_widget_show(item);
+ gtk_signal_connect(GTK_OBJECT(item), "toggled", (GtkSignalFunc) xsane_page_rotate_callback, 0);
+
+
+
+ /* insert separator: */
+
+ item = gtk_menu_item_new();
+ gtk_menu_append(GTK_MENU(menu), item);
+ gtk_widget_show(item);
+
+ /* Save device setting */
+
+ item = gtk_menu_item_new_with_label(MENU_ITEM_SAVE_DEVICE_SETTINGS);
+ gtk_menu_append(GTK_MENU(menu), item);
+ gtk_signal_connect(GTK_OBJECT(item), "activate", (GtkSignalFunc) xsane_device_preferences_save, 0);
+ gtk_widget_show(item);
+
+ /* Load device setting */
+
+ item = gtk_menu_item_new_with_label(MENU_ITEM_LOAD_DEVICE_SETTINGS);
+ gtk_menu_append(GTK_MENU(menu), item);
+ gtk_signal_connect(GTK_OBJECT(item), "activate", (GtkSignalFunc) xsane_device_preferences_load, 0);
+ gtk_widget_show(item);
+
+ return menu;
+}
+
+/* ---------------------------------------------------------------------------------------------------------------------- */
+
+static GtkWidget *xsane_help_build_menu(void)
+{
+ GtkWidget *menu, *item;
+
+ menu = gtk_menu_new();
+
+ item = gtk_menu_item_new_with_label(MENU_ITEM_XSANE_DOC);
+ gtk_menu_append(GTK_MENU(menu), item);
+ gtk_signal_connect(GTK_OBJECT(item), "activate", (GtkSignalFunc) xsane_show_doc, (void *) "sane-xsane");
+ gtk_widget_show(item);
+
+ item = gtk_menu_item_new();
+ gtk_menu_append(GTK_MENU(menu), item);
+ gtk_widget_show(item);
+
+ if (xsane.backend)
+ {
+ item = gtk_menu_item_new_with_label(MENU_ITEM_BACKEND_DOC);
+ gtk_menu_append(GTK_MENU(menu), item);
+ gtk_signal_connect(GTK_OBJECT(item), "activate", (GtkSignalFunc) xsane_show_doc, (void *) xsane.backend);
+ gtk_widget_show(item);
+ }
+
+ item = gtk_menu_item_new_with_label(MENU_ITEM_AVAILABLE_BACKENDS);
+ gtk_menu_append(GTK_MENU(menu), item);
+ gtk_signal_connect(GTK_OBJECT(item), "activate", (GtkSignalFunc) xsane_show_doc, (void *) "sane-backends");
+ gtk_widget_show(item);
+
+ item = gtk_menu_item_new_with_label(MENU_ITEM_PROBLEMS);
+ gtk_menu_append(GTK_MENU(menu), item);
+ gtk_signal_connect(GTK_OBJECT(item), "activate", (GtkSignalFunc) xsane_show_doc, (void *) "sane-problems");
+ gtk_widget_show(item);
+
+ item = gtk_menu_item_new();
+ gtk_menu_append(GTK_MENU(menu), item);
+ gtk_widget_show(item);
+
+ item = gtk_menu_item_new_with_label(MENU_ITEM_SCANTIPS);
+ gtk_menu_append(GTK_MENU(menu), item);
+ gtk_signal_connect(GTK_OBJECT(item), "activate", (GtkSignalFunc) xsane_show_doc, (void *) "sane-scantips");
+ gtk_widget_show(item);
+
+ return menu;
+}
+
+/* ---------------------------------------------------------------------------------------------------------------------- */
+
+void xsane_panel_build(GSGDialog *dialog)
+{
+ GtkWidget *xsane_hbox;
+ GtkWidget *standard_hbox, *standard_vbox;
+ GtkWidget *advanced_hbox, *advanced_vbox;
+ GtkWidget *parent, *vbox, *button, *label;
+ const SANE_Option_Descriptor *opt;
+ SANE_Handle dev = dialog->dev;
+ double dval, dmin, dmax, dquant;
+ char *buf, str[16], title[256];
+ GSGDialogElement *elem;
+ SANE_Word quant, val;
+ SANE_Status status;
+ SANE_Int num_words;
+ char **str_list;
+ int i, j;
+ int num_vector_opts = 0;
+ int *vector_opts;
+
+ xsane_hbox = 0;
+
+ /* reset well-known options: */
+ dialog->well_known.scanmode = -1;
+ dialog->well_known.scansource = -1;
+ dialog->well_known.preview = -1;
+ dialog->well_known.dpi = -1;
+ dialog->well_known.dpi_x = -1;
+ dialog->well_known.dpi_y = -1;
+ dialog->well_known.coord[xsane_back_gtk_TL_X] = -1;
+ dialog->well_known.coord[xsane_back_gtk_TL_Y] = -1;
+ dialog->well_known.coord[xsane_back_gtk_BR_X] = -1;
+ dialog->well_known.coord[xsane_back_gtk_BR_Y] = -1;
+ dialog->well_known.gamma_vector = -1;
+ dialog->well_known.gamma_vector_r = -1;
+ dialog->well_known.gamma_vector_g = -1;
+ dialog->well_known.gamma_vector_b = -1;
+ dialog->well_known.bit_depth = -1;
+
+
+ /* standard options */
+ standard_hbox = gtk_hbox_new(FALSE, 2);
+ gtk_widget_show(standard_hbox);
+ standard_vbox = gtk_vbox_new(/* homogeneous */ FALSE, 0);
+ gtk_widget_show(standard_vbox);
+/* gtk_box_pack_start(GTK_BOX(standard_hbox), standard_vbox, FALSE, FALSE, 0); */ /* make frame fixed */
+ gtk_box_pack_start(GTK_BOX(standard_hbox), standard_vbox, TRUE, TRUE, 0); /* make frame sizeable */
+
+ /* advanced options */
+ advanced_hbox = gtk_hbox_new(FALSE, 2);
+ gtk_widget_show(advanced_hbox);
+ advanced_vbox = gtk_vbox_new(/* homogeneous */ FALSE, 0);
+ gtk_widget_show(advanced_vbox);
+/* gtk_box_pack_start(GTK_BOX(advanced_hbox), advanced_vbox, FALSE, FALSE, 0); */ /* make frame fixed */
+ gtk_box_pack_start(GTK_BOX(advanced_hbox), advanced_vbox, TRUE, TRUE, 0); /* make frame sizeable */
+
+
+ vector_opts = alloca(dialog->num_elements * sizeof (int));
+
+ parent = standard_vbox;
+ for (i = 1; i < dialog->num_elements; ++i)
+ {
+ opt = sane_get_option_descriptor (dev, i);
+ if (!SANE_OPTION_IS_ACTIVE(opt->cap))
+ continue;
+
+ /* pick up well-known options as we go: */
+ if (opt->name)
+ {
+ if (strcmp(opt->name, SANE_NAME_PREVIEW) == 0 && opt->type == SANE_TYPE_BOOL)
+ {
+ dialog->well_known.preview = i;
+ continue;
+ }
+ else if (strcmp(opt->name, SANE_NAME_SCAN_RESOLUTION) == 0
+ && opt->unit == SANE_UNIT_DPI && (opt->type == SANE_TYPE_INT || opt->type == SANE_TYPE_FIXED))
+ dialog->well_known.dpi = i;
+ else if (strcmp(opt->name, SANE_NAME_SCAN_X_RESOLUTION) == 0
+ && opt->unit == SANE_UNIT_DPI && (opt->type == SANE_TYPE_INT || opt->type == SANE_TYPE_FIXED))
+ dialog->well_known.dpi_x = i;
+ else if (strcmp(opt->name, SANE_NAME_SCAN_Y_RESOLUTION) == 0
+ && opt->unit == SANE_UNIT_DPI && (opt->type == SANE_TYPE_INT || opt->type == SANE_TYPE_FIXED))
+ dialog->well_known.dpi_y = i;
+ else if (strcmp (opt->name, SANE_NAME_SCAN_MODE) == 0)
+ dialog->well_known.scanmode = i;
+ else if (strcmp (opt->name, SANE_NAME_SCAN_SOURCE) == 0)
+ dialog->well_known.scansource = i;
+ else if (strcmp (opt->name, SANE_NAME_SCAN_TL_X) == 0)
+ dialog->well_known.coord[xsane_back_gtk_TL_X] = i;
+ else if (strcmp (opt->name, SANE_NAME_SCAN_TL_Y) == 0)
+ dialog->well_known.coord[xsane_back_gtk_TL_Y] = i;
+ else if (strcmp (opt->name, SANE_NAME_SCAN_BR_X) == 0)
+ dialog->well_known.coord[xsane_back_gtk_BR_X] = i;
+ else if (strcmp (opt->name, SANE_NAME_SCAN_BR_Y) == 0)
+ dialog->well_known.coord[xsane_back_gtk_BR_Y] = i;
+ else if (strcmp (opt->name, SANE_NAME_GAMMA_VECTOR) == 0)
+ dialog->well_known.gamma_vector = i;
+ else if (strcmp (opt->name, SANE_NAME_GAMMA_VECTOR_R) == 0)
+ dialog->well_known.gamma_vector_r = i;
+ else if (strcmp (opt->name, SANE_NAME_GAMMA_VECTOR_G) == 0)
+ dialog->well_known.gamma_vector_g = i;
+ else if (strcmp (opt->name, SANE_NAME_GAMMA_VECTOR_B) == 0)
+ dialog->well_known.gamma_vector_b = i;
+ else if (strcmp (opt->name, SANE_NAME_BIT_DEPTH) == 0)
+ dialog->well_known.bit_depth = i;
+ }
+
+ elem = dialog->element + i;
+ elem->dialog = dialog;
+
+
+ if (opt->unit == SANE_UNIT_NONE)
+ {
+ snprintf(title, sizeof(title), "%s", _BGT(opt->title));
+ }
+ else
+ {
+ snprintf(title, sizeof(title), "%s [%s]", _BGT(opt->title), xsane_back_gtk_unit_string(opt->unit));
+ }
+
+ switch (opt->type)
+ {
+ case SANE_TYPE_GROUP:
+ /* group a set of options */
+ vbox = standard_vbox;
+ if (opt->cap & SANE_CAP_ADVANCED)
+ {
+ vbox = advanced_vbox;
+ }
+ parent = xsane_back_gtk_group_new(vbox, title);
+ elem->widget = parent;
+ break;
+
+ case SANE_TYPE_BOOL:
+ assert(opt->size == sizeof(SANE_Word));
+ status = sane_control_option(dialog->dev, i, SANE_ACTION_GET_VALUE, &val, 0);
+ if (status != SANE_STATUS_GOOD)
+ {
+ goto get_value_failed;
+ }
+ xsane_back_gtk_button_new(parent, title, val, elem, dialog->tooltips, _BGT(opt->desc), SANE_OPTION_IS_SETTABLE(opt->cap));
+ gtk_widget_show(parent->parent);
+ break;
+
+ case SANE_TYPE_INT:
+ if (opt->size != sizeof(SANE_Word))
+ {
+ vector_opts[num_vector_opts++] = i;
+ break;
+ }
+ status = sane_control_option(dialog->dev, i, SANE_ACTION_GET_VALUE, &val, 0);
+ if (status != SANE_STATUS_GOOD)
+ {
+ goto get_value_failed;
+ }
+
+ switch (opt->constraint_type)
+ {
+ case SANE_CONSTRAINT_RANGE:
+ if ( (strcmp(opt->name, SANE_NAME_SCAN_RESOLUTION) ) && /* do not show resolution */
+ (strcmp(opt->name, SANE_NAME_SCAN_X_RESOLUTION)) && /* do not show x-resolution */
+ (strcmp(opt->name, SANE_NAME_SCAN_Y_RESOLUTION)) ) /* do not show y-resolution */
+ {
+ /* use a scale */
+ quant = opt->constraint.range->quant;
+ if (quant == 0)
+ quant = 1;
+ xsane_back_gtk_scale_new(parent, title, val, opt->constraint.range->min, opt->constraint.range->max, quant,
+ (opt->cap & SANE_CAP_AUTOMATIC), elem, dialog->tooltips, _BGT(opt->desc), SANE_OPTION_IS_SETTABLE(opt->cap));
+ gtk_widget_show(parent->parent);
+ }
+ break;
+
+ case SANE_CONSTRAINT_WORD_LIST:
+ if ( (strcmp(opt->name, SANE_NAME_SCAN_RESOLUTION) ) && /* do not show resolution */
+ (strcmp(opt->name, SANE_NAME_SCAN_X_RESOLUTION)) && /* do not show x-resolution */
+ (strcmp(opt->name, SANE_NAME_SCAN_Y_RESOLUTION)) ) /* do not show y-resolution */
+ {
+ /* use a "list-selection" widget */
+ num_words = opt->constraint.word_list[0];
+ str_list = malloc((num_words + 1) * sizeof(str_list[0]));
+ for (j = 0; j < num_words; ++j)
+ {
+ sprintf(str, "%d", opt->constraint.word_list[j + 1]);
+ str_list[j] = strdup(str);
+ }
+ str_list[j] = 0;
+ sprintf(str, "%d", val);
+ xsane_back_gtk_option_menu_new(parent, title, str_list, str, elem, dialog->tooltips, _BGT(opt->desc),
+ SANE_OPTION_IS_SETTABLE(opt->cap));
+ free(str_list);
+ gtk_widget_show(parent->parent);
+ }
+ break;
+
+ default:
+ fprintf(stderr, "xsane_panel_build: %s %d!\n", ERR_UNKNOWN_CONSTRAINT_TYPE, opt->constraint_type);
+ break;
+ }
+ break;
+
+ case SANE_TYPE_FIXED:
+ if (opt->size != sizeof (SANE_Word))
+ {
+ vector_opts[num_vector_opts++] = i;
+ break;
+ }
+ status = sane_control_option(dialog->dev, i, SANE_ACTION_GET_VALUE, &val, 0);
+ if (status != SANE_STATUS_GOOD)
+ {
+ goto get_value_failed;
+ }
+
+ switch (opt->constraint_type)
+ {
+ case SANE_CONSTRAINT_RANGE:
+ if ( (strcmp(opt->name, SANE_NAME_SCAN_RESOLUTION) ) && /* do not show resolution */
+ (strcmp(opt->name, SANE_NAME_SCAN_X_RESOLUTION)) && /* do not show x-resolution */
+ (strcmp(opt->name, SANE_NAME_SCAN_Y_RESOLUTION)) ) /* do not show y-resolution */
+ {
+ /* use a scale */
+ quant = opt->constraint.range->quant;
+ if (quant == 0)
+ quant = 1;
+ dval = SANE_UNFIX(val);
+ dmin = SANE_UNFIX(opt->constraint.range->min);
+ dmax = SANE_UNFIX(opt->constraint.range->max);
+ dquant = SANE_UNFIX(quant);
+ if (opt->unit == SANE_UNIT_MM)
+ {
+ dval /= preferences.length_unit;
+ dmin /= preferences.length_unit;
+ dmax /= preferences.length_unit;
+ dquant /= preferences.length_unit;
+ }
+ xsane_back_gtk_scale_new(parent, title, dval, dmin, dmax, dquant, (opt->cap & SANE_CAP_AUTOMATIC), elem,
+ dialog->tooltips, _BGT(opt->desc), SANE_OPTION_IS_SETTABLE(opt->cap));
+ gtk_widget_show(parent->parent);
+ }
+ break;
+
+ case SANE_CONSTRAINT_WORD_LIST:
+ if ( (strcmp(opt->name, SANE_NAME_SCAN_RESOLUTION) ) && /* do not show resolution */
+ (strcmp(opt->name, SANE_NAME_SCAN_X_RESOLUTION)) && /* do not show x-resolution */
+ (strcmp(opt->name, SANE_NAME_SCAN_Y_RESOLUTION)) ) /* do not show y-resolution */
+ {
+ /* use a "list-selection" widget */
+ num_words = opt->constraint.word_list[0];
+ str_list = malloc ((num_words + 1) * sizeof (str_list[0]));
+ for (j = 0; j < num_words; ++j)
+ {
+ sprintf(str, "%g", SANE_UNFIX(opt->constraint.word_list[j + 1]));
+ str_list[j] = strdup (str);
+ }
+ str_list[j] = 0;
+ sprintf(str, "%g", SANE_UNFIX (val));
+ xsane_back_gtk_option_menu_new(parent, title, str_list, str, elem, dialog->tooltips, _BGT(opt->desc), SANE_OPTION_IS_SETTABLE(opt->cap));
+ free (str_list);
+ gtk_widget_show(parent->parent);
+ }
+ break;
+
+ default:
+ fprintf(stderr, "xsane_panel_build: %s %d!\n", ERR_UNKNOWN_CONSTRAINT_TYPE, opt->constraint_type);
+ break;
+ }
+ break;
+
+ case SANE_TYPE_STRING:
+ buf = malloc (opt->size);
+ status = sane_control_option(dialog->dev, i, SANE_ACTION_GET_VALUE, buf, 0);
+ if (status != SANE_STATUS_GOOD)
+ {
+ free (buf);
+ goto get_value_failed;
+ }
+
+ switch (opt->constraint_type)
+ {
+ case SANE_CONSTRAINT_STRING_LIST:
+ if ( (strcmp (opt->name, SANE_NAME_SCAN_MODE) != 0) && /* do not show scanmode */
+ (strcmp (opt->name, SANE_NAME_SCAN_SOURCE) != 0) ) /* do not show scansource */
+ {
+ /* use a "list-selection" widget */
+ xsane_back_gtk_option_menu_new(parent, title, (char **) opt->constraint.string_list, buf,
+ elem, dialog->tooltips, _BGT(opt->desc), SANE_OPTION_IS_SETTABLE(opt->cap));
+ gtk_widget_show (parent->parent);
+ }
+ break;
+
+ case SANE_CONSTRAINT_NONE:
+ xsane_back_gtk_text_entry_new(parent, title, buf, elem, dialog->tooltips, _BGT(opt->desc), SANE_OPTION_IS_SETTABLE(opt->cap));
+ gtk_widget_show (parent->parent);
+ break;
+
+ default:
+ fprintf(stderr, "xsane_panel_build: %s %d!\n", ERR_UNKNOWN_CONSTRAINT_TYPE, opt->constraint_type);
+ break;
+ }
+ free (buf);
+ break;
+
+ case SANE_TYPE_BUTTON:
+ button = gtk_button_new();
+ gtk_signal_connect(GTK_OBJECT (button), "clicked", (GtkSignalFunc) xsane_back_gtk_push_button_callback, elem);
+ xsane_back_gtk_set_tooltip(dialog->tooltips, button, _BGT(opt->desc));
+
+ label = gtk_label_new(title);
+ gtk_container_add(GTK_CONTAINER (button), label);
+
+ gtk_box_pack_start(GTK_BOX (parent), button, FALSE, TRUE, 0);
+
+ gtk_widget_show(label);
+ gtk_widget_show(button);
+
+ gtk_widget_set_sensitive(button, SANE_OPTION_IS_SETTABLE(opt->cap));
+
+ elem->widget = button;
+ gtk_widget_show(parent->parent);
+ break;
+
+ default:
+ fprintf(stderr, "xsane_panel_build: %s %d\n", ERR_UNKNOWN_TYPE, opt->type);
+ break;
+ }
+ continue;
+
+ get_value_failed:
+ {
+ char msg[256];
+
+ sprintf(msg, "%s %s: %s.", ERR_GET_OPTION, opt->name, XSANE_STRSTATUS(status));
+ xsane_back_gtk_error(msg, TRUE);
+ }
+ }
+
+ if ((dialog->well_known.dpi_x == -1) && (dialog->well_known.dpi_y != -1))
+ {
+ dialog->well_known.dpi_x = dialog->well_known.dpi;
+ }
+
+ xsane_hbox = xsane_update_xsane_callback();
+
+ gtk_container_add(GTK_CONTAINER(dialog->xsane_window), xsane_hbox);
+ gtk_container_add(GTK_CONTAINER(dialog->standard_window), standard_hbox);
+ gtk_container_add(GTK_CONTAINER(dialog->advanced_window), advanced_hbox);
+
+ dialog->xsane_hbox = xsane_hbox;
+ dialog->standard_hbox = standard_hbox;
+ dialog->advanced_hbox = advanced_hbox;
+
+ xsane_update_histogram();
+/*
+ xsane_draw_slider_level(&xsane.slider_gray);
+ xsane_draw_slider_level(&xsane.slider_red);
+ xsane_draw_slider_level(&xsane.slider_green);
+ xsane_draw_slider_level(&xsane.slider_blue);
+*/
+ xsane_update_sliders();
+
+ if (xsane.length_unit_widget)
+ {
+ int unit;
+
+ status = xsane_get_area_value(dialog->well_known.coord[0], 0, &unit);
+
+ if ( (unit == SANE_UNIT_PIXEL) || (status) )
+ {
+ gtk_widget_set_sensitive(xsane.length_unit_widget, FALSE);
+ }
+ else
+ {
+ gtk_widget_set_sensitive(xsane.length_unit_widget, TRUE);
+ }
+ }
+
+ /* now add in vector editor, if necessary: */
+/*
+ if (num_vector_opts)
+ vector_new (dialog, custom_gamma_vbox, num_vector_opts, vector_opts);
+*/
+}
+
+/* ---------------------------------------------------------------------------------------------------------------------- */
+
+/* Create the main dialog box. */
+
+static void xsane_device_dialog(void)
+{
+ GtkWidget *hbox, *button, *frame, *infobox;
+ GtkWidget *main_dialog_window, *standard_dialog_window, *advanced_dialog_window;
+ GtkWidget *menubar, *menubar_item;
+ const gchar *devname;
+ char buf[256];
+ char windowname[255];
+ char devicetext[255];
+ char *textptr;
+ GtkWidget *xsane_window;
+ GtkWidget *xsane_vbox_main;
+ GtkWidget *xsane_vbox_standard;
+ GtkWidget *xsane_vbox_advanced;
+ GdkColormap *colormap;
+ SANE_Int num_elements;
+ SANE_Status status;
+ SANE_Handle dev;
+
+
+ devname = devlist[seldev]->name;
+
+ status = sane_open(devname, &dev);
+ if (status != SANE_STATUS_GOOD)
+ {
+ snprintf(buf, sizeof(buf), "%s `%s':\n %s.", ERR_DEVICE_OPEN_FAILED, devname, XSANE_STRSTATUS(status));
+ xsane_back_gtk_error(buf, TRUE);
+ return;
+ }
+
+ if (sane_control_option(dev, 0, SANE_ACTION_GET_VALUE, &num_elements, 0) != SANE_STATUS_GOOD)
+ {
+ xsane_back_gtk_error(ERR_OPTION_COUNT, TRUE);
+ sane_close(dev);
+ return;
+ }
+
+ snprintf(buf, sizeof(buf), "%s", devlist[seldev]->name); /* generate "sane-BACKENDNAME" */
+ textptr = strrchr(buf, ':'); /* format is midend:midend:midend:backend:device or backend:device */
+ if (textptr)
+ {
+ *textptr = 0; /* erase ":device" at end of text */
+ textptr = strrchr(buf, ':');
+ if (textptr) /* midend:backend:device */
+ {
+ textptr++;
+ }
+ else /* backend:device */
+ {
+ textptr = buf;
+ }
+
+ xsane.backend = malloc(strlen(textptr)+6);
+ sprintf(xsane.backend, "sane-%s", textptr); /* add "sane-" */
+
+ bindtextdomain(xsane.backend, LOCALEDIR); /* set path for backend translation texts */
+ }
+
+ /* create device-text for window titles */
+
+ snprintf(devicetext, sizeof(devicetext), "%s", devlist[seldev]->model);
+ textptr = devicetext + strlen(devicetext);
+ while (*(textptr-1) == ' ') /* erase spaces at end of text */
+ {
+ textptr--;
+ }
+
+ *textptr = ':';
+ textptr++;
+ *textptr = 0;
+
+ if (!strncmp(devname, "net:", 4)) /* network device ? */
+ {
+ sprintf(textptr, "net:");
+ textptr = devicetext + strlen(devicetext);
+ }
+
+ snprintf(buf, sizeof(buf), ":%s", devname);
+ snprintf(buf, sizeof(buf), "/%s", (strrchr(buf, ':')+1));
+ sprintf(textptr, (strrchr(buf, '/')+1));
+
+ device_text = strdup(devicetext);
+
+
+ /* if no preferences filename is given on commandline create one from devicenaname */
+
+ if (!xsane.device_set_filename)
+ {
+ if (!strcmp(devlist[seldev]->vendor, TEXT_UNKNOWN))
+ {
+ snprintf(buf, sizeof(buf), "%s", devlist[seldev]->name);
+ }
+ else
+ {
+ snprintf(buf, sizeof(buf), "%s:%s", devlist[seldev]->vendor, devlist[seldev]->model);
+ }
+ xsane.device_set_filename = strdup(buf); /* set preferences filename */
+ }
+
+
+ xsane_pref_restore(); /* restore preferences */
+
+ if (xsane.main_window_fixed == -1) /* no command line option given */
+ {
+ xsane.main_window_fixed = preferences.main_window_fixed;
+ }
+
+
+ /* create the xsane dialog box */
+
+ xsane.shell = gtk_dialog_new();
+ gtk_widget_set_uposition(xsane.shell, XSANE_SHELL_POS_X, XSANE_SHELL_POS_Y);
+ sprintf(windowname, "%s %s %s", prog_name, XSANE_VERSION, device_text);
+ gtk_window_set_title(GTK_WINDOW(xsane.shell), (char *) windowname);
+ gtk_signal_connect(GTK_OBJECT(xsane.shell), "delete_event", GTK_SIGNAL_FUNC(xsane_scan_win_delete), 0);
+
+ xsane_set_window_icon(xsane.shell, 0);
+
+ /* set the main vbox */
+
+ xsane_window = GTK_DIALOG(xsane.shell)->vbox;
+ gtk_widget_show(xsane_window); /* normally not necessary, but to be sure */
+
+ /* create the menubar */
+
+ menubar = gtk_menu_bar_new();
+ gtk_box_pack_start(GTK_BOX(xsane_window), menubar, FALSE, FALSE, 0);
+
+ /* "Files" submenu: */
+ menubar_item = gtk_menu_item_new_with_label(MENU_FILE);
+ gtk_container_add(GTK_CONTAINER(menubar), menubar_item);
+ gtk_menu_item_set_submenu(GTK_MENU_ITEM(menubar_item), xsane_files_build_menu());
+ gtk_widget_show(menubar_item);
+
+ /* "Preferences" submenu: */
+ menubar_item = gtk_menu_item_new_with_label(MENU_PREFERENCES);
+ gtk_container_add(GTK_CONTAINER(menubar), menubar_item);
+ gtk_menu_item_set_submenu(GTK_MENU_ITEM(menubar_item), xsane_pref_build_menu());
+ gtk_widget_show(menubar_item);
+
+ /* "View" submenu: */
+ menubar_item = gtk_menu_item_new_with_label(MENU_VIEW);
+ gtk_container_add(GTK_CONTAINER(menubar), menubar_item);
+ gtk_menu_item_set_submenu(GTK_MENU_ITEM(menubar_item), xsane_view_build_menu());
+ gtk_widget_show(menubar_item);
+
+
+ /* "Help" submenu: */
+ menubar_item = gtk_menu_item_new_with_label(MENU_HELP);
+ gtk_container_add(GTK_CONTAINER(menubar), menubar_item);
+ gtk_menu_item_right_justify((GtkMenuItem *) menubar_item);
+ gtk_menu_item_set_submenu(GTK_MENU_ITEM(menubar_item), xsane_help_build_menu());
+ gtk_widget_show(menubar_item);
+
+ gtk_widget_show(menubar);
+
+ if (xsane.main_window_fixed) /* fixed window: use it like it is */
+ {
+ /* shrink grow auto_shrink */
+ gtk_window_set_policy(GTK_WINDOW(xsane.shell), FALSE, FALSE, TRUE); /* auto size */
+
+ 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);
+ gtk_container_add(GTK_CONTAINER(xsane_window), xsane_vbox_main);
+ }
+ 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 */
+
+ /* shrink grow auto_shrink */
+ gtk_window_set_policy(GTK_WINDOW(xsane.shell), TRUE, TRUE, FALSE); /* 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);
+
+ gtk_container_add(GTK_CONTAINER(xsane_window), xsane.main_dialog_scrolled);
+ gtk_widget_show(xsane.main_dialog_scrolled);
+
+ xsane_vbox_main = gtk_vbox_new(TRUE, 5);
+ gtk_container_set_border_width(GTK_CONTAINER(xsane_vbox_main), 5);
+ gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(xsane.main_dialog_scrolled), xsane_vbox_main);
+ }
+
+ /* create a subwindow so the standard dialog keeps its position on rebuilds: */
+ main_dialog_window = gtk_hbox_new(/* homogeneous */ FALSE, 0);
+ gtk_box_pack_start(GTK_BOX(xsane_vbox_main), main_dialog_window, TRUE, TRUE, 0);
+ gtk_widget_show(main_dialog_window);
+
+ gtk_widget_show(xsane_vbox_main);
+
+
+ /* create the scanner standard options dialog box */
+
+ xsane.standard_options_shell = gtk_window_new(GTK_WINDOW_DIALOG);
+ gtk_widget_set_uposition(xsane.standard_options_shell, XSANE_STD_OPTIONS_POS_X, XSANE_STD_OPTIONS_POS_Y);
+ sprintf(windowname, "%s %s", WINDOW_STANDARD_OPTIONS, device_text);
+ gtk_window_set_title(GTK_WINDOW(xsane.standard_options_shell), (char *) windowname);
+
+ /* shrink grow auto_shrink */
+ gtk_window_set_policy(GTK_WINDOW(xsane.standard_options_shell), FALSE, FALSE, TRUE);
+ gtk_signal_connect(GTK_OBJECT(xsane.standard_options_shell), "delete_event",
+ GTK_SIGNAL_FUNC(xsane_standard_option_win_delete), 0);
+
+ xsane_set_window_icon(xsane.standard_options_shell, 0);
+
+ xsane_vbox_standard = gtk_vbox_new(TRUE, 5);
+ gtk_container_set_border_width(GTK_CONTAINER(xsane_vbox_standard), 5);
+ gtk_container_add(GTK_CONTAINER(xsane.standard_options_shell), xsane_vbox_standard);
+ gtk_widget_show(xsane_vbox_standard);
+
+ /* create a subwindow so the standard dialog keeps its position on rebuilds: */
+ standard_dialog_window = gtk_hbox_new(/* homogeneous */ FALSE, 0);
+ gtk_box_pack_start(GTK_BOX(xsane_vbox_standard), standard_dialog_window, TRUE, TRUE, 0);
+ gtk_widget_show(standard_dialog_window);
+
+
+
+ /* create the scanner advanced options dialog box */
+
+ xsane.advanced_options_shell = gtk_window_new(GTK_WINDOW_DIALOG);
+ gtk_widget_set_uposition(xsane.advanced_options_shell, XSANE_ADV_OPTIONS_POS_X, XSANE_ADV_OPTIONS_POS_Y);
+ sprintf(windowname, "%s %s",WINDOW_ADVANCED_OPTIONS, device_text);
+ gtk_window_set_title(GTK_WINDOW(xsane.advanced_options_shell), (char *) windowname);
+
+ /* shrink grow auto_shrink */
+ gtk_window_set_policy(GTK_WINDOW(xsane.advanced_options_shell), FALSE, FALSE, TRUE);
+ gtk_signal_connect(GTK_OBJECT(xsane.advanced_options_shell), "delete_event",
+ GTK_SIGNAL_FUNC(xsane_advanced_option_win_delete), 0);
+
+ xsane_set_window_icon(xsane.advanced_options_shell, 0);
+
+ xsane_vbox_advanced = gtk_vbox_new(TRUE, 5);
+ gtk_container_set_border_width(GTK_CONTAINER(xsane_vbox_advanced), 5);
+ gtk_container_add(GTK_CONTAINER(xsane.advanced_options_shell), xsane_vbox_advanced);
+ gtk_widget_show(xsane_vbox_advanced);
+
+ /* create a subwindow so the advanced dialog keeps its position on rebuilds: */
+ advanced_dialog_window = gtk_hbox_new(/* homogeneous */ FALSE, 0);
+ gtk_box_pack_start(GTK_BOX(xsane_vbox_advanced), advanced_dialog_window, TRUE, TRUE, 0);
+ gtk_widget_show(advanced_dialog_window);
+
+
+ dialog = malloc(sizeof (*dialog));
+ if (!dialog)
+ {
+ printf("Could not create dialog\n");
+ return;
+ }
+
+ /* fill in dialog structure */
+
+ memset(dialog, 0, sizeof(*dialog));
+
+ dialog->xsane_window = main_dialog_window;
+ dialog->standard_window = standard_dialog_window;
+ dialog->advanced_window = advanced_dialog_window;
+ dialog->dev = dev;
+ dialog->dev_name = strdup(devname);
+ dialog->num_elements = num_elements;
+ dialog->option_reload_callback = xsane_update_preview;
+ dialog->option_reload_arg = 0;
+ dialog->param_change_callback = xsane_update_param;
+ dialog->param_change_arg = 0;
+
+ dialog->element = malloc(num_elements * sizeof(dialog->element[0]));
+ memset(dialog->element, 0, num_elements * sizeof(dialog->element[0]));
+
+
+
+
+ /* realize xsane main dialog */
+ /* normally a realize should be ok, but then
+ the default size of the scrollwed window is ignored
+ so we use a widget_show in that case */
+
+ if (xsane.main_window_fixed)
+ {
+ gtk_widget_realize(xsane.shell);
+ }
+ else
+ {
+ gtk_widget_show(xsane.shell);
+ /* the disadavantage of this is that the main window does
+ not have the focus when every window is shown */
+ }
+
+
+ /* define tooltips colors */
+
+ dialog->tooltips = gtk_tooltips_new();
+ colormap = gdk_window_get_colormap(xsane.shell->window);
+
+/* I don`t know why the following does not work with gtk-1.2.x */
+/* but the gimp has the same problems ;-) */
+ /* use black as foreground: */
+ dialog->tooltips_fg.red = 0;
+ dialog->tooltips_fg.green = 0;
+ dialog->tooltips_fg.blue = 0;
+ gdk_color_alloc(colormap, &dialog->tooltips_fg);
+
+ /* postit yellow (khaki) as background: */
+ dialog->tooltips_bg.red = 61669;
+ dialog->tooltips_bg.green = 59113;
+ dialog->tooltips_bg.blue = 35979;
+ gdk_color_alloc(colormap, &dialog->tooltips_bg);
+
+/* as long as gtk_tooltips_set_colors() does not work : */
+#if 1
+ gtk_tooltips_force_window(dialog->tooltips);
+ {
+ GtkStyle *current_style = gtk_style_copy(gtk_widget_get_style(dialog->tooltips->tip_window));
+
+ current_style->bg[GTK_STATE_NORMAL] = dialog->tooltips_bg;
+ current_style->fg[GTK_STATE_NORMAL] = dialog->tooltips_fg;
+ gtk_widget_set_style(dialog->tooltips->tip_window, current_style);
+ }
+#else
+ gtk_tooltips_set_colors(dialog->tooltips, &dialog->tooltips_bg, &dialog->tooltips_fg);
+#endif
+ xsane_back_gtk_set_tooltips(dialog, preferences.tooltips_enabled);
+
+
+
+ /* create histogram dialog and set colors */
+ xsane_create_histogram_dialog(device_text); /* create the histogram dialog */
+
+
+ /* The bottom row of info and start button */
+
+#if 0
+ hbox = GTK_DIALOG(xsane.shell)->action_area;
+#endif
+
+ hbox = gtk_hbox_new(FALSE, 5);
+ gtk_box_pack_end(GTK_BOX(GTK_DIALOG(xsane.shell)->action_area), hbox, TRUE, TRUE, 0);
+ gtk_widget_show(hbox);
+
+ /* Info frame */
+ frame = gtk_frame_new(0);
+ gtk_frame_set_shadow_type(GTK_FRAME(frame), GTK_SHADOW_IN);
+#if 0
+ gtk_box_pack_start(GTK_BOX(hbox), frame, FALSE, FALSE, 0);
+#endif
+ gtk_box_pack_start(GTK_BOX(hbox), frame, TRUE, TRUE, 0);
+ gtk_widget_show(frame);
+
+ infobox = gtk_hbox_new(FALSE, 5);
+ gtk_container_set_border_width(GTK_CONTAINER(infobox), 2);
+ gtk_container_add(GTK_CONTAINER(frame), infobox);
+ gtk_widget_show(infobox);
+
+ xsane.info_label = gtk_label_new(TEXT_INFO_BOX);
+ gtk_box_pack_start(GTK_BOX(infobox), xsane.info_label, FALSE, FALSE, 0);
+#if 0
+ gtk_box_pack_start(GTK_BOX(infobox), xsane.info_label, TRUE, TRUE, 0);
+#endif
+ gtk_widget_show(xsane.info_label);
+
+
+ /* The Scan button */
+ button = gtk_button_new_with_label(BUTTON_START);
+ gtk_signal_connect(GTK_OBJECT(button), "clicked", (GtkSignalFunc) xsane_scan_dialog, 0);
+ gtk_box_pack_start(GTK_BOX(hbox), button, TRUE, TRUE, 0);
+ gtk_widget_show(button);
+ xsane.start_button = GTK_OBJECT(button);
+
+
+ /* create backend dependend options */
+ xsane_panel_build(dialog);
+
+
+ /* create preview dialog */
+ xsane.preview = preview_new(dialog);
+ gtk_signal_connect(GTK_OBJECT(xsane.preview->top), "delete_event", GTK_SIGNAL_FUNC(xsane_preview_window_destroyed), 0);
+
+
+ xsane_device_preferences_restore(); /* restore device-settings */
+
+ xsane_update_param(dialog, 0);
+
+ gtk_widget_realize(xsane.standard_options_shell); /* is needed for saving window geometry */
+ gtk_widget_realize(xsane.advanced_options_shell);
+
+ if (preferences.show_standard_options)
+ {
+ gtk_widget_show(xsane.standard_options_shell);
+ }
+
+ if (preferences.show_advanced_options)
+ {
+ gtk_widget_show(xsane.advanced_options_shell);
+ }
+
+ gtk_widget_show(xsane.shell); /* call as last so focus is on it */
+
+ while (gtk_events_pending())
+ {
+ gtk_main_iteration();
+ }
+
+ xsane_device_preferences_restore(); /* restore device-settings */
+
+ xsane_update_sliders();
+
+ if (xsane.show_preview)
+ {
+ gtk_widget_show(xsane.preview->top);
+ }
+ else
+ {
+ gtk_widget_hide(xsane.preview->top);
+ }
+ gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(xsane.show_preview_widget), xsane.show_preview);
+
+ xsane_set_all_resolutions(); /* make sure resolution, resolution_x and resolution_y are up to date */
+}
+
+/* ---------------------------------------------------------------------------------------------------------------------- */
+
+static void xsane_choose_dialog_ok_callback(void)
+{
+ gtk_signal_disconnect_by_func(GTK_OBJECT(choose_device_dialog), GTK_SIGNAL_FUNC(xsane_quit), 0);
+ gtk_widget_destroy(choose_device_dialog);
+ xsane_device_dialog();
+
+ if (!dialog)
+ {
+ xsane_quit();
+ }
+}
+
+/* ---------------------------------------------------------------------------------------------------------------------- */
+
+static void xsane_select_device_by_key_callback(GtkWidget * widget, gpointer data)
+{
+ seldev = (long) data;
+}
+
+/* ---------------------------------------------------------------------------------------------------------------------- */
+
+static void xsane_select_device_by_mouse_callback(GtkWidget * widget, GdkEventButton *event, gpointer data)
+{
+ seldev = (long) data;
+ if (event->type == GDK_2BUTTON_PRESS && event->button == 1)
+ {
+ xsane_choose_dialog_ok_callback();
+ }
+}
+
+/* ---------------------------------------------------------------------------------------------------------------------- */
+
+static gint32 xsane_choose_device(void)
+{
+ GtkWidget *main_vbox, *vbox, *hbox, *button, *device_frame, *device_vbox, *pixmapwidget;
+ GdkBitmap *mask;
+ GdkPixmap *pixmap;
+ GtkStyle *style;
+ GdkColor *bg_trans;
+ GSList *owner;
+ gint i;
+ const SANE_Device *adev;
+ char buf[256];
+ char vendor[9];
+ char model[17];
+ char type[20];
+ int j;
+
+ choose_device_dialog = gtk_dialog_new();
+ gtk_window_set_position(GTK_WINDOW(choose_device_dialog), GTK_WIN_POS_CENTER);
+ gtk_window_set_policy(GTK_WINDOW(choose_device_dialog), FALSE, FALSE, FALSE);
+ gtk_signal_connect(GTK_OBJECT(choose_device_dialog), "destroy", GTK_SIGNAL_FUNC(xsane_quit), 0);
+ snprintf(buf, sizeof(buf), "%s %s", prog_name, WINDOW_DEVICE_SELECTION);
+ gtk_window_set_title(GTK_WINDOW(choose_device_dialog), buf);
+
+ main_vbox = GTK_DIALOG(choose_device_dialog)->vbox;
+
+ vbox = gtk_vbox_new(FALSE, 5);
+ gtk_container_set_border_width(GTK_CONTAINER(vbox), 3);
+ gtk_box_pack_start(GTK_BOX(main_vbox), vbox, TRUE, TRUE, 0);
+ gtk_widget_show(vbox);
+
+ /* xsane logo */
+ gtk_widget_realize(choose_device_dialog);
+
+ style = gtk_widget_get_style(choose_device_dialog);
+ bg_trans = &style->bg[GTK_STATE_NORMAL];
+
+ snprintf(buf, sizeof(buf), "%s/xsane-logo.xpm", STRINGIFY(PATH_SANE_DATA_DIR));
+ pixmap = gdk_pixmap_create_from_xpm(choose_device_dialog->window, &mask, bg_trans, buf);
+ pixmapwidget = gtk_pixmap_new(pixmap, mask);
+ gtk_box_pack_start(GTK_BOX(vbox), pixmapwidget, FALSE, FALSE, 2);
+ gtk_widget_show(pixmapwidget);
+ gdk_pixmap_unref(pixmap);
+
+ xsane_set_window_icon(choose_device_dialog, (gchar **) 0);
+
+ xsane_separator_new(vbox, 5);
+
+
+ /* list the drivers with radiobuttons */
+ device_frame = gtk_frame_new(TEXT_AVAILABLE_DEVICES);
+ gtk_box_pack_start(GTK_BOX(vbox), device_frame, FALSE, FALSE, 2);
+ gtk_widget_show(device_frame);
+
+ device_vbox = gtk_vbox_new(FALSE, 5);
+ gtk_container_set_border_width(GTK_CONTAINER(device_vbox), 3);
+ gtk_container_add(GTK_CONTAINER(device_frame), device_vbox);
+
+ owner = 0;
+ for (i = 0; i < ndevs; i++)
+ {
+ adev = devlist[i];
+
+ strncpy(vendor, adev->vendor, sizeof(vendor)-1);
+ vendor[sizeof(vendor)-1] = 0;
+ for (j = strlen(vendor); j < sizeof(vendor)-1; j++)
+ {
+ vendor[j] = ' ';
+ }
+
+ strncpy(model, adev->model, sizeof(model)-1);
+ model[sizeof(model)-1] = 0;
+ for (j = strlen(model); j < sizeof(model)-1; j++)
+ {
+ model[j] = ' ';
+ }
+
+ strncpy(type, _(adev->type), sizeof(type)-1); /* allow translation of device type */
+ type[sizeof(type)-1] = 0;
+ for (j = strlen(type); j < sizeof(type)-1; j++)
+ {
+ type[j] = ' ';
+ }
+
+ snprintf(buf, sizeof(buf), "%s %s %s [%s]", vendor, model, type, adev->name);
+ button = gtk_radio_button_new_with_label(owner, (char *) buf);
+ gtk_signal_connect(GTK_OBJECT(button), "button_press_event",
+ (GtkSignalFunc) xsane_select_device_by_mouse_callback, (void *) (long) i);
+ gtk_signal_connect(GTK_OBJECT(button), "clicked",
+ (GtkSignalFunc) xsane_select_device_by_key_callback, (void *) (long) i);
+ gtk_box_pack_start(GTK_BOX(device_vbox), button, TRUE, TRUE, 0);
+ gtk_widget_show(button);
+ owner = gtk_radio_button_group(GTK_RADIO_BUTTON(button));;
+ }
+ gtk_widget_show(device_vbox);
+
+ /* The bottom row of buttons */
+ hbox = GTK_DIALOG(choose_device_dialog)->action_area;
+
+ /* The OK button */
+ button = gtk_button_new_with_label(BUTTON_OK);
+ GTK_WIDGET_SET_FLAGS(button, GTK_CAN_DEFAULT);
+ gtk_signal_connect(GTK_OBJECT(button), "clicked", (GtkSignalFunc) xsane_choose_dialog_ok_callback, 0);
+ gtk_box_pack_start(GTK_BOX(hbox), button, TRUE, TRUE, 0);
+ gtk_widget_grab_default(button);
+ gtk_widget_show(button);
+
+ /* The Cancel button */
+ button = gtk_button_new_with_label(BUTTON_CANCEL);
+ gtk_signal_connect(GTK_OBJECT(button), "clicked", (GtkSignalFunc) xsane_quit, 0);
+ gtk_box_pack_start(GTK_BOX(hbox), button, TRUE, TRUE, 0);
+ gtk_widget_show(button);
+
+ gtk_widget_show(choose_device_dialog);
+
+ return 0;
+}
+
+/* ---------------------------------------------------------------------------------------------------------------------- */
+
+static void xsane_usage(void)
+{
+ printf("%s %s %s\n", TEXT_USAGE, prog_name, TEXT_USAGE_OPTIONS);
+ printf("\n%s\n\n", TEXT_HELP);
+}
+
+/* ---------------------------------------------------------------------------------------------------------------------- */
+
+static void xsane_init(int argc, char **argv)
+{
+ char filename[PATH_MAX];
+ struct stat st;
+
+ gtk_init(&argc, &argv);
+#ifdef HAVE_LIBGIMP_GIMP_H
+ gtk_rc_parse(gimp_gtkrc());
+
+ gdk_set_use_xshm(gimp_use_xshm());
+#endif
+
+ xsane_back_gtk_make_path(sizeof(filename), filename, "xsane", 0, "xsane-style", 0, ".rc", XSANE_PATH_LOCAL_SANE);
+ if (stat(filename, &st) >= 0)
+ {
+ gtk_rc_parse(filename);
+ }
+ else /* no local xsane-style.rc, look for system file */
+ {
+ xsane_back_gtk_make_path(sizeof(filename), filename, "xsane", 0, "xsane-style", 0, ".rc", XSANE_PATH_SYSTEM);
+ if (stat(filename, &st) >= 0)
+ {
+ gtk_rc_parse(filename);
+ }
+ }
+
+ sane_init(&xsane.sane_backend_versioncode, (void *) xsane_authorization_callback);
+ if (SANE_VERSION_MAJOR(xsane.sane_backend_versioncode) != SANE_V_MAJOR)
+ {
+ fprintf(stderr, "\n\n"
+ "%s %s:\n"
+ " %s\n"
+ " %s %d\n"
+ " %s %d\n"
+ "%s\n\n",
+ 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;
+ }
+
+ if (argc > 1)
+ {
+ int ch;
+
+ while((ch = getopt_long(argc, argv, "cd:fghnsvFR", long_options, 0)) != EOF)
+ {
+ switch(ch)
+ {
+ case 'g': /* This options is set when xsane is called from the */
+ /* GIMP. If xsane is compiled without GIMP support */
+ /* then you get the error message when GIMP does */
+ /* query or tries to start the xsane plugin! */
+#ifndef HAVE_LIBGIMP_GIMP_H
+ printf("%s: %s\n", argv[0], ERR_GIMP_SUPPORT_MISSING);
+ exit(0);
+#endif
+ break;
+
+ case 'v': /* --version */
+#ifdef HAVE_LIBGIMP_GIMP_H
+ printf("%s-%s, %s \"%s\", SANE-%d.%d, %s, %s%s\n",
+ prog_name,
+ XSANE_VERSION,
+ TEXT_PACKAGE,
+ PACKAGE_VERSION,
+ SANE_VERSION_MAJOR(xsane.sane_backend_versioncode),
+ SANE_VERSION_MINOR(xsane.sane_backend_versioncode),
+ TEXT_WITH_GIMP_SUPPORT,
+ TEXT_GIMP_VERSION,
+ GIMP_VERSION);
+#else
+ printf("%s-%s, %s \"%s\", SANE-%d.%d, %s\n",
+ prog_name,
+ XSANE_VERSION,
+ TEXT_PACKAGE,
+ PACKAGE_VERSION,
+ SANE_VERSION_MAJOR(xsane.sane_backend_versioncode),
+ SANE_VERSION_MINOR(xsane.sane_backend_versioncode),
+ TEXT_WITHOUT_GIMP_SUPPORT);
+#endif
+ exit(0);
+
+ case 'd': /* --device-settings */
+ xsane.device_set_filename = strdup(optarg);
+ break;
+
+ case 's': /* --scan */
+ xsane.xsane_mode = XSANE_SCAN;
+ break;
+
+ case 'c': /* --copy */
+ xsane.xsane_mode = XSANE_COPY;
+ break;
+
+ case 'n': /* --No-modes-election */
+ xsane.mode_selection = 0;
+ break;
+
+ case 'f': /* --fax */
+ xsane.xsane_mode = XSANE_FAX;
+ break;
+
+ case 'F': /* --Fixed */
+ xsane.main_window_fixed = 1;
+ break;
+
+ case 'R': /* --Resizeable */
+ xsane.main_window_fixed = 0;
+ break;
+
+ case 'h': /* --help */
+ default:
+ xsane_usage();
+ exit(0);
+ }
+ }
+ }
+
+ sane_get_devices(&devlist, SANE_FALSE /* local and network devices */);
+
+ /* if devicename is given try to identify it, if not found, open device list */
+ if (optind < argc)
+ {
+ int ndevs;
+
+ for (ndevs = 0; devlist[ndevs]; ++ndevs)
+ {
+ if (!strncmp(devlist[ndevs]->name, argv[argc - 1], strlen(argv[argc - 1])))
+ {
+ seldev = ndevs;
+ break;
+ }
+ }
+
+ if ((seldev < 0) && (argc > 1))
+ {
+ static SANE_Device dev;
+ static const SANE_Device *device_list[] = { &dev, 0 };
+
+ memset(&dev, 0, sizeof(dev));
+ dev.name = argv[argc - 1];
+ dev.vendor = TEXT_UNKNOWN;
+ dev.type = TEXT_UNKNOWN;
+ dev.model = TEXT_UNKNOWN;
+
+ devlist = device_list;
+ seldev = 0;
+ }
+ }
+}
+
+/* ---------------------------------------------------------------------------------------------------------------------- */
+
+void xsane_interface(int argc, char **argv)
+{
+ xsane.info_label = 0;
+
+ xsane_init(argc, argv); /* initialize xsane variables if command line option is given, set seldev */
+
+ for (ndevs = 0; devlist[ndevs]; ++ndevs); /* count available devices */
+
+ if (seldev >= 0) /* device name is given on cammand line */
+ {
+ xsane_device_dialog(); /* open device seldev */
+
+ if (!dialog)
+ {
+ xsane_exit();
+ }
+ }
+ else /* no device name given on command line */
+ {
+ if (ndevs > 0) /* devices available */
+ {
+ seldev = 0;
+ if (ndevs == 1)
+ {
+ xsane_device_dialog(); /* open device seldev */
+ if (!dialog)
+ {
+ xsane_exit();
+ }
+ }
+ else
+ {
+ xsane_choose_device(); /* open device selection window and get device */
+ }
+ }
+ else /* ndevs == 0, no devices available */
+ {
+ char buf[256];
+
+ snprintf(buf, sizeof(buf), "%s: %s\n", prog_name, ERR_NO_DEVICES);
+ xsane_back_gtk_error(buf, TRUE);
+ xsane_exit();
+ }
+ }
+
+ gtk_main();
+ sane_exit();
+}
+
+/* ---------------------------------------------------------------------------------------------------------------------- */
+
+int main(int argc, char **argv)
+{
+ dialog = 0;
+ memset(&xsane, 0, sizeof(xsane)); /* set all values in xsane to 0 */
+
+ umask(XSANE_DEFAULT_UMASK); /* define permissions of new files */
+
+ xsane.sensitivity = TRUE;
+
+ xsane.main_window_fixed = -1; /* no command line option given, use preferences or fixed */
+
+ xsane.mode = XSANE_STANDALONE;
+ xsane.xsane_mode = XSANE_SCAN;
+ xsane.xsane_output_format = XSANE_PNM;
+ xsane.mode_selection = 1; /* enable selection of xsane mode */
+
+ xsane.input_tag = -1; /* no input tag */
+
+ xsane.histogram_lines = 1;
+
+ xsane.zoom = 1.0;
+ xsane.zoom_x = 1.0;
+ xsane.zoom_y = 1.0;
+ xsane.resolution = 0.0;
+ xsane.resolution_x = 0.0;
+ xsane.resolution_y = 0.0;
+ xsane.copy_number = 1;
+
+ xsane.gamma = 1.0;
+ xsane.gamma_red = 1.0;
+ xsane.gamma_green = 1.0;
+ xsane.gamma_blue = 1.0;
+ xsane.brightness = 0.0;
+ xsane.brightness_red = 0.0;
+ xsane.brightness_green = 0.0;
+ xsane.brightness_blue = 0.0;
+ xsane.contrast = 0.0;
+ xsane.contrast_red = 0.0;
+ xsane.contrast_green = 0.0;
+ xsane.contrast_blue = 0.0;
+ xsane.slider_gray.value[2] = 100.0;
+ xsane.slider_gray.value[1] = 50.0;
+ xsane.slider_gray.value[0] = 0.0;
+ xsane.slider_red.value[2] = 100.0;
+ xsane.slider_red.value[1] = 50.0;
+ xsane.slider_red.value[0] = 0.0;
+ xsane.slider_green.value[2] = 100.0;
+ xsane.slider_green.value[1] = 50.0;
+ xsane.slider_green.value[0] = 0.0;
+ xsane.slider_blue.value[2] = 100.0;
+ xsane.slider_blue.value[1] = 50.0;
+ xsane.slider_blue.value[0] = 0.0;
+ xsane.auto_white = 100.0;
+ xsane.auto_gray = 50.0;
+ xsane.auto_black = 0.0;
+
+ xsane.histogram_red = 1;
+ xsane.histogram_green = 1;
+ xsane.histogram_blue = 1;
+ xsane.histogram_int = 1;
+ xsane.histogram_log = 1;
+
+ xsane.xsane_color = TRUE;
+ xsane.scanner_gamma_color = FALSE;
+ xsane.scanner_gamma_gray = FALSE;
+ xsane.enhancement_rgb_default = TRUE;
+
+ prog_name = strrchr(argv[0], '/');
+ if (prog_name)
+ {
+ ++prog_name;
+ }
+ else
+ {
+ prog_name = argv[0];
+ }
+#if 0
+ bindtextdomain(PACKAGE, LOCALEDIR);
+ textdomain(PACKAGE);
+#endif
+ bindtextdomain(prog_name, LOCALEDIR);
+ textdomain(prog_name);
+
+#ifdef HAVE_LIBGIMP_GIMP_H
+ {
+ GPrintFunc old_print_func;
+ int result;
+
+ /* Temporarily install a print function that discards all output.
+ This is to avoid annoying "you must run this program under
+ gimp" messages when xsane gets invoked in stand-alone
+ mode. */
+ old_print_func = g_set_print_handler((GPrintFunc) null_print_func);
+
+ /* gimp_main() returns 1 if xsane wasn't invoked by GIMP */
+ result = gimp_main(argc, argv);
+ g_set_message_handler(old_print_func);
+ if (result)
+ {
+ xsane_interface(argc, argv);
+ }
+ }
+#else
+ xsane_interface(argc, argv);
+#endif
+ return 0;
+}
+
+/* ---------------------------------------------------------------------------------------------------------------------- */