Full support for libusb.

DEVEL_2_0_BRANCH-1
Karl Heinz Kremer 2002-11-03 20:47:46 +00:00
rodzic 1e746b9637
commit 0ee8173f13
2 zmienionych plików z 268 dodań i 210 usunięć

Wyświetl plik

@ -1,3 +1,7 @@
2002-11-03 Karl Heinz Kremer <khk@khk.net>
* backend/epson.c: Full support for libusb
2002-11-03 Henning Meier-Geinitz <henning@meier-geinitz.de> 2002-11-03 Henning Meier-Geinitz <henning@meier-geinitz.de>
* README configure.in configure po/Makefile.in po/README: * README configure.in configure po/Makefile.in po/README:

Wyświetl plik

@ -16,8 +16,8 @@
*/ */
#define SANE_EPSON_VERSION "SANE Epson Backend v0.2.24 - 2002-10-05" #define SANE_EPSON_VERSION "SANE Epson Backend v0.2.30 - 2002-11-03"
#define SANE_EPSON_BUILD 224 #define SANE_EPSON_BUILD 230
/* /*
This file is part of the SANE package. This file is part of the SANE package.
@ -59,6 +59,7 @@
If you do not wish that, delete this exception notice. */ If you do not wish that, delete this exception notice. */
/* /*
2002-11-03 Full libusb support.
2002-10-05 Fixed problem with incorrect response to sane_get_parameters() 2002-10-05 Fixed problem with incorrect response to sane_get_parameters()
in certain situations. in certain situations.
2002-09-01 USB scanners are now using libsane-usb funtions 2002-09-01 USB scanners are now using libsane-usb funtions
@ -745,7 +746,8 @@ max_string_size (const SANE_String_Const strings[])
typedef struct { typedef struct {
u_char code; u_char code;
u_char status; u_char status;
u_short count; u_char count1;
u_char count2;
u_char buf [ 1]; u_char buf [ 1];
} EpsonHdrRec, * EpsonHdr; } EpsonHdrRec, * EpsonHdr;
@ -753,7 +755,8 @@ typedef struct {
typedef struct { typedef struct {
u_char code; u_char code;
u_char status; u_char status;
u_short count; u_char count1;
u_char count2;
u_char type; u_char type;
u_char level; u_char level;
@ -785,20 +788,29 @@ typedef struct {
* *
*/ */
static EpsonHdr command ( Epson_Scanner * s, u_char * cmd, size_t cmd_size, SANE_Status * status); static EpsonHdr command ( Epson_Scanner * s, u_char * cmd, size_t cmd_size,
SANE_Status * status);
static SANE_Status get_identity_information(SANE_Handle handle); static SANE_Status get_identity_information(SANE_Handle handle);
static SANE_Status get_identity2_information(SANE_Handle handle); static SANE_Status get_identity2_information(SANE_Handle handle);
static int send ( Epson_Scanner * s, void *buf, size_t buf_size, SANE_Status * status); static int send ( Epson_Scanner * s, void *buf, size_t buf_size,
static ssize_t receive ( Epson_Scanner * s, void *buf, ssize_t buf_size, SANE_Status * status); 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 color_shuffle(SANE_Handle handle, int *new_length);
static SANE_Status request_focus_position(SANE_Handle handle, u_char * position); static SANE_Status request_focus_position(SANE_Handle handle,
static SANE_Bool request_push_button_status(SANE_Handle handle, SANE_Bool * theButtonStatus); u_char * position);
static void sane_activate( Epson_Scanner * s, SANE_Int option, SANE_Bool * change); static SANE_Bool request_push_button_status(SANE_Handle handle,
static void sane_deactivate( Epson_Scanner * s, SANE_Int option, SANE_Bool * change); SANE_Bool * theButtonStatus);
static void sane_optstate( SANE_Bool state, Epson_Scanner * s, SANE_Int option, SANE_Bool * change); static void sane_activate( Epson_Scanner * s, SANE_Int option,
SANE_Bool * change);
static void sane_deactivate( Epson_Scanner * s, SANE_Int option,
SANE_Bool * change);
static void sane_optstate( SANE_Bool state, Epson_Scanner * s,
SANE_Int option, SANE_Bool * change);
static void close_scanner( Epson_Scanner * s); static void close_scanner( Epson_Scanner * s);
static SANE_Status open_scanner( Epson_Scanner * s); static SANE_Status open_scanner( Epson_Scanner * s);
SANE_Status sane_auto_eject ( Epson_Scanner * s); SANE_Status sane_auto_eject ( Epson_Scanner * s);
static SANE_Status attach_one_usb(SANE_String_Const devname);
/* /*
* *
@ -815,8 +827,10 @@ send(Epson_Scanner * s, void *buf, size_t buf_size, SANE_Status * status)
size_t k; size_t k;
const u_char * s = buf; const u_char * s = buf;
for( k = 0; k < buf_size; k++) { for (k = 0; k < buf_size; k++)
DBG( 125, "buf[%u] %02x %c\n", k, s[ k], isprint( s[ k]) ? s[ k] : '.'); {
DBG( 125, "buf[%u] %02x %c\n", k, s[ k],
isprint( s[ k]) ? s[ k] : '.');
} }
} }
#endif #endif
@ -862,7 +876,7 @@ receive(Epson_Scanner * s, void *buf, ssize_t buf_size, SANE_Status * status)
{ {
n = sanei_epson_scsi_read(s->fd, buf, buf_size, status); n = sanei_epson_scsi_read(s->fd, buf, buf_size, status);
} }
else if ( s->hw->connection == SANE_EPSON_PIO) else if ( s->hw->connection == SANE_EPSON_PIO)
{ {
if (buf_size == (n = sanei_pio_read( s->fd, buf, (size_t) buf_size))) if (buf_size == (n = sanei_pio_read( s->fd, buf, (size_t) buf_size)))
*status = SANE_STATUS_GOOD; *status = SANE_STATUS_GOOD;
@ -918,7 +932,6 @@ receive(Epson_Scanner * s, void *buf, ssize_t buf_size, SANE_Status * status)
{ {
if (k!=0) /* don't do this the first time */ if (k!=0) /* don't do this the first time */
{ {
fprintf(stderr, "running from i=%d to %d\n", strlen(hex_str), NUM_OF_HEX_ELEMENTS*3);
for (i = strlen(hex_str); i < (NUM_OF_HEX_ELEMENTS*3); i++) for (i = strlen(hex_str); i < (NUM_OF_HEX_ELEMENTS*3); i++)
{ {
hex_str[i] = ' '; hex_str[i] = ' ';
@ -951,7 +964,9 @@ fprintf(stderr, "running from i=%d to %d\n", strlen(hex_str), NUM_OF_HEX_ELEMENT
* *
*/ */
static SANE_Status expect_ack ( Epson_Scanner * s) { static SANE_Status
expect_ack(Epson_Scanner * s)
{
u_char result [ 1]; u_char result [ 1];
size_t len; size_t len;
SANE_Status status; SANE_Status status;
@ -1403,7 +1418,8 @@ static void close_scanner ( Epson_Scanner * s)
* different open functions are called. * different open functions are called.
*/ */
static SANE_Status open_scanner ( Epson_Scanner * s) static SANE_Status
open_scanner(Epson_Scanner * s)
{ {
SANE_Status status = 0; SANE_Status status = 0;
@ -1411,7 +1427,7 @@ static SANE_Status open_scanner ( Epson_Scanner * s)
/* don't do this for OS2: */ /* don't do this for OS2: */
#ifndef HAVE_OS2_H #ifndef HAVE_OS2_H
#if 0
/* test the device name */ /* test the device name */
if ((s->hw->connection != SANE_EPSON_PIO) && (access(s->hw->sane.name, R_OK | W_OK) != 0)) if ((s->hw->connection != SANE_EPSON_PIO) && (access(s->hw->sane.name, R_OK | W_OK) != 0))
{ {
@ -1419,20 +1435,27 @@ static SANE_Status open_scanner ( Epson_Scanner * s)
return SANE_STATUS_ACCESS_DENIED; return SANE_STATUS_ACCESS_DENIED;
} }
#endif #endif
#endif
if( s->hw->connection == SANE_EPSON_SCSI) { if( s->hw->connection == SANE_EPSON_SCSI)
status = sanei_scsi_open(s->hw->sane.name, &s->fd, sanei_epson_scsi_sense_handler, NULL); {
status = sanei_scsi_open(s->hw->sane.name, &s->fd,
sanei_epson_scsi_sense_handler, NULL);
if (SANE_STATUS_GOOD != status) if (SANE_STATUS_GOOD != status)
{ {
DBG(1, "sane_start: %s open failed: %s\n", s->hw->sane.name, sane_strstatus( status)); DBG(1, "sane_start: %s open failed: %s\n", s->hw->sane.name,
sane_strstatus( status));
return status; return status;
} }
} else if ( s->hw->connection == SANE_EPSON_PIO) { }
else if (s->hw->connection == SANE_EPSON_PIO)
{
status = sanei_pio_open( s->hw->sane.name, &s->fd); status = sanei_pio_open( s->hw->sane.name, &s->fd);
if( SANE_STATUS_GOOD != status) if( SANE_STATUS_GOOD != status)
{ {
DBG(1, "sane_start: %s open failed: %s\n", s->hw->sane.name, sane_strstatus( status)); DBG(1, "sane_start: %s open failed: %s\n", s->hw->sane.name,
sane_strstatus( status));
return status; return status;
} }
} }
@ -1493,10 +1516,11 @@ static Epson_Scanner *first_handle = NULL;
static EpsonHdr static EpsonHdr
command ( Epson_Scanner * s, u_char * cmd, size_t cmd_size, SANE_Status * status) command(Epson_Scanner * s, u_char * cmd, size_t cmd_size, SANE_Status * status)
{ {
EpsonHdr head; EpsonHdr head;
u_char * buf; u_char * buf;
int count;
if( NULL == ( head = walloc( EpsonHdrRec))) { if( NULL == ( head = walloc( EpsonHdrRec))) {
DBG( 1, "out of memory (line %d)\n", __LINE__); DBG( 1, "out of memory (line %d)\n", __LINE__);
@ -1517,10 +1541,10 @@ command ( Epson_Scanner * s, u_char * cmd, size_t cmd_size, SANE_Status * status
buf += 4; buf += 4;
} }
else if (s->hw->connection == SANE_EPSON_USB) else if (s->hw->connection == SANE_EPSON_USB)
{ {
int bytes_read; int bytes_read;
bytes_read = receive( s, buf, 4, status); bytes_read = receive( s, buf, 4, status);
buf += bytes_read; buf += bytes_read;
} }
else else
{ {
@ -1534,61 +1558,63 @@ command ( Epson_Scanner * s, u_char * cmd, size_t cmd_size, SANE_Status * status
DBG( 4, "code %02x\n", (int) head->code); DBG( 4, "code %02x\n", (int) head->code);
switch (head->code) switch (head->code)
{ {
case NAK: case NAK:
/* fall through */ /* fall through */
/* !!! is this really sufficient to report an error ? */ /* !!! is this really sufficient to report an error ? */
case ACK: case ACK:
break; /* no need to read any more data after ACK or NAK */ break; /* no need to read any more data after ACK or NAK */
case STX: case STX:
if( s->hw->connection == SANE_EPSON_SCSI) if( s->hw->connection == SANE_EPSON_SCSI)
{ {
/* nope */ /* nope */
} }
else if (s->hw->connection == SANE_EPSON_USB) else if (s->hw->connection == SANE_EPSON_USB)
{ {
/* we've already read the complete data */ /* we've already read the complete data */
} }
else else
{ {
receive (s, buf, 3, status); receive (s, buf, 3, status);
/* buf += 3; */ /* buf += 3; */
} }
if( SANE_STATUS_GOOD != *status) if( SANE_STATUS_GOOD != *status)
return (EpsonHdr) 0; return (EpsonHdr) 0;
DBG( 4, "status %02x\n", (int) head->status); DBG( 4, "status %02x\n", (int) head->status);
DBG( 4, "count %d\n", (int) head->count);
if( NULL == (head = realloc (head, sizeof (EpsonHdrRec) + head->count))) count = head->count2 * 255 + head->count1;
{ DBG( 4, "count %d\n", count);
DBG( 1, "out of memory (line %d)\n", __LINE__);
*status = SANE_STATUS_NO_MEM;
return (EpsonHdr) 0;
}
buf = head->buf; if( NULL == (head = realloc (head, sizeof (EpsonHdrRec) + count)))
receive (s, buf, head->count, status); {
DBG( 1, "out of memory (line %d)\n", __LINE__);
*status = SANE_STATUS_NO_MEM;
return (EpsonHdr) 0;
}
if( SANE_STATUS_GOOD != *status) buf = head->buf;
return (EpsonHdr) 0; receive (s, buf, count, status);
break; if( SANE_STATUS_GOOD != *status)
return (EpsonHdr) 0;
default: break;
if( 0 == head->code)
DBG( 1, "Incompatible printer port (probably bi/directional)\n");
else if( cmd[cmd_size - 1] == head->code)
DBG( 1, "Incompatible printer port (probably not bi/directional)\n");
DBG( 2, "Illegal response of scanner for command: %02x\n", head->code); default:
break; if( 0 == head->code)
} DBG( 1, "Incompatible printer port (probably bi/directional)\n");
else if( cmd[cmd_size - 1] == head->code)
DBG( 1, "Incompatible printer port (probably not bi/directional)\n");
return head; DBG( 2, "Illegal response of scanner for command: %02x\n", head->code);
break;
}
return head;
} }
@ -1598,16 +1624,19 @@ command ( Epson_Scanner * s, u_char * cmd, size_t cmd_size, SANE_Status * status
* Attach one device with name *dev_name to the backend. * Attach one device with name *dev_name to the backend.
*/ */
static SANE_Status attach ( const char * dev_name, Epson_Device * * devp) { static SANE_Status
attach(const char * dev_name, Epson_Device * * devp, int type)
{
SANE_Status status; SANE_Status status;
Epson_Scanner * s = walloca( Epson_Scanner); Epson_Scanner * s = walloca( Epson_Scanner);
char * str; char * str;
struct Epson_Device * dev; struct Epson_Device * dev;
SANE_String_Const * source_list_add = source_list; SANE_String_Const * source_list_add = source_list;
int port;
DBG(1, "%s\n", SANE_EPSON_VERSION); DBG(1, "%s\n", SANE_EPSON_VERSION);
DBG(5, "attach(%s)\n", dev_name); DBG(5, "attach(%s, %d)\n", dev_name, type);
for (dev = first_dev; dev; dev = dev->next) for (dev = first_dev; dev; dev = dev->next)
{ {
@ -1623,16 +1652,32 @@ static SANE_Status attach ( const char * dev_name, Epson_Device * * devp) {
dev = malloc(sizeof(*dev)); dev = malloc(sizeof(*dev));
if (!dev) if (!dev)
{ {
DBG( 1, "out of memory (line %d)\n", __LINE__); DBG( 1, "out of memory (line %d)\n", __LINE__);
return SANE_STATUS_NO_MEM; return SANE_STATUS_NO_MEM;
} }
/* check for PIO devices */
/* can we convert the device name to an integer? This is only possible
with PIO devices */
port = atoi(dev_name);
if (port != 0)
{
type = SANE_EPSON_PIO;
}
/* if (strncmp(dev_name, SANE_EPSON_CONFIG_PIO, strlen(SANE_EPSON_CONFIG_PIO)) == 0)
* set dummy values. {
*/ /* we have a match for the PIO string and adjust the device name */
dev_name += strlen(SANE_EPSON_CONFIG_PIO);
dev_name = sanei_config_skip_whitespace(dev_name);
type = SANE_EPSON_PIO;
}
/*
* set dummy values.
*/
s->hw = dev; s->hw = dev;
s->hw->sane.name = NULL; s->hw->sane.name = NULL;
@ -1646,66 +1691,32 @@ static SANE_Status attach ( const char * dev_name, Epson_Device * * devp) {
s->hw->need_color_reorder = SANE_FALSE; s->hw->need_color_reorder = SANE_FALSE;
s->hw->need_double_vertical = SANE_FALSE; s->hw->need_double_vertical = SANE_FALSE;
s->hw->cmd = &epson_cmd[EPSON_LEVEL_DEFAULT]; /* use default function level */ s->hw->cmd = &epson_cmd[EPSON_LEVEL_DEFAULT]; /* default function level */
s->hw->connection = SANE_EPSON_NODEV; /* no device configured yet */ s->hw->connection = type;
DBG( 3, "attach: opening %s\n", dev_name); DBG( 3, "attach: opening %s\n", dev_name);
s->hw->last_res = s->hw->last_res_preview = 0; /* set resolution to safe values */ s->hw->last_res = 0;
s->hw->last_res_preview = 0; /* set resolution to safe values */
/*
* decide if interface is USB, SCSI or parallel.
*/
/* /*
* if the config file contains a line "usb /dev/usbscanner", then handle this * decide if interface is USB, SCSI or parallel.
* here and use the USB device from now on.
*/ */
if (strncmp(dev_name, SANE_EPSON_CONFIG_USB, strlen(SANE_EPSON_CONFIG_USB)) == 0) {
/* we have a match for the USB string and adjust the device name */
dev_name += strlen(SANE_EPSON_CONFIG_USB);
dev_name = sanei_config_skip_whitespace(dev_name);
s->hw->connection = SANE_EPSON_USB;
/*
* if the config file contains a line "usb /dev/usbscanner", then handle
* this here and use the USB device from now on.
*/
if (s->hw->connection == SANE_EPSON_USB)
{
/* we have a match for the USB string and adjust the device name */
sanei_usb_init(); sanei_usb_init();
} }
/* /*
* if the config file contains a line "pio 0xXXX", then handle this case here * if interface is SCSI do an inquiry.
* and use the PIO (parallel interface) device from now on.
*/ */
else if (strncmp(dev_name, SANE_EPSON_CONFIG_PIO, strlen(SANE_EPSON_CONFIG_PIO)) == 0) {
/* we have a match for the PIO string and adjust the device name */
dev_name += strlen(SANE_EPSON_CONFIG_PIO);
dev_name = sanei_config_skip_whitespace(dev_name);
s->hw->connection = SANE_EPSON_PIO;
}
else { /* legacy mode */
char * end;
strtol( dev_name, &end, 0);
if( ( end == dev_name) || *end) {
s->hw->connection = SANE_EPSON_SCSI;
} else {
s->hw->connection = SANE_EPSON_PIO;
}
}
if (s->hw->connection == SANE_EPSON_NODEV)
{
/*
With the current code this can neve happen, because
the routine to handle the legacy mode will always
return a SCSI device. If this gets changed however,
here is the test to return with an error code.
*/
return SANE_STATUS_INVAL;
}
/*
* if interface is SCSI do an inquiry.
*/
if( s->hw->connection == SANE_EPSON_SCSI) if( s->hw->connection == SANE_EPSON_SCSI)
{ {
@ -1738,13 +1749,13 @@ static SANE_Status attach ( const char * dev_name, Epson_Device * * devp) {
*/ */
if( buf[ 0] != TYPE_PROCESSOR if( buf[ 0] != TYPE_PROCESSOR
|| strncmp( buf + 8, "EPSON", 5) != 0 || strncmp( buf + 8, "EPSON", 5) != 0
|| (strncmp( buf + 16, "SCANNER ", 8) != 0 || (strncmp( buf + 16, "SCANNER ", 8) != 0
&& strncmp( buf + 14, "SCANNER ", 8) != 0 && strncmp( buf + 14, "SCANNER ", 8) != 0
&& strncmp( buf + 14, "Perfection", 10) != 0 && strncmp( buf + 14, "Perfection", 10) != 0
&& strncmp( buf + 16, "Perfection", 10) != 0 && strncmp( buf + 16, "Perfection", 10) != 0
&& strncmp( buf + 16, "Expression", 10) != 0 && strncmp( buf + 16, "Expression", 10) != 0
&& strncmp( buf + 16, "GT", 2) != 0 )) && strncmp( buf + 16, "GT", 2) != 0 ))
{ {
DBG( 1, "attach: device doesn't look like an EPSON scanner\n"); DBG( 1, "attach: device doesn't look like an EPSON scanner\n");
close_scanner( s); close_scanner( s);
@ -1757,7 +1768,7 @@ static SANE_Status attach ( const char * dev_name, Epson_Device * * devp) {
if( SANE_STATUS_GOOD != ( status = sanei_pio_open(dev_name, &s->fd))) if( SANE_STATUS_GOOD != ( status = sanei_pio_open(dev_name, &s->fd)))
{ {
DBG(0, "Cannot open %s as a parallel-port device: %s\n", DBG(0, "Cannot open %s as a parallel-port device: %s\n",
dev_name, sane_strstatus( status)); dev_name, sane_strstatus( status));
return status; return status;
} }
} }
@ -1765,10 +1776,29 @@ static SANE_Status attach ( const char * dev_name, Epson_Device * * devp) {
else if (s->hw->connection == SANE_EPSON_USB) else if (s->hw->connection == SANE_EPSON_USB)
{ {
SANE_Word vendor; SANE_Word vendor;
SANE_Word product; SANE_Word product;
SANE_Bool isLibUSB;
isLibUSB = (strncmp(dev_name, "libusb:", strlen("libusb:")) == 0);
if ((!isLibUSB) && (strlen(dev_name) == 0))
{
int i;
i = 0;
while (sanei_epson_usb_product_ids[i] != 0)
{
product = sanei_epson_usb_product_ids[i];
vendor = 0x4b8;
status = sanei_usb_find_devices(vendor, product, attach_one_usb);
i++;
}
return SANE_STATUS_INVAL; /* return - the attach_one_usb()
will take care of this */
}
status = sanei_usb_open(dev_name, &s->fd); status = sanei_usb_open(dev_name, &s->fd);
if (SANE_STATUS_GOOD != status) if (SANE_STATUS_GOOD != status)
{ {
return status; return status;
@ -1810,7 +1840,7 @@ static SANE_Status attach ( const char * dev_name, Epson_Device * * devp) {
if (is_valid == SANE_FALSE) if (is_valid == SANE_FALSE)
{ {
DBG(0, "The device at %s is not a supported EPSON scanner (product id=0x%x)\n", DBG(0, "The device at %s is not a supported EPSON scanner (product id=0x%x)\n",
dev_name, product); dev_name, product);
sanei_usb_close(s->fd); sanei_usb_close(s->fd);
s->fd = -1; s->fd = -1;
return SANE_STATUS_INVAL; return SANE_STATUS_INVAL;
@ -1823,15 +1853,15 @@ static SANE_Status attach ( const char * dev_name, Epson_Device * * devp) {
} }
} }
/* /*
* Initialize the scanner (ESC @). * Initialize the scanner (ESC @).
*/ */
reset(s); reset(s);
/* /*
* Identification Request (ESC I). * Identification Request (ESC I).
*/ */
if (s->hw->cmd->request_identity != 0) if (s->hw->cmd->request_identity != 0)
{ {
status = get_identity_information(s); status = get_identity_information(s);
@ -1978,7 +2008,6 @@ static SANE_Status attach ( const char * dev_name, Epson_Device * * devp) {
u_char * buf; u_char * buf;
u_char params[2]; u_char params[2];
EpsonHdr head; EpsonHdr head;
DBG(0, "Requesting extended status\n");
params[0] = ESC; params[0] = ESC;
params[1] = s->hw->cmd->request_extended_status; params[1] = s->hw->cmd->request_extended_status;
@ -1991,14 +2020,10 @@ DBG(0, "Requesting extended status\n");
{ {
buf = &head->buf[ 0]; buf = &head->buf[ 0];
DBG(0, "No error\n");
/* /*
* ADF * ADF
*/ */
DBG(0, "Checking for ADF: (%02x)\n", buf[1]);
if( buf[ 1] & EXT_STATUS_IST) { if( buf[ 1] & EXT_STATUS_IST) {
DBG( 1, "ADF detected\n"); DBG( 1, "ADF detected\n");
@ -2032,7 +2057,6 @@ DBG(0, "Checking for ADF: (%02x)\n", buf[1]);
/* /*
* TPU * TPU
*/ */
DBG(0, "Checking for TPU: (%02x)\n", buf[6]);
if( buf[ 6] & EXT_STATUS_IST) { if( buf[ 6] & EXT_STATUS_IST) {
DBG( 1, "TPU detected\n"); DBG( 1, "TPU detected\n");
@ -2091,7 +2115,6 @@ DBG(0, "Checking for TPU: (%02x)\n", buf[6]);
/* finally copy the device name to the structure */ /* finally copy the device name to the structure */
dev->sane.model = ( char *) memcpy( str, device_name, len); dev->sane.model = ( char *) memcpy( str, device_name, len);
DBG(0, "Device name = %s\n", dev->sane.model);
} }
} }
} }
@ -2146,60 +2169,88 @@ DBG(0, "Device name = %s\n", dev->sane.model);
static SANE_Status attach_one ( const char *dev) static SANE_Status attach_one ( const char *dev)
{ {
DBG(5, "attach(%s)\n", dev); DBG(5, "attach_one(%s)\n", dev);
return attach( dev, 0); return attach(dev, 0, SANE_EPSON_SCSI);
} }
SANE_Status attach_one_usb(SANE_String_Const devname)
{
int len = strlen(devname);
char * attach_string;
DBG(5, "attach_one_usb(%s)\n", devname);
attach_string = alloca(len + 5);
if (attach_string == NULL)
return SANE_STATUS_NO_MEM;
return attach(devname, 0, SANE_EPSON_USB);
}
/* /*
* sane_init() * sane_init()
* *
* *
*/ */
SANE_Status
sane_init(SANE_Int * version_code, SANE_Auth_Callback authorize)
{
size_t len;
FILE *fp;
SANE_Status sane_init (SANE_Int * version_code, SANE_Auth_Callback authorize) { authorize = authorize; /* get rid of compiler warning */
size_t len;
FILE *fp;
authorize = authorize; /* get rid of compiler warning */ /* sanei_authorization(devicename, STRINGIFY(BACKEND_NAME), auth_callback); */
/* sanei_authorization(devicename, STRINGIFY(BACKEND_NAME), auth_callback); */ DBG_INIT ();
DBG_INIT ();
#if defined PACKAGE && defined VERSION #if defined PACKAGE && defined VERSION
DBG( 2, "sane_init: " PACKAGE " " VERSION "\n"); DBG( 2, "sane_init: " PACKAGE " " VERSION "\n");
#endif #endif
if( version_code != NULL) if( version_code != NULL)
*version_code = SANE_VERSION_CODE (V_MAJOR, V_MINOR, SANE_EPSON_BUILD); *version_code = SANE_VERSION_CODE (V_MAJOR, V_MINOR, SANE_EPSON_BUILD);
/* default to /dev/scanner instead of insisting on config file */ /* default to /dev/scanner instead of insisting on config file */
if( (fp = sanei_config_open (EPSON_CONFIG_FILE))) if( (fp = sanei_config_open (EPSON_CONFIG_FILE)))
{
char line[PATH_MAX];
while (sanei_config_read (line, sizeof (line), fp))
{ {
DBG( 4, "sane_init, >%s<\n", line); char line[PATH_MAX];
if( line[0] == '#') /* ignore line comments */
continue;
len = strlen (line);
if( !len)
continue; /* ignore empty lines */
DBG( 4, "sane_init, >%s<\n", line);
sanei_config_attach_matching_devices (line, attach_one); while (sanei_config_read (line, sizeof (line), fp))
{
int vendor, product;
DBG( 4, "sane_init, >%s<\n", line);
if( line[0] == '#') /* ignore line comments */
continue;
len = strlen (line);
if( !len)
continue; /* ignore empty lines */
if (sscanf(line, "usb %d %d", &vendor, &product) == 2)
{
sanei_usb_attach_matching_devices(line, attach_one_usb);
}
else if (strncmp(line, "usb", 3) == 0)
{
const char * dev_name;
/* remove the "usb" sub string */
dev_name = sanei_config_skip_whitespace(line+3);
attach_one_usb(dev_name);
}
else
{
sanei_config_attach_matching_devices(line, attach_one);
}
}
fclose (fp);
} }
fclose (fp);
}
/* read the option section and assign the connection type to the /* read the option section and assign the connection type to the
scanner structure - which we don't have at this time. So I have scanner structure - which we don't have at this time. So I have
to come up with something :-) */ to come up with something :-) */
return SANE_STATUS_GOOD; return SANE_STATUS_GOOD;
} }
/* /*
@ -2939,11 +2990,11 @@ static SANE_Status init_options ( Epson_Scanner * s) {
* *
*/ */
SANE_Status sane_open ( SANE_String_Const devicename, SANE_Handle * handle) SANE_Status
sane_open(SANE_String_Const devicename, SANE_Handle * handle)
{ {
Epson_Device *dev; Epson_Device *dev;
Epson_Scanner *s; Epson_Scanner *s;
SANE_Status status;
DBG(5, "sane_open(%s)\n", devicename); DBG(5, "sane_open(%s)\n", devicename);
@ -2960,11 +3011,15 @@ SANE_Status sane_open ( SANE_String_Const devicename, SANE_Handle * handle)
if (!dev) if (!dev)
{ {
status = attach(devicename, &dev); #if 0
status = attach(devicename, &dev, SANE_EPSON_);
if (status != SANE_STATUS_GOOD) if (status != SANE_STATUS_GOOD)
{ {
return status; return status;
} }
#endif
DBG(0, "Error opening the device");
return SANE_STATUS_INVAL;
} }
} }
else else
@ -3197,7 +3252,7 @@ static SANE_Status getvalue( SANE_Handle handle,
case OPT_THRESHOLD: case OPT_THRESHOLD:
case OPT_ZOOM: case OPT_ZOOM:
case OPT_BIT_DEPTH: case OPT_BIT_DEPTH:
case OPT_WAIT_FOR_BUTTON: case OPT_WAIT_FOR_BUTTON:
*((SANE_Word *) value) = sval->w; *((SANE_Word *) value) = sval->w;
break; break;
@ -4737,28 +4792,26 @@ START_READ:
*/ */
/* /*
* The Perfection 1640 seems to have the R and G channels swapped. * Some scaners (e.g. the Perfection 1640 and GT-2200) seem
* to have the R and G channels swapped.
* The GT-8700 is the Asian version of the Perfection1640. * The GT-8700 is the Asian version of the Perfection1640.
* If the scanner name is one of these, and the scan mode is * If the scanner name is one of these, and the scan mode is
* RGB and the maxDepth is set to 14 (this is just another * RGB then swap the colors.
* check to make sure that we are dealing with the correct
* device) then swap the colors.
*/ */
needStrangeReorder = needStrangeReorder =
(strstr(s->hw->sane.model, "GT-2200") && ( strstr(s->hw->sane.model, "GT-2200") ||
s->params.format == SANE_FRAME_RGB) || ((strstr(s->hw->sane.model, "1640") &&
((strstr(s->hw->sane.model, "1640") && strstr(s->hw->sane.model, "Perfection")) ||
strstr(s->hw->sane.model, "Perfection")) || strstr(s->hw->sane.model, "GT-8700")) ) &&
strstr(s->hw->sane.model, "GT-8700")) && s->params.format == SANE_FRAME_RGB;
s->params.format == SANE_FRAME_RGB &&
s->hw->maxDepth == 14;
/* /*
* Certain Perfection 1650 also need this re-ordering of the two color channels. * Certain Perfection 1650 also need this re-ordering of the two
* These scanners are identified by the problem with the half vertical scanning * color channels. These scanners are identified by the problem
* area. When we corrected this, we also set the variable s->hw->need_color_reorder * with the half vertical scanning area. When we corrected this,
*/ * we also set the variable s->hw->need_color_reorder
*/
if (s->hw->need_color_reorder) if (s->hw->need_color_reorder)
{ {
needStrangeReorder = SANE_TRUE; needStrangeReorder = SANE_TRUE;
@ -5197,8 +5250,9 @@ get_identity_information(SANE_Handle handle)
{ {
int n, k; int n, k;
int x = 0, y = 0; int x = 0, y = 0;
int count = ident->count2 * 255 + ident->count1;
for( n = ident->count, buf = ident->buf; n; n -= k, buf += k) { for( n = count, buf = ident->buf; n; n -= k, buf += k) {
switch (*buf) { switch (*buf) {
case 'R': case 'R':
{ {