diff options
Diffstat (limited to 'src/scanner.vala')
-rw-r--r-- | src/scanner.vala | 448 |
1 files changed, 239 insertions, 209 deletions
diff --git a/src/scanner.vala b/src/scanner.vala index 8a8c6f6..158fa50 100644 --- a/src/scanner.vala +++ b/src/scanner.vala @@ -221,9 +221,8 @@ public class Scanner /* Last option read */ private Sane.Int option_index; - /* Option index for scan area */ - private Sane.Int br_x_option_index; - private Sane.Int br_y_option_index; + /* Table of options */ + private HashTable<string, int> options; /* Buffer for received line */ private uchar[] buffer; @@ -701,6 +700,7 @@ public class Scanner Sane.close (handle); debug ("sane_close ()"); have_handle = false; + options = null; } buffer = null; @@ -762,8 +762,6 @@ public class Scanner page_number = 0; notified_page = -1; option_index = 0; - br_x_option_index = 0; - br_y_option_index = 0; if (job.device == null && default_device != null) job.device = default_device; @@ -794,6 +792,7 @@ public class Scanner current_device = null; have_handle = false; + options = new HashTable <string, int> (str_hash, str_equal); var status = Sane.open (job.device, out handle); debug ("sane_open (\"%s\") -> %s", job.device, Sane.status_to_string (status)); @@ -820,34 +819,251 @@ public class Scanner var index = option_index; option_index++; + /* Options complete, apply settings */ if (option == null) { + /* Pick source */ + option = get_option_by_name (handle, Sane.NAME_SCAN_SOURCE, out index); + if (option != null) + { + string[] flatbed_sources = + { + "Auto", + Sane.I18N ("Auto"), + "Flatbed", + Sane.I18N ("Flatbed"), + "FlatBed", + "Normal", + Sane.I18N ("Normal") + }; + + string[] adf_sources = + { + "Automatic Document Feeder", + Sane.I18N ("Automatic Document Feeder"), + "ADF", + "Automatic Document Feeder(left aligned)", /* Seen in the proprietary brother3 driver */ + "Automatic Document Feeder(centrally aligned)" /* Seen in the proprietary brother3 driver */ + }; + + string[] adf_front_sources = + { + "ADF Front", + Sane.I18N ("ADF Front") + }; + + string[] adf_back_sources = + { + "ADF Back", + Sane.I18N ("ADF Back") + }; + + string[] adf_duplex_sources = + { + "ADF Duplex", + Sane.I18N ("ADF Duplex") + }; + + switch (job.type) + { + case ScanType.SINGLE: + if (!set_default_option (handle, option, index)) + if (!set_constrained_string_option (handle, option, index, flatbed_sources, null)) + warning ("Unable to set single page source, please file a bug"); + break; + case ScanType.ADF_FRONT: + if (!set_constrained_string_option (handle, option, index, adf_front_sources, null)) + if (!!set_constrained_string_option (handle, option, index, adf_sources, null)) + warning ("Unable to set front ADF source, please file a bug"); + break; + case ScanType.ADF_BACK: + if (!set_constrained_string_option (handle, option, index, adf_back_sources, null)) + if (!set_constrained_string_option (handle, option, index, adf_sources, null)) + warning ("Unable to set back ADF source, please file a bug"); + break; + case ScanType.ADF_BOTH: + if (!set_constrained_string_option (handle, option, index, adf_duplex_sources, null)) + if (!set_constrained_string_option (handle, option, index, adf_sources, null)) + warning ("Unable to set duplex ADF source, please file a bug"); + break; + } + } + + /* Scan mode (before resolution as it tends to affect that */ + option = get_option_by_name (handle, Sane.NAME_SCAN_MODE, out index); + if (option != null) + { + /* The names of scan modes often used in drivers, as taken from the sane-backends source */ + string[] color_scan_modes = + { + Sane.VALUE_SCAN_MODE_COLOR, + "Color", + "24bit Color" /* Seen in the proprietary brother3 driver */ + }; + string[] gray_scan_modes = + { + Sane.VALUE_SCAN_MODE_GRAY, + "Gray", + "Grayscale", + Sane.I18N ("Grayscale"), + "True Gray" /* Seen in the proprietary brother3 driver */ + }; + string[] lineart_scan_modes = + { + Sane.VALUE_SCAN_MODE_LINEART, + "Lineart", + "LineArt", + Sane.I18N ("LineArt"), + "Black & White", + Sane.I18N ("Black & White"), + "Binary", + Sane.I18N ("Binary"), + "Thresholded", + Sane.VALUE_SCAN_MODE_GRAY, + "Gray", + "Grayscale", + Sane.I18N ("Grayscale"), + "True Gray" /* Seen in the proprietary brother3 driver */ + }; + + switch (job.scan_mode) + { + case ScanMode.COLOR: + if (!set_constrained_string_option (handle, option, index, color_scan_modes, null)) + warning ("Unable to set Color mode, please file a bug"); + break; + case ScanMode.GRAY: + if (!set_constrained_string_option (handle, option, index, gray_scan_modes, null)) + warning ("Unable to set Gray mode, please file a bug"); + break; + case ScanMode.LINEART: + if (!set_constrained_string_option (handle, option, index, lineart_scan_modes, null)) + warning ("Unable to set Lineart mode, please file a bug"); + break; + default: + break; + } + } + + /* Duplex */ + option = get_option_by_name (handle, "duplex", out index); + if (option != null) + { + if (option.type == Sane.ValueType.BOOL) + set_bool_option (handle, option, index, job.type == ScanType.ADF_BOTH, null); + } + + /* Multi-page options */ + option = get_option_by_name (handle, "batch-scan", out index); + if (option != null) + { + if (option.type == Sane.ValueType.BOOL) + set_bool_option (handle, option, index, job.type != ScanType.SINGLE, null); + } + + /* Disable compression, we will compress after scanning */ + option = get_option_by_name (handle, "compression", out index); + if (option != null) + { + string[] disable_compression_names = + { + Sane.I18N ("None"), + Sane.I18N ("none"), + "None", + "none" + }; + + if (!set_constrained_string_option (handle, option, index, disable_compression_names, null)) + warning ("Unable to disable compression, please file a bug"); + } + + /* Set resolution and bit depth */ + option = get_option_by_name (handle, Sane.NAME_SCAN_RESOLUTION, out index); + if (option != null) + { + if (option.type == Sane.ValueType.FIXED) + set_fixed_option (handle, option, index, job.dpi, out job.dpi); + else + { + int dpi; + set_int_option (handle, option, index, (int) job.dpi, out dpi); + job.dpi = dpi; + } + option = get_option_by_name (handle, Sane.NAME_BIT_DEPTH, out index); + if (option != null) + { + if (job.depth > 0) + set_int_option (handle, option, index, job.depth, null); + } + } + /* Always use maximum scan area - some scanners default to using partial areas. This should be patched in sane-backends */ - if (br_x_option_index != 0) + option = get_option_by_name (handle, Sane.NAME_SCAN_BR_X, out index); + if (option != null) { - option = Sane.get_option_descriptor (handle, br_x_option_index); - debug ("sane_get_option_descriptor (%d)", (int) br_x_option_index); if (option.constraint_type == Sane.ConstraintType.RANGE) { if (option.type == Sane.ValueType.FIXED) - set_fixed_option (handle, option, br_x_option_index, Sane.UNFIX (option.range.max), null); + set_fixed_option (handle, option, index, Sane.UNFIX (option.range.max), null); else - set_int_option (handle, option, br_x_option_index, (int) option.range.max, null); + set_int_option (handle, option, index, (int) option.range.max, null); } } - if (br_y_option_index != 0) + option = get_option_by_name (handle, Sane.NAME_SCAN_BR_Y, out index); + if (option != null) { - option = Sane.get_option_descriptor (handle, br_y_option_index); - debug ("sane_get_option_descriptor (%d)", (int) br_y_option_index); if (option.constraint_type == Sane.ConstraintType.RANGE) { if (option.type == Sane.ValueType.FIXED) - set_fixed_option (handle, option, br_y_option_index, Sane.UNFIX (option.range.max), null); + set_fixed_option (handle, option, index, Sane.UNFIX (option.range.max), null); + else + set_int_option (handle, option, index, (int) option.range.max, null); + } + } + + option = get_option_by_name (handle, Sane.NAME_PAGE_WIDTH, out index); + if (option != null) + { + if (job.page_width > 0.0) + { + if (option.type == Sane.ValueType.FIXED) + set_fixed_option (handle, option, index, job.page_width / 10.0, null); + else + set_int_option (handle, option, index, job.page_width / 10, null); + } + } + option = get_option_by_name (handle, Sane.NAME_PAGE_HEIGHT, out index); + if (option != null) + { + if (job.page_height > 0.0) + { + if (option.type == Sane.ValueType.FIXED) + set_fixed_option (handle, option, index, job.page_height / 10.0, null); else - set_int_option (handle, option, br_y_option_index, (int) option.range.max, null); + set_int_option (handle, option, index, job.page_height / 10, null); } } + /* Test scanner options (hoping will not effect other scanners...) */ + if (current_device == "test") + { + option = get_option_by_name (handle, "hand-scanner", out index); + if (option != null) + set_bool_option (handle, option, index, false, null); + option = get_option_by_name (handle, "three-pass", out index); + if (option != null) + set_bool_option (handle, option, index, false, null); + option = get_option_by_name (handle, "test-picture", out index); + if (option != null) + set_string_option (handle, option, index, "Color pattern", null); + option = get_option_by_name (handle, "read-delay", out index); + if (option != null) + set_bool_option (handle, option, index, true, null); + option = get_option_by_name (handle, "read-delay-duration", out index); + if (option != null) + set_int_option (handle, option, index, 200000, null); + } + state = ScanState.START; return; } @@ -866,202 +1082,16 @@ public class Scanner if (option.name == null) return; - if (option.name == Sane.NAME_SCAN_RESOLUTION) - { - if (option.type == Sane.ValueType.FIXED) - set_fixed_option (handle, option, index, job.dpi, out job.dpi); - else - { - int dpi; - set_int_option (handle, option, index, (int) job.dpi, out dpi); - job.dpi = dpi; - } - } - else if (option.name == Sane.NAME_SCAN_SOURCE) - { - string[] flatbed_sources = - { - "Auto", - Sane.I18N ("Auto"), - "Flatbed", - Sane.I18N ("Flatbed"), - "FlatBed", - "Normal", - Sane.I18N ("Normal") - }; - - string[] adf_sources = - { - "Automatic Document Feeder", - Sane.I18N ("Automatic Document Feeder"), - "ADF", - "Automatic Document Feeder(left aligned)", /* Seen in the proprietary brother3 driver */ - "Automatic Document Feeder(centrally aligned)" /* Seen in the proprietary brother3 driver */ - }; - - string[] adf_front_sources = - { - "ADF Front", - Sane.I18N ("ADF Front") - }; - - string[] adf_back_sources = - { - "ADF Back", - Sane.I18N ("ADF Back") - }; - - string[] adf_duplex_sources = - { - "ADF Duplex", - Sane.I18N ("ADF Duplex") - }; + options.insert (option.name, (int) index); + } - switch (job.type) - { - case ScanType.SINGLE: - if (!set_default_option (handle, option, index)) - if (!set_constrained_string_option (handle, option, index, flatbed_sources, null)) - warning ("Unable to set single page source, please file a bug"); - break; - case ScanType.ADF_FRONT: - if (!set_constrained_string_option (handle, option, index, adf_front_sources, null)) - if (!!set_constrained_string_option (handle, option, index, adf_sources, null)) - warning ("Unable to set front ADF source, please file a bug"); - break; - case ScanType.ADF_BACK: - if (!set_constrained_string_option (handle, option, index, adf_back_sources, null)) - if (!set_constrained_string_option (handle, option, index, adf_sources, null)) - warning ("Unable to set back ADF source, please file a bug"); - break; - case ScanType.ADF_BOTH: - if (!set_constrained_string_option (handle, option, index, adf_duplex_sources, null)) - if (!set_constrained_string_option (handle, option, index, adf_sources, null)) - warning ("Unable to set duplex ADF source, please file a bug"); - break; - } - } - else if (option.name == "duplex") - { - if (option.type == Sane.ValueType.BOOL) - set_bool_option (handle, option, index, job.type == ScanType.ADF_BOTH, null); - } - else if (option.name == "batch-scan") - { - if (option.type == Sane.ValueType.BOOL) - set_bool_option (handle, option, index, job.type != ScanType.SINGLE, null); - } - else if (option.name == Sane.NAME_BIT_DEPTH) - { - if (job.depth > 0) - set_int_option (handle, option, index, job.depth, null); - } - else if (option.name == Sane.NAME_SCAN_MODE) - { - /* The names of scan modes often used in drivers, as taken from the sane-backends source */ - string[] color_scan_modes = - { - Sane.VALUE_SCAN_MODE_COLOR, - "Color", - "24bit Color" /* Seen in the proprietary brother3 driver */ - }; - string[] gray_scan_modes = - { - Sane.VALUE_SCAN_MODE_GRAY, - "Gray", - "Grayscale", - Sane.I18N ("Grayscale"), - "True Gray" /* Seen in the proprietary brother3 driver */ - }; - string[] lineart_scan_modes = - { - Sane.VALUE_SCAN_MODE_LINEART, - "Lineart", - "LineArt", - Sane.I18N ("LineArt"), - "Black & White", - Sane.I18N ("Black & White"), - "Binary", - Sane.I18N ("Binary"), - "Thresholded", - Sane.VALUE_SCAN_MODE_GRAY, - "Gray", - "Grayscale", - Sane.I18N ("Grayscale"), - "True Gray" /* Seen in the proprietary brother3 driver */ - }; - - switch (job.scan_mode) - { - case ScanMode.COLOR: - if (!set_constrained_string_option (handle, option, index, color_scan_modes, null)) - warning ("Unable to set Color mode, please file a bug"); - break; - case ScanMode.GRAY: - if (!set_constrained_string_option (handle, option, index, gray_scan_modes, null)) - warning ("Unable to set Gray mode, please file a bug"); - break; - case ScanMode.LINEART: - if (!set_constrained_string_option (handle, option, index, lineart_scan_modes, null)) - warning ("Unable to set Lineart mode, please file a bug"); - break; - default: - break; - } - } - /* Disable compression, we will compress after scanning */ - else if (option.name == "compression") - { - string[] disable_compression_names = - { - Sane.I18N ("None"), - Sane.I18N ("none"), - "None", - "none" - }; - - if (!set_constrained_string_option (handle, option, index, disable_compression_names, null)) - warning ("Unable to disable compression, please file a bug"); - } - else if (option.name == Sane.NAME_SCAN_BR_X) - br_x_option_index = index; - else if (option.name == Sane.NAME_SCAN_BR_Y) - br_y_option_index = index; - else if (option.name == Sane.NAME_PAGE_WIDTH) - { - if (job.page_width > 0.0) - { - if (option.type == Sane.ValueType.FIXED) - set_fixed_option (handle, option, index, job.page_width / 10.0, null); - else - set_int_option (handle, option, index, job.page_width / 10, null); - } - } - else if (option.name == Sane.NAME_PAGE_HEIGHT) - { - if (job.page_height > 0.0) - { - if (option.type == Sane.ValueType.FIXED) - set_fixed_option (handle, option, index, job.page_height / 10.0, null); - else - set_int_option (handle, option, index, job.page_height / 10, null); - } - } + private Sane.OptionDescriptor? get_option_by_name (Sane.Handle handle, string name, out int index) + { + index = options.lookup (name); + if (index == 0) + return null; - /* Test scanner options (hoping will not effect other scanners...) */ - if (current_device == "test") - { - if (option.name == "hand-scanner") - set_bool_option (handle, option, index, false, null); - else if (option.name == "three-pass") - set_bool_option (handle, option, index, false, null); - else if (option.name == "test-picture") - set_string_option (handle, option, index, "Color pattern", null); - else if (option.name == "read-delay") - set_bool_option (handle, option, index, true, null); - else if (option.name == "read-delay-duration") - set_int_option (handle, option, index, 200000, null); - } + return Sane.get_option_descriptor (handle, index); } private void do_complete_document () |