Added hp5400 backend from Martijn van Oosterhout <kleptog@svana.org> and

Thomas Soumarmon <soumarmt@nerim.net>. Changed to use sanei_usb instead of
direct /dev/usb/scanner access. Added manual page. Fixed some portablility
issues and some warnings. Added SANE headers.
merge-requests/1/head
Henning Geinitz 2003-04-17 09:19:25 +00:00
rodzic a563d4735d
commit 517751ff09
13 zmienionych plików z 3065 dodań i 6 usunięć

Wyświetl plik

@ -36,7 +36,8 @@ Backends:
hp: Peter Kirchgessner (*)
Geoffrey Dairiki
hpsj5s: Max Vorobiev (*)
ibm: mf, Henning Meier-Geinitz (*)
hp5400: Martijn van Oosterhout (*), Thomas Soumarmon (*)
ibm: M.F., Henning Meier-Geinitz (*)
leo: Frank Zago (*)
ma1509: Henning Meier-Geinitz (*)
matsushita: Frank Zago (*)
@ -145,15 +146,16 @@ Karsten Festag <karsten.festag@gmx.de>
Kazuhiro Sasayama <kaz@hypercore.co.jp>
Kazuya Fukuda <kaafuu@mug.biglobe.ne.jp>
Kevin Charter <charter@cs.rice.edu>
M.F. <massifr@tiscalinet.it>
Manuel Panea <Manuel.Panea@rzg.mpg.de>
Marcio Teixeira <marciot@users.sourceforge.net>
Marian Eichholz <eichholz@computer.org>
Markus Mertinat <Markus.Mertinat@Physik.Uni-Augsburg.DE>
Martijn van Oosterhout <kleptog@svana.org>
Matthew Duggan <stauff1@users.sourceforge.net>
Matthew Marjanovic <maddog@mir.com>
Max Vorobiev <pcwizard@yandex.ru>
Meino Christian Cramer <mccramer@s.netic.de>
mf <massifr@tiscalinet.it>
Michael Herder <crapsite@gmx.net>
Michael K. Johnson <johnsonm@redhat.com>
Michel Roelofs <michelr@stack.nl>
@ -175,6 +177,7 @@ Sergey Vlasov <vsu@altlinux.ru>
Simon Krix <kinsei@users.sourceforge.net>
Simon Munton <simon@munton.demon.co.uk>
Stéphane Voltz <svoltz@wanadoo.fr>
Thomas Soumarmon <soumarmt@nerim.net>
Tom Martone <tom@martoneconsulting.com>
Tom Wang <tom.wang@mustek.com.tw>
Tristan Tarrant <ttarrant@etnoteam.it>

Wyświetl plik

@ -1,3 +1,15 @@
2003-04-17 Henning Meier-Geinitz <henning@meier-geinitz.de>
* AUTHORS backend/Makefile.in backend/dll.conf backend/hp5400.c
backend/hp5400.conf backend/hp5400.h backend/hp5400_internal.c
backend/hp5400_sanei.c backend/hp5400_xfer.h doc/.cvsignore
doc/Makefile.in doc/sane-hp5400.man doc/sane.man:
Added hp5400 backend from Martijn van Oosterhout
<kleptog@svana.org> and Thomas Soumarmon
<soumarmt@nerim.net>. Changed to use sanei_usb instead of direct
/dev/usb/scanner access. Added manual page. Fixed some
portablility issues and some warnings. Added SANE headers.
2003-04-16 Henning Meier-Geinitz <henning@meier-geinitz.de>
* doc/scanimage.man: Added EXAMPLES section.

Wyświetl plik

@ -66,7 +66,7 @@ PRELOADABLE_BACKENDS = abaton agfafocus apple artec as6e avision bh canon \
microtek2 mustek mustek_pp mustek_usb nec @NET@ pie @PINT@ plustek \
@PNM@ @QCAM@ ricoh s9036 sceptre sharp @SM3600@ @SNAPSCAN@ \
sp15c st400 tamarack test teco1 teco2 teco3 umax umax_pp umax1220u \
@V4L@ artec_eplus48u ma1509 ibm
@V4L@ artec_eplus48u ma1509 ibm hp5400
ifneq (@SELECTED_BACKENDS@,)
PRELOADABLE_BACKENDS = @SELECTED_BACKENDS@
endif
@ -111,6 +111,7 @@ DISTFILES = abaton.c abaton.conf abaton.h agfafocus.c agfafocus.conf \
hp-device.c hp-device.h hp.h hp-handle.c hp-handle.h hp-hpmem.c hp-option.c \
hp-option.h hp.README hp-scl.c hp-scl.h hp-scsi.h hp.TODO \
hpsj5s.c hpsj5s.conf hpsj5s.h \
hp5400.c hp5400.h hp5400.conf hp5400_internal.c hp5400_sanei.c hp5400_xfer.h \
ibm.c ibm.conf ibm.h ibm-scsi.c \
jinclude.h \
leo.c leo.h leo.conf \
@ -315,6 +316,8 @@ libsane-hp.la: ../sanei/sanei_scsi.lo
libsane-hp.la: ../sanei/sanei_usb.lo
libsane-hp.la: $(addsuffix .lo,$(EXTRA_hp))
libsane-hp.la: ../sanei/sanei_pio.lo
libsane-hp5400.la: ../sanei/sanei_usb.lo
libsane-hp5400.la: ../sanei/sanei_config2.lo
libsane-ibm.la: ../sanei/sanei_scsi.lo
libsane-ibm.la: ../sanei/sanei_config2.lo
libsane-ibm.la: ../sanei/sanei_constrain_value.lo

Wyświetl plik

@ -23,6 +23,7 @@ fujitsu
gt68xx
hp
hpsj5s
hp5400
ibm
leo
ma1509

973
backend/hp5400.c 100644
Wyświetl plik

@ -0,0 +1,973 @@
/* sane - Scanner Access Now Easy.
Copyright (C) 2003 Martijn van Oosterhout <kleptog@svana.org>
This file was initially copied from the hp3300 testools and adjusted to
suit. Original copyright notice follows:
Copyright (C) 2001 Bertrik Sikken (bertrik@zonnet.nl)
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.
*/
/*
SANE interface for hp54xx scanners. Prototype.
Parts of this source were inspired by other backends.
*/
/* definitions for debug */
#define BACKEND_NAME hp5400
#define BUILD 2
#include "../include/sane/config.h"
#include "../include/sane/sane.h"
#include "../include/sane/sanei.h"
#include "../include/sane/sanei_backend.h"
#include "../include/sane/sanei_config.h"
#include "../include/sane/saneopts.h"
#include <stdlib.h> /* malloc, free */
#include <string.h> /* memcpy */
#include <stdio.h>
#define DBG_ASSERT 1
#define DBG_ERR 16
#define DBG_MSG 32
#define HP5400_CONFIG_FILE "hp5400.conf"
#include "hp5400.h"
/* (source) includes for data transfer methods */
#include "hp5400_internal.c"
#include "hp5400_sanei.c"
/* other definitions */
#define TRUE 1
#define FALSE 0
#define MM_TO_PIXEL(_mm_, _dpi_) ((_mm_) * (_dpi_) / 25.4)
#define PIXEL_TO_MM(_pixel_, _dpi_) ((_pixel_) * 25.4 / (_dpi_))
#define NUM_GAMMA_ENTRIES 65536
/* Device filename for USB access */
static char *usb_devfile = "/dev/usb/scanner0";
/* options enumerator */
typedef enum
{
optCount = 0,
optGroupGeometry,
optTLX, optTLY, optBRX, optBRY,
optDPI,
optGroupImage,
optGammaTableRed, /* Gamma Tables */
optGammaTableGreen,
optGammaTableBlue,
optLast, /* Disable the offset code */
optGroupMisc,
optOffsetX, optOffsetY
/* put temporarily disabled options here after optLast */
/*
optLamp,
*/
}
EOptionIndex;
typedef union
{
SANE_Word w;
SANE_Word *wa; /* word array */
SANE_String s;
}
TOptionValue;
typedef struct
{
SANE_Option_Descriptor aOptions[optLast];
TOptionValue aValues[optLast];
TScanParams ScanParams;
THWParams HWParams;
TDataPipe DataPipe;
int iLinesLeft;
SANE_Int *aGammaTableR; /* a 16-to-16 bit color lookup table */
SANE_Int *aGammaTableG; /* a 16-to-16 bit color lookup table */
SANE_Int *aGammaTableB; /* a 16-to-16 bit color lookup table */
int fScanning; /* TRUE if actively scanning */
int fCanceled;
}
TScanner;
/* linked list of SANE_Device structures */
typedef struct TDevListEntry
{
struct TDevListEntry *pNext;
SANE_Device dev;
}
TDevListEntry;
static TDevListEntry *_pFirstSaneDev = 0;
static int iNumSaneDev = 0;
static const SANE_Device **_pSaneDevList = 0;
/* option constraints */
static const SANE_Range rangeGammaTable = { 0, 65535, 1 };
#ifdef SUPPORT_2400_DPI
static const SANE_Int setResolutions[] = { 6, 75, 150, 300, 600, 1200, 2400 };
#else
static const SANE_Int setResolutions[] = { 5, 75, 150, 300, 600, 1200 };
#endif
static const SANE_Range rangeXmm = { 0, 220, 1 };
static const SANE_Range rangeYmm = { 0, 300, 1 };
static const SANE_Range rangeXoffset = { 0, 20, 1 };
static const SANE_Range rangeYoffset = { 0, 70, 1 };
static const SANE_Int offsetX = 5;
static const SANE_Int offsetY = 52;
static void
_InitOptions (TScanner * s)
{
int i, j;
SANE_Option_Descriptor *pDesc;
TOptionValue *pVal;
/* set a neutral gamma */
if (s->aGammaTableR == NULL) /* Not yet allocated */
{
s->aGammaTableR = malloc (NUM_GAMMA_ENTRIES * sizeof (SANE_Int));
s->aGammaTableG = malloc (NUM_GAMMA_ENTRIES * sizeof (SANE_Int));
s->aGammaTableB = malloc (NUM_GAMMA_ENTRIES * sizeof (SANE_Int));
for (j = 0; j < NUM_GAMMA_ENTRIES; j++)
{
s->aGammaTableR[j] = j;
s->aGammaTableG[j] = j;
s->aGammaTableB[j] = j;
}
}
for (i = optCount; i < optLast; i++)
{
pDesc = &s->aOptions[i];
pVal = &s->aValues[i];
/* defaults */
pDesc->name = "";
pDesc->title = "";
pDesc->desc = "";
pDesc->type = SANE_TYPE_INT;
pDesc->unit = SANE_UNIT_NONE;
pDesc->size = sizeof (SANE_Word);
pDesc->constraint_type = SANE_CONSTRAINT_NONE;
pDesc->cap = 0;
switch (i)
{
case optCount:
pDesc->title = SANE_TITLE_NUM_OPTIONS;
pDesc->desc = SANE_DESC_NUM_OPTIONS;
pDesc->cap = SANE_CAP_SOFT_DETECT;
pVal->w = (SANE_Word) optLast;
break;
case optGroupGeometry:
pDesc->title = "Geometry";
pDesc->type = SANE_TYPE_GROUP;
pDesc->size = 0;
break;
case optTLX:
pDesc->name = SANE_NAME_SCAN_TL_X;
pDesc->title = SANE_TITLE_SCAN_TL_X;
pDesc->desc = SANE_DESC_SCAN_TL_X;
pDesc->unit = SANE_UNIT_MM;
pDesc->constraint_type = SANE_CONSTRAINT_RANGE;
pDesc->constraint.range = &rangeXmm;
pDesc->cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT;
pVal->w = rangeXmm.min + offsetX;
break;
case optTLY:
pDesc->name = SANE_NAME_SCAN_TL_Y;
pDesc->title = SANE_TITLE_SCAN_TL_Y;
pDesc->desc = SANE_DESC_SCAN_TL_Y;
pDesc->unit = SANE_UNIT_MM;
pDesc->constraint_type = SANE_CONSTRAINT_RANGE;
pDesc->constraint.range = &rangeYmm;
pDesc->cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT;
pVal->w = rangeYmm.min + offsetY;
break;
case optBRX:
pDesc->name = SANE_NAME_SCAN_BR_X;
pDesc->title = SANE_TITLE_SCAN_BR_X;
pDesc->desc = SANE_DESC_SCAN_BR_X;
pDesc->unit = SANE_UNIT_MM;
pDesc->constraint_type = SANE_CONSTRAINT_RANGE;
pDesc->constraint.range = &rangeXmm;
pDesc->cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT;
pVal->w = rangeXmm.max + offsetX;
break;
case optBRY:
pDesc->name = SANE_NAME_SCAN_BR_Y;
pDesc->title = SANE_TITLE_SCAN_BR_Y;
pDesc->desc = SANE_DESC_SCAN_BR_Y;
pDesc->unit = SANE_UNIT_MM;
pDesc->constraint_type = SANE_CONSTRAINT_RANGE;
pDesc->constraint.range = &rangeYmm;
pDesc->cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT;
pVal->w = rangeYmm.max + offsetY;
break;
case optDPI:
pDesc->name = SANE_NAME_SCAN_RESOLUTION;
pDesc->title = SANE_TITLE_SCAN_RESOLUTION;
pDesc->desc = SANE_DESC_SCAN_RESOLUTION;
pDesc->unit = SANE_UNIT_DPI;
pDesc->constraint_type = SANE_CONSTRAINT_WORD_LIST;
pDesc->constraint.word_list = setResolutions;
pDesc->cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT;
pVal->w = setResolutions[1];
break;
case optGroupImage:
pDesc->title = SANE_I18N ("Image");
pDesc->type = SANE_TYPE_GROUP;
pDesc->size = 0;
break;
case optGammaTableRed:
pDesc->name = SANE_NAME_GAMMA_VECTOR_R;
pDesc->title = SANE_TITLE_GAMMA_VECTOR_R;
pDesc->desc = SANE_DESC_GAMMA_VECTOR_R;
pDesc->size = NUM_GAMMA_ENTRIES * sizeof (SANE_Int);
pDesc->constraint_type = SANE_CONSTRAINT_RANGE;
pDesc->constraint.range = &rangeGammaTable;
pDesc->cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT;
pVal->wa = s->aGammaTableR;
break;
case optGammaTableGreen:
pDesc->name = SANE_NAME_GAMMA_VECTOR_G;
pDesc->title = SANE_TITLE_GAMMA_VECTOR_G;
pDesc->desc = SANE_DESC_GAMMA_VECTOR_G;
pDesc->size = NUM_GAMMA_ENTRIES * sizeof (SANE_Int);
pDesc->constraint_type = SANE_CONSTRAINT_RANGE;
pDesc->constraint.range = &rangeGammaTable;
pDesc->cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT;
pVal->wa = s->aGammaTableG;
break;
case optGammaTableBlue:
pDesc->name = SANE_NAME_GAMMA_VECTOR_B;
pDesc->title = SANE_TITLE_GAMMA_VECTOR_B;
pDesc->desc = SANE_DESC_GAMMA_VECTOR_B;
pDesc->size = NUM_GAMMA_ENTRIES * sizeof (SANE_Int);
pDesc->constraint_type = SANE_CONSTRAINT_RANGE;
pDesc->constraint.range = &rangeGammaTable;
pDesc->cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT;
pVal->wa = s->aGammaTableB;
break;
case optGroupMisc:
pDesc->title = SANE_I18N ("Miscellaneous");
pDesc->type = SANE_TYPE_GROUP;
pDesc->size = 0;
break;
case optOffsetX:
pDesc->title = SANE_I18N ("offset X");
pDesc->desc =
SANE_I18N ("Hardware internal X position of the scanning area.");
pDesc->unit = SANE_UNIT_MM;
pDesc->constraint_type = SANE_CONSTRAINT_RANGE;
pDesc->constraint.range = &rangeXoffset;
pDesc->cap = SANE_CAP_SOFT_SELECT;
pVal->w = offsetX;
break;
case optOffsetY:
pDesc->title = SANE_I18N ("offset Y");
pDesc->desc =
SANE_I18N ("Hardware internal Y position of the scanning area.");
pDesc->unit = SANE_UNIT_MM;
pDesc->constraint_type = SANE_CONSTRAINT_RANGE;
pDesc->constraint.range = &rangeYoffset;
pDesc->cap = SANE_CAP_SOFT_SELECT;
pVal->w = offsetY;
break;
#if 0
case optLamp:
pDesc->name = "lamp";
pDesc->title = SANE_I18N ("Lamp status");
pDesc->desc = SANE_I18N ("Switches the lamp on or off.");
pDesc->type = SANE_TYPE_BOOL;
pDesc->cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT;
/* switch the lamp on when starting for first the time */
pVal->w = SANE_TRUE;
break;
#endif
#if 0
case optCalibrate:
pDesc->name = "calibrate";
pDesc->title = SANE_I18N ("Calibrate");
pDesc->desc = SANE_I18N ("Calibrates for black and white level.");
pDesc->type = SANE_TYPE_BUTTON;
pDesc->cap = SANE_CAP_SOFT_SELECT;
pDesc->size = 0;
break;
#endif
default:
DBG (DBG_ERR, "Uninitialised option %d\n", i);
break;
}
}
}
static int
_ReportDevice (TScannerModel * pModel, char *pszDeviceName)
{
TDevListEntry *pNew, *pDev;
DBG (DBG_MSG, "hp5400: _ReportDevice '%s'\n", pszDeviceName);
pNew = malloc (sizeof (TDevListEntry));
if (!pNew)
{
DBG (DBG_ERR, "no mem\n");
return -1;
}
/* add new element to the end of the list */
if (_pFirstSaneDev == NULL)
{
_pFirstSaneDev = pNew;
}
else
{
for (pDev = _pFirstSaneDev; pDev->pNext; pDev = pDev->pNext)
{
;
}
pDev->pNext = pNew;
}
/* fill in new element */
pNew->pNext = 0;
pNew->dev.name = strdup (pszDeviceName);
pNew->dev.vendor = pModel->pszVendor;
pNew->dev.model = pModel->pszName;
pNew->dev.type = "flatbed scanner";
iNumSaneDev++;
return 0;
}
static SANE_Status
attach_one_device (SANE_String_Const devname)
{
if (HP5400Detect (devname, _ReportDevice) < 0)
{
DBG (DBG_MSG, "attach_one_device: couldn't attach %s\n", devname);
return SANE_STATUS_INVAL;
}
DBG (DBG_MSG, "attach_one_device: attached %s successfully\n", devname);
return SANE_STATUS_GOOD;
}
/*****************************************************************************/
SANE_Status
sane_init (SANE_Int * piVersion, SANE_Auth_Callback pfnAuth)
{
FILE *conf_fp; /* Config file stream */
SANE_Char line[PATH_MAX];
SANE_Char *str = NULL;
SANE_String_Const proper_str;
int nline = 0;
/* prevent compiler from complaing about unused parameters */
pfnAuth = pfnAuth;
DBG_INIT ();
DBG (DBG_MSG, "sane_init: SANE hp5400 backend version %d.%d-%d (from %s)\n",
V_MAJOR, V_MINOR, BUILD, PACKAGE_STRING);
sanei_usb_init ();
conf_fp = sanei_config_open (HP5400_CONFIG_FILE);
iNumSaneDev = 0;
if (conf_fp)
{
DBG (DBG_MSG, "Reading config file\n");
while (sanei_config_read (line, sizeof (line), conf_fp))
{
++nline;
if (str)
{
free (str);
}
proper_str = sanei_config_get_string (line, &str);
/* Discards white lines and comments */
if (!str || proper_str == line || str[0] == '#')
{
DBG (DBG_MSG, "Discarding line %d\n", nline);
}
else
{
/* If line's not blank or a comment, then it's the device
* filename or a usb directive. */
DBG (DBG_MSG, "Trying to attach %s\n", line);
sanei_usb_attach_matching_devices (line, attach_one_device);
}
} /* while */
fclose (conf_fp);
}
else
{
DBG (DBG_ERR, "Unable to read config file \"%s\": %s\n",
HP5400_CONFIG_FILE, strerror (errno));
DBG (DBG_MSG, "Using default built-in values\n");
attach_one_device (usb_devfile);
}
if (piVersion != NULL)
{
*piVersion = SANE_VERSION_CODE (V_MAJOR, V_MINOR, BUILD);
}
return SANE_STATUS_GOOD;
}
void
sane_exit (void)
{
TDevListEntry *pDev, *pNext;
DBG (DBG_MSG, "sane_exit\n");
/* free device list memory */
if (_pSaneDevList)
{
for (pDev = _pFirstSaneDev; pDev; pDev = pNext)
{
pNext = pDev->pNext;
free ((void *) pDev->dev.name);
free (pDev);
}
_pFirstSaneDev = 0;
free (_pSaneDevList);
_pSaneDevList = 0;
}
}
SANE_Status
sane_get_devices (const SANE_Device *** device_list, SANE_Bool local_only)
{
TDevListEntry *pDev;
int i;
DBG (DBG_MSG, "sane_get_devices\n");
local_only = local_only;
if (_pSaneDevList)
{
free (_pSaneDevList);
}
_pSaneDevList = malloc (sizeof (*_pSaneDevList) * (iNumSaneDev + 1));
if (!_pSaneDevList)
{
DBG (DBG_MSG, "no mem\n");
return SANE_STATUS_NO_MEM;
}
i = 0;
for (pDev = _pFirstSaneDev; pDev; pDev = pDev->pNext)
{
_pSaneDevList[i++] = &pDev->dev;
}
_pSaneDevList[i++] = 0; /* last entry is 0 */
*device_list = _pSaneDevList;
return SANE_STATUS_GOOD;
}
SANE_Status
sane_open (SANE_String_Const name, SANE_Handle * h)
{
TScanner *s;
DBG (DBG_MSG, "sane_open: %s\n", name);
/* check the name */
if (strlen (name) == 0)
{
/* default to first available device */
name = _pFirstSaneDev->dev.name;
}
s = malloc (sizeof (TScanner));
if (!s)
{
DBG (DBG_MSG, "malloc failed\n");
return SANE_STATUS_NO_MEM;
}
memset (s, 0, sizeof (TScanner)); /* Clear everything to zero */
if (HP5400Open (&s->HWParams, (char *) name) < 0)
{
/* is this OK ? */
DBG (DBG_ERR, "HP5400Open failed\n");
free ((void *) s);
return SANE_STATUS_INVAL; /* is this OK? */
}
DBG (DBG_MSG, "Handle=%d\n", s->HWParams.iXferHandle);
_InitOptions (s);
*h = s;
/* Turn on lamp by default at startup */
/* SetLamp(&s->HWParams, TRUE); */
return SANE_STATUS_GOOD;
}
void
sane_close (SANE_Handle h)
{
TScanner *s;
DBG (DBG_MSG, "sane_close\n");
s = (TScanner *) h;
/* turn of scanner lamp */
SetLamp (&s->HWParams, FALSE);
/* close scanner */
HP5400Close (&s->HWParams);
/* free scanner object memory */
free ((void *) s);
}
const SANE_Option_Descriptor *
sane_get_option_descriptor (SANE_Handle h, SANE_Int n)
{
TScanner *s;
DBG (DBG_MSG, "sane_get_option_descriptor %d\n", n);
if ((n < optCount) || (n >= optLast))
{
return NULL;
}
s = (TScanner *) h;
return &s->aOptions[n];
}
SANE_Status
sane_control_option (SANE_Handle h, SANE_Int n, SANE_Action Action,
void *pVal, SANE_Int * pInfo)
{
TScanner *s;
SANE_Int info;
DBG (DBG_MSG, "sane_control_option: option %d, action %d\n", n, Action);
s = (TScanner *) h;
info = 0;
switch (Action)
{
case SANE_ACTION_GET_VALUE:
switch (n)
{
/* Get options of type SANE_Word */
case optBRX:
case optTLX:
*(SANE_Word *) pVal = s->aValues[n].w; /* Not needed anymore - s->aValues[optOffsetX].w; */
DBG (DBG_MSG,
"sane_control_option: SANE_ACTION_GET_VALUE %d = %d\n", n,
*(SANE_Word *) pVal);
break;
case optBRY:
case optTLY:
*(SANE_Word *) pVal = s->aValues[n].w; /* Not needed anymore - - s->aValues[optOffsetY].w; */
DBG (DBG_MSG,
"sane_control_option: SANE_ACTION_GET_VALUE %d = %d\n", n,
*(SANE_Word *) pVal);
break;
case optOffsetX:
case optOffsetY:
case optCount:
case optDPI:
DBG (DBG_MSG,
"sane_control_option: SANE_ACTION_GET_VALUE %d = %d\n", n,
(int) s->aValues[n].w);
*(SANE_Word *) pVal = s->aValues[n].w;
break;
/* Get options of type SANE_Word array */
case optGammaTableRed:
case optGammaTableGreen:
case optGammaTableBlue:
DBG (DBG_MSG, "Reading gamma table\n");
memcpy (pVal, s->aValues[n].wa, s->aOptions[n].size);
break;
#if 0
/* Get options of type SANE_Bool */
case optLamp:
GetLamp (&s->HWParams, &fLampIsOn);
*(SANE_Bool *) pVal = fLampIsOn;
break;
#endif
#if 0
case optCalibrate:
/* although this option has nothing to read,
it's added here to avoid a warning when running scanimage --help */
break;
#endif
default:
DBG (DBG_MSG, "SANE_ACTION_GET_VALUE: Invalid option (%d)\n", n);
}
break;
case SANE_ACTION_SET_VALUE:
if (s->fScanning)
{
DBG (DBG_ERR,
"sane_control_option: SANE_ACTION_SET_VALUE not allowed during scan\n");
return SANE_STATUS_INVAL;
}
switch (n)
{
case optCount:
return SANE_STATUS_INVAL;
break;
case optBRX:
case optTLX:
info |= SANE_INFO_RELOAD_PARAMS;
s->ScanParams.iLines = 0; /* Forget actual image settings */
s->aValues[n].w = *(SANE_Word *) pVal; /* Not needed anymore - + s->aValues[optOffsetX].w; */
break;
case optBRY:
case optTLY:
info |= SANE_INFO_RELOAD_PARAMS;
s->ScanParams.iLines = 0; /* Forget actual image settings */
s->aValues[n].w = *(SANE_Word *) pVal; /* Not needed anymore - + s->aValues[optOffsetY].w; */
break;
case optDPI:
info |= SANE_INFO_RELOAD_PARAMS;
s->ScanParams.iLines = 0; /* Forget actual image settings */
#ifdef SUPPORT_2400_DPI
(s->aValues[n].w) = *(SANE_Word *) pVal;
#else
(s->aValues[n].w) = min (1200, *(SANE_Word *) pVal);
#endif
break;
case optGammaTableRed:
case optGammaTableGreen:
case optGammaTableBlue:
DBG (DBG_MSG, "Writing gamma table\n");
memcpy (s->aValues[n].wa, pVal, s->aOptions[n].size);
break;
/*
case optLamp:
fVal = *(SANE_Bool *)pVal;
DBG(DBG_MSG, "lamp %s\n", fVal ? "on" : "off");
SetLamp(&s->HWParams, fVal);
break;
*/
#if 0
case optCalibrate:
/* SimpleCalib(&s->HWParams); */
break;
#endif
default:
DBG (DBG_ERR, "SANE_ACTION_SET_VALUE: Invalid option (%d)\n", n);
}
if (pInfo != NULL)
{
*pInfo = info;
}
break;
case SANE_ACTION_SET_AUTO:
return SANE_STATUS_UNSUPPORTED;
default:
DBG (DBG_ERR, "Invalid action (%d)\n", Action);
return SANE_STATUS_INVAL;
}
return SANE_STATUS_GOOD;
}
SANE_Status
sane_get_parameters (SANE_Handle h, SANE_Parameters * p)
{
TScanner *s;
DBG (DBG_MSG, "sane_get_parameters\n");
s = (TScanner *) h;
/* first do some checks */
if (s->aValues[optTLX].w >= s->aValues[optBRX].w)
{
DBG (DBG_ERR, "TLX should be smaller than BRX\n");
return SANE_STATUS_INVAL; /* proper error code? */
}
if (s->aValues[optTLY].w >= s->aValues[optBRY].w)
{
DBG (DBG_ERR, "TLY should be smaller than BRY\n");
return SANE_STATUS_INVAL; /* proper error code? */
}
/* return the data */
p->format = SANE_FRAME_RGB;
p->last_frame = SANE_TRUE;
p->depth = 8;
if (s->ScanParams.iLines) /* Initialised by doing a scan */
{
p->pixels_per_line = s->ScanParams.iBytesPerLine / 3;
p->lines = s->ScanParams.iLines;
p->bytes_per_line = s->ScanParams.iBytesPerLine;
}
else
{
p->lines = MM_TO_PIXEL (s->aValues[optBRY].w - s->aValues[optTLY].w,
s->aValues[optDPI].w);
p->pixels_per_line =
MM_TO_PIXEL (s->aValues[optBRX].w - s->aValues[optTLX].w,
s->aValues[optDPI].w);
p->bytes_per_line = p->pixels_per_line * 3;
}
return SANE_STATUS_GOOD;
}
#define BUFFER_READ_HEADER_SIZE 32
SANE_Status
sane_start (SANE_Handle h)
{
TScanner *s;
SANE_Parameters par;
DBG (DBG_MSG, "sane_start\n");
s = (TScanner *) h;
if (sane_get_parameters (h, &par) != SANE_STATUS_GOOD)
{
DBG (DBG_MSG, "Invalid scan parameters (sane_get_parameters)\n");
return SANE_STATUS_INVAL;
}
s->iLinesLeft = par.lines;
/* fill in the scanparams using the option values */
s->ScanParams.iDpi = s->aValues[optDPI].w;
s->ScanParams.iLpi = s->aValues[optDPI].w;
/* Guessing here. 75dpi => 1, 2400dpi => 32 */
/* s->ScanParams.iColourOffset = s->aValues[optDPI].w / 75; */
/* now we don't need correction => corrected by scan request type ? */
s->ScanParams.iColourOffset = 0;
s->ScanParams.iTop =
MM_TO_PIXEL (s->aValues[optTLY].w + s->HWParams.iTopLeftY, HW_LPI);
s->ScanParams.iLeft =
MM_TO_PIXEL (s->aValues[optTLX].w + s->HWParams.iTopLeftX, HW_DPI);
/* Note: All measurements passed to the scanning routines must be in HW_LPI */
s->ScanParams.iWidth =
MM_TO_PIXEL (s->aValues[optBRX].w - s->aValues[optTLX].w, HW_LPI);
s->ScanParams.iHeight =
MM_TO_PIXEL (s->aValues[optBRY].w - s->aValues[optTLY].w, HW_LPI);
/* After the scanning, the iLines and iBytesPerLine will be filled in */
/* copy gamma table */
WriteGammaCalibTable (s->HWParams.iXferHandle, s->aGammaTableR,
s->aGammaTableG, s->aGammaTableB);
/* prepare the actual scan */
/* We say normal here. In future we should have a preview flag to set preview mode */
if (InitScan (SCAN_TYPE_NORMAL, &s->ScanParams, &s->HWParams) != 0)
{
DBG (DBG_MSG, "Invalid scan parameters (InitScan)\n");
return SANE_STATUS_INVAL;
}
/* for the moment no lines has been read */
s->ScanParams.iLinesRead = 0;
s->fScanning = TRUE;
return SANE_STATUS_GOOD;
}
SANE_Status
sane_read (SANE_Handle h, SANE_Byte * buf, SANE_Int maxlen, SANE_Int * len)
{
/* Read actual scan from the circular buffer */
/* Note: this is already color corrected, though some work still needs to be done
to deal with the colour offsetting */
TScanner *s;
char *buffer = buf;
DBG (DBG_MSG, "sane_read: request %d bytes \n", maxlen);
s = (TScanner *) h;
/* nothing has been read for the moment */
*len = 0;
/* if we read all the lines return EOF */
if (s->ScanParams.iLinesRead == s->ScanParams.iLines)
{
/* FinishScan( &s->HWParams ); *** FinishScan called in sane_cancel */
DBG (DBG_MSG, "sane_read: EOF\n");
return SANE_STATUS_EOF;
}
/* read as many lines the buffer may contain and while there are lines to be read */
while ((*len + s->ScanParams.iBytesPerLine <= maxlen)
&& (s->ScanParams.iLinesRead < s->ScanParams.iLines))
{
/* get one more line from the circular buffer */
CircBufferGetLine (s->HWParams.iXferHandle, &s->HWParams.pipe, buffer);
/* increment pointer, size and line number */
buffer += s->ScanParams.iBytesPerLine;
*len += s->ScanParams.iBytesPerLine;
s->ScanParams.iLinesRead++;
}
DBG (DBG_MSG, "sane_read: %d bytes read\n", *len);
return SANE_STATUS_GOOD;
}
void
sane_cancel (SANE_Handle h)
{
TScanner *s;
DBG (DBG_MSG, "sane_cancel\n");
s = (TScanner *) h;
/* to be implemented more thoroughly */
/* Make sure the scanner head returns home */
FinishScan (&s->HWParams);
s->fCanceled = TRUE;
s->fScanning = FALSE;
}
SANE_Status
sane_set_io_mode (SANE_Handle h, SANE_Bool m)
{
DBG (DBG_MSG, "sane_set_io_mode %s\n", m ? "non-blocking" : "blocking");
/* prevent compiler from complaining about unused parameters */
h = h;
if (m)
{
return SANE_STATUS_UNSUPPORTED;
}
return SANE_STATUS_GOOD;
}
SANE_Status
sane_get_select_fd (SANE_Handle h, SANE_Int * fd)
{
DBG (DBG_MSG, "sane_select_fd\n");
/* prevent compiler from complaining about unused parameters */
h = h;
fd = fd;
return SANE_STATUS_UNSUPPORTED;
}

Wyświetl plik

@ -0,0 +1,14 @@
# hp5400.conf
# See man sane-hp5400 for a description.
#
# HP 5400C
usb 0x03F0 0x1005
#
# HP 5470C
usb 0x03F0 0x1105
#
# Device filename to use for scanner access
#
# Uncomment the following line if autodetection fails
#
#/dev/usbscanner

119
backend/hp5400.h 100644
Wyświetl plik

@ -0,0 +1,119 @@
/* sane - Scanner Access Now Easy.
Copyright (C) 2003 Martijn van Oosterhout <kleptog@svana.org>
Originally copied from HP3300 testtools. Original notice follows:
Copyright (C) 2001 Bertrik Sikken (bertrik@zonnet.nl)
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.
$Id$
*/
/*
Core HP5400 functions.
*/
#ifndef _HP5400_H_
#define _HP5400_H_
#include <unistd.h>
#include "hp5400_xfer.h" /* for EScannerModel */
#define HW_DPI 300 /* horizontal resolution of hardware */
#define HW_LPI 300 /* vertical resolution of hardware */
enum ScanType
{
SCAN_TYPE_CALIBRATION,
SCAN_TYPE_PREVIEW,
SCAN_TYPE_NORMAL
};
/* In case we ever need to track multiple models */
typedef struct
{
char *pszVendor;
char *pszName;
}
TScannerModel;
typedef struct
{
/* transfer buffer */
void *buffer; /* Pointer to memory allocated for buffer */
int roff, goff, boff; /* Offset into buffer of rows to be copied *next* */
int bufstart, bufend; /* What is currently the valid buffer */
int bpp; /* Bytes per pixel per colour (1 or 2) */
int linelength, pixels; /* Bytes per line from scanner */
int transfersize; /* Number of bytes to transfer resulting image */
int blksize; /* Size of blocks to pull from scanner */
int buffersize; /* Size of the buffer */
}
TDataPipe;
typedef struct
{
int iXferHandle; /* handle used for data transfer to HW */
TDataPipe pipe; /* Pipe for data */
int iTopLeftX; /* in mm */
int iTopLeftY; /* in mm */
/* int iSensorSkew; *//* in units of 1/1200 inch */
/* int iSkipLines; *//* lines of garbage to skip */
/* int fReg07; *//* NIASH00019 */
/* int fGamma16; *//* if TRUE, gamma entries are 16 bit */
/* int iExpTime; */
/* int iReversedHead; *//* Head is reversed */
/* int iBufferSize; *//* Size of internal scan buffer */
/* EScannerModel eModel; */
}
THWParams;
/* The scanner needs a Base DPI off which all it's calibration and
* offset/size parameters are based. For the time being this is the same as
* the iDpi but maybe we want it seperate. This is because while this field
* would have limited values (300,600,1200,2400) the x/y dpi can vary. The
* windows interface seems to allow 200dpi (though I've never tried it). We
* need to decide how these values are related to the HW coordinates. */
typedef struct
{
int iDpi; /* horizontal resolution */
int iLpi; /* vertical resolution */
int iTop; /* in HW coordinates (units HW_LPI) */
int iLeft; /* in HW coordinates (units HW_LPI) */
int iWidth; /* in HW coordinates (units HW_LPI) */
int iHeight; /* in HW coordinates (units HW_LPI) */
int iBytesPerLine; /* Resulting bytes per line */
int iLines; /* Resulting lines of image */
int iLinesRead; /* Lines of image already read */
int iColourOffset; /* How far the colours are offset. Currently this is
* set by the caller. This doesn't seem to be
* necessary anymore since the scanner is doing it
* internally. Leave it for the time being as it
* may be needed later. */
}
TScanParams;
#endif /* NO _HP5400_H_ */

Plik diff jest za duży Load Diff

Wyświetl plik

@ -0,0 +1,355 @@
/* sane - Scanner Access Now Easy.
(c) 2003 Henning Meier-Geinitz, <henning@meier-geinitz.de>
(c) 2003 Martijn van Oosterhout, kleptog@svana.org
(c) 2002 Bertrik Sikken, bertrik@zonnet.nl
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.
Transport layer for communication with HP5400/5470 scanner.
Implementation using sanei_usb
Additions to support bulk data transport. Added debugging info - 19/02/2003 Martijn
Changed to use sanei_usb instead of direct /dev/usb/scanner access - 15/04/2003 Henning
*/
#include "hp5400_xfer.h"
#include <stdio.h>
#include "../include/sane/sanei_usb.h"
#define CMD_INITBULK1 0x0087 /* send 0x14 */
#define CMD_INITBULK2 0x0083 /* send 0x24 */
#define CMD_INITBULK3 0x0082 /* transfer length 0xf000 */
static void
_UsbWriteControl (int fd, int iValue, int iIndex, void *pabData, int iSize)
{
int requesttype = USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_OUT;
int request = (iSize > 1) ? 0x04 : 0x0C;
DBG (DBG_MSG,
"Write: reqtype = 0x%02X, req = 0x%02X, value = %04X, len = %d\n",
requesttype, request, iValue, iSize);
if (iSize > 0)
{
int i;
DBG (DBG_MSG, " Data: ");
for (i = 0; i < iSize && i < 8; i++)
DBG (DBG_MSG, "%02X ", ((unsigned char *) pabData)[i]);
if (iSize > 8)
DBG (DBG_MSG, "...");
DBG (DBG_MSG, "\n");
}
if (fd != -1)
{
sanei_usb_control_msg (fd, requesttype, request, iValue, iIndex, iSize,
pabData);
}
/* No error checking? */
}
void
hp5400_command_write_noverify (int fd, int iValue, void *pabData, int iSize)
{
_UsbWriteControl (fd, iValue, 0, pabData, iSize);
}
static void
_UsbReadControl (int fd, int iValue, int iIndex, void *pabData, int iSize)
{
int requesttype = USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN;
int request = (iSize > 1) ? 0x04 : 0x0C;
DBG (DBG_MSG, "Read: reqtype = 0x%02X, req = 0x%02X, value = %04X\n",
requesttype, request, iValue);
if (fd != -1)
{
sanei_usb_control_msg (fd, requesttype, request, iValue, iIndex, iSize,
pabData);
}
}
int
hp5400_open (const char *filename)
{
int fd, iVendor, iProduct;
SANE_Status status;
if (!filename)
filename = "/dev/usb/scanner0";
status = sanei_usb_open (filename, &fd);
if (status != SANE_STATUS_GOOD)
{
DBG (DBG_MSG, "hp5400_open: open returned %s\n",
sane_strstatus (status));
return -1;
}
status = sanei_usb_get_vendor_product (fd, &iVendor, &iProduct);
if (status != SANE_STATUS_GOOD)
{
DBG (DBG_MSG, "hp5400_open: can't get vendor/product ids: %s\n",
sane_strstatus (status));
sanei_usb_close (fd);
return -1;
}
if ((iVendor != 0x03F0) || ((iProduct != 0x1005) && (iProduct != 0x1105)))
{
DBG (DBG_MSG, "hp5400_open: vendor/product 0x%04X-0x%04X is not "
"supported\n", iVendor, iProduct);
sanei_usb_close (fd);
return -1;
}
DBG (DBG_MSG, "vendor/product 0x%04X-0x%04X opened\n", iVendor, iProduct);
return fd;
}
void
hp5400_close (int iHandle)
{
sanei_usb_close (iHandle);
}
/* returns value > 0 if verify ok */
int
hp5400_command_verify (int iHandle, int iCmd)
{
unsigned char abData[4];
int fd;
if (iHandle < 0)
{
DBG (DBG_ERR, "hp5400_command_verify: invalid handle\n");
return -1;
}
fd = iHandle;
/* command 0xc500: read back previous command */
_UsbReadControl (fd, 0xc500, 0, (char *) abData, 2);
if (abData[0] != (iCmd >> 8))
{
DBG (DBG_ERR,
"hp5400_command_verify failed, expected 0x%02X%02X, got 0x%02X%02X\n",
(int) (iCmd >> 8), (int) (iCmd & 0xff), (int) abData[0],
(int) abData[1]);
return -1;
}
if (abData[1] != 0) /* Error code non-zero */
{
_UsbReadControl (fd, 0x0300, 0, (char *) abData, 3);
DBG (DBG_ERR, " error response is: %02X %02X %02X\n", abData[0],
abData[1], abData[2]);
return -1;
}
DBG (DBG_MSG, "Command %02X verified\n", abData[0]);
return 1;
}
/* returns > 0 if command OK */
int
hp5400_command_read_noverify (int iHandle, int iCmd, int iLen, void *pbData)
{
int fd;
if (iHandle < 0)
{
DBG (DBG_ERR, "hp5400_command_read: invalid handle\n");
return -1;
}
fd = iHandle;
_UsbReadControl (fd, iCmd, 0, pbData, iLen);
return 1;
}
/* returns > 0 if command OK */
int
hp5400_command_read (int iHandle, int iCmd, int iLen, void *pbData)
{
hp5400_command_read_noverify (iHandle, iCmd, iLen, pbData);
return hp5400_command_verify (iHandle, iCmd);
}
/* returns >0 if command OK */
int
hp5400_command_write (int iHandle, int iCmd, int iLen, void *pbData)
{
int fd;
if (iHandle < 0)
{
DBG (DBG_ERR, "hp5400_command_write: invalid handle\n");
return -1;
}
fd = iHandle;
_UsbWriteControl (fd, iCmd, 0, (char *) pbData, iLen);
return hp5400_command_verify (iHandle, iCmd);
}
/* returns >0 if command OK */
int
hp5400_bulk_read (int iHandle, int len, int block, FILE * file)
{
int fd;
char x1 = 0x14, x2 = 0x24;
short buf[4] = { 0, 0, 0, 0 };
unsigned char *buffer;
int res = 0;
buf[2] = block;
if (iHandle < 0)
{
DBG (DBG_ERR, "hp5400_command_read: invalid handle\n");
return -1;
}
fd = iHandle;
buffer = malloc (block);
_UsbWriteControl (fd, CMD_INITBULK1, 0, &x1, 1);
_UsbWriteControl (fd, CMD_INITBULK2, 0, &x2, 1);
while (len > 0)
{
_UsbWriteControl (fd, CMD_INITBULK3, 0, (unsigned char *) &buf,
sizeof (buf));
res = block;
sanei_usb_read_bulk (fd, buffer, &res);
DBG (DBG_MSG, "Read bulk returned %d, %d remain\n", res, len);
if (res > 0)
{
fwrite (buffer, (len < res) ? len : res, 1, file);
}
len -= block;
}
/* error handling? */
return 0;
}
/* returns >0 if command OK */
int
hp5400_bulk_read_block (int iHandle, int iCmd, void *cmd, int cmdlen,
void *buffer, int len)
{
int fd;
int res = 0;
if (iHandle < 0)
{
DBG (DBG_ERR, "hp5400_command_write: invalid handle\n");
return -1;
}
fd = iHandle;
_UsbWriteControl (fd, iCmd, 0, cmd, cmdlen);
res = len;
sanei_usb_read_bulk (fd, buffer, &res);
DBG (DBG_MSG, "Read block returned %d when reading %d\n", res, len);
return res;
}
/* returns >0 if command OK */
int
hp5400_bulk_command_write (int iHandle, int iCmd, void *cmd, int cmdlen,
int datalen, int block, char *data)
{
int fd;
int res = 0, offset = 0;
if (iHandle < 0)
{
DBG (DBG_ERR, "hp5400_command_write: invalid handle\n");
return -1;
}
fd = iHandle;
DBG (DBG_MSG, "bulk_command_write(%04X,<%d bytes>,<%d bytes>)\n", iCmd,
cmdlen, datalen);
_UsbWriteControl (fd, iCmd, 0, cmd, cmdlen);
while (datalen > 0)
{
{
int i;
DBG (DBG_MSG, " Data: ");
for (i = 0; i < datalen && i < block && i < 8; i++)
DBG (DBG_MSG, "%02X ", ((unsigned char *) data + offset)[i]);
if (i >= 8)
DBG (DBG_MSG, "...");
DBG (DBG_MSG, "\n");
}
res = (datalen < block) ? datalen : block;
sanei_usb_write_bulk (fd, data + offset, &res);
DBG (DBG_MSG, "Write returned %d, %d remain\n", res, datalen);
datalen -= block;
offset += block;
}
return hp5400_command_verify (iHandle, iCmd);
}
/**
ScannerIsOn
retrieve on/off status from scanner
@return 1 if is on 0 if is off -1 if is not reachable
*/
int
hp5400_isOn (int iHandle)
{
unsigned char text2400[3];
hp5400_command_read (iHandle, 0x2400, 0x03, text2400);
/* byte 0 indicates if is on or off if 0x02 */
/* byte 1 indicates time since is on */
/* byte 2 indicates time since is power plugged */
if (text2400[0] & 0x02)
{
return 1; /* is on */
}
return 0; /* is off */
}

Wyświetl plik

@ -0,0 +1,42 @@
/* sane - Scanner Access Now Easy.
(c) 2003 Martijn van Oosterhout, kleptog@svana.org
(c) 2002 Bertrik Sikken, bertrik@zonnet.nl
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.
Transport layer for communication with HP5400/5470 scanner.
Add support for bulk transport of data - 19/02/2003 Martijn
*/
static int hp5400_open (const char *filename);
static void hp5400_close (int iHandle);
static int hp5400_command_verify (int iHandle, int iCmd);
static int hp5400_command_read (int iHandle, int iCmd, int iLen, void *pbData);
static int hp5400_command_read_noverify (int iHandle, int iCmd, int iLen,
void *pbData);
static int hp5400_command_write (int iHandle, int iCmd, int iLen, void *pbData);
static void hp5400_command_write_noverify (int fd, int iValue, void *pabData,
int iSize);
static int hp5400_bulk_read (int iHandle, int size, int block, FILE * file);
static int hp5400_bulk_read_block (int iHandle, int iCmd, void *cmd, int cmdlen,
void *buffer, int len);
static int hp5400_bulk_command_write (int iHandle, int iCmd, void *cmd, int cmdlen,
int len, int block, char *data);
static int hp5400_isOn (int iHandle);

Wyświetl plik

@ -51,7 +51,7 @@ SECT5 = sane-abaton.5 sane-agfafocus.5 sane-apple.5 sane-as6e.5 sane-dll.5 \
sane-mustek_usb.5 sane-sceptre.5 sane-canon_pp.5 sane-canon630u.5 \
sane-teco1.5 sane-teco2.5 sane-teco3.5 sane-test.5 sane-sp15c.5 \
sane-coolscan2.5 sane-hpsj5s.5 sane-gt68xx.5 sane-artec_eplus48u.5 \
sane-ma1509.5 sane-ibm.5
sane-ma1509.5 sane-ibm.5 sane-hp5400.5
SECT7 = sane.7
MANPAGES = $(SECT1) $(SECT5) $(SECT7)
READMES = README AUTHORS COPYING ChangeLog LICENSE NEWS PROBLEMS \
@ -90,7 +90,7 @@ DISTFILES = Makefile.in backend-writing.txt descriptions.txt \
sane.tex saned.man scanimage.man sane-sceptre.man sane-canon_pp.man \
sane-teco1.man sane-teco2.man sane-teco3.man sane-test.man sane-sp15c.man \
sane-hpsj5s.man gamma4scanimage.man sane-gt68xx.man sane-artec_eplus48u.man \
sane-ma1509.man sane-ibm.man
sane-ma1509.man sane-ibm.man sane-hp5400.man
.PHONY: all clean depend dist distclean html html-man install \
install-mostang sane-html uninstall

102
doc/sane-hp5400.man 100644
Wyświetl plik

@ -0,0 +1,102 @@
.TH sane-hp5400 5 "17 Apr 2003" "@PACKAGEVERSION@" "SANE Scanner Access Now Easy"
.IX sane-hp5400
.SH NAME
sane-hp5400 \- SANE backend for Hewlett-Packard 54XX scanners
.SH DESCRIPTION
The
.B sane-hp5400
library implements a SANE (Scanner Access Now Easy) backend that provides
access to the following Hewlett-Packard USB flatbed scanners:
.PP
.RS
ScanJet 5400C
.br
ScanJet 5470C
.br
ScanJet 5490C
.RE
.PP
More details can be found on the hp5400 backend homepage
.IR http://hp5400backend.sourceforge.net/ .
.PP
This is ALPHA software. Keep your hand at the scanner's plug and unplug it, if
the head bumps at the end of the scan area. See also the BUGS section.
.PP
If you own a scanner other than the ones listed above that works with this
backend, please let us know this by sending the scanner's exact model name and
the USB vendor and device ids (e.g. from
.IR /proc/bus/usb/devices ,
.I sane-find-scanner
or syslog) to us. Even if the scanner's name is only slightly different from
the models mentioned above, please let us know.
.PP
.SH CONFIGURATION
The contents of the
.I hp5400.conf
file is a list of usb lines containing vendor and product ids that correspond
to USB scanners. The file can also contain the names of device files that
correspond to an HP 54XX scanner. Empty lines and lines starting with a hash
mark (#) are ignored. The scanners are autodetected by
.B usb vendor_id product_id
statements which are already included into
.IR hp5400.conf .
"vendor_id" and "product_id" are hexadecimal numbers that identify the
scanner. If autodetection does not work, add the device name of your scanner
to the configuration file, e.g.
.IR /dev/usb/scanner0 .
.PP
.SH FILES
.TP
.I @CONFIGDIR@/hp5400.conf
The backend configuration file (see also description of
.B SANE_CONFIG_DIR
below).
.TP
.I @LIBDIR@/libsane-hp5400.a
The static library implementing this backend.
.TP
.I @LIBDIR@/libsane-hp5400.so
The shared library implementing this backend (present on systems that
support dynamic loading).
.SH ENVIRONMENT
.TP
.B SANE_CONFIG_DIR
This environment variable specifies the list of directories that may
contain the configuration file. Under UNIX, the directories are
separated by a colon (`:'), under OS/2, they are separated by a
semi-colon (`;'). If this variable is not set, the configuration file
is searched in two default directories: first, the current working
directory (".") and then in @CONFIGDIR@. If the value of the
environment variable ends with the directory separator character, then
the default directories are searched after the explicitly specified
directories. For example, setting
.B SANE_CONFIG_DIR
to "/tmp/config:" would result in directories "tmp/config", ".", and
"@CONFIGDIR@" being searched (in this order).
.TP
.B SANE_DEBUG_HP5400
If the library was compiled with debug support enabled, this
environment variable controls the debug level for this backend. Higher
debug levels increase the verbosity of the output.
Example:
export SANE_DEBUG_HP5400=4
.SH "SEE ALSO"
.BR sane (7),
.BR sane\-usb (5),
.br
.I http://hp5400backend.sourceforge.net/
.SH AUTHOR
Martijn van Oosterhout <kleptog@svana.org>, Thomas Soumarmon
<soumarmt@nerim.net>. Manpage by Henning Meier-Geinitz
<henning@meier-geinitz.de>.
.SH BUGS
Scanning is only tested with Linux/ix86/gcc. Be careful when testing on other
operating systems and especially on big-endian platforms. The scanner may get
wrong data.

Wyświetl plik

@ -1,4 +1,4 @@
.TH sane 7 "14 Apr 2003" "@PACKAGEVERSION@" "SANE Scanner Access Now Easy"
.TH sane 7 "17 Apr 2003" "@PACKAGEVERSION@" "SANE Scanner Access Now Easy"
.IX sane
.SH NAME
@ -260,6 +260,11 @@ The SANE backend for the Hewlett-Packard ScanJet 5S scanner. See
.BR sane\-hpsj5s (5)
for details.
.TP
.B hp5400
The SANE backend for the Hewlett-Packard ScanJet 54XXC series. See
.BR sane\-hp5400 (5)
for details.
.TP
.B ibm
The SANE backend for some IBM and Ricoh SCSI scanners. See
.BR sane\-ibm (5)
@ -798,6 +803,7 @@ you can also contact the author of this manual page:
.BR sane\-gt68xx (5),
.BR sane\-hp (5),
.BR sane\-hpsj5s (5),
.BR sane\-hp5400 (5)
.BR sane\-ibm (5),
.BR sane\-leo (5),
.BR sane\-ma1509 (5),