diff options
Diffstat (limited to 'frontend/xsane-back-gtk.c')
-rw-r--r-- | frontend/xsane-back-gtk.c | 1426 |
1 files changed, 0 insertions, 1426 deletions
diff --git a/frontend/xsane-back-gtk.c b/frontend/xsane-back-gtk.c deleted file mode 100644 index 8bde762..0000000 --- a/frontend/xsane-back-gtk.c +++ /dev/null @@ -1,1426 +0,0 @@ -/* xsane -- a graphical (X11, gtk) scanner-oriented SANE frontend - - xsane-back-gtk.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-preferences.h" -#include "xsane-text.h" - -/* ----------------------------------------------------------------------------------------------------------------- */ - -/* extern declarations */ -extern void xsane_panel_build(GSGDialog *dialog); - -/* ----------------------------------------------------------------------------------------------------------------- */ - -/* forward declarations: */ -static void xsane_back_gtk_panel_rebuild(GSGDialog *dialog); -void xsane_set_sensitivity(SANE_Int sensitivity); -void xsane_set_window_icon(GtkWidget *gtk_window, gchar **xpm_d); - -/* ----------------------------------------------------------------------------------------------------------------- */ - -const char *xsane_back_gtk_unit_string(SANE_Unit unit) -{ - double d; - - switch (unit) - { - case SANE_UNIT_NONE: return "none"; - case SANE_UNIT_PIXEL: return "pixel"; - case SANE_UNIT_BIT: return "bit"; - case SANE_UNIT_DPI: return "dpi"; - case SANE_UNIT_PERCENT: return "%"; - case SANE_UNIT_MM: - d = preferences.length_unit; - if (d > 9.9 && d < 10.1) - { - return "cm"; - } - else if (d > 25.3 && d < 25.5) - { - return "in"; - } - return "mm"; - case SANE_UNIT_MICROSECOND: return "\265s"; - } - return 0; -} - -/* ----------------------------------------------------------------------------------------------------------------- */ - -void xsane_back_gtk_set_tooltip(GtkTooltips *tooltips, GtkWidget *widget, const char *desc) -{ - if (desc && desc[0]) - { - gtk_tooltips_set_tip(tooltips, widget, desc, 0); - } -} - -/* ----------------------------------------------------------------------------------------------------------------- */ - -int xsane_back_gtk_make_path(size_t buf_size, char *buf, - const char *prog_name, - const char *dir_name, - const char *prefix, const char *dev_name, - const char *postfix, - int location) -{ - struct passwd *pw; - size_t len, extra; - int i; - - if (location == XSANE_PATH_LOCAL_SANE) /* make path to local file */ - { - pw = getpwuid(getuid()); /* get homedirectory */ - if (!pw) - { - snprintf(buf, buf_size, "%s %s", ERR_HOME_DIR, strerror(errno)); - xsane_back_gtk_error(buf, FALSE); - return -1; - } - - snprintf(buf, buf_size, "%s/.sane", pw->pw_dir); - mkdir(buf, 0777); /* ensure ~/.sane directory exists */ - } - else if (location == XSANE_PATH_SYSTEM) /* make path to system file */ - { - snprintf(buf, buf_size, "%s", STRINGIFY(PATH_SANE_DATA_DIR)); - } - else /* make path to temporary file */ - { - snprintf(buf, buf_size, "%s", PATH_SANE_TMP); - } - - len = strlen(buf); - - if (prog_name) - { - extra = strlen(prog_name); - if (len + extra + 1 >= buf_size) - { - goto filename_too_long; - } - - buf[len++] = '/'; - memcpy(buf + len, prog_name, extra); - len += extra; - buf[len] = '\0'; - mkdir(buf, 0777); /* ensure ~/.sane/PROG_NAME directory exists */ - } - if (len >= buf_size) - { - goto filename_too_long; - } - - buf[len++] = '/'; - - - if (dir_name) - { - extra = strlen(dir_name); - if (len + extra + 1 >= buf_size) - { - goto filename_too_long; - } - - buf[len++] = '/'; - memcpy(buf + len, dir_name, extra); - len += extra; - buf[len] = '\0'; - mkdir(buf, 0777); /* ensure DIR_NAME directory exists */ - } - - if (len >= buf_size) - { - goto filename_too_long; - } - - buf[len++] = '/'; - - - if (prefix) - { - extra = strlen(prefix); - if (len + extra >= buf_size) - { - goto filename_too_long; - } - - memcpy(buf + len, prefix, extra); - len += extra; - } - - if (location == XSANE_PATH_TMP) /* system tmp dir, add uid */ - { - char uid_prefix[256]; - uid_t uid; - - uid = getuid(); - snprintf(uid_prefix, sizeof(uid_prefix), "%d-", uid); - - extra = strlen(uid_prefix); - if (len + extra >= buf_size) - { - goto filename_too_long; - } - - memcpy(buf + len, uid_prefix, extra); - len += extra; - } - - if (dev_name) - { - /* Turn devicename into valid filename by replacing slashes by "_", "_" gets "__", spaces are erased */ - - for (i = 0; dev_name[i]; ++i) - { - if (len + 2 >= buf_size) - { - goto filename_too_long; - } - - switch (dev_name[i]) - { - case '/': /* "/" -> "_" */ - buf[len++] = '_'; - break; - - case ' ': /* erase " " */ - break; - - case '_': /* "_" -> "__" */ - buf[len++] = '_'; - /* fall through */ - default: - buf[len++] = dev_name[i]; - break; - } - } - } - - if (postfix) - { - extra = strlen(postfix); - if (len + extra >= buf_size) - { - goto filename_too_long; - } - memcpy(buf + len, postfix, extra); - len += extra; - } - if (len >= buf_size) - goto filename_too_long; - - buf[len++] = '\0'; - return 0; - -filename_too_long: - xsane_back_gtk_error(ERR_FILENAME_TOO_LONG, FALSE); - errno = E2BIG; - return -1; -} - -/* ----------------------------------------------------------------------------------------------------------------- */ - -void xsane_back_gtk_set_option(GSGDialog * dialog, int opt_num, void *val, SANE_Action action) -{ - SANE_Status status; - SANE_Int info; - char buf[256]; - - status = sane_control_option(dialog->dev, opt_num, action, val, &info); - if (status != SANE_STATUS_GOOD) - { - snprintf(buf, sizeof(buf), "%s %s: %s.", ERR_SET_OPTION, sane_get_option_descriptor(dialog->dev, opt_num)->name, - XSANE_STRSTATUS(status)); - xsane_back_gtk_error(buf, FALSE); - return; - } - - if ((info & SANE_INFO_RELOAD_PARAMS) && dialog->param_change_callback) - { - (*dialog->param_change_callback) (dialog, dialog->param_change_arg); - } - - if (info & SANE_INFO_RELOAD_OPTIONS) - { - xsane_back_gtk_panel_rebuild(dialog); - if (dialog->option_reload_callback) - { - (*dialog->option_reload_callback) (dialog, dialog->option_reload_arg); - } - } -} - -/* ----------------------------------------------------------------------------------------------------------------- */ - -void xsane_back_gtk_close_dialog_callback(GtkWidget * widget, gpointer data) -{ - gtk_widget_destroy(data); - xsane_back_gtk_message_dialog_active = 0; -} - -/* ----------------------------------------------------------------------------------------------------------------- */ - -static gint decision_flag; -static GtkWidget *decision_dialog; - -void xsane_back_gtk_decision_callback(GtkWidget * widget, gpointer data) -{ - gtk_widget_destroy(decision_dialog); - xsane_back_gtk_message_dialog_active = 0; - decision_flag = (long) data; -} - -/* ----------------------------------------------------------------------------------------------------------------- */ - -gint xsane_back_gtk_decision(gchar *title, gchar **xpm_d, gchar *message, gchar *oktext, gchar *rejecttext, gint wait) -{ - GtkWidget *main_vbox, *hbox, *label, *button; - GdkPixmap *pixmap; - GdkBitmap *mask; - GtkWidget *pixmapwidget; - - if (xsane_back_gtk_message_dialog_active) - { - fprintf(stderr, "%s: %s\n", title, message); - return TRUE; - } - xsane_back_gtk_message_dialog_active = 1; - decision_dialog = gtk_window_new(GTK_WINDOW_DIALOG); - gtk_window_set_position(GTK_WINDOW(decision_dialog), GTK_WIN_POS_MOUSE); - gtk_window_set_title(GTK_WINDOW(decision_dialog), title); - gtk_signal_connect(GTK_OBJECT(decision_dialog), "delete_event", - GTK_SIGNAL_FUNC(xsane_back_gtk_decision_callback), (void *) -1); /* -1 = cancel */ - - xsane_set_window_icon(decision_dialog, 0); - - /* create the main vbox */ - main_vbox = gtk_vbox_new(TRUE, 5); - gtk_container_set_border_width(GTK_CONTAINER(main_vbox), 5); - gtk_widget_show(main_vbox); - - gtk_container_add(GTK_CONTAINER(decision_dialog), main_vbox); - - hbox = gtk_hbox_new(FALSE, 2); - gtk_container_set_border_width(GTK_CONTAINER(hbox), 4); - gtk_box_pack_start(GTK_BOX(main_vbox), hbox, FALSE, FALSE, 0); - - /* the info icon */ - if (xpm_d) - { - pixmap = gdk_pixmap_create_from_xpm_d(decision_dialog->window, &mask, xsane.bg_trans, xpm_d); - pixmapwidget = gtk_pixmap_new(pixmap, mask); - gtk_box_pack_start(GTK_BOX(hbox), pixmapwidget, FALSE, FALSE, 10); - gtk_widget_show(pixmapwidget); - gdk_pixmap_unref(pixmap); - } - - /* the message */ - label = gtk_label_new(message); - gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0); - gtk_widget_show(label); - - gtk_widget_show(hbox); - - - hbox = gtk_hbox_new(FALSE, 2); - gtk_container_set_border_width(GTK_CONTAINER(hbox), 4); - gtk_box_pack_start(GTK_BOX(main_vbox), hbox, FALSE, FALSE, 0); - - /* the confirmation button */ - button = gtk_button_new_with_label(oktext); - GTK_WIDGET_SET_FLAGS(button, GTK_CAN_DEFAULT); - gtk_signal_connect(GTK_OBJECT(button), "clicked", (GtkSignalFunc) xsane_back_gtk_decision_callback, (void *) 1 /* confirm */); - gtk_container_add(GTK_CONTAINER(hbox), button); - gtk_widget_grab_default(button); - gtk_widget_show(button); - - - if (rejecttext) /* the rejection button */ - { - button = gtk_button_new_with_label(rejecttext); - gtk_signal_connect(GTK_OBJECT(button), "clicked", (GtkSignalFunc) xsane_back_gtk_decision_callback, (void *) -1 /* reject */); - gtk_container_add(GTK_CONTAINER(hbox), button); - gtk_widget_show(button); - } - gtk_widget_show(hbox); - - gtk_widget_show(decision_dialog); - - if (!wait) - { - return TRUE; - } - - decision_flag = 0; - - while (decision_flag == 0) - { - gtk_main_iteration(); - } - - while (gtk_events_pending()) - { - gtk_main_iteration(); - } - - if (decision_flag == 1) - { - return TRUE; - } - - return FALSE; -} - -/* ----------------------------------------------------------------------------------------------------------------- */ - -void xsane_back_gtk_message(gchar *title, gchar **icon_xpm, gchar *message, gint wait) -{ - xsane_back_gtk_decision(title, icon_xpm, message, ERR_BUTTON_OK, 0 /* no reject text */, wait); -} - -/* ----------------------------------------------------------------------------------------------------------------- */ - -void xsane_back_gtk_error(gchar *error, gint wait) -{ - if (wait) - { - SANE_Int old_sensitivity = xsane.sensitivity; - - xsane_set_sensitivity(FALSE); - xsane_back_gtk_message(ERR_HEADER_ERROR, (gchar**) error_xpm, error, wait); - xsane_set_sensitivity(old_sensitivity); - } - else - { - xsane_back_gtk_message(ERR_HEADER_ERROR, (gchar **) error_xpm, error, wait); - } -} - -/* ----------------------------------------------------------------------------------------------------------------- */ - -void xsane_back_gtk_warning(gchar *warning, gint wait) -{ - if (wait) - { - SANE_Int old_sensitivity = xsane.sensitivity; - - xsane_set_sensitivity(FALSE); - xsane_back_gtk_message(ERR_HEADER_WARNING, (gchar**) warning_xpm, warning, wait); - xsane_set_sensitivity(old_sensitivity); - } - else - { - xsane_back_gtk_message(ERR_HEADER_WARNING, (gchar**) warning_xpm, warning, wait); - } -} - -/* ----------------------------------------------------------------------------------------------------------------- */ - -static void xsane_back_gtk_get_filename_button_clicked(GtkWidget *w, gpointer data) -{ - int *clicked = data; - *clicked = 1; -} - -/* ----------------------------------------------------------------------------------------------------------------- */ - -int xsane_back_gtk_get_filename(const char *label, const char *default_name, size_t max_len, char *filename, int show_fileopts) -{ - int cancel = 0, ok = 0, destroy = 0; - GtkWidget *fileselection; - - fileselection = gtk_file_selection_new((char *) label); - - gtk_signal_connect(GTK_OBJECT(fileselection), - "destroy", GTK_SIGNAL_FUNC(xsane_back_gtk_get_filename_button_clicked), &destroy); - gtk_signal_connect(GTK_OBJECT(GTK_FILE_SELECTION(fileselection)->cancel_button), - "clicked", (GtkSignalFunc) xsane_back_gtk_get_filename_button_clicked, &cancel); - gtk_signal_connect(GTK_OBJECT(GTK_FILE_SELECTION(fileselection)->ok_button), - "clicked", (GtkSignalFunc) xsane_back_gtk_get_filename_button_clicked, &ok); - if (default_name) - { - gtk_file_selection_set_filename(GTK_FILE_SELECTION(fileselection), (char *) default_name); - } - - if (show_fileopts) - { - gtk_file_selection_show_fileop_buttons(GTK_FILE_SELECTION(fileselection)); - } - else - { - gtk_file_selection_hide_fileop_buttons(GTK_FILE_SELECTION(fileselection)); - } - - gtk_widget_show(fileselection); - - while (!cancel && !ok && !destroy) - { - if (!gtk_events_pending()) - { - usleep(100000); - } - gtk_main_iteration(); - } - - if (ok) - { - size_t len, cwd_len; - char *cwd; - - strncpy(filename, gtk_file_selection_get_filename(GTK_FILE_SELECTION(fileselection)), max_len - 1); - filename[max_len - 1] = '\0'; - - len = strlen(filename); - cwd = alloca(len + 2); - getcwd(cwd, len + 1); - cwd_len = strlen(cwd); - cwd[cwd_len++] = '/'; - cwd[cwd_len] = '\0'; - if (strncmp(filename, cwd, cwd_len) == 0) - { - memcpy(filename, filename + cwd_len, len - cwd_len + 1); - } - } - - if (!destroy) - { - gtk_widget_destroy(fileselection); - } - - return ok ? 0 : -1; -} - -/* ----------------------------------------------------------------------------------------------------------------- */ - -static gint xsane_back_gtk_autobutton_update(GtkWidget *widget, GSGDialogElement *elem) -{ - GSGDialog *dialog = elem->dialog; - int opt_num = elem - dialog->element; - const SANE_Option_Descriptor *opt; - SANE_Status status; - SANE_Word val; - char buf[256]; - - opt = sane_get_option_descriptor(dialog->dev, opt_num); - if (GTK_TOGGLE_BUTTON(widget)->active) - { - xsane_back_gtk_set_option(dialog, opt_num, 0, SANE_ACTION_SET_AUTO); - } - else - { - status = sane_control_option(dialog->dev, opt_num, SANE_ACTION_GET_VALUE, &val, 0); - if (status != SANE_STATUS_GOOD) - { - snprintf(buf, sizeof(buf), "%s %s: %s.", ERR_GET_OPTION, opt->name, XSANE_STRSTATUS(status)); - xsane_back_gtk_error(buf, FALSE); - } - xsane_back_gtk_set_option(dialog, opt_num, &val, SANE_ACTION_SET_VALUE); - } - return FALSE; -} - -/* ----------------------------------------------------------------------------------------------------------------- */ - -static void xsane_back_gtk_autobutton_new(GtkWidget *parent, GSGDialogElement *elem, - GtkWidget *label, GtkTooltips *tooltips) -{ - GtkWidget *button, *alignment; - - button = gtk_check_button_new(); - gtk_container_set_border_width(GTK_CONTAINER(button), 0); - gtk_widget_set_usize(button, 20, 20); - gtk_signal_connect(GTK_OBJECT(button), "toggled", (GtkSignalFunc) xsane_back_gtk_autobutton_update, elem); - xsane_back_gtk_set_tooltip(tooltips, button, "Turns on automatic mode."); - - alignment = gtk_alignment_new(0.0, 1.0, 0.5, 0.5); - gtk_container_add(GTK_CONTAINER(alignment), button); - - gtk_box_pack_end(GTK_BOX(parent), label, FALSE, FALSE, 0); - gtk_box_pack_end(GTK_BOX(parent), alignment, FALSE, FALSE, 2); - - gtk_widget_show(alignment); - gtk_widget_show(button); -} - -/* ----------------------------------------------------------------------------------------------------------------- */ - -static gint xsane_back_gtk_button_update(GtkWidget * widget, GSGDialogElement * elem) -{ - GSGDialog *dialog = elem->dialog; - int opt_num = elem - dialog->element; - const SANE_Option_Descriptor *opt; - SANE_Word val = SANE_FALSE; - - opt = sane_get_option_descriptor(dialog->dev, opt_num); - if (GTK_TOGGLE_BUTTON(widget)->active) - { - val = SANE_TRUE; - } - xsane_back_gtk_set_option(dialog, opt_num, &val, SANE_ACTION_SET_VALUE); - - return FALSE; -} - -/* ----------------------------------------------------------------------------------------------------------------- */ - -void xsane_back_gtk_button_new(GtkWidget * parent, const char *name, SANE_Word val, - GSGDialogElement * elem, GtkTooltips *tooltips, const char *desc, SANE_Int settable) -{ - GtkWidget *button; - - button = gtk_check_button_new_with_label((char *) name); - gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button), val); - gtk_signal_connect(GTK_OBJECT(button), "toggled", (GtkSignalFunc) xsane_back_gtk_button_update, elem); - gtk_box_pack_start(GTK_BOX(parent), button, FALSE, TRUE, 0); - gtk_widget_show(button); - xsane_back_gtk_set_tooltip(tooltips, button, desc); - - gtk_widget_set_sensitive(button, settable); - - elem->widget = button; -} - -/* ----------------------------------------------------------------------------------------------------------------- */ - -static void xsane_back_gtk_scale_update(GtkAdjustment * adj_data, GSGDialogElement * elem) -{ - const SANE_Option_Descriptor *opt; - GSGDialog *dialog = elem->dialog; - SANE_Word val, new_val; - int opt_num; - double d; - - opt_num = elem - dialog->element; - opt = sane_get_option_descriptor(dialog->dev, opt_num); - switch(opt->type) - { - case SANE_TYPE_INT: - val = adj_data->value + 0.5; - break; - - case SANE_TYPE_FIXED: - d = adj_data->value; - if (opt->unit == SANE_UNIT_MM) - { - d *= preferences.length_unit; - } - val = SANE_FIX(d); - break; - - default: - fprintf(stderr, "xsane_back_gtk_scale_update: %s %d\n", ERR_UNKNOWN_TYPE, opt->type); - return; - } - - xsane_back_gtk_set_option(dialog, opt_num, &val, SANE_ACTION_SET_VALUE); - sane_control_option(dialog->dev, opt_num, SANE_ACTION_GET_VALUE, &new_val, 0); - if (new_val != val) - { - val = new_val; - goto value_changed; - } - return; /* value didn't change */ - -value_changed: - switch(opt->type) - { - case SANE_TYPE_INT: - adj_data->value = val; - break; - - case SANE_TYPE_FIXED: - d = SANE_UNFIX(val); - if (opt->unit == SANE_UNIT_MM) - { - d /= preferences.length_unit; - } - adj_data->value = d; - break; - - default: - break; - } - /* Let widget know that value changed _again_. This must converge - quickly---otherwise things would get very slow very quickly (as - in "infinite recursion"): */ - gtk_signal_emit_by_name(GTK_OBJECT(adj_data), "value_changed"); - return; -} - -/* ----------------------------------------------------------------------------------------------------------------- */ - -void xsane_back_gtk_scale_new(GtkWidget * parent, const char *name, gfloat val, - gfloat min, gfloat max, gfloat quant, int automatic, - GSGDialogElement * elem, GtkTooltips *tooltips, const char *desc, SANE_Int settable) -{ - GtkWidget *hbox, *label, *scale; - - hbox = gtk_hbox_new(FALSE, 2); - gtk_container_set_border_width(GTK_CONTAINER(hbox), 0); - gtk_box_pack_start(GTK_BOX(parent), hbox, FALSE, FALSE, 0); - - label = gtk_label_new((char *) name); - gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 2); - - elem->data = gtk_adjustment_new(val, min, max, quant, 1.0, 0.0); - scale = gtk_hscale_new(GTK_ADJUSTMENT(elem->data)); - xsane_back_gtk_set_tooltip(tooltips, scale, desc); - gtk_widget_set_usize(scale, 150, 0); - - if (automatic) - { - xsane_back_gtk_autobutton_new(hbox, elem, scale, tooltips); - } - else - { - gtk_box_pack_end(GTK_BOX(hbox), scale, FALSE, FALSE, 0); /* make scales fixed */ -/* gtk_box_pack_end(GTK_BOX(hbox), scale, TRUE, TRUE, 0); */ /* make scales sizeable */ - } - - gtk_range_set_update_policy(GTK_RANGE(scale), GTK_UPDATE_CONTINUOUS); - gtk_scale_set_value_pos(GTK_SCALE(scale), GTK_POS_TOP); - if (quant - (int) quant == 0.0) - { - gtk_scale_set_digits(GTK_SCALE(scale), 0); - } - else - { - /* one place behind decimal point */ - gtk_scale_set_digits(GTK_SCALE(scale), 1); - } - - gtk_signal_connect(elem->data, "value_changed", (GtkSignalFunc) xsane_back_gtk_scale_update, elem); - - gtk_widget_show(label); - gtk_widget_show(scale); - gtk_widget_show(hbox); - - gtk_widget_set_sensitive(scale, settable); - - elem->widget = scale; -} - -/* ----------------------------------------------------------------------------------------------------------------- */ - -void xsane_back_gtk_push_button_callback(GtkWidget * widget, gpointer data) -{ - GSGDialogElement *elem = data; - GSGDialog *dialog = elem->dialog; - int opt_num; - - opt_num = elem - dialog->element; - xsane_back_gtk_set_option(dialog, opt_num, 0, SANE_ACTION_SET_VALUE); -} - -/* ----------------------------------------------------------------------------------------------------------------- */ - -static int xsane_back_gtk_option_menu_lookup(GSGMenuItem menu_items[], const char *string) -{ - int i; - - for (i = 0; strcmp(menu_items[i].label, string) != 0; ++i); - - return i; -} - -/* ----------------------------------------------------------------------------------------------------------------- */ - -static void xsane_back_gtk_option_menu_callback(GtkWidget * widget, gpointer data) -{ - GSGMenuItem *menu_item = data; - GSGDialogElement *elem = menu_item->elem; - const SANE_Option_Descriptor *opt; - GSGDialog *dialog = elem->dialog; - int opt_num; - double dval; - SANE_Word val; - void *valp = &val; - - opt_num = elem - dialog->element; - opt = sane_get_option_descriptor(dialog->dev, opt_num); - switch(opt->type) - { - case SANE_TYPE_INT: - sscanf(menu_item->label, "%d", &val); - break; - - case SANE_TYPE_FIXED: - sscanf(menu_item->label, "%lg", &dval); - val = SANE_FIX(dval); - break; - - case SANE_TYPE_STRING: - valp = menu_item->label; - break; - - default: - fprintf(stderr, "xsane_back_gtk_option_menu_callback: %s %d\n", ERR_UNKNOWN_TYPE, opt->type); - break; - } - xsane_back_gtk_set_option(dialog, opt_num, valp, SANE_ACTION_SET_VALUE); -} - -/* ----------------------------------------------------------------------------------------------------------------- */ - -void xsane_back_gtk_option_menu_new(GtkWidget *parent, const char *name, char *str_list[], - const char *val, GSGDialogElement * elem, - GtkTooltips *tooltips, const char *desc, SANE_Int settable) -{ - GtkWidget *hbox, *label, *option_menu, *menu, *item; - GSGMenuItem *menu_items; - int i, num_items; - - hbox = gtk_hbox_new(FALSE, 2); - gtk_container_set_border_width(GTK_CONTAINER(hbox), 0); - gtk_box_pack_start(GTK_BOX(parent), hbox, FALSE, FALSE, 0); - - label = gtk_label_new((char *) name); - gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 2); - - for (num_items = 0; str_list[num_items]; ++num_items); - menu_items = malloc(num_items * sizeof(menu_items[0])); - - menu = gtk_menu_new(); - for (i = 0; i < num_items; ++i) - { - item = gtk_menu_item_new_with_label(_BGT(str_list[i])); - gtk_container_add(GTK_CONTAINER(menu), item); - gtk_signal_connect(GTK_OBJECT(item), "activate", (GtkSignalFunc) xsane_back_gtk_option_menu_callback, menu_items + i); - - gtk_widget_show(item); - - menu_items[i].label = str_list[i]; - menu_items[i].elem = elem; - menu_items[i].index = i; - } - - option_menu = gtk_option_menu_new(); - gtk_box_pack_end(GTK_BOX(hbox), option_menu, FALSE, FALSE, 2); - gtk_option_menu_set_menu(GTK_OPTION_MENU(option_menu), menu); - gtk_option_menu_set_history(GTK_OPTION_MENU(option_menu), xsane_back_gtk_option_menu_lookup(menu_items, val)); - xsane_back_gtk_set_tooltip(tooltips, option_menu, desc); - - gtk_widget_show(label); - gtk_widget_show(option_menu); - gtk_widget_show(hbox); - - gtk_widget_set_sensitive(option_menu, settable); - - elem->widget = option_menu; - elem->menu_size = num_items; - elem->menu = menu_items; -} - -/* ----------------------------------------------------------------------------------------------------------------- */ - -static void xsane_back_gtk_text_entry_callback(GtkWidget *w, gpointer data) -{ - GSGDialogElement *elem = data; - const SANE_Option_Descriptor *opt; - GSGDialog *dialog = elem->dialog; - gchar *text; - int opt_num; - char *buf; - - opt_num = elem - dialog->element; - opt = sane_get_option_descriptor(dialog->dev, opt_num); - - buf = alloca(opt->size); - buf[0] = '\0'; - - text = gtk_entry_get_text(GTK_ENTRY(elem->widget)); - if (text) - { - strncpy(buf, text, opt->size); - } - buf[opt->size - 1] = '\0'; - - xsane_back_gtk_set_option(dialog, opt_num, buf, SANE_ACTION_SET_VALUE); - - if (strcmp(buf, text) != 0) /* the backend modified the option value; update widget: */ - { - gtk_entry_set_text(GTK_ENTRY(elem->widget), buf); - } -} - -/* ----------------------------------------------------------------------------------------------------------------- */ - -void xsane_back_gtk_text_entry_new(GtkWidget * parent, const char *name, const char *val, GSGDialogElement *elem, - GtkTooltips *tooltips, const char *desc, SANE_Int settable) -{ - GtkWidget *hbox, *text, *label; - - hbox = gtk_hbox_new(FALSE, 2); - gtk_container_set_border_width(GTK_CONTAINER(hbox), 0); - gtk_box_pack_start(GTK_BOX(parent), hbox, FALSE, FALSE, 0); - - label = gtk_label_new((char *) name); - gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 2); - - text = gtk_entry_new(); - gtk_entry_set_text(GTK_ENTRY(text), (char *) val); -/* gtk_box_pack_start(GTK_BOX(hbox), text, FALSE, TRUE, 0); */ /* text entry fixed */ - gtk_box_pack_start(GTK_BOX(hbox), text, TRUE, TRUE, 0); /* text entry sizeable */ - gtk_signal_connect(GTK_OBJECT(text), "changed", (GtkSignalFunc) xsane_back_gtk_text_entry_callback, elem); - xsane_back_gtk_set_tooltip(tooltips, text, desc); - - gtk_widget_show(hbox); - gtk_widget_show(label); - gtk_widget_show(text); - - gtk_widget_set_sensitive(text, settable); - - elem->widget = text; -} - -/* ----------------------------------------------------------------------------------------------------------------- */ - -GtkWidget *xsane_back_gtk_group_new(GtkWidget *parent, const char * title) -{ - GtkWidget * frame, * vbox; - - frame = gtk_frame_new((char *) title); - gtk_container_set_border_width(GTK_CONTAINER(frame), 4); - gtk_frame_set_shadow_type(GTK_FRAME(frame), GTK_SHADOW_ETCHED_IN); - gtk_box_pack_start(GTK_BOX(parent), frame, FALSE, FALSE, 0); - - vbox = gtk_vbox_new(FALSE, 4); - gtk_container_set_border_width(GTK_CONTAINER(vbox), 2); - gtk_container_add(GTK_CONTAINER(frame), vbox); - gtk_widget_show(vbox); - return vbox; -} - -/* ----------------------------------------------------------------------------------------------------------------- */ -#if 0 -static GtkWidget* xsane_back_gtk_curve_new(GSGDialog *dialog, int optnum) -{ - const SANE_Option_Descriptor * opt; - gfloat fmin, fmax, val, *vector; - SANE_Word *optval, min, max; - GtkWidget *curve, *gamma; - SANE_Status status; - SANE_Handle dev; - int i, optlen; - - gamma = gtk_gamma_curve_new(); - curve = GTK_GAMMA_CURVE(gamma)->curve; - dev = dialog->dev; - - opt = sane_get_option_descriptor(dev, optnum); - optlen = opt->size / sizeof(SANE_Word); - vector = alloca(optlen * (sizeof(vector[0]) + sizeof(optval[0]))); - optval = (SANE_Word *) (vector + optlen); - - min = max = 0; - switch(opt->constraint_type) - { - case SANE_CONSTRAINT_RANGE: - min = opt->constraint.range->min; - max = opt->constraint.range->max; - break; - - case SANE_CONSTRAINT_WORD_LIST: - if (opt->constraint.word_list[0] > 1) - { - min = max = opt->constraint.word_list[1]; - for (i = 2; i < opt->constraint.word_list[0]; ++i) - { - if (opt->constraint.word_list[i] < min) - { - min = opt->constraint.word_list[i]; - } - - if (opt->constraint.word_list[i] > max) - { - max = opt->constraint.word_list[i]; - } - } - } - break; - - default: - break; - } - if (min == max) - { - fprintf(stderr, "xsane_back_gtk_curve_new: %s: `%s'\n", WARN_NO_VALUE_CONSTRAINT, opt->name); - fmin = 0; - fmax = 255; - } - else if (opt->type == SANE_TYPE_FIXED) - { - fmin = SANE_UNFIX(min); - fmax = SANE_UNFIX(max); - } - else - { - fmin = min; - fmax = max; - } - gtk_curve_set_range(GTK_CURVE(curve), 0, optlen - 1, fmin, fmax); - - status = sane_control_option(dev, optnum, SANE_ACTION_GET_VALUE, optval, 0); - if (status == SANE_STATUS_GOOD) - { - for (i = 0; i < optlen; ++i) - { - if (opt->type == SANE_TYPE_FIXED) - { - val = SANE_UNFIX(optval[i]); - } - else - { - val = optval[i]; - } - vector[i] = val; - } - gtk_curve_set_vector(GTK_CURVE(curve), optlen, vector); - } - else - { - gtk_widget_set_sensitive(gamma, FALSE); - } - - return gamma; -} - -/* ----------------------------------------------------------------------------------------------------------------- */ - -static void xsane_back_gtk_vector_new(GSGDialog * dialog, GtkWidget *vbox, int num_vopts, int *vopts) -{ - GtkWidget *notebook, *label, *curve; - const SANE_Option_Descriptor *opt; - int i; - - notebook = gtk_notebook_new(); - gtk_container_set_border_width(GTK_CONTAINER(notebook), 4); - gtk_box_pack_start(GTK_BOX(vbox), notebook, TRUE, TRUE, 0); - - for (i = 0; i < num_vopts; ++i) - { - opt = sane_get_option_descriptor(dialog->dev, vopts[i]); - - label = gtk_label_new((char *) opt->title); - vbox = gtk_vbox_new(/* homogeneous */ FALSE, 0); - gtk_notebook_append_page(GTK_NOTEBOOK(notebook), vbox, label); - gtk_widget_show(vbox); - gtk_widget_show(label); - - curve = xsane_back_gtk_curve_new(dialog, vopts[i]); - gtk_container_set_border_width(GTK_CONTAINER(curve), 4); - gtk_box_pack_start(GTK_BOX(vbox), curve, TRUE, TRUE, 0); - gtk_widget_show(curve); - - dialog->element[vopts[i]].widget = curve; - } - gtk_widget_show(notebook); -} -#endif -/* ----------------------------------------------------------------------------------------------------------------- */ -#if 0 -static void tooltips_destroy(GSGDialog * dialog) -{ - gtk_object_unref(GTK_OBJECT(dialog->tooltips)); - dialog->tooltips = 0; -} -#endif -/* ----------------------------------------------------------------------------------------------------------------- */ - -static void xsane_back_gtk_panel_destroy(GSGDialog * dialog) -{ - const SANE_Option_Descriptor *opt; - GSGDialogElement *elem; - int i, j; - - gtk_widget_destroy(dialog->xsane_hbox); - gtk_widget_destroy(dialog->standard_hbox); - gtk_widget_destroy(dialog->advanced_hbox); - - /* free the menu labels of integer/fix-point word-lists: */ - for (i = 0; i < dialog->num_elements; ++i) - { - if (dialog->element[i].menu) - { - opt = sane_get_option_descriptor(dialog->dev, i); - elem = dialog->element + i; - if (opt->type != SANE_TYPE_STRING) - { - for (j = 0; j < elem->menu_size; ++j) - { - if (elem->menu[j].label) - { - free(elem->menu[j].label); - elem->menu[j].label = 0; - } - } - free(elem->menu); - elem->menu = 0; - } - } - } - memset(dialog->element, 0, dialog->num_elements * sizeof(dialog->element[0])); -} - -/* ----------------------------------------------------------------------------------------------------------------- */ - -/* When an setting an option changes the dialog, everything may - change: the option titles, the activity-status of the option, its - constraints or what not. Thus, rather than trying to be clever in - detecting what exactly changed, we use a brute-force method of - rebuilding the entire dialog. */ - -static void xsane_back_gtk_panel_rebuild(GSGDialog * dialog) -{ - xsane_back_gtk_panel_destroy(dialog); - xsane_panel_build(dialog); -} - -/* ----------------------------------------------------------------------------------------------------------------- */ - -void xsane_back_gtk_refresh_dialog(GSGDialog *dialog) -{ - xsane_back_gtk_panel_rebuild(dialog); - if (dialog->param_change_callback) - { - (*dialog->param_change_callback) (dialog, dialog->param_change_arg); - } -} - -/* ----------------------------------------------------------------------------------------------------------------- */ - -void xsane_back_gtk_update_scan_window(GSGDialog *dialog) -{ - const SANE_Option_Descriptor *opt; - double old_val, new_val; - GSGDialogElement *elem; - SANE_Status status; - SANE_Word word; - int i, optnum; - char str[64]; - - for (i = 0; i < 4; ++i) - { - if (dialog->well_known.coord[i] > 0) - { - optnum = dialog->well_known.coord[i]; - elem = dialog->element + optnum; - opt = sane_get_option_descriptor(dialog->dev, optnum); - - status = sane_control_option(dialog->dev, optnum, SANE_ACTION_GET_VALUE, &word, 0); - if (status != SANE_STATUS_GOOD) - { - continue; /* sliently ignore errors */ - } - - switch(opt->constraint_type) - { - case SANE_CONSTRAINT_RANGE: - if (opt->type == SANE_TYPE_INT) - { - old_val = GTK_ADJUSTMENT(elem->data)->value; - new_val = word; - GTK_ADJUSTMENT(elem->data)->value = new_val; - } - else - { - old_val = GTK_ADJUSTMENT(elem->data)->value; - new_val = SANE_UNFIX(word); - if (opt->unit == SANE_UNIT_MM) - { - new_val /= preferences.length_unit; - } - GTK_ADJUSTMENT(elem->data)->value = new_val; - } - - if (old_val != new_val) - { - gtk_signal_emit_by_name(GTK_OBJECT(elem->data), "value_changed"); - } - break; - - case SANE_CONSTRAINT_WORD_LIST: - if (opt->type == SANE_TYPE_INT) - { - sprintf(str, "%d", word); - } - else - { - sprintf(str, "%g", SANE_UNFIX(word)); - } - /* XXX maybe we should call this only when the value changes... */ - gtk_option_menu_set_history(GTK_OPTION_MENU(elem->widget), xsane_back_gtk_option_menu_lookup(elem->menu, str)); - break; - - default: - break; - } - } - } -} - -/* ----------------------------------------------------------------------------------------------------------------- */ - -/* Ensure sure the device has up-to-date option values. Except for - vectors, all option values are kept current. Vectors are - downloaded into the device during this call. */ -void xsane_back_gtk_sync(GSGDialog *dialog) -{ - const SANE_Option_Descriptor *opt; - gfloat val, *vector; - SANE_Word *optval; - int i, j, optlen; - GtkWidget *curve; - - for (i = 1; i < dialog->num_elements; ++i) - { - opt = sane_get_option_descriptor(dialog->dev, i); - - if (!SANE_OPTION_IS_ACTIVE(opt->cap)) - { - continue; - } - - if (opt->type != SANE_TYPE_INT && opt->type != SANE_TYPE_FIXED) - { - continue; - } - - if (opt->size == sizeof(SANE_Word)) - { - continue; - } - - /* ok, we're dealing with an active vector */ - - optlen = opt->size / sizeof(SANE_Word); - optval = alloca(optlen * sizeof(optval[0])); - vector = alloca(optlen * sizeof(vector[0])); - - curve = GTK_GAMMA_CURVE(dialog->element[i].widget)->curve; - gtk_curve_get_vector(GTK_CURVE(curve), optlen, vector); - for (j = 0; j < optlen; ++j) - { - val = vector[j]; - if (opt->type == SANE_TYPE_FIXED) - { - optval[j] = SANE_FIX(val); - } - else - { - optval[j] = val + 0.5; - } - } - - xsane_back_gtk_set_option(dialog, i, optval, SANE_ACTION_SET_VALUE); - } -} - -/* ----------------------------------------------------------------------------------------------------------------- */ - -void xsane_back_gtk_update_vector(GSGDialog *dialog, int opt_num, SANE_Int *vector) -{ - const SANE_Option_Descriptor *opt; - gfloat val; - SANE_Word *optval; - int j, optlen; - - if (opt_num < 1) - return; /* not defined */ - - opt = sane_get_option_descriptor(dialog->dev, opt_num); - if (!SANE_OPTION_IS_ACTIVE(opt->cap)) - { - return; /* inactive */ - } - - if (opt->type != SANE_TYPE_INT && opt->type != SANE_TYPE_FIXED) - { - return; - } - - if (opt->size == sizeof(SANE_Word)) - { - return; - } - - /* ok, we're dealing with an active vector */ - - optlen = opt->size / sizeof(SANE_Word); - optval = alloca(optlen * sizeof(optval[0])); - for (j = 0; j < optlen; ++j) - { - val = vector[j]; - if (opt->type == SANE_TYPE_FIXED) - { - optval[j] = SANE_FIX(val); - } - else - { - optval[j] = val + 0.5; - } - } - - xsane_back_gtk_set_option(dialog, opt_num, optval, SANE_ACTION_SET_VALUE); -} - -/* ----------------------------------------------------------------------------------------------------------------- */ - -void xsane_back_gtk_set_tooltips(GSGDialog *dialog, int enable) -{ - if (!dialog->tooltips) - { - return; - } - - if (enable) - { - gtk_tooltips_enable(dialog->tooltips); - } - else - { - gtk_tooltips_disable(dialog->tooltips); - } -} - -/* ----------------------------------------------------------------------------------------------------------------- */ - -void xsane_back_gtk_set_sensitivity(GSGDialog *dialog, int sensitive) -{ - const SANE_Option_Descriptor *opt; - int i; - - for (i = 0; i < dialog->num_elements; ++i) - { - opt = sane_get_option_descriptor(dialog->dev, i); - - if (!SANE_OPTION_IS_ACTIVE(opt->cap) || !SANE_OPTION_IS_SETTABLE(opt->cap) || - opt->type == SANE_TYPE_GROUP || !dialog->element[i].widget) - { - continue; - } - - if (!(opt->cap & SANE_CAP_ALWAYS_SETTABLE)) - { - gtk_widget_set_sensitive(dialog->element[i].widget, sensitive); - } - } - - if (dialog) - { - if (dialog->xsanemode_widget) - { - gtk_widget_set_sensitive(dialog->xsanemode_widget, sensitive); - } - } - - while (gtk_events_pending()) - { - gtk_main_iteration(); - } -} -/* ---------------------------------------------------------------------------------------------------------------------- */ - -void xsane_set_sensitivity(SANE_Int sensitivity) -{ - if (xsane.shell) - { - gtk_widget_set_sensitive(xsane.shell, sensitivity); - gtk_widget_set_sensitive(xsane.standard_options_shell, sensitivity); - gtk_widget_set_sensitive(xsane.advanced_options_shell, sensitivity); - gtk_widget_set_sensitive(xsane.histogram_dialog, sensitivity); - } - - if (xsane.preview) - { - gtk_widget_set_sensitive(xsane.preview->button_box, sensitivity); /* button box at top of window */ -#if 0 - gtk_widget_set_sensitive(xsane.preview->viewport, sensitivity); /* Preview image selection */ -#endif - gtk_widget_set_sensitive(xsane.preview->start, sensitivity); /* Acquire preview button */ - } - - if (xsane.fax_dialog) - { - gtk_widget_set_sensitive(xsane.fax_dialog, sensitivity); - } - - if (dialog) - { - xsane_back_gtk_set_sensitivity(dialog, sensitivity); - } - - while (gtk_events_pending()) /* make sure set_sensitivity is displayed */ - { - gtk_main_iteration(); - } - - xsane.sensitivity = sensitivity; -} - -/* ----------------------------------------------------------------------------------------------------------------- */ - -void xsane_back_gtk_destroy_dialog(GSGDialog * dialog) -{ - SANE_Handle dev = dialog->dev; - - xsane_back_gtk_panel_destroy(dialog); - free((void *) dialog->dev_name); - free(dialog->element); - free(dialog); - - sane_close(dev); -} -/* ---------------------------------------------------------------------------------------------------------------------- */ - -void xsane_set_window_icon(GtkWidget *gtk_window, gchar **xpm_d) -{ - GdkPixmap *pixmap; - GdkBitmap *mask; - - gtk_widget_realize(gtk_window); - if (xpm_d) - { - pixmap = gdk_pixmap_create_from_xpm_d(gtk_window->window, &mask, xsane.bg_trans, xpm_d); - } - else - { - if (xsane.window_icon_pixmap) - { - pixmap = xsane.window_icon_pixmap; - mask = xsane.window_icon_mask; - } - else - { - pixmap = gdk_pixmap_create_from_xpm_d(gtk_window->window, &mask, xsane.bg_trans, (gchar **) xsane_window_icon_xpm); - } - } - - gdk_window_set_icon(gtk_window->window, 0, pixmap, mask); -} - -/* ---------------------------------------------------------------------------------------------------------------------- */ |