Added support for "set focus position" command. This command is

necessary to scan via the TPU with the Expression1600.
DEVEL_2_0_BRANCH-1
Karl Heinz Kremer 2000-11-19 22:24:11 +00:00
rodzic 175e7d6f02
commit 439e781922
1 zmienionych plików z 156 dodań i 56 usunięć

Wyświetl plik

@ -16,7 +16,7 @@
*/
#define SANE_EPSON_VERSION "SANE Epson Backend v0.1.33 - 2000-07-29"
#define SANE_EPSON_VERSION "SANE Epson Backend v0.1.34 - 2000-11-19"
/*
This file is part of the SANE package.
@ -58,6 +58,8 @@
If you do not wish that, delete this exception notice. */
/*
2000-11-19 Added support for the "set focus position" command,
this is necessary for the Expression1600.
2000-07-28 Changed #include <...> to #include "..." for the
sane/... include files.
2000-07-26 Fixed problem with Perfection610: The variable
@ -356,32 +358,23 @@ static EpsonCmdRec epson_cmd [ ] =
* | | | | | | | | | | | | | | | | | | | | | | | | | | | | set exposure time
* | | | | | | | | | | | | | | | | | | | | | | | | | | | | | set bay
* | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | set threshold
* | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
* | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
* | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | set focus position
* | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | request focus position
* | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
* | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
*/
{"A1",'I', 0 ,'F','S', 0 ,'G', 0 ,'R', 0 ,'A', 0 ,{ 0,0,0}, 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 }
,
{"A2",'I', 0 ,'F','S', 0 ,'G','D','R','H','A','L',{-3,3,0},'Z','B', 0 ,'@', 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 }
,
{"B1",'I', 0 ,'F','S','C','G','D','R', 0 ,'A', 0 ,{ 0,0,0}, 0 ,'B', 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 }
,
{"B2",'I', 0 ,'F','S','C','G','D','R','H','A','L',{-3,3,0},'Z','B', 0 ,'@', 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 }
,
{"B3",'I', 0 ,'F','S','C','G','D','R','H','A','L',{-3,3,0},'Z','B','M','@', 0 , 0 , 0 , 0 , 0 , 0 ,'m','f','e', 0 , 0 , 0 , 0 , 0 , 0 , 0 }
,
{"B4",'I', 0 ,'F','S','C','G','D','R','H','A','L',{-3,3,0},'Z','B','M','@','g','d', 0 ,'z','Q','b','m','f','e', 0 , 0 , 0 , 0 , 0 , 0 , 0 }
,
{"B5",'I', 0 ,'F','S','C','G','D','R','H','A','L',{-3,3,0},'Z','B','M','@','g','d','K','z','Q','b','m','f','e', 0 , 0 , 0 , 0 , 0 , 0 , 0 }
,
{"B6",'I', 0 ,'F','S','C','G','D','R','H','A','L',{-3,3,0},'Z','B','M','@','g','d','K','z','Q','b','m','f','e', 0 , 0 , 0 , 0 , 0 , 0 , 0 }
,
{"B7",'I', 0 ,'F','S','C','G','D','R','H','A','L',{-4,3,0},'Z','B','M','@','g','d','K','z','Q','b','m','f','e','\f','!','s','N', 0 , 0 ,'t'}
,
{"B8",'I', 0 ,'F','S','C','G','D','R','H','A','L',{-4,3,0},'Z','B','M','@','g','d','K','z','Q','b','m','f','e', 0 ,'!','s','N', 0 , 0 , 0 }
,
{"F5",'I', 0 ,'F','S','C','G','D','R','H','A','L',{-3,3,0},'Z', 0 ,'M','@','g','d','K','z','Q', 0 ,'m','f','e','\f', 0 , 0 ,'N','T','P', 0 }
,
{"D1",'I','i','F', 0 ,'C','G','D','R', 0 ,'A', 0 ,{ 0,0,0},'Z', 0 , 0 ,'@','g','d', 0 ,'z', 0 , 0 , 0 ,'f', 0 , 0 ,'!', 0 , 0 , 0 , 0 , 0 }
{"A1",'I', 0 ,'F','S', 0 ,'G', 0 ,'R', 0 ,'A', 0 ,{ 0,0,0}, 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 },
{"A2",'I', 0 ,'F','S', 0 ,'G','D','R','H','A','L',{-3,3,0},'Z','B', 0 ,'@', 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 },
{"B1",'I', 0 ,'F','S','C','G','D','R', 0 ,'A', 0 ,{ 0,0,0}, 0 ,'B', 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 },
{"B2",'I', 0 ,'F','S','C','G','D','R','H','A','L',{-3,3,0},'Z','B', 0 ,'@', 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 },
{"B3",'I', 0 ,'F','S','C','G','D','R','H','A','L',{-3,3,0},'Z','B','M','@', 0 , 0 , 0 , 0 , 0 , 0 ,'m','f','e', 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 },
{"B4",'I', 0 ,'F','S','C','G','D','R','H','A','L',{-3,3,0},'Z','B','M','@','g','d', 0 ,'z','Q','b','m','f','e', 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 },
{"B5",'I', 0 ,'F','S','C','G','D','R','H','A','L',{-3,3,0},'Z','B','M','@','g','d','K','z','Q','b','m','f','e', 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 },
{"B6",'I', 0 ,'F','S','C','G','D','R','H','A','L',{-3,3,0},'Z','B','M','@','g','d','K','z','Q','b','m','f','e', 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 },
{"B7",'I', 0 ,'F','S','C','G','D','R','H','A','L',{-4,3,0},'Z','B','M','@','g','d','K','z','Q','b','m','f','e','\f','!','s','N', 0 , 0 ,'t', 0 , 0 },
{"B8",'I', 0 ,'F','S','C','G','D','R','H','A','L',{-4,3,0},'Z','B','M','@','g','d','K','z','Q','b','m','f','e', 0 ,'!','s','N', 0 , 0 , 0 ,'p','q'},
{"F5",'I', 0 ,'F','S','C','G','D','R','H','A','L',{-3,3,0},'Z', 0 ,'M','@','g','d','K','z','Q', 0 ,'m','f','e','\f', 0 , 0 ,'N','T','P', 0 , 0 , 0 },
{"D1",'I','i','F', 0 ,'C','G','D','R', 0 ,'A', 0 ,{ 0,0,0},'Z', 0 , 0 ,'@','g','d', 0 ,'z', 0 , 0 , 0 ,'f', 0 , 0 ,'!', 0 , 0 , 0 , 0 , 0 , 0 , 0 },
};
@ -493,6 +486,13 @@ static const SANE_String_Const film_list [ ] =
, NULL
};
static const SANE_String_Const focus_list [] =
{
"Focus on glass",
"Focus 2.5mm above glass",
NULL
};
/*
* TODO: add some missing const.
*/
@ -774,6 +774,7 @@ static SANE_Status get_identity2_information(SANE_Handle handle);
static int send ( Epson_Scanner * s, const void *buf, size_t buf_size, SANE_Status * status);
static ssize_t receive ( Epson_Scanner * s, void *buf, ssize_t buf_size, SANE_Status * status);
static SANE_Status color_shuffle(SANE_Handle handle, int *new_length);
static SANE_Status request_focus_position(SANE_Handle handle, u_char * position);
/*
*
@ -927,7 +928,8 @@ static SANE_Status set_cmd ( Epson_Scanner * s, u_char cmd, int val) {
*
*/
#define set_color_mode(s,v) set_cmd(s,(s)->hw->cmd->set_color_mode,v)
#define set_focus_position(s,v) set_cmd( s,(s)->hw->cmd->set_focus_position,v)
#define set_color_mode(s,v) set_cmd( s,(s)->hw->cmd->set_color_mode,v)
#define set_data_format(s,v) set_cmd( s,(s)->hw->cmd->set_data_format, v)
#define set_halftoning(s,v) set_cmd( s,(s)->hw->cmd->set_halftoning, v)
#define set_gamma(s,v) set_cmd( s,(s)->hw->cmd->set_gamma, v)
@ -1253,6 +1255,8 @@ static SANE_Status check_ext_status ( Epson_Scanner * s) {
*
*/
#if 0
static SANE_Status reset ( Epson_Scanner * s) {
SANE_Status status;
u_char param[2];
@ -1268,6 +1272,8 @@ static SANE_Status reset ( Epson_Scanner * s) {
return status;
}
#endif
/*
*
*
@ -1712,6 +1718,39 @@ static SANE_Status attach ( const char * dev_name, Epson_Device * * devp) {
} /* request identity 2 */
/*
* Check for "request focus position" command. If this command is
* supported, then the scanner does also support the "set focus
* position" command.
*/
if (request_focus_position(s, &s->currentFocusPosition) == SANE_STATUS_GOOD)
{
DBG( 0, "Enabling 'Set Focus' support\n");
s->hw->focusSupport = SANE_TRUE;
s->opt[ OPT_FOCUS].cap &= ~SANE_CAP_INACTIVE;
/* reflect the current focus position in the GUI */
if (s->currentFocusPosition < 0x4C)
{
/* focus on glass */
s->val[OPT_FOCUS].w = 0;
}
else
{
/* focus 2.5mm above glass */
s->val[OPT_FOCUS].w = 1;
}
}
else
{
DBG( 0, "Disabling 'Set Focus' support\n");
s->hw->focusSupport = SANE_FALSE;
s->opt[ OPT_FOCUS].cap |= SANE_CAP_INACTIVE;
}
/*
* Set defaults for no extension.
@ -1990,20 +2029,6 @@ void sane_exit ( void) {
SANE_Status sane_get_devices ( const SANE_Device * * * device_list, SANE_Bool local_only)
{
#if 0
static const SANE_Device *devlist [ 2];
int i;
i = 0;
if( dummy_dev.sane.name != NULL)
devlist[ i++] = &dummy_dev.sane;
devlist[ i] = NULL;
*device_list = devlist;
return SANE_STATUS_GOOD;
#endif
static const SANE_Device **devlist = 0;
Epson_Device *dev;
int i;
@ -2592,6 +2617,18 @@ static SANE_Status init_options ( Epson_Scanner * s) {
s->opt[ OPT_FILM_TYPE].cap |= SANE_CAP_INACTIVE; /* default is 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 0
if( ( ! s->hw->TPU) && ( ! s->hw->cmd->set_bay) ) { /* Hack: Using set_bay to indicate. */
s->opt[ OPT_FILM_TYPE].cap |= SANE_CAP_INACTIVE;
@ -2602,7 +2639,7 @@ static SANE_Status init_options ( Epson_Scanner * s) {
/* forward feed / eject */
s->opt[ OPT_EJECT].name = "eject";
s->opt[ OPT_EJECT].title = "Eject";
s->opt[ OPT_EJECT].desc = "";
s->opt[ OPT_EJECT].desc = "Eject the sheet in the ADF";
s->opt[ OPT_EJECT].type = SANE_TYPE_BUTTON;
@ -2933,6 +2970,7 @@ static SANE_Status getvalue( SANE_Handle handle,
case OPT_GAMMA_CORRECTION:
case OPT_COLOR_CORRECTION:
case OPT_BAY:
case OPT_FOCUS:
strcpy( (char *) value, sopt->constraint.string_list[sval->w]);
break;
#if 0
@ -3063,12 +3101,17 @@ static void handle_source( Epson_Scanner * s, SANE_Int optindex,
/*
Handles setting the source (flatbed, transparency adapter (TPU),
or auto document feeder (ADF)).
For newer scanners it also sets the focus according to the
glass / TPU settings.
*/
{
int force_max = SANE_FALSE;
SANE_Bool dummy;
s->focusOnGlass = SANE_TRUE; /* this is the default */
if (s->val[ OPT_SOURCE ].w == optindex) return;
s->val[ OPT_SOURCE ].w = optindex;
@ -3085,18 +3128,22 @@ static void handle_source( Epson_Scanner * s, SANE_Int optindex,
s->hw->use_extension = SANE_TRUE;
/* disable film type option */
s->opt[ OPT_FILM_TYPE].cap &= ~SANE_CAP_INACTIVE;
s->val[ OPT_FOCUS].w = 0;
} else if( ! strcmp( TPU_STR, value) ) {
s->hw->x_range = &s->hw->tpu_x_range;
s->hw->y_range = &s->hw->tpu_y_range;
s->hw->use_extension = SANE_TRUE;
/* enable film type option */
s->opt[ OPT_FILM_TYPE].cap |= SANE_CAP_INACTIVE;
s->val[ OPT_FOCUS].w = 1;
s->focusOnGlass = SANE_FALSE;
} else {
s->hw->x_range = &s->hw->fbf_x_range;
s->hw->y_range = &s->hw->fbf_y_range;
s->hw->use_extension = SANE_FALSE;
/* disable film type option */
s->opt[ OPT_FILM_TYPE].cap &= ~SANE_CAP_INACTIVE;
s->val[ OPT_FOCUS].w = 0;
}
qf_params[ XtNumber(qf_params)-1 ].tl_x = s->hw->x_range->min;
@ -3193,6 +3240,7 @@ static SANE_Status setvalue( SANE_Handle handle,
case OPT_DROPOUT:
case OPT_FILM_TYPE:
case OPT_BAY:
case OPT_FOCUS:
sval->w = optindex; /* Simple lists */
break;
@ -3464,20 +3512,6 @@ SANE_Status sane_start ( SANE_Handle handle) {
*/
#if 0
if( s->hw->TPU) {
/*
* NOTE: should remove source TPU, and switch automatically.
* NOTE: not shure if that is a good idea.
*/
} else
#endif
/*
*
*/
@ -3554,6 +3588,27 @@ SANE_Status sane_start ( SANE_Handle handle) {
close_scanner( s);
return status;
}
/*
* set the focus position according to the extension used:
* if the TPU is selected, then focus 2.5mm above the glass,
* otherwise focus on the glass
*/
if (s->hw->focusSupport == SANE_TRUE)
{
if (s->val[ OPT_FOCUS].w == 0)
{
DBG( 1, "Setting focus to glass surface\n");
set_focus_position(s, 0x40);
}
else
{
DBG( 1, "Setting focus to 2.5mm above glass\n");
set_focus_position(s, 0x59);
}
}
}
/*
@ -4945,6 +5000,51 @@ void sane_cancel ( SANE_Handle handle) {
s->canceling = SANE_TRUE;
}
static SANE_Status
request_focus_position(SANE_Handle handle, u_char * position)
{
Epson_Scanner * s = ( Epson_Scanner *) handle;
SANE_Status status;
int len;
u_char param[3];
u_char result[4];
u_char *buf;
DBG(5, "request_focus_position()\n");
if (s->hw->cmd->request_focus_position == 0)
return SANE_STATUS_UNSUPPORTED;
param[0] = ESC;
param[1] = s->hw->cmd->request_focus_position;
param[2] = '\0';
send( s, param, 2, &status);
if( SANE_STATUS_GOOD != status)
return status;
len = 4; /* receive header */
receive( s, result, len, &status);
if( SANE_STATUS_GOOD != status)
return status;
len = result[ 3] << 8 | result[ 2];
buf = alloca( len);
receive( s, buf, len, &status); /* reveive actual status data */
*position = buf[ 1];
DBG(1, "Focus position = 0x%x\n", buf[1]);
return SANE_STATUS_GOOD;
}
/**********************************************************************************/
/*
* SANE_Status sane_set_io_mode()
*