Add options for reading LCD counter and LED indicator.

* Add command line parameters for readling LCD counter and LED indicator.
* Code refactoring: Use static parameter strings instead of dynamically
allocated string in order to avoid memory leak.
merge-requests/83/head
Bernard B Badeer 2019-06-03 06:10:26 +00:00 zatwierdzone przez Ilia Sotnikov
rodzic 1f847e4128
commit 1f383b3795
4 zmienionych plików z 600 dodań i 112 usunięć

Wyświetl plik

@ -1,8 +1,8 @@
/* sane - Scanner Access Now Easy.
Copyright (C) 2007 Ilia Sotnikov <hostcc@gmail.com>
HP ScanJet 4570c support by Markham Thomas
ADF page detection and high DPI fixes by Bernard Badr
scanbd integration by Damiano Scaramuzza and Bernard Badr
ADF page detection and high DPI fixes by Bernard Badeer
scanbd integration by Damiano Scaramuzza and Bernard Badeer
This file is part of the SANE package.
This program is free software; you can redistribute it and/or
@ -83,7 +83,7 @@
#define MY_MAX(a, b) (((a) > (b)) ? (a) : (b))
/* #define HAS_WORKING_COLOR_48 */
#define BUILD 7
#define BUILD 8
#define USB_TIMEOUT 30 * 1000
static SANE_Word
@ -94,6 +94,15 @@ res_list[] = { 6, 100, 200, 300, 600, 1200, 2400 };
#define SANE_VALUE_SCAN_SOURCE_ADF_DUPLEX SANE_I18N("ADF Duplex")
#define SANE_VALUE_SCAN_SOURCE_TMA_SLIDES SANE_I18N("TMA Slides")
#define SANE_VALUE_SCAN_SOURCE_TMA_NEGATIVES SANE_I18N("TMA Negatives")
static SANE_String_Const
sources_list[] = {
SANE_VALUE_SCAN_SOURCE_FLATBED,
SANE_VALUE_SCAN_SOURCE_ADF,
SANE_VALUE_SCAN_SOURCE_ADF_DUPLEX,
SANE_VALUE_SCAN_SOURCE_TMA_SLIDES,
SANE_VALUE_SCAN_SOURCE_TMA_NEGATIVES,
NULL
};
#define SANE_VALUE_SCAN_MODE_COLOR_24 SANE_VALUE_SCAN_MODE_COLOR
#define SANE_VALUE_SCAN_MODE_COLOR_48 SANE_I18N("Color (48 bits)")
@ -108,7 +117,15 @@ res_list[] = { 6, 100, 200, 300, 600, 1200, 2400 };
#define SANE_NAME_BUTTON_PRESSED "button-pressed"
#define SANE_TITLE_BUTTON_PRESSED SANE_I18N("Last button pressed")
#define SANE_DESC_BUTTON_PRESSED SANE_I18N("Get ID of last button pressed (read only)")
#define BUTTON_PRESSED_BUTTONNAME_MAX_LEN 32
#define SANE_NAME_LCD_COUNTER "counter-value"
#define SANE_TITLE_LCD_COUNTER SANE_I18N("LCD counter")
#define SANE_DESC_LCD_COUNTER SANE_I18N("Get value of LCD counter (read only)")
#define SANE_NAME_COLOR_LED "color-led"
#define SANE_TITLE_COLOR_LED SANE_I18N("Color LED indicator")
#define SANE_DESC_COLOR_LED SANE_I18N("Get value of LED indicator (read only)")
#define SANE_NAME_DOC_IN_ADF "doc-in-adf"
#define SANE_TITLE_DOC_IN_ADF SANE_I18N("Document available in ADF")
#define SANE_DESC_DOC_IN_ADF SANE_I18N("Get state of document-available indicator in ADF (read only)")
#define SANE_NAME_OVERWRITE_EOP_PIXEL "hide-eop-pixel"
#define SANE_TITLE_OVERWRITE_EOP_PIXEL SANE_I18N("Hide end-of-page pixel")
#define SANE_DESC_OVERWRITE_EOP_PIXEL SANE_I18N("Hide end-of-page indicator pixels and overwrite with neighbor pixels")
@ -121,6 +138,56 @@ res_list[] = { 6, 100, 200, 300, 600, 1200, 2400 };
#define SANE_DESC_TRAILING_LINES_COLOR SANE_I18N("Color value for trailing lines filling mode 'color'. "\
"RGB color as r*65536+256*g+b or gray value (default=violet or gray)")
#define BUTTON_PRESSED_VALUE_COUNT 11
#define BUTTON_PRESSED_VALUE_NONE_KEY "none"
#define BUTTON_PRESSED_VALUE_POWER_KEY "power"
#define BUTTON_PRESSED_VALUE_SCAN_KEY "scan"
#define BUTTON_PRESSED_VALUE_COLLECT_KEY "collect"
#define BUTTON_PRESSED_VALUE_FILE_KEY "file"
#define BUTTON_PRESSED_VALUE_EMAIL_KEY "email"
#define BUTTON_PRESSED_VALUE_COPY_KEY "copy"
#define BUTTON_PRESSED_VALUE_UP_KEY "up"
#define BUTTON_PRESSED_VALUE_DOWN_KEY "down"
#define BUTTON_PRESSED_VALUE_MODE_KEY "mode"
#define BUTTON_PRESSED_VALUE_CANCEL_KEY "cancel"
#define BUTTON_PRESSED_VALUE_MAX_KEY_LEN 32
static SANE_String_Const
buttonstate_list[] = {
BUTTON_PRESSED_VALUE_NONE_KEY,
BUTTON_PRESSED_VALUE_POWER_KEY,
BUTTON_PRESSED_VALUE_SCAN_KEY,
BUTTON_PRESSED_VALUE_COLLECT_KEY,
BUTTON_PRESSED_VALUE_FILE_KEY,
BUTTON_PRESSED_VALUE_EMAIL_KEY,
BUTTON_PRESSED_VALUE_COPY_KEY,
BUTTON_PRESSED_VALUE_UP_KEY,
BUTTON_PRESSED_VALUE_DOWN_KEY,
BUTTON_PRESSED_VALUE_MODE_KEY,
BUTTON_PRESSED_VALUE_CANCEL_KEY,
NULL
};
#define COLOR_LED_VALUE_COUNT 2
#define COLOR_LED_VALUE_COLOR_KEY "color"
#define COLOR_LED_VALUE_BLACKWHITE_KEY "black_white"
#define COLOR_LED_VALUE_MAX_KEY_LEN 32
static SANE_String_Const
colorledstate_list[] = {
COLOR_LED_VALUE_COLOR_KEY,
COLOR_LED_VALUE_BLACKWHITE_KEY,
NULL
};
#define LCD_COUNTER_VALUE_MIN 1
#define LCD_COUNTER_VALUE_MAX 99
#define LCD_COUNTER_VALUE_QUANT 1
static SANE_Range
lcd_counter_range = {
LCD_COUNTER_VALUE_MIN,
LCD_COUNTER_VALUE_MAX,
LCD_COUNTER_VALUE_QUANT
};
#define TRAILING_LINES_MODE_RAW 0
#define TRAILING_LINES_MODE_LAST 1
#define TRAILING_LINES_MODE_RASTER 2
@ -135,7 +202,17 @@ res_list[] = { 6, 100, 200, 300, 600, 1200, 2400 };
#define TRAILING_LINES_MODE_WHITE_KEY "white"
#define TRAILING_LINES_MODE_BLACK_KEY "black"
#define TRAILING_LINES_MODE_COLOR_KEY "color"
#define TRAILING_LINES_MODE_MAX_VALUE_LEN 24
#define TRAILING_LINES_MODE_MAX_KEY_LEN 24
static SANE_String_Const
trailingmode_list[] = {
TRAILING_LINES_MODE_RAW_KEY,
TRAILING_LINES_MODE_LAST_KEY,
TRAILING_LINES_MODE_RASTER_KEY,
TRAILING_LINES_MODE_WHITE_KEY,
TRAILING_LINES_MODE_BLACK_KEY,
TRAILING_LINES_MODE_COLOR_KEY,
NULL
};
#define MAX_SCAN_SOURCE_VALUE_LEN 24
#define MAX_SCAN_MODE_VALUE_LEN 24
@ -166,6 +243,9 @@ enum hp5590_opt_idx {
HP5590_OPT_LAMP_TIMEOUT,
HP5590_OPT_WAIT_FOR_BUTTON,
HP5590_OPT_BUTTON_PRESSED,
HP5590_OPT_COLOR_LED,
HP5590_OPT_LCD_COUNTER,
HP5590_OPT_DOC_IN_ADF,
HP5590_OPT_PREVIEW,
HP5590_OPT_OVERWRITE_EOP_PIXEL,
HP5590_OPT_TRAILING_LINES_MODE,
@ -527,13 +607,6 @@ sane_open (SANE_String_Const devicename, SANE_Handle * handle)
{
struct hp5590_scanner *ptr;
SANE_Option_Descriptor *opts;
unsigned int available_sources;
SANE_String_Const *sources_list;
unsigned int source_idx;
SANE_String_Const *fillmode_list;
unsigned int fillmode_idx;
SANE_String_Const *buttonstate_list;
unsigned int buttonstate_idx;
DBG (DBG_proc, "%s: device name: %s\n", __func__, devicename);
@ -658,18 +731,7 @@ sane_open (SANE_String_Const devicename, SANE_Handle * handle)
opts[HP5590_OPT_MODE].constraint_type = SANE_CONSTRAINT_STRING_LIST;
opts[HP5590_OPT_MODE].constraint.string_list = mode_list;
available_sources = 6; /* Show all features, check on feature in command line evaluation. */
sources_list = malloc (available_sources * sizeof (SANE_String_Const));
if (!sources_list)
return SANE_STATUS_NO_MEM;
source_idx = 0;
sources_list[source_idx++] = SANE_VALUE_SCAN_SOURCE_FLATBED;
sources_list[source_idx++] = SANE_VALUE_SCAN_SOURCE_ADF;
sources_list[source_idx++] = SANE_VALUE_SCAN_SOURCE_ADF_DUPLEX;
sources_list[source_idx++] = SANE_VALUE_SCAN_SOURCE_TMA_SLIDES;
sources_list[source_idx++] = SANE_VALUE_SCAN_SOURCE_TMA_NEGATIVES;
sources_list[source_idx++] = NULL;
/* Show all features, check on feature in command line evaluation. */
opts[HP5590_OPT_SOURCE].name = SANE_NAME_SCAN_SOURCE;
opts[HP5590_OPT_SOURCE].title = SANE_TITLE_SCAN_SOURCE;
opts[HP5590_OPT_SOURCE].desc = SANE_DESC_SCAN_SOURCE;
@ -710,23 +772,46 @@ sane_open (SANE_String_Const devicename, SANE_Handle * handle)
opts[HP5590_OPT_WAIT_FOR_BUTTON].constraint_type = SANE_CONSTRAINT_NONE;
opts[HP5590_OPT_WAIT_FOR_BUTTON].constraint.string_list = NULL;
buttonstate_list = malloc ((TRAILING_LINES_MODE_VALUE_COUNT + 1) * sizeof (SANE_String_Const));
if (!buttonstate_list)
return SANE_STATUS_NO_MEM;
buttonstate_idx = 0;
buttonstate_list[buttonstate_idx++] = "read-only";
buttonstate_list[buttonstate_idx++] = NULL;
opts[HP5590_OPT_BUTTON_PRESSED].name = SANE_NAME_BUTTON_PRESSED;
opts[HP5590_OPT_BUTTON_PRESSED].title = SANE_TITLE_BUTTON_PRESSED;
opts[HP5590_OPT_BUTTON_PRESSED].desc = SANE_DESC_BUTTON_PRESSED;
opts[HP5590_OPT_BUTTON_PRESSED].type = SANE_TYPE_STRING;
opts[HP5590_OPT_BUTTON_PRESSED].unit = SANE_UNIT_NONE;
opts[HP5590_OPT_BUTTON_PRESSED].size = BUTTON_PRESSED_BUTTONNAME_MAX_LEN;
opts[HP5590_OPT_BUTTON_PRESSED].size = BUTTON_PRESSED_VALUE_MAX_KEY_LEN;
opts[HP5590_OPT_BUTTON_PRESSED].cap = SANE_CAP_HARD_SELECT | SANE_CAP_SOFT_DETECT;
opts[HP5590_OPT_BUTTON_PRESSED].constraint_type = SANE_CONSTRAINT_NONE;
opts[HP5590_OPT_BUTTON_PRESSED].constraint_type = SANE_CONSTRAINT_STRING_LIST;
opts[HP5590_OPT_BUTTON_PRESSED].constraint.string_list = buttonstate_list;
opts[HP5590_OPT_COLOR_LED].name = SANE_NAME_COLOR_LED;
opts[HP5590_OPT_COLOR_LED].title = SANE_TITLE_COLOR_LED;
opts[HP5590_OPT_COLOR_LED].desc = SANE_DESC_COLOR_LED;
opts[HP5590_OPT_COLOR_LED].type = SANE_TYPE_STRING;
opts[HP5590_OPT_COLOR_LED].unit = SANE_UNIT_NONE;
opts[HP5590_OPT_COLOR_LED].size = COLOR_LED_VALUE_MAX_KEY_LEN;
opts[HP5590_OPT_COLOR_LED].cap = SANE_CAP_HARD_SELECT | SANE_CAP_SOFT_DETECT;
opts[HP5590_OPT_COLOR_LED].constraint_type = SANE_CONSTRAINT_STRING_LIST;
opts[HP5590_OPT_COLOR_LED].constraint.string_list = colorledstate_list;
opts[HP5590_OPT_LCD_COUNTER].name = SANE_NAME_LCD_COUNTER;
opts[HP5590_OPT_LCD_COUNTER].title = SANE_TITLE_LCD_COUNTER;
opts[HP5590_OPT_LCD_COUNTER].desc = SANE_DESC_LCD_COUNTER;
opts[HP5590_OPT_LCD_COUNTER].type = SANE_TYPE_INT;
opts[HP5590_OPT_LCD_COUNTER].unit = SANE_UNIT_NONE;
opts[HP5590_OPT_LCD_COUNTER].size = sizeof(SANE_Int);
opts[HP5590_OPT_LCD_COUNTER].cap = SANE_CAP_HARD_SELECT | SANE_CAP_SOFT_DETECT;
opts[HP5590_OPT_LCD_COUNTER].constraint_type = SANE_CONSTRAINT_RANGE;
opts[HP5590_OPT_LCD_COUNTER].constraint.range = &lcd_counter_range;
opts[HP5590_OPT_DOC_IN_ADF].name = SANE_NAME_DOC_IN_ADF;
opts[HP5590_OPT_DOC_IN_ADF].title = SANE_TITLE_DOC_IN_ADF;
opts[HP5590_OPT_DOC_IN_ADF].desc = SANE_DESC_DOC_IN_ADF;
opts[HP5590_OPT_DOC_IN_ADF].type = SANE_TYPE_BOOL;
opts[HP5590_OPT_DOC_IN_ADF].unit = SANE_UNIT_NONE;
opts[HP5590_OPT_DOC_IN_ADF].size = sizeof(SANE_Bool);
opts[HP5590_OPT_DOC_IN_ADF].cap = SANE_CAP_HARD_SELECT | SANE_CAP_SOFT_DETECT;
opts[HP5590_OPT_DOC_IN_ADF].constraint_type = SANE_CONSTRAINT_NONE;
opts[HP5590_OPT_DOC_IN_ADF].constraint.range = NULL;
opts[HP5590_OPT_PREVIEW].name = SANE_NAME_PREVIEW;
opts[HP5590_OPT_PREVIEW].title = SANE_TITLE_PREVIEW;
opts[HP5590_OPT_PREVIEW].desc = SANE_DESC_PREVIEW;
@ -747,34 +832,22 @@ sane_open (SANE_String_Const devicename, SANE_Handle * handle)
opts[HP5590_OPT_OVERWRITE_EOP_PIXEL].constraint_type = SANE_CONSTRAINT_NONE;
opts[HP5590_OPT_OVERWRITE_EOP_PIXEL].constraint.string_list = NULL;
fillmode_list = malloc ((TRAILING_LINES_MODE_VALUE_COUNT + 1) * sizeof (SANE_String_Const));
if (!fillmode_list)
return SANE_STATUS_NO_MEM;
fillmode_idx = 0;
fillmode_list[fillmode_idx++] = TRAILING_LINES_MODE_RAW_KEY;
fillmode_list[fillmode_idx++] = TRAILING_LINES_MODE_LAST_KEY;
fillmode_list[fillmode_idx++] = TRAILING_LINES_MODE_RASTER_KEY;
fillmode_list[fillmode_idx++] = TRAILING_LINES_MODE_WHITE_KEY;
fillmode_list[fillmode_idx++] = TRAILING_LINES_MODE_BLACK_KEY;
fillmode_list[fillmode_idx++] = TRAILING_LINES_MODE_COLOR_KEY;
fillmode_list[fillmode_idx++] = NULL;
opts[HP5590_OPT_TRAILING_LINES_MODE].name = SANE_NAME_TRAILING_LINES_MODE;
opts[HP5590_OPT_TRAILING_LINES_MODE].title = SANE_TITLE_TRAILING_LINES_MODE;
opts[HP5590_OPT_TRAILING_LINES_MODE].desc = SANE_DESC_TRAILING_LINES_MODE;
opts[HP5590_OPT_TRAILING_LINES_MODE].type = SANE_TYPE_STRING;
opts[HP5590_OPT_TRAILING_LINES_MODE].unit = SANE_UNIT_NONE;
opts[HP5590_OPT_TRAILING_LINES_MODE].size = TRAILING_LINES_MODE_MAX_VALUE_LEN;
opts[HP5590_OPT_TRAILING_LINES_MODE].size = TRAILING_LINES_MODE_MAX_KEY_LEN;
opts[HP5590_OPT_TRAILING_LINES_MODE].cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT | SANE_CAP_ADVANCED;
opts[HP5590_OPT_TRAILING_LINES_MODE].constraint_type = SANE_CONSTRAINT_STRING_LIST;
opts[HP5590_OPT_TRAILING_LINES_MODE].constraint.string_list = fillmode_list;
opts[HP5590_OPT_TRAILING_LINES_MODE].constraint.string_list = trailingmode_list;
opts[HP5590_OPT_TRAILING_LINES_COLOR].name = SANE_NAME_TRAILING_LINES_COLOR;
opts[HP5590_OPT_TRAILING_LINES_COLOR].title = SANE_TITLE_TRAILING_LINES_COLOR;
opts[HP5590_OPT_TRAILING_LINES_COLOR].desc = SANE_DESC_TRAILING_LINES_COLOR;
opts[HP5590_OPT_TRAILING_LINES_COLOR].type = SANE_TYPE_INT;
opts[HP5590_OPT_TRAILING_LINES_COLOR].unit = SANE_UNIT_NONE;
opts[HP5590_OPT_TRAILING_LINES_COLOR].size = sizeof(SANE_Bool);
opts[HP5590_OPT_TRAILING_LINES_COLOR].size = sizeof(SANE_Int);
opts[HP5590_OPT_TRAILING_LINES_COLOR].cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT | SANE_CAP_ADVANCED;
opts[HP5590_OPT_TRAILING_LINES_COLOR].constraint_type = SANE_CONSTRAINT_NONE;
opts[HP5590_OPT_TRAILING_LINES_COLOR].constraint.string_list = NULL;
@ -829,6 +902,50 @@ read_button_pressed(SANE_Handle handle, enum button_status * button_pressed)
return SANE_STATUS_GOOD;
}
/******************************************************************************/
SANE_Status
read_lcd_and_led_values(SANE_Handle handle,
SANE_Int * lcd_counter,
enum color_led_status * color_led)
{
struct hp5590_scanner * scanner = handle;
*lcd_counter = 1;
*color_led = LED_COLOR;
DBG (DBG_verbose, "%s: Reading LCD and LED values (device_number = %u) (device_name = %s)\n",
__func__, scanner->dn, scanner->sane.name);
SANE_Status ret = hp5590_read_lcd_and_led (scanner->dn, scanner->proto_flags, lcd_counter, color_led);
if (ret != SANE_STATUS_GOOD)
{
DBG (DBG_proc, "%s: Error reading LCD and LED values (%u)\n", __func__, ret);
return ret;
}
DBG (DBG_verbose, "%s: LCD = %d, LED = %s\n", __func__, *lcd_counter,
*color_led == LED_BLACKWHITE ? COLOR_LED_VALUE_BLACKWHITE_KEY : COLOR_LED_VALUE_COLOR_KEY);
return SANE_STATUS_GOOD;
}
/******************************************************************************/
SANE_Status
read_doc_in_adf_value(SANE_Handle handle,
SANE_Bool * doc_in_adf)
{
struct hp5590_scanner * scanner = handle;
DBG (DBG_verbose, "%s: Reading state of document-available in ADF (device_number = %u) (device_name = %s)\n",
__func__, scanner->dn, scanner->sane.name);
SANE_Status ret = hp5590_is_data_available (scanner->dn, scanner->proto_flags);
if (ret == SANE_STATUS_GOOD)
*doc_in_adf = SANE_TRUE;
else if (ret == SANE_STATUS_NO_DOCS)
*doc_in_adf = SANE_FALSE;
else
{
DBG (DBG_proc, "%s: Error reading state of document-available in ADF (%u)\n", __func__, ret);
return ret;
}
DBG (DBG_verbose, "%s: doc_in_adf = %s\n", __func__, *doc_in_adf == SANE_FALSE ? "false" : "true");
return SANE_STATUS_GOOD;
}
/******************************************************************************/
SANE_Status
sane_control_option (SANE_Handle handle, SANE_Int option,
@ -956,41 +1073,77 @@ sane_control_option (SANE_Handle handle, SANE_Int option,
return ret;
switch (button_pressed) {
case BUTTON_POWER:
strncpy (value, "power", scanner->opts[option].size);
strncpy (value, BUTTON_PRESSED_VALUE_POWER_KEY, scanner->opts[option].size);
break;
case BUTTON_SCAN:
strncpy (value, "scan", scanner->opts[option].size);
strncpy (value, BUTTON_PRESSED_VALUE_SCAN_KEY, scanner->opts[option].size);
break;
case BUTTON_COLLECT:
strncpy (value, "collect", scanner->opts[option].size);
strncpy (value, BUTTON_PRESSED_VALUE_COLLECT_KEY, scanner->opts[option].size);
break;
case BUTTON_FILE:
strncpy (value, "file", scanner->opts[option].size);
strncpy (value, BUTTON_PRESSED_VALUE_FILE_KEY, scanner->opts[option].size);
break;
case BUTTON_EMAIL:
strncpy (value, "email", scanner->opts[option].size);
strncpy (value, BUTTON_PRESSED_VALUE_EMAIL_KEY, scanner->opts[option].size);
break;
case BUTTON_COPY:
strncpy (value, "copy", scanner->opts[option].size);
strncpy (value, BUTTON_PRESSED_VALUE_COPY_KEY, scanner->opts[option].size);
break;
case BUTTON_UP:
strncpy (value, "up", scanner->opts[option].size);
strncpy (value, BUTTON_PRESSED_VALUE_UP_KEY, scanner->opts[option].size);
break;
case BUTTON_DOWN:
strncpy (value, "down", scanner->opts[option].size);
strncpy (value, BUTTON_PRESSED_VALUE_DOWN_KEY, scanner->opts[option].size);
break;
case BUTTON_MODE:
strncpy (value, "mode", scanner->opts[option].size);
strncpy (value, BUTTON_PRESSED_VALUE_MODE_KEY, scanner->opts[option].size);
break;
case BUTTON_CANCEL:
strncpy (value, "cancel", scanner->opts[option].size);
strncpy (value, BUTTON_PRESSED_VALUE_CANCEL_KEY, scanner->opts[option].size);
break;
case BUTTON_NONE:
default:
strncpy (value, "none", scanner->opts[option].size);
strncpy (value, BUTTON_PRESSED_VALUE_NONE_KEY, scanner->opts[option].size);
}
}
if (option == HP5590_OPT_COLOR_LED)
{
SANE_Int lcd_counter = 0;
enum color_led_status color_led = LED_COLOR;
SANE_Status ret = read_lcd_and_led_values(scanner, &lcd_counter, &color_led);
if (ret != SANE_STATUS_GOOD)
return ret;
switch (color_led) {
case LED_BLACKWHITE:
strncpy (value, COLOR_LED_VALUE_BLACKWHITE_KEY, scanner->opts[option].size);
break;
case LED_COLOR:
default:
strncpy (value, COLOR_LED_VALUE_COLOR_KEY, scanner->opts[option].size);
}
}
if (option == HP5590_OPT_LCD_COUNTER)
{
SANE_Int lcd_counter = 0;
enum color_led_status color_led = LED_COLOR;
SANE_Status ret = read_lcd_and_led_values(scanner, &lcd_counter, &color_led);
if (ret != SANE_STATUS_GOOD)
return ret;
*(SANE_Int *) value = lcd_counter;
}
if (option == HP5590_OPT_DOC_IN_ADF)
{
SANE_Bool doc_in_adf = SANE_FALSE;
SANE_Status ret = read_doc_in_adf_value(scanner, &doc_in_adf);
if (ret != SANE_STATUS_GOOD)
return ret;
*(SANE_Bool *) value = doc_in_adf;
}
if (option == HP5590_OPT_PREVIEW)
{
*(SANE_Bool *) value = scanner->preview;
@ -1208,6 +1361,21 @@ sane_control_option (SANE_Handle handle, SANE_Int option,
DBG(DBG_verbose, "State of buttons is read only. Setting of state will be ignored.\n");
}
if (option == HP5590_OPT_COLOR_LED)
{
DBG(DBG_verbose, "State of color LED indicator is read only. Setting of state will be ignored.\n");
}
if (option == HP5590_OPT_LCD_COUNTER)
{
DBG(DBG_verbose, "Value of LCD counter is read only. Setting of value will be ignored.\n");
}
if (option == HP5590_OPT_DOC_IN_ADF)
{
DBG(DBG_verbose, "Value of document-available indicator is read only. Setting of value will be ignored.\n");
}
if (option == HP5590_OPT_PREVIEW)
{
scanner->preview = *(SANE_Bool *) value;

Wyświetl plik

@ -1,8 +1,8 @@
/* sane - Scanner Access Now Easy.
Copyright (C) 2007 Ilia Sotnikov <hostcc@gmail.com>
HP ScanJet 4570c support by Markham Thomas
ADF page detection and high DPI fixes by Bernard Badr
scanbd integration by Damiano Scaramuzza and Bernard Badr
ADF page detection and high DPI fixes by Bernard Badeer
scanbd integration by Damiano Scaramuzza and Bernard Badeer
This file is part of the SANE package.
This program is free software; you can redistribute it and/or
@ -160,6 +160,7 @@ hp5590_models[] = {
#define CMD_GET_IMAGE_PARAMS 0x0034
#define CMD_START_SCAN 0x051b
#define CMD_BUTTON_STATUS 0x0020
#define CMD_LCD_STATUS 0x0021
struct init_resp
{
@ -825,7 +826,28 @@ hp5590_read_eeprom_all_cmd (SANE_Int dn,
if (ret != SANE_STATUS_GOOD)
return ret;
/* FIXME: Debug output */
DBG (DBG_verbose, "hp5590_read_eeprom_all_cmd: rc = %d\n", ret);
{
const int LEN = 4096;
char buf[LEN];
char* p = buf;
for (size_t i = 0; i < sizeof(eeprom); ++i) {
if (i % 16 == 0) {
int n = sprintf(p, "\n%04x ", (int)i);
if (n < 0) {
break;
}
p += n;
}
int n = sprintf(p, " %02x", eeprom[i]);
if (n < 0 ) {
break;
}
p += n;
}
*p = '\0';
DBG (DBG_verbose, "dump:%s\n", buf);
}
return SANE_STATUS_GOOD;
}
@ -1991,6 +2013,47 @@ hp5590_read_buttons (SANE_Int dn,
return SANE_STATUS_GOOD;
}
/******************************************************************************/
static SANE_Status
hp5590_read_lcd_and_led (SANE_Int dn,
enum proto_flags proto_flags,
SANE_Int * lcd_counter,
enum color_led_status * color_led)
{
SANE_Status ret;
DBG (DBG_proc, "%s\n", __func__);
hp5590_cmds_assert (lcd_counter != NULL);
hp5590_cmds_assert (color_led != NULL);
/*
* Read LCD status bytes and get current value of counter and
* state of color/black_white LED.
* data[0x29]: LCD counter value, data[0x2a]: 1=color / 2=black_white.
*/
uint8_t data[0x30];
ret = hp5590_cmd (dn,
proto_flags,
CMD_IN | CMD_VERIFY,
CMD_LCD_STATUS,
(unsigned char *) &data,
sizeof (data), CORE_NONE);
if (ret != SANE_STATUS_GOOD)
return ret;
*lcd_counter = data[0x29];
if (data[0x2a] == 2) {
*color_led = LED_BLACKWHITE;
} else {
*color_led = LED_COLOR;
}
DBG (DBG_cmds, "LCD and LED values: lcd=%d, led=%s\n", *lcd_counter,
*color_led == LED_BLACKWHITE ? "black_white" : "color");
return SANE_STATUS_GOOD;
}
/* SET SCAN PARAMETERS
==================== 50 =======================
BW 50 (425 x 585)

Wyświetl plik

@ -101,6 +101,12 @@ enum button_status
BUTTON_CANCEL
};
enum color_led_status
{
LED_COLOR = 1,
LED_BLACKWHITE
};
enum hp5590_lamp_state
{
LAMP_STATE_TURNOFF = 1,

Wyświetl plik

@ -1,69 +1,320 @@
.TH sane\-hp5590 5 "13 Jul 2008" "@PACKAGEVERSION@" "SANE Scanner Access Now Easy"
.IX sane\-hp5590
.\" Automatically generated by Pandoc 2.7.2
.\"
.TH "sane-hp5590" "5" "13 Jul 2008" "@PACKAGEVERSION@" "SANE Scanner Access Now Easy"
.hy
.SH NAME
sane\-hp5590 \- SANE backend for
Hewlett-Packard 4500C/4570C/5500C/5550C/5590/7650 Workgroup/Document scanners
.PP
sane-hp5590 - SANE backend for Hewlett-Packard
4500C/4570C/5500C/5550C/5590/7650 Workgroup/Document scanners
.SH DESCRIPTION
The
.B sane\-hp5590
library implements a SANE (Scanner Access Now Easy) backend that provides
access to the following Hewlett-Packard Workgroup/Document scanners:
.PP
.RS
The \f[B]sane-hp5590\f[R] library implements a SANE (Scanner Access Now
Easy) backend that provides access to the following Hewlett-Packard
Workgroup/Document scanners:
.IP \[bu] 2
ScanJet 4500C
.br
.IP \[bu] 2
ScanJet 4570C
.br
.IP \[bu] 2
ScanJet 5500C
.br
.IP \[bu] 2
ScanJet 5550C
.br
.IP \[bu] 2
ScanJet 5590
.br
.IP \[bu] 2
ScanJet 7650
.RE
.PP
If you own a scanner other than the ones listed above that works with this
backend, please let us know this by sending the scanner's exact model name and
the USB vendor and device ids (e.g. from
.IR /proc/bus/usb/devices ,
.I sane\-find\-scanner
or syslog) to us. Even if the scanner's name is only slightly different from
the models mentioned above, please let us know.
.SH CONFIGURATION
None required.
If you own a scanner other than the ones listed above that works with
this backend, please let us know this by sending the scanner\[cq]s exact
model name and the USB vendor and device ids (e.g.\ from
\f[I]/sys/bus/usb/devices\f[R], \f[I]sane-find-scanner\f[R] or syslog)
to us.
Even if the scanner\[cq]s name is only slightly different from the
models mentioned above, please let us know.
.SH OPTIONS
.PP
The options the backend supports can either be selected through command
line options to programs like scanimage or through GUI elements in
\f[I]xscanimage\f[R] or \f[I]xsane\f[R].
Valid command line options and their syntax can be listed by using:
.IP
.nf
\f[C]
scanimage --help -d hp5590:interface:device
\f[R]
.fi
.PP
where \f[I]interface\f[R] and \f[I]device\f[R] specify the device in
question, as in the configuration file.
Add \f[I]--all-options\f[R] to also list the hardware read-out options.
The -d parameter and its argument can be omitted to obtain information
on the first scanner identified.
.PP
Use the command:
.IP
.nf
\f[C]
scanimage -L
\f[R]
.fi
.PP
to list all devices recognized by your SANE installation.
.SH DEVICE SPECIFIC OPTIONS
.TP
.B -l \f[I]n\f[R]
Top-left X position of scan area in \f[B]mm\f[R].
Allowed range: 0 ..
215.889.
.TP
.B -t \f[I]n\f[R]
Top-left Y position of scan area in \f[B]mm\f[R].
Allowed range: 0 ..
297.699.
.TP
.B -x \f[I]n\f[R]
X width of scan-area in \f[B]mm\f[R].
Allowed range: 0 ..
215.889.
.TP
.B -y \f[I]n\f[R]
Y height of scan-area in \f[B]mm\f[R].
Allowed range: 0 ..
297.699.
.PP
By default, the maximum size will be scanned.
.TP
.B --mode \f[I]mode\f[R]
Select color mode.
\f[I]mode\f[R] must be one of: \[lq]Color\[rq], \[lq]Color (48
bits)\[rq], \[lq]Gray\[rq], \[lq]Lineart\[rq].
.RS
.IP \[bu] 2
\[lq]Color\[rq] - Scanning is done with 3 * 8 bit RGB color values per
pixel.
.IP \[bu] 2
\[lq]Color (48 bits)\[rq] - Scanning is done with 3 * 16 bit RGB color
values per pixel.
.IP \[bu] 2
\[lq]Gray\[rq] - Scanning is done with 1 * 8 bit gray value per pixel.
.IP \[bu] 2
\[lq]Lineart\[rq] - Scanning is done with 1 bit black and white value
per pixel.
.RE
.TP
.B --source \f[I]source\f[R]
Select the source for scanning.
\f[I]source\f[R] must be one of: \[lq]Flatbed\[rq], \[lq]ADF\[rq],
\[lq]ADF Duplex\[rq], \[lq]TMA Slides\[rq], \[lq]TMA Negatives\[rq].
.RS
.IP \[bu] 2
\[lq]Flatbed\[rq] - Scan document on the flat document glass.
.IP \[bu] 2
\[lq]ADF\[rq] - Scan frontsides of documents with automatic document
feeder.
.IP \[bu] 2
\[lq]ADF Duplex\[rq] - Scan front- and backsides of documents with
automatic document feeder.
Note, the backside images must be rotated in a separate post process
step.
.IP \[bu] 2
\[lq]TMA Slides\[rq] - Slide scanning with transparent media adapter.
(Not fully supported by hp5590 backend).
.IP \[bu] 2
\[lq]TMA Negatives\[rq] - Negative film scanning with transparent media
adapter.
(Not fully supported by hp5590 backend).
.RE
.TP
.B --resolution \f[I]res\f[R]
Set the resolution of the scanned image in \f[B]dpi\f[R].
\f[I]res\f[R] must be one of: 100, 200, 300, 600, 1200, 2400.
.PP
Default settings: Lineart, Flatbed, 100dpi.
.TP
.B --extend-lamp-timeout[=yes|no]
Extend lamp timeout period.
no = 15 minutes, yes = 1 hour.
(Default: no)
.TP
.B --wait-for-button[=yes|no]
Wait for button press before scanning starts.
(Default: no)
.TP
.B --preview[=yes|no]
Request a preview-quality scan.
(Default: no)
.TP
.B --hide-eop-pixel[=yes|no]
Hide end-of-page indicator pixels and overwrite with color of next
neighbor pixels.
(Default: yes)
.PD 0
.P
.PD
The scanner uses the last pixel in every scan line for storing the
end-of-page status.
This is needed to detect the end of the document sheet when the
automatic document feeder (ADF) is used.
Unfortunately the end-of-page pixels are also generated in flatbed
scans.
It is recommended to hide these pixels.
.TP
.B --trailing-lines-mode \f[I]mode\f[R]
Filling mode of trailing lines after end of page when automatic document
feeder (ADF) is used.
\f[I]mode\f[R] must be one of: \[lq]last\[rq], \[lq]raw\[rq],
\[lq]raster\[rq], \[lq]white\[rq], \[lq]black\[rq], \[lq]color\[rq].
(Default: \[lq]last\[rq])
.RS
.IP \[bu] 2
\[lq]last\[rq] = repeat the last scan line (recommended),
.IP \[bu] 2
\[lq]raw\[rq] = read raw scan data (not recommended),
.IP \[bu] 2
\[lq]raster\[rq] = generate black and white pixel pattern,
.IP \[bu] 2
\[lq]white\[rq] = white pixels,
.IP \[bu] 2
\[lq]black\[rq] = black pixels,
.IP \[bu] 2
\[lq]color\[rq] = RGB or gray colored pixels (see next option).
.RE
.TP
.B --trailing-lines-color \f[I]n\f[R]
Set color value for filling trailing scan lines in trailing lines mode
\[lq]color\[rq] (see previous option).
(Default color: violet)
.PD 0
.P
.PD
The RGB color value must be specified and calculated as 65536 * r + 256
* g + b, with r, g, b being values in the range of 0 ..
255.
.SH READ OUT OPTIONS
.PP
The following options allow reading out the button state, counter value,
color setting, and the state of document in ADF.
This can be used to programmatically control corresponding scanner
options like switching between \f[I]flatbed\f[R] and \f[I]ADF\f[R] mode,
or triggering prost processing tasks after scanning.
.TP
.B --button-pressed
Get the id of the last button pressed.
Id is one of \[lq]none\[rq], \[lq]power\[rq], \[lq]scan\[rq],
\[lq]collect\[rq], \[lq]file\[rq], \[lq]email\[rq], \[lq]copy\[rq],
\[lq]up\[rq], \[lq]down\[rq], \[lq]mode\[rq], \[lq]cancel\[rq].
.PD 0
.P
.PD
The scanner stores the id of the last button pressed until it is read.
After read out, the state is reset and subsequent readings will return
\[lq]none\[rq].
.TP
.B --color-led
Get the state of the color LED indicators.
The state is either \[lq]color\[rq] or \[lq]black_white\[rq].
.TP
.B --counter-value
Get the counter value as shown on LCD.
The value is in the range of 1 ..
99.
.TP
.B --doc-in-adf
Get the state of the document-available indicator of the automatic
document feeder (ADF).
The state is either \[lq]yes\[rq] or \[lq]no\[rq].
.SH HINTS FOR USERS OF SCANBD
.PP
\f[I]Scanbd\f[R] is a scanner button daemon, which can read scanner
buttons and trigger scan actions.
.PP
Do not use the old \f[I]scanbuttond\f[R] interface with hp5590.
It is outdated and shall not be used any more.
Scanbd\[cq]s regular interface is fully supported by the current version
of the \f[I]hp5590\f[R] backend.
.PP
This example shows a minimum configuration file and the corresponding
script file for scanbd to be included in \f[I]scanbd.conf\f[R].
.IP \[bu] 2
\f[B]hp5590.conf\f[R]
.IP
.nf
\f[C]
device hp5590 {
# Device matching
filter = \[dq]\[ha]hp5590.*\[dq]
desc = \[dq]HP5590 Scanner Family\[dq]
# Read out counter value and store in environment variable.
function function_lcd_counter {
filter = \[dq]\[ha]counter-value.*\[dq]
desc = \[dq]hp5590: LCD counter\[dq]
env = \[dq]SCANBD_FUNCTION_LCD_COUNTER\[dq]
}
# Run scan script when button is pressed.
action do-scan {
filter = \[dq]\[ha]button-pressed.*\[dq]
desc = \[dq]hp5590: Scan button pressed\[dq]
script = \[dq]scan_action.script\[dq]
string-trigger {
from-value = \[dq]none\[dq]
to-value = \[dq]scan\[dq]
}
}
}
\f[R]
.fi
.IP \[bu] 2
\f[B]scan_action.script\f[R]
.IP
.nf
\f[C]
#!/bin/bash
echo device = $SCANBD_DEVICE
echo action = $SCANBD_ACTION
echo counter = $SCANBD_FUNCTION_LCD_COUNTER
scanfile=\[dq]$HOME/tmp/scans/scan-$(date +%s).pnm\[dq]
case $SCANBD_ACTION in
do-scan)
scanimage -d \[dq]$SCANBD_DEVICE\[dq] > \[dq]$scanfile\[dq]
;;
*)
echo Warning: Unknown scanbd action: \[dq]$SCANBD_ACTION\[dq]
;;
esac
\f[R]
.fi
.SH FILES
.TP
.I @LIBDIR@/libsane\-hp5590.a
.B \f[I]\[at]LIBDIR\[at]/libsane-hp5590.a\f[R]
The static library implementing this backend.
.TP
.I @LIBDIR@/libsane\-hp5590.so
.B \f[I]\[at]LIBDIR\[at]/libsane-hp5590.so\f[R]
The shared library implementing this backend (present on systems that
support dynamic loading).
.SH ENVIRONMENT
.PP
If the library was compiled with debug support enabled, this environment
variable controls the debug level for this backend.
.PP
\f[B]SANE_DEBUG_HP5590\f[R]
.PP
Higher debug levels increase the verbosity of the output:
.IP
.nf
\f[C]
10 - generic processing
20 - verbose backend messages
40 - HP5590 high-level commands
50 - HP5590 low-level (USB-in-USB) commands
\f[R]
.fi
.TP
.B SANE_DEBUG_HP5590
If the library was compiled with debug support enabled, this
environment variable controls the debug level for this backend. Higher
debug levels increase the verbosity of the output. See used levels below.
.P
.RS
Level 10 - generic processing
.br
Level 20 - verbose backend messages
.br
Level 40 - HP5590 high-level commands
.br
Level 50 - HP5590 low-level (USB-in-USB) commands
.P
Example:
.B Example:
export SANE_DEBUG_HP5590=50
.SH "SEE ALSO"
.BR sane (7),
.BR sane\-usb (5),
.SH AUTHOR
Ilia Sotnikov <hostcc@gmail.com>
.SH SEE ALSO
.PP
\f[B]sane\f[R](7), \f[B]sane-usb\f[R](5)
.SH AUTHORS
Ilia Sotnikov <hostcc@gmail.com>.