diff options
Diffstat (limited to 'backend/epson2.c')
-rw-r--r-- | backend/epson2.c | 141 |
1 files changed, 92 insertions, 49 deletions
diff --git a/backend/epson2.c b/backend/epson2.c index e6f6786..a15a620 100644 --- a/backend/epson2.c +++ b/backend/epson2.c @@ -138,12 +138,6 @@ static const SANE_String_Const film_list[] = { NULL }; -static const SANE_String_Const focus_list[] = { - SANE_I18N("Focus on glass"), - SANE_I18N("Focus 2.5mm above glass"), - NULL -}; - #define HALFTONE_NONE 0x01 #define HALFTONE_TET 0x03 @@ -239,7 +233,7 @@ enum { * Gamma correction: * The A and B level scanners work differently than the D level scanners, * therefore I define two different sets of arrays, plus one set of - * variables that get set to the actally used params and list arrays at runtime. + * variables that get set to the actually used params and list arrays at runtime. */ static int gamma_params_ab[] = { @@ -302,12 +296,11 @@ static const SANE_String_Const bay_list[] = { }; /* minimum, maximum, quantization */ +static const SANE_Range focus_range = { 0, 254, 0 }; static const SANE_Range u8_range = { 0, 255, 0 }; static const SANE_Range fx_range = { SANE_FIX(-2.0), SANE_FIX(2.0), 0 }; - static const SANE_Range outline_emphasis_range = { -2, 2, 0 }; - /* * List of pointers to devices - will be dynamically allocated depending * on the number of devices found. @@ -813,10 +806,11 @@ attach_one_pio(const char *dev) } static SANE_Status -attach_one_config(SANEI_Config __sane_unused__ *config, const char *line) +attach_one_config(SANEI_Config __sane_unused__ *config, const char *line, + void *data) { int vendor, product; - + SANE_Bool local_only = *(SANE_Bool*) data; int len = strlen(line); DBG(7, "%s: len = %d, line = %s\n", __func__, len, line); @@ -847,13 +841,16 @@ attach_one_config(SANEI_Config __sane_unused__ *config, const char *line) } else if (strncmp(line, "net", 3) == 0) { - /* remove the "net" sub string */ - const char *name = sanei_config_skip_whitespace(line + 3); + if (!local_only) { + /* remove the "net" sub string */ + const char *name = + sanei_config_skip_whitespace(line + 3); - if (strncmp(name, "autodiscovery", 13) == 0) - e2_network_discovery(); - else - attach_one_net(name); + if (strncmp(name, "autodiscovery", 13) == 0) + e2_network_discovery(); + else + attach_one_net(name); + } } else if (strncmp(line, "pio", 3) == 0) { @@ -889,14 +886,14 @@ free_devices(void) } static void -probe_devices(void) +probe_devices(SANE_Bool local_only) { DBG(5, "%s\n", __func__); free_devices(); sanei_configure_attach(EPSON2_CONFIG_FILE, NULL, - attach_one_config); + attach_one_config, &local_only); } SANE_Status @@ -926,14 +923,14 @@ sane_exit(void) } SANE_Status -sane_get_devices(const SANE_Device ***device_list, SANE_Bool __sane_unused__ local_only) +sane_get_devices(const SANE_Device ***device_list, SANE_Bool local_only) { Epson_Device *dev; int i; DBG(5, "%s\n", __func__); - probe_devices(); + probe_devices(local_only); devlist = malloc((num_devices + 1) * sizeof(devlist[0])); if (!devlist) { @@ -1336,6 +1333,39 @@ init_options(Epson_Scanner *s) s->opt[OPT_BR_Y].constraint.range = s->hw->y_range; s->val[OPT_BR_Y].w = s->hw->y_range->max; + /* "Focus" group: */ + s->opt[OPT_FOCUS_GROUP].title = SANE_I18N("Focus"); + s->opt[OPT_FOCUS_GROUP].desc = ""; + s->opt[OPT_FOCUS_GROUP].type = SANE_TYPE_GROUP; + s->opt[OPT_FOCUS_GROUP].cap = SANE_CAP_ADVANCED; + + /* autofocus */ + s->opt[OPT_AUTOFOCUS].name = SANE_NAME_AUTOFOCUS; + s->opt[OPT_AUTOFOCUS].title = SANE_TITLE_AUTOFOCUS; + s->opt[OPT_AUTOFOCUS].desc = SANE_DESC_AUTOFOCUS; + s->opt[OPT_AUTOFOCUS].type = SANE_TYPE_BOOL; + s->val[OPT_AUTOFOCUS].w = SANE_FALSE; + s->opt[OPT_AUTOFOCUS].cap |= SANE_CAP_ADVANCED; + + /* focus position */ + s->opt[OPT_FOCUS_POS].name = SANE_NAME_FOCUS; + s->opt[OPT_FOCUS_POS].title = SANE_TITLE_FOCUS; + s->opt[OPT_FOCUS_POS].desc = SANE_DESC_FOCUS; + s->opt[OPT_FOCUS_POS].type = SANE_TYPE_INT; + s->opt[OPT_FOCUS_POS].unit = SANE_UNIT_NONE; + s->opt[OPT_FOCUS_POS].constraint_type = SANE_CONSTRAINT_RANGE; + s->opt[OPT_FOCUS_POS].constraint.range = &focus_range; + s->val[OPT_FOCUS_POS].w = FOCUS_ON_GLASS; + s->opt[OPT_FOCUS_POS].cap |= SANE_CAP_ADVANCED; + + if (s->hw->focusSupport == SANE_TRUE) { + s->opt[OPT_FOCUS_POS].cap &= ~SANE_CAP_INACTIVE; + s->opt[OPT_AUTOFOCUS].cap &= ~SANE_CAP_INACTIVE; + } else { + s->opt[OPT_FOCUS_POS].cap |= SANE_CAP_INACTIVE; + s->opt[OPT_AUTOFOCUS].cap |= SANE_CAP_INACTIVE; + } + /* "Optional equipment" group: */ s->opt[OPT_EQU_GROUP].title = SANE_I18N("Optional equipment"); s->opt[OPT_EQU_GROUP].desc = ""; @@ -1372,22 +1402,6 @@ init_options(Epson_Scanner *s) if (!s->hw->cmd->set_bay) s->opt[OPT_FILM_TYPE].cap |= SANE_CAP_INACTIVE; - /* focus position */ - s->opt[OPT_FOCUS].name = SANE_EPSON_FOCUS_NAME; - s->opt[OPT_FOCUS].title = SANE_EPSON_FOCUS_TITLE; - s->opt[OPT_FOCUS].desc = SANE_EPSON_FOCUS_DESC; - s->opt[OPT_FOCUS].type = SANE_TYPE_STRING; - s->opt[OPT_FOCUS].size = max_string_size(focus_list); - s->opt[OPT_FOCUS].constraint_type = SANE_CONSTRAINT_STRING_LIST; - s->opt[OPT_FOCUS].constraint.string_list = focus_list; - s->val[OPT_FOCUS].w = 0; - s->opt[OPT_FOCUS].cap |= SANE_CAP_ADVANCED; - - if (s->hw->focusSupport == SANE_TRUE) - s->opt[OPT_FOCUS].cap &= ~SANE_CAP_INACTIVE; - else - s->opt[OPT_FOCUS].cap |= SANE_CAP_INACTIVE; - /* forward feed / eject */ s->opt[OPT_EJECT].name = "eject"; s->opt[OPT_EJECT].title = SANE_I18N("Eject"); @@ -1470,7 +1484,7 @@ sane_open(SANE_String_Const name, SANE_Handle *handle) /* probe if empty device name provided */ if (l == 0) { - probe_devices(); + probe_devices(SANE_FALSE); if (first_dev == NULL) { DBG(1, "no device detected\n"); @@ -1507,7 +1521,7 @@ sane_open(SANE_String_Const name, SANE_Handle *handle) */ if (first_dev == NULL) - probe_devices(); + probe_devices(SANE_FALSE); s = device_detect(name, SANE_EPSON_NODEV, 0, &status); if (s == NULL) { @@ -1646,6 +1660,8 @@ getvalue(SANE_Handle handle, SANE_Int option, void *value) case OPT_THRESHOLD: case OPT_BIT_DEPTH: case OPT_WAIT_FOR_BUTTON: + case OPT_AUTOFOCUS: + case OPT_FOCUS_POS: *((SANE_Word *) value) = sval->w; break; @@ -1659,7 +1675,6 @@ getvalue(SANE_Handle handle, SANE_Int option, void *value) case OPT_GAMMA_CORRECTION: case OPT_COLOR_CORRECTION: case OPT_BAY: - case OPT_FOCUS: strcpy((char *) value, sopt->constraint.string_list[sval->w]); break; @@ -1730,8 +1745,6 @@ change_source(Epson_Scanner *s, SANE_Int optindex, char *value) if (s->hw->need_reset_on_source_change) esci_reset(s); - s->focusOnGlass = SANE_TRUE; /* this is the default */ - if (s->val[OPT_SOURCE].w == optindex) return; @@ -1750,7 +1763,7 @@ change_source(Epson_Scanner *s, SANE_Int optindex, char *value) s->hw->use_extension = SANE_TRUE; /* disable film type option */ deactivateOption(s, OPT_FILM_TYPE, &dummy); - s->val[OPT_FOCUS].w = 0; + s->val[OPT_FOCUS_POS].w = FOCUS_ON_GLASS; if (s->hw->duplex) { activateOption(s, OPT_ADF_MODE, &dummy); } else { @@ -1782,10 +1795,8 @@ change_source(Epson_Scanner *s, SANE_Int optindex, char *value) deactivateOption(s, OPT_FILM_TYPE, &dummy); /* enable focus position if the scanner supports it */ - if (s->hw->cmd->set_focus_position != 0) { - s->val[OPT_FOCUS].w = 1; - s->focusOnGlass = SANE_FALSE; - } + if (s->hw->focusSupport) + s->val[OPT_FOCUS_POS].w = FOCUS_ABOVE_25MM; deactivateOption(s, OPT_ADF_MODE, &dummy); deactivateOption(s, OPT_EJECT, &dummy); @@ -1798,7 +1809,7 @@ change_source(Epson_Scanner *s, SANE_Int optindex, char *value) /* disable film type option */ deactivateOption(s, OPT_FILM_TYPE, &dummy); - s->val[OPT_FOCUS].w = 0; + s->val[OPT_FOCUS_POS].w = FOCUS_ON_GLASS; deactivateOption(s, OPT_ADF_MODE, &dummy); } @@ -1872,7 +1883,6 @@ setvalue(SANE_Handle handle, SANE_Int option, void *value, SANE_Int *info) case OPT_DROPOUT: case OPT_FILM_TYPE: case OPT_BAY: - case OPT_FOCUS: sval->w = optindex; /* Simple lists */ break; @@ -1981,6 +1991,11 @@ setvalue(SANE_Handle handle, SANE_Int option, void *value, SANE_Int *info) break; } + case OPT_AUTOFOCUS: + sval->w = *((SANE_Word *) value); + setOptionState(s, !sval->w, OPT_FOCUS_POS, &reload); + break; + case OPT_MIRROR: case OPT_AAS: case OPT_PREVIEW: /* needed? */ @@ -1989,6 +2004,7 @@ setvalue(SANE_Handle handle, SANE_Int option, void *value, SANE_Int *info) case OPT_AUTO_EJECT: case OPT_THRESHOLD: case OPT_WAIT_FOR_BUTTON: + case OPT_FOCUS_POS: sval->w = *((SANE_Word *) value); break; @@ -2122,6 +2138,27 @@ sane_start(SANE_Handle handle) if (status != SANE_STATUS_GOOD) return status; + /* + * set focus after we set scanning parameters because the scanner will + * use the middle of the scanning area for autofocus. If we want to + * support a defined x,y position for autofocus, we'd need to send + * specific scanning paramters just for autofocus. + */ + if (s->hw->focusSupport == SANE_TRUE) { + if (s->val[OPT_AUTOFOCUS].w) { + DBG(1, "setting autofocus\n"); + status = esci_set_focus_position(s, 0xff); + } else { + DBG(1, "setting focus to %u\n", s->val[OPT_FOCUS_POS].w); + status = esci_set_focus_position(s, s->val[OPT_FOCUS_POS].w); + } + + if (status != SANE_STATUS_GOOD) { + DBG(1, "setting focus failed\n"); + return status; + } + } + /* ESC z, user defined gamma table */ if (dev->cmd->set_gamma_table && gamma_userdefined[s->val[OPT_GAMMA_CORRECTION].w]) { @@ -2227,6 +2264,12 @@ sane_start(SANE_Handle handle) if (status != SANE_STATUS_GOOD) return status; + if (s->hw->focusSupport == SANE_TRUE && s->val[OPT_AUTOFOCUS].w) { + status = esci_request_focus_position(s, &s->currentFocusPosition); + if (status == SANE_STATUS_GOOD) + s->val[OPT_FOCUS_POS].w = s->currentFocusPosition; + } + /* start scanning */ DBG(1, "%s: scanning...\n", __func__); |