From 84ef34005ffa72079046b12429c79c5cf18e8718 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Voltz?= Date: Tue, 2 Mar 2010 06:38:19 +0100 Subject: [PATCH 1/6] enforce source geometry based on device description on source change - dynamically allocate SANE_Range for geometry - recompute ranges when source change using flatbed or xpa description --- backend/genesys.c | 101 ++++++++++++++++++++++++++++++++++------------ backend/genesys.h | 3 ++ 2 files changed, 79 insertions(+), 25 deletions(-) diff --git a/backend/genesys.c b/backend/genesys.c index 1e444647f..d6800587e 100644 --- a/backend/genesys.c +++ b/backend/genesys.c @@ -55,7 +55,7 @@ #include "../include/sane/config.h" -#define BUILD 12 +#define BUILD 13 #include #include @@ -114,23 +114,11 @@ static SANE_String_Const cis_color_filter_list[] = { }; static SANE_String_Const source_list[] = { - SANE_I18N ("Flatbed"), - SANE_I18N ("Transparency Adapter"), + SANE_I18N (FLATBED), + SANE_I18N (TRANSPARENCY_ADAPTER), 0 }; -static SANE_Range x_range = { - SANE_FIX (0.0), /* minimum */ - SANE_FIX (216.0), /* maximum */ - SANE_FIX (0.0) /* quantization */ -}; - -static SANE_Range y_range = { - SANE_FIX (0.0), /* minimum */ - SANE_FIX (299.0), /* maximum */ - SANE_FIX (0.0) /* quantization */ -}; - static SANE_Range time_range = { 0, /* minimum */ 60, /* maximum */ @@ -5334,7 +5322,7 @@ calc_parameters (Genesys_Scanner * s) s->dev->settings.scan_mode = SCAN_MODE_LINEART; /* todo: change and check */ - if (strcmp (source, "Flatbed") == 0) + if (strcmp (source, FLATBED) == 0) s->dev->settings.scan_method = SCAN_METHOD_FLATBED; else /* transparency */ s->dev->settings.scan_method = SCAN_METHOD_TRANSPARENCY; @@ -5427,6 +5415,26 @@ init_gamma_vector_option (Genesys_Scanner * scanner, int option) scanner->val[option].wa = NULL; } +/** + * allocate a geometry range + * @param size maximum size of the range + * @return a poiter to a valid range or NULL + */ +static create_range(SANE_Fixed size) +{ +SANE_Range *range=NULL; + + range=(SANE_Range *)malloc(sizeof(SANE_Range)); + if(range!=NULL) + { + range->min = SANE_FIX (0.0); + range->max = size; + range->quant = SANE_FIX (0.0); + } + return range; +} + + static SANE_Status init_options (Genesys_Scanner * s) { @@ -5435,6 +5443,7 @@ init_options (Genesys_Scanner * s) SANE_Word *dpi_list; Genesys_Model *model = s->dev->model; SANE_Bool has_ta; + SANE_Range *x_range, *y_range; DBG (DBG_proc, "init_options: start\n"); @@ -5482,7 +5491,7 @@ init_options (Genesys_Scanner * s) s->opt[OPT_SOURCE].constraint_type = SANE_CONSTRAINT_STRING_LIST; s->opt[OPT_SOURCE].size = max_string_size (source_list); s->opt[OPT_SOURCE].constraint.string_list = source_list; - s->val[OPT_SOURCE].s = strdup ("Flatbed"); + s->val[OPT_SOURCE].s = strdup (FLATBED); DISABLE (OPT_SOURCE); /* preview */ @@ -5533,8 +5542,17 @@ init_options (Genesys_Scanner * s) s->opt[OPT_GEOMETRY_GROUP].size = 0; s->opt[OPT_GEOMETRY_GROUP].constraint_type = SANE_CONSTRAINT_NONE; - x_range.max = model->x_size; - y_range.max = model->y_size; + x_range=create_range(model->x_size); + if(x_range==NULL) + { + return SANE_STATUS_NO_MEM; + } + + y_range=create_range(model->x_size); + if(y_range==NULL) + { + return SANE_STATUS_NO_MEM; + } /* top-left x */ s->opt[OPT_TL_X].name = SANE_NAME_SCAN_TL_X; @@ -5543,7 +5561,7 @@ init_options (Genesys_Scanner * s) s->opt[OPT_TL_X].type = SANE_TYPE_FIXED; s->opt[OPT_TL_X].unit = SANE_UNIT_MM; s->opt[OPT_TL_X].constraint_type = SANE_CONSTRAINT_RANGE; - s->opt[OPT_TL_X].constraint.range = &x_range; + s->opt[OPT_TL_X].constraint.range = x_range; s->val[OPT_TL_X].w = 0; /* top-left y */ @@ -5553,7 +5571,7 @@ init_options (Genesys_Scanner * s) s->opt[OPT_TL_Y].type = SANE_TYPE_FIXED; s->opt[OPT_TL_Y].unit = SANE_UNIT_MM; s->opt[OPT_TL_Y].constraint_type = SANE_CONSTRAINT_RANGE; - s->opt[OPT_TL_Y].constraint.range = &y_range; + s->opt[OPT_TL_Y].constraint.range = y_range; s->val[OPT_TL_Y].w = 0; /* bottom-right x */ @@ -5563,8 +5581,8 @@ init_options (Genesys_Scanner * s) s->opt[OPT_BR_X].type = SANE_TYPE_FIXED; s->opt[OPT_BR_X].unit = SANE_UNIT_MM; s->opt[OPT_BR_X].constraint_type = SANE_CONSTRAINT_RANGE; - s->opt[OPT_BR_X].constraint.range = &x_range; - s->val[OPT_BR_X].w = x_range.max; + s->opt[OPT_BR_X].constraint.range = x_range; + s->val[OPT_BR_X].w = x_range->max; /* bottom-right y */ s->opt[OPT_BR_Y].name = SANE_NAME_SCAN_BR_Y; @@ -5573,8 +5591,8 @@ init_options (Genesys_Scanner * s) s->opt[OPT_BR_Y].type = SANE_TYPE_FIXED; s->opt[OPT_BR_Y].unit = SANE_UNIT_MM; s->opt[OPT_BR_Y].constraint_type = SANE_CONSTRAINT_RANGE; - s->opt[OPT_BR_Y].constraint.range = &y_range; - s->val[OPT_BR_Y].w = y_range.max; + s->opt[OPT_BR_Y].constraint.range = y_range; + s->val[OPT_BR_Y].w = y_range->max; /* "Enhancement" group: */ s->opt[OPT_ENHANCEMENT_GROUP].title = SANE_I18N ("Enhancement"); @@ -6523,6 +6541,8 @@ sane_close (SANE_Handle handle) free (s->val[OPT_SOURCE].s); free (s->val[OPT_MODE].s); free (s->val[OPT_COLOR_FILTER].s); + FREE_IFNOT_NULL (s->opt[OPT_TL_X].constraint.range); + FREE_IFNOT_NULL (s->opt[OPT_TL_Y].constraint.range); if (prev) prev->next = s->next; @@ -6685,6 +6705,7 @@ set_option_value (Genesys_Scanner * s, int option, void *val, SANE_Status status = SANE_STATUS_GOOD; SANE_Word *table; unsigned int i; + SANE_Range *x_range, *y_range; Genesys_Calibration_Cache *cache, *next_cache; switch (option) @@ -6714,6 +6735,36 @@ set_option_value (Genesys_Scanner * s, int option, void *val, if (s->val[option].s) free (s->val[option].s); s->val[option].s = strdup (val); + + /* change geometry constraint to the new source value */ + if (strcmp (s->val[option].s, FLATBED) == 0) + { + x_range=create_range(s->dev->model->x_size); + y_range=create_range(s->dev->model->x_size); + } + else + { + x_range=create_range(s->dev->model->x_size_ta); + y_range=create_range(s->dev->model->x_size_ta); + } + if(x_range==NULL || y_range==NULL) + { + return SANE_STATUS_NO_MEM; + } + + /* assign new values */ + free(s->opt[OPT_TL_X].constraint.range); + free(s->opt[OPT_TL_Y].constraint.range); + s->opt[OPT_TL_X].constraint.range = x_range; + s->val[OPT_TL_X].w = 0; + s->opt[OPT_TL_Y].constraint.range = y_range; + s->val[OPT_TL_Y].w = 0; + s->opt[OPT_BR_X].constraint.range = x_range; + s->opt[OPT_BR_Y].constraint.range = y_range; + s->val[OPT_BR_Y].w = y_range->max; + s->val[OPT_BR_X].w = x_range->max; + + /* signals reload */ *myinfo |= SANE_INFO_RELOAD_PARAMS | SANE_INFO_RELOAD_OPTIONS; } break; diff --git a/backend/genesys.h b/backend/genesys.h index 6ef01a869..f85e9e6eb 100644 --- a/backend/genesys.h +++ b/backend/genesys.h @@ -58,6 +58,9 @@ /* Maximum time for lamp warm-up */ #define WARMUP_TIME 45 +#define FLATBED "Flatbed" +#define TRANSPARENCY_ADAPTER "Transparency Adapter" + #ifndef SANE_I18N #define SANE_I18N(text) text #endif From e5b413ea328f9d65e3d979c4ffe99591afe75f9b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Voltz?= Date: Tue, 2 Mar 2010 06:39:57 +0100 Subject: [PATCH 2/6] tune HP3670 XPA parameters --- backend/genesys_devices.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/backend/genesys_devices.c b/backend/genesys_devices.c index fd331f914..41f121abc 100644 --- a/backend/genesys_devices.c +++ b/backend/genesys_devices.c @@ -1060,12 +1060,12 @@ static Genesys_Model hp3670c_model = { SANE_FIX (0.0), /* Start of white strip in mm (y) */ SANE_FIX (1.0), /* Start of black mark in mm (x) */ - SANE_FIX (0.0), /* Start of scan area in TA mode in mm (x) */ - SANE_FIX (0.0), /* Start of scan area in TA mode in mm (y) */ - SANE_FIX (100.0), /* Size of scan area in TA mode in mm (x) */ + SANE_FIX (52.2), /* Start of scan area in TA mode in mm (x) */ + SANE_FIX (55.6), /* Start of scan area in TA mode in mm (y) */ + SANE_FIX (21.6), /* Size of scan area in TA mode in mm (x) */ SANE_FIX (100.0), /* Size of scan area in TA mode in mm (y) */ - SANE_FIX (0.0), /* Start of white strip in TA mode in mm (y) */ + SANE_FIX (43.2), /* Start of white strip in TA mode in mm (y) */ SANE_FIX (0.0), /* Size of scan area after paper sensor stops sensing document in mm */ @@ -1087,7 +1087,6 @@ static Genesys_Model hp3670c_model = { | GENESYS_FLAG_XPA | GENESYS_FLAG_DARK_CALIBRATION | GENESYS_FLAG_OFFSET_CALIBRATION - /* | GENESYS_FLAG_SKIP_WARMUP */ | GENESYS_FLAG_STAGGERED_LINE | GENESYS_FLAG_CUSTOM_GAMMA, GENESYS_HAS_COPY_SW | GENESYS_HAS_EMAIL_SW | GENESYS_HAS_SCAN_SW, From 32c1b061b84c4071aa6de1742c8188e69b2149e0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Voltz?= Date: Mon, 8 Mar 2010 06:39:22 +0100 Subject: [PATCH 3/6] adapt gl646 calibration to XPA usage --- backend/genesys_gl646.c | 48 ++++++++++++++++++++++++++++++----------- backend/genesys_low.h | 1 + 2 files changed, 36 insertions(+), 13 deletions(-) diff --git a/backend/genesys_gl646.c b/backend/genesys_gl646.c index 4130429c9..5f29cbeae 100644 --- a/backend/genesys_gl646.c +++ b/backend/genesys_gl646.c @@ -3214,7 +3214,7 @@ gl646_init_regs_for_shading (Genesys_Device * dev) } /* fill settings for scan : always a color scan */ - settings.scan_method = SCAN_METHOD_FLATBED; + settings.scan_method = dev->settings.scan_method; settings.scan_mode = dev->settings.scan_mode; if (dev->model->is_cis == SANE_FALSE) { @@ -3335,9 +3335,9 @@ setup_for_scan (Genesys_Device * dev, Genesys_Settings settings, DBG (DBG_proc, "setup_for_scan: start\n"); DBG (DBG_info, "setup_for_scan settings:\nResolution: %ux%uDPI\n" - "Lines : %u\nPixels : %u\nStartpos : %.3f/%.3f\nScan mode : %d\n\n", - settings.xres, settings.yres, settings.lines, - settings.pixels, settings.tl_x, settings.tl_y, settings.scan_mode); + "Lines : %u\nPixels : %u\nStartpos : %.3f/%.3f\nScan mode : %d\nScan method: %s\n\n", + settings.xres, settings.yres, settings.lines, settings.pixels, settings.tl_x, settings.tl_y, settings.scan_mode, + settings.scan_method==SCAN_METHOD_FLATBED ? "flatbed":"XPA"); if (settings.scan_mode == SCAN_MODE_COLOR) /* single pass color */ { @@ -4236,6 +4236,7 @@ gl646_coarse_gain_calibration (Genesys_Device * dev, int dpi) float average[3]; Genesys_Settings settings; char title[32]; + SANE_Bool move=SANE_TRUE; if (dev->model->ccd_type == CIS_XP200) { @@ -4260,14 +4261,23 @@ gl646_coarse_gain_calibration (Genesys_Device * dev, int dpi) get_closest_resolution (dev->model->ccd_type, dpi, SANE_TRUE); } - settings.scan_method = SCAN_METHOD_FLATBED; + settings.scan_method = dev->settings.scan_method; settings.scan_mode = SCAN_MODE_COLOR; settings.xres = resolution; settings.yres = resolution; - settings.tl_x = 0; - settings.tl_y = 0; - settings.pixels = - (dev->sensor.sensor_pixels * resolution) / dev->sensor.optical_res; + if(settings.scan_method==SCAN_METHOD_FLATBED) + { + settings.tl_x = 0; + settings.tl_y = 0; + settings.pixels = + (dev->sensor.sensor_pixels * resolution) / dev->sensor.optical_res; + } + else + { + settings.tl_x = (dev->model->x_offset_ta * resolution) / dev->sensor.optical_res; + settings.tl_y = (dev->model->y_offset_calib_ta * resolution) / dev->sensor.optical_res; + settings.pixels = (dev->model->x_size_ta * resolution) / dev->sensor.optical_res; + } settings.lines = CALIBRATION_LINES; settings.depth = 8; settings.color_filter = 0; @@ -4308,9 +4318,9 @@ gl646_coarse_gain_calibration (Genesys_Device * dev, int dpi) || (average[1] < dev->sensor.gain_white_ref) || (average[2] < dev->sensor.gain_white_ref)) && (pass < 30)) { - /* scan with no move */ + /* scan with no move but for first scan */ status = - simple_scan (dev, settings, SANE_FALSE, SANE_TRUE, SANE_FALSE, &line); + simple_scan (dev, settings, move, SANE_TRUE, SANE_FALSE, &line); if (status != SANE_STATUS_GOOD) { DBG (DBG_error, @@ -4318,6 +4328,10 @@ gl646_coarse_gain_calibration (Genesys_Device * dev, int dpi) return status; } + /* after first scan, we don't move anymore */ + move = SANE_TRUE; + settings.tl_y = 0; + /* log scanning data */ if (DBG_LEVEL >= DBG_data) { @@ -4939,6 +4953,12 @@ simple_scan (Genesys_Device * dev, Genesys_Settings settings, SANE_Bool move, dev->reg[reg_0x02].value &= ~REG02_MTRREV; } + /* no automatic go home when using XPA */ + if(settings.scan_method==SCAN_METHOD_TRANSPARENCY) + { + dev->reg[reg_0x02].value &= ~REG02_AGOHOME; + } + /* write scan registers */ status = gl646_bulk_write_register (dev, dev->reg, sizeof (dev->reg) / @@ -5305,8 +5325,7 @@ gl646_is_compatible_calibration (Genesys_Device * dev, "gl646_is_compatible_calibration: start (for_overwrite=%d)\n", for_overwrite); - /* calibration caching not supported yet for HP3670 */ - if (cache == NULL || dev->model->ccd_type == CCD_HP2400) + if (cache == NULL) return SANE_STATUS_UNSUPPORTED; /* build minimal current_setup for calibration cache use only, it will be better @@ -5321,6 +5340,7 @@ gl646_is_compatible_calibration (Genesys_Device * dev, dev->current_setup.channels = 1; } dev->current_setup.xres = dev->settings.xres; + dev->current_setup.scan_method = dev->settings.scan_method; DBG (DBG_io, "gl646_is_compatible_calibration: requested=(%d,%f), tested=(%d,%f)\n", @@ -5335,6 +5355,8 @@ gl646_is_compatible_calibration (Genesys_Device * dev, ((dev->current_setup.channels == cache->used_setup.channels) && (((int) dev->current_setup.xres) == ((int) cache->used_setup.xres))); + if(dev->current_setup.scan_method != cache->used_setup.scan_method) + compatible = SANE_STATUS_UNSUPPORTED; } else { diff --git a/backend/genesys_low.h b/backend/genesys_low.h index a65613e31..0c792b5c3 100644 --- a/backend/genesys_low.h +++ b/backend/genesys_low.h @@ -520,6 +520,7 @@ typedef struct Genesys_Current_Setup int lines; /* line count expected from scanner */ int depth; /* depth expected from scanner */ int channels; /* channel count expected from scanner */ + int scan_method; /* scanning method: flatbed or XPA */ int exposure_time; /* used exposure time */ float xres; /* used xres */ float yres; /* used yres*/ From 7e95fd836509a05c8871a61e3426bec4e554f64a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Voltz?= Date: Tue, 9 Mar 2010 22:22:43 +0100 Subject: [PATCH 4/6] fixed ta size handling and gl646 calibration --- backend/genesys.c | 8 ++++---- backend/genesys_devices.c | 2 +- backend/genesys_gl646.c | 29 +++++++++++++++++------------ 3 files changed, 22 insertions(+), 17 deletions(-) diff --git a/backend/genesys.c b/backend/genesys.c index d6800587e..9fe973234 100644 --- a/backend/genesys.c +++ b/backend/genesys.c @@ -5548,7 +5548,7 @@ init_options (Genesys_Scanner * s) return SANE_STATUS_NO_MEM; } - y_range=create_range(model->x_size); + y_range=create_range(model->y_size); if(y_range==NULL) { return SANE_STATUS_NO_MEM; @@ -6740,12 +6740,12 @@ set_option_value (Genesys_Scanner * s, int option, void *val, if (strcmp (s->val[option].s, FLATBED) == 0) { x_range=create_range(s->dev->model->x_size); - y_range=create_range(s->dev->model->x_size); + y_range=create_range(s->dev->model->y_size); } else { x_range=create_range(s->dev->model->x_size_ta); - y_range=create_range(s->dev->model->x_size_ta); + y_range=create_range(s->dev->model->y_size_ta); } if(x_range==NULL || y_range==NULL) { @@ -6760,8 +6760,8 @@ set_option_value (Genesys_Scanner * s, int option, void *val, s->opt[OPT_TL_Y].constraint.range = y_range; s->val[OPT_TL_Y].w = 0; s->opt[OPT_BR_X].constraint.range = x_range; - s->opt[OPT_BR_Y].constraint.range = y_range; s->val[OPT_BR_Y].w = y_range->max; + s->opt[OPT_BR_Y].constraint.range = y_range; s->val[OPT_BR_X].w = x_range->max; /* signals reload */ diff --git a/backend/genesys_devices.c b/backend/genesys_devices.c index 41f121abc..dd448b65e 100644 --- a/backend/genesys_devices.c +++ b/backend/genesys_devices.c @@ -1062,7 +1062,7 @@ static Genesys_Model hp3670c_model = { SANE_FIX (52.2), /* Start of scan area in TA mode in mm (x) */ SANE_FIX (55.6), /* Start of scan area in TA mode in mm (y) */ - SANE_FIX (21.6), /* Size of scan area in TA mode in mm (x) */ + SANE_FIX (25.6), /* Size of scan area in TA mode in mm (x) */ SANE_FIX (100.0), /* Size of scan area in TA mode in mm (y) */ SANE_FIX (43.2), /* Start of white strip in TA mode in mm (y) */ diff --git a/backend/genesys_gl646.c b/backend/genesys_gl646.c index 5f29cbeae..f6fe096f2 100644 --- a/backend/genesys_gl646.c +++ b/backend/genesys_gl646.c @@ -4139,11 +4139,9 @@ ad_fe_coarse_gain_calibration (Genesys_Device * dev, int dpi) /* setup for a RGB scan, one full sensor's width line */ /* resolution is the one from the final scan */ - resolution = - get_closest_resolution (dev->model->ccd_type, dpi, SANE_TRUE); - channels = 3; - settings.scan_mode = SCAN_MODE_COLOR; - + resolution = get_closest_resolution (dev->model->ccd_type, dpi, SANE_TRUE); + channels = 3; + settings.scan_mode = SCAN_MODE_COLOR; settings.scan_method = SCAN_METHOD_FLATBED; settings.xres = resolution; @@ -4224,7 +4222,10 @@ ad_fe_coarse_gain_calibration (Genesys_Device * dev, int dpi) /** * Alternative coarse gain calibration - * this on uses the settings from offset_calibration. + * this on uses the settings from offset_calibration. First scan moves so + * we can go to calibration area for XPA. + * @param dev device for scan + * @param dpi resolutnio to calibrate at */ static SANE_Status gl646_coarse_gain_calibration (Genesys_Device * dev, int dpi) @@ -4258,7 +4259,7 @@ gl646_coarse_gain_calibration (Genesys_Device * dev, int dpi) else { resolution = - get_closest_resolution (dev->model->ccd_type, dpi, SANE_TRUE); + get_closest_resolution (dev->model->ccd_type, dev->settings.xres, SANE_TRUE); } settings.scan_method = dev->settings.scan_method; @@ -4305,10 +4306,7 @@ gl646_coarse_gain_calibration (Genesys_Device * dev, int dpi) average[0] = 255; average[1] = 255; average[2] = 255; - if (dev->model->ccd_type == CIS_XP200) - idx = 0; - else - idx = dev->settings.color_filter; + idx = dev->settings.color_filter; average[idx] = 0; } pass = 0; @@ -4329,7 +4327,7 @@ gl646_coarse_gain_calibration (Genesys_Device * dev, int dpi) } /* after first scan, we don't move anymore */ - move = SANE_TRUE; + move = SANE_FALSE; settings.tl_y = 0; /* log scanning data */ @@ -4870,6 +4868,7 @@ simple_scan (Genesys_Device * dev, Genesys_Settings settings, SANE_Bool move, unsigned char *buffer; DBG (DBG_proc, "simple_scan: starting\n"); + DBG (DBG_io, "simple_scan: move=%d, forward=%d, shading=%d\n",move,forward,shading); /* round up to multiple of 3 in case of CIS scanner */ if (dev->model->is_cis == SANE_TRUE) @@ -4984,6 +4983,12 @@ simple_scan (Genesys_Device * dev, Genesys_Settings settings, SANE_Bool move, /* wait for buffers to be filled */ do { + usleep (10000UL); + RIE (sanei_genesys_get_status (dev, &empty)); + if (DBG_LEVEL > DBG_info) + { + print_status (empty); + } RIE (sanei_genesys_test_buffer_empty (dev, &empty)); } while (empty); From 598d3c82baa9176bea13672daa51bd91cb44ca97 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Voltz?= Date: Thu, 11 Mar 2010 06:12:04 +0100 Subject: [PATCH 5/6] XPA support fixes --- backend/genesys_gl646.c | 50 +++++++++++++++++++++++++++++++---------- 1 file changed, 38 insertions(+), 12 deletions(-) diff --git a/backend/genesys_gl646.c b/backend/genesys_gl646.c index f6fe096f2..9820ff6e4 100644 --- a/backend/genesys_gl646.c +++ b/backend/genesys_gl646.c @@ -3297,7 +3297,7 @@ gl646_init_regs_for_scan (Genesys_Device * dev) SANE_Status status; /* park head after calibration if needed */ - if (dev->scanhead_position_in_steps > 0) + if (dev->scanhead_position_in_steps > 0 && settings.scan_method==SCAN_METHOD_FLATBED) { status = gl646_slow_back_home (dev, SANE_TRUE); if (status != SANE_STATUS_GOOD) @@ -4237,7 +4237,7 @@ gl646_coarse_gain_calibration (Genesys_Device * dev, int dpi) float average[3]; Genesys_Settings settings; char title[32]; - SANE_Bool move=SANE_TRUE; + SANE_Bool move=SANE_FALSE; if (dev->model->ccd_type == CIS_XP200) { @@ -4272,12 +4272,14 @@ gl646_coarse_gain_calibration (Genesys_Device * dev, int dpi) settings.tl_y = 0; settings.pixels = (dev->sensor.sensor_pixels * resolution) / dev->sensor.optical_res; + move=SANE_FALSE; } else { - settings.tl_x = (dev->model->x_offset_ta * resolution) / dev->sensor.optical_res; - settings.tl_y = (dev->model->y_offset_calib_ta * resolution) / dev->sensor.optical_res; - settings.pixels = (dev->model->x_size_ta * resolution) / dev->sensor.optical_res; + settings.tl_x = (SANE_UNFIX(dev->model->x_offset_ta) * resolution) / MM_PER_INCH; + settings.tl_y = (SANE_UNFIX(dev->model->y_offset_calib_ta) * resolution) / MM_PER_INCH; + settings.pixels = (SANE_UNFIX(dev->model->x_size_ta) * resolution) / MM_PER_INCH; + move=SANE_TRUE; } settings.lines = CALIBRATION_LINES; settings.depth = 8; @@ -4864,8 +4866,10 @@ simple_scan (Genesys_Device * dev, Genesys_Settings settings, SANE_Bool move, { SANE_Status status = SANE_STATUS_INVAL; unsigned int size, lines, x, y, bpp; - SANE_Bool empty; + SANE_Bool empty, split; unsigned char *buffer; + int count; + u_int8_t val; DBG (DBG_proc, "simple_scan: starting\n"); DBG (DBG_io, "simple_scan: move=%d, forward=%d, shading=%d\n",move,forward,shading); @@ -4876,7 +4880,16 @@ simple_scan (Genesys_Device * dev, Genesys_Settings settings, SANE_Bool move, settings.lines = ((settings.lines + 2) / 3) * 3; } - status = setup_for_scan (dev, settings, SANE_TRUE, SANE_FALSE, SANE_FALSE); + /* setup for move then scan */ + if(move==SANE_TRUE && settings.tl_y >0) + { + split=SANE_FALSE; + } + else + { + split=SANE_TRUE; + } + status = setup_for_scan (dev, settings, split, SANE_FALSE, SANE_FALSE); if (status != SANE_STATUS_GOOD) { DBG (DBG_error, "simple_scan: setup_for_scan failed (%s)\n", @@ -4981,17 +4994,26 @@ simple_scan (Genesys_Device * dev, Genesys_Settings settings, SANE_Bool move, } /* wait for buffers to be filled */ + count=0; do { usleep (10000UL); - RIE (sanei_genesys_get_status (dev, &empty)); + RIE (sanei_genesys_get_status (dev, &val)); if (DBG_LEVEL > DBG_info) { - print_status (empty); + print_status (val); } RIE (sanei_genesys_test_buffer_empty (dev, &empty)); + count++; + } + while (empty && count <1000); + if(count==1000) + { + free (*data); + DBG (DBG_error, + "simple_scan: failed toread data\n"); + return SANE_STATUS_IO_ERROR; } - while (empty); /* now we're on target, we can read data */ status = sanei_genesys_read_data_from_scanner (dev, *data, size); @@ -5360,14 +5382,18 @@ gl646_is_compatible_calibration (Genesys_Device * dev, ((dev->current_setup.channels == cache->used_setup.channels) && (((int) dev->current_setup.xres) == ((int) cache->used_setup.xres))); - if(dev->current_setup.scan_method != cache->used_setup.scan_method) - compatible = SANE_STATUS_UNSUPPORTED; } else { compatible = (dev->current_setup.channels == cache->used_setup.channels); } + if(dev->current_setup.scan_method != cache->used_setup.scan_method) + { + DBG (DBG_io, "gl646_is_compatible_calibration: current method=%d, used=%d\n", + dev->current_setup.scan_method, cache->used_setup.scan_method); + compatible = SANE_STATUS_UNSUPPORTED; + } if (!compatible) { DBG (DBG_proc, From f91ceaddf4bc7a6c00f93c002551f8f68d243417 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Voltz?= Date: Mon, 15 Mar 2010 06:24:23 +0100 Subject: [PATCH 6/6] working transparency support for gl646 based scanners - add move to transparency adapter function to command set - no warmup when using transparency adapter - increase maximum warmup time to match HP3670 requirements - tune HP3670's transparency adapter geometry - handle calibration area geometry in gain calibration - add simple move head function for gl646 based scanners --- backend/genesys.c | 22 +++- backend/genesys.h | 2 +- backend/genesys_devices.c | 6 +- backend/genesys_gl646.c | 217 ++++++++++++++++++++++++++++---------- backend/genesys_gl646.h | 13 +++ backend/genesys_gl841.c | 1 + backend/genesys_low.h | 8 +- 7 files changed, 208 insertions(+), 61 deletions(-) diff --git a/backend/genesys.c b/backend/genesys.c index 9fe973234..5784b56b0 100644 --- a/backend/genesys.c +++ b/backend/genesys.c @@ -4309,8 +4309,10 @@ genesys_start_scan (Genesys_Device * dev) return status; } - /* wait for lamp warmup */ - if (!(dev->model->flags & GENESYS_FLAG_SKIP_WARMUP)) + /* wait for lamp warmup : until a warmup for TRANSPARENCY is designed, skip + * it when scanning from XPA */ + if (!(dev->model->flags & GENESYS_FLAG_SKIP_WARMUP) + && (dev->settings.scan_method == SCAN_METHOD_FLATBED)) { RIE (genesys_warmup_lamp (dev)); } @@ -4358,6 +4360,20 @@ genesys_start_scan (Genesys_Device * dev) } } + /* move to calibration area for transparency adapter */ + if ((dev->settings.scan_method == SCAN_METHOD_TRANSPARENCY) + && dev->model->cmd_set->move_to_ta != NULL) + { + status=dev->model->cmd_set->move_to_ta(dev); + if (status != SANE_STATUS_GOOD) + { + DBG (DBG_error, + "genesys_start_scan: failed to move to start of transparency adapter: %s\n", + sane_strstatus (status)); + return status; + } + } + /* load document if needed (for sheetfed scanner for instance) */ if (dev->model->is_sheetfed == SANE_TRUE && dev->model->cmd_set->load_document != NULL) @@ -4518,7 +4534,7 @@ genesys_start_scan (Genesys_Device * dev) if (status != SANE_STATUS_GOOD) { DBG (DBG_error, - "genesys_start_scan: Failed to read valid words: %s\n", + "genesys_start_scan: failed to read valid words: %s\n", sane_strstatus (status)); return status; } diff --git a/backend/genesys.h b/backend/genesys.h index f85e9e6eb..0c474042b 100644 --- a/backend/genesys.h +++ b/backend/genesys.h @@ -56,7 +56,7 @@ #define GENESYS_CONFIG_FILE "genesys.conf" /* Maximum time for lamp warm-up */ -#define WARMUP_TIME 45 +#define WARMUP_TIME 65 #define FLATBED "Flatbed" #define TRANSPARENCY_ADAPTER "Transparency Adapter" diff --git a/backend/genesys_devices.c b/backend/genesys_devices.c index dd448b65e..7d7baddd8 100644 --- a/backend/genesys_devices.c +++ b/backend/genesys_devices.c @@ -1060,12 +1060,12 @@ static Genesys_Model hp3670c_model = { SANE_FIX (0.0), /* Start of white strip in mm (y) */ SANE_FIX (1.0), /* Start of black mark in mm (x) */ - SANE_FIX (52.2), /* Start of scan area in TA mode in mm (x) */ + SANE_FIX (104.0), /* Start of scan area in TA mode in mm (x) */ SANE_FIX (55.6), /* Start of scan area in TA mode in mm (y) */ SANE_FIX (25.6), /* Size of scan area in TA mode in mm (x) */ - SANE_FIX (100.0), /* Size of scan area in TA mode in mm (y) */ + SANE_FIX (78.0), /* Size of scan area in TA mode in mm (y) */ - SANE_FIX (43.2), /* Start of white strip in TA mode in mm (y) */ + SANE_FIX (76.0), /* Start of white strip in TA mode in mm (y) */ SANE_FIX (0.0), /* Size of scan area after paper sensor stops sensing document in mm */ diff --git a/backend/genesys_gl646.c b/backend/genesys_gl646.c index 9820ff6e4..54beaa990 100644 --- a/backend/genesys_gl646.c +++ b/backend/genesys_gl646.c @@ -530,6 +530,39 @@ gl646_stop_motor (Genesys_Device * dev) } +/** + * find the lowest resolution for the sensor in the given mode. + * @param sensor id of the sensor + * @param required required resolution + * @param color true is color mode + * @return the closest resolution for the sensor and mode + */ +static int +get_lowest_resolution (int sensor, SANE_Bool color) +{ + int i, nb; + int dpi; + + i = 0; + dpi = 9600; + nb = sizeof (sensor_master) / sizeof (Sensor_Master); + while (sensor_master[i].sensor != -1 && i < nb) + { + /* computes distance and keep mode if it is closer than previous */ + if (sensor == sensor_master[i].sensor + && sensor_master[i].color == color) + { + if (sensor_master[i].dpi < dpi) + { + dpi = sensor_master[i].dpi; + } + } + i++; + } + DBG (DBG_info, "get_lowest_resolution: %d\n", dpi); + return dpi; +} + /** * find the closest match in mode tables for the given resolution and scan mode. * @param sensor id of the sensor @@ -993,13 +1026,15 @@ gl646_setup_registers (Genesys_Device * dev, if ((!half_ccd) && (dev->model->flags & GENESYS_FLAG_STAGGERED_LINE)) { /* for HP3670, stagger happens only at >=1200 dpi */ - if((dev->model->motor_type != MOTOR_HP3670 && dev->model->motor_type != MOTOR_HP2400)|| scan_settings.yres >= dev->sensor.optical_res) - { - stagger = (4 * scan_settings.yres) / dev->motor.base_ydpi; - } + if ((dev->model->motor_type != MOTOR_HP3670 + && dev->model->motor_type != MOTOR_HP2400) + || scan_settings.yres >= dev->sensor.optical_res) + { + stagger = (4 * scan_settings.yres) / dev->motor.base_ydpi; + } } linecnt += stagger; - + DBG (DBG_info, "gl646_setup_registers : max_shift=%d, stagger=%d lines\n", max_shift, stagger); @@ -3198,7 +3233,7 @@ gl646_init_regs_for_shading (Genesys_Device * dev) Genesys_Settings settings; /* 1: no half_ccd, 2: use half number of pixels */ int half_ccd = 1; - int cksel=1; + int cksel = 1; DBG (DBG_proc, "gl646_init_register_for_shading: start\n"); @@ -3221,7 +3256,7 @@ gl646_init_regs_for_shading (Genesys_Device * dev) settings.scan_mode = SCAN_MODE_COLOR; } settings.xres = dev->sensor.optical_res / half_ccd; - cksel=get_cksel(dev->model->ccd_type, dev->settings.xres, SANE_TRUE); + cksel = get_cksel (dev->model->ccd_type, dev->settings.xres, SANE_TRUE); settings.xres = settings.xres / cksel; settings.yres = settings.xres; settings.tl_x = 0; @@ -3297,7 +3332,8 @@ gl646_init_regs_for_scan (Genesys_Device * dev) SANE_Status status; /* park head after calibration if needed */ - if (dev->scanhead_position_in_steps > 0 && settings.scan_method==SCAN_METHOD_FLATBED) + if (dev->scanhead_position_in_steps > 0 + && dev->settings.scan_method == SCAN_METHOD_FLATBED) { status = gl646_slow_back_home (dev, SANE_TRUE); if (status != SANE_STATUS_GOOD) @@ -3336,8 +3372,9 @@ setup_for_scan (Genesys_Device * dev, Genesys_Settings settings, DBG (DBG_info, "setup_for_scan settings:\nResolution: %ux%uDPI\n" "Lines : %u\nPixels : %u\nStartpos : %.3f/%.3f\nScan mode : %d\nScan method: %s\n\n", - settings.xres, settings.yres, settings.lines, settings.pixels, settings.tl_x, settings.tl_y, settings.scan_mode, - settings.scan_method==SCAN_METHOD_FLATBED ? "flatbed":"XPA"); + settings.xres, settings.yres, settings.lines, settings.pixels, + settings.tl_x, settings.tl_y, settings.scan_mode, + settings.scan_method == SCAN_METHOD_FLATBED ? "flatbed" : "XPA"); if (settings.scan_mode == SCAN_MODE_COLOR) /* single pass color */ { @@ -3393,9 +3430,18 @@ setup_for_scan (Genesys_Device * dev, Genesys_Settings settings, startx = dev->sensor.CCD_start_xoffset; else startx = dev->sensor.dummy_pixel; - startx += - ((SANE_UNFIX (dev->model->x_offset) * dev->sensor.optical_res) / - MM_PER_INCH); + if (settings.scan_method == SCAN_METHOD_FLATBED) + { + startx += + ((SANE_UNFIX (dev->model->x_offset) * dev->sensor.optical_res) / + MM_PER_INCH); + } + else + { + startx += + ((SANE_UNFIX (dev->model->x_offset_ta) * + dev->sensor.optical_res) / MM_PER_INCH); + } } else { @@ -3442,7 +3488,7 @@ setup_for_scan (Genesys_Device * dev, Genesys_Settings settings, /* select color filter based on settings */ dev->reg[reg_0x04].value &= ~REG04_FILTER; - if(channels==1) + if (channels == 1) { switch (settings.color_filter) { @@ -4237,7 +4283,6 @@ gl646_coarse_gain_calibration (Genesys_Device * dev, int dpi) float average[3]; Genesys_Settings settings; char title[32]; - SANE_Bool move=SANE_FALSE; if (dev->model->ccd_type == CIS_XP200) { @@ -4259,27 +4304,26 @@ gl646_coarse_gain_calibration (Genesys_Device * dev, int dpi) else { resolution = - get_closest_resolution (dev->model->ccd_type, dev->settings.xres, SANE_TRUE); + get_closest_resolution (dev->model->ccd_type, dev->settings.xres, + SANE_TRUE); } settings.scan_method = dev->settings.scan_method; settings.scan_mode = SCAN_MODE_COLOR; settings.xres = resolution; settings.yres = resolution; - if(settings.scan_method==SCAN_METHOD_FLATBED) + settings.tl_y = 0; + if (settings.scan_method == SCAN_METHOD_FLATBED) { settings.tl_x = 0; - settings.tl_y = 0; settings.pixels = - (dev->sensor.sensor_pixels * resolution) / dev->sensor.optical_res; - move=SANE_FALSE; + (dev->sensor.sensor_pixels * resolution) / dev->sensor.optical_res; } else { - settings.tl_x = (SANE_UNFIX(dev->model->x_offset_ta) * resolution) / MM_PER_INCH; - settings.tl_y = (SANE_UNFIX(dev->model->y_offset_calib_ta) * resolution) / MM_PER_INCH; - settings.pixels = (SANE_UNFIX(dev->model->x_size_ta) * resolution) / MM_PER_INCH; - move=SANE_TRUE; + settings.tl_x = SANE_UNFIX (dev->model->x_offset_ta); + settings.pixels = + (SANE_UNFIX (dev->model->x_size_ta) * resolution) / MM_PER_INCH; } settings.lines = CALIBRATION_LINES; settings.depth = 8; @@ -4318,9 +4362,9 @@ gl646_coarse_gain_calibration (Genesys_Device * dev, int dpi) || (average[1] < dev->sensor.gain_white_ref) || (average[2] < dev->sensor.gain_white_ref)) && (pass < 30)) { - /* scan with no move but for first scan */ + /* scan with no move */ status = - simple_scan (dev, settings, move, SANE_TRUE, SANE_FALSE, &line); + simple_scan (dev, settings, SANE_FALSE, SANE_TRUE, SANE_FALSE, &line); if (status != SANE_STATUS_GOOD) { DBG (DBG_error, @@ -4328,10 +4372,6 @@ gl646_coarse_gain_calibration (Genesys_Device * dev, int dpi) return status; } - /* after first scan, we don't move anymore */ - move = SANE_FALSE; - settings.tl_y = 0; - /* log scanning data */ if (DBG_LEVEL >= DBG_data) { @@ -4456,7 +4496,7 @@ gl646_init_regs_for_warmup (Genesys_Device * dev, /* don't enable any correction for this scan */ dev->reg[reg_0x01].value &= ~REG01_DVDSET; /* XXX STEF XXX - dev->reg[reg_0x05].value &= ~REG05_GMMENB; */ + dev->reg[reg_0x05].value &= ~REG05_GMMENB; */ /* turn off motor during this scan */ gl646_set_motor_power (local_reg, SANE_FALSE); @@ -4846,6 +4886,26 @@ gl646_init (Genesys_Device * dev) return SANE_STATUS_GOOD; } +#ifndef UNIT_TESTING +static +#endif +gl646_move_to_ta (Genesys_Device * dev) +{ + SANE_Status status = SANE_STATUS_GOOD; + + DBG (DBG_proc, "gl646_move_to_ta: starting\n"); + if (simple_move (dev, SANE_UNFIX (dev->model->y_offset_calib_ta)) != + SANE_STATUS_GOOD) + { + DBG (DBG_error, + "gl646_move_to_ta: failed to move to calibration area\n"); + return status; + } + DBG (DBG_proc, "gl646_move_to_ta: end\n"); + + return status; +} + /** * Does a simple scan: ie no line reordering and avanced data buffering and @@ -4872,7 +4932,8 @@ simple_scan (Genesys_Device * dev, Genesys_Settings settings, SANE_Bool move, u_int8_t val; DBG (DBG_proc, "simple_scan: starting\n"); - DBG (DBG_io, "simple_scan: move=%d, forward=%d, shading=%d\n",move,forward,shading); + DBG (DBG_io, "simple_scan: move=%d, forward=%d, shading=%d\n", move, + forward, shading); /* round up to multiple of 3 in case of CIS scanner */ if (dev->model->is_cis == SANE_TRUE) @@ -4881,13 +4942,13 @@ simple_scan (Genesys_Device * dev, Genesys_Settings settings, SANE_Bool move, } /* setup for move then scan */ - if(move==SANE_TRUE && settings.tl_y >0) + if (move == SANE_TRUE && settings.tl_y > 0) { - split=SANE_FALSE; + split = SANE_FALSE; } else { - split=SANE_TRUE; + split = SANE_TRUE; } status = setup_for_scan (dev, settings, split, SANE_FALSE, SANE_FALSE); if (status != SANE_STATUS_GOOD) @@ -4966,7 +5027,7 @@ simple_scan (Genesys_Device * dev, Genesys_Settings settings, SANE_Bool move, } /* no automatic go home when using XPA */ - if(settings.scan_method==SCAN_METHOD_TRANSPARENCY) + if (settings.scan_method == SCAN_METHOD_TRANSPARENCY) { dev->reg[reg_0x02].value &= ~REG02_AGOHOME; } @@ -4994,24 +5055,23 @@ simple_scan (Genesys_Device * dev, Genesys_Settings settings, SANE_Bool move, } /* wait for buffers to be filled */ - count=0; + count = 0; do { usleep (10000UL); RIE (sanei_genesys_get_status (dev, &val)); if (DBG_LEVEL > DBG_info) - { - print_status (val); - } + { + print_status (val); + } RIE (sanei_genesys_test_buffer_empty (dev, &empty)); count++; } - while (empty && count <1000); - if(count==1000) + while (empty && count < 1000); + if (count == 1000) { free (*data); - DBG (DBG_error, - "simple_scan: failed toread data\n"); + DBG (DBG_error, "simple_scan: failed toread data\n"); return SANE_STATUS_IO_ERROR; } @@ -5104,6 +5164,55 @@ simple_scan (Genesys_Device * dev, Genesys_Settings settings, SANE_Bool move, return status; } +/** + * Does a simple move of the given distance by doing a scan at lowest resolution + * shading correction. Memory for data is allocated in this function + * and must be freed by caller. + * @param dev device of the scanner + * @param distance distance to move in MM + */ +#ifndef UNIT_TESTING +static +#endif + SANE_Status +simple_move (Genesys_Device * dev, SANE_Int distance) +{ + SANE_Status status = SANE_STATUS_INVAL; + unsigned char *data = NULL; + Genesys_Settings settings; + + DBG (DBG_proc, "simple_move: %d mm\n", distance); + + /* TODO give a no AGOHOME flag */ + settings.scan_method = SCAN_METHOD_TRANSPARENCY; + settings.scan_mode = SCAN_MODE_COLOR; + settings.xres = get_lowest_resolution (dev->model->ccd_type, SANE_TRUE); + settings.yres = settings.xres; + settings.tl_y = 0; + settings.tl_x = 0; + settings.pixels = + (dev->sensor.sensor_pixels * settings.xres) / dev->sensor.optical_res; + settings.lines = (distance * settings.xres) / MM_PER_INCH; + settings.depth = 8; + settings.color_filter = 0; + + settings.disable_interpolation = 0; + settings.threshold = 0; + settings.exposure_time = 0; + + status = + simple_scan (dev, settings, SANE_TRUE, SANE_TRUE, SANE_FALSE, &data); + free (data); + if (status != SANE_STATUS_GOOD) + { + DBG (DBG_error, "simple_move: simple_scan failed\n"); + return status; + } + + DBG (DBG_proc, "simple_move: end.\n"); + return status; +} + /** * update the status of the required sensor in the scanner session * the last_val fileds are used to make events 'sticky' @@ -5388,11 +5497,12 @@ gl646_is_compatible_calibration (Genesys_Device * dev, compatible = (dev->current_setup.channels == cache->used_setup.channels); } - if(dev->current_setup.scan_method != cache->used_setup.scan_method) + if (dev->current_setup.scan_method != cache->used_setup.scan_method) { - DBG (DBG_io, "gl646_is_compatible_calibration: current method=%d, used=%d\n", - dev->current_setup.scan_method, cache->used_setup.scan_method); - compatible = SANE_STATUS_UNSUPPORTED; + DBG (DBG_io, + "gl646_is_compatible_calibration: current method=%d, used=%d\n", + dev->current_setup.scan_method, cache->used_setup.scan_method); + compatible = 0; } if (!compatible) { @@ -5401,12 +5511,12 @@ gl646_is_compatible_calibration (Genesys_Device * dev, return SANE_STATUS_UNSUPPORTED; } - /* a cache entry expires after 10 minutes for non CIS scanners */ - /* TODO have depend on s->val[OPT_LAMP_OFF_TIME].w */ + /* a cache entry expires after 30 minutes for non CIS scanners */ #ifdef HAVE_SYS_TIME_H gettimeofday (&time, NULL); - if ((time.tv_sec - cache->last_calibration > 10 * 60) - && (dev->model->is_cis == SANE_FALSE)) + if ((time.tv_sec - cache->last_calibration > 30 * 60) + && (dev->model->is_cis == SANE_FALSE) + && (dev->settings.scan_method == SCAN_METHOD_FLATBED)) { DBG (DBG_proc, "gl646_is_compatible_calibration: expired entry, non compatible cache\n"); @@ -5641,7 +5751,8 @@ static Genesys_Command_Set gl646_cmd_set = { gl646_eject_document, gl646_search_strip, - gl646_is_compatible_calibration + gl646_is_compatible_calibration, + gl646_move_to_ta }; SANE_Status diff --git a/backend/genesys_gl646.h b/backend/genesys_gl646.h index e45711310..c51f99377 100644 --- a/backend/genesys_gl646.h +++ b/backend/genesys_gl646.h @@ -312,6 +312,19 @@ gl646_setup_registers (Genesys_Device * dev, uint16_t startx, uint16_t endx, SANE_Bool color, SANE_Int depth); +/** + * Does a simple move of the given distance by doing a scan at lowest resolution + * shading correction. Memory for data is allocated in this function + * and must be freed by caller. + * @param dev device of the scanner + * @param distance distance to move in MM + */ +#ifndef UNIT_TESTING +static +#endif + SANE_Status +simple_move (Genesys_Device * dev, SANE_Int distance); + /** * Does a simple scan of the area given by the settings. Scanned data * it put in an allocated area which must be freed by the caller. diff --git a/backend/genesys_gl841.c b/backend/genesys_gl841.c index 26749ca50..1e46e8d96 100644 --- a/backend/genesys_gl841.c +++ b/backend/genesys_gl841.c @@ -6296,6 +6296,7 @@ static Genesys_Command_Set gl841_cmd_set = { gl841_search_strip, gl841_is_compatible_calibration, + NULL }; SANE_Status diff --git a/backend/genesys_low.h b/backend/genesys_low.h index 0c792b5c3..bf38ac391 100644 --- a/backend/genesys_low.h +++ b/backend/genesys_low.h @@ -3,7 +3,7 @@ Copyright (C) 2003 Oliver Rauch Copyright (C) 2003, 2004 Henning Meier-Geinitz Copyright (C) 2004, 2005 Gerhard Jaeger - Copyright (C) 2004-2009 Stéphane Voltz + Copyright (C) 2004-2010 Stéphane Voltz Copyright (C) 2005-2009 Pierre Willenbrock Copyright (C) 2006 Laurent Charpentier Parts of the structs have been taken from the gt68xx backend by @@ -410,6 +410,12 @@ typedef struct Genesys_Command_Set Genesys_Device * dev, Genesys_Calibration_Cache *cache, SANE_Bool for_overwrite); + + /* functions for transparency adapter */ + /** + * move scanning head to transparency adapter + */ + SANE_Status (*move_to_ta) (Genesys_Device * dev); } Genesys_Command_Set; typedef struct Genesys_Model