kopia lustrzana https://gitlab.com/sane-project/backends
Porównaj commity
8 Commity
a6857425cc
...
be5ccdb392
Autor | SHA1 | Data |
---|---|---|
tly000 | be5ccdb392 | |
ThierryFR | 728ca40272 | |
ThierryFR | 113be50f6b | |
tly | 7296238e5f | |
tly | 098ec069f3 | |
tly | 94bd3f980a | |
tly | 4ff97ac86a | |
tly | 67b85b021e |
|
@ -187,7 +187,7 @@ be_convenience_libs = libabaton.la libagfafocus.la \
|
|||
libtamarack.la libtest.la libteco1.la \
|
||||
libteco2.la libteco3.la libu12.la libumax.la \
|
||||
libumax1220u.la libumax_pp.la libv4l.la \
|
||||
libxerox_mfp.la
|
||||
libxerox_mfp.la libcs3200f.la
|
||||
|
||||
# Each stand-alone backend that's possible to be built should be listed
|
||||
# here. There are the libraries that are installed under $(libdir)/sane.
|
||||
|
@ -222,7 +222,7 @@ be_dlopen_libs = libsane-abaton.la libsane-agfafocus.la \
|
|||
libsane-tamarack.la libsane-test.la libsane-teco1.la \
|
||||
libsane-teco2.la libsane-teco3.la libsane-u12.la libsane-umax.la \
|
||||
libsane-umax1220u.la libsane-umax_pp.la libsane-v4l.la \
|
||||
libsane-xerox_mfp.la
|
||||
libsane-xerox_mfp.la libsane-cs3200f.la
|
||||
|
||||
EXTRA_LTLIBRARIES = $(be_convenience_libs) $(be_dlopen_libs)
|
||||
|
||||
|
@ -1179,6 +1179,24 @@ libsane_ma1509_la_LIBADD = $(COMMON_LIBS) \
|
|||
$(USB_LIBS) $(RESMGR_LIBS)
|
||||
EXTRA_DIST += ma1509.conf.in
|
||||
|
||||
libcs3200f_la_SOURCES = cs3200f.c
|
||||
libcs3200f_la_CPPFLAGS = $(AM_CPPFLAGS) -DBACKEND_NAME=cs3200f
|
||||
|
||||
nodist_libsane_cs3200f_la_SOURCES = cs3200f-s.c
|
||||
libsane_cs3200f_la_CPPFLAGS = $(AM_CPPFLAGS) -DBACKEND_NAME=cs3200f
|
||||
libsane_cs3200f_la_LDFLAGS = $(DIST_SANELIBS_LDFLAGS)
|
||||
libsane_cs3200f_la_LIBADD = $(COMMON_LIBS) \
|
||||
libcs3200f.la \
|
||||
../sanei/sanei_init_debug.lo \
|
||||
../sanei/sanei_constrain_value.lo \
|
||||
../sanei/sanei_config.lo \
|
||||
sane_strstatus.lo \
|
||||
../sanei/sanei_usb.lo \
|
||||
../sanei/sanei_access.lo \
|
||||
../sanei/sanei_thread.lo \
|
||||
$(USB_LIBS) $(RESMGR_LIBS)
|
||||
# EXTRA_DIST += cs3200f.conf.in
|
||||
|
||||
libmagicolor_la_SOURCES = magicolor.c magicolor.h
|
||||
libmagicolor_la_CPPFLAGS = $(AM_CPPFLAGS) -DBACKEND_NAME=magicolor $(SNMP_CFLAGS)
|
||||
|
||||
|
|
Plik diff jest za duży
Load Diff
|
@ -0,0 +1,382 @@
|
|||
/* sane - Scanner Access Now Easy.
|
||||
Copyright (C) 2006 Lauri Pirttiaho <lauri.pirttiaho@cornell.edu>
|
||||
|
||||
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; either version 2 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston,
|
||||
MA 02111-1307, USA.
|
||||
|
||||
As a special exception, the authors of SANE give permission for
|
||||
additional uses of the libraries contained in this release of SANE.
|
||||
|
||||
The exception is that, if you link a SANE library with other files
|
||||
to produce an executable, this does not by itself cause the
|
||||
resulting executable to be covered by the GNU General Public
|
||||
License. Your use of that executable is in no way restricted on
|
||||
account of linking the SANE library code into it.
|
||||
|
||||
This exception does not, however, invalidate any other reasons why
|
||||
the executable file might be covered by the GNU General Public
|
||||
License.
|
||||
|
||||
If you submit changes to SANE to the maintainers to be included in
|
||||
a subsequent release, you agree by submitting the changes that
|
||||
those changes may be distributed with this exception intact.
|
||||
|
||||
If you write modifications of your own for SANE, it is your choice
|
||||
whether to permit this exception to apply to your modifications.
|
||||
If you do not wish that, delete this exception notice.
|
||||
|
||||
This backend is for CanoScan 3200F.
|
||||
*/
|
||||
|
||||
#ifndef CS3200F_DAT_H
|
||||
#define CS3200F_DAT_H
|
||||
|
||||
#include "../include/sane/sane.h"
|
||||
|
||||
/***********************************************************************
|
||||
* Options
|
||||
***********************************************************************/
|
||||
|
||||
/** Option identifiers */
|
||||
typedef enum
|
||||
{
|
||||
OPT_NUM_OPTS = 0,
|
||||
OPT_RESOLUTION, /* 1 */
|
||||
OPT_SOURCE, /* 2 */
|
||||
|
||||
OPT_MODE_GROUP, /* 3 */
|
||||
OPT_MODE, /* 4 */
|
||||
OPT_DEPTH, /* 5 */
|
||||
OPT_GRAY_COLOR, /* 6 */
|
||||
OPT_PREVIEW, /* 7 */
|
||||
|
||||
OPT_GAMMA_GROUP, /* 8 */
|
||||
OPT_RGB_BIND, /* 9 */
|
||||
OPT_GAMMA, /* 10 */
|
||||
OPT_GAMMA_R, /* 11 */
|
||||
OPT_GAMMA_G, /* 12 */
|
||||
OPT_GAMMA_B, /* 13 */
|
||||
OPT_THRESHOLD, /* 14 */
|
||||
|
||||
OPT_GEOMETRY_GROUP, /* 15 */
|
||||
OPT_TL_X, /* 16 */
|
||||
OPT_TL_Y, /* 17 */
|
||||
OPT_BR_X, /* 18 */
|
||||
OPT_BR_Y, /* 19 */
|
||||
|
||||
OPT_CALIBRATE_GROUP, /* 20 */
|
||||
OPT_CALIBRATE, /* 21 */
|
||||
OPT_CALIBRATE_BEFORE_SCAN, /* 22 */
|
||||
|
||||
NUM_OPTIONS /* 23 */
|
||||
} OPT_E;
|
||||
|
||||
/************************************************************************
|
||||
* Option constraints
|
||||
************************************************************************/
|
||||
|
||||
/** Sources */
|
||||
typedef enum
|
||||
{
|
||||
OPT_SOURCE_PAPER,
|
||||
OPT_SOURCE_FILM
|
||||
} OPT_SOURCE_E;
|
||||
|
||||
/** Modes */
|
||||
typedef enum
|
||||
{
|
||||
OPT_MODE_COLOR,
|
||||
OPT_MODE_GRAY,
|
||||
OPT_MODE_LINEART
|
||||
} OPT_MODE_E;
|
||||
|
||||
/** RGB Color */
|
||||
typedef enum
|
||||
{
|
||||
OPT_RGB_COLOR_RED,
|
||||
OPT_RGB_COLOR_GREEN,
|
||||
OPT_RGB_COLOR_BLUE
|
||||
} OPT_RGB_COLOR_E;
|
||||
|
||||
/** Geometry limits in mm */
|
||||
#define OPT_X_MAX 219.0
|
||||
#define OPT_X_MAX_TA 38.0
|
||||
#define OPT_Y_MAX 299.0
|
||||
#define OPT_Y_MAX_TA 25.0
|
||||
|
||||
/** Resolutions */
|
||||
extern const SANE_Word opt_const_resolutions[];
|
||||
|
||||
/** Sources */
|
||||
extern const SANE_String_Const opt_const_sources[];
|
||||
#define OPT_CONST_SOURCES_MAX_LEN (sizeof(SANE_I18N("Paper")))
|
||||
|
||||
/** Modes */
|
||||
extern const SANE_String_Const opt_const_modes[];
|
||||
#define OPT_CONST_MODES_MAX_LEN (sizeof(SANE_VALUE_SCAN_MODE_LINEART))
|
||||
|
||||
/** Sample depths */
|
||||
extern const SANE_Word opt_const_depths[];
|
||||
|
||||
/** RGB Color */
|
||||
extern const SANE_String_Const opt_const_rgb_colors[];
|
||||
#define OPT_CONST_RGB_COLORS_MAX_LEN (sizeof(SANE_I18N("Green")))
|
||||
|
||||
/** Gamma */
|
||||
extern const SANE_Range opt_gamma_range;
|
||||
|
||||
/** Threshold */
|
||||
extern const SANE_Range opt_threshold_range;
|
||||
|
||||
/** X range in mm */
|
||||
extern const SANE_Range opt_x_range;
|
||||
|
||||
/** X range in mm */
|
||||
extern const SANE_Range opt_x_range_ta;
|
||||
|
||||
/** Y range in mm */
|
||||
extern const SANE_Range opt_y_range;
|
||||
|
||||
/** Y range in mm */
|
||||
extern const SANE_Range opt_y_range_ta;
|
||||
|
||||
/** Device specific options */
|
||||
typedef struct
|
||||
{
|
||||
SANE_Int resolution;
|
||||
OPT_SOURCE_E source;
|
||||
OPT_MODE_E mode;
|
||||
SANE_Int depth;
|
||||
OPT_RGB_COLOR_E gray_color;
|
||||
SANE_Bool preview;
|
||||
SANE_Bool rgb_bind;
|
||||
SANE_Fixed gamma;
|
||||
SANE_Fixed gamma_r;
|
||||
SANE_Fixed gamma_g;
|
||||
SANE_Fixed gamma_b;
|
||||
SANE_Fixed threshold;
|
||||
SANE_Fixed tl_x;
|
||||
SANE_Fixed tl_y;
|
||||
SANE_Fixed br_x;
|
||||
SANE_Fixed br_y;
|
||||
SANE_Fixed tl_x_ta;
|
||||
SANE_Fixed tl_y_ta;
|
||||
SANE_Fixed br_x_ta;
|
||||
SANE_Fixed br_y_ta;
|
||||
SANE_Bool calibrate_before_scan;
|
||||
} OPT_T;
|
||||
|
||||
/************************************************************************
|
||||
* HW control
|
||||
************************************************************************/
|
||||
|
||||
/** RGB triplet */
|
||||
typedef struct
|
||||
{
|
||||
char r;
|
||||
char g;
|
||||
char b;
|
||||
} RGB_T;
|
||||
|
||||
/** AFE settings */
|
||||
typedef struct {
|
||||
RGB_T offs;
|
||||
RGB_T gain;
|
||||
} AFE_SET_T;
|
||||
|
||||
/************************************************************************
|
||||
* Calibration data
|
||||
************************************************************************/
|
||||
|
||||
typedef struct
|
||||
{
|
||||
SANE_Int res; /*< resolution */
|
||||
SANE_Int offs_x; /*< imaging area offset in 1200 dpi pixels */
|
||||
SANE_Int offs_y; /*< imaging area offset in 2400 dpi lines */
|
||||
AFE_SET_T afe_set; /*< AFE settings */
|
||||
SANE_Int width; /*< width of the imaging area in pixels */
|
||||
double *bshd; /*< averaged black shading data */
|
||||
double *wshd; /*< averaged white shading data */
|
||||
} CAL_T;
|
||||
|
||||
/************************************************************************
|
||||
* Line FIFO
|
||||
************************************************************************/
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int width;
|
||||
int length;
|
||||
int length2;
|
||||
int write_idx;
|
||||
int read_idx;
|
||||
SANE_Byte *data;
|
||||
} LINE_FIFO_T;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
SANE_Int n_lines;
|
||||
SANE_Int current_line;
|
||||
SANE_Int line_width;
|
||||
SANE_Int line_pos;
|
||||
SANE_Byte *line;
|
||||
|
||||
LINE_FIFO_T *r;
|
||||
LINE_FIFO_T *g;
|
||||
LINE_FIFO_T *b;
|
||||
} SCAN_T;
|
||||
|
||||
/************************************************************************
|
||||
* Device data
|
||||
************************************************************************/
|
||||
|
||||
typedef struct DEVICE DEVICE_T;
|
||||
typedef DEVICE_T *DEVICE_H;
|
||||
|
||||
struct DEVICE
|
||||
{
|
||||
DEVICE_T *next;
|
||||
DEVICE_T *prev;
|
||||
|
||||
SANE_String name;
|
||||
|
||||
SANE_Int dn;
|
||||
SANE_Bool open;
|
||||
SANE_Bool hs;
|
||||
|
||||
SANE_Bool scanning;
|
||||
SANE_Pid scan_thread;
|
||||
int scan_pipe[2];
|
||||
int scan_bytes_left;
|
||||
|
||||
OPT_T opt;
|
||||
|
||||
CAL_T cal_300;
|
||||
CAL_T cal_600;
|
||||
CAL_T cal_1200;
|
||||
CAL_T cal_300_ta;
|
||||
CAL_T cal_600_ta;
|
||||
CAL_T cal_1200_ta;
|
||||
|
||||
SCAN_T scan;
|
||||
};
|
||||
|
||||
/** Initialize device data
|
||||
*/
|
||||
void
|
||||
a_init_data( void );
|
||||
|
||||
/** Create new device data
|
||||
* @return handle to the device
|
||||
*/
|
||||
SANE_Handle
|
||||
a_new_dev( void );
|
||||
|
||||
/** Check if the give handle is valid
|
||||
* @param h handle of the device
|
||||
* @return SANE_STATUS_GOOD if OK, SANE_STATUS_INVAL if invalid
|
||||
*/
|
||||
SANE_Status
|
||||
a_handle_valid( SANE_Handle h );
|
||||
|
||||
/** Delete device data
|
||||
* @param d handle to the device
|
||||
*/
|
||||
void
|
||||
a_delete_dev( SANE_Handle d );
|
||||
|
||||
/** Option getters */
|
||||
SANE_Int a_get_resolution( SANE_Handle d );
|
||||
SANE_String_Const a_get_source( SANE_Handle d );
|
||||
OPT_SOURCE_E a_get_source_e( SANE_Handle d );
|
||||
SANE_String_Const a_get_mode( SANE_Handle d );
|
||||
OPT_MODE_E a_get_mode_e( SANE_Handle d );
|
||||
SANE_Int a_get_depth( SANE_Handle d );
|
||||
SANE_String_Const a_get_gray_color( SANE_Handle d );
|
||||
OPT_RGB_COLOR_E a_get_gray_color_e( SANE_Handle d );
|
||||
SANE_Bool a_get_preview( SANE_Handle d );
|
||||
SANE_Bool a_get_rgb_bind( SANE_Handle d );
|
||||
SANE_Fixed a_get_gamma( SANE_Handle d );
|
||||
SANE_Fixed a_get_gamma_r( SANE_Handle d );
|
||||
SANE_Fixed a_get_gamma_g( SANE_Handle d );
|
||||
SANE_Fixed a_get_gamma_b( SANE_Handle d );
|
||||
SANE_Fixed a_get_threshold( SANE_Handle d );
|
||||
SANE_Fixed a_get_tl_x( SANE_Handle d );
|
||||
SANE_Fixed a_get_tl_y( SANE_Handle d );
|
||||
SANE_Fixed a_get_br_x( SANE_Handle d );
|
||||
SANE_Fixed a_get_br_y( SANE_Handle d );
|
||||
SANE_Int a_get_tl_x_pix( SANE_Handle d );
|
||||
SANE_Int a_get_tl_y_pix( SANE_Handle d );
|
||||
SANE_Int a_get_br_x_pix( SANE_Handle d );
|
||||
SANE_Int a_get_br_y_pix( SANE_Handle d );
|
||||
SANE_Bool a_get_calibrate_before_scan( SANE_Handle d );
|
||||
|
||||
/** Option setters */
|
||||
SANE_Int a_set_resolution( SANE_Handle d, SANE_Int resolution );
|
||||
SANE_Int a_set_source( SANE_Handle d, SANE_String_Const source );
|
||||
SANE_Int a_set_mode( SANE_Handle d, SANE_String_Const mode );
|
||||
SANE_Int a_set_depth( SANE_Handle d, SANE_Int depth );
|
||||
SANE_Int a_set_gray_color( SANE_Handle d, SANE_String_Const gray_color );
|
||||
SANE_Int a_set_preview( SANE_Handle d, SANE_Bool preview );
|
||||
SANE_Int a_set_rgb_bind( SANE_Handle d, SANE_Bool rgb_bind );
|
||||
SANE_Int a_set_gamma( SANE_Handle d, SANE_Fixed gamma );
|
||||
SANE_Int a_set_gamma_r( SANE_Handle d, SANE_Fixed gamma_r );
|
||||
SANE_Int a_set_gamma_g( SANE_Handle d, SANE_Fixed gamma_g );
|
||||
SANE_Int a_set_gamma_b( SANE_Handle d, SANE_Fixed gamma_b );
|
||||
SANE_Int a_set_threshold( SANE_Handle d, SANE_Fixed threshold );
|
||||
SANE_Int a_set_tl_x( SANE_Handle d, SANE_Fixed tl_x );
|
||||
SANE_Int a_set_tl_y( SANE_Handle d, SANE_Fixed tl_y );
|
||||
SANE_Int a_set_br_x( SANE_Handle d, SANE_Fixed br_x );
|
||||
SANE_Int a_set_br_y( SANE_Handle d, SANE_Fixed br_y );
|
||||
SANE_Int a_set_calibrate_before_scan( SANE_Handle d, SANE_Bool cbs );
|
||||
|
||||
/** Scan parameters */
|
||||
SANE_Frame a_format( SANE_Handle handle );
|
||||
SANE_Int a_depth( SANE_Handle handle );
|
||||
SANE_Int a_lines( SANE_Handle handle );
|
||||
SANE_Int a_pixels_per_line( SANE_Handle handle );
|
||||
SANE_Int a_bytes_per_line( SANE_Handle handle );
|
||||
void a_scan_init( SANE_Handle handle );
|
||||
void a_scan_finish( SANE_Handle handle );
|
||||
|
||||
/** Line FIFO */
|
||||
LINE_FIFO_T *a_new_fifo( int width, int length, int length2 );
|
||||
void a_delete_fifo( LINE_FIFO_T *fifo );
|
||||
int a_write_idx( LINE_FIFO_T *fifo );
|
||||
int a_read_idx( LINE_FIFO_T *fifo );
|
||||
int a_read_idx2( LINE_FIFO_T *fifo );
|
||||
void a_write_idx_inc( LINE_FIFO_T *fifo );
|
||||
void a_read_idx_inc( LINE_FIFO_T *fifo );
|
||||
int a_space_in_fifo( LINE_FIFO_T *fifo );
|
||||
SANE_Byte *a_fifo_write_ptr( LINE_FIFO_T *fifo );
|
||||
SANE_Byte *a_fifo_read_ptr( LINE_FIFO_T *fifo );
|
||||
SANE_Byte *a_fifo_read_ptr2( LINE_FIFO_T *fifo );
|
||||
int a_fifo_width( LINE_FIFO_T *fifo );
|
||||
int a_write_to_fifo( LINE_FIFO_T *fifo, int in_pipe );
|
||||
void a_read_from_fifo_g( SCAN_T *scan );
|
||||
void a_read_from_fifo_g_2( SCAN_T *scan );
|
||||
void a_read_from_fifos_c( SCAN_T *scan );
|
||||
void a_read_from_fifos_c_2( SCAN_T *scan );
|
||||
SANE_Int a_read_from_scan( SCAN_T *scan, SANE_Byte *data, SANE_Int max );
|
||||
SANE_Bool a_lines_left( SCAN_T *scan );
|
||||
SANE_Bool a_line_empty( SCAN_T *scan );
|
||||
|
||||
#endif /* ndef CS3200F_DAT_H */
|
||||
|
||||
/************************************************************************
|
||||
* $Id: cs3200f-dat.h,v 1.1 2006/03/26 19:01:59 lapi-guest Exp $
|
||||
************************************************************************/
|
|
@ -0,0 +1,374 @@
|
|||
/* sane - Scanner Access Now Easy.
|
||||
Copyright (C) 2006 Lauri Pirttiaho <lauri.pirttiaho@cornell.edu>
|
||||
|
||||
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; either version 2 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston,
|
||||
MA 02111-1307, USA.
|
||||
|
||||
As a special exception, the authors of SANE give permission for
|
||||
additional uses of the libraries contained in this release of SANE.
|
||||
|
||||
The exception is that, if you link a SANE library with other files
|
||||
to produce an executable, this does not by itself cause the
|
||||
resulting executable to be covered by the GNU General Public
|
||||
License. Your use of that executable is in no way restricted on
|
||||
account of linking the SANE library code into it.
|
||||
|
||||
This exception does not, however, invalidate any other reasons why
|
||||
the executable file might be covered by the GNU General Public
|
||||
License.
|
||||
|
||||
If you submit changes to SANE to the maintainers to be included in
|
||||
a subsequent release, you agree by submitting the changes that
|
||||
those changes may be distributed with this exception intact.
|
||||
|
||||
If you write modifications of your own for SANE, it is your choice
|
||||
whether to permit this exception to apply to your modifications.
|
||||
If you do not wish that, delete this exception notice.
|
||||
|
||||
This backend is for CanoScan 3200F.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "cs3200f-dev.h"
|
||||
#include "cs3200f-dat.h"
|
||||
#include "cs3200f-drv.h"
|
||||
#include "cs3200f-usb.h"
|
||||
|
||||
#include "../include/sane/sanei_access.h"
|
||||
|
||||
/***********************************************************************
|
||||
* Local types
|
||||
***********************************************************************/
|
||||
|
||||
typedef struct DEVICE_NODE DEVICE_NODE_T;
|
||||
|
||||
struct DEVICE_NODE
|
||||
{
|
||||
SANE_Device dev;
|
||||
SANE_String name;
|
||||
DEVICE_NODE_T *next;
|
||||
};
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* Local prototypes
|
||||
***********************************************************************/
|
||||
|
||||
static void build_device_list( void );
|
||||
static SANE_Status tell_device( SANE_String_Const name );
|
||||
static void get_first_device( void );
|
||||
static SANE_Status first_device( SANE_String_Const name );
|
||||
|
||||
/***********************************************************************
|
||||
* Local data
|
||||
***********************************************************************/
|
||||
|
||||
static SANE_String_Const str_c_vendor_canon =
|
||||
SANE_I18N( "CANON" );
|
||||
static SANE_String_Const str_c_model_cs3200f =
|
||||
SANE_I18N( "CS3200F" );
|
||||
static SANE_String_Const str_c_type_flatbed_scanner =
|
||||
SANE_I18N( "flatbed scanner" );
|
||||
|
||||
static const SANE_Int usb_vendor_canon = 0x04A9;
|
||||
static const SANE_Int usb_device_cs3200f = 0x2216;
|
||||
|
||||
static DEVICE_NODE_T *current_device_list;
|
||||
static const SANE_Device **current_device_table;
|
||||
|
||||
static SANE_String first_device_name;
|
||||
|
||||
/***********************************************************************
|
||||
* Interface
|
||||
***********************************************************************/
|
||||
|
||||
void d_init_devices( void )
|
||||
{
|
||||
DBG( D_CALL, "d_init_devices()\n" );
|
||||
|
||||
current_device_list = 0;
|
||||
current_device_table = 0;
|
||||
first_device_name = 0;
|
||||
|
||||
a_init_data();
|
||||
}
|
||||
|
||||
const SANE_Device **
|
||||
d_get_devices( void )
|
||||
{
|
||||
const SANE_Device **dt;
|
||||
|
||||
DBG( D_CALL, "d_get_devices()\n" );
|
||||
|
||||
build_device_list();
|
||||
dt = current_device_table;
|
||||
|
||||
DBG( D_RES, "return device table %08X\n", (unsigned int)dt );
|
||||
return dt;
|
||||
}
|
||||
|
||||
SANE_Status
|
||||
d_open_device( SANE_String_Const devicename, SANE_Handle *handle )
|
||||
{
|
||||
DEVICE_T *dh;
|
||||
SANE_String_Const the_name;
|
||||
|
||||
DBG( D_CALL, "d_open_device( devicename = %s, handle = %08X )\n",
|
||||
devicename, (unsigned int)handle );
|
||||
|
||||
if ( handle )
|
||||
{
|
||||
*handle = a_new_dev();
|
||||
}
|
||||
else
|
||||
{
|
||||
return SANE_STATUS_INVAL;
|
||||
}
|
||||
|
||||
if ( ! *handle )
|
||||
{
|
||||
DBG( D_ERR, "Can't allocate memory for the device\n" );
|
||||
return SANE_STATUS_NO_MEM;
|
||||
}
|
||||
|
||||
dh = *handle;
|
||||
|
||||
if ( strcmp( devicename, "dummy" ) == 0 )
|
||||
{
|
||||
DBG( D_RES, "Dummy device handle %08X\n", (unsigned int)*handle );
|
||||
return SANE_STATUS_GOOD;
|
||||
}
|
||||
|
||||
if ( devicename[0] == 0 )
|
||||
{
|
||||
get_first_device();
|
||||
|
||||
if ( first_device_name == 0 )
|
||||
{
|
||||
DBG( D_INFO, "No CS3200F found\n" );
|
||||
a_delete_dev( *handle );
|
||||
*handle = 0;
|
||||
return SANE_STATUS_IO_ERROR;
|
||||
}
|
||||
else
|
||||
{
|
||||
DBG( D_INFO, "CS3200F found at [%s]\n", first_device_name );
|
||||
the_name = first_device_name;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
the_name = devicename;
|
||||
}
|
||||
|
||||
dh->name = malloc( strlen( the_name ) + 1 );
|
||||
strcpy( dh->name, the_name );
|
||||
|
||||
/* check is there is already device with that name open */
|
||||
DBG( D_INFO, "Trying to lock %s\n", the_name );
|
||||
if ( sanei_access_lock( the_name, 5 ) )
|
||||
{
|
||||
DBG( D_INFO, "Device already open by someone else\n" );
|
||||
a_delete_dev( *handle );
|
||||
*handle = 0;
|
||||
return SANE_STATUS_DEVICE_BUSY;
|
||||
}
|
||||
DBG( D_INFO, "Lock obtained\n" );
|
||||
|
||||
|
||||
if ( u_open( dh ) != SANE_STATUS_GOOD )
|
||||
{
|
||||
sane_close( *handle );
|
||||
*handle = 0;
|
||||
return SANE_STATUS_DEVICE_BUSY;
|
||||
}
|
||||
|
||||
if ( r_boot( dh->dn ) != SANE_STATUS_GOOD )
|
||||
{
|
||||
sane_close( *handle );
|
||||
*handle = 0;
|
||||
return SANE_STATUS_IO_ERROR;
|
||||
}
|
||||
|
||||
DBG( D_RES, "Device handle %08X\n", (unsigned int)*handle );
|
||||
|
||||
return SANE_STATUS_GOOD;
|
||||
}
|
||||
|
||||
void
|
||||
d_close_device( SANE_Handle handle )
|
||||
{
|
||||
DEVICE_T *dh = handle;
|
||||
|
||||
DBG( D_CALL, "d_close_device( handle = %08X )\n",
|
||||
(unsigned int)handle );
|
||||
|
||||
if ( a_handle_valid( handle ) != SANE_STATUS_GOOD )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
u_close( dh );
|
||||
|
||||
if ( dh->name )
|
||||
{
|
||||
DBG( D_INFO, "Unlocking %s\n", dh->name );
|
||||
(void)sanei_access_unlock( dh->name );
|
||||
}
|
||||
|
||||
a_delete_dev( handle );
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* Local code
|
||||
***********************************************************************/
|
||||
|
||||
static void build_device_list( void )
|
||||
{
|
||||
DEVICE_NODE_T *dn;
|
||||
int n_devices;
|
||||
int i;
|
||||
|
||||
DBG( D_CALL, "build_device_list()\n" );
|
||||
|
||||
/* kill old device list */
|
||||
while( current_device_list )
|
||||
{
|
||||
dn = current_device_list;
|
||||
current_device_list = current_device_list->next;
|
||||
if ( dn->name )
|
||||
{
|
||||
free( dn->name );
|
||||
}
|
||||
free( dn );
|
||||
}
|
||||
|
||||
/* kill old device table */
|
||||
if ( current_device_table )
|
||||
{
|
||||
free( current_device_table );
|
||||
current_device_table = 0;
|
||||
}
|
||||
|
||||
/* build new name list */
|
||||
sanei_usb_find_devices( usb_vendor_canon,
|
||||
usb_device_cs3200f,
|
||||
tell_device );
|
||||
|
||||
/* add dummy device if the list is empty */
|
||||
if ( ! current_device_list )
|
||||
{
|
||||
(void)tell_device( "dummy" );
|
||||
}
|
||||
|
||||
/* build new device table & device list*/
|
||||
n_devices = 0;
|
||||
dn = current_device_list;
|
||||
while ( dn )
|
||||
{
|
||||
++n_devices;
|
||||
dn = dn->next;
|
||||
}
|
||||
|
||||
current_device_table =
|
||||
malloc( ( n_devices + 1 ) * sizeof( SANE_Device * ) );
|
||||
|
||||
dn = current_device_list;
|
||||
|
||||
for ( i = 0; i < n_devices; i++ )
|
||||
{
|
||||
current_device_table[i] = &(dn->dev);
|
||||
dn = dn->next;
|
||||
}
|
||||
current_device_table[i] = 0;
|
||||
}
|
||||
|
||||
static SANE_Status tell_device( SANE_String_Const name )
|
||||
{
|
||||
DEVICE_NODE_T *dn;
|
||||
|
||||
DBG( D_CALL, "tell_device_name( name = %s )\n", name );
|
||||
|
||||
if ( ! name )
|
||||
{
|
||||
/* got null string pointer */
|
||||
return SANE_STATUS_INVAL;
|
||||
}
|
||||
|
||||
DBG( D_INFO, "Found device %s\n", name );
|
||||
|
||||
dn = current_device_list;
|
||||
while ( dn && dn->next )
|
||||
{
|
||||
dn = dn->next;
|
||||
}
|
||||
|
||||
if ( dn )
|
||||
{
|
||||
dn = dn->next = malloc( sizeof( DEVICE_NODE_T ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
dn = current_device_list = malloc( sizeof( DEVICE_NODE_T ) );
|
||||
}
|
||||
|
||||
dn->name = malloc( strlen( name ) + 1 );
|
||||
strcpy( dn->name, name );
|
||||
|
||||
dn->dev.name = dn->name;
|
||||
dn->dev.vendor = str_c_vendor_canon;
|
||||
dn->dev.model = str_c_model_cs3200f;
|
||||
dn->dev.type = str_c_type_flatbed_scanner;
|
||||
|
||||
dn->next = 0;
|
||||
|
||||
return SANE_STATUS_GOOD;
|
||||
}
|
||||
|
||||
static void get_first_device( void )
|
||||
{
|
||||
DBG( D_CALL, "get_first_device()\n" );
|
||||
|
||||
if ( first_device_name )
|
||||
{
|
||||
free( first_device_name );
|
||||
first_device_name = 0;
|
||||
}
|
||||
|
||||
sanei_usb_find_devices( usb_vendor_canon,
|
||||
usb_device_cs3200f,
|
||||
first_device );
|
||||
}
|
||||
|
||||
static SANE_Status first_device( SANE_String_Const name )
|
||||
{
|
||||
DBG( D_CALL, "first_device( name = %s )\n", name );
|
||||
|
||||
if ( ! first_device_name )
|
||||
{
|
||||
first_device_name = malloc( strlen( name ) + 1 );
|
||||
strcpy( first_device_name, name );
|
||||
}
|
||||
|
||||
return SANE_STATUS_GOOD;
|
||||
}
|
||||
|
||||
/************************************************************************
|
||||
* $Id: cs3200f-dev.c,v 1.1 2006/03/26 19:01:59 lapi-guest Exp $
|
||||
************************************************************************/
|
|
@ -0,0 +1,84 @@
|
|||
/* sane - Scanner Access Now Easy.
|
||||
Copyright (C) 2006 Lauri Pirttiaho <lauri.pirttiaho@cornell.edu>
|
||||
|
||||
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; either version 2 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston,
|
||||
MA 02111-1307, USA.
|
||||
|
||||
As a special exception, the authors of SANE give permission for
|
||||
additional uses of the libraries contained in this release of SANE.
|
||||
|
||||
The exception is that, if you link a SANE library with other files
|
||||
to produce an executable, this does not by itself cause the
|
||||
resulting executable to be covered by the GNU General Public
|
||||
License. Your use of that executable is in no way restricted on
|
||||
account of linking the SANE library code into it.
|
||||
|
||||
This exception does not, however, invalidate any other reasons why
|
||||
the executable file might be covered by the GNU General Public
|
||||
License.
|
||||
|
||||
If you submit changes to SANE to the maintainers to be included in
|
||||
a subsequent release, you agree by submitting the changes that
|
||||
those changes may be distributed with this exception intact.
|
||||
|
||||
If you write modifications of your own for SANE, it is your choice
|
||||
whether to permit this exception to apply to your modifications.
|
||||
If you do not wish that, delete this exception notice.
|
||||
|
||||
This backend is for CanoScan 3200F.
|
||||
*/
|
||||
|
||||
#ifndef CS3200F_DEV_H
|
||||
#define CS3200F_DEV_H
|
||||
|
||||
#include "../include/sane/sane.h"
|
||||
|
||||
/***********************************************************************
|
||||
* Interface
|
||||
***********************************************************************/
|
||||
|
||||
/** Initialize devices
|
||||
*/
|
||||
void d_init_devices( void );
|
||||
|
||||
/** Get list of available devices
|
||||
* @return null terminated list of pointers to SANE_Device structures
|
||||
*/
|
||||
const SANE_Device **
|
||||
d_get_devices( void );
|
||||
|
||||
/** Open a device
|
||||
* @param devicename name of the device to be opened
|
||||
* @param handle pointer to place where the handle will be put
|
||||
* @return status of the opening
|
||||
* @note If the device name is empty string, the first device will be
|
||||
* opened.
|
||||
*/
|
||||
SANE_Status
|
||||
d_open_device( SANE_String_Const devicename, SANE_Handle *handle );
|
||||
|
||||
/** Close a device
|
||||
* @param handle handle to the device
|
||||
*/
|
||||
void
|
||||
d_close_device( SANE_Handle handle );
|
||||
|
||||
#endif /* ndef CS3200F_DEV_H */
|
||||
|
||||
/************************************************************************
|
||||
* $Id: cs3200f-dev.h,v 1.1 2006/03/26 19:01:59 lapi-guest Exp $
|
||||
************************************************************************/
|
Plik diff jest za duży
Load Diff
|
@ -0,0 +1,222 @@
|
|||
/* sane - Scanner Access Now Easy.
|
||||
Copyright (C) 2006 Lauri Pirttiaho <lauri.pirttiaho@cornell.edu>
|
||||
|
||||
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; either version 2 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston,
|
||||
MA 02111-1307, USA.
|
||||
|
||||
As a special exception, the authors of SANE give permission for
|
||||
additional uses of the libraries contained in this release of SANE.
|
||||
|
||||
The exception is that, if you link a SANE library with other files
|
||||
to produce an executable, this does not by itself cause the
|
||||
resulting executable to be covered by the GNU General Public
|
||||
License. Your use of that executable is in no way restricted on
|
||||
account of linking the SANE library code into it.
|
||||
|
||||
This exception does not, however, invalidate any other reasons why
|
||||
the executable file might be covered by the GNU General Public
|
||||
License.
|
||||
|
||||
If you submit changes to SANE to the maintainers to be included in
|
||||
a subsequent release, you agree by submitting the changes that
|
||||
those changes may be distributed with this exception intact.
|
||||
|
||||
If you write modifications of your own for SANE, it is your choice
|
||||
whether to permit this exception to apply to your modifications.
|
||||
If you do not wish that, delete this exception notice.
|
||||
|
||||
This backend is for CanoScan 3200F.
|
||||
*/
|
||||
|
||||
#ifndef CS3200F_DRV_H
|
||||
#define CS3200F_DRV_H
|
||||
|
||||
#include "../include/sane/sane.h"
|
||||
|
||||
/***********************************************************************
|
||||
* Interface constants
|
||||
***********************************************************************/
|
||||
|
||||
/** Lamp control */
|
||||
typedef enum
|
||||
{
|
||||
LAMP_MAIN_LOW,
|
||||
LAMP_MAIN_HIGH,
|
||||
LAMP_TA
|
||||
} LAMP_E;
|
||||
|
||||
/** Color line of the scan */
|
||||
typedef enum
|
||||
{
|
||||
COLOR_RED = 0,
|
||||
COLOR_GREEN,
|
||||
COLOR_BLUE,
|
||||
COLOR_ALL
|
||||
} COLOR_E;
|
||||
|
||||
/***********************************************************************
|
||||
* The device interface
|
||||
***********************************************************************/
|
||||
|
||||
/** Boot the scanner
|
||||
* @param dn device number of the scanner
|
||||
* @return status of the boot
|
||||
*/
|
||||
SANE_Status
|
||||
r_boot( SANE_Int dn );
|
||||
|
||||
/** Set lamp watchdog counts
|
||||
* @param dn device number of the scanner
|
||||
* @param c1 zero state count
|
||||
* @param c2 one state count
|
||||
* @return status of the boot
|
||||
* @note Unit of the counts is such that there are 31+13/15 counts
|
||||
* in one second. Typically c1 = 4000 and c2 = 20000 making
|
||||
* the lamp tun-off time 24000/(31+13/15) = 753 s or about
|
||||
* 12.5 min.
|
||||
*/
|
||||
SANE_Status
|
||||
r_wd_set( SANE_Int dn, SANE_Int c1, SANE_Int c2 );
|
||||
|
||||
/** Turn a lamp on
|
||||
* @param dn device number of the scanner
|
||||
* @param lamp which lamp to turn on
|
||||
* @return status of the command
|
||||
*/
|
||||
SANE_Status
|
||||
r_lamp_on( SANE_Int dn, LAMP_E lamp );
|
||||
|
||||
/** Turn lamps off
|
||||
* @param dn device number of the scanner
|
||||
*/
|
||||
void
|
||||
r_lamp_off( SANE_Int dn );
|
||||
|
||||
/** Set AFE
|
||||
* @param dn device number of the scanner
|
||||
* @param as the AFE settings
|
||||
*/
|
||||
void
|
||||
r_afe_set( SANE_Int dn, AFE_SET_T *as );
|
||||
|
||||
/** Move scan head home
|
||||
* @param dn device number of the scanner
|
||||
*/
|
||||
void r_home( SANE_Int dn );
|
||||
|
||||
/** Move scan head to the given line
|
||||
* @param dn device number of the scanner
|
||||
* @param line line to move to
|
||||
*/
|
||||
void r_move( SANE_Int dn, SANE_Int line );
|
||||
|
||||
/** Wait until the lamp intensity settles
|
||||
* @param dn device number of the scanner
|
||||
* @param ta tells if transparency adapter is being used
|
||||
* @param nmax maximum number of trials (also approximately max
|
||||
* waiting time is 5*nmax seconds)
|
||||
* @return SANE_STATUS_GOOD if settled, else SANE_STATUS_CANCELLED
|
||||
*/
|
||||
SANE_Status
|
||||
r_lamp_settle( SANE_Int dn, SANE_Bool ta, SANE_Int nmax );
|
||||
|
||||
/** Calibrate AFE to given targets
|
||||
* @param dn device number of the scanner
|
||||
* @param res scan head resolution (300/600/1200)
|
||||
* @param ta tells if transparency adapter is being used
|
||||
* @param afe_set pointer to initial AFE settings or null if
|
||||
* offset 0 gain 1 should be used
|
||||
* @param target_swing target swing of the signal (0..255, typ 250)
|
||||
* @param target_offset target offset of the signal (0..255, typ 2 )
|
||||
* @return pointer to a AFE setting structure which is afe_set or
|
||||
* a newly allocated block if afe_set is null
|
||||
*/
|
||||
AFE_SET_T *
|
||||
r_afe_calibrate( SANE_Int dn,
|
||||
SANE_Int res,
|
||||
SANE_Bool ta,
|
||||
AFE_SET_T *afe_set,
|
||||
SANE_Int target_swing,
|
||||
SANE_Int target_offset );
|
||||
|
||||
/** Set scanning offsets
|
||||
* @param dn device number of the scanner
|
||||
* @param col horizontal offset in 1200 dpi pixels
|
||||
* @param row vertical offset in 2400 dpi lines
|
||||
*/
|
||||
void r_offset( SANE_Int dn, SANE_Int col, SANE_Int row );
|
||||
|
||||
/** Reset scan
|
||||
* @param dn device number of the scanner
|
||||
*/
|
||||
void r_reset( SANE_Int dn );
|
||||
|
||||
/** Set gamma
|
||||
* @param dn device number of the scanner
|
||||
* @param t linear threshold (typ 0.05, rane 0-1)
|
||||
* @param rg red gamma
|
||||
* @param gg green gamma
|
||||
* @param bg blue gamma
|
||||
*/
|
||||
void r_gamma( SANE_Int dn,
|
||||
SANE_Fixed t,
|
||||
SANE_Fixed rg,
|
||||
SANE_Fixed gg,
|
||||
SANE_Fixed bg );
|
||||
|
||||
/** Set null shading
|
||||
* @param dn device number of the scanner
|
||||
*/
|
||||
SANE_Status
|
||||
r_null_shading( SANE_Int dn );
|
||||
|
||||
/** Start color scan
|
||||
* @param dn device number of the scanner
|
||||
* @param res resolution
|
||||
* @param x column offset in pixels of current resolution
|
||||
* @param w scan width in pixels of currebt resolution
|
||||
* @param y starting line in current resoloution
|
||||
* @param l number of lines in current resolution
|
||||
* @param c color line of the scan
|
||||
*/
|
||||
SANE_Status
|
||||
r_scan( SANE_Int dn,
|
||||
SANE_Int res,
|
||||
SANE_Int x,
|
||||
SANE_Int w,
|
||||
SANE_Int y,
|
||||
SANE_Int l,
|
||||
COLOR_E c );
|
||||
|
||||
/** Find the top left corner of the scanning area
|
||||
* @param dn device number of the scanner
|
||||
* @param res resolution
|
||||
* @param top pointer to var to receive the x coordinate of
|
||||
* the top left corner in 1200 lpi lines
|
||||
* @param left pointer to var to receive the y coordinate of
|
||||
* the top left corner in 1200 dpi pixels
|
||||
*/
|
||||
void r_find_top_left( SANE_Int dn,
|
||||
SANE_Int res,
|
||||
SANE_Int *top,
|
||||
SANE_Int *left );
|
||||
|
||||
#endif /* ndef CS3200F_DRV_H */
|
||||
|
||||
/************************************************************************
|
||||
* $Id: cs3200f-drv.h,v 1.2 2006/03/31 18:55:51 lapi-guest Exp $
|
||||
************************************************************************/
|
|
@ -0,0 +1,852 @@
|
|||
/* sane - Scanner Access Now Easy.
|
||||
Copyright (C) 2006 Lauri Pirttiaho <lauri.pirttiaho@cornell.edu>
|
||||
|
||||
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; either version 2 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston,
|
||||
MA 02111-1307, USA.
|
||||
|
||||
As a special exception, the authors of SANE give permission for
|
||||
additional uses of the libraries contained in this release of SANE.
|
||||
|
||||
The exception is that, if you link a SANE library with other files
|
||||
to produce an executable, this does not by itself cause the
|
||||
resulting executable to be covered by the GNU General Public
|
||||
License. Your use of that executable is in no way restricted on
|
||||
account of linking the SANE library code into it.
|
||||
|
||||
This exception does not, however, invalidate any other reasons why
|
||||
the executable file might be covered by the GNU General Public
|
||||
License.
|
||||
|
||||
If you submit changes to SANE to the maintainers to be included in
|
||||
a subsequent release, you agree by submitting the changes that
|
||||
those changes may be distributed with this exception intact.
|
||||
|
||||
If you write modifications of your own for SANE, it is your choice
|
||||
whether to permit this exception to apply to your modifications.
|
||||
If you do not wish that, delete this exception notice.
|
||||
|
||||
This backend is for CanoScan 3200F.
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "cs3200f-opt.h"
|
||||
|
||||
/* temporarily for testing only */
|
||||
#include "cs3200f-drv.h"
|
||||
|
||||
/************************************************************************
|
||||
* Option descriptors
|
||||
************************************************************************/
|
||||
|
||||
static const SANE_Option_Descriptor o_od_num_opts =
|
||||
{
|
||||
/* name = */ "",
|
||||
/* title = */ SANE_TITLE_NUM_OPTIONS,
|
||||
/* desc = */ SANE_DESC_NUM_OPTIONS,
|
||||
/* type = */ SANE_TYPE_INT,
|
||||
/* unit = */ SANE_UNIT_NONE,
|
||||
/* size = */ sizeof(SANE_Word),
|
||||
/* cap = */ SANE_CAP_SOFT_DETECT,
|
||||
/* constraint_type = */ SANE_CONSTRAINT_NONE,
|
||||
/* constraint.range = */ { 0 }
|
||||
};
|
||||
|
||||
static const SANE_Option_Descriptor o_od_resolution =
|
||||
{
|
||||
/* name = */ SANE_NAME_SCAN_RESOLUTION,
|
||||
/* title = */ SANE_TITLE_SCAN_RESOLUTION,
|
||||
/* desc = */ SANE_DESC_SCAN_RESOLUTION,
|
||||
/* type = */ SANE_TYPE_INT,
|
||||
/* unit = */ SANE_UNIT_DPI,
|
||||
/* size = */ sizeof(SANE_Word),
|
||||
/* cap = */ SANE_CAP_SOFT_DETECT | SANE_CAP_SOFT_SELECT,
|
||||
/* constraint_type = */ SANE_CONSTRAINT_WORD_LIST,
|
||||
/* constraint.word_list = */ { (const void *)opt_const_resolutions }
|
||||
};
|
||||
|
||||
static const SANE_Option_Descriptor o_od_source =
|
||||
{
|
||||
/* name = */ "source",
|
||||
/* title = */ SANE_I18N( "Source" ),
|
||||
/* desc = */ SANE_I18N( "Source for the scan." ),
|
||||
/* type = */ SANE_TYPE_STRING,
|
||||
/* unit = */ SANE_UNIT_NONE,
|
||||
/* size = */ OPT_CONST_SOURCES_MAX_LEN,
|
||||
/* cap = */ SANE_CAP_SOFT_DETECT | SANE_CAP_SOFT_SELECT,
|
||||
/* constraint_type = */ SANE_CONSTRAINT_STRING_LIST,
|
||||
/* constraint.string_list = */ { opt_const_sources }
|
||||
};
|
||||
|
||||
static const SANE_Option_Descriptor o_od_mode_group =
|
||||
{
|
||||
/* name = */ "",
|
||||
/* title = */ SANE_I18N( "Mode settings" ),
|
||||
/* desc = */ "",
|
||||
/* type = */ SANE_TYPE_GROUP,
|
||||
/* unit = */ SANE_UNIT_NONE,
|
||||
/* size = */ 0,
|
||||
/* cap = */ 0,
|
||||
/* constraint_type = */ SANE_CONSTRAINT_NONE,
|
||||
/* constraint.range = */ { 0 }
|
||||
};
|
||||
|
||||
static const SANE_Option_Descriptor o_od_mode =
|
||||
{
|
||||
/* name = */ SANE_NAME_SCAN_MODE,
|
||||
/* title = */ SANE_TITLE_SCAN_MODE,
|
||||
/* desc = */ SANE_DESC_SCAN_MODE,
|
||||
/* type = */ SANE_TYPE_STRING,
|
||||
/* unit = */ SANE_UNIT_NONE,
|
||||
/* size = */ OPT_CONST_MODES_MAX_LEN,
|
||||
/* cap = */ SANE_CAP_SOFT_DETECT | SANE_CAP_SOFT_SELECT,
|
||||
/* constraint_type = */ SANE_CONSTRAINT_STRING_LIST,
|
||||
/* constraint.range = */ { opt_const_modes }
|
||||
};
|
||||
|
||||
static const SANE_Option_Descriptor o_od_depth =
|
||||
{
|
||||
/* name = */ SANE_NAME_BIT_DEPTH,
|
||||
/* title = */ SANE_TITLE_BIT_DEPTH,
|
||||
/* desc = */ SANE_DESC_BIT_DEPTH,
|
||||
/* type = */ SANE_TYPE_INT,
|
||||
/* unit = */ SANE_UNIT_NONE,
|
||||
/* size = */ sizeof( SANE_Word ),
|
||||
/* cap = */ SANE_CAP_SOFT_DETECT | SANE_CAP_SOFT_SELECT,
|
||||
/* constraint_type = */ SANE_CONSTRAINT_WORD_LIST,
|
||||
/* constraint.range = */ { (const void *)opt_const_depths }
|
||||
};
|
||||
|
||||
static const SANE_Option_Descriptor o_od_depth_ia =
|
||||
{
|
||||
/* name = */ SANE_NAME_BIT_DEPTH,
|
||||
/* title = */ SANE_TITLE_BIT_DEPTH,
|
||||
/* desc = */ SANE_DESC_BIT_DEPTH,
|
||||
/* type = */ SANE_TYPE_INT,
|
||||
/* unit = */ SANE_UNIT_NONE,
|
||||
/* size = */ sizeof( SANE_Word ),
|
||||
/* cap = */ SANE_CAP_INACTIVE,
|
||||
/* constraint_type = */ SANE_CONSTRAINT_WORD_LIST,
|
||||
/* constraint.range = */ { (const void *)opt_const_depths }
|
||||
};
|
||||
|
||||
static const SANE_Option_Descriptor o_od_gray_color =
|
||||
{
|
||||
/* name = */ SANE_I18N( "graycolor" ),
|
||||
/* title = */ SANE_I18N( "Gray color" ),
|
||||
/* desc = */ SANE_I18N( "The color that will be used for the gray scale scanning." ),
|
||||
/* type = */ SANE_TYPE_STRING,
|
||||
/* unit = */ SANE_UNIT_NONE,
|
||||
/* size = */ OPT_CONST_RGB_COLORS_MAX_LEN,
|
||||
/* cap = */ SANE_CAP_SOFT_DETECT | SANE_CAP_SOFT_SELECT,
|
||||
/* constraint_type = */ SANE_CONSTRAINT_STRING_LIST,
|
||||
/* constraint.range = */ { opt_const_rgb_colors }
|
||||
};
|
||||
|
||||
static const SANE_Option_Descriptor o_od_gray_color_ia =
|
||||
{
|
||||
/* name = */ SANE_I18N( "graycolor" ),
|
||||
/* title = */ SANE_I18N( "Gray color" ),
|
||||
/* desc = */ SANE_I18N( "The color that will be used for the gray scale scanning." ),
|
||||
/* type = */ SANE_TYPE_STRING,
|
||||
/* unit = */ SANE_UNIT_NONE,
|
||||
/* size = */ OPT_CONST_RGB_COLORS_MAX_LEN,
|
||||
/* cap = */ SANE_CAP_INACTIVE,
|
||||
/* constraint_type = */ SANE_CONSTRAINT_STRING_LIST,
|
||||
/* constraint.range = */ { opt_const_rgb_colors }
|
||||
};
|
||||
|
||||
static const SANE_Option_Descriptor o_od_gamma_group =
|
||||
{
|
||||
/* name = */ "",
|
||||
/* title = */ SANE_I18N( "Gamma settings") ,
|
||||
/* desc = */ "",
|
||||
/* type = */ SANE_TYPE_GROUP,
|
||||
/* unit = */ SANE_UNIT_NONE,
|
||||
/* size = */ 0,
|
||||
/* cap = */ 0,
|
||||
/* constraint_type = */ SANE_CONSTRAINT_NONE,
|
||||
/* constraint.range = */ { 0 }
|
||||
};
|
||||
|
||||
static const SANE_Option_Descriptor o_od_preview =
|
||||
{
|
||||
/* name = */ SANE_NAME_PREVIEW,
|
||||
/* title = */ SANE_TITLE_PREVIEW,
|
||||
/* desc = */ SANE_DESC_PREVIEW,
|
||||
/* type = */ SANE_TYPE_BOOL,
|
||||
/* unit = */ SANE_UNIT_NONE,
|
||||
/* size = */ sizeof(SANE_Word),
|
||||
/* cap = */ SANE_CAP_SOFT_DETECT | SANE_CAP_SOFT_SELECT,
|
||||
/* constraint_type = */ SANE_CONSTRAINT_NONE,
|
||||
/* constraint.range = */ { 0 }
|
||||
};
|
||||
|
||||
static const SANE_Option_Descriptor o_od_rgb_bind =
|
||||
{
|
||||
/* name = */ SANE_NAME_RGB_BIND,
|
||||
/* title = */ SANE_TITLE_RGB_BIND,
|
||||
/* desc = */ SANE_DESC_RGB_BIND,
|
||||
/* type = */ SANE_TYPE_BOOL,
|
||||
/* unit = */ SANE_UNIT_NONE,
|
||||
/* size = */ sizeof(SANE_Word),
|
||||
/* cap = */ SANE_CAP_SOFT_DETECT | SANE_CAP_SOFT_SELECT,
|
||||
/* constraint_type = */ SANE_CONSTRAINT_NONE,
|
||||
/* constraint.range = */ { 0 }
|
||||
};
|
||||
|
||||
static const SANE_Option_Descriptor o_od_rgb_bind_ia =
|
||||
{
|
||||
/* name = */ SANE_NAME_RGB_BIND,
|
||||
/* title = */ SANE_TITLE_RGB_BIND,
|
||||
/* desc = */ SANE_DESC_RGB_BIND,
|
||||
/* type = */ SANE_TYPE_BOOL,
|
||||
/* unit = */ SANE_UNIT_NONE,
|
||||
/* size = */ sizeof(SANE_Word),
|
||||
/* cap = */ SANE_CAP_INACTIVE,
|
||||
/* constraint_type = */ SANE_CONSTRAINT_NONE,
|
||||
/* constraint.range = */ { 0 }
|
||||
};
|
||||
|
||||
static const SANE_Option_Descriptor o_od_gamma =
|
||||
{
|
||||
/* name = */ "gamma",
|
||||
/* title = */ SANE_I18N( "Gamma" ),
|
||||
/* desc = */ SANE_I18N( "Gamma correction for scanning." ),
|
||||
/* type = */ SANE_TYPE_FIXED,
|
||||
/* unit = */ SANE_UNIT_NONE,
|
||||
/* size = */ sizeof(SANE_Word),
|
||||
/* cap = */ SANE_CAP_SOFT_DETECT | SANE_CAP_SOFT_SELECT,
|
||||
/* constraint_type = */ SANE_CONSTRAINT_RANGE,
|
||||
/* constraint.range = */ { (const void *)&opt_gamma_range }
|
||||
};
|
||||
|
||||
static const SANE_Option_Descriptor o_od_gamma_ia =
|
||||
{
|
||||
/* name = */ "gamma",
|
||||
/* title = */ SANE_I18N( "Gamma" ),
|
||||
/* desc = */ SANE_I18N( "Gamma correction for scanning." ),
|
||||
/* type = */ SANE_TYPE_FIXED,
|
||||
/* unit = */ SANE_UNIT_NONE,
|
||||
/* size = */ sizeof(SANE_Word),
|
||||
/* cap = */ SANE_CAP_INACTIVE,
|
||||
/* constraint_type = */ SANE_CONSTRAINT_RANGE,
|
||||
/* constraint.range = */ { (const void *)&opt_gamma_range }
|
||||
};
|
||||
|
||||
static const SANE_Option_Descriptor o_od_gamma_r =
|
||||
{
|
||||
/* name = */ "gammar",
|
||||
/* title = */ SANE_I18N( "Red Gamma" ),
|
||||
/* desc = */ SANE_I18N( "Gamma correction for scanning red." ),
|
||||
/* type = */ SANE_TYPE_FIXED,
|
||||
/* unit = */ SANE_UNIT_NONE,
|
||||
/* size = */ sizeof(SANE_Word),
|
||||
/* cap = */ SANE_CAP_SOFT_DETECT | SANE_CAP_SOFT_SELECT,
|
||||
/* constraint_type = */ SANE_CONSTRAINT_RANGE,
|
||||
/* constraint.range = */ { (const void *)&opt_gamma_range }
|
||||
};
|
||||
|
||||
static const SANE_Option_Descriptor o_od_gamma_r_ia =
|
||||
{
|
||||
/* name = */ "gammar",
|
||||
/* title = */ SANE_I18N( "Red Gamma" ),
|
||||
/* desc = */ SANE_I18N( "Gamma correction for scanning red." ),
|
||||
/* type = */ SANE_TYPE_FIXED,
|
||||
/* unit = */ SANE_UNIT_NONE,
|
||||
/* size = */ sizeof(SANE_Word),
|
||||
/* cap = */ SANE_CAP_INACTIVE,
|
||||
/* constraint_type = */ SANE_CONSTRAINT_RANGE,
|
||||
/* constraint.range = */ { (const void *)&opt_gamma_range }
|
||||
};
|
||||
|
||||
static const SANE_Option_Descriptor o_od_gamma_g =
|
||||
{
|
||||
/* name = */ "gammag",
|
||||
/* title = */ SANE_I18N( "Green Gamma" ),
|
||||
/* desc = */ SANE_I18N( "Gamma correction for scanning green." ),
|
||||
/* type = */ SANE_TYPE_FIXED,
|
||||
/* unit = */ SANE_UNIT_NONE,
|
||||
/* size = */ sizeof(SANE_Word),
|
||||
/* cap = */ SANE_CAP_SOFT_DETECT | SANE_CAP_SOFT_SELECT,
|
||||
/* constraint_type = */ SANE_CONSTRAINT_RANGE,
|
||||
/* constraint.range = */ { (const void *)&opt_gamma_range }
|
||||
};
|
||||
|
||||
static const SANE_Option_Descriptor o_od_gamma_g_ia =
|
||||
{
|
||||
/* name = */ "gammag",
|
||||
/* title = */ SANE_I18N( "Green Gamma" ),
|
||||
/* desc = */ SANE_I18N( "Gamma correction for scanning green." ),
|
||||
/* type = */ SANE_TYPE_FIXED,
|
||||
/* unit = */ SANE_UNIT_NONE,
|
||||
/* size = */ sizeof(SANE_Word),
|
||||
/* cap = */ SANE_CAP_INACTIVE,
|
||||
/* constraint_type = */ SANE_CONSTRAINT_RANGE,
|
||||
/* constraint.range = */ { (const void *)&opt_gamma_range }
|
||||
};
|
||||
|
||||
static const SANE_Option_Descriptor o_od_gamma_b =
|
||||
{
|
||||
/* name = */ "gammab",
|
||||
/* title = */ SANE_I18N( "Blue Gamma" ),
|
||||
/* desc = */ SANE_I18N( "Gamma correction for scanning blue." ),
|
||||
/* type = */ SANE_TYPE_FIXED,
|
||||
/* unit = */ SANE_UNIT_NONE,
|
||||
/* size = */ sizeof(SANE_Word),
|
||||
/* cap = */ SANE_CAP_SOFT_DETECT | SANE_CAP_SOFT_SELECT,
|
||||
/* constraint_type = */ SANE_CONSTRAINT_RANGE,
|
||||
/* constraint.range = */ { (const void *)&opt_gamma_range }
|
||||
};
|
||||
|
||||
static const SANE_Option_Descriptor o_od_gamma_b_ia =
|
||||
{
|
||||
/* name = */ "gammab",
|
||||
/* title = */ SANE_I18N( "Blue Gamma" ),
|
||||
/* desc = */ SANE_I18N( "Gamma correction for scanning blue." ),
|
||||
/* type = */ SANE_TYPE_FIXED,
|
||||
/* unit = */ SANE_UNIT_NONE,
|
||||
/* size = */ sizeof(SANE_Word),
|
||||
/* cap = */ SANE_CAP_INACTIVE,
|
||||
/* constraint_type = */ SANE_CONSTRAINT_RANGE,
|
||||
/* constraint.range = */ { (const void *)&opt_gamma_range }
|
||||
};
|
||||
|
||||
static const SANE_Option_Descriptor o_od_threshold =
|
||||
{
|
||||
/* name = */ SANE_NAME_THRESHOLD,
|
||||
/* title = */ SANE_TITLE_THRESHOLD,
|
||||
/* desc = */ SANE_DESC_THRESHOLD,
|
||||
/* type = */ SANE_TYPE_FIXED,
|
||||
/* unit = */ SANE_UNIT_PERCENT,
|
||||
/* size = */ sizeof(SANE_Word),
|
||||
/* cap = */ SANE_CAP_SOFT_DETECT | SANE_CAP_SOFT_SELECT,
|
||||
/* constraint_type = */ SANE_CONSTRAINT_RANGE,
|
||||
/* constraint.range = */ { (const void *)&opt_threshold_range }
|
||||
};
|
||||
|
||||
static const SANE_Option_Descriptor o_od_threshold_ia =
|
||||
{
|
||||
/* name = */ SANE_NAME_THRESHOLD,
|
||||
/* title = */ SANE_TITLE_THRESHOLD,
|
||||
/* desc = */ SANE_DESC_THRESHOLD,
|
||||
/* type = */ SANE_TYPE_FIXED,
|
||||
/* unit = */ SANE_UNIT_PERCENT,
|
||||
/* size = */ sizeof(SANE_Word),
|
||||
/* cap = */ SANE_CAP_INACTIVE,
|
||||
/* constraint_type = */ SANE_CONSTRAINT_RANGE,
|
||||
/* constraint.range = */ { (const void *)&opt_threshold_range }
|
||||
};
|
||||
|
||||
static const SANE_Option_Descriptor o_od_geometry_group =
|
||||
{
|
||||
/* name = */ "",
|
||||
/* title = */ SANE_I18N( "Geometry" ),
|
||||
/* desc = */ "",
|
||||
/* type = */ SANE_TYPE_GROUP,
|
||||
/* unit = */ SANE_UNIT_NONE,
|
||||
/* size = */ 0,
|
||||
/* cap = */ 0,
|
||||
/* constraint_type = */ SANE_CONSTRAINT_NONE,
|
||||
/* constraint.range = */ { 0 }
|
||||
};
|
||||
|
||||
static const SANE_Option_Descriptor o_od_tl_x =
|
||||
{
|
||||
/* name = */ SANE_NAME_SCAN_TL_X,
|
||||
/* title = */ SANE_TITLE_SCAN_TL_X,
|
||||
/* desc = */ SANE_DESC_SCAN_TL_X,
|
||||
/* type = */ SANE_TYPE_FIXED,
|
||||
/* unit = */ SANE_UNIT_MM,
|
||||
/* size = */ sizeof(SANE_Word),
|
||||
/* cap = */ SANE_CAP_SOFT_DETECT | SANE_CAP_SOFT_SELECT,
|
||||
/* constraint_type = */ SANE_CONSTRAINT_RANGE,
|
||||
/* constraint.range = */ { (const void *)&opt_x_range }
|
||||
};
|
||||
|
||||
static const SANE_Option_Descriptor o_od_tl_y =
|
||||
{
|
||||
/* name = */ SANE_NAME_SCAN_TL_Y,
|
||||
/* title = */ SANE_TITLE_SCAN_TL_Y,
|
||||
/* desc = */ SANE_DESC_SCAN_TL_Y,
|
||||
/* type = */ SANE_TYPE_FIXED,
|
||||
/* unit = */ SANE_UNIT_MM,
|
||||
/* size = */ sizeof(SANE_Word),
|
||||
/* cap = */ SANE_CAP_SOFT_DETECT | SANE_CAP_SOFT_SELECT,
|
||||
/* constraint_type = */ SANE_CONSTRAINT_RANGE,
|
||||
/* constraint.range = */ { (const void *)&opt_y_range }
|
||||
};
|
||||
|
||||
static const SANE_Option_Descriptor o_od_br_x =
|
||||
{
|
||||
/* name = */ SANE_NAME_SCAN_BR_X,
|
||||
/* title = */ SANE_TITLE_SCAN_BR_X,
|
||||
/* desc = */ SANE_DESC_SCAN_BR_X,
|
||||
/* type = */ SANE_TYPE_FIXED,
|
||||
/* unit = */ SANE_UNIT_MM,
|
||||
/* size = */ sizeof(SANE_Word),
|
||||
/* cap = */ SANE_CAP_SOFT_DETECT | SANE_CAP_SOFT_SELECT,
|
||||
/* constraint_type = */ SANE_CONSTRAINT_RANGE,
|
||||
/* constraint.range = */ { (const void *)&opt_x_range }
|
||||
};
|
||||
|
||||
static const SANE_Option_Descriptor o_od_br_x_ta =
|
||||
{
|
||||
/* name = */ SANE_NAME_SCAN_BR_X,
|
||||
/* title = */ SANE_TITLE_SCAN_BR_X,
|
||||
/* desc = */ SANE_DESC_SCAN_BR_X,
|
||||
/* type = */ SANE_TYPE_FIXED,
|
||||
/* unit = */ SANE_UNIT_MM,
|
||||
/* size = */ sizeof(SANE_Word),
|
||||
/* cap = */ SANE_CAP_SOFT_DETECT | SANE_CAP_SOFT_SELECT,
|
||||
/* constraint_type = */ SANE_CONSTRAINT_RANGE,
|
||||
/* constraint.range = */ { (const void *)&opt_x_range_ta }
|
||||
};
|
||||
|
||||
static const SANE_Option_Descriptor o_od_br_y =
|
||||
{
|
||||
/* name = */ SANE_NAME_SCAN_BR_Y,
|
||||
/* title = */ SANE_TITLE_SCAN_BR_Y,
|
||||
/* desc = */ SANE_DESC_SCAN_BR_Y,
|
||||
/* type = */ SANE_TYPE_FIXED,
|
||||
/* unit = */ SANE_UNIT_MM,
|
||||
/* size = */ sizeof(SANE_Word),
|
||||
/* cap = */ SANE_CAP_SOFT_DETECT | SANE_CAP_SOFT_SELECT,
|
||||
/* constraint_type = */ SANE_CONSTRAINT_RANGE,
|
||||
/* constraint.range = */ { (const void *)&opt_y_range }
|
||||
};
|
||||
|
||||
static const SANE_Option_Descriptor o_od_br_y_ta =
|
||||
{
|
||||
/* name = */ SANE_NAME_SCAN_BR_Y,
|
||||
/* title = */ SANE_TITLE_SCAN_BR_Y,
|
||||
/* desc = */ SANE_DESC_SCAN_BR_Y,
|
||||
/* type = */ SANE_TYPE_FIXED,
|
||||
/* unit = */ SANE_UNIT_MM,
|
||||
/* size = */ sizeof(SANE_Word),
|
||||
/* cap = */ SANE_CAP_SOFT_DETECT | SANE_CAP_SOFT_SELECT,
|
||||
/* constraint_type = */ SANE_CONSTRAINT_RANGE,
|
||||
/* constraint.range = */ { (const void *)&opt_y_range_ta }
|
||||
};
|
||||
|
||||
static const SANE_Option_Descriptor o_od_calibrate_group =
|
||||
{
|
||||
/* name = */ "",
|
||||
/* title = */ SANE_I18N( "Calibration") ,
|
||||
/* desc = */ "",
|
||||
/* type = */ SANE_TYPE_GROUP,
|
||||
/* unit = */ SANE_UNIT_NONE,
|
||||
/* size = */ 0,
|
||||
/* cap = */ 0,
|
||||
/* constraint_type = */ SANE_CONSTRAINT_NONE,
|
||||
/* constraint.range = */ { 0 }
|
||||
};
|
||||
|
||||
static const SANE_Option_Descriptor o_od_calibrate =
|
||||
{
|
||||
/* name = */ "calibrate",
|
||||
/* title = */ SANE_I18N( "Calibrate now" ),
|
||||
/* desc = */ SANE_I18N( "Calibrates the current source" ),
|
||||
/* type = */ SANE_TYPE_BUTTON,
|
||||
/* unit = */ SANE_UNIT_NONE,
|
||||
/* size = */ 0,
|
||||
/* cap = */ SANE_CAP_SOFT_DETECT | SANE_CAP_SOFT_SELECT,
|
||||
/* constraint_type = */ SANE_CONSTRAINT_NONE,
|
||||
/* constraint.range = */ { 0 }
|
||||
};
|
||||
|
||||
static const SANE_Option_Descriptor o_od_calibrate_before_scan =
|
||||
{
|
||||
/* name = */ "calibratebs",
|
||||
/* title = */ SANE_I18N( "Calibrate before every scan" ),
|
||||
/* desc = */ SANE_I18N( "If this is selected the chosen mode and source will"
|
||||
"be calibrated before each scan" ),
|
||||
/* type = */ SANE_TYPE_BOOL,
|
||||
/* unit = */ SANE_UNIT_NONE,
|
||||
/* size = */ sizeof(SANE_Word),
|
||||
/* cap = */ SANE_CAP_SOFT_DETECT | SANE_CAP_SOFT_SELECT,
|
||||
/* constraint_type = */ SANE_CONSTRAINT_NONE,
|
||||
/* constraint.range = */ { 0 }
|
||||
};
|
||||
|
||||
/************************************************************************
|
||||
* Option descriptor get
|
||||
************************************************************************/
|
||||
|
||||
const SANE_Option_Descriptor *
|
||||
o_opt_desc( SANE_Handle handle,
|
||||
SANE_Int option )
|
||||
{
|
||||
DEVICE_H dh = handle;
|
||||
|
||||
switch ( option )
|
||||
{
|
||||
case OPT_NUM_OPTS:
|
||||
return &o_od_num_opts;
|
||||
break;
|
||||
case OPT_RESOLUTION:
|
||||
return &o_od_resolution;
|
||||
break;
|
||||
case OPT_SOURCE:
|
||||
return &o_od_source;
|
||||
break;
|
||||
case OPT_MODE_GROUP:
|
||||
return &o_od_mode_group;
|
||||
break;
|
||||
case OPT_MODE:
|
||||
return &o_od_mode;
|
||||
break;
|
||||
case OPT_DEPTH:
|
||||
if ( dh->opt.mode == OPT_MODE_LINEART )
|
||||
{
|
||||
return &o_od_depth_ia;
|
||||
}
|
||||
else
|
||||
{
|
||||
return &o_od_depth;
|
||||
}
|
||||
break;
|
||||
case OPT_GRAY_COLOR:
|
||||
if ( dh->opt.mode == OPT_MODE_COLOR )
|
||||
{
|
||||
return &o_od_gray_color_ia;
|
||||
}
|
||||
else
|
||||
{
|
||||
return &o_od_gray_color;
|
||||
}
|
||||
break;
|
||||
case OPT_PREVIEW:
|
||||
return &o_od_preview;
|
||||
break;
|
||||
case OPT_GAMMA_GROUP:
|
||||
return &o_od_gamma_group;
|
||||
break;
|
||||
case OPT_RGB_BIND:
|
||||
if ( dh->opt.mode == OPT_MODE_COLOR )
|
||||
{
|
||||
return &o_od_rgb_bind;
|
||||
}
|
||||
else
|
||||
{
|
||||
return &o_od_rgb_bind_ia;
|
||||
}
|
||||
break;
|
||||
case OPT_GAMMA:
|
||||
if ( dh->opt.mode == OPT_MODE_LINEART ||
|
||||
( dh->opt.rgb_bind == SANE_FALSE &&
|
||||
dh->opt.mode == OPT_MODE_COLOR ) )
|
||||
{
|
||||
return &o_od_gamma_ia;
|
||||
}
|
||||
else
|
||||
{
|
||||
return &o_od_gamma;
|
||||
}
|
||||
break;
|
||||
case OPT_GAMMA_R:
|
||||
if ( ( dh->opt.rgb_bind == SANE_TRUE &&
|
||||
dh->opt.mode == OPT_MODE_COLOR ) ||
|
||||
dh->opt.mode != OPT_MODE_COLOR )
|
||||
{
|
||||
return &o_od_gamma_r_ia;
|
||||
}
|
||||
else
|
||||
{
|
||||
return &o_od_gamma_r;
|
||||
}
|
||||
break;
|
||||
case OPT_GAMMA_G:
|
||||
if ( ( dh->opt.rgb_bind == SANE_TRUE &&
|
||||
dh->opt.mode == OPT_MODE_COLOR ) ||
|
||||
dh->opt.mode != OPT_MODE_COLOR )
|
||||
{
|
||||
return &o_od_gamma_g_ia;
|
||||
}
|
||||
else
|
||||
{
|
||||
return &o_od_gamma_g;
|
||||
}
|
||||
break;
|
||||
case OPT_GAMMA_B:
|
||||
if ( ( dh->opt.rgb_bind == SANE_TRUE &&
|
||||
dh->opt.mode == OPT_MODE_COLOR ) ||
|
||||
dh->opt.mode != OPT_MODE_COLOR )
|
||||
{
|
||||
return &o_od_gamma_b_ia;
|
||||
}
|
||||
else
|
||||
{
|
||||
return &o_od_gamma_b;
|
||||
}
|
||||
break;
|
||||
case OPT_THRESHOLD:
|
||||
if ( dh->opt.mode == OPT_MODE_LINEART )
|
||||
{
|
||||
return &o_od_threshold;
|
||||
}
|
||||
else
|
||||
{
|
||||
return &o_od_threshold_ia;
|
||||
}
|
||||
break;
|
||||
case OPT_GEOMETRY_GROUP:
|
||||
return &o_od_geometry_group;
|
||||
break;
|
||||
case OPT_TL_X:
|
||||
return &o_od_tl_x;
|
||||
break;
|
||||
case OPT_TL_Y:
|
||||
return &o_od_tl_y;
|
||||
break;
|
||||
case OPT_BR_X:
|
||||
if ( dh->opt.source == OPT_SOURCE_PAPER )
|
||||
{
|
||||
return &o_od_br_x;
|
||||
}
|
||||
else
|
||||
{
|
||||
return &o_od_br_x_ta;
|
||||
}
|
||||
break;
|
||||
case OPT_BR_Y:
|
||||
if ( dh->opt.source == OPT_SOURCE_PAPER )
|
||||
{
|
||||
return &o_od_br_y;
|
||||
}
|
||||
else
|
||||
{
|
||||
return &o_od_br_y_ta;
|
||||
}
|
||||
break;
|
||||
case OPT_CALIBRATE_GROUP:
|
||||
return &o_od_calibrate_group;
|
||||
break;
|
||||
case OPT_CALIBRATE:
|
||||
return &o_od_calibrate;
|
||||
break;
|
||||
case OPT_CALIBRATE_BEFORE_SCAN:
|
||||
return &o_od_calibrate_before_scan;
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/************************************************************************
|
||||
* Option manipulation
|
||||
************************************************************************/
|
||||
|
||||
SANE_Status
|
||||
o_opt_get( SANE_Handle handle,
|
||||
SANE_Int option,
|
||||
void *value )
|
||||
{
|
||||
DBG( D_CALL, "o_opt_get( handle = %08X, option = %d, value = %08X )\n",
|
||||
(unsigned int)handle, option, (unsigned int)value );
|
||||
|
||||
if ( ( ( ! value ) && option != OPT_CALIBRATE ) ||
|
||||
( a_handle_valid( handle ) != SANE_STATUS_GOOD ) )
|
||||
{
|
||||
return SANE_STATUS_INVAL;
|
||||
}
|
||||
|
||||
switch ( option )
|
||||
{
|
||||
case OPT_NUM_OPTS:
|
||||
*(SANE_Int *)value = NUM_OPTIONS;
|
||||
DBG( D_RES, "return number of options: %d\n", NUM_OPTIONS );
|
||||
break;
|
||||
case OPT_RESOLUTION:
|
||||
*(SANE_Int *)value = a_get_resolution( handle );
|
||||
break;
|
||||
case OPT_SOURCE:
|
||||
strcpy( (SANE_String)value, a_get_source( handle ) );
|
||||
break;
|
||||
case OPT_MODE:
|
||||
strcpy( (SANE_String)value, a_get_mode( handle ) );
|
||||
break;
|
||||
case OPT_DEPTH:
|
||||
*(SANE_Int *)value = a_get_depth( handle );
|
||||
break;
|
||||
case OPT_GRAY_COLOR:
|
||||
strcpy( (SANE_String)value, a_get_gray_color( handle ) );
|
||||
break;
|
||||
case OPT_PREVIEW:
|
||||
*(SANE_Bool *)value = a_get_preview( handle );
|
||||
break;
|
||||
case OPT_RGB_BIND:
|
||||
*(SANE_Bool *)value = a_get_rgb_bind( handle );
|
||||
break;
|
||||
case OPT_GAMMA:
|
||||
*(SANE_Fixed *)value = a_get_gamma( handle );
|
||||
break;
|
||||
case OPT_GAMMA_R:
|
||||
*(SANE_Fixed *)value = a_get_gamma_r( handle );
|
||||
break;
|
||||
case OPT_GAMMA_G:
|
||||
*(SANE_Fixed *)value = a_get_gamma_g( handle );
|
||||
break;
|
||||
case OPT_GAMMA_B:
|
||||
*(SANE_Fixed *)value = a_get_gamma_b( handle );
|
||||
break;
|
||||
case OPT_THRESHOLD:
|
||||
*(SANE_Fixed *)value = a_get_threshold( handle );
|
||||
break;
|
||||
case OPT_TL_X:
|
||||
*(SANE_Fixed *)value = a_get_tl_x( handle );
|
||||
break;
|
||||
case OPT_TL_Y:
|
||||
*(SANE_Fixed *)value = a_get_tl_y( handle );
|
||||
break;
|
||||
case OPT_BR_X:
|
||||
*(SANE_Fixed *)value = a_get_br_x( handle );
|
||||
break;
|
||||
case OPT_BR_Y:
|
||||
*(SANE_Fixed *)value = a_get_br_y( handle );
|
||||
break;
|
||||
case OPT_CALIBRATE:
|
||||
break;
|
||||
case OPT_CALIBRATE_BEFORE_SCAN:
|
||||
*(SANE_Bool *)value = a_get_calibrate_before_scan( handle );
|
||||
break;
|
||||
default:
|
||||
return SANE_STATUS_INVAL;
|
||||
break;
|
||||
}
|
||||
|
||||
return SANE_STATUS_GOOD;
|
||||
}
|
||||
|
||||
SANE_Status
|
||||
o_opt_set( SANE_Handle handle,
|
||||
SANE_Int option,
|
||||
void *value,
|
||||
SANE_Int * info)
|
||||
{
|
||||
SANE_Int no_info;
|
||||
|
||||
DBG( D_CALL, "o_opt_set( handle = %08X, option = %d,"
|
||||
" value = %08X, info =%08X )\n",
|
||||
(unsigned int)handle, option,
|
||||
(unsigned int)value, (unsigned int)info );
|
||||
|
||||
if ( ( ( ! value ) && option != OPT_CALIBRATE ) ||
|
||||
( a_handle_valid( handle ) != SANE_STATUS_GOOD ) )
|
||||
{
|
||||
return SANE_STATUS_INVAL;
|
||||
}
|
||||
|
||||
if ( !info )
|
||||
{
|
||||
info = &no_info;
|
||||
}
|
||||
|
||||
switch ( option )
|
||||
{
|
||||
case OPT_RESOLUTION:
|
||||
*info = a_set_resolution( handle, *(SANE_Int *)value );
|
||||
break;
|
||||
case OPT_SOURCE:
|
||||
*info = a_set_source( handle, (SANE_String_Const)value );
|
||||
break;
|
||||
case OPT_MODE:
|
||||
*info = a_set_mode( handle, (SANE_String_Const)value );
|
||||
break;
|
||||
case OPT_DEPTH:
|
||||
*info = a_set_depth( handle, *(SANE_Int *)value );
|
||||
break;
|
||||
case OPT_GRAY_COLOR:
|
||||
*info = a_set_gray_color( handle, (SANE_String_Const)value );
|
||||
break;
|
||||
case OPT_PREVIEW:
|
||||
*info = a_set_preview( handle, *(SANE_Bool *)value );
|
||||
break;
|
||||
case OPT_RGB_BIND:
|
||||
*info = a_set_rgb_bind( handle, *(SANE_Bool *)value );
|
||||
break;
|
||||
case OPT_GAMMA:
|
||||
*info = a_set_gamma( handle, *(SANE_Fixed *)value );
|
||||
break;
|
||||
case OPT_GAMMA_R:
|
||||
*info = a_set_gamma_r( handle, *(SANE_Fixed *)value );
|
||||
break;
|
||||
case OPT_GAMMA_G:
|
||||
*info = a_set_gamma_g( handle, *(SANE_Fixed *)value );
|
||||
break;
|
||||
case OPT_GAMMA_B:
|
||||
*info = a_set_gamma_b( handle, *(SANE_Fixed *)value );
|
||||
break;
|
||||
case OPT_THRESHOLD:
|
||||
*info = a_set_threshold( handle, *(SANE_Fixed *)value );
|
||||
break;
|
||||
case OPT_TL_X:
|
||||
*info = a_set_tl_x( handle, *(SANE_Fixed *)value );
|
||||
break;
|
||||
case OPT_TL_Y:
|
||||
*info = a_set_tl_y( handle, *(SANE_Fixed *)value );
|
||||
if ( 0 )
|
||||
{
|
||||
SANE_Int line;
|
||||
DEVICE_H dh = handle;
|
||||
line = SANE_UNFIX( a_get_tl_y( handle ) ) * 2400. / 25.4;
|
||||
DBG( D_INFO, "Moving to line %d\n", line );
|
||||
if ( dh->dn >= 0 )
|
||||
{
|
||||
r_move( dh->dn, line );
|
||||
}
|
||||
}
|
||||
break;
|
||||
case OPT_BR_X:
|
||||
*info = a_set_br_x( handle, *(SANE_Fixed *)value );
|
||||
break;
|
||||
case OPT_BR_Y:
|
||||
*info = a_set_br_y( handle, *(SANE_Fixed *)value );
|
||||
break;
|
||||
case OPT_CALIBRATE:
|
||||
DBG( D_INFO, "Calibrating now!\n" );
|
||||
{
|
||||
DEVICE_H dh = handle;
|
||||
AFE_SET_T *afe_set = 0;
|
||||
|
||||
r_lamp_on( dh->dn, LAMP_MAIN_HIGH );
|
||||
r_lamp_settle( dh->dn, SANE_FALSE, 120 );
|
||||
r_afe_calibrate( dh->dn, 600, SANE_FALSE, afe_set, 250, 2 );
|
||||
free( afe_set );
|
||||
}
|
||||
*info = 0;
|
||||
break;
|
||||
case OPT_CALIBRATE_BEFORE_SCAN:
|
||||
*info = a_set_calibrate_before_scan( handle, *(SANE_Bool *)value );
|
||||
break;
|
||||
default:
|
||||
return SANE_STATUS_INVAL;
|
||||
break;
|
||||
}
|
||||
|
||||
DBG( D_RES, "info: %s, %s, %s\n",
|
||||
*info & SANE_INFO_INEXACT ? "inexact" : "exact",
|
||||
*info & SANE_INFO_RELOAD_OPTIONS ? "reload options" : "keep options",
|
||||
*info & SANE_INFO_RELOAD_PARAMS ? "reload params" : "keep params" );
|
||||
|
||||
return SANE_STATUS_GOOD;
|
||||
}
|
||||
|
||||
/************************************************************************
|
||||
* $Id: cs3200f-opt.c,v 1.1 2006/03/26 19:01:59 lapi-guest Exp $
|
||||
************************************************************************/
|
|
@ -0,0 +1,88 @@
|
|||
/* sane - Scanner Access Now Easy.
|
||||
Copyright (C) 2006 Lauri Pirttiaho <lauri.pirttiaho@cornell.edu>
|
||||
|
||||
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; either version 2 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston,
|
||||
MA 02111-1307, USA.
|
||||
|
||||
As a special exception, the authors of SANE give permission for
|
||||
additional uses of the libraries contained in this release of SANE.
|
||||
|
||||
The exception is that, if you link a SANE library with other files
|
||||
to produce an executable, this does not by itself cause the
|
||||
resulting executable to be covered by the GNU General Public
|
||||
License. Your use of that executable is in no way restricted on
|
||||
account of linking the SANE library code into it.
|
||||
|
||||
This exception does not, however, invalidate any other reasons why
|
||||
the executable file might be covered by the GNU General Public
|
||||
License.
|
||||
|
||||
If you submit changes to SANE to the maintainers to be included in
|
||||
a subsequent release, you agree by submitting the changes that
|
||||
those changes may be distributed with this exception intact.
|
||||
|
||||
If you write modifications of your own for SANE, it is your choice
|
||||
whether to permit this exception to apply to your modifications.
|
||||
If you do not wish that, delete this exception notice.
|
||||
|
||||
This backend is for CanoScan 3200F.
|
||||
*/
|
||||
|
||||
#ifndef CS3200F_OPT_H
|
||||
#define CS3200F_OPT_H
|
||||
|
||||
#include "../include/sane/sane.h"
|
||||
#include "cs3200f-dat.h"
|
||||
|
||||
/** Get option decriptor
|
||||
* @param handle the device for which the descriptor is queried
|
||||
* @param option the option for which the descriptor is queried
|
||||
* @return pointer to the descriptor
|
||||
*/
|
||||
const SANE_Option_Descriptor *
|
||||
o_opt_desc( SANE_Handle handle,
|
||||
SANE_Int option );
|
||||
|
||||
/** Get option
|
||||
* @param handle the device for which the option is queried
|
||||
* @param option the option which is being queried
|
||||
* @param value pointer to the location where value is put
|
||||
* @return status of the query
|
||||
*/
|
||||
SANE_Status
|
||||
o_opt_get( SANE_Handle handle,
|
||||
SANE_Int option,
|
||||
void *value );
|
||||
|
||||
/** Set option
|
||||
* @param handle the device for which the option is set
|
||||
* @param option the option which is being set
|
||||
* @param value pointer to the location where the new value is
|
||||
* @param info tells about the side effects of setting
|
||||
* @return status of the query
|
||||
*/
|
||||
SANE_Status
|
||||
o_opt_set( SANE_Handle handle,
|
||||
SANE_Int option,
|
||||
void *value,
|
||||
SANE_Int * info);
|
||||
|
||||
#endif /* ndef CS3200F_OPT_H */
|
||||
|
||||
/************************************************************************
|
||||
* $Id: cs3200f-opt.h,v 1.1 2006/03/26 19:01:59 lapi-guest Exp $
|
||||
************************************************************************/
|
|
@ -0,0 +1,539 @@
|
|||
/* sane - Scanner Access Now Easy.
|
||||
Copyright (C) 2006 Lauri Pirttiaho <lauri.pirttiaho@cornell.edu>
|
||||
|
||||
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; either version 2 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston,
|
||||
MA 02111-1307, USA.
|
||||
|
||||
As a special exception, the authors of SANE give permission for
|
||||
additional uses of the libraries contained in this release of SANE.
|
||||
|
||||
The exception is that, if you link a SANE library with other files
|
||||
to produce an executable, this does not by itself cause the
|
||||
resulting executable to be covered by the GNU General Public
|
||||
License. Your use of that executable is in no way restricted on
|
||||
account of linking the SANE library code into it.
|
||||
|
||||
This exception does not, however, invalidate any other reasons why
|
||||
the executable file might be covered by the GNU General Public
|
||||
License.
|
||||
|
||||
If you submit changes to SANE to the maintainers to be included in
|
||||
a subsequent release, you agree by submitting the changes that
|
||||
those changes may be distributed with this exception intact.
|
||||
|
||||
If you write modifications of your own for SANE, it is your choice
|
||||
whether to permit this exception to apply to your modifications.
|
||||
If you do not wish that, delete this exception notice.
|
||||
|
||||
This backend is for CanoScan 3200F.
|
||||
*/
|
||||
|
||||
#include "../include/sane/sanei_thread.h"
|
||||
#include <unistd.h>
|
||||
|
||||
#include "cs3200f-scan.h"
|
||||
#include "cs3200f-dat.h"
|
||||
#include "cs3200f-drv.h"
|
||||
|
||||
/***********************************************************************
|
||||
* Local types
|
||||
***********************************************************************/
|
||||
|
||||
typedef struct RAW_DATA
|
||||
{
|
||||
struct RAW_DATA *next;
|
||||
SANE_Int n_lines;
|
||||
SANE_Byte data[1];
|
||||
} RAW_DATA_T;
|
||||
|
||||
/***********************************************************************
|
||||
* Local prototypes
|
||||
***********************************************************************/
|
||||
|
||||
static int s_scan_thread( void *handle );
|
||||
void s_unstagger( SANE_Handle handle,
|
||||
SANE_Byte * data,
|
||||
SANE_Int max_length,
|
||||
SANE_Int * length );
|
||||
|
||||
/***********************************************************************
|
||||
* Interface
|
||||
***********************************************************************/
|
||||
|
||||
SANE_Status s_get_params( SANE_Handle handle,
|
||||
SANE_Parameters * params )
|
||||
{
|
||||
DBG( D_CALL, "s_get_params( handle = %08X, params = %08X)\n",
|
||||
(unsigned int)handle, (unsigned int)params );
|
||||
|
||||
if ( ( ! params ) ||
|
||||
( a_handle_valid( handle ) != SANE_STATUS_GOOD ) )
|
||||
{
|
||||
DBG( D_ERR, "Bad parameters\n" );
|
||||
return SANE_STATUS_INVAL;
|
||||
}
|
||||
|
||||
params->format = a_format( handle );
|
||||
DBG( D_RES, "Format: %s\n",
|
||||
(params->format == SANE_FRAME_RGB ) ? "RGB": "Gray" );
|
||||
|
||||
params->last_frame = SANE_TRUE;
|
||||
DBG( D_RES, "Last frame: true\n" );
|
||||
|
||||
params->depth = a_depth( handle );
|
||||
DBG( D_RES, "Depth: %d\n", params->depth );
|
||||
|
||||
params->lines = a_lines( handle );
|
||||
DBG( D_RES, "Lines: %d\n", params->lines );
|
||||
|
||||
|
||||
params->pixels_per_line = a_pixels_per_line( handle );
|
||||
DBG( D_RES, "Pixels per line: %d\n", params->pixels_per_line );
|
||||
|
||||
|
||||
params->bytes_per_line = a_bytes_per_line( handle );
|
||||
DBG( D_RES, "Bytes per line: %d\n", params->bytes_per_line );
|
||||
|
||||
return SANE_STATUS_GOOD;
|
||||
}
|
||||
|
||||
SANE_Status s_scan_start( SANE_Handle handle )
|
||||
{
|
||||
DEVICE_H dh = handle;
|
||||
|
||||
DBG( D_CALL, "s_scan_start( handle = %08X )\n",
|
||||
(unsigned int)handle );
|
||||
|
||||
a_scan_finish( handle );
|
||||
a_scan_init(handle );
|
||||
|
||||
if ( pipe( dh->scan_pipe ) == -1 )
|
||||
{
|
||||
DBG( D_ERR, "Pipe creation failed\n" );
|
||||
return SANE_STATUS_IO_ERROR;
|
||||
}
|
||||
|
||||
dh->scan_thread = sanei_thread_begin( s_scan_thread, dh );
|
||||
|
||||
if ( sanei_thread_is_forked() )
|
||||
{
|
||||
close( dh->scan_pipe[1] );
|
||||
}
|
||||
|
||||
if ( dh->scan_thread == -1 )
|
||||
{
|
||||
DBG( D_ERR, "Scan thread spawning failed\n" );
|
||||
return SANE_STATUS_IO_ERROR;
|
||||
}
|
||||
else
|
||||
{
|
||||
DBG( D_INFO, "Scan thread %d spawned\n", dh->scan_thread );
|
||||
}
|
||||
|
||||
dh->scan_bytes_left = a_lines( handle ) * a_bytes_per_line( handle );
|
||||
|
||||
if ( a_get_mode_e( handle ) == OPT_MODE_COLOR
|
||||
|| a_get_resolution( handle ) == 1200 )
|
||||
{
|
||||
a_scan_init( handle );
|
||||
}
|
||||
|
||||
return SANE_STATUS_GOOD;
|
||||
}
|
||||
|
||||
SANE_Status
|
||||
s_scan_read( SANE_Handle handle,
|
||||
SANE_Byte * data,
|
||||
SANE_Int max_length,
|
||||
SANE_Int * length )
|
||||
{
|
||||
DEVICE_H dh = handle;
|
||||
|
||||
DBG( D_CALL, "s_scan_read( handle = %08X, data = %08X, "
|
||||
"max_length = %d, length = %08X )\n",
|
||||
(unsigned int)handle, (unsigned int)data,
|
||||
max_length, (unsigned int)length );
|
||||
|
||||
if ( dh->dn < 0 )
|
||||
{
|
||||
*length = read( dh->scan_pipe[0], data, max_length );
|
||||
}
|
||||
else
|
||||
{
|
||||
s_unstagger( handle, data, max_length, length );
|
||||
}
|
||||
|
||||
if ( *length <= 0 )
|
||||
{
|
||||
*length = 0;
|
||||
DBG( D_INFO, "Read finished\n" );
|
||||
DBG( D_INFO, "Killing scan thread %d\n", dh->scan_thread );
|
||||
/* TODO: how to handle rbuf in scan thread? */
|
||||
sanei_thread_kill( dh->scan_thread );
|
||||
/* reset scanner */
|
||||
r_reset( dh->dn );
|
||||
r_home( dh->dn );
|
||||
a_scan_finish( handle );
|
||||
return SANE_STATUS_EOF;
|
||||
}
|
||||
|
||||
dh->scan_bytes_left -= *length;
|
||||
|
||||
DBG( D_INFO, "Read %d bytes %d left\n", *length, dh->scan_bytes_left );
|
||||
|
||||
return SANE_STATUS_GOOD;
|
||||
}
|
||||
|
||||
void
|
||||
s_scan_cancel( SANE_Handle handle )
|
||||
{
|
||||
DEVICE_H dh = handle;
|
||||
int info;
|
||||
|
||||
DBG( D_CALL, "s_scan_cancel( handle = %08X )\n",
|
||||
(unsigned int)handle );
|
||||
|
||||
a_scan_finish( handle );
|
||||
|
||||
if ( dh->scan_thread != -1 )
|
||||
{
|
||||
#if 1
|
||||
DBG( D_INFO, "Waiting scan thread %d\n", dh->scan_thread );
|
||||
sanei_thread_waitpid( dh->scan_thread, &info );
|
||||
#else
|
||||
DBG( D_INFO, "Killing scan thread %d\n", dh->scan_thread );
|
||||
sanei_thread_kill( dh->scan_thread );
|
||||
#endif
|
||||
}
|
||||
|
||||
dh->scan_thread = -1;
|
||||
close( dh->scan_pipe[0] );
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* Local code
|
||||
***********************************************************************/
|
||||
|
||||
static int s_scan_thread( void *handle )
|
||||
{
|
||||
DEVICE_H dh = handle;
|
||||
int i;
|
||||
|
||||
DBG( D_INFO, "Scan thread starting\n" );
|
||||
|
||||
i = 0;
|
||||
|
||||
if ( sanei_thread_is_forked() )
|
||||
{
|
||||
close( dh->scan_pipe[0] );
|
||||
}
|
||||
|
||||
if ( dh->dn < 0 ) /* dummy scanner */
|
||||
{
|
||||
int n_bytes = 0;
|
||||
|
||||
char buf1[3] = { '\377', '\000', '\000' };
|
||||
char buf2[3] = { '\000', '\000', '\377' };
|
||||
|
||||
n_bytes = a_lines( handle ) * a_bytes_per_line( handle );
|
||||
|
||||
while ( n_bytes > 0 )
|
||||
{
|
||||
if ( i == 64 )
|
||||
{
|
||||
n_bytes -= write( dh->scan_pipe[1], buf1, 3 );
|
||||
i = 0;
|
||||
DBG( D_INFO, "bytes left in scan %d\n", n_bytes );
|
||||
}
|
||||
else
|
||||
{
|
||||
n_bytes -= write( dh->scan_pipe[1], buf2, 3 );
|
||||
i++;
|
||||
}
|
||||
/* usleep(1); */
|
||||
}
|
||||
}
|
||||
else /* real scanner */
|
||||
{
|
||||
AFE_SET_T *as;
|
||||
SANE_Int ccd_res;
|
||||
COLOR_E c;
|
||||
SANE_Int m;
|
||||
SANE_Fixed rg,gg,bg;
|
||||
SANE_Status status;
|
||||
SANE_Byte *rbuf;
|
||||
size_t n_bytes;
|
||||
size_t n_bytes_r;
|
||||
size_t len;
|
||||
SANE_Int res;
|
||||
SANE_Int n_lines;
|
||||
SANE_Int width;
|
||||
|
||||
/* turn lamp on */
|
||||
r_lamp_on( dh->dn, LAMP_MAIN_HIGH );
|
||||
r_lamp_settle( dh->dn, SANE_FALSE, 30 );
|
||||
|
||||
/* calibrate if not done or if every scan */
|
||||
ccd_res = a_get_resolution( handle );
|
||||
if ( ccd_res < 300 )
|
||||
{
|
||||
ccd_res = 300;
|
||||
}
|
||||
|
||||
as = r_afe_calibrate( dh->dn,
|
||||
ccd_res,
|
||||
SANE_FALSE,
|
||||
0,
|
||||
250,
|
||||
2 );
|
||||
|
||||
/* set AFE */
|
||||
r_afe_set( dh->dn, as );
|
||||
|
||||
/* set gamma */
|
||||
if ( a_get_rgb_bind( handle ) )
|
||||
{
|
||||
rg = gg = bg = a_get_gamma( handle );
|
||||
}
|
||||
else
|
||||
{
|
||||
rg = a_get_gamma_r( handle );
|
||||
gg = a_get_gamma_g( handle );
|
||||
bg = a_get_gamma_b( handle );
|
||||
}
|
||||
r_gamma( dh->dn, SANE_FIX( 0.05 ),
|
||||
rg,gg,bg );
|
||||
|
||||
/* set shading */
|
||||
r_null_shading( dh->dn );
|
||||
|
||||
/* set offset */
|
||||
{
|
||||
SANE_Int offs_x = 0;
|
||||
SANE_Int offs_y = 0;
|
||||
|
||||
switch( ccd_res )
|
||||
{
|
||||
case 300:
|
||||
offs_x = dh->cal_300.offs_x;
|
||||
offs_y = dh->cal_300.offs_y;
|
||||
break;
|
||||
case 600:
|
||||
offs_x = dh->cal_600.offs_x;
|
||||
offs_y = dh->cal_600.offs_y;
|
||||
break;
|
||||
case 1200:
|
||||
offs_x = dh->cal_1200.offs_x;
|
||||
offs_y = dh->cal_1200.offs_y;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
r_offset( dh->dn, offs_x, offs_y );
|
||||
}
|
||||
|
||||
/* start scan */
|
||||
|
||||
res = a_get_resolution( handle );
|
||||
n_lines = a_lines( handle );
|
||||
|
||||
if ( a_get_resolution( handle ) == 75 )
|
||||
{
|
||||
n_lines += ( n_lines + 2 ) / 3 + 1;
|
||||
}
|
||||
|
||||
if ( a_get_mode_e( handle ) == OPT_MODE_COLOR )
|
||||
{
|
||||
c = 3;
|
||||
m = 3;
|
||||
n_lines += 48*res/1200;
|
||||
if ( a_get_resolution( handle ) == 75 )
|
||||
{
|
||||
n_lines += ( n_lines + 2 ) / 3 + 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
c = a_get_gray_color_e( handle );
|
||||
m = 1;
|
||||
}
|
||||
|
||||
if ( a_get_resolution( handle ) == 1200 )
|
||||
{
|
||||
n_lines += 4;
|
||||
}
|
||||
|
||||
width = a_pixels_per_line( handle );
|
||||
|
||||
status = r_scan( dh->dn,
|
||||
res,
|
||||
a_get_tl_x_pix( handle ),
|
||||
width,
|
||||
a_get_tl_y_pix( handle ),
|
||||
n_lines,
|
||||
c
|
||||
);
|
||||
|
||||
if ( status != SANE_STATUS_GOOD )
|
||||
{
|
||||
DBG( D_ERR, "Can't start scan\n" );
|
||||
close( dh->scan_pipe[1] );
|
||||
return 0;
|
||||
}
|
||||
|
||||
rbuf = malloc( 0x10000 );
|
||||
/* in loop read all bytes */
|
||||
n_bytes_r = n_lines * width * m;
|
||||
while ( n_bytes_r > 0 )
|
||||
{
|
||||
n_bytes = n_bytes_r;
|
||||
if ( n_bytes > 0x10000 )
|
||||
{
|
||||
n_bytes = 0x10000;
|
||||
}
|
||||
|
||||
len = ( n_bytes + 511 ) & ~511;
|
||||
DBG( D_INFO, ">>Bytes left %d now reading %d bytes\n",
|
||||
n_bytes_r, n_bytes );
|
||||
|
||||
status = u_bulk_read( dh->dn, rbuf, &len );
|
||||
|
||||
n_bytes = len;
|
||||
if ( status != SANE_STATUS_GOOD || len != n_bytes )
|
||||
{
|
||||
DBG( D_ERR, "Can't read scan data (status %d len %d of %d)\n",
|
||||
status, len, n_bytes );
|
||||
break;
|
||||
}
|
||||
|
||||
write( dh->scan_pipe[1], rbuf, n_bytes );
|
||||
|
||||
if ( n_bytes > n_bytes_r )
|
||||
{
|
||||
n_bytes_r = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
n_bytes_r -= n_bytes;
|
||||
}
|
||||
}
|
||||
|
||||
/* reset scanner */
|
||||
r_reset( dh->dn );
|
||||
r_home( dh->dn );
|
||||
|
||||
free( rbuf );
|
||||
}
|
||||
|
||||
close( dh->scan_pipe[1] );
|
||||
DBG( D_INFO, "Scan thread exiting\n" );
|
||||
return 0;
|
||||
}
|
||||
|
||||
/************************************************************************
|
||||
* Unstaggerer
|
||||
************************************************************************/
|
||||
|
||||
void unstagger_gray( int width, int length );
|
||||
void unstagger_color( int width, int length, int res );
|
||||
void unstagger_color_2( int width, int length );
|
||||
|
||||
void s_unstagger( SANE_Handle handle,
|
||||
SANE_Byte * data,
|
||||
SANE_Int max_length,
|
||||
SANE_Int * length )
|
||||
{
|
||||
int res;
|
||||
int gray;
|
||||
DEVICE_H dh = handle;
|
||||
SCAN_T *scan;
|
||||
int in_pipe;
|
||||
|
||||
scan = &(dh->scan);
|
||||
in_pipe = dh->scan_pipe[0];
|
||||
|
||||
gray = 1;
|
||||
if ( a_get_mode_e( handle ) == OPT_MODE_COLOR )
|
||||
{
|
||||
gray = 0;
|
||||
}
|
||||
res = a_get_resolution( handle );
|
||||
|
||||
*length = 0;
|
||||
|
||||
while ( a_lines_left( scan ) && *length != max_length )
|
||||
{
|
||||
DBG( D_INFO, ">> line %d length %d\n", scan->current_line, *length );
|
||||
*length += a_read_from_scan( scan,
|
||||
&data[*length],
|
||||
max_length - *length );
|
||||
|
||||
if ( a_line_empty( scan ) )
|
||||
{
|
||||
if ( gray )
|
||||
{
|
||||
while ( a_space_in_fifo( scan->r ) )
|
||||
{
|
||||
a_write_to_fifo( scan->r, in_pipe );
|
||||
}
|
||||
|
||||
if ( res == 1200 )
|
||||
{
|
||||
a_read_from_fifo_g_2( scan );
|
||||
}
|
||||
else
|
||||
{
|
||||
a_read_from_fifo_g( scan );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( res == 75 && ( scan->current_line & 3 ) == 3 )
|
||||
{
|
||||
a_read_idx_inc( scan->r );
|
||||
a_read_idx_inc( scan->g );
|
||||
a_read_idx_inc( scan->b );
|
||||
}
|
||||
while ( a_space_in_fifo( scan->r ) ||
|
||||
a_space_in_fifo( scan->g ) ||
|
||||
a_space_in_fifo( scan->b ) )
|
||||
{
|
||||
if ( !a_space_in_fifo( scan->r ) )
|
||||
{
|
||||
a_read_idx_inc( scan->r );
|
||||
}
|
||||
if ( !a_space_in_fifo( scan->g ) )
|
||||
{
|
||||
a_read_idx_inc( scan->g );
|
||||
}
|
||||
a_write_to_fifo( scan->r, in_pipe );
|
||||
a_write_to_fifo( scan->g, in_pipe );
|
||||
a_write_to_fifo( scan->b, in_pipe );
|
||||
}
|
||||
|
||||
if ( res == 1200 )
|
||||
{
|
||||
a_read_from_fifos_c_2( scan );
|
||||
}
|
||||
else
|
||||
{
|
||||
a_read_from_fifos_c( scan );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,84 @@
|
|||
/* sane - Scanner Access Now Easy.
|
||||
Copyright (C) 2006 Lauri Pirttiaho <lauri.pirttiaho@cornell.edu>
|
||||
|
||||
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; either version 2 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston,
|
||||
MA 02111-1307, USA.
|
||||
|
||||
As a special exception, the authors of SANE give permission for
|
||||
additional uses of the libraries contained in this release of SANE.
|
||||
|
||||
The exception is that, if you link a SANE library with other files
|
||||
to produce an executable, this does not by itself cause the
|
||||
resulting executable to be covered by the GNU General Public
|
||||
License. Your use of that executable is in no way restricted on
|
||||
account of linking the SANE library code into it.
|
||||
|
||||
This exception does not, however, invalidate any other reasons why
|
||||
the executable file might be covered by the GNU General Public
|
||||
License.
|
||||
|
||||
If you submit changes to SANE to the maintainers to be included in
|
||||
a subsequent release, you agree by submitting the changes that
|
||||
those changes may be distributed with this exception intact.
|
||||
|
||||
If you write modifications of your own for SANE, it is your choice
|
||||
whether to permit this exception to apply to your modifications.
|
||||
If you do not wish that, delete this exception notice.
|
||||
|
||||
This backend is for CanoScan 3200F.
|
||||
*/
|
||||
|
||||
#ifndef CS3200F_SCAN_H
|
||||
#define CS3200F_SCAN_H
|
||||
|
||||
#include "../include/sane/sane.h"
|
||||
|
||||
/***********************************************************************
|
||||
* Interface
|
||||
***********************************************************************/
|
||||
|
||||
/** Get scanning parameters
|
||||
* @param handle handle of the device
|
||||
* @param params pointer to the parameter structure
|
||||
* @return status
|
||||
*/
|
||||
SANE_Status s_get_params( SANE_Handle handle,
|
||||
SANE_Parameters * params );
|
||||
|
||||
/** Start scanning with the current options
|
||||
* @param handle handle of the device
|
||||
* @return status
|
||||
*/
|
||||
SANE_Status s_scan_start( SANE_Handle handle );
|
||||
|
||||
/** Read scan data
|
||||
*/
|
||||
SANE_Status
|
||||
s_scan_read( SANE_Handle handle,
|
||||
SANE_Byte * data,
|
||||
SANE_Int max_length,
|
||||
SANE_Int * length );
|
||||
|
||||
|
||||
/** Cancel scanning
|
||||
*/
|
||||
void
|
||||
s_scan_cancel( SANE_Handle handle );
|
||||
|
||||
|
||||
|
||||
#endif /* ndef CS3200F_SCAN_H */
|
|
@ -0,0 +1,514 @@
|
|||
/* sane - Scanner Access Now Easy.
|
||||
Copyright (C) 2006 Lauri Pirttiaho <lauri.pirttiaho@cornell.edu>
|
||||
|
||||
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; either version 2 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston,
|
||||
MA 02111-1307, USA.
|
||||
|
||||
As a special exception, the authors of SANE give permission for
|
||||
additional uses of the libraries contained in this release of SANE.
|
||||
|
||||
The exception is that, if you link a SANE library with other files
|
||||
to produce an executable, this does not by itself cause the
|
||||
resulting executable to be covered by the GNU General Public
|
||||
License. Your use of that executable is in no way restricted on
|
||||
account of linking the SANE library code into it.
|
||||
|
||||
This exception does not, however, invalidate any other reasons why
|
||||
the executable file might be covered by the GNU General Public
|
||||
License.
|
||||
|
||||
If you submit changes to SANE to the maintainers to be included in
|
||||
a subsequent release, you agree by submitting the changes that
|
||||
those changes may be distributed with this exception intact.
|
||||
|
||||
If you write modifications of your own for SANE, it is your choice
|
||||
whether to permit this exception to apply to your modifications.
|
||||
If you do not wish that, delete this exception notice.
|
||||
|
||||
This backend is for CanoScan 3200F.
|
||||
*/
|
||||
|
||||
#include "cs3200f-usb.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "../include/sane/sanei.h"
|
||||
#include "../include/sane/sanei_usb.h"
|
||||
|
||||
/***********************************************************************
|
||||
* local prototypes
|
||||
***********************************************************************/
|
||||
|
||||
/** Check if the device is connected via high speed USB
|
||||
* @param dn usb device number
|
||||
* @return SANE_TRUE if connected via USB HS, else SANE_FALSE
|
||||
*/
|
||||
static SANE_Bool
|
||||
is_hs( SANE_Int dn );
|
||||
|
||||
/***********************************************************************
|
||||
* Basic interface functions
|
||||
***********************************************************************/
|
||||
|
||||
SANE_Status
|
||||
u_open( DEVICE_T *dev )
|
||||
{
|
||||
SANE_Status status;
|
||||
|
||||
DBG( D_CALL, "u_open( dev = %08X )\n", (unsigned int)dev );
|
||||
|
||||
status = sanei_usb_open( dev->name, &(dev->dn) );
|
||||
|
||||
if ( status != SANE_STATUS_GOOD )
|
||||
{
|
||||
DBG( D_ERR, "sanei_usb_open() failed with status %d\n", status );
|
||||
return status;
|
||||
}
|
||||
|
||||
dev->open = SANE_TRUE;
|
||||
|
||||
dev->hs = is_hs( dev->dn );
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
void
|
||||
u_close( DEVICE_T *dev )
|
||||
{
|
||||
DBG( D_CALL, "u_close( dev = %08X )\n", (unsigned int)dev );
|
||||
|
||||
if ( dev->open ) {
|
||||
sanei_usb_close( dev->dn );
|
||||
}
|
||||
|
||||
dev->open = SANE_FALSE;
|
||||
|
||||
}
|
||||
|
||||
SANE_Byte
|
||||
u_byte_read( SANE_Int dn,
|
||||
SANE_Int value,
|
||||
SANE_Int index )
|
||||
{
|
||||
SANE_Byte data;
|
||||
SANE_Status status;
|
||||
|
||||
DBG( D_CALL, "u_byte_read( dn = %d, value = %04X, index = %04X )\n",
|
||||
dn, value, index );
|
||||
|
||||
status = sanei_usb_control_msg( dn,
|
||||
USB_DIR_IN
|
||||
| USB_TYPE_VENDOR
|
||||
| USB_RECIP_DEVICE,
|
||||
0x0c,
|
||||
value,
|
||||
index,
|
||||
1,
|
||||
&data );
|
||||
|
||||
if ( status != SANE_STATUS_GOOD )
|
||||
{
|
||||
DBG( D_ERR, "u_byte_read() failed\n" );
|
||||
return 0;
|
||||
}
|
||||
|
||||
DBG( D_RES, "return: %2X\n", (unsigned int) data );
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
void
|
||||
u_byte_write( SANE_Int dn,
|
||||
SANE_Int value,
|
||||
SANE_Int index,
|
||||
SANE_Byte data )
|
||||
{
|
||||
SANE_Byte data_out[2] = { 0, 0 };
|
||||
SANE_Status status;
|
||||
|
||||
DBG( D_CALL, "u_byte_write( dn = %d, value = %04X,"
|
||||
" index = %04X, data = %02X )\n",
|
||||
dn, value, index, data );
|
||||
|
||||
data_out[0] = data;
|
||||
|
||||
status = sanei_usb_control_msg( dn,
|
||||
USB_DIR_OUT
|
||||
| USB_TYPE_VENDOR
|
||||
| USB_RECIP_DEVICE,
|
||||
0x04,
|
||||
value,
|
||||
index,
|
||||
2,
|
||||
data_out );
|
||||
|
||||
if ( status != SANE_STATUS_GOOD )
|
||||
{
|
||||
DBG( D_ERR, "u_byte_write() failed\n" );
|
||||
}
|
||||
}
|
||||
|
||||
SANE_Status
|
||||
u_read( SANE_Int dn,
|
||||
SANE_Int value,
|
||||
SANE_Int index,
|
||||
SANE_Byte *data,
|
||||
SANE_Int len )
|
||||
{
|
||||
SANE_Status status;
|
||||
|
||||
DBG( D_CALL, "u_read( dn = %d, value = %04X, index = %04X,"
|
||||
" data = %08X, len = %d, len )\n",
|
||||
dn, value, index, (unsigned int)data, len );
|
||||
|
||||
status = sanei_usb_control_msg( dn,
|
||||
USB_DIR_IN
|
||||
| USB_TYPE_VENDOR
|
||||
| USB_RECIP_DEVICE,
|
||||
0x04,
|
||||
value,
|
||||
index,
|
||||
len,
|
||||
data );
|
||||
|
||||
if ( status != SANE_STATUS_GOOD )
|
||||
{
|
||||
DBG( D_ERR, "u_read() failed\n" );
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
SANE_Status
|
||||
u_write( SANE_Int dn,
|
||||
SANE_Int value,
|
||||
SANE_Int index,
|
||||
SANE_Byte *data,
|
||||
SANE_Int len )
|
||||
{
|
||||
SANE_Status status;
|
||||
|
||||
DBG( D_CALL, "u_write( dn = %d, value = %04X, index = %04X,"
|
||||
" data = %08X, len = %d )\n",
|
||||
dn, value, index, (unsigned int)data, len);
|
||||
|
||||
if ( data[len-1] != 0 )
|
||||
{
|
||||
DBG( D_WARN, "The last byte of the control write should be \\0\n" );
|
||||
}
|
||||
|
||||
status = sanei_usb_control_msg( dn,
|
||||
USB_DIR_OUT
|
||||
| USB_TYPE_VENDOR
|
||||
| USB_RECIP_DEVICE,
|
||||
0x04,
|
||||
value,
|
||||
index,
|
||||
len,
|
||||
data );
|
||||
|
||||
if ( status != SANE_STATUS_GOOD )
|
||||
{
|
||||
DBG( D_ERR, "u_write() failed\n" );
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
SANE_Status
|
||||
u_bulk_read( SANE_Int dn,
|
||||
SANE_Byte *data,
|
||||
size_t *len )
|
||||
{
|
||||
SANE_Status status;
|
||||
int retry;
|
||||
size_t len_read;
|
||||
size_t len_remaining;
|
||||
|
||||
DBG( D_CALL, "u_bulk_read( dn = %d, data = %08X, len = %d )\n",
|
||||
dn, (unsigned int)data, (int)(*len) );
|
||||
|
||||
#define RETRY_COUNT 60
|
||||
|
||||
len_read = 0;
|
||||
|
||||
for ( retry = 0; retry < RETRY_COUNT; retry++ )
|
||||
{
|
||||
len_remaining = *len - len_read;
|
||||
status = sanei_usb_read_bulk( dn, data+len_read, &len_remaining );
|
||||
len_read += len_remaining;
|
||||
if ( status != SANE_STATUS_IO_ERROR )
|
||||
{
|
||||
break;
|
||||
}
|
||||
usleep( 10000 );
|
||||
/* allow 10 ms for the device to catch up, then try again */
|
||||
}
|
||||
|
||||
*len = len_read;
|
||||
|
||||
if ( status != SANE_STATUS_GOOD )
|
||||
{
|
||||
DBG( D_ERR, "u_bulk_read() failed\n" );
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
SANE_Status
|
||||
u_bulk_write( SANE_Int dn,
|
||||
SANE_Byte *data,
|
||||
size_t *len )
|
||||
{
|
||||
SANE_Status status;
|
||||
|
||||
DBG( D_CALL, "u_bulk_write( dn = %d, data = %08X, len = %d )\n",
|
||||
dn, (unsigned int)data, *len );
|
||||
|
||||
status = sanei_usb_write_bulk( dn, data, len );
|
||||
|
||||
if ( status != SANE_STATUS_GOOD )
|
||||
{
|
||||
DBG( D_ERR, "u_bulk_write() failed\n" );
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
SANE_Status
|
||||
u_mem_read( SANE_Int dn,
|
||||
SANE_Int addr,
|
||||
SANE_Byte *data,
|
||||
size_t *len )
|
||||
{
|
||||
SANE_Status status;
|
||||
SANE_Byte saddr[5];
|
||||
SANE_Byte slen[4];
|
||||
int i;
|
||||
|
||||
DBG( D_CALL, "u_mem_read( dn = %d, addr = %08X, data = %08X, len = %d )\n",
|
||||
dn, addr, (unsigned int)data, (int)(*len));
|
||||
|
||||
if ( ( addr & 0xf ) != 0 )
|
||||
{
|
||||
DBG( D_ERR, "Error: address must be multiple of 16\n" );
|
||||
return SANE_STATUS_INVAL;
|
||||
}
|
||||
|
||||
if ( ( addr & 0x3f ) != 0 )
|
||||
{
|
||||
DBG( D_ERR, "Error: length must be multiple of 64\n" );
|
||||
return SANE_STATUS_INVAL;
|
||||
}
|
||||
|
||||
for ( i = 0; i < 4; i++ )
|
||||
{
|
||||
saddr[i] = ( addr >> (8*i+1) ) & 0xff;
|
||||
}
|
||||
saddr[4] = 0;
|
||||
|
||||
for ( i = 0; i < 3; i++ )
|
||||
{
|
||||
slen[i] = ( (SANE_Int)(*len) >> (8*i+1) ) & 0xff;
|
||||
}
|
||||
slen[3] = 0;
|
||||
|
||||
status = u_state_q( dn );
|
||||
status = u_write( dn, 0x00f0, 0x0000, saddr, 5 );
|
||||
|
||||
if ( status != SANE_STATUS_GOOD )
|
||||
{
|
||||
DBG( D_ERR, "Can't set address\n" );
|
||||
return status;
|
||||
}
|
||||
|
||||
status = u_state_q( dn );
|
||||
status = u_write( dn, 0x00f4, 0x0000, slen, 4 );
|
||||
|
||||
if ( status != SANE_STATUS_GOOD )
|
||||
{
|
||||
DBG( D_ERR, "Can't set length\n" );
|
||||
return status;
|
||||
}
|
||||
|
||||
status = u_bulk_read( dn, data, len );
|
||||
|
||||
if ( status != SANE_STATUS_GOOD )
|
||||
{
|
||||
DBG( D_ERR, "u_mem_read() failed\n" );
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
SANE_Status
|
||||
u_mem_write( SANE_Int dn,
|
||||
SANE_Int addr,
|
||||
SANE_Byte *data,
|
||||
size_t *len )
|
||||
{
|
||||
SANE_Status status;
|
||||
SANE_Byte saddr[5];
|
||||
SANE_Byte slen[4];
|
||||
int i;
|
||||
|
||||
DBG( D_CALL, "u_mem_write( dn = %d, addr = %08X, data = %08X, len = %d )\n",
|
||||
dn, addr, (unsigned int)data, (int)(*len) );
|
||||
|
||||
if ( ( addr & 0xf ) != 0 )
|
||||
{
|
||||
DBG( D_ERR, "Error: address must be multiple of 16\n" );
|
||||
return SANE_STATUS_INVAL;
|
||||
}
|
||||
|
||||
if ( ( addr & 0xf ) != 0 )
|
||||
{
|
||||
DBG( D_ERR, "Error: length must be multiple of 16\n" );
|
||||
return SANE_STATUS_INVAL;
|
||||
}
|
||||
|
||||
for ( i = 0; i < 4; i++ )
|
||||
{
|
||||
saddr[i] = ( addr >> (8*i+1) ) & 0xff;
|
||||
}
|
||||
saddr[4] = 0;
|
||||
|
||||
for ( i = 0; i < 3; i++ )
|
||||
{
|
||||
slen[i] = ( (SANE_Int)(*len) >> (8*i+1) ) & 0xff;
|
||||
}
|
||||
slen[3] = 0;
|
||||
|
||||
status = u_state_q( dn );
|
||||
status = u_write( dn, 0x00f0, 0x0000, saddr, 5 );
|
||||
|
||||
if ( status != SANE_STATUS_GOOD )
|
||||
{
|
||||
DBG( D_ERR, "Can't set address\n" );
|
||||
return status;
|
||||
}
|
||||
|
||||
status = u_state_q( dn );
|
||||
status = u_write( dn, 0x00f3, 0x0000, slen, 4 );
|
||||
|
||||
if ( status != SANE_STATUS_GOOD )
|
||||
{
|
||||
DBG( D_ERR, "Can't set length\n" );
|
||||
return status;
|
||||
}
|
||||
|
||||
status = u_bulk_write( dn, data, len );
|
||||
|
||||
if ( status != SANE_STATUS_GOOD )
|
||||
{
|
||||
DBG( D_ERR, "u_mem_write() failed\n" );
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* Applied interface functions
|
||||
***********************************************************************/
|
||||
|
||||
SANE_Byte
|
||||
u_b_r( SANE_Int dn, SANE_Int addr )
|
||||
{
|
||||
return u_byte_read( dn, 0x00e1, addr );
|
||||
}
|
||||
|
||||
void
|
||||
u_b_w( SANE_Int dn, SANE_Int addr, SANE_Byte data )
|
||||
{
|
||||
u_byte_write( dn, 0x00e0, addr, data );
|
||||
}
|
||||
|
||||
SANE_Byte
|
||||
u_state_q( SANE_Int dn )
|
||||
{
|
||||
/* TODO: the original driver sometimes queries 2 and sometimes 4 bytes. */
|
||||
SANE_Byte status[2] = { 0 };
|
||||
|
||||
(void)u_read( dn, 0x0040, 0, status, sizeof(status) );
|
||||
|
||||
return status[0];
|
||||
}
|
||||
|
||||
SANE_Bool
|
||||
u_home_q( SANE_Int dn )
|
||||
{
|
||||
SANE_Byte status[2] = { 0, 0 };
|
||||
|
||||
(void)u_read( dn, 0x0040, 0, status, 2 );
|
||||
|
||||
return status[1]?SANE_FALSE:SANE_TRUE;
|
||||
}
|
||||
|
||||
SANE_Int
|
||||
u_line_q( SANE_Int dn )
|
||||
{
|
||||
SANE_Byte status[4] = { 0, 0, 0, 0 };
|
||||
|
||||
(void)u_read( dn, 0x0040, 0, status, 4 );
|
||||
|
||||
return ( ( (SANE_Int)status[2] & 0xFF ) << 8 ) +
|
||||
( (SANE_Int)status[3] & 0xFF );
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* local utilities
|
||||
***********************************************************************/
|
||||
|
||||
static SANE_Bool
|
||||
is_hs( SANE_Int dn )
|
||||
{
|
||||
SANE_Byte device_descriptor[ USB_DT_DEVICE_SIZE ];
|
||||
SANE_Status status;
|
||||
|
||||
DBG( D_CALL, "is_hs( dn = %d )\n", dn );
|
||||
|
||||
status = sanei_usb_control_msg( dn,
|
||||
USB_DIR_IN
|
||||
| USB_TYPE_STANDARD
|
||||
| USB_RECIP_DEVICE,
|
||||
USB_REQ_GET_DESCRIPTOR,
|
||||
( USB_DT_DEVICE << 8 ),
|
||||
0,
|
||||
USB_DT_DEVICE_SIZE,
|
||||
device_descriptor );
|
||||
|
||||
if ( status != SANE_STATUS_GOOD )
|
||||
{
|
||||
DBG( D_ERR, "xFailed to get device descriptor\n" );
|
||||
return SANE_FALSE;
|
||||
}
|
||||
|
||||
DBG( D_RES, "USB interface version %X.%02X\n",
|
||||
device_descriptor[3], device_descriptor[2]);
|
||||
|
||||
if ( device_descriptor[3] == 2 )
|
||||
{
|
||||
return SANE_TRUE;
|
||||
}
|
||||
|
||||
return SANE_FALSE;
|
||||
}
|
||||
|
||||
/************************************************************************
|
||||
* $Id: cs3200f-usb.c,v 1.4 2006/05/30 18:10:45 lapi-guest Exp $
|
||||
************************************************************************/
|
|
@ -0,0 +1,215 @@
|
|||
/* sane - Scanner Access Now Easy.
|
||||
Copyright (C) 2006 Lauri Pirttiaho <lauri.pirttiaho@cornell.edu>
|
||||
|
||||
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; either version 2 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston,
|
||||
MA 02111-1307, USA.
|
||||
|
||||
As a special exception, the authors of SANE give permission for
|
||||
additional uses of the libraries contained in this release of SANE.
|
||||
|
||||
The exception is that, if you link a SANE library with other files
|
||||
to produce an executable, this does not by itself cause the
|
||||
resulting executable to be covered by the GNU General Public
|
||||
License. Your use of that executable is in no way restricted on
|
||||
account of linking the SANE library code into it.
|
||||
|
||||
This exception does not, however, invalidate any other reasons why
|
||||
the executable file might be covered by the GNU General Public
|
||||
License.
|
||||
|
||||
If you submit changes to SANE to the maintainers to be included in
|
||||
a subsequent release, you agree by submitting the changes that
|
||||
those changes may be distributed with this exception intact.
|
||||
|
||||
If you write modifications of your own for SANE, it is your choice
|
||||
whether to permit this exception to apply to your modifications.
|
||||
If you do not wish that, delete this exception notice.
|
||||
|
||||
This backend is for CanoScan 3200F.
|
||||
*/
|
||||
|
||||
#ifndef CS3200F_USB_H
|
||||
#define CS3200F_USB_H
|
||||
|
||||
#include "../include/sane/sane.h"
|
||||
|
||||
/***********************************************************************
|
||||
* Basic interface functions
|
||||
***********************************************************************/
|
||||
|
||||
/** Open the scanner
|
||||
* @param dev the device to be opened
|
||||
* @return status of the opening
|
||||
*/
|
||||
SANE_Status
|
||||
u_open( DEVICE_T *dev );
|
||||
|
||||
/** Close the scanner
|
||||
* @param dev the device to be close
|
||||
*/
|
||||
void
|
||||
u_close( DEVICE_T *dev );
|
||||
|
||||
/** Read one byte from the scanner
|
||||
* @param dn device number of the scanner
|
||||
* @param value wValue of the control transfer
|
||||
* @param index wIndex of the control transfer
|
||||
* @return the byte read
|
||||
*/
|
||||
SANE_Byte
|
||||
u_byte_read( SANE_Int dn,
|
||||
SANE_Int value,
|
||||
SANE_Int index );
|
||||
|
||||
/** Write one byte to the scanner
|
||||
* @param dn device number of the scanner
|
||||
* @param value wValue of the control transfer
|
||||
* @param index wIndex of the control transfer
|
||||
* @param data the byte to be written
|
||||
*/
|
||||
void
|
||||
u_byte_write( SANE_Int dn,
|
||||
SANE_Int value,
|
||||
SANE_Int index,
|
||||
SANE_Byte data );
|
||||
|
||||
/** Read bytes from the scanner
|
||||
* @param dn device number of the scanner
|
||||
* @param value wValue of the control transfer
|
||||
* @param index wIndex of the control transfer
|
||||
* @param data pointer to the data buffer
|
||||
* @param len number of bytes to read
|
||||
* @return status of the read
|
||||
*/
|
||||
SANE_Status
|
||||
u_read( SANE_Int dn,
|
||||
SANE_Int value,
|
||||
SANE_Int index,
|
||||
SANE_Byte *data,
|
||||
SANE_Int len );
|
||||
|
||||
/** Write bytes to the scanner
|
||||
* @param dn device number of the scanner
|
||||
* @param value wValue of the control transfer
|
||||
* @param index wIndex of the control transfer
|
||||
* @param data the byte to be written
|
||||
* @param len number of bytes to write
|
||||
* @note The last byte of the data must be 0!
|
||||
*/
|
||||
SANE_Status
|
||||
u_write( SANE_Int dn,
|
||||
SANE_Int value,
|
||||
SANE_Int index,
|
||||
SANE_Byte *data,
|
||||
SANE_Int len );
|
||||
|
||||
/** Bulk read bytes from the scanner
|
||||
* @param dn device number of the scanner
|
||||
* @param data pointer to the data buffer
|
||||
* @param len pointer to the number of bytes to read;
|
||||
* after return the number indicates bytes read
|
||||
* @return status of the read
|
||||
*/
|
||||
SANE_Status
|
||||
u_bulk_read( SANE_Int dn,
|
||||
SANE_Byte *data,
|
||||
size_t *len );
|
||||
|
||||
/** Bulk write bytes to the scanner
|
||||
* @param dn device number of the scanner
|
||||
* @param data pointer to the data buffer
|
||||
* @param len pointer to the number of bytes to write
|
||||
* after return the number indicates bytes written
|
||||
* @return status of the write
|
||||
*/
|
||||
SANE_Status
|
||||
u_bulk_write( SANE_Int dn,
|
||||
SANE_Byte *data,
|
||||
size_t *len );
|
||||
|
||||
/** Read bytes from the scanner memory
|
||||
* @param dn device number of the scanner
|
||||
* @param addr address to read from
|
||||
* @param data pointer to the data buffer
|
||||
* @param len pointer to the number of bytes to read;
|
||||
* after return the number indicates bytes read
|
||||
* @return status of the read
|
||||
* @note Address must be multiple of 16 and length multiple of 64!
|
||||
*/
|
||||
SANE_Status
|
||||
u_mem_read( SANE_Int dn,
|
||||
SANE_Int addr,
|
||||
SANE_Byte *data,
|
||||
size_t *len );
|
||||
|
||||
/** Write bytes to the scanner memory
|
||||
* @param dn device number of the scanner
|
||||
* @param addr address to write to
|
||||
* @param data pointer to the data buffer
|
||||
* @param len poiter to the number of bytes to write;
|
||||
* after return the number indicates bytes written
|
||||
* @return status of the write
|
||||
* @note Address and length must be multiples of 16!
|
||||
*/
|
||||
SANE_Status
|
||||
u_mem_write( SANE_Int dn,
|
||||
SANE_Int addr,
|
||||
SANE_Byte *data,
|
||||
size_t *len );
|
||||
|
||||
/***********************************************************************
|
||||
* Applied interface functions
|
||||
***********************************************************************/
|
||||
|
||||
/** Read a byte from the scanner memory
|
||||
* @param dn the device number of the scanner
|
||||
* @param addr address to read form
|
||||
* @return the byte or 0 in failure
|
||||
*/
|
||||
SANE_Byte
|
||||
u_b_r( SANE_Int dn, SANE_Int addr );
|
||||
|
||||
/** Write a byte from the scanner memory
|
||||
* @param dn the device number of the scanner
|
||||
* @param addr address to read form
|
||||
* @param data the byte to write
|
||||
*/
|
||||
void
|
||||
u_b_w( SANE_Int dn, SANE_Int addr, SANE_Byte data );
|
||||
|
||||
/** Query the scan engine state
|
||||
* @param dn the device number of the scanner
|
||||
* @return the state
|
||||
*/
|
||||
SANE_Byte
|
||||
u_state_q( SANE_Int dn );
|
||||
|
||||
/** Query if the scanner cartridge is at home
|
||||
* @param dn the device number of the scanner
|
||||
* @return the home status
|
||||
*/
|
||||
SANE_Bool
|
||||
u_home_q( SANE_Int dn );
|
||||
|
||||
/** Query the scanner cartridge position (in 1200 dpi lines)
|
||||
* @param dn the device number of the scanner
|
||||
* @return the line number
|
||||
*/
|
||||
SANE_Int
|
||||
u_line_q( SANE_Int dn );
|
||||
|
||||
#endif /* ndef CS3200F_USB_H */
|
|
@ -0,0 +1,313 @@
|
|||
/* sane - Scanner Access Now Easy.
|
||||
Copyright (C) 2006 Lauri Pirttiaho <lauri.pirttiaho@cornell.edu>
|
||||
|
||||
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; either version 2 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston,
|
||||
MA 02111-1307, USA.
|
||||
|
||||
As a special exception, the authors of SANE give permission for
|
||||
additional uses of the libraries contained in this release of SANE.
|
||||
|
||||
The exception is that, if you link a SANE library with other files
|
||||
to produce an executable, this does not by itself cause the
|
||||
resulting executable to be covered by the GNU General Public
|
||||
License. Your use of that executable is in no way restricted on
|
||||
account of linking the SANE library code into it.
|
||||
|
||||
This exception does not, however, invalidate any other reasons why
|
||||
the executable file might be covered by the GNU General Public
|
||||
License.
|
||||
|
||||
If you submit changes to SANE to the maintainers to be included in
|
||||
a subsequent release, you agree by submitting the changes that
|
||||
those changes may be distributed with this exception intact.
|
||||
|
||||
If you write modifications of your own for SANE, it is your choice
|
||||
whether to permit this exception to apply to your modifications.
|
||||
If you do not wish that, delete this exception notice.
|
||||
|
||||
This backend is for CanoScan 3200F.
|
||||
*/
|
||||
|
||||
#define BACKEND_NAME cs3200f
|
||||
|
||||
#include "../include/sane/config.h"
|
||||
#include "../include/sane/sane.h"
|
||||
#include "../include/sane/sanei_backend.h"
|
||||
#include "../include/sane/sanei_debug.h"
|
||||
#include "../include/sane/sanei_access.h"
|
||||
#include "../include/sane/sanei_usb.h"
|
||||
#include "../include/sane/sanei_thread.h"
|
||||
|
||||
#include "../include/sane/saneopts.h"
|
||||
#include "cs3200f-dat.h"
|
||||
#include "cs3200f-dev.h"
|
||||
#include "cs3200f-opt.h"
|
||||
#include "cs3200f-scan.h"
|
||||
|
||||
/***********************************************************************
|
||||
* Debug info levels
|
||||
***********************************************************************/
|
||||
|
||||
#define D_ERR 1
|
||||
#define D_WARN 2
|
||||
#define D_INFO 3
|
||||
#define D_CALL 4
|
||||
#define D_RES 5
|
||||
|
||||
/***********************************************************************
|
||||
* Library
|
||||
***********************************************************************/
|
||||
|
||||
#define CS_VERSION_MAJOR 1
|
||||
#define CS_VERSION_MINOR 1
|
||||
#define CS_VERSION_BUILD 1
|
||||
|
||||
static const SANE_Int
|
||||
c_version = SANE_VERSION_CODE( CS_VERSION_MAJOR,
|
||||
CS_VERSION_MINOR,
|
||||
CS_VERSION_BUILD );
|
||||
|
||||
SANE_Status
|
||||
sane_init( SANE_Int * version_code,
|
||||
SANE_Auth_Callback authorize )
|
||||
{
|
||||
|
||||
(void)authorize; /* we don't need authorizations */
|
||||
|
||||
DBG_INIT();
|
||||
|
||||
DBG( D_CALL, "sane_init( version_code = %08X, authorize = %08X )\n",
|
||||
(unsigned int)version_code, (unsigned int)authorize );
|
||||
|
||||
sanei_access_init( STRINGIFY(BACKEND_NAME) );
|
||||
sanei_usb_init();
|
||||
sanei_thread_init();
|
||||
|
||||
d_init_devices();
|
||||
|
||||
if ( version_code )
|
||||
{
|
||||
*version_code = c_version;
|
||||
DBG( D_RES, "return version %08X\n", c_version );
|
||||
}
|
||||
|
||||
return SANE_STATUS_GOOD;
|
||||
}
|
||||
|
||||
void
|
||||
sane_exit( void )
|
||||
{
|
||||
DBG( D_CALL, "sane_exit()\n" );
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* Devices
|
||||
***********************************************************************/
|
||||
|
||||
SANE_Status
|
||||
sane_get_devices( const SANE_Device *** device_list,
|
||||
SANE_Bool local_only )
|
||||
{
|
||||
(void)local_only; /* we don't look for remote devices anyway */
|
||||
|
||||
DBG( D_CALL, "sane_get_devices( device_list = %08X, local_only = %d )\n",
|
||||
(unsigned int)device_list, local_only );
|
||||
|
||||
if ( device_list )
|
||||
{
|
||||
*device_list = d_get_devices();
|
||||
}
|
||||
|
||||
return SANE_STATUS_GOOD;
|
||||
}
|
||||
|
||||
SANE_Status
|
||||
sane_open( SANE_String_Const devicename,
|
||||
SANE_Handle * handle )
|
||||
{
|
||||
DBG( D_CALL, "sane_open( devicename = %s, handle = %08X )\n",
|
||||
devicename, (unsigned int)handle );
|
||||
|
||||
return d_open_device( devicename, handle );
|
||||
}
|
||||
|
||||
void
|
||||
sane_close( SANE_Handle handle )
|
||||
{
|
||||
(void)handle;
|
||||
|
||||
DBG( D_CALL, "sane_close( handle = %08X )\n",
|
||||
(unsigned int)handle );
|
||||
|
||||
d_close_device( handle );
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* Options
|
||||
***********************************************************************/
|
||||
|
||||
const SANE_Option_Descriptor *
|
||||
sane_get_option_descriptor( SANE_Handle handle,
|
||||
SANE_Int option )
|
||||
{
|
||||
const SANE_Option_Descriptor * od;
|
||||
|
||||
(void)handle;
|
||||
|
||||
DBG( D_CALL, "sane_get_option_descriptor( handle = %08X, option = %d )\n",
|
||||
(unsigned int)handle, option );
|
||||
|
||||
od = o_opt_desc( handle, option );
|
||||
|
||||
if ( od )
|
||||
{
|
||||
DBG( D_RES, "return option descriptor for %s\n", od->title );
|
||||
}
|
||||
else
|
||||
{
|
||||
DBG( D_ERR, "no option descriptor to return\n" );
|
||||
}
|
||||
|
||||
return od;
|
||||
}
|
||||
|
||||
SANE_Status
|
||||
sane_control_option( SANE_Handle handle,
|
||||
SANE_Int option,
|
||||
SANE_Action action,
|
||||
void *value,
|
||||
SANE_Int * info )
|
||||
{
|
||||
(void)handle;
|
||||
(void)option;
|
||||
(void)info;
|
||||
|
||||
DBG( D_CALL, "sane_control_option( handle = %08X, option = %d, "
|
||||
"action = %d, value = %08X, info = %08X)\n",
|
||||
(unsigned int)handle, option, action,
|
||||
(unsigned int)value, (unsigned int)info );
|
||||
|
||||
switch ( action )
|
||||
{
|
||||
case SANE_ACTION_GET_VALUE:
|
||||
return o_opt_get( handle, option, value );
|
||||
case SANE_ACTION_SET_VALUE:
|
||||
return o_opt_set( handle, option, value, info );
|
||||
case SANE_ACTION_SET_AUTO:
|
||||
return SANE_STATUS_UNSUPPORTED;
|
||||
default:
|
||||
return SANE_STATUS_INVAL;
|
||||
}
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* Scanning
|
||||
***********************************************************************/
|
||||
|
||||
SANE_Status
|
||||
sane_get_parameters( SANE_Handle handle,
|
||||
SANE_Parameters * params )
|
||||
{
|
||||
DBG( D_CALL, "sane_get_parameters( handle = %08X, params = %08X )\n",
|
||||
(unsigned int)handle, (unsigned int)params );
|
||||
|
||||
return s_get_params( handle, params );
|
||||
}
|
||||
|
||||
SANE_Status
|
||||
sane_start( SANE_Handle handle )
|
||||
{
|
||||
DBG( D_CALL, "sane_start( handle = %08X )\n",
|
||||
(unsigned int)handle );
|
||||
|
||||
return s_scan_start( handle );
|
||||
}
|
||||
|
||||
SANE_Status
|
||||
sane_read( SANE_Handle handle,
|
||||
SANE_Byte * data,
|
||||
SANE_Int max_length,
|
||||
SANE_Int * length )
|
||||
{
|
||||
DBG( D_CALL, "sane_read( handle = %08X, data = %08X, "
|
||||
"max_length = %d, length = %08X )\n",
|
||||
(unsigned int)handle, (unsigned int)data,
|
||||
max_length, (unsigned int)length );
|
||||
|
||||
return s_scan_read( handle, data, max_length, length );
|
||||
}
|
||||
|
||||
void
|
||||
sane_cancel( SANE_Handle handle )
|
||||
{
|
||||
DBG( D_CALL, "sane_cancel( handle = %08X )\n",
|
||||
(unsigned int)handle );
|
||||
|
||||
s_scan_cancel( handle );
|
||||
}
|
||||
|
||||
SANE_Status
|
||||
sane_set_io_mode( SANE_Handle handle,
|
||||
SANE_Bool non_blocking )
|
||||
{
|
||||
(void)handle;
|
||||
(void)non_blocking;
|
||||
|
||||
DBG( D_CALL, "sane_set_io_mode( handle = %08X, non_blocking = %d )\n",
|
||||
(unsigned int)handle, non_blocking );
|
||||
|
||||
return SANE_STATUS_UNSUPPORTED;
|
||||
}
|
||||
|
||||
SANE_Status
|
||||
sane_get_select_fd( SANE_Handle handle,
|
||||
SANE_Int * fd )
|
||||
{
|
||||
(void)handle;
|
||||
(void)fd;
|
||||
|
||||
DBG( D_CALL, "sane_get_select_fd( handle = %08X, fd = %08X )\n",
|
||||
(unsigned int)handle, (unsigned int)fd );
|
||||
|
||||
return SANE_STATUS_UNSUPPORTED;
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* Level 2
|
||||
***********************************************************************/
|
||||
|
||||
#include "cs3200f-dev.c"
|
||||
#include "cs3200f-opt.c"
|
||||
#include "cs3200f-scan.c"
|
||||
|
||||
/***********************************************************************
|
||||
* Level 3
|
||||
***********************************************************************/
|
||||
|
||||
#include "cs3200f-drv.c"
|
||||
|
||||
/***********************************************************************
|
||||
* Level 4
|
||||
***********************************************************************/
|
||||
|
||||
#include "cs3200f-dat.c"
|
||||
#include "cs3200f-usb.c"
|
||||
|
||||
/************************************************************************
|
||||
* $Id: cs3200f.c,v 1.2 2006/05/27 18:47:49 lapi-guest Exp $
|
||||
************************************************************************/
|
|
@ -0,0 +1,239 @@
|
|||
************************************************************************
|
||||
* NOTE!
|
||||
************************************************************************
|
||||
|
||||
NOTE! The code in this directory is highly experimental, likely
|
||||
to contain errors, crappy by outlook etc. etc.
|
||||
Also note: because of this: IF YOU DO NOT KNOW WHAT
|
||||
YOU ARE DOING, DON'T USE IT. At best it may give
|
||||
some hint of where the development is going, at
|
||||
worst IT MAY BURN YOUR SCANNER. So, you were warned!
|
||||
|
||||
************************************************************************
|
||||
* Status
|
||||
************************************************************************
|
||||
|
||||
What works in this version is basically the UI and uncalibrated
|
||||
reflective scans at 150/300/600/1200 dpi, 8-bit gray and color.
|
||||
|
||||
Everything else is non-functional or buggy or someting else that
|
||||
makes it useless in practice.
|
||||
|
||||
************************************************************************
|
||||
* Design info
|
||||
************************************************************************
|
||||
|
||||
Files
|
||||
=====
|
||||
|
||||
First level
|
||||
-----------
|
||||
cs3200f.c
|
||||
- identifier prefix c_
|
||||
- contains the SANE interface functions that delegate
|
||||
almost all workings to subsystems
|
||||
- only the library initialization is done here
|
||||
(sane_init implementation intializes trace, usb etc.)
|
||||
- includes interfaces of second level subsystems
|
||||
- includes sources of second level subsystems
|
||||
|
||||
Second level
|
||||
------------
|
||||
cs3200f-dev.[ch]
|
||||
- identifier prefix d_
|
||||
- device handling
|
||||
|
||||
cs3200f-opt.[ch]
|
||||
- identifier prefix o_
|
||||
- option and option descriptor handling
|
||||
|
||||
cs3200f-scan.[ch]
|
||||
- identifier prefix s_
|
||||
- scanning engine
|
||||
|
||||
Third level
|
||||
-----------
|
||||
cs3200f-drv.[ch]
|
||||
- identifier prefix r_
|
||||
- scanner driver
|
||||
|
||||
Fourth level
|
||||
------------
|
||||
cs3200f-dat.[ch]
|
||||
- identifier prefix a_
|
||||
- device specific data
|
||||
|
||||
cs3200f-usb.[ch]
|
||||
- identifier prefix u_
|
||||
- scanner specific USB interface
|
||||
|
||||
************************************************************************
|
||||
* How to build
|
||||
************************************************************************
|
||||
|
||||
Below some instructions of how to compile this in.
|
||||
I do not provide this as a patch to SANE release
|
||||
because of the pre-alpha experimental status.
|
||||
Still, it can be compiled and run, with varying
|
||||
success.
|
||||
------------------------------------------------------
|
||||
First, take the latest SANE back-ends from CVS, or any
|
||||
1.0.17 release (I think any should work since cs3200f
|
||||
does not depend on any recent patches).
|
||||
|
||||
I would recommend a directory structure
|
||||
$SOMEDIR/sane-backends
|
||||
$SOMEDIR/sandbox
|
||||
if you have SANE already installed. The sandbox dir will
|
||||
be used for installing the compiled backend instead of the
|
||||
actual directories (like /usr/lib/sane etc.)
|
||||
|
||||
Then put the cs3200f files into
|
||||
$SOMEDIR/sane-backends/backend
|
||||
Put only c and h files. The links will be made automatically
|
||||
in compilation phase.
|
||||
|
||||
In $SOMEDIR/sane-backends do
|
||||
./configure --prefix=$SOMEDIR/sandbox BACKENDS="test cs3200f"
|
||||
|
||||
The test backend is not necessary but will show if your
|
||||
compilation system works when you build it.
|
||||
|
||||
Now, in dir $SOMEDIR/sane-backends/backend you must add
|
||||
to the Makefile the following lines
|
||||
(e.g. before the line starting libsane-dc25.la: ...)
|
||||
libsane-cs3200f.la: ../sanei/sanei_constrain_value.lo
|
||||
libsane-cs3200f.la: ../sanei/sanei_thread.lo
|
||||
libsane-cs3200f.la: ../sanei/sanei_usb.lo
|
||||
libsane-cs3200f.la: ../sanei/sanei_access.lo
|
||||
libsane-cs3200f.la: ../lib/md5.lo
|
||||
|
||||
Now in dir $SOMEDIR/sane-backends
|
||||
do make and check that it works OK. E.g. in
|
||||
$SOMEDIR/sane-backends do
|
||||
make >make.log 2>&1
|
||||
In make log there may be warnings but compilation
|
||||
of cs3200f.c should give no warnings or errors. If
|
||||
it does, drop me a note with log (compressed please :) ).
|
||||
The make may end in error in makin sane.ps but that
|
||||
do not worry about, that's just docs.
|
||||
|
||||
Then do make install and you should now have the
|
||||
cs3200f libraries in $SOMEDIR/sandbox/lib/sane.
|
||||
|
||||
Now become a root and copy the cs3200f lib files
|
||||
to /usr/lib/sane or where ever your xsane expects
|
||||
the libs to be.
|
||||
|
||||
Then in /etc/sane.d (or wherever you find the dll.conf
|
||||
for sane dll lib) add to the dll.conf line
|
||||
cs3200f
|
||||
and if you wish, uncomment test backend.
|
||||
|
||||
Now run xsane. You should have test backend and
|
||||
cs3200f:dummy devices available (do not plugin the
|
||||
scanner, if you plugin the scanner, the real one
|
||||
instead of dummy you shall get). :)
|
||||
|
||||
Now, into directory $SOMEDIR/share/sane/cs3200f put
|
||||
the firmware file cs3200f_v0054.fw you have
|
||||
created. Instructions are given below.
|
||||
|
||||
Now, if you plug in the scanner and restart the xsane
|
||||
you should actually be able to boot the sanner and
|
||||
then moving the top left y cordinate will actually
|
||||
move the scan head, and pressing the calibrate
|
||||
now, will calibrate the AFE (that takes some time
|
||||
if lamp is not warmed up). These are just for
|
||||
testing the driver and thus do not reflect the
|
||||
actual final functions of these controls.
|
||||
|
||||
Warning: if you hear strange noises from the scanner,
|
||||
unplug the power adapter immediately. Then reset
|
||||
the scanner with windows driver and check that it
|
||||
still works OK. This "should" hot happen but
|
||||
happened to me several times when figuring out the
|
||||
command set.
|
||||
|
||||
If you suspect problems,
|
||||
have the following env vars exported:
|
||||
export SANE_DEBUG_CS3200F=255
|
||||
export SANE_DEBUG_SANEI_USB=255
|
||||
export SANE_DEBUG_SANEI_ACCESS=255
|
||||
and start xsane from a command line like
|
||||
xsane >xsane.log 2>&1
|
||||
|
||||
Send me the log, compressed, or try to figure out
|
||||
where the problem is.
|
||||
|
||||
That should do it. If not, drop me a note.
|
||||
|
||||
************************************************************************
|
||||
* On the firmware
|
||||
************************************************************************
|
||||
|
||||
Now, there is one complication, that must be addressed
|
||||
early. Like snapscan driver, this will also require
|
||||
uploading the firmware to the scanner at the beginning.
|
||||
While cross checking Windows logs (thanks to Mike
|
||||
Evans) I found out that there are at least two versions
|
||||
of the firmware out there. Some early CDs shipped with
|
||||
the scanners contain firmware version 0052. The latest
|
||||
(and presumably final one, since CanoScan 3200F is a
|
||||
discontinued product) is version 0054 and that version
|
||||
can be found in ScanGear version 8.5.1.1 which is available
|
||||
from Canon www pages (either as 3200F8511WNEN.exe which
|
||||
is a self extracting LHA package, for US and Japan, I guess,
|
||||
or s3A0Benx.exe which is a self extracting ZIP file).
|
||||
In the package there is a self extracting ZIP file
|
||||
(installer) SetupSG.exe which contains the low level
|
||||
DLL file CNQL1210.DLL. That file contains, as a binary file
|
||||
resource, the needed firmware.
|
||||
|
||||
If you have CD version 1.03 or 1.04 that should contain
|
||||
the correct version of the DLL, which is 1.0.3.0. Else
|
||||
get your copy from the net.
|
||||
|
||||
In the first phase I will only support the version 0054
|
||||
so anybody wanting to use the driver will need that
|
||||
version of the firmware. To get it you have to get the
|
||||
mentioned DLL and run the following perl script on it:
|
||||
=====================================================
|
||||
#!perl
|
||||
|
||||
use Digest::MD5 qw(md5_base64);
|
||||
|
||||
$start_address = 0x3a8c0;
|
||||
$end_address = 0x44304;
|
||||
$length = $end_address - $start_address;
|
||||
$refmd5 = "/wyuQDxka5rgidwmcDedZA";
|
||||
|
||||
open FIN, "<CNQL1210.DLL";
|
||||
binmode FIN;
|
||||
|
||||
sysseek FIN, 0x3a8c0, 0;
|
||||
|
||||
$res = sysread FIN, $fw, $length;
|
||||
|
||||
close FIN;
|
||||
|
||||
$md5 = md5_base64( $fw );
|
||||
if ( $md5 ne $refmd5 ) {
|
||||
print "Did not find CanoScan 3200F firmware v0054\n";
|
||||
die;
|
||||
}
|
||||
|
||||
open FOUT, ">cs3200f_v0054.fw";
|
||||
binmode FOUT;
|
||||
|
||||
syswrite FOUT, $fw, $length;
|
||||
|
||||
close FOUT;
|
||||
=====================================================
|
||||
|
||||
The resulting file cs3200f_v0054.fw will be needed
|
||||
in order to the driver to work properly.
|
||||
|
||||
************************************************************************
|
||||
* $Id: cs3200f.txt,v 1.1 2006/03/26 19:01:59 lapi-guest Exp $
|
||||
************************************************************************
|
|
@ -25,6 +25,7 @@ cardscan
|
|||
coolscan
|
||||
#coolscan2
|
||||
coolscan3
|
||||
cs3200f
|
||||
#dc210
|
||||
#dc240
|
||||
#dc25
|
||||
|
|
|
@ -1345,7 +1345,7 @@ sane_cancel(SANE_Handle h)
|
|||
}
|
||||
handler->scanner->work = SANE_FALSE;
|
||||
handler->cancel = SANE_TRUE;
|
||||
escl_scanner(handler->device, handler->scanner->scanJob, handler->result);
|
||||
escl_scanner(handler->device, handler->scanner->scanJob, handler->result, SANE_TRUE);
|
||||
free(handler->result);
|
||||
handler->result = NULL;
|
||||
free(handler->scanner->scanJob);
|
||||
|
@ -1566,6 +1566,7 @@ sane_start(SANE_Handle h)
|
|||
handler->decompress_scan_data = SANE_FALSE;
|
||||
handler->end_read = SANE_FALSE;
|
||||
if (handler->scanner->work == SANE_FALSE) {
|
||||
escl_reset_all_jobs(handler->device);
|
||||
SANE_Status st = escl_status(handler->device,
|
||||
handler->scanner->source,
|
||||
NULL,
|
||||
|
|
|
@ -248,7 +248,11 @@ SANE_Status escl_scan(capabilities_t *scanner,
|
|||
|
||||
void escl_scanner(const ESCL_Device *device,
|
||||
char *scanJob,
|
||||
char *result);
|
||||
char *result,
|
||||
SANE_Bool status);
|
||||
|
||||
SANE_Status escl_reset_all_jobs(ESCL_Device *device);
|
||||
|
||||
|
||||
typedef void CURL;
|
||||
|
||||
|
|
|
@ -44,7 +44,32 @@ write_callback(void __sane_unused__*str,
|
|||
* This function is called in the 'sane_cancel' function.
|
||||
*/
|
||||
void
|
||||
escl_scanner(const ESCL_Device *device, char *scanJob, char *result)
|
||||
escl_delete(const ESCL_Device *device, char *uri)
|
||||
{
|
||||
CURL *curl_handle = NULL;
|
||||
long answer = 0;
|
||||
|
||||
if (uri == NULL)
|
||||
return;
|
||||
curl_handle = curl_easy_init();
|
||||
if (curl_handle != NULL) {
|
||||
escl_curl_url(curl_handle, device, uri);
|
||||
curl_easy_setopt(curl_handle, CURLOPT_CUSTOMREQUEST, "DELETE");
|
||||
if (curl_easy_perform(curl_handle) == CURLE_OK) {
|
||||
curl_easy_getinfo(curl_handle, CURLINFO_RESPONSE_CODE, &answer);
|
||||
return;
|
||||
}
|
||||
curl_easy_cleanup(curl_handle);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* \fn void escl_scanner(const ESCL_Device *device, char *result)
|
||||
* \brief Function that resets the scanner after each scan, using curl.
|
||||
* This function is called in the 'sane_cancel' function.
|
||||
*/
|
||||
void
|
||||
escl_scanner(const ESCL_Device *device, char *scanJob, char *result, SANE_Bool status)
|
||||
{
|
||||
CURL *curl_handle = NULL;
|
||||
const char *scan_jobs = "/eSCL/";
|
||||
|
@ -70,10 +95,15 @@ CURL_CALL:
|
|||
if (i >= 15) return;
|
||||
}
|
||||
curl_easy_cleanup(curl_handle);
|
||||
if (SANE_STATUS_GOOD != escl_status(device,
|
||||
PLATEN,
|
||||
NULL,
|
||||
NULL))
|
||||
goto CURL_CALL;
|
||||
char* end = strrchr(scan_cmd, '/');
|
||||
*end = 0;
|
||||
escl_delete(device, scan_cmd);
|
||||
if (status) {
|
||||
if (SANE_STATUS_GOOD != escl_status(device,
|
||||
PLATEN,
|
||||
NULL,
|
||||
NULL))
|
||||
goto CURL_CALL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <libxml/parser.h>
|
||||
|
||||
|
@ -270,3 +271,135 @@ clean_data:
|
|||
}
|
||||
return (status);
|
||||
}
|
||||
|
||||
static void
|
||||
print_xml_job_finish(xmlNode *node,
|
||||
SANE_Status *job)
|
||||
{
|
||||
while (node) {
|
||||
if (node->type == XML_ELEMENT_NODE) {
|
||||
if (find_nodes_s(node)) {
|
||||
if (strcmp((const char *)node->name, "JobState") == 0) {
|
||||
const char *state = (const char *)xmlNodeGetContent(node);
|
||||
if (!strcmp(state, "Canceled")) {
|
||||
*job = SANE_STATUS_GOOD;
|
||||
DBG(10, "jobId Completed SANE_STATUS_GOOD\n");
|
||||
}
|
||||
else if (!strcmp(state, "Aborted")) {
|
||||
*job = SANE_STATUS_GOOD;
|
||||
DBG(10, "jobId Completed SANE_STATUS_GOOD\n");
|
||||
}
|
||||
else if (!strcmp(state, "Completed")) {
|
||||
*job = SANE_STATUS_GOOD;
|
||||
DBG(10, "jobId Completed SANE_STATUS_GOOD\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
print_xml_job_finish(node->children, job);
|
||||
node = node->next;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
print_xml_reset_all_jobs (xmlNode *node,
|
||||
ESCL_Device *device)
|
||||
{
|
||||
DBG(10, "print_xml_reset_all_jobs\n");
|
||||
SANE_Status status = SANE_STATUS_DEVICE_BUSY;
|
||||
while (node) {
|
||||
if (node->type == XML_ELEMENT_NODE) {
|
||||
if (find_nodes_s(node)) {
|
||||
if (strcmp((const char *)node->name, "JobUri") == 0) {
|
||||
DBG(10, "print_xml_reset_all_jobs: %s\n", node->name);
|
||||
if (device != NULL) {
|
||||
print_xml_job_finish (node, &status);
|
||||
if (status == SANE_STATUS_DEVICE_BUSY) {
|
||||
char *jobUri = (char *)xmlNodeGetContent(node);
|
||||
char *job = strrchr((const char *)jobUri, '/');
|
||||
char *scanj = NULL;
|
||||
if (job != NULL) {
|
||||
if (strstr(jobUri,"ScanJobs"))
|
||||
scanj = strdup("ScanJobs");
|
||||
else
|
||||
scanj = strdup("ScanJob");
|
||||
DBG(10, "print_xml_reset_all_jobs: %s/%s\n", scanj, job);
|
||||
escl_scanner(device, scanj, job, SANE_FALSE);
|
||||
free(scanj);
|
||||
}
|
||||
DBG(10, "print_xml_reset_all_jobs: sleep to finish the job\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
print_xml_reset_all_jobs (node->children,
|
||||
device);
|
||||
node = node->next;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* \fn SANE_Status escl_reset_all_jobs (ESCL_Device *device, , char *scanJob)
|
||||
* \brief Function that forces the end of jobs, using curl.
|
||||
* This function is called in the 'sane_start' function.
|
||||
*
|
||||
* \return status (if everything is OK, status = SANE_STATUS_GOOD, otherwise, SANE_STATUS_NO_MEM/SANE_STATUS_INVAL)
|
||||
*/
|
||||
SANE_Status
|
||||
escl_reset_all_jobs(ESCL_Device *device)
|
||||
{
|
||||
CURL *curl_handle = NULL;
|
||||
xmlDoc *data = NULL;
|
||||
xmlNode *node = NULL;
|
||||
struct idle *var = NULL;
|
||||
const char *scanner_status = "/eSCL/ScannerStatus";
|
||||
SANE_Status status = SANE_STATUS_DEVICE_BUSY;
|
||||
|
||||
DBG(10, "escl_reset_all_jobs\n");
|
||||
if (device == NULL)
|
||||
return (SANE_STATUS_NO_MEM);
|
||||
DBG(10, "1 - escl_reset_all_jobs\n");
|
||||
var = (struct idle*)calloc(1, sizeof(struct idle));
|
||||
if (var == NULL)
|
||||
return (SANE_STATUS_NO_MEM);
|
||||
DBG(10, "2 - escl_reset_all_jobs\n");
|
||||
var->memory = malloc(1);
|
||||
var->size = 0;
|
||||
curl_handle = curl_easy_init();
|
||||
|
||||
escl_curl_url(curl_handle, device, scanner_status);
|
||||
curl_easy_setopt(curl_handle, CURLOPT_WRITEFUNCTION, memory_callback_s);
|
||||
curl_easy_setopt(curl_handle, CURLOPT_WRITEDATA, (void *)var);
|
||||
curl_easy_setopt(curl_handle, CURLOPT_FOLLOWLOCATION, 1L);
|
||||
curl_easy_setopt(curl_handle, CURLOPT_MAXREDIRS, 3L);
|
||||
CURLcode res = curl_easy_perform(curl_handle);
|
||||
if (res != CURLE_OK) {
|
||||
DBG( 1, "The scanner didn't respond: %s\n", curl_easy_strerror(res));
|
||||
status = SANE_STATUS_INVAL;
|
||||
goto clean_data1;
|
||||
}
|
||||
DBG(10, "3 - escl_reset_all_jobs\n");
|
||||
DBG( 10, "eSCL : Status : %s.\n", var->memory);
|
||||
data = xmlReadMemory(var->memory, var->size, "file.xml", NULL, 0);
|
||||
if (data == NULL) {
|
||||
status = SANE_STATUS_NO_MEM;
|
||||
goto clean_data1;
|
||||
}
|
||||
node = xmlDocGetRootElement(data);
|
||||
if (node == NULL) {
|
||||
status = SANE_STATUS_NO_MEM;
|
||||
goto clean1;
|
||||
}
|
||||
print_xml_reset_all_jobs (node, device);
|
||||
status = SANE_STATUS_GOOD;
|
||||
clean1:
|
||||
xmlFreeDoc(data);
|
||||
clean_data1:
|
||||
xmlCleanupParser();
|
||||
xmlMemoryDump();
|
||||
curl_easy_cleanup(curl_handle);
|
||||
free(var->memory);
|
||||
free(var);
|
||||
return status;
|
||||
}
|
||||
|
|
|
@ -20,6 +20,9 @@
|
|||
|
||||
#define DEBUG_DECLARE_ONLY
|
||||
|
||||
#include "../include/sane/config.h"
|
||||
#include <unistd.h>
|
||||
|
||||
#include "scanner_interface_usb.h"
|
||||
#include "low.h"
|
||||
|
||||
|
|
|
@ -668,7 +668,7 @@ AC_ARG_ENABLE(local-backends,
|
|||
|
||||
ALL_BACKENDS="abaton agfafocus apple artec artec_eplus48u as6e \
|
||||
avision bh canon canon630u canon_dr canon_lide70 canon_pp cardscan \
|
||||
coolscan coolscan2 coolscan3 dc25 dc210 dc240 \
|
||||
coolscan coolscan2 coolscan3 cs3200f dc25 dc210 dc240 \
|
||||
dell1600n_net dmc epjitsu epson epson2 epsonds escl fujitsu \
|
||||
genesys gphoto2 gt68xx hp hp3500 hp3900 hp4200 hp5400 \
|
||||
hp5590 hpsj5s hpljm1005 hs2p ibm kodak kodakaio kvs1025 kvs20xx \
|
||||
|
|
Ładowanie…
Reference in New Issue