1141cc406Sopenharmony_ci/* sane - Scanner Access Now Easy. 2141cc406Sopenharmony_ci Copyright (C) 2020 Ralph Little <skelband@gmail.com> 3141cc406Sopenharmony_ci Copyright (C) 2003 Martijn van Oosterhout <kleptog@svana.org> 4141cc406Sopenharmony_ci Copyright (C) 2003 Thomas Soumarmon <thomas.soumarmon@cogitae.net> 5141cc406Sopenharmony_ci 6141cc406Sopenharmony_ci Originally copied from HP3300 testtools. Original notice follows: 7141cc406Sopenharmony_ci 8141cc406Sopenharmony_ci Copyright (C) 2001 Bertrik Sikken (bertrik@zonnet.nl) 9141cc406Sopenharmony_ci 10141cc406Sopenharmony_ci This file is part of the SANE package. 11141cc406Sopenharmony_ci 12141cc406Sopenharmony_ci This program is free software; you can redistribute it and/or 13141cc406Sopenharmony_ci modify it under the terms of the GNU General Public License 14141cc406Sopenharmony_ci as published by the Free Software Foundation; either version 2 15141cc406Sopenharmony_ci of the License, or (at your option) any later version. 16141cc406Sopenharmony_ci 17141cc406Sopenharmony_ci This program is distributed in the hope that it will be useful, 18141cc406Sopenharmony_ci but WITHOUT ANY WARRANTY; without even the implied warranty of 19141cc406Sopenharmony_ci MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 20141cc406Sopenharmony_ci GNU General Public License for more details. 21141cc406Sopenharmony_ci 22141cc406Sopenharmony_ci You should have received a copy of the GNU General Public License 23141cc406Sopenharmony_ci along with this program. If not, see <https://www.gnu.org/licenses/>. 24141cc406Sopenharmony_ci 25141cc406Sopenharmony_ci As a special exception, the authors of SANE give permission for 26141cc406Sopenharmony_ci additional uses of the libraries contained in this release of SANE. 27141cc406Sopenharmony_ci 28141cc406Sopenharmony_ci The exception is that, if you link a SANE library with other files 29141cc406Sopenharmony_ci to produce an executable, this does not by itself cause the 30141cc406Sopenharmony_ci resulting executable to be covered by the GNU General Public 31141cc406Sopenharmony_ci License. Your use of that executable is in no way restricted on 32141cc406Sopenharmony_ci account of linking the SANE library code into it. 33141cc406Sopenharmony_ci 34141cc406Sopenharmony_ci This exception does not, however, invalidate any other reasons why 35141cc406Sopenharmony_ci the executable file might be covered by the GNU General Public 36141cc406Sopenharmony_ci License. 37141cc406Sopenharmony_ci 38141cc406Sopenharmony_ci If you submit changes to SANE to the maintainers to be included in 39141cc406Sopenharmony_ci a subsequent release, you agree by submitting the changes that 40141cc406Sopenharmony_ci those changes may be distributed with this exception intact. 41141cc406Sopenharmony_ci 42141cc406Sopenharmony_ci If you write modifications of your own for SANE, it is your choice 43141cc406Sopenharmony_ci whether to permit this exception to apply to your modifications. 44141cc406Sopenharmony_ci If you do not wish that, delete this exception notice. 45141cc406Sopenharmony_ci*/ 46141cc406Sopenharmony_ci 47141cc406Sopenharmony_ci 48141cc406Sopenharmony_ci/* 49141cc406Sopenharmony_ci SANE interface for hp54xx scanners. Prototype. 50141cc406Sopenharmony_ci Parts of this source were inspired by other backends. 51141cc406Sopenharmony_ci*/ 52141cc406Sopenharmony_ci 53141cc406Sopenharmony_ci#include "../include/sane/config.h" 54141cc406Sopenharmony_ci 55141cc406Sopenharmony_ci/* definitions for debug */ 56141cc406Sopenharmony_ci#include "hp5400_debug.h" 57141cc406Sopenharmony_ci 58141cc406Sopenharmony_ci#include "../include/sane/sane.h" 59141cc406Sopenharmony_ci#include "../include/sane/sanei.h" 60141cc406Sopenharmony_ci#include "../include/sane/sanei_backend.h" 61141cc406Sopenharmony_ci#include "../include/sane/sanei_config.h" 62141cc406Sopenharmony_ci#include "../include/sane/saneopts.h" 63141cc406Sopenharmony_ci#include "../include/sane/sanei_usb.h" 64141cc406Sopenharmony_ci 65141cc406Sopenharmony_ci#include <stdlib.h> /* malloc, free */ 66141cc406Sopenharmony_ci#include <string.h> /* memcpy */ 67141cc406Sopenharmony_ci#include <stdio.h> 68141cc406Sopenharmony_ci#include <errno.h> 69141cc406Sopenharmony_ci 70141cc406Sopenharmony_ci#define HP5400_CONFIG_FILE "hp5400.conf" 71141cc406Sopenharmony_ci 72141cc406Sopenharmony_ci#include "hp5400.h" 73141cc406Sopenharmony_ci 74141cc406Sopenharmony_ci/* other definitions */ 75141cc406Sopenharmony_ci#ifndef min 76141cc406Sopenharmony_ci#define min(A,B) (((A)<(B)) ? (A) : (B)) 77141cc406Sopenharmony_ci#endif 78141cc406Sopenharmony_ci#ifndef max 79141cc406Sopenharmony_ci#define max(A,B) (((A)>(B)) ? (A) : (B)) 80141cc406Sopenharmony_ci#endif 81141cc406Sopenharmony_ci 82141cc406Sopenharmony_ci#define TRUE 1 83141cc406Sopenharmony_ci#define FALSE 0 84141cc406Sopenharmony_ci 85141cc406Sopenharmony_ci#define MM_TO_PIXEL(_mm_, _dpi_) ((_mm_) * (_dpi_) / 25.4) 86141cc406Sopenharmony_ci#define PIXEL_TO_MM(_pixel_, _dpi_) ((_pixel_) * 25.4 / (_dpi_)) 87141cc406Sopenharmony_ci 88141cc406Sopenharmony_ci#define NUM_GAMMA_ENTRIES 65536 89141cc406Sopenharmony_ci 90141cc406Sopenharmony_ci 91141cc406Sopenharmony_ci/* options enumerator */ 92141cc406Sopenharmony_citypedef enum 93141cc406Sopenharmony_ci{ 94141cc406Sopenharmony_ci optCount = 0, 95141cc406Sopenharmony_ci 96141cc406Sopenharmony_ci optDPI, 97141cc406Sopenharmony_ci 98141cc406Sopenharmony_ci optGroupGeometry, 99141cc406Sopenharmony_ci optTLX, optTLY, optBRX, optBRY, 100141cc406Sopenharmony_ci 101141cc406Sopenharmony_ci optGroupEnhancement, 102141cc406Sopenharmony_ci 103141cc406Sopenharmony_ci optGammaTableRed, /* Gamma Tables */ 104141cc406Sopenharmony_ci optGammaTableGreen, 105141cc406Sopenharmony_ci optGammaTableBlue, 106141cc406Sopenharmony_ci 107141cc406Sopenharmony_ci optGroupSensors, 108141cc406Sopenharmony_ci 109141cc406Sopenharmony_ci optSensorScanTo, 110141cc406Sopenharmony_ci optSensorWeb, 111141cc406Sopenharmony_ci optSensorReprint, 112141cc406Sopenharmony_ci optSensorEmail, 113141cc406Sopenharmony_ci optSensorCopy, 114141cc406Sopenharmony_ci optSensorMoreOptions, 115141cc406Sopenharmony_ci optSensorCancel, 116141cc406Sopenharmony_ci optSensorPowerSave, 117141cc406Sopenharmony_ci optSensorCopiesUp, 118141cc406Sopenharmony_ci optSensorCopiesDown, 119141cc406Sopenharmony_ci optSensorColourBW, 120141cc406Sopenharmony_ci 121141cc406Sopenharmony_ci optSensorColourBWState, 122141cc406Sopenharmony_ci optSensorCopyCount, 123141cc406Sopenharmony_ci 124141cc406Sopenharmony_ci // Unsupported as yet. 125141cc406Sopenharmony_ci //optGroupMisc, 126141cc406Sopenharmony_ci //optLamp, 127141cc406Sopenharmony_ci //optCalibrate, 128141cc406Sopenharmony_ci 129141cc406Sopenharmony_ci optLast, /* Disable the offset code */ 130141cc406Sopenharmony_ci} 131141cc406Sopenharmony_ciEOptionIndex; 132141cc406Sopenharmony_ci 133141cc406Sopenharmony_ci/* 134141cc406Sopenharmony_ci * Array mapping (optSensor* - optGroupSensors - 1) to the bit mask of the 135141cc406Sopenharmony_ci * corresponding sensor bit that we get from the scanner. 136141cc406Sopenharmony_ci * All sensor bits are reported as a complete 16-bit word with individual bits set 137141cc406Sopenharmony_ci * to indicate that the sensor has been activated. 138141cc406Sopenharmony_ci * They seem to be latched so that they are picked up on next query and a number 139141cc406Sopenharmony_ci * of bits can be set in any one query. 140141cc406Sopenharmony_ci * 141141cc406Sopenharmony_ci */ 142141cc406Sopenharmony_ci 143141cc406Sopenharmony_ci#define SENSOR_BIT_SCAN 0x0400 144141cc406Sopenharmony_ci#define SENSOR_BIT_WEB 0x0200 145141cc406Sopenharmony_ci#define SENSOR_BIT_REPRINT 0x0002 146141cc406Sopenharmony_ci#define SENSOR_BIT_EMAIL 0x0080 147141cc406Sopenharmony_ci#define SENSOR_BIT_COPY 0x0040 148141cc406Sopenharmony_ci#define SENSOR_BIT_MOREOPTIONS 0x0004 149141cc406Sopenharmony_ci#define SENSOR_BIT_CANCEL 0x0100 150141cc406Sopenharmony_ci#define SENSOR_BIT_POWERSAVE 0x2000 151141cc406Sopenharmony_ci#define SENSOR_BIT_COPIESUP 0x0008 152141cc406Sopenharmony_ci#define SENSOR_BIT_COPIESDOWN 0x0020 153141cc406Sopenharmony_ci#define SENSOR_BIT_COLOURBW 0x0010 154141cc406Sopenharmony_ci 155141cc406Sopenharmony_ci 156141cc406Sopenharmony_ciuint16_t sensorMaskMap[] = 157141cc406Sopenharmony_ci{ 158141cc406Sopenharmony_ci SENSOR_BIT_SCAN, 159141cc406Sopenharmony_ci SENSOR_BIT_WEB, 160141cc406Sopenharmony_ci SENSOR_BIT_REPRINT, 161141cc406Sopenharmony_ci SENSOR_BIT_EMAIL, 162141cc406Sopenharmony_ci SENSOR_BIT_COPY, 163141cc406Sopenharmony_ci SENSOR_BIT_MOREOPTIONS, 164141cc406Sopenharmony_ci SENSOR_BIT_CANCEL, 165141cc406Sopenharmony_ci 166141cc406Sopenharmony_ci // Special buttons. 167141cc406Sopenharmony_ci // These affect local machine settings, but we can still detect them being pressed. 168141cc406Sopenharmony_ci SENSOR_BIT_POWERSAVE, 169141cc406Sopenharmony_ci SENSOR_BIT_COPIESUP, 170141cc406Sopenharmony_ci SENSOR_BIT_COPIESDOWN, 171141cc406Sopenharmony_ci SENSOR_BIT_COLOURBW, 172141cc406Sopenharmony_ci 173141cc406Sopenharmony_ci // Extra entries to make the array up to the 16 possible bits. 174141cc406Sopenharmony_ci 0x0000, // Unused 175141cc406Sopenharmony_ci 0x0000, // Unused 176141cc406Sopenharmony_ci 0x0000, // Unused 177141cc406Sopenharmony_ci 0x0000, // Unused 178141cc406Sopenharmony_ci 0x0000 // Unused 179141cc406Sopenharmony_ci}; 180141cc406Sopenharmony_ci 181141cc406Sopenharmony_citypedef union 182141cc406Sopenharmony_ci{ 183141cc406Sopenharmony_ci SANE_Word w; 184141cc406Sopenharmony_ci SANE_Word *wa; /* word array */ 185141cc406Sopenharmony_ci SANE_String s; 186141cc406Sopenharmony_ci} 187141cc406Sopenharmony_ciTOptionValue; 188141cc406Sopenharmony_ci 189141cc406Sopenharmony_ci 190141cc406Sopenharmony_citypedef struct 191141cc406Sopenharmony_ci{ 192141cc406Sopenharmony_ci SANE_Option_Descriptor aOptions[optLast]; 193141cc406Sopenharmony_ci TOptionValue aValues[optLast]; 194141cc406Sopenharmony_ci 195141cc406Sopenharmony_ci TScanParams ScanParams; 196141cc406Sopenharmony_ci THWParams HWParams; 197141cc406Sopenharmony_ci 198141cc406Sopenharmony_ci TDataPipe DataPipe; 199141cc406Sopenharmony_ci int iLinesLeft; 200141cc406Sopenharmony_ci 201141cc406Sopenharmony_ci SANE_Int *aGammaTableR; /* a 16-to-16 bit color lookup table */ 202141cc406Sopenharmony_ci SANE_Int *aGammaTableG; /* a 16-to-16 bit color lookup table */ 203141cc406Sopenharmony_ci SANE_Int *aGammaTableB; /* a 16-to-16 bit color lookup table */ 204141cc406Sopenharmony_ci 205141cc406Sopenharmony_ci int fScanning; /* TRUE if actively scanning */ 206141cc406Sopenharmony_ci int fCanceled; 207141cc406Sopenharmony_ci 208141cc406Sopenharmony_ci uint16_t sensorMap; /* Contains the current unreported sensor bits. */ 209141cc406Sopenharmony_ci} 210141cc406Sopenharmony_ciTScanner; 211141cc406Sopenharmony_ci 212141cc406Sopenharmony_ci 213141cc406Sopenharmony_ci/* linked list of SANE_Device structures */ 214141cc406Sopenharmony_citypedef struct TDevListEntry 215141cc406Sopenharmony_ci{ 216141cc406Sopenharmony_ci struct TDevListEntry *pNext; 217141cc406Sopenharmony_ci SANE_Device dev; 218141cc406Sopenharmony_ci char* devname; 219141cc406Sopenharmony_ci} 220141cc406Sopenharmony_ciTDevListEntry; 221141cc406Sopenharmony_ci 222141cc406Sopenharmony_ci 223141cc406Sopenharmony_ci 224141cc406Sopenharmony_ci/* Device filename for USB access */ 225141cc406Sopenharmony_cichar usb_devfile[128]; 226141cc406Sopenharmony_ci 227141cc406Sopenharmony_cistatic TDevListEntry *_pFirstSaneDev = 0; 228141cc406Sopenharmony_cistatic int iNumSaneDev = 0; 229141cc406Sopenharmony_ci 230141cc406Sopenharmony_ci 231141cc406Sopenharmony_cistatic const SANE_Device **_pSaneDevList = 0; 232141cc406Sopenharmony_ci 233141cc406Sopenharmony_ci/* option constraints */ 234141cc406Sopenharmony_cistatic const SANE_Range rangeGammaTable = {0, 65535, 1}; 235141cc406Sopenharmony_cistatic const SANE_Range rangeCopyCountTable = {0, 99, 1}; 236141cc406Sopenharmony_cistatic SANE_String_Const modeSwitchList[] = { 237141cc406Sopenharmony_ci SANE_VALUE_SCAN_MODE_COLOR, 238141cc406Sopenharmony_ci SANE_VALUE_SCAN_MODE_GRAY, 239141cc406Sopenharmony_ci NULL 240141cc406Sopenharmony_ci}; 241141cc406Sopenharmony_ci#ifdef SUPPORT_2400_DPI 242141cc406Sopenharmony_cistatic const SANE_Int setResolutions[] = {6, 75, 150, 300, 600, 1200, 2400}; 243141cc406Sopenharmony_ci#else 244141cc406Sopenharmony_cistatic const SANE_Int setResolutions[] = {5, 75, 150, 300, 600, 1200}; 245141cc406Sopenharmony_ci#endif 246141cc406Sopenharmony_cistatic const SANE_Range rangeXmm = {0, 216, 1}; 247141cc406Sopenharmony_cistatic const SANE_Range rangeYmm = {0, 297, 1}; 248141cc406Sopenharmony_ci 249141cc406Sopenharmony_cistatic void _InitOptions(TScanner *s) 250141cc406Sopenharmony_ci{ 251141cc406Sopenharmony_ci int i, j; 252141cc406Sopenharmony_ci SANE_Option_Descriptor *pDesc; 253141cc406Sopenharmony_ci TOptionValue *pVal; 254141cc406Sopenharmony_ci 255141cc406Sopenharmony_ci /* set a neutral gamma */ 256141cc406Sopenharmony_ci if( s->aGammaTableR == NULL ) /* Not yet allocated */ 257141cc406Sopenharmony_ci { 258141cc406Sopenharmony_ci s->aGammaTableR = malloc( NUM_GAMMA_ENTRIES * sizeof( SANE_Int ) ); 259141cc406Sopenharmony_ci s->aGammaTableG = malloc( NUM_GAMMA_ENTRIES * sizeof( SANE_Int ) ); 260141cc406Sopenharmony_ci s->aGammaTableB = malloc( NUM_GAMMA_ENTRIES * sizeof( SANE_Int ) ); 261141cc406Sopenharmony_ci 262141cc406Sopenharmony_ci for (j = 0; j < NUM_GAMMA_ENTRIES; j++) { 263141cc406Sopenharmony_ci s->aGammaTableR[j] = j; 264141cc406Sopenharmony_ci s->aGammaTableG[j] = j; 265141cc406Sopenharmony_ci s->aGammaTableB[j] = j; 266141cc406Sopenharmony_ci } 267141cc406Sopenharmony_ci } 268141cc406Sopenharmony_ci 269141cc406Sopenharmony_ci for (i = optCount; i < optLast; i++) { 270141cc406Sopenharmony_ci 271141cc406Sopenharmony_ci pDesc = &s->aOptions[i]; 272141cc406Sopenharmony_ci pVal = &s->aValues[i]; 273141cc406Sopenharmony_ci 274141cc406Sopenharmony_ci /* defaults */ 275141cc406Sopenharmony_ci pDesc->name = ""; 276141cc406Sopenharmony_ci pDesc->title = ""; 277141cc406Sopenharmony_ci pDesc->desc = ""; 278141cc406Sopenharmony_ci pDesc->type = SANE_TYPE_INT; 279141cc406Sopenharmony_ci pDesc->unit = SANE_UNIT_NONE; 280141cc406Sopenharmony_ci pDesc->size = sizeof(SANE_Word); 281141cc406Sopenharmony_ci pDesc->constraint_type = SANE_CONSTRAINT_NONE; 282141cc406Sopenharmony_ci pDesc->cap = 0; 283141cc406Sopenharmony_ci 284141cc406Sopenharmony_ci switch (i) { 285141cc406Sopenharmony_ci 286141cc406Sopenharmony_ci case optCount: 287141cc406Sopenharmony_ci pDesc->title = SANE_TITLE_NUM_OPTIONS; 288141cc406Sopenharmony_ci pDesc->desc = SANE_DESC_NUM_OPTIONS; 289141cc406Sopenharmony_ci pDesc->cap = SANE_CAP_SOFT_DETECT; 290141cc406Sopenharmony_ci pVal->w = (SANE_Word)optLast; 291141cc406Sopenharmony_ci break; 292141cc406Sopenharmony_ci 293141cc406Sopenharmony_ci case optDPI: 294141cc406Sopenharmony_ci pDesc->name = SANE_NAME_SCAN_RESOLUTION; 295141cc406Sopenharmony_ci pDesc->title = SANE_TITLE_SCAN_RESOLUTION; 296141cc406Sopenharmony_ci pDesc->desc = SANE_DESC_SCAN_RESOLUTION; 297141cc406Sopenharmony_ci pDesc->unit = SANE_UNIT_DPI; 298141cc406Sopenharmony_ci pDesc->constraint_type = SANE_CONSTRAINT_WORD_LIST; 299141cc406Sopenharmony_ci pDesc->constraint.word_list = setResolutions; 300141cc406Sopenharmony_ci pDesc->cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT; 301141cc406Sopenharmony_ci pVal->w = setResolutions[1]; 302141cc406Sopenharmony_ci break; 303141cc406Sopenharmony_ci 304141cc406Sopenharmony_ci //--------------------------------- 305141cc406Sopenharmony_ci case optGroupGeometry: 306141cc406Sopenharmony_ci pDesc->name = SANE_NAME_GEOMETRY; 307141cc406Sopenharmony_ci pDesc->title = SANE_TITLE_GEOMETRY; 308141cc406Sopenharmony_ci pDesc->desc = SANE_DESC_GEOMETRY; 309141cc406Sopenharmony_ci pDesc->type = SANE_TYPE_GROUP; 310141cc406Sopenharmony_ci pDesc->size = 0; 311141cc406Sopenharmony_ci break; 312141cc406Sopenharmony_ci 313141cc406Sopenharmony_ci case optTLX: 314141cc406Sopenharmony_ci pDesc->name = SANE_NAME_SCAN_TL_X; 315141cc406Sopenharmony_ci pDesc->title = SANE_TITLE_SCAN_TL_X; 316141cc406Sopenharmony_ci pDesc->desc = SANE_DESC_SCAN_TL_X; 317141cc406Sopenharmony_ci pDesc->unit = SANE_UNIT_MM; 318141cc406Sopenharmony_ci pDesc->constraint_type = SANE_CONSTRAINT_RANGE; 319141cc406Sopenharmony_ci pDesc->constraint.range = &rangeXmm; 320141cc406Sopenharmony_ci pDesc->cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT; 321141cc406Sopenharmony_ci pVal->w = rangeXmm.min; 322141cc406Sopenharmony_ci break; 323141cc406Sopenharmony_ci 324141cc406Sopenharmony_ci case optTLY: 325141cc406Sopenharmony_ci pDesc->name = SANE_NAME_SCAN_TL_Y; 326141cc406Sopenharmony_ci pDesc->title = SANE_TITLE_SCAN_TL_Y; 327141cc406Sopenharmony_ci pDesc->desc = SANE_DESC_SCAN_TL_Y; 328141cc406Sopenharmony_ci pDesc->unit = SANE_UNIT_MM; 329141cc406Sopenharmony_ci pDesc->constraint_type = SANE_CONSTRAINT_RANGE; 330141cc406Sopenharmony_ci pDesc->constraint.range = &rangeYmm; 331141cc406Sopenharmony_ci pDesc->cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT; 332141cc406Sopenharmony_ci pVal->w = rangeYmm.min; 333141cc406Sopenharmony_ci break; 334141cc406Sopenharmony_ci 335141cc406Sopenharmony_ci case optBRX: 336141cc406Sopenharmony_ci pDesc->name = SANE_NAME_SCAN_BR_X; 337141cc406Sopenharmony_ci pDesc->title = SANE_TITLE_SCAN_BR_X; 338141cc406Sopenharmony_ci pDesc->desc = SANE_DESC_SCAN_BR_X; 339141cc406Sopenharmony_ci pDesc->unit = SANE_UNIT_MM; 340141cc406Sopenharmony_ci pDesc->constraint_type = SANE_CONSTRAINT_RANGE; 341141cc406Sopenharmony_ci pDesc->constraint.range = &rangeXmm; 342141cc406Sopenharmony_ci pDesc->cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT; 343141cc406Sopenharmony_ci pVal->w = rangeXmm.max; 344141cc406Sopenharmony_ci break; 345141cc406Sopenharmony_ci 346141cc406Sopenharmony_ci case optBRY: 347141cc406Sopenharmony_ci pDesc->name = SANE_NAME_SCAN_BR_Y; 348141cc406Sopenharmony_ci pDesc->title = SANE_TITLE_SCAN_BR_Y; 349141cc406Sopenharmony_ci pDesc->desc = SANE_DESC_SCAN_BR_Y; 350141cc406Sopenharmony_ci pDesc->unit = SANE_UNIT_MM; 351141cc406Sopenharmony_ci pDesc->constraint_type = SANE_CONSTRAINT_RANGE; 352141cc406Sopenharmony_ci pDesc->constraint.range = &rangeYmm; 353141cc406Sopenharmony_ci pDesc->cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT; 354141cc406Sopenharmony_ci pVal->w = rangeYmm.max; 355141cc406Sopenharmony_ci break; 356141cc406Sopenharmony_ci 357141cc406Sopenharmony_ci //--------------------------------- 358141cc406Sopenharmony_ci case optGroupEnhancement: 359141cc406Sopenharmony_ci pDesc->name = SANE_NAME_ENHANCEMENT; 360141cc406Sopenharmony_ci pDesc->title = SANE_TITLE_ENHANCEMENT; 361141cc406Sopenharmony_ci pDesc->desc = SANE_DESC_ENHANCEMENT; 362141cc406Sopenharmony_ci pDesc->type = SANE_TYPE_GROUP; 363141cc406Sopenharmony_ci pDesc->size = 0; 364141cc406Sopenharmony_ci break; 365141cc406Sopenharmony_ci 366141cc406Sopenharmony_ci case optGammaTableRed: 367141cc406Sopenharmony_ci pDesc->name = SANE_NAME_GAMMA_VECTOR_R; 368141cc406Sopenharmony_ci pDesc->title = SANE_TITLE_GAMMA_VECTOR_R; 369141cc406Sopenharmony_ci pDesc->desc = SANE_DESC_GAMMA_VECTOR_R; 370141cc406Sopenharmony_ci pDesc->size = NUM_GAMMA_ENTRIES * sizeof( SANE_Int ); 371141cc406Sopenharmony_ci pDesc->constraint_type = SANE_CONSTRAINT_RANGE; 372141cc406Sopenharmony_ci pDesc->constraint.range = &rangeGammaTable; 373141cc406Sopenharmony_ci pDesc->cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT; 374141cc406Sopenharmony_ci pVal->wa = s->aGammaTableR; 375141cc406Sopenharmony_ci break; 376141cc406Sopenharmony_ci 377141cc406Sopenharmony_ci case optGammaTableGreen: 378141cc406Sopenharmony_ci pDesc->name = SANE_NAME_GAMMA_VECTOR_G; 379141cc406Sopenharmony_ci pDesc->title = SANE_TITLE_GAMMA_VECTOR_G; 380141cc406Sopenharmony_ci pDesc->desc = SANE_DESC_GAMMA_VECTOR_G; 381141cc406Sopenharmony_ci pDesc->size = NUM_GAMMA_ENTRIES * sizeof( SANE_Int ); 382141cc406Sopenharmony_ci pDesc->constraint_type = SANE_CONSTRAINT_RANGE; 383141cc406Sopenharmony_ci pDesc->constraint.range = &rangeGammaTable; 384141cc406Sopenharmony_ci pDesc->cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT; 385141cc406Sopenharmony_ci pVal->wa = s->aGammaTableG; 386141cc406Sopenharmony_ci break; 387141cc406Sopenharmony_ci 388141cc406Sopenharmony_ci case optGammaTableBlue: 389141cc406Sopenharmony_ci pDesc->name = SANE_NAME_GAMMA_VECTOR_B; 390141cc406Sopenharmony_ci pDesc->title = SANE_TITLE_GAMMA_VECTOR_B; 391141cc406Sopenharmony_ci pDesc->desc = SANE_DESC_GAMMA_VECTOR_B; 392141cc406Sopenharmony_ci pDesc->size = NUM_GAMMA_ENTRIES * sizeof( SANE_Int ); 393141cc406Sopenharmony_ci pDesc->constraint_type = SANE_CONSTRAINT_RANGE; 394141cc406Sopenharmony_ci pDesc->constraint.range = &rangeGammaTable; 395141cc406Sopenharmony_ci pDesc->cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT; 396141cc406Sopenharmony_ci pVal->wa = s->aGammaTableB; 397141cc406Sopenharmony_ci break; 398141cc406Sopenharmony_ci 399141cc406Sopenharmony_ci //--------------------------------- 400141cc406Sopenharmony_ci case optGroupSensors: 401141cc406Sopenharmony_ci pDesc->name = SANE_NAME_SENSORS; 402141cc406Sopenharmony_ci pDesc->title = SANE_TITLE_SENSORS; 403141cc406Sopenharmony_ci pDesc->type = SANE_TYPE_GROUP; 404141cc406Sopenharmony_ci pDesc->desc = SANE_DESC_SENSORS; 405141cc406Sopenharmony_ci pDesc->size = 0; 406141cc406Sopenharmony_ci break; 407141cc406Sopenharmony_ci 408141cc406Sopenharmony_ci case optSensorScanTo: 409141cc406Sopenharmony_ci pDesc->name = SANE_NAME_SCAN; 410141cc406Sopenharmony_ci pDesc->title = SANE_TITLE_SCAN; 411141cc406Sopenharmony_ci pDesc->desc = SANE_DESC_SCAN; 412141cc406Sopenharmony_ci pDesc->type = SANE_TYPE_BOOL; 413141cc406Sopenharmony_ci pDesc->cap = SANE_CAP_SOFT_DETECT | SANE_CAP_HARD_SELECT | SANE_CAP_ADVANCED; 414141cc406Sopenharmony_ci break; 415141cc406Sopenharmony_ci 416141cc406Sopenharmony_ci case optSensorWeb: 417141cc406Sopenharmony_ci pDesc->name = SANE_I18N("web"); 418141cc406Sopenharmony_ci pDesc->title = SANE_I18N("Share-To-Web button"); 419141cc406Sopenharmony_ci pDesc->desc = SANE_I18N("Scan an image and send it on the web"); 420141cc406Sopenharmony_ci pDesc->type = SANE_TYPE_BOOL; 421141cc406Sopenharmony_ci pDesc->cap = SANE_CAP_SOFT_DETECT | SANE_CAP_HARD_SELECT | SANE_CAP_ADVANCED; 422141cc406Sopenharmony_ci break; 423141cc406Sopenharmony_ci 424141cc406Sopenharmony_ci case optSensorReprint: 425141cc406Sopenharmony_ci pDesc->name = SANE_I18N("reprint"); 426141cc406Sopenharmony_ci pDesc->title = SANE_I18N("Reprint Photos button"); 427141cc406Sopenharmony_ci pDesc->desc = SANE_I18N("Button for reprinting photos"); 428141cc406Sopenharmony_ci pDesc->type = SANE_TYPE_BOOL; 429141cc406Sopenharmony_ci pDesc->cap = SANE_CAP_SOFT_DETECT | SANE_CAP_HARD_SELECT | SANE_CAP_ADVANCED; 430141cc406Sopenharmony_ci break; 431141cc406Sopenharmony_ci 432141cc406Sopenharmony_ci case optSensorEmail: 433141cc406Sopenharmony_ci pDesc->name = SANE_NAME_EMAIL; 434141cc406Sopenharmony_ci pDesc->title = SANE_TITLE_EMAIL; 435141cc406Sopenharmony_ci pDesc->desc = SANE_DESC_EMAIL; 436141cc406Sopenharmony_ci pDesc->type = SANE_TYPE_BOOL; 437141cc406Sopenharmony_ci pDesc->cap = SANE_CAP_SOFT_DETECT | SANE_CAP_HARD_SELECT | SANE_CAP_ADVANCED; 438141cc406Sopenharmony_ci break; 439141cc406Sopenharmony_ci 440141cc406Sopenharmony_ci case optSensorCopy: 441141cc406Sopenharmony_ci pDesc->name = SANE_NAME_COPY; 442141cc406Sopenharmony_ci pDesc->title = SANE_TITLE_COPY; 443141cc406Sopenharmony_ci pDesc->desc = SANE_DESC_COPY; 444141cc406Sopenharmony_ci pDesc->type = SANE_TYPE_BOOL; 445141cc406Sopenharmony_ci pDesc->cap = SANE_CAP_SOFT_DETECT | SANE_CAP_HARD_SELECT | SANE_CAP_ADVANCED; 446141cc406Sopenharmony_ci break; 447141cc406Sopenharmony_ci 448141cc406Sopenharmony_ci case optSensorMoreOptions: 449141cc406Sopenharmony_ci pDesc->name = SANE_I18N("more-options"); 450141cc406Sopenharmony_ci pDesc->title = SANE_I18N("More Options button"); 451141cc406Sopenharmony_ci pDesc->desc = SANE_I18N("Button for additional options/configuration"); 452141cc406Sopenharmony_ci pDesc->type = SANE_TYPE_BOOL; 453141cc406Sopenharmony_ci pDesc->cap = SANE_CAP_SOFT_DETECT | SANE_CAP_HARD_SELECT | SANE_CAP_ADVANCED; 454141cc406Sopenharmony_ci break; 455141cc406Sopenharmony_ci 456141cc406Sopenharmony_ci case optSensorCancel: 457141cc406Sopenharmony_ci pDesc->name = SANE_NAME_CANCEL; 458141cc406Sopenharmony_ci pDesc->title = SANE_TITLE_CANCEL; 459141cc406Sopenharmony_ci pDesc->desc = SANE_DESC_CANCEL; 460141cc406Sopenharmony_ci pDesc->type = SANE_TYPE_BOOL; 461141cc406Sopenharmony_ci pDesc->cap = SANE_CAP_SOFT_DETECT | SANE_CAP_HARD_SELECT | SANE_CAP_ADVANCED; 462141cc406Sopenharmony_ci break; 463141cc406Sopenharmony_ci 464141cc406Sopenharmony_ci case optSensorPowerSave: 465141cc406Sopenharmony_ci pDesc->name = SANE_I18N("power-save"); 466141cc406Sopenharmony_ci pDesc->title = SANE_I18N("Power Save button"); 467141cc406Sopenharmony_ci pDesc->desc = SANE_I18N("Puts the scanner in an energy-conservation mode"); 468141cc406Sopenharmony_ci pDesc->type = SANE_TYPE_BOOL; 469141cc406Sopenharmony_ci pDesc->cap = SANE_CAP_SOFT_DETECT | SANE_CAP_HARD_SELECT | SANE_CAP_ADVANCED; 470141cc406Sopenharmony_ci break; 471141cc406Sopenharmony_ci 472141cc406Sopenharmony_ci case optSensorCopiesUp: 473141cc406Sopenharmony_ci pDesc->name = SANE_I18N("copies-up"); 474141cc406Sopenharmony_ci pDesc->title = SANE_I18N("Increase Copies button"); 475141cc406Sopenharmony_ci pDesc->desc = SANE_I18N("Increase the number of copies"); 476141cc406Sopenharmony_ci pDesc->type = SANE_TYPE_BOOL; 477141cc406Sopenharmony_ci pDesc->cap = SANE_CAP_SOFT_DETECT | SANE_CAP_HARD_SELECT | SANE_CAP_ADVANCED; 478141cc406Sopenharmony_ci break; 479141cc406Sopenharmony_ci 480141cc406Sopenharmony_ci case optSensorCopiesDown: 481141cc406Sopenharmony_ci pDesc->name = SANE_I18N("copies-down"); 482141cc406Sopenharmony_ci pDesc->title = SANE_I18N("Decrease Copies button"); 483141cc406Sopenharmony_ci pDesc->desc = SANE_I18N("Decrease the number of copies"); 484141cc406Sopenharmony_ci pDesc->type = SANE_TYPE_BOOL; 485141cc406Sopenharmony_ci pDesc->cap = SANE_CAP_SOFT_DETECT | SANE_CAP_HARD_SELECT | SANE_CAP_ADVANCED; 486141cc406Sopenharmony_ci break; 487141cc406Sopenharmony_ci 488141cc406Sopenharmony_ci case optSensorColourBW: 489141cc406Sopenharmony_ci pDesc->name = SANE_I18N("color-bw"); 490141cc406Sopenharmony_ci pDesc->title = SANE_I18N("Select color/BW button"); 491141cc406Sopenharmony_ci pDesc->desc = SANE_I18N("Alternates between color and black/white scanning"); 492141cc406Sopenharmony_ci pDesc->type = SANE_TYPE_BOOL; 493141cc406Sopenharmony_ci pDesc->cap = SANE_CAP_SOFT_DETECT | SANE_CAP_HARD_SELECT | SANE_CAP_ADVANCED; 494141cc406Sopenharmony_ci break; 495141cc406Sopenharmony_ci 496141cc406Sopenharmony_ci case optSensorColourBWState: 497141cc406Sopenharmony_ci pDesc->name = SANE_I18N("color-bw-state"); 498141cc406Sopenharmony_ci pDesc->title = SANE_I18N("Read color/BW button state"); 499141cc406Sopenharmony_ci pDesc->desc = SANE_I18N("Reads state of BW/colour panel setting"); 500141cc406Sopenharmony_ci pDesc->type = SANE_TYPE_STRING; 501141cc406Sopenharmony_ci pDesc->constraint_type = SANE_CONSTRAINT_STRING_LIST; 502141cc406Sopenharmony_ci pDesc->constraint.string_list = modeSwitchList; 503141cc406Sopenharmony_ci pDesc->cap = SANE_CAP_SOFT_DETECT | SANE_CAP_SOFT_SELECT | SANE_CAP_ADVANCED; 504141cc406Sopenharmony_ci break; 505141cc406Sopenharmony_ci 506141cc406Sopenharmony_ci case optSensorCopyCount: 507141cc406Sopenharmony_ci pDesc->name = SANE_I18N("copies-count"); 508141cc406Sopenharmony_ci pDesc->title = SANE_I18N("Read copy count value"); 509141cc406Sopenharmony_ci pDesc->desc = SANE_I18N("Reads state of copy count panel setting"); 510141cc406Sopenharmony_ci pDesc->type = SANE_TYPE_INT; 511141cc406Sopenharmony_ci pDesc->constraint_type = SANE_CONSTRAINT_RANGE; 512141cc406Sopenharmony_ci pDesc->constraint.range = &rangeCopyCountTable; 513141cc406Sopenharmony_ci pDesc->cap = SANE_CAP_SOFT_DETECT | SANE_CAP_SOFT_SELECT | SANE_CAP_ADVANCED; 514141cc406Sopenharmony_ci break; 515141cc406Sopenharmony_ci 516141cc406Sopenharmony_ci#if 0 517141cc406Sopenharmony_ci case optGroupMisc: 518141cc406Sopenharmony_ci pDesc->title = SANE_I18N("Miscellaneous"); 519141cc406Sopenharmony_ci pDesc->type = SANE_TYPE_GROUP; 520141cc406Sopenharmony_ci pDesc->size = 0; 521141cc406Sopenharmony_ci break; 522141cc406Sopenharmony_ci 523141cc406Sopenharmony_ci case optLamp: 524141cc406Sopenharmony_ci pDesc->name = "lamp"; 525141cc406Sopenharmony_ci pDesc->title = SANE_I18N("Lamp status"); 526141cc406Sopenharmony_ci pDesc->desc = SANE_I18N("Switches the lamp on or off."); 527141cc406Sopenharmony_ci pDesc->type = SANE_TYPE_BOOL; 528141cc406Sopenharmony_ci pDesc->cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT; 529141cc406Sopenharmony_ci /* switch the lamp on when starting for first the time */ 530141cc406Sopenharmony_ci pVal->w = SANE_TRUE; 531141cc406Sopenharmony_ci break; 532141cc406Sopenharmony_ci 533141cc406Sopenharmony_ci case optCalibrate: 534141cc406Sopenharmony_ci pDesc->name = "calibrate"; 535141cc406Sopenharmony_ci pDesc->title = SANE_I18N("Calibrate"); 536141cc406Sopenharmony_ci pDesc->desc = SANE_I18N("Calibrates for black and white level."); 537141cc406Sopenharmony_ci pDesc->type = SANE_TYPE_BUTTON; 538141cc406Sopenharmony_ci pDesc->cap = SANE_CAP_SOFT_SELECT; 539141cc406Sopenharmony_ci pDesc->size = 0; 540141cc406Sopenharmony_ci break; 541141cc406Sopenharmony_ci#endif 542141cc406Sopenharmony_ci default: 543141cc406Sopenharmony_ci HP5400_DBG(DBG_ERR, "Uninitialised option %d\n", i); 544141cc406Sopenharmony_ci break; 545141cc406Sopenharmony_ci } 546141cc406Sopenharmony_ci } 547141cc406Sopenharmony_ci} 548141cc406Sopenharmony_ci 549141cc406Sopenharmony_ci 550141cc406Sopenharmony_cistatic int _ReportDevice(TScannerModel *pModel, const char *pszDeviceName) 551141cc406Sopenharmony_ci{ 552141cc406Sopenharmony_ci TDevListEntry *pNew, *pDev; 553141cc406Sopenharmony_ci 554141cc406Sopenharmony_ci HP5400_DBG(DBG_MSG, "hp5400: _ReportDevice '%s'\n", pszDeviceName); 555141cc406Sopenharmony_ci 556141cc406Sopenharmony_ci pNew = malloc(sizeof(TDevListEntry)); 557141cc406Sopenharmony_ci if (!pNew) { 558141cc406Sopenharmony_ci HP5400_DBG(DBG_ERR, "no mem\n"); 559141cc406Sopenharmony_ci return -1; 560141cc406Sopenharmony_ci } 561141cc406Sopenharmony_ci 562141cc406Sopenharmony_ci /* add new element to the end of the list */ 563141cc406Sopenharmony_ci if (_pFirstSaneDev == NULL) { 564141cc406Sopenharmony_ci _pFirstSaneDev = pNew; 565141cc406Sopenharmony_ci } 566141cc406Sopenharmony_ci else { 567141cc406Sopenharmony_ci for (pDev = _pFirstSaneDev; pDev->pNext; pDev = pDev->pNext) { 568141cc406Sopenharmony_ci ; 569141cc406Sopenharmony_ci } 570141cc406Sopenharmony_ci pDev->pNext = pNew; 571141cc406Sopenharmony_ci } 572141cc406Sopenharmony_ci 573141cc406Sopenharmony_ci /* fill in new element */ 574141cc406Sopenharmony_ci pNew->pNext = 0; 575141cc406Sopenharmony_ci /* we use devname to avoid having to free a const 576141cc406Sopenharmony_ci * pointer */ 577141cc406Sopenharmony_ci pNew->devname = (char*)strdup(pszDeviceName); 578141cc406Sopenharmony_ci pNew->dev.name = pNew->devname; 579141cc406Sopenharmony_ci pNew->dev.vendor = pModel->pszVendor; 580141cc406Sopenharmony_ci pNew->dev.model = pModel->pszName; 581141cc406Sopenharmony_ci pNew->dev.type = "flatbed scanner"; 582141cc406Sopenharmony_ci 583141cc406Sopenharmony_ci iNumSaneDev++; 584141cc406Sopenharmony_ci 585141cc406Sopenharmony_ci return 0; 586141cc406Sopenharmony_ci} 587141cc406Sopenharmony_ci 588141cc406Sopenharmony_cistatic SANE_Status 589141cc406Sopenharmony_ciattach_one_device (SANE_String_Const devname) 590141cc406Sopenharmony_ci{ 591141cc406Sopenharmony_ci const char * filename = (const char*) devname; 592141cc406Sopenharmony_ci if (HP5400Detect (filename, _ReportDevice) < 0) 593141cc406Sopenharmony_ci { 594141cc406Sopenharmony_ci HP5400_DBG (DBG_MSG, "attach_one_device: couldn't attach %s\n", devname); 595141cc406Sopenharmony_ci return SANE_STATUS_INVAL; 596141cc406Sopenharmony_ci } 597141cc406Sopenharmony_ci HP5400_DBG (DBG_MSG, "attach_one_device: attached %s successfully\n", devname); 598141cc406Sopenharmony_ci return SANE_STATUS_GOOD; 599141cc406Sopenharmony_ci} 600141cc406Sopenharmony_ci 601141cc406Sopenharmony_ci 602141cc406Sopenharmony_ci/*****************************************************************************/ 603141cc406Sopenharmony_ci 604141cc406Sopenharmony_ciSANE_Status 605141cc406Sopenharmony_cisane_init (SANE_Int * piVersion, SANE_Auth_Callback pfnAuth) 606141cc406Sopenharmony_ci{ 607141cc406Sopenharmony_ci FILE *conf_fp; /* Config file stream */ 608141cc406Sopenharmony_ci SANE_Char line[PATH_MAX]; 609141cc406Sopenharmony_ci SANE_Char *str = NULL; 610141cc406Sopenharmony_ci SANE_String_Const proper_str; 611141cc406Sopenharmony_ci int nline = 0; 612141cc406Sopenharmony_ci 613141cc406Sopenharmony_ci /* prevent compiler from complaining about unused parameters */ 614141cc406Sopenharmony_ci (void) pfnAuth; 615141cc406Sopenharmony_ci 616141cc406Sopenharmony_ci strcpy(usb_devfile, "/dev/usb/scanner0"); 617141cc406Sopenharmony_ci _pFirstSaneDev = 0; 618141cc406Sopenharmony_ci iNumSaneDev = 0; 619141cc406Sopenharmony_ci 620141cc406Sopenharmony_ci InitHp5400_internal(); 621141cc406Sopenharmony_ci 622141cc406Sopenharmony_ci 623141cc406Sopenharmony_ci DBG_INIT (); 624141cc406Sopenharmony_ci 625141cc406Sopenharmony_ci HP5400_DBG (DBG_MSG, "sane_init: SANE hp5400 backend version %d.%d-%d (from %s)\n", 626141cc406Sopenharmony_ci SANE_CURRENT_MAJOR, SANE_CURRENT_MINOR, BUILD, PACKAGE_STRING); 627141cc406Sopenharmony_ci 628141cc406Sopenharmony_ci sanei_usb_init (); 629141cc406Sopenharmony_ci 630141cc406Sopenharmony_ci conf_fp = sanei_config_open (HP5400_CONFIG_FILE); 631141cc406Sopenharmony_ci 632141cc406Sopenharmony_ci iNumSaneDev = 0; 633141cc406Sopenharmony_ci 634141cc406Sopenharmony_ci if (conf_fp) 635141cc406Sopenharmony_ci { 636141cc406Sopenharmony_ci HP5400_DBG (DBG_MSG, "Reading config file\n"); 637141cc406Sopenharmony_ci 638141cc406Sopenharmony_ci while (sanei_config_read (line, sizeof (line), conf_fp)) 639141cc406Sopenharmony_ci { 640141cc406Sopenharmony_ci ++nline; 641141cc406Sopenharmony_ci 642141cc406Sopenharmony_ci if (str) 643141cc406Sopenharmony_ci { 644141cc406Sopenharmony_ci free (str); 645141cc406Sopenharmony_ci } 646141cc406Sopenharmony_ci 647141cc406Sopenharmony_ci proper_str = sanei_config_get_string (line, &str); 648141cc406Sopenharmony_ci 649141cc406Sopenharmony_ci /* Discards white lines and comments */ 650141cc406Sopenharmony_ci if (!str || proper_str == line || str[0] == '#') 651141cc406Sopenharmony_ci { 652141cc406Sopenharmony_ci HP5400_DBG (DBG_MSG, "Discarding line %d\n", nline); 653141cc406Sopenharmony_ci } 654141cc406Sopenharmony_ci else 655141cc406Sopenharmony_ci { 656141cc406Sopenharmony_ci /* If line's not blank or a comment, then it's the device 657141cc406Sopenharmony_ci * filename or a usb directive. */ 658141cc406Sopenharmony_ci HP5400_DBG (DBG_MSG, "Trying to attach %s\n", line); 659141cc406Sopenharmony_ci sanei_usb_attach_matching_devices (line, attach_one_device); 660141cc406Sopenharmony_ci } 661141cc406Sopenharmony_ci } /* while */ 662141cc406Sopenharmony_ci fclose (conf_fp); 663141cc406Sopenharmony_ci } 664141cc406Sopenharmony_ci else 665141cc406Sopenharmony_ci { 666141cc406Sopenharmony_ci HP5400_DBG (DBG_ERR, "Unable to read config file \"%s\": %s\n", 667141cc406Sopenharmony_ci HP5400_CONFIG_FILE, strerror (errno)); 668141cc406Sopenharmony_ci HP5400_DBG (DBG_MSG, "Using default built-in values\n"); 669141cc406Sopenharmony_ci attach_one_device (usb_devfile); 670141cc406Sopenharmony_ci } 671141cc406Sopenharmony_ci 672141cc406Sopenharmony_ci if (piVersion != NULL) 673141cc406Sopenharmony_ci { 674141cc406Sopenharmony_ci *piVersion = SANE_VERSION_CODE (SANE_CURRENT_MAJOR, SANE_CURRENT_MINOR, BUILD); 675141cc406Sopenharmony_ci } 676141cc406Sopenharmony_ci 677141cc406Sopenharmony_ci return SANE_STATUS_GOOD; 678141cc406Sopenharmony_ci} 679141cc406Sopenharmony_ci 680141cc406Sopenharmony_ci 681141cc406Sopenharmony_civoid 682141cc406Sopenharmony_cisane_exit (void) 683141cc406Sopenharmony_ci{ 684141cc406Sopenharmony_ci TDevListEntry *pDev, *pNext; 685141cc406Sopenharmony_ci HP5400_DBG (DBG_MSG, "sane_exit\n"); 686141cc406Sopenharmony_ci 687141cc406Sopenharmony_ci /* free device list memory */ 688141cc406Sopenharmony_ci if (_pSaneDevList) 689141cc406Sopenharmony_ci { 690141cc406Sopenharmony_ci for (pDev = _pFirstSaneDev; pDev; pDev = pNext) 691141cc406Sopenharmony_ci { 692141cc406Sopenharmony_ci pNext = pDev->pNext; 693141cc406Sopenharmony_ci free (pDev->devname); 694141cc406Sopenharmony_ci /* pDev->dev.name is the same pointer that pDev->devname */ 695141cc406Sopenharmony_ci free (pDev); 696141cc406Sopenharmony_ci } 697141cc406Sopenharmony_ci _pFirstSaneDev = 0; 698141cc406Sopenharmony_ci free (_pSaneDevList); 699141cc406Sopenharmony_ci _pSaneDevList = 0; 700141cc406Sopenharmony_ci } 701141cc406Sopenharmony_ci 702141cc406Sopenharmony_ci 703141cc406Sopenharmony_ci FreeHp5400_internal(); 704141cc406Sopenharmony_ci} 705141cc406Sopenharmony_ci 706141cc406Sopenharmony_ci 707141cc406Sopenharmony_ciSANE_Status 708141cc406Sopenharmony_cisane_get_devices (const SANE_Device *** device_list, SANE_Bool local_only) 709141cc406Sopenharmony_ci{ 710141cc406Sopenharmony_ci TDevListEntry *pDev; 711141cc406Sopenharmony_ci int i; 712141cc406Sopenharmony_ci 713141cc406Sopenharmony_ci HP5400_DBG (DBG_MSG, "sane_get_devices\n"); 714141cc406Sopenharmony_ci 715141cc406Sopenharmony_ci (void) local_only; 716141cc406Sopenharmony_ci 717141cc406Sopenharmony_ci if (_pSaneDevList) 718141cc406Sopenharmony_ci { 719141cc406Sopenharmony_ci free (_pSaneDevList); 720141cc406Sopenharmony_ci } 721141cc406Sopenharmony_ci 722141cc406Sopenharmony_ci _pSaneDevList = malloc (sizeof (*_pSaneDevList) * (iNumSaneDev + 1)); 723141cc406Sopenharmony_ci if (!_pSaneDevList) 724141cc406Sopenharmony_ci { 725141cc406Sopenharmony_ci HP5400_DBG (DBG_MSG, "no mem\n"); 726141cc406Sopenharmony_ci return SANE_STATUS_NO_MEM; 727141cc406Sopenharmony_ci } 728141cc406Sopenharmony_ci i = 0; 729141cc406Sopenharmony_ci for (pDev = _pFirstSaneDev; pDev; pDev = pDev->pNext) 730141cc406Sopenharmony_ci { 731141cc406Sopenharmony_ci _pSaneDevList[i++] = &pDev->dev; 732141cc406Sopenharmony_ci } 733141cc406Sopenharmony_ci _pSaneDevList[i++] = 0; /* last entry is 0 */ 734141cc406Sopenharmony_ci 735141cc406Sopenharmony_ci *device_list = _pSaneDevList; 736141cc406Sopenharmony_ci 737141cc406Sopenharmony_ci return SANE_STATUS_GOOD; 738141cc406Sopenharmony_ci} 739141cc406Sopenharmony_ci 740141cc406Sopenharmony_ci 741141cc406Sopenharmony_ciSANE_Status 742141cc406Sopenharmony_cisane_open (SANE_String_Const name, SANE_Handle * h) 743141cc406Sopenharmony_ci{ 744141cc406Sopenharmony_ci TScanner *s; 745141cc406Sopenharmony_ci 746141cc406Sopenharmony_ci HP5400_DBG (DBG_MSG, "sane_open: %s\n", name); 747141cc406Sopenharmony_ci 748141cc406Sopenharmony_ci /* check the name */ 749141cc406Sopenharmony_ci if (strlen (name) == 0) 750141cc406Sopenharmony_ci { 751141cc406Sopenharmony_ci /* default to first available device */ 752141cc406Sopenharmony_ci name = _pFirstSaneDev->dev.name; 753141cc406Sopenharmony_ci } 754141cc406Sopenharmony_ci 755141cc406Sopenharmony_ci s = malloc (sizeof (TScanner)); 756141cc406Sopenharmony_ci if (!s) 757141cc406Sopenharmony_ci { 758141cc406Sopenharmony_ci HP5400_DBG (DBG_MSG, "malloc failed\n"); 759141cc406Sopenharmony_ci return SANE_STATUS_NO_MEM; 760141cc406Sopenharmony_ci } 761141cc406Sopenharmony_ci 762141cc406Sopenharmony_ci memset (s, 0, sizeof (TScanner)); /* Clear everything to zero */ 763141cc406Sopenharmony_ci if (HP5400Open (&s->HWParams, name) < 0) 764141cc406Sopenharmony_ci { 765141cc406Sopenharmony_ci /* is this OK ? */ 766141cc406Sopenharmony_ci HP5400_DBG (DBG_ERR, "HP5400Open failed\n"); 767141cc406Sopenharmony_ci free ((void *) s); 768141cc406Sopenharmony_ci return SANE_STATUS_INVAL; /* is this OK? */ 769141cc406Sopenharmony_ci } 770141cc406Sopenharmony_ci HP5400_DBG (DBG_MSG, "Handle=%d\n", s->HWParams.iXferHandle); 771141cc406Sopenharmony_ci _InitOptions (s); 772141cc406Sopenharmony_ci *h = s; 773141cc406Sopenharmony_ci 774141cc406Sopenharmony_ci /* Turn on lamp by default at startup */ 775141cc406Sopenharmony_ci/* SetLamp(&s->HWParams, TRUE); */ 776141cc406Sopenharmony_ci 777141cc406Sopenharmony_ci return SANE_STATUS_GOOD; 778141cc406Sopenharmony_ci} 779141cc406Sopenharmony_ci 780141cc406Sopenharmony_ci 781141cc406Sopenharmony_civoid 782141cc406Sopenharmony_cisane_close (SANE_Handle h) 783141cc406Sopenharmony_ci{ 784141cc406Sopenharmony_ci TScanner *s; 785141cc406Sopenharmony_ci 786141cc406Sopenharmony_ci HP5400_DBG (DBG_MSG, "sane_close\n"); 787141cc406Sopenharmony_ci 788141cc406Sopenharmony_ci s = (TScanner *) h; 789141cc406Sopenharmony_ci 790141cc406Sopenharmony_ci /* turn of scanner lamp */ 791141cc406Sopenharmony_ci SetLamp (&s->HWParams, FALSE); 792141cc406Sopenharmony_ci 793141cc406Sopenharmony_ci /* close scanner */ 794141cc406Sopenharmony_ci HP5400Close (&s->HWParams); 795141cc406Sopenharmony_ci 796141cc406Sopenharmony_ci /* free scanner object memory */ 797141cc406Sopenharmony_ci free ((void *) s); 798141cc406Sopenharmony_ci} 799141cc406Sopenharmony_ci 800141cc406Sopenharmony_ci 801141cc406Sopenharmony_ciconst SANE_Option_Descriptor * 802141cc406Sopenharmony_cisane_get_option_descriptor (SANE_Handle h, SANE_Int n) 803141cc406Sopenharmony_ci{ 804141cc406Sopenharmony_ci TScanner *s; 805141cc406Sopenharmony_ci 806141cc406Sopenharmony_ci HP5400_DBG (DBG_MSG, "sane_get_option_descriptor %d\n", n); 807141cc406Sopenharmony_ci 808141cc406Sopenharmony_ci if ((n < optCount) || (n >= optLast)) 809141cc406Sopenharmony_ci { 810141cc406Sopenharmony_ci return NULL; 811141cc406Sopenharmony_ci } 812141cc406Sopenharmony_ci 813141cc406Sopenharmony_ci s = (TScanner *) h; 814141cc406Sopenharmony_ci return &s->aOptions[n]; 815141cc406Sopenharmony_ci} 816141cc406Sopenharmony_ci 817141cc406Sopenharmony_ci 818141cc406Sopenharmony_ciSANE_Status 819141cc406Sopenharmony_cisane_control_option (SANE_Handle h, SANE_Int n, SANE_Action Action, 820141cc406Sopenharmony_ci void *pVal, SANE_Int * pInfo) 821141cc406Sopenharmony_ci{ 822141cc406Sopenharmony_ci TScanner *s; 823141cc406Sopenharmony_ci SANE_Int info; 824141cc406Sopenharmony_ci 825141cc406Sopenharmony_ci HP5400_DBG (DBG_MSG, "sane_control_option: option %d, action %d\n", n, Action); 826141cc406Sopenharmony_ci 827141cc406Sopenharmony_ci s = (TScanner *) h; 828141cc406Sopenharmony_ci info = 0; 829141cc406Sopenharmony_ci 830141cc406Sopenharmony_ci switch (Action) 831141cc406Sopenharmony_ci { 832141cc406Sopenharmony_ci case SANE_ACTION_GET_VALUE: 833141cc406Sopenharmony_ci switch (n) 834141cc406Sopenharmony_ci { 835141cc406Sopenharmony_ci 836141cc406Sopenharmony_ci /* Get options of type SANE_Word */ 837141cc406Sopenharmony_ci case optBRX: 838141cc406Sopenharmony_ci case optTLX: 839141cc406Sopenharmony_ci *(SANE_Word *) pVal = s->aValues[n].w; 840141cc406Sopenharmony_ci HP5400_DBG (DBG_MSG, 841141cc406Sopenharmony_ci "sane_control_option: SANE_ACTION_GET_VALUE %d = %d\n", n, 842141cc406Sopenharmony_ci *(SANE_Word *) pVal); 843141cc406Sopenharmony_ci break; 844141cc406Sopenharmony_ci 845141cc406Sopenharmony_ci case optBRY: 846141cc406Sopenharmony_ci case optTLY: 847141cc406Sopenharmony_ci *(SANE_Word *) pVal = s->aValues[n].w; 848141cc406Sopenharmony_ci HP5400_DBG (DBG_MSG, 849141cc406Sopenharmony_ci "sane_control_option: SANE_ACTION_GET_VALUE %d = %d\n", n, 850141cc406Sopenharmony_ci *(SANE_Word *) pVal); 851141cc406Sopenharmony_ci break; 852141cc406Sopenharmony_ci 853141cc406Sopenharmony_ci case optCount: 854141cc406Sopenharmony_ci case optDPI: 855141cc406Sopenharmony_ci HP5400_DBG (DBG_MSG, 856141cc406Sopenharmony_ci "sane_control_option: SANE_ACTION_GET_VALUE %d = %d\n", n, 857141cc406Sopenharmony_ci (int) s->aValues[n].w); 858141cc406Sopenharmony_ci *(SANE_Word *) pVal = s->aValues[n].w; 859141cc406Sopenharmony_ci break; 860141cc406Sopenharmony_ci 861141cc406Sopenharmony_ci /* Get options of type SANE_Word array */ 862141cc406Sopenharmony_ci case optGammaTableRed: 863141cc406Sopenharmony_ci case optGammaTableGreen: 864141cc406Sopenharmony_ci case optGammaTableBlue: 865141cc406Sopenharmony_ci HP5400_DBG (DBG_MSG, "Reading gamma table\n"); 866141cc406Sopenharmony_ci memcpy (pVal, s->aValues[n].wa, s->aOptions[n].size); 867141cc406Sopenharmony_ci break; 868141cc406Sopenharmony_ci 869141cc406Sopenharmony_ci case optSensorScanTo: 870141cc406Sopenharmony_ci case optSensorWeb: 871141cc406Sopenharmony_ci case optSensorReprint: 872141cc406Sopenharmony_ci case optSensorEmail: 873141cc406Sopenharmony_ci case optSensorCopy: 874141cc406Sopenharmony_ci case optSensorMoreOptions: 875141cc406Sopenharmony_ci case optSensorCancel: 876141cc406Sopenharmony_ci case optSensorPowerSave: 877141cc406Sopenharmony_ci case optSensorCopiesUp: 878141cc406Sopenharmony_ci case optSensorCopiesDown: 879141cc406Sopenharmony_ci case optSensorColourBW: 880141cc406Sopenharmony_ci { 881141cc406Sopenharmony_ci HP5400_DBG (DBG_MSG, "Reading sensor state\n"); 882141cc406Sopenharmony_ci 883141cc406Sopenharmony_ci uint16_t sensorMap; 884141cc406Sopenharmony_ci if (GetSensors(&s->HWParams, &sensorMap) != 0) 885141cc406Sopenharmony_ci { 886141cc406Sopenharmony_ci HP5400_DBG (DBG_ERR, 887141cc406Sopenharmony_ci "sane_control_option: SANE_ACTION_SET_VALUE could not retrieve sensors\n"); 888141cc406Sopenharmony_ci return SANE_STATUS_IO_ERROR; 889141cc406Sopenharmony_ci 890141cc406Sopenharmony_ci } 891141cc406Sopenharmony_ci 892141cc406Sopenharmony_ci HP5400_DBG (DBG_MSG, "Sensor state=%x\n", sensorMap); 893141cc406Sopenharmony_ci 894141cc406Sopenharmony_ci // Add read flags to what we already have so that we can report them when requested. 895141cc406Sopenharmony_ci s->sensorMap |= sensorMap; 896141cc406Sopenharmony_ci 897141cc406Sopenharmony_ci // Look up the mask based on the option number. 898141cc406Sopenharmony_ci uint16_t mask = sensorMaskMap[n - optGroupSensors - 1]; 899141cc406Sopenharmony_ci *(SANE_Word *) pVal = (s->sensorMap & mask)? 1:0; 900141cc406Sopenharmony_ci s->sensorMap &= ~mask; 901141cc406Sopenharmony_ci break; 902141cc406Sopenharmony_ci } 903141cc406Sopenharmony_ci 904141cc406Sopenharmony_ci case optSensorCopyCount: 905141cc406Sopenharmony_ci { 906141cc406Sopenharmony_ci HP5400_DBG (DBG_MSG, "Reading copy count\n"); 907141cc406Sopenharmony_ci 908141cc406Sopenharmony_ci TPanelInfo panelInfo; 909141cc406Sopenharmony_ci if (GetPanelInfo(&s->HWParams, &panelInfo) != 0) 910141cc406Sopenharmony_ci { 911141cc406Sopenharmony_ci HP5400_DBG (DBG_ERR, 912141cc406Sopenharmony_ci "sane_control_option: SANE_ACTION_SET_VALUE could not retrieve panel info\n"); 913141cc406Sopenharmony_ci return SANE_STATUS_IO_ERROR; 914141cc406Sopenharmony_ci 915141cc406Sopenharmony_ci } 916141cc406Sopenharmony_ci 917141cc406Sopenharmony_ci HP5400_DBG (DBG_MSG, "Copy count setting=%u\n", panelInfo.copycount); 918141cc406Sopenharmony_ci *(SANE_Word *) pVal = panelInfo.copycount; 919141cc406Sopenharmony_ci break; 920141cc406Sopenharmony_ci } 921141cc406Sopenharmony_ci 922141cc406Sopenharmony_ci case optSensorColourBWState: 923141cc406Sopenharmony_ci { 924141cc406Sopenharmony_ci HP5400_DBG (DBG_MSG, "Reading BW/Colour setting\n"); 925141cc406Sopenharmony_ci 926141cc406Sopenharmony_ci TPanelInfo panelInfo; 927141cc406Sopenharmony_ci if (GetPanelInfo(&s->HWParams, &panelInfo) != 0) 928141cc406Sopenharmony_ci { 929141cc406Sopenharmony_ci HP5400_DBG (DBG_ERR, 930141cc406Sopenharmony_ci "sane_control_option: SANE_ACTION_SET_VALUE could not retrieve panel info\n"); 931141cc406Sopenharmony_ci return SANE_STATUS_IO_ERROR; 932141cc406Sopenharmony_ci 933141cc406Sopenharmony_ci } 934141cc406Sopenharmony_ci 935141cc406Sopenharmony_ci HP5400_DBG (DBG_MSG, "BW/Colour setting=%u\n", panelInfo.bwcolour); 936141cc406Sopenharmony_ci 937141cc406Sopenharmony_ci // Just for safety: 938141cc406Sopenharmony_ci if (panelInfo.bwcolour < 1) 939141cc406Sopenharmony_ci { 940141cc406Sopenharmony_ci panelInfo.bwcolour = 1; 941141cc406Sopenharmony_ci } 942141cc406Sopenharmony_ci else if (panelInfo.bwcolour > 2) 943141cc406Sopenharmony_ci { 944141cc406Sopenharmony_ci panelInfo.bwcolour = 2; 945141cc406Sopenharmony_ci } 946141cc406Sopenharmony_ci (void)strcpy((SANE_String)pVal, modeSwitchList[panelInfo.bwcolour - 1]); 947141cc406Sopenharmony_ci break; 948141cc406Sopenharmony_ci } 949141cc406Sopenharmony_ci 950141cc406Sopenharmony_ci#if 0 951141cc406Sopenharmony_ci /* Get options of type SANE_Bool */ 952141cc406Sopenharmony_ci case optLamp: 953141cc406Sopenharmony_ci GetLamp (&s->HWParams, &fLampIsOn); 954141cc406Sopenharmony_ci *(SANE_Bool *) pVal = fLampIsOn; 955141cc406Sopenharmony_ci break; 956141cc406Sopenharmony_ci 957141cc406Sopenharmony_ci case optCalibrate: 958141cc406Sopenharmony_ci /* although this option has nothing to read, 959141cc406Sopenharmony_ci it's added here to avoid a warning when running scanimage --help */ 960141cc406Sopenharmony_ci break; 961141cc406Sopenharmony_ci#endif 962141cc406Sopenharmony_ci default: 963141cc406Sopenharmony_ci HP5400_DBG (DBG_MSG, "SANE_ACTION_GET_VALUE: Invalid option (%d)\n", n); 964141cc406Sopenharmony_ci } 965141cc406Sopenharmony_ci break; 966141cc406Sopenharmony_ci 967141cc406Sopenharmony_ci 968141cc406Sopenharmony_ci case SANE_ACTION_SET_VALUE: 969141cc406Sopenharmony_ci if (s->fScanning) 970141cc406Sopenharmony_ci { 971141cc406Sopenharmony_ci HP5400_DBG (DBG_ERR, 972141cc406Sopenharmony_ci "sane_control_option: SANE_ACTION_SET_VALUE not allowed during scan\n"); 973141cc406Sopenharmony_ci return SANE_STATUS_INVAL; 974141cc406Sopenharmony_ci } 975141cc406Sopenharmony_ci switch (n) 976141cc406Sopenharmony_ci { 977141cc406Sopenharmony_ci 978141cc406Sopenharmony_ci case optCount: 979141cc406Sopenharmony_ci return SANE_STATUS_INVAL; 980141cc406Sopenharmony_ci break; 981141cc406Sopenharmony_ci 982141cc406Sopenharmony_ci case optBRX: 983141cc406Sopenharmony_ci case optTLX: 984141cc406Sopenharmony_ci { 985141cc406Sopenharmony_ci // Check against legal values. 986141cc406Sopenharmony_ci SANE_Word value = *(SANE_Word *) pVal; 987141cc406Sopenharmony_ci if ((value < s->aOptions[n].constraint.range->min) || 988141cc406Sopenharmony_ci (value > s->aOptions[n].constraint.range->max)) 989141cc406Sopenharmony_ci { 990141cc406Sopenharmony_ci HP5400_DBG (DBG_ERR, 991141cc406Sopenharmony_ci "sane_control_option: SANE_ACTION_SET_VALUE out of range X value\n"); 992141cc406Sopenharmony_ci return SANE_STATUS_INVAL; 993141cc406Sopenharmony_ci } 994141cc406Sopenharmony_ci 995141cc406Sopenharmony_ci info |= SANE_INFO_RELOAD_PARAMS; 996141cc406Sopenharmony_ci s->ScanParams.iLines = 0; /* Forget actual image settings */ 997141cc406Sopenharmony_ci s->aValues[n].w = value; 998141cc406Sopenharmony_ci break; 999141cc406Sopenharmony_ci } 1000141cc406Sopenharmony_ci 1001141cc406Sopenharmony_ci case optBRY: 1002141cc406Sopenharmony_ci case optTLY: 1003141cc406Sopenharmony_ci { 1004141cc406Sopenharmony_ci // Check against legal values. 1005141cc406Sopenharmony_ci SANE_Word value = *(SANE_Word *) pVal; 1006141cc406Sopenharmony_ci if ((value < s->aOptions[n].constraint.range->min) || 1007141cc406Sopenharmony_ci (value > s->aOptions[n].constraint.range->max)) 1008141cc406Sopenharmony_ci { 1009141cc406Sopenharmony_ci HP5400_DBG (DBG_ERR, 1010141cc406Sopenharmony_ci "sane_control_option: SANE_ACTION_SET_VALUE out of range Y value\n"); 1011141cc406Sopenharmony_ci return SANE_STATUS_INVAL; 1012141cc406Sopenharmony_ci } 1013141cc406Sopenharmony_ci 1014141cc406Sopenharmony_ci info |= SANE_INFO_RELOAD_PARAMS; 1015141cc406Sopenharmony_ci s->ScanParams.iLines = 0; /* Forget actual image settings */ 1016141cc406Sopenharmony_ci s->aValues[n].w = value; 1017141cc406Sopenharmony_ci break; 1018141cc406Sopenharmony_ci } 1019141cc406Sopenharmony_ci 1020141cc406Sopenharmony_ci case optDPI: 1021141cc406Sopenharmony_ci { 1022141cc406Sopenharmony_ci // Check against legal values. 1023141cc406Sopenharmony_ci SANE_Word dpiValue = *(SANE_Word *) pVal; 1024141cc406Sopenharmony_ci 1025141cc406Sopenharmony_ci // First check too large. 1026141cc406Sopenharmony_ci SANE_Word maxRes = setResolutions[setResolutions[0]]; 1027141cc406Sopenharmony_ci if (dpiValue > maxRes) 1028141cc406Sopenharmony_ci { 1029141cc406Sopenharmony_ci dpiValue = maxRes; 1030141cc406Sopenharmony_ci } 1031141cc406Sopenharmony_ci else // Check smaller values: if not exact match, pick next higher available. 1032141cc406Sopenharmony_ci { 1033141cc406Sopenharmony_ci for (SANE_Int resIdx = 1; resIdx <= setResolutions[0]; resIdx++) 1034141cc406Sopenharmony_ci { 1035141cc406Sopenharmony_ci if (dpiValue <= setResolutions[resIdx]) 1036141cc406Sopenharmony_ci { 1037141cc406Sopenharmony_ci dpiValue = setResolutions[resIdx]; 1038141cc406Sopenharmony_ci break; 1039141cc406Sopenharmony_ci } 1040141cc406Sopenharmony_ci } 1041141cc406Sopenharmony_ci } 1042141cc406Sopenharmony_ci 1043141cc406Sopenharmony_ci info |= SANE_INFO_RELOAD_PARAMS; 1044141cc406Sopenharmony_ci s->ScanParams.iLines = 0; /* Forget actual image settings */ 1045141cc406Sopenharmony_ci (s->aValues[n].w) = dpiValue; 1046141cc406Sopenharmony_ci break; 1047141cc406Sopenharmony_ci } 1048141cc406Sopenharmony_ci 1049141cc406Sopenharmony_ci case optGammaTableRed: 1050141cc406Sopenharmony_ci case optGammaTableGreen: 1051141cc406Sopenharmony_ci case optGammaTableBlue: 1052141cc406Sopenharmony_ci HP5400_DBG (DBG_MSG, "Writing gamma table\n"); 1053141cc406Sopenharmony_ci memcpy (s->aValues[n].wa, pVal, s->aOptions[n].size); 1054141cc406Sopenharmony_ci break; 1055141cc406Sopenharmony_ci 1056141cc406Sopenharmony_ci case optSensorColourBWState: 1057141cc406Sopenharmony_ci { 1058141cc406Sopenharmony_ci SANE_String bwColour = (SANE_String)pVal; 1059141cc406Sopenharmony_ci SANE_Word bwColourValue; 1060141cc406Sopenharmony_ci 1061141cc406Sopenharmony_ci if (strcmp(bwColour, SANE_VALUE_SCAN_MODE_COLOR) == 0) 1062141cc406Sopenharmony_ci { 1063141cc406Sopenharmony_ci bwColourValue = 1; 1064141cc406Sopenharmony_ci } 1065141cc406Sopenharmony_ci else if (strcmp(bwColour, SANE_VALUE_SCAN_MODE_GRAY) == 0) 1066141cc406Sopenharmony_ci { 1067141cc406Sopenharmony_ci bwColourValue = 2; 1068141cc406Sopenharmony_ci } 1069141cc406Sopenharmony_ci else 1070141cc406Sopenharmony_ci { 1071141cc406Sopenharmony_ci HP5400_DBG (DBG_ERR, 1072141cc406Sopenharmony_ci "sane_control_option: SANE_ACTION_SET_VALUE invalid colour/bw mode\n"); 1073141cc406Sopenharmony_ci return SANE_STATUS_INVAL; 1074141cc406Sopenharmony_ci } 1075141cc406Sopenharmony_ci 1076141cc406Sopenharmony_ci HP5400_DBG (DBG_MSG, "Setting BW/Colour state=%d\n", bwColourValue); 1077141cc406Sopenharmony_ci 1078141cc406Sopenharmony_ci /* 1079141cc406Sopenharmony_ci * Now write it with the other panel settings back to the scanner. 1080141cc406Sopenharmony_ci * 1081141cc406Sopenharmony_ci */ 1082141cc406Sopenharmony_ci if (SetColourBW(&s->HWParams, bwColourValue) != 0) 1083141cc406Sopenharmony_ci { 1084141cc406Sopenharmony_ci HP5400_DBG (DBG_ERR, 1085141cc406Sopenharmony_ci "sane_control_option: SANE_ACTION_SET_VALUE could not set colour/BW mode\n"); 1086141cc406Sopenharmony_ci return SANE_STATUS_IO_ERROR; 1087141cc406Sopenharmony_ci } 1088141cc406Sopenharmony_ci break; 1089141cc406Sopenharmony_ci } 1090141cc406Sopenharmony_ci 1091141cc406Sopenharmony_ci case optSensorCopyCount: 1092141cc406Sopenharmony_ci { 1093141cc406Sopenharmony_ci SANE_Word copyCount = *(SANE_Word *) pVal; 1094141cc406Sopenharmony_ci if (copyCount < 0) 1095141cc406Sopenharmony_ci { 1096141cc406Sopenharmony_ci copyCount = 0; 1097141cc406Sopenharmony_ci } 1098141cc406Sopenharmony_ci else if (copyCount > 99) 1099141cc406Sopenharmony_ci { 1100141cc406Sopenharmony_ci copyCount = 99; 1101141cc406Sopenharmony_ci } 1102141cc406Sopenharmony_ci 1103141cc406Sopenharmony_ci HP5400_DBG (DBG_MSG, "Setting Copy Count=%d\n", copyCount); 1104141cc406Sopenharmony_ci 1105141cc406Sopenharmony_ci /* 1106141cc406Sopenharmony_ci * Now write it with the other panel settings back to the scanner. 1107141cc406Sopenharmony_ci * 1108141cc406Sopenharmony_ci */ 1109141cc406Sopenharmony_ci if (SetCopyCount(&s->HWParams, copyCount) != 0) 1110141cc406Sopenharmony_ci { 1111141cc406Sopenharmony_ci HP5400_DBG (DBG_ERR, 1112141cc406Sopenharmony_ci "sane_control_option: SANE_ACTION_SET_VALUE could not set copy count\n"); 1113141cc406Sopenharmony_ci return SANE_STATUS_IO_ERROR; 1114141cc406Sopenharmony_ci 1115141cc406Sopenharmony_ci } 1116141cc406Sopenharmony_ci break; 1117141cc406Sopenharmony_ci } 1118141cc406Sopenharmony_ci 1119141cc406Sopenharmony_ci/* 1120141cc406Sopenharmony_ci case optLamp: 1121141cc406Sopenharmony_ci fVal = *(SANE_Bool *)pVal; 1122141cc406Sopenharmony_ci HP5400_DBG(DBG_MSG, "lamp %s\n", fVal ? "on" : "off"); 1123141cc406Sopenharmony_ci SetLamp(&s->HWParams, fVal); 1124141cc406Sopenharmony_ci break; 1125141cc406Sopenharmony_ci*/ 1126141cc406Sopenharmony_ci#if 0 1127141cc406Sopenharmony_ci case optCalibrate: 1128141cc406Sopenharmony_ci/* SimpleCalib(&s->HWParams); */ 1129141cc406Sopenharmony_ci break; 1130141cc406Sopenharmony_ci#endif 1131141cc406Sopenharmony_ci default: 1132141cc406Sopenharmony_ci HP5400_DBG (DBG_ERR, "SANE_ACTION_SET_VALUE: Invalid option (%d)\n", n); 1133141cc406Sopenharmony_ci } 1134141cc406Sopenharmony_ci if (pInfo != NULL) 1135141cc406Sopenharmony_ci { 1136141cc406Sopenharmony_ci *pInfo = info; 1137141cc406Sopenharmony_ci } 1138141cc406Sopenharmony_ci break; 1139141cc406Sopenharmony_ci 1140141cc406Sopenharmony_ci case SANE_ACTION_SET_AUTO: 1141141cc406Sopenharmony_ci return SANE_STATUS_UNSUPPORTED; 1142141cc406Sopenharmony_ci 1143141cc406Sopenharmony_ci 1144141cc406Sopenharmony_ci default: 1145141cc406Sopenharmony_ci HP5400_DBG (DBG_ERR, "Invalid action (%d)\n", Action); 1146141cc406Sopenharmony_ci return SANE_STATUS_INVAL; 1147141cc406Sopenharmony_ci } 1148141cc406Sopenharmony_ci 1149141cc406Sopenharmony_ci return SANE_STATUS_GOOD; 1150141cc406Sopenharmony_ci} 1151141cc406Sopenharmony_ci 1152141cc406Sopenharmony_ci 1153141cc406Sopenharmony_ci 1154141cc406Sopenharmony_ciSANE_Status 1155141cc406Sopenharmony_cisane_get_parameters (SANE_Handle h, SANE_Parameters * p) 1156141cc406Sopenharmony_ci{ 1157141cc406Sopenharmony_ci TScanner *s; 1158141cc406Sopenharmony_ci HP5400_DBG (DBG_MSG, "sane_get_parameters\n"); 1159141cc406Sopenharmony_ci 1160141cc406Sopenharmony_ci s = (TScanner *) h; 1161141cc406Sopenharmony_ci 1162141cc406Sopenharmony_ci /* first do some checks */ 1163141cc406Sopenharmony_ci if (s->aValues[optTLX].w >= s->aValues[optBRX].w) 1164141cc406Sopenharmony_ci { 1165141cc406Sopenharmony_ci HP5400_DBG (DBG_ERR, "TLX should be smaller than BRX\n"); 1166141cc406Sopenharmony_ci return SANE_STATUS_INVAL; /* proper error code? */ 1167141cc406Sopenharmony_ci } 1168141cc406Sopenharmony_ci if (s->aValues[optTLY].w >= s->aValues[optBRY].w) 1169141cc406Sopenharmony_ci { 1170141cc406Sopenharmony_ci HP5400_DBG (DBG_ERR, "TLY should be smaller than BRY\n"); 1171141cc406Sopenharmony_ci return SANE_STATUS_INVAL; /* proper error code? */ 1172141cc406Sopenharmony_ci } 1173141cc406Sopenharmony_ci 1174141cc406Sopenharmony_ci /* return the data */ 1175141cc406Sopenharmony_ci p->format = SANE_FRAME_RGB; 1176141cc406Sopenharmony_ci p->last_frame = SANE_TRUE; 1177141cc406Sopenharmony_ci 1178141cc406Sopenharmony_ci p->depth = 8; 1179141cc406Sopenharmony_ci if (s->ScanParams.iLines) /* Initialised by doing a scan */ 1180141cc406Sopenharmony_ci { 1181141cc406Sopenharmony_ci p->pixels_per_line = s->ScanParams.iBytesPerLine / 3; 1182141cc406Sopenharmony_ci p->lines = s->ScanParams.iLines; 1183141cc406Sopenharmony_ci p->bytes_per_line = s->ScanParams.iBytesPerLine; 1184141cc406Sopenharmony_ci } 1185141cc406Sopenharmony_ci else 1186141cc406Sopenharmony_ci { 1187141cc406Sopenharmony_ci p->lines = MM_TO_PIXEL (s->aValues[optBRY].w - s->aValues[optTLY].w, 1188141cc406Sopenharmony_ci s->aValues[optDPI].w); 1189141cc406Sopenharmony_ci p->pixels_per_line = 1190141cc406Sopenharmony_ci MM_TO_PIXEL (s->aValues[optBRX].w - s->aValues[optTLX].w, 1191141cc406Sopenharmony_ci s->aValues[optDPI].w); 1192141cc406Sopenharmony_ci p->bytes_per_line = p->pixels_per_line * 3; 1193141cc406Sopenharmony_ci } 1194141cc406Sopenharmony_ci 1195141cc406Sopenharmony_ci return SANE_STATUS_GOOD; 1196141cc406Sopenharmony_ci} 1197141cc406Sopenharmony_ci 1198141cc406Sopenharmony_ci#define BUFFER_READ_HEADER_SIZE 32 1199141cc406Sopenharmony_ci 1200141cc406Sopenharmony_ciSANE_Status 1201141cc406Sopenharmony_cisane_start (SANE_Handle h) 1202141cc406Sopenharmony_ci{ 1203141cc406Sopenharmony_ci TScanner *s; 1204141cc406Sopenharmony_ci SANE_Parameters par; 1205141cc406Sopenharmony_ci 1206141cc406Sopenharmony_ci HP5400_DBG (DBG_MSG, "sane_start\n"); 1207141cc406Sopenharmony_ci 1208141cc406Sopenharmony_ci s = (TScanner *) h; 1209141cc406Sopenharmony_ci 1210141cc406Sopenharmony_ci if (sane_get_parameters (h, &par) != SANE_STATUS_GOOD) 1211141cc406Sopenharmony_ci { 1212141cc406Sopenharmony_ci HP5400_DBG (DBG_MSG, "Invalid scan parameters (sane_get_parameters)\n"); 1213141cc406Sopenharmony_ci return SANE_STATUS_INVAL; 1214141cc406Sopenharmony_ci } 1215141cc406Sopenharmony_ci s->iLinesLeft = par.lines; 1216141cc406Sopenharmony_ci 1217141cc406Sopenharmony_ci /* fill in the scanparams using the option values */ 1218141cc406Sopenharmony_ci s->ScanParams.iDpi = s->aValues[optDPI].w; 1219141cc406Sopenharmony_ci s->ScanParams.iLpi = s->aValues[optDPI].w; 1220141cc406Sopenharmony_ci 1221141cc406Sopenharmony_ci /* Guessing here. 75dpi => 1, 2400dpi => 32 */ 1222141cc406Sopenharmony_ci /* s->ScanParams.iColourOffset = s->aValues[optDPI].w / 75; */ 1223141cc406Sopenharmony_ci /* now we don't need correction => corrected by scan request type ? */ 1224141cc406Sopenharmony_ci s->ScanParams.iColourOffset = 0; 1225141cc406Sopenharmony_ci 1226141cc406Sopenharmony_ci s->ScanParams.iTop = 1227141cc406Sopenharmony_ci MM_TO_PIXEL (s->aValues[optTLY].w + s->HWParams.iTopLeftY, HW_LPI); 1228141cc406Sopenharmony_ci s->ScanParams.iLeft = 1229141cc406Sopenharmony_ci MM_TO_PIXEL (s->aValues[optTLX].w + s->HWParams.iTopLeftX, HW_DPI); 1230141cc406Sopenharmony_ci 1231141cc406Sopenharmony_ci /* Note: All measurements passed to the scanning routines must be in HW_LPI */ 1232141cc406Sopenharmony_ci s->ScanParams.iWidth = 1233141cc406Sopenharmony_ci MM_TO_PIXEL (s->aValues[optBRX].w - s->aValues[optTLX].w, HW_LPI); 1234141cc406Sopenharmony_ci s->ScanParams.iHeight = 1235141cc406Sopenharmony_ci MM_TO_PIXEL (s->aValues[optBRY].w - s->aValues[optTLY].w, HW_LPI); 1236141cc406Sopenharmony_ci 1237141cc406Sopenharmony_ci /* After the scanning, the iLines and iBytesPerLine will be filled in */ 1238141cc406Sopenharmony_ci 1239141cc406Sopenharmony_ci /* copy gamma table */ 1240141cc406Sopenharmony_ci WriteGammaCalibTable (s->HWParams.iXferHandle, s->aGammaTableR, 1241141cc406Sopenharmony_ci s->aGammaTableG, s->aGammaTableB); 1242141cc406Sopenharmony_ci 1243141cc406Sopenharmony_ci /* prepare the actual scan */ 1244141cc406Sopenharmony_ci /* We say normal here. In future we should have a preview flag to set preview mode */ 1245141cc406Sopenharmony_ci if (InitScan (SCAN_TYPE_NORMAL, &s->ScanParams, &s->HWParams) != 0) 1246141cc406Sopenharmony_ci { 1247141cc406Sopenharmony_ci HP5400_DBG (DBG_MSG, "Invalid scan parameters (InitScan)\n"); 1248141cc406Sopenharmony_ci return SANE_STATUS_INVAL; 1249141cc406Sopenharmony_ci } 1250141cc406Sopenharmony_ci 1251141cc406Sopenharmony_ci /* for the moment no lines has been read */ 1252141cc406Sopenharmony_ci s->ScanParams.iLinesRead = 0; 1253141cc406Sopenharmony_ci 1254141cc406Sopenharmony_ci s->fScanning = TRUE; 1255141cc406Sopenharmony_ci s->fCanceled = FALSE; 1256141cc406Sopenharmony_ci return SANE_STATUS_GOOD; 1257141cc406Sopenharmony_ci} 1258141cc406Sopenharmony_ci 1259141cc406Sopenharmony_ci 1260141cc406Sopenharmony_ciSANE_Status 1261141cc406Sopenharmony_cisane_read (SANE_Handle h, SANE_Byte * buf, SANE_Int maxlen, SANE_Int * len) 1262141cc406Sopenharmony_ci{ 1263141cc406Sopenharmony_ci 1264141cc406Sopenharmony_ci /* Read actual scan from the circular buffer */ 1265141cc406Sopenharmony_ci /* Note: this is already color corrected, though some work still needs to be done 1266141cc406Sopenharmony_ci to deal with the colour offsetting */ 1267141cc406Sopenharmony_ci TScanner *s; 1268141cc406Sopenharmony_ci char *buffer = (char*)buf; 1269141cc406Sopenharmony_ci 1270141cc406Sopenharmony_ci HP5400_DBG (DBG_MSG, "sane_read: request %d bytes \n", maxlen); 1271141cc406Sopenharmony_ci 1272141cc406Sopenharmony_ci s = (TScanner *) h; 1273141cc406Sopenharmony_ci 1274141cc406Sopenharmony_ci /* nothing has been read for the moment */ 1275141cc406Sopenharmony_ci *len = 0; 1276141cc406Sopenharmony_ci if (!s->fScanning || s->fCanceled) 1277141cc406Sopenharmony_ci { 1278141cc406Sopenharmony_ci HP5400_DBG (DBG_MSG, "sane_read: we're not scanning.\n"); 1279141cc406Sopenharmony_ci return SANE_STATUS_EOF; 1280141cc406Sopenharmony_ci } 1281141cc406Sopenharmony_ci 1282141cc406Sopenharmony_ci 1283141cc406Sopenharmony_ci /* if we read all the lines return EOF */ 1284141cc406Sopenharmony_ci if (s->ScanParams.iLinesRead == s->ScanParams.iLines) 1285141cc406Sopenharmony_ci { 1286141cc406Sopenharmony_ci/* FinishScan( &s->HWParams ); *** FinishScan called in sane_cancel */ 1287141cc406Sopenharmony_ci HP5400_DBG (DBG_MSG, "sane_read: EOF\n"); 1288141cc406Sopenharmony_ci return SANE_STATUS_EOF; 1289141cc406Sopenharmony_ci } 1290141cc406Sopenharmony_ci 1291141cc406Sopenharmony_ci /* read as many lines the buffer may contain and while there are lines to be read */ 1292141cc406Sopenharmony_ci while ((*len + s->ScanParams.iBytesPerLine <= maxlen) 1293141cc406Sopenharmony_ci && (s->ScanParams.iLinesRead < s->ScanParams.iLines)) 1294141cc406Sopenharmony_ci { 1295141cc406Sopenharmony_ci 1296141cc406Sopenharmony_ci /* get one more line from the circular buffer */ 1297141cc406Sopenharmony_ci CircBufferGetLine (s->HWParams.iXferHandle, &s->HWParams.pipe, buffer); 1298141cc406Sopenharmony_ci 1299141cc406Sopenharmony_ci /* increment pointer, size and line number */ 1300141cc406Sopenharmony_ci buffer += s->ScanParams.iBytesPerLine; 1301141cc406Sopenharmony_ci *len += s->ScanParams.iBytesPerLine; 1302141cc406Sopenharmony_ci s->ScanParams.iLinesRead++; 1303141cc406Sopenharmony_ci } 1304141cc406Sopenharmony_ci 1305141cc406Sopenharmony_ci HP5400_DBG (DBG_MSG, "sane_read: %d bytes read\n", *len); 1306141cc406Sopenharmony_ci 1307141cc406Sopenharmony_ci return SANE_STATUS_GOOD; 1308141cc406Sopenharmony_ci} 1309141cc406Sopenharmony_ci 1310141cc406Sopenharmony_ci 1311141cc406Sopenharmony_civoid 1312141cc406Sopenharmony_cisane_cancel (SANE_Handle h) 1313141cc406Sopenharmony_ci{ 1314141cc406Sopenharmony_ci TScanner *s; 1315141cc406Sopenharmony_ci 1316141cc406Sopenharmony_ci HP5400_DBG (DBG_MSG, "sane_cancel\n"); 1317141cc406Sopenharmony_ci 1318141cc406Sopenharmony_ci s = (TScanner *) h; 1319141cc406Sopenharmony_ci 1320141cc406Sopenharmony_ci /* to be implemented more thoroughly */ 1321141cc406Sopenharmony_ci 1322141cc406Sopenharmony_ci /* Make sure the scanner head returns home */ 1323141cc406Sopenharmony_ci FinishScan (&s->HWParams); 1324141cc406Sopenharmony_ci 1325141cc406Sopenharmony_ci s->fCanceled = TRUE; 1326141cc406Sopenharmony_ci s->fScanning = FALSE; 1327141cc406Sopenharmony_ci} 1328141cc406Sopenharmony_ci 1329141cc406Sopenharmony_ci 1330141cc406Sopenharmony_ciSANE_Status 1331141cc406Sopenharmony_cisane_set_io_mode (SANE_Handle h, SANE_Bool m) 1332141cc406Sopenharmony_ci{ 1333141cc406Sopenharmony_ci HP5400_DBG (DBG_MSG, "sane_set_io_mode %s\n", m ? "non-blocking" : "blocking"); 1334141cc406Sopenharmony_ci 1335141cc406Sopenharmony_ci /* prevent compiler from complaining about unused parameters */ 1336141cc406Sopenharmony_ci (void) h; 1337141cc406Sopenharmony_ci 1338141cc406Sopenharmony_ci if (m) 1339141cc406Sopenharmony_ci { 1340141cc406Sopenharmony_ci return SANE_STATUS_UNSUPPORTED; 1341141cc406Sopenharmony_ci } 1342141cc406Sopenharmony_ci return SANE_STATUS_GOOD; 1343141cc406Sopenharmony_ci} 1344141cc406Sopenharmony_ci 1345141cc406Sopenharmony_ci 1346141cc406Sopenharmony_ciSANE_Status 1347141cc406Sopenharmony_cisane_get_select_fd (SANE_Handle h, SANE_Int * fd) 1348141cc406Sopenharmony_ci{ 1349141cc406Sopenharmony_ci HP5400_DBG (DBG_MSG, "sane_select_fd\n"); 1350141cc406Sopenharmony_ci 1351141cc406Sopenharmony_ci /* prevent compiler from complaining about unused parameters */ 1352141cc406Sopenharmony_ci (void) h; 1353141cc406Sopenharmony_ci (void) fd; 1354141cc406Sopenharmony_ci 1355141cc406Sopenharmony_ci return SANE_STATUS_UNSUPPORTED; 1356141cc406Sopenharmony_ci} 1357