kopia lustrzana https://gitlab.com/sane-project/backends
				
				
				
			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
							rodzic
							
								
									a563d4735d
								
							
						
					
					
						commit
						517751ff09
					
				
							
								
								
									
										7
									
								
								AUTHORS
								
								
								
								
							
							
						
						
									
										7
									
								
								AUTHORS
								
								
								
								
							|  | @ -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> | ||||
|  |  | |||
							
								
								
									
										12
									
								
								ChangeLog
								
								
								
								
							
							
						
						
									
										12
									
								
								ChangeLog
								
								
								
								
							|  | @ -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. | ||||
|  |  | |||
|  | @ -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 | ||||
|  |  | |||
|  | @ -23,6 +23,7 @@ fujitsu | |||
| gt68xx | ||||
| hp | ||||
| hpsj5s | ||||
| hp5400 | ||||
| ibm | ||||
| leo | ||||
| ma1509 | ||||
|  |  | |||
|  | @ -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; | ||||
| } | ||||
|  | @ -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 | ||||
|  | @ -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
											
										
									
								
							|  | @ -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 */ | ||||
| } | ||||
|  | @ -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); | ||||
|  | @ -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 | ||||
|  |  | |||
|  | @ -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. | ||||
| 
 | ||||
|  | @ -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), | ||||
|  |  | |||
		Ładowanie…
	
		Reference in New Issue
	
	 Henning Geinitz
						Henning Geinitz