diff --git a/backend/epsonds-cmd.c b/backend/epsonds-cmd.c index 0474d908b..1fe301d50 100644 --- a/backend/epsonds-cmd.c +++ b/backend/epsonds-cmd.c @@ -465,6 +465,7 @@ static SANE_Status info_cb(void *userdata, char *token, int len) int max = decode_value(value + 4 + 8, 8); DBG(1, " ADF: max %dx%d @ 100dpi\n", min, max); + eds_set_adf_area_large(s->hw, min, max, 100); } } @@ -493,6 +494,7 @@ static SANE_Status info_cb(void *userdata, char *token, int len) int max = decode_value(value + 4 + 4, 8); DBG(1, " ADF: max %dx%d @ 100dpi\n", min, max); + eds_set_adf_area_large(s->hw, min, max, 100); } } diff --git a/backend/epsonds-ops.c b/backend/epsonds-ops.c index 9c90a3f46..fff0ddaf1 100644 --- a/backend/epsonds-ops.c +++ b/backend/epsonds-ops.c @@ -157,6 +157,25 @@ eds_set_adf_area(struct epsonds_device *dev, int x, int y, int unit) SANE_UNFIX(dev->adf_y_range.max), unit); } +void +eds_set_adf_area_large(struct epsonds_device *dev, int x, int y, int unit) +{ + dev->adf_x_range_large.min = 0; + dev->adf_x_range_large.max = SANE_FIX(x * MM_PER_INCH / unit); + dev->adf_x_range_large.quant = 0; + + dev->adf_y_range_large.min = 0; + dev->adf_y_range_large.max = SANE_FIX(y * MM_PER_INCH / unit); + dev->adf_y_range_large.quant = 0; + + DBG(5, "%s: %f,%f %f,%f %d [mm]\n", + __func__, + SANE_UNFIX(dev->adf_x_range_large.min), + SANE_UNFIX(dev->adf_y_range_large.min), + SANE_UNFIX(dev->adf_x_range_large.max), + SANE_UNFIX(dev->adf_y_range_large.max), unit); +} + void eds_set_tpu_area(struct epsonds_device *dev, int x, int y, int unit) { diff --git a/backend/epsonds-ops.h b/backend/epsonds-ops.h index 108d5444b..3622297c8 100644 --- a/backend/epsonds-ops.h +++ b/backend/epsonds-ops.h @@ -20,6 +20,7 @@ extern SANE_Status eds_add_resolution(epsonds_device *dev, int r); extern SANE_Status eds_set_resolution_range(epsonds_device *dev, int min, int max); extern void eds_set_fbf_area(epsonds_device *dev, int x, int y, int unit); extern void eds_set_adf_area(epsonds_device *dev, int x, int y, int unit); +extern void eds_set_adf_area_large(epsonds_device *dev, int x, int y, int unit); extern void eds_set_tpu_area(epsonds_device *dev, int x, int y, int unit); extern SANE_Status eds_add_depth(epsonds_device *dev, SANE_Word depth); diff --git a/backend/epsonds.c b/backend/epsonds.c index aae7bfecd..e7ad884ce 100644 --- a/backend/epsonds.c +++ b/backend/epsonds.c @@ -1597,11 +1597,16 @@ device_detect(const char *name, int type, SANE_Status *status) dev->alignment = dev->fbf_alignment; } else if (s->hw->has_adf) { + if (dev->adf_x_range_large.max > 0) { + dev->x_range = &dev->adf_x_range_large; + dev->y_range = &dev->adf_y_range_large; + } else { + DBG(17, "ADF AMAX was not sent by scanner, using AREA instead\n"); + dev->x_range = &dev->adf_x_range; + dev->y_range = &dev->adf_y_range; + } - dev->x_range = &dev->adf_x_range; - dev->y_range = &dev->adf_y_range; dev->alignment = dev->adf_alignment; - } else { DBG(0, "unable to lay on the flatbed or feed the feeder. is that a scanner??\n"); } @@ -2209,9 +2214,21 @@ change_source(epsonds_scanner *s, SANE_Int optindex, char *value) force_max = SANE_TRUE; } + SANE_Word min_resolution = + (s->hw->dpi_range.quant) ? s->hw->dpi_range.min : s->hw->res_list[1]; + SANE_Bool in_min_resolution = (s->val[OPT_RESOLUTION].w == min_resolution); + if (strcmp(STRING_ADFFRONT, value) == 0 || strcmp(STRING_ADFDUPLEX, value) == 0) { - s->hw->x_range = &s->hw->adf_x_range; - s->hw->y_range = &s->hw->adf_y_range; + if (s->hw->adf_x_range_large.max > 0 && in_min_resolution) { + s->hw->x_range = &s->hw->adf_x_range_large; + s->hw->y_range = &s->hw->adf_y_range_large; + } else { + if(!in_min_resolution) DBG(17, "ADF AMAX was not sent by scanner, using AREA instead\n"); + else DBG(17, "Not allowed to use AMAX due to DPI, using AREA instead\n"); + s->hw->x_range = &s->hw->adf_x_range; + s->hw->y_range = &s->hw->adf_y_range; + } + s->hw->alignment = s->hw->adf_alignment; @@ -2317,8 +2334,37 @@ setvalue(SANE_Handle handle, SANE_Int option, void *value, SANE_Int *info) switch (option) { - case OPT_ADF_SKEW: case OPT_RESOLUTION: + /* Note: this includes an assumption that only the lowest DPI supports + * the large ADF area. This assumption holds true on at least the ES-50 + * and friends, but other scanners need to be tested to see if this is + * universally true or not. + */ + if (strcmp(source_list[s->val[OPT_SOURCE].w], STRING_ADFFRONT) == 0 || strcmp(source_list[s->val[OPT_SOURCE].w], STRING_ADFDUPLEX) == 0) { + SANE_Word min_resolution = + (s->hw->dpi_range.quant) ? s->hw->dpi_range.min : s->hw->res_list[1]; + + if (*((SANE_Word *) value) == min_resolution) { + DBG(17, "DPI change, setting ADF to large area\n"); + s->hw->x_range = &s->hw->adf_x_range_large; + s->hw->y_range = &s->hw->adf_y_range_large; + } else { + DBG(17, "DPI change, setting ADF to normal area\n"); + s->hw->x_range = &s->hw->adf_x_range; + s->hw->y_range = &s->hw->adf_y_range; + } + + s->opt[OPT_BR_X].constraint.range = s->hw->x_range; + s->opt[OPT_BR_Y].constraint.range = s->hw->y_range; + + if (s->val[OPT_BR_X].w > s->hw->x_range->max) + s->val[OPT_BR_X].w = s->hw->x_range->max; + + if (s->val[OPT_BR_Y].w > s->hw->y_range->max) + s->val[OPT_BR_Y].w = s->hw->y_range->max; + } + // fall through + case OPT_ADF_SKEW: case OPT_ADF_CRP: sval->w = *((SANE_Word *) value); reload = SANE_TRUE; @@ -2823,6 +2869,13 @@ sane_start(SANE_Handle handle) char cmd[CMD_BUF_SIZE]; /* take care not to overflow */ SANE_Status status = 0; + /* A pending cancel will interfere with sane_get_parameters, so process it first. */ + if (s->canceling) + { + DBG(5, "Cancel request in progress at start of scan.\n"); + esci2_can(s); + } + s->pages++; DBG(5, "** %s, pages = %d, scanning = %d, backside = %d, front fill: %d, back fill: %d\n", @@ -3588,6 +3641,7 @@ sane_read(SANE_Handle handle, SANE_Byte *data, SANE_Int max_length, SANE_Int *le { esci2_can(s); *length = 0; + s->canceling = 0; return SANE_STATUS_CANCELLED; } @@ -3631,6 +3685,7 @@ sane_cancel(SANE_Handle handle) { DBG(1, "** %s\n", __func__); ((epsonds_scanner *)handle)->canceling = SANE_TRUE; + ((epsonds_scanner *)handle)->scanning = SANE_FALSE; } /* diff --git a/backend/epsonds.h b/backend/epsonds.h index accd283b4..7a53156ab 100644 --- a/backend/epsonds.h +++ b/backend/epsonds.h @@ -140,6 +140,8 @@ struct epsonds_device SANE_Bool has_adf; /* adf */ SANE_Range adf_x_range; /* x range */ SANE_Range adf_y_range; /* y range */ + SANE_Range adf_x_range_large; /* x range in largest scan mode (low DPI) */ + SANE_Range adf_y_range_large; /* y range in largest scan mode (low DPI) */ SANE_Bool adf_is_duplex; /* supports duplex mode */ SANE_Bool adf_singlepass; /* supports single pass duplex */ SANE_Bool adf_has_skew; /* supports skew correction */