Added missing bits for epson2 driver.

merge-requests/1/head
Alessandro Zummo 2006-12-02 14:47:21 +00:00
rodzic 57e12f246a
commit 735130b0ff
10 zmienionych plików z 6629 dodań i 1 usunięć

Wyświetl plik

@ -1,3 +1,7 @@
2006-12-02 Alessandro Zummo <a.zummo@towertech.it>
* Added missing bits for epson2 driver.
2006-12-01 Alessandro Zummo <a.zummo@towertech.it>
* Added (experimental) epson2 driver.

Wyświetl plik

@ -98,7 +98,7 @@ DISTFILES = abaton.c abaton.conf.in abaton.h agfafocus.c agfafocus.conf.in \
dc240.c dc240.conf.in dc240.h dc25.c dc25.conf.in dc25.h dell1600n_net.c\
dell1600n_net.conf.in dll.aliases dll.c dll.conf.in dmc.c dmc.conf.in dmc.h \
epson.c epson_scsi.c epson_usb.c epson.conf.in epson.h epson_scsi.h \
epson_usb.h \
epson_usb.h epson2_net.c epson2_net.h epson2.c epson2_scsi.c epson2.conf.in\
fujitsu.c fujitsu.conf.in fujitsu.h fujitsu-scsi.h \
gphoto2.c gphoto2.conf.in gphoto2.h \
gt68xx.c gt68xx.h gt68xx_high.c gt68xx_high.h gt68xx_mid.c gt68xx_mid.h \
@ -310,6 +310,7 @@ EXTRA_genesys = genesys_gl646 genesys_gl841
EXTRA_hp = hp-accessor hp-device hp-handle hp-hpmem hp-option hp-scl
EXTRA_umax_pp = umax_pp_low umax_pp_mid
EXTRA_epson = epson_scsi epson_usb
EXTRA_epson2 = epson2_scsi epson_usb epson2_net
EXTRA_lexmark = lexmark-x1100
EXTRA_pixma = pixma_io_sanei pixma_common pixma_mp150 pixma_mp730 pixma_mp750
@ -372,6 +373,13 @@ libsane-epson.la: ../sanei/sanei_constrain_value.lo
libsane-epson.la: ../sanei/sanei_scsi.lo
libsane-epson.la: ../sanei/sanei_usb.lo
libsane-epson.la: ../sanei/sanei_pio.lo
libsane-epson2.la: $(addsuffix .lo,$(EXTRA_epson2))
libsane-epson2.la: ../sanei/sanei_config2.lo
libsane-epson2.la: ../sanei/sanei_constrain_value.lo
libsane-epson2.la: ../sanei/sanei_scsi.lo
libsane-epson2.la: ../sanei/sanei_usb.lo
libsane-epson2.la: ../sanei/sanei_pio.lo
libsane-epson2.la: ../sanei/sanei_tcp.lo
libsane-fujitsu.la: ../sanei/sanei_config2.lo
libsane-fujitsu.la: ../sanei/sanei_constrain_value.lo
libsane-fujitsu.la: ../sanei/sanei_scsi.lo

Wyświetl plik

@ -19,6 +19,7 @@ coolscan2
dell1600n_net
dmc
epson
epson2
fujitsu
#gphoto2
genesys

6020
backend/epson2.c 100644

Plik diff jest za duży Load Diff

Wyświetl plik

@ -0,0 +1,24 @@
# epson2.conf
#
# here are some examples for how to configure the EPSON2 backend
# SCSI
scsi EPSON
# for the GT-6500:
#scsi "EPSON SC"
# Parallel port
#pio 0x278
#pio 0x378
#pio 0x3BC
# USB
usb
# For libusb support for unknown scanners use the following command
# usb <product ID> <device ID>
# e.g.:
# usb 0x4b8 0x110
# Network
# net 192.168.1.123

236
backend/epson2.h 100644
Wyświetl plik

@ -0,0 +1,236 @@
/*
* epson2.h - SANE library for Epson scanners.
*
* Based on Kazuhiro Sasayama previous
* Work on epson.[ch] file from the SANE package.
* Please see those files for original copyrights.
*
* Copyright (C) 2006 Tower Technologies
* Author: Alessandro Zummo <a.zummo@towertech.it>
*
* This file is part of the SANE package.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation, version 2.
*/
#ifndef epson2_h
#define epson2_h
#include <sys/ioctl.h>
#include <sys/types.h>
/* some string constants that are used in the config file */
#define SANE_EPSON_CONFIG_USB "usb"
#define SANE_EPSON_CONFIG_PIO "pio"
#define SANE_EPSON_CONFIG_NET "net"
/* string constants for GUI elements that are not defined SANE-wide */
#define SANE_NAME_GAMMA_CORRECTION "gamma-correction"
#define SANE_TITLE_GAMMA_CORRECTION SANE_I18N("Gamma Correction")
#define SANE_DESC_GAMMA_CORRECTION SANE_I18N("Selects the gamma correction value from a list of pre-defined devices or the user defined table, which can be downloaded to the scanner")
#define SANE_EPSON_FOCUS_NAME "focus-position"
#define SANE_EPSON_FOCUS_TITLE SANE_I18N("Focus Position")
#define SANE_EPSON_FOCUS_DESC SANE_I18N("Sets the focus position to either the glass or 2.5mm above the glass")
#define SANE_EPSON_WAIT_FOR_BUTTON_NAME "wait-for-button"
#define SANE_EPSON_WAIT_FOR_BUTTON_TITLE SANE_I18N("Wait for Button")
#define SANE_EPSON_WAIT_FOR_BUTTON_DESC SANE_I18N("After sending the scan command, wait until the button on the scanner is pressed to actually start the scan process.");
#define LINES_SHUFFLE_MAX (17) /* 2 x 8 lines plus 1 */
#define SANE_EPSON_MAX_RETRIES (120) /* how often do we retry during warmup ? */
typedef struct
{
char *level;
unsigned char request_identity;
unsigned char request_identity2; /* new request identity command for Dx command level */
unsigned char request_status;
unsigned char request_condition;
unsigned char set_color_mode;
unsigned char start_scanning;
unsigned char set_data_format;
unsigned char set_resolution;
unsigned char set_zoom;
unsigned char set_scan_area;
unsigned char set_bright;
SANE_Range bright_range;
unsigned char set_gamma;
unsigned char set_halftoning;
unsigned char set_color_correction;
unsigned char initialize_scanner;
unsigned char set_speed; /* B4 and later */
unsigned char set_lcount;
unsigned char mirror_image; /* B5 and later */
unsigned char set_gamma_table; /* B4 and later */
unsigned char set_outline_emphasis; /* B4 and later */
unsigned char set_dither; /* B4 and later */
unsigned char set_color_correction_coefficients; /* B3 and later */
unsigned char request_extended_status; /* get extended status from scanner */
unsigned char control_an_extension; /* for extension control */
unsigned char eject; /* for extension control */
unsigned char feed;
unsigned char request_push_button_status;
unsigned char control_auto_area_segmentation;
unsigned char set_film_type; /* for extension control */
unsigned char set_exposure_time; /* F5 only */
unsigned char set_bay; /* F5 only */
unsigned char set_threshold;
unsigned char set_focus_position; /* B8 only */
unsigned char request_focus_position; /* B8 only */
unsigned char request_extended_identity;
unsigned char request_scanner_status;
} EpsonCmdRec, *EpsonCmd;
enum
{ OPT_NUM_OPTS =
0, OPT_MODE_GROUP, OPT_MODE, OPT_BIT_DEPTH, OPT_HALFTONE, OPT_DROPOUT,
OPT_BRIGHTNESS, OPT_SHARPNESS, OPT_GAMMA_CORRECTION, OPT_COLOR_CORRECTION,
OPT_RESOLUTION, OPT_THRESHOLD, OPT_ADVANCED_GROUP, OPT_MIRROR, OPT_SPEED,
OPT_AAS, OPT_LIMIT_RESOLUTION, OPT_ZOOM, /* OPT_GAMMA_VECTOR */
OPT_GAMMA_VECTOR_R, OPT_GAMMA_VECTOR_G, OPT_GAMMA_VECTOR_B,
OPT_WAIT_FOR_BUTTON, OPT_CCT_GROUP, OPT_CCT_1, OPT_CCT_2, OPT_CCT_3,
OPT_CCT_4, OPT_CCT_5, OPT_CCT_6, OPT_CCT_7, OPT_CCT_8, OPT_CCT_9,
OPT_PREVIEW_GROUP, OPT_PREVIEW, OPT_PREVIEW_SPEED, OPT_GEOMETRY_GROUP,
OPT_TL_X, OPT_TL_Y, OPT_BR_X, OPT_BR_Y, OPT_QUICK_FORMAT, OPT_EQU_GROUP,
OPT_SOURCE, OPT_AUTO_EJECT, OPT_FILM_TYPE, OPT_FOCUS, OPT_BAY,
OPT_EJECT, OPT_ADF_MODE, NUM_OPTIONS
};
typedef enum
{ /* hardware connection to the scanner */
SANE_EPSON_NODEV, /* default, no HW specified yet */
SANE_EPSON_SCSI, /* SCSI interface */
SANE_EPSON_PIO, /* parallel interface */
SANE_EPSON_USB, /* USB interface */
SANE_EPSON_NET /* network interface */
} Epson_Connection_Type;
typedef struct
{
u_short opt_resolution;
u_char sensor;
u_char scan_order;
u_char line_dist1;
u_char line_dist2;
u_short main_res1;
u_short main_res2;
u_short main_res3;
u_short main_res4;
u_short main_res5;
u_short main_res6;
u_short main_res7;
u_short sub_res1;
u_short sub_res2;
u_short sub_res3;
u_short sub_res4;
u_short sub_res5;
u_short sub_res6;
} Epson_Identity2;
struct Epson_Device
{
struct Epson_Device *next;
SANE_Device sane;
SANE_Int level;
SANE_Range dpi_range;
SANE_Range *x_range; /* x range w/out extension */
SANE_Range *y_range; /* y range w/out extension */
SANE_Range fbf_x_range; /* flattbed x range */
SANE_Range fbf_y_range; /* flattbed y range */
SANE_Range adf_x_range; /* autom. document feeder x range */
SANE_Range adf_y_range; /* autom. document feeder y range */
SANE_Range tpu_x_range; /* transparency unit x range */
SANE_Range tpu_y_range; /* transparency unit y range */
Epson_Connection_Type connection;
/* hardware interface type */
SANE_Int *res_list; /* list of resolutions */
SANE_Int res_list_size; /* number of entries in this list */
SANE_Int last_res; /* last selected resolution */
SANE_Int last_res_preview; /* last selected preview resolution */
SANE_Word *resolution_list; /* for display purposes we store a second copy */
SANE_Bool extension; /* extension is installed */
SANE_Int use_extension; /* use the installed extension */
SANE_Bool TPU; /* TPU is installed */
SANE_Bool ADF; /* ADF is installed */
SANE_Bool duplexSupport; /* does the ADF handle duplex scanning */
SANE_Bool focusSupport; /* does this scanner have support for "set focus position" ? */
SANE_Bool color_shuffle; /* does this scanner need color shuffling */
SANE_Int maxDepth; /* max. color depth */
SANE_Int optical_res; /* optical resolution */
SANE_Int max_line_distance;
SANE_Bool need_double_vertical;
SANE_Bool need_color_reorder;
SANE_Bool need_reset_on_source_change;
SANE_Bool wait_for_button; /* do we have to wait until the scanner button is pressed? */
SANE_Int fbf_max_x;
SANE_Int fbf_max_y;
SANE_Int adf_max_x;
SANE_Int adf_max_y;
SANE_Int devtype;
SANE_Bool local;
SANE_Bool extended_commands;
EpsonCmd cmd;
};
typedef struct Epson_Device Epson_Device;
struct Epson_Scanner
{
struct Epson_Scanner *next;
int fd;
Epson_Device *hw;
SANE_Option_Descriptor opt[NUM_OPTIONS];
Option_Value val[NUM_OPTIONS];
SANE_Parameters params;
SANE_Bool block;
SANE_Bool eof;
SANE_Byte *buf, *end, *ptr;
SANE_Bool canceling;
SANE_Bool invert_image;
SANE_Bool focusOnGlass;
SANE_Byte currentFocusPosition;
/* SANE_Word gamma_table [ 4] [ 256]; */
SANE_Word gamma_table[3][256];
SANE_Int retry_count;
SANE_Byte *line_buffer[LINES_SHUFFLE_MAX];
/* buffer lines for color shuffling */
SANE_Int color_shuffle_line; /* current line number for color shuffling */
SANE_Int line_distance; /* current line distance */
SANE_Int current_output_line; /* line counter when color shuffling */
SANE_Int lines_written; /* debug variable */
SANE_Bool option_has_changed; /* did one of the options change it's value? */
SANE_Int left, top, lcount;
unsigned char *netbuf, *netptr;
size_t netlen;
};
typedef struct Epson_Scanner Epson_Scanner;
#endif /* epson2_h */

Wyświetl plik

@ -0,0 +1,195 @@
/*
* epson2_net.c - SANE library for Epson scanners.
*
* Copyright (C) 2006 Tower Technologies
* Author: Alessandro Zummo <a.zummo@towertech.it>
*
* This file is part of the SANE package.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation, version 2.
*/
#include "../include/sane/config.h"
#include <sane/sane.h>
#include <sane/saneopts.h>
#include <sane/sanei_debug.h>
#include <sane/sanei_tcp.h>
#include <sane/sanei_config.h>
#include <sane/sanei_backend.h>
#include "epson2.h"
#include "epson2_net.h"
#ifdef HAVE_STDDEF_H
#include <stddef.h>
#endif
#ifdef HAVE_STDLIB_H
#include <stdlib.h>
#endif
#ifdef NEED_SYS_TYPES_H
#include <sys/types.h>
#endif
#include <string.h> /* for memset and memcpy */
#include <stdio.h>
int
sanei_epson_net_read(Epson_Scanner *s, unsigned char *buf, size_t wanted,
SANE_Status * status)
{
size_t size, read = 0;
unsigned char header[12];
if (s->netbuf != s->netptr ) {
/* if (s->netlen == wanted) {*/
DBG(4, "reading %d from buffer at %p\n", wanted, s->netptr);
memcpy(buf, s->netptr + s->netlen - wanted, wanted);
read = wanted;
/* } */
free(s->netbuf);
s->netbuf = s->netptr = NULL;
s->netlen = 0;
return read;
}
sanei_tcp_read(s->fd, header, 12);
if (header[0] != 'I' || header[1] != 'S') {
DBG(1, "header mismatch: %02X %02x\n", header[0], header[1]);
/* return 0;*/
}
size = (header[6] << 24) | (header[7] << 16) | (header[8] << 8) | header[9];
DBG(4, "%s: wanted %d, got %d\n", __FUNCTION__, wanted, size);
*status = SANE_STATUS_GOOD;
if (size == wanted) {
DBG(4, "direct read\n");
sanei_tcp_read(s->fd, buf, size);
if (s->netbuf)
free(s->netbuf);
s->netbuf = NULL;
s->netlen = 0;
read = wanted;
} else if (wanted < size && s->netlen == size) {
/* unsigned int k; */
sanei_tcp_read(s->fd, s->netbuf, size);
/* for (k = 0; k < size; k++) {
DBG(0, "buf[%d] %02x %c\n", k, s->netbuf[k], isprint(s->netbuf[k]) ? s->netbuf[k] : '.');
}
*/
s->netlen = size - wanted;
s->netptr += wanted;
read = wanted;
DBG(4, "0,4 %02x %02x", s->netbuf[0], s->netbuf[4]);
DBG(4, "storing %d to buffer at %p, next read at %p\n", size, s->netbuf, s->netptr);
memcpy(buf, s->netbuf , wanted);
}
return read;
}
int
sanei_epson_net_write(Epson_Scanner *s, unsigned int cmd, const unsigned char *buf,
size_t buf_size, size_t reply_len, SANE_Status *status)
{
unsigned char *h1, *h2, *payload;
unsigned char *packet = malloc(12 + 8 + buf_size);
/* XXX check allocation failure */
h1 = packet;
h2 = packet + 12;
payload = packet + 12 + 8;
if (reply_len) {
s->netbuf = s->netptr = malloc(reply_len);
s->netlen = reply_len;
DBG(8, "allocated %d bytes at %p\n", reply_len, s->netbuf);
}
DBG(2, "%s: cmd = %04x, buf = %p, buf_size = %d, reply_len = %d\n", __FUNCTION__, cmd, buf, buf_size, reply_len);
memset(h1, 0x00, 12);
memset(h2, 0x00, 8);
h1[0] = 'I';
h1[1] = 'S';
h1[2] = cmd >> 8;
h1[3] = cmd;
h1[4] = 0x00;
h1[5] = 0x0C; /* Don't know what's that */
DBG(9, "H1 [0-3]: %02x %02x %02x %02x\n", h1[0], h1[1], h1[2], h1[3]);
if((cmd >> 8) == 0x20) {
h1[6] = (buf_size + 8) >> 24;
h1[7] = (buf_size + 8) >> 16;
h1[8] = (buf_size + 8) >> 8;
h1[9] = (buf_size + 8);
DBG(9, "H1 [6-9]: %02x %02x %02x %02x\n", h1[6], h1[7], h1[8], h1[9]);
h2[0] = (buf_size) >> 24;
h2[1] = (buf_size) >> 16;
h2[2] = (buf_size) >> 8;
h2[3] = buf_size;
h2[4] = reply_len >> 24;
h2[5] = reply_len >> 16;
h2[6] = reply_len >> 8;
h2[7] = reply_len;
DBG(9, "H2(%d): %02x %02x %02x %02x\n", buf_size, h2[0], h2[1], h2[2], h2[3]);
DBG(9, "H2(%d): %02x %02x %02x %02x\n", reply_len, h2[4], h2[5], h2[6], h2[7]);
}
if (buf_size && (cmd >> 8) == 0x20) {
memcpy(payload, buf, buf_size);
sanei_tcp_write(s->fd, packet, 12 + 8 + buf_size);
}
else
sanei_tcp_write(s->fd, packet, 12);
free(packet);
*status = SANE_STATUS_GOOD;
return buf_size;
}
SANE_Status
sanei_epson_net_lock(struct Epson_Scanner *s)
{
SANE_Status status;
unsigned char buf[1];
sanei_epson_net_write(s, 0x2100, NULL, 0, 0, &status);
sanei_epson_net_read(s, buf, 1, &status);
return status;
}
SANE_Status
sanei_epson_net_unlock(struct Epson_Scanner *s)
{
SANE_Status status;
unsigned char buf[1];
sanei_epson_net_write(s, 0x2101, NULL, 0, 0, &status);
sanei_epson_net_read(s, buf, 1, &status);
return status;
}

Wyświetl plik

@ -0,0 +1,16 @@
#ifndef _EPSON2_NET_H_
#define _EPSON2_NET_H_
#include <sys/types.h>
#include <sane/sane.h>
extern int sanei_epson_net_read(struct Epson_Scanner *s, unsigned char *buf, size_t buf_size,
SANE_Status *status);
extern int sanei_epson_net_write(struct Epson_Scanner *s, unsigned int cmd, const unsigned char *buf,
size_t buf_size, size_t reply_len,
SANE_Status *status);
extern SANE_Status sanei_epson_net_lock(struct Epson_Scanner *s);
extern SANE_Status sanei_epson_net_unlock(struct Epson_Scanner *s);
#endif

Wyświetl plik

@ -0,0 +1,100 @@
#include <sane/config.h>
#include <sane/sanei_debug.h>
#include <sane/sanei_scsi.h>
#include "epson2_scsi.h"
#ifdef HAVE_STDDEF_H
#include <stddef.h>
#endif
#ifdef HAVE_STDLIB_H
#include <stdlib.h>
#endif
#ifdef NEED_SYS_TYPES_H
#include <sys/types.h>
#endif
#include <string.h> /* for memset and memcpy */
#include <stdio.h>
/* sense handler for the sanei_scsi_xxx comands */
SANE_Status
sanei_epson2_scsi_sense_handler(int scsi_fd,
unsigned char *result, void *arg)
{
/* to get rid of warnings */
scsi_fd = scsi_fd;
arg = arg;
if (result[0] && result[0] != 0x70) {
DBG(2, "%s: sense code = 0x%02x\n",
__FUNCTION__, result[0]);
return SANE_STATUS_IO_ERROR;
} else {
return SANE_STATUS_GOOD;
}
}
SANE_Status
sanei_epson2_scsi_inquiry(int fd, void *buf, size_t *buf_size)
{
unsigned char cmd[6];
int status;
memset(cmd, 0, 6);
cmd[0] = INQUIRY_COMMAND;
cmd[4] = *buf_size > 255 ? 255 : *buf_size;
status = sanei_scsi_cmd(fd, cmd, sizeof cmd, buf, buf_size);
return status;
}
SANE_Status
sanei_epson2_scsi_test_unit_ready(int fd)
{
unsigned char cmd[6];
memset(cmd, 0, 6);
cmd[0] = TEST_UNIT_READY_COMMAND;
return sanei_scsi_cmd2(fd, cmd, sizeof(cmd), NULL, 0, NULL, NULL);
}
int
sanei_epson2_scsi_read(int fd, void *buf, size_t buf_size,
SANE_Status *status)
{
unsigned char cmd[6];
memset(cmd, 0, 6);
cmd[0] = READ_6_COMMAND;
cmd[2] = buf_size >> 16;
cmd[3] = buf_size >> 8;
cmd[4] = buf_size;
*status = sanei_scsi_cmd2(fd, cmd, sizeof(cmd), NULL, 0, buf, &buf_size);
if (*status == SANE_STATUS_GOOD)
return buf_size;
return 0;
}
int
sanei_epson2_scsi_write(int fd, const void *buf, size_t buf_size,
SANE_Status *status)
{
unsigned char cmd[6];
memset(cmd, 0, sizeof(cmd));
cmd[0] = WRITE_6_COMMAND;
cmd[2] = buf_size >> 16;
cmd[3] = buf_size >> 8;
cmd[4] = buf_size;
*status = sanei_scsi_cmd2(fd, cmd, sizeof(cmd), buf, buf_size, NULL, NULL);
if (*status == SANE_STATUS_GOOD)
return buf_size;
return 0;
}

Wyświetl plik

@ -0,0 +1,24 @@
#ifndef _EPSON2_SCSI_H_
#define _EPSON2_SCSI_H_
#include <sys/types.h>
#include <sane/sane.h>
#define TEST_UNIT_READY_COMMAND (0x00)
#define READ_6_COMMAND (0x08)
#define WRITE_6_COMMAND (0x0a)
#define INQUIRY_COMMAND (0x12)
#define TYPE_PROCESSOR (0x03)
#define INQUIRY_BUF_SIZE (36)
SANE_Status sanei_epson2_scsi_sense_handler(int scsi_fd, unsigned char *result,
void *arg);
SANE_Status sanei_epson2_scsi_inquiry(int fd, void *buf,
size_t *buf_size);
int sanei_epson2_scsi_read(int fd, void *buf, size_t buf_size,
SANE_Status *status);
int sanei_epson2_scsi_write(int fd, const void *buf, size_t buf_size,
SANE_Status *status);
SANE_Status sanei_epson2_scsi_test_unit_ready(int fd);
#endif