1141cc406Sopenharmony_ci/* sane - Scanner Access Now Easy. 2141cc406Sopenharmony_ci Copyright (C) 1997 Geoffrey T. Dairiki 3141cc406Sopenharmony_ci Support for HP PhotoSmart Photoscanner by Peter Kirchgessner 4141cc406Sopenharmony_ci This file is part of the SANE package. 5141cc406Sopenharmony_ci 6141cc406Sopenharmony_ci This program is free software; you can redistribute it and/or 7141cc406Sopenharmony_ci modify it under the terms of the GNU General Public License as 8141cc406Sopenharmony_ci published by the Free Software Foundation; either version 2 of the 9141cc406Sopenharmony_ci License, or (at your option) any later version. 10141cc406Sopenharmony_ci 11141cc406Sopenharmony_ci This program is distributed in the hope that it will be useful, but 12141cc406Sopenharmony_ci WITHOUT ANY WARRANTY; without even the implied warranty of 13141cc406Sopenharmony_ci MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14141cc406Sopenharmony_ci General Public License for more details. 15141cc406Sopenharmony_ci 16141cc406Sopenharmony_ci You should have received a copy of the GNU General Public License 17141cc406Sopenharmony_ci along with this program. If not, see <https://www.gnu.org/licenses/>. 18141cc406Sopenharmony_ci 19141cc406Sopenharmony_ci As a special exception, the authors of SANE give permission for 20141cc406Sopenharmony_ci additional uses of the libraries contained in this release of SANE. 21141cc406Sopenharmony_ci 22141cc406Sopenharmony_ci The exception is that, if you link a SANE library with other files 23141cc406Sopenharmony_ci to produce an executable, this does not by itself cause the 24141cc406Sopenharmony_ci resulting executable to be covered by the GNU General Public 25141cc406Sopenharmony_ci License. Your use of that executable is in no way restricted on 26141cc406Sopenharmony_ci account of linking the SANE library code into it. 27141cc406Sopenharmony_ci 28141cc406Sopenharmony_ci This exception does not, however, invalidate any other reasons why 29141cc406Sopenharmony_ci the executable file might be covered by the GNU General Public 30141cc406Sopenharmony_ci License. 31141cc406Sopenharmony_ci 32141cc406Sopenharmony_ci If you submit changes to SANE to the maintainers to be included in 33141cc406Sopenharmony_ci a subsequent release, you agree by submitting the changes that 34141cc406Sopenharmony_ci those changes may be distributed with this exception intact. 35141cc406Sopenharmony_ci 36141cc406Sopenharmony_ci If you write modifications of your own for SANE, it is your choice 37141cc406Sopenharmony_ci whether to permit this exception to apply to your modifications. 38141cc406Sopenharmony_ci If you do not wish that, delete this exception notice. 39141cc406Sopenharmony_ci 40141cc406Sopenharmony_ci This file is part of a SANE backend for HP Scanners supporting 41141cc406Sopenharmony_ci HP Scanner Control Language (SCL). 42141cc406Sopenharmony_ci*/ 43141cc406Sopenharmony_ci 44141cc406Sopenharmony_cistatic char *hp_backend_version = "1.06"; 45141cc406Sopenharmony_ci/* Changes: 46141cc406Sopenharmony_ci 47141cc406Sopenharmony_ci V 1.06: 48141cc406Sopenharmony_ci Revision 1.22 2008/11/26 21:21:25 kitno-guest 49141cc406Sopenharmony_ci * backend/ *.[ch]: nearly every backend used V_MAJOR 50141cc406Sopenharmony_ci instead of SANE_CURRENT_MAJOR in sane_init() 51141cc406Sopenharmony_ci * backend/snapscan.c: remove EXPECTED_VERSION check 52141cc406Sopenharmony_ci since new SANE standard is forward compatible 53141cc406Sopenharmony_ci 54141cc406Sopenharmony_ci Revision 1.21 2004-10-04 18:09:05 kig-guest 55141cc406Sopenharmony_ci Rename global function hp_init_openfd to sanei_hp_init_openfd 56141cc406Sopenharmony_ci 57141cc406Sopenharmony_ci Revision 1.20 2004/03/27 13:52:39 kig-guest 58141cc406Sopenharmony_ci Keep USB-connection open (was problem with Linux 2.6.x) 59141cc406Sopenharmony_ci 60141cc406Sopenharmony_ci 61141cc406Sopenharmony_ci V 1.05: 62141cc406Sopenharmony_ci Revision 1.19 2003/10/24 17:26:07 kig-guest 63141cc406Sopenharmony_ci Use new sanei-thread-interface 64141cc406Sopenharmony_ci 65141cc406Sopenharmony_ci Revision 1.18 2003/10/09 19:37:29 kig-guest 66141cc406Sopenharmony_ci Redo when TEST UNIT READY failed 67141cc406Sopenharmony_ci Redo when read returns with 0 bytes (non-SCSI only) 68141cc406Sopenharmony_ci Bug #300241: fix inverse image on 3c/4c/6100C at 10 bit depth 69141cc406Sopenharmony_ci 70141cc406Sopenharmony_ci Revision 1.17 2003/10/06 19:54:07 kig-guest 71141cc406Sopenharmony_ci Bug #300248: correct "Negatives" to "Negative" in option description 72141cc406Sopenharmony_ci 73141cc406Sopenharmony_ci 74141cc406Sopenharmony_ci V 1.04, 24-Jul-2003, PK (peter@kirchgessner.net) 75141cc406Sopenharmony_ci - Add internationalization 76141cc406Sopenharmony_ci 77141cc406Sopenharmony_ci V 1.03, 14-Apr-2003, PK (peter@kirchgessner.net) 78141cc406Sopenharmony_ci - check valp in call of sane_control_option() 79141cc406Sopenharmony_ci 80141cc406Sopenharmony_ci V 1.02, 02-Feb-2003, PK (peter@kirchgessner.net) 81141cc406Sopenharmony_ci - add OS/2-support by Franz Bakan 82141cc406Sopenharmony_ci 83141cc406Sopenharmony_ci V 1.01, 06-Dec-2002, PK (peter@kirchgessner.net) 84141cc406Sopenharmony_ci - add option dumb-read to work around problems 85141cc406Sopenharmony_ci with BusLogic SCSI driver (error during device I/O) 86141cc406Sopenharmony_ci 87141cc406Sopenharmony_ci V 1.00, 17-Nov-2002, PK (peter@kirchgessner.net) 88141cc406Sopenharmony_ci - add libusb support 89141cc406Sopenharmony_ci 90141cc406Sopenharmony_ci V 0.96, 05-Aug-2002, PK (peter@kirchgessner.net) 91141cc406Sopenharmony_ci - check USB device names 92141cc406Sopenharmony_ci 93141cc406Sopenharmony_ci V 0.95, 07-Jul-2001, PK (peter@kirchgessner.net) 94141cc406Sopenharmony_ci - add support for active XPA 95141cc406Sopenharmony_ci - check if paper in ADF for ADF scan 96141cc406Sopenharmony_ci - add option lamp off 97141cc406Sopenharmony_ci - remove some really unused parameters 98141cc406Sopenharmony_ci 99141cc406Sopenharmony_ci V 0.94, 31-Dec-2000, PK (peter@kirchgessner.net) 100141cc406Sopenharmony_ci - always switch off lamp after scan 101141cc406Sopenharmony_ci 102141cc406Sopenharmony_ci V 0.93, 04-Dec-2000, PK (peter@kirchgessner.net) 103141cc406Sopenharmony_ci - fix problem with ADF-support on ScanJet 6350 (and maybe others) 104141cc406Sopenharmony_ci 105141cc406Sopenharmony_ci V 0.92, 03-Oct-2000, Rupert W. Curwen (rcurwen@uk.research.att.com): 106141cc406Sopenharmony_ci - try to not allocate accessors twice (only for accessors 107141cc406Sopenharmony_ci that have fixed length) 108141cc406Sopenharmony_ci - fix problem with leaving connection open for some error conditions 109141cc406Sopenharmony_ci 110141cc406Sopenharmony_ci V 0.91, 04-Sep-2000, David Paschal (paschal@rcsis.com): 111141cc406Sopenharmony_ci - Added support for flatbed HP OfficeJets 112141cc406Sopenharmony_ci - (PK) fix problem with cancel preview 113141cc406Sopenharmony_ci 114141cc406Sopenharmony_ci V 0.90, 02-Sep-2000, PK: 115141cc406Sopenharmony_ci - fix timing problem between killing child and writing to pipe 116141cc406Sopenharmony_ci - change fprintf(stderr,...) to DBG 117141cc406Sopenharmony_ci - change include <sane..> to "sane.." in hp.h 118141cc406Sopenharmony_ci - change handling of options that have global effects. 119141cc406Sopenharmony_ci i.e. if option scanmode is received (has global effect), 120141cc406Sopenharmony_ci all options that "may change" are send to the scanner again. 121141cc406Sopenharmony_ci This fixes a problem that --resolution specified infront of 122141cc406Sopenharmony_ci --mode on command line of scanimage was ignored. 123141cc406Sopenharmony_ci NOTE: This change does not allow to specify --depth 12 infront of 124141cc406Sopenharmony_ci --mode color, because --depth is only enabled with --mode color. 125141cc406Sopenharmony_ci - add depth greater 8 bits for mode grayscale 126141cc406Sopenharmony_ci - add option for 8 bit output but 10/12 bit scanning 127141cc406Sopenharmony_ci V 0.88, 25-Jul-2000, PK: 128141cc406Sopenharmony_ci - remove inlines 129141cc406Sopenharmony_ci V 0.88, 20-Jul-2000, PK: 130141cc406Sopenharmony_ci - Use sanei_config_read() 131141cc406Sopenharmony_ci - don't write chars < 32 to DBG 132141cc406Sopenharmony_ci V 0.88, 09-Jul-2000, PK: 133141cc406Sopenharmony_ci - Add front button support by Chris S. Cowles, Houston, Texas, 134141cc406Sopenharmony_ci c_cowles@ieee.org 135141cc406Sopenharmony_ci V 0.87, 28-Jun-2000, PK: 136141cc406Sopenharmony_ci - ADF-support for ScanJet IIp 137141cc406Sopenharmony_ci - Return error SANE_STATUS_NO_DOCS if no paper in ADF 138141cc406Sopenharmony_ci V 0.86, 12-Feb-2000, PK: 139141cc406Sopenharmony_ci - fix gcc warnings 140141cc406Sopenharmony_ci - fix problems with bitdepths > 8 141141cc406Sopenharmony_ci - allow hp_data_resize to be called with newsize==bufsiz 142141cc406Sopenharmony_ci (Jens Heise, <heisbeee@calvados.zrz.TU-Berlin.DE>) 143141cc406Sopenharmony_ci - add option enable-image-buffering 144141cc406Sopenharmony_ci V 0.85, 30-Jan-2000, PK: 145141cc406Sopenharmony_ci - correct and enhance data widths > 8 (Ewald de Wit <ewald@pobox.com>) 146141cc406Sopenharmony_ci - enable data width for all scanners 147141cc406Sopenharmony_ci - PhotoSmart: exposure "Off" changed to "Default" 148141cc406Sopenharmony_ci - PhotoSmart: even if max. datawidth 24 is reported, allow 30 bits. 149141cc406Sopenharmony_ci - change keyword -data-width to -depth and use value for bits per sample 150141cc406Sopenharmony_ci - change keyword -halftone-type to -halftone-pattern 151141cc406Sopenharmony_ci - change keyword -scantype to -source 152141cc406Sopenharmony_ci - fix problem with multiple definition of sanei_debug_hp 153141cc406Sopenharmony_ci V 0.83, 04-Jul-99, PK: 154141cc406Sopenharmony_ci - reset scanner before downloading parameters (fixes problem 155141cc406Sopenharmony_ci with sleep mode of scanners) 156141cc406Sopenharmony_ci - fix problem with coredump if non-scanner HP SCSI devices 157141cc406Sopenharmony_ci are connected (CDR) 158141cc406Sopenharmony_ci - option scan-from-adf replaced by scantype normal/adf/xpa 159141cc406Sopenharmony_ci - change value "Film strip" to "Film-strip" for option 160141cc406Sopenharmony_ci --media-type 161141cc406Sopenharmony_ci - PhotoScanner: allow only scanning at multiple of 300 dpi 162141cc406Sopenharmony_ci for scanning slides/film strips. This also fixes a problem with the 163141cc406Sopenharmony_ci preview which uses arbitrary resolutions. 164141cc406Sopenharmony_ci - Marian Szebenyi: close pipe (endless loop on Digital UNIX) 165141cc406Sopenharmony_ci 166141cc406Sopenharmony_ci V 0.82, 28-Feb-99, Ewald de Wit <ewald@pobox.com>: 167141cc406Sopenharmony_ci - add options 'exposure time' and 'data width' 168141cc406Sopenharmony_ci 169141cc406Sopenharmony_ci V 0.81, 11-Jan-99, PK: 170141cc406Sopenharmony_ci - occasionally 'scan from ADF' was active for Photoscanner 171141cc406Sopenharmony_ci 172141cc406Sopenharmony_ci V 0.80, 10-Jan-99, PK: 173141cc406Sopenharmony_ci - fix problem with scan size for ADF-scan 174141cc406Sopenharmony_ci (thanks to Christop Biardzki <cbi@allgaeu.org> for tests) 175141cc406Sopenharmony_ci - add option "unload after scan" for HP PhotoScanner 176141cc406Sopenharmony_ci - no blanks in command line options 177141cc406Sopenharmony_ci - fix problem with segmentation fault for scanimage -d hp:/dev/sga 178141cc406Sopenharmony_ci with /dev/sga not included in hp.conf 179141cc406Sopenharmony_ci 180141cc406Sopenharmony_ci V 0.72, 25-Dec-98, PK: 181141cc406Sopenharmony_ci - add patches from mike@easysw.com to fix problems: 182141cc406Sopenharmony_ci - core dumps by memory alignment 183141cc406Sopenharmony_ci - config file to accept matching devices (scsi HP) 184141cc406Sopenharmony_ci - add simulation for brightness/contrast/custom gamma table 185141cc406Sopenharmony_ci if not supported by scanner 186141cc406Sopenharmony_ci - add configuration options for connect-... 187141cc406Sopenharmony_ci 188141cc406Sopenharmony_ci V 0.72c, 04-Dec-98, PK: 189141cc406Sopenharmony_ci - use sanei_pio 190141cc406Sopenharmony_ci - try ADF support 191141cc406Sopenharmony_ci 192141cc406Sopenharmony_ci V 0.72b, 29-Nov-98 James Carter <james@cs.york.ac.uk>, PK: 193141cc406Sopenharmony_ci - try to add parallel scanner support 194141cc406Sopenharmony_ci 195141cc406Sopenharmony_ci V 0.71, 14-Nov-98 PK: 196141cc406Sopenharmony_ci - add HP 6200 C 197141cc406Sopenharmony_ci - cleanup hp_scsi_s structure 198141cc406Sopenharmony_ci - show calibrate button on photoscanner only for print media 199141cc406Sopenharmony_ci - suppress halftone mode on photoscanner 200141cc406Sopenharmony_ci - add media selection for photoscanner 201141cc406Sopenharmony_ci 202141cc406Sopenharmony_ci V 0.70, 26-Jul-98 PK: 203141cc406Sopenharmony_ci - Rename global symbols to sanei_... 204141cc406Sopenharmony_ci Change filenames to hp-... 205141cc406Sopenharmony_ci Use backend name hp 206141cc406Sopenharmony_ci 207141cc406Sopenharmony_ci V 0.65, 18-Jul-98 PK: 208141cc406Sopenharmony_ci - Dont use pwd.h for VACPP-Compiler to get home-directory, 209141cc406Sopenharmony_ci check $SANE_HOME_XHP instead 210141cc406Sopenharmony_ci 211141cc406Sopenharmony_ci V 0.64, 12-Jul-98 PK: 212141cc406Sopenharmony_ci - only download calibration file for media = 1 (prints) 213141cc406Sopenharmony_ci - Changes for VACPP-Compiler (check macros __IBMC__, __IBMCPP__) 214141cc406Sopenharmony_ci 215141cc406Sopenharmony_ci V 0.63, 07-Jun-98 PK: 216141cc406Sopenharmony_ci - fix problem with custom gamma table 217141cc406Sopenharmony_ci - Add unload button 218141cc406Sopenharmony_ci 219141cc406Sopenharmony_ci V 0.62, 25-May-98 PK: 220141cc406Sopenharmony_ci - make it compilable under sane V 0.73 221141cc406Sopenharmony_ci 222141cc406Sopenharmony_ci V 0.61, 28-Mar-98, Peter Kirchgessner <pkirchg@aol.com>: 223141cc406Sopenharmony_ci - Add support for HP PhotoSmart Photoscanner 224141cc406Sopenharmony_ci - Use more inquiries to see what the scanner supports 225141cc406Sopenharmony_ci - Add options: calibrate/Mirror horizontal+vertical 226141cc406Sopenharmony_ci - Upload/download calibration data 227141cc406Sopenharmony_ci*/ 228141cc406Sopenharmony_ci 229141cc406Sopenharmony_ci#define VERSIO 8 230141cc406Sopenharmony_ci 231141cc406Sopenharmony_ci#include "../include/sane/config.h" 232141cc406Sopenharmony_ci#include "hp.h" 233141cc406Sopenharmony_ci 234141cc406Sopenharmony_ci#include <string.h> 235141cc406Sopenharmony_ci/* #include <sys/types.h> */ 236141cc406Sopenharmony_ci/* #include "../include/sane/sane.h" */ 237141cc406Sopenharmony_ci#include "../include/sane/sanei_config.h" 238141cc406Sopenharmony_ci#include "../include/sane/sanei_backend.h" 239141cc406Sopenharmony_ci#include "../include/sane/sanei_usb.h" 240141cc406Sopenharmony_ci#include "../include/sane/sanei_thread.h" 241141cc406Sopenharmony_ci/* #include "../include/sane/sanei_debug.h" */ 242141cc406Sopenharmony_ci#include "hp-device.h" 243141cc406Sopenharmony_ci#include "hp-handle.h" 244141cc406Sopenharmony_ci 245141cc406Sopenharmony_ci#ifndef PATH_MAX 246141cc406Sopenharmony_ci# define PATH_MAX 1024 247141cc406Sopenharmony_ci#endif 248141cc406Sopenharmony_ci 249141cc406Sopenharmony_ci#ifndef NDEBUG 250141cc406Sopenharmony_ci#include <ctype.h> 251141cc406Sopenharmony_civoid 252141cc406Sopenharmony_cisanei_hp_dbgdump (const void * bufp, size_t len) 253141cc406Sopenharmony_ci{ 254141cc406Sopenharmony_ci const hp_byte_t *buf = bufp; 255141cc406Sopenharmony_ci int offset = 0; 256141cc406Sopenharmony_ci int i; 257141cc406Sopenharmony_ci char line[128], pt[32]; 258141cc406Sopenharmony_ci 259141cc406Sopenharmony_ci for (offset = 0; offset < (int)len; offset += 16) 260141cc406Sopenharmony_ci { 261141cc406Sopenharmony_ci sprintf (line," 0x%04X ", offset); 262141cc406Sopenharmony_ci for (i = offset; i < offset + 16 && i < (int)len; i++) 263141cc406Sopenharmony_ci { 264141cc406Sopenharmony_ci sprintf (pt," %02X", buf[i]); 265141cc406Sopenharmony_ci strcat (line, pt); 266141cc406Sopenharmony_ci } 267141cc406Sopenharmony_ci while (i++ < offset + 16) 268141cc406Sopenharmony_ci strcat (line, " "); 269141cc406Sopenharmony_ci strcat (line, " "); 270141cc406Sopenharmony_ci for (i = offset; i < offset + 16 && i < (int)len; i++) 271141cc406Sopenharmony_ci { 272141cc406Sopenharmony_ci sprintf (pt, "%c", isprint(buf[i]) ? buf[i] : '.'); 273141cc406Sopenharmony_ci strcat (line, pt); 274141cc406Sopenharmony_ci } 275141cc406Sopenharmony_ci DBG(16,"%s\n",line); 276141cc406Sopenharmony_ci } 277141cc406Sopenharmony_ci} 278141cc406Sopenharmony_ci 279141cc406Sopenharmony_ci#endif 280141cc406Sopenharmony_ci 281141cc406Sopenharmony_citypedef struct info_list_el_s * HpDeviceInfoList; 282141cc406Sopenharmony_cistruct info_list_el_s 283141cc406Sopenharmony_ci{ 284141cc406Sopenharmony_ci HpDeviceInfoList next; 285141cc406Sopenharmony_ci HpDeviceInfo info; 286141cc406Sopenharmony_ci}; 287141cc406Sopenharmony_ci 288141cc406Sopenharmony_citypedef struct device_list_el_s * HpDeviceList; 289141cc406Sopenharmony_cistruct device_list_el_s 290141cc406Sopenharmony_ci{ 291141cc406Sopenharmony_ci HpDeviceList next; 292141cc406Sopenharmony_ci HpDevice dev; 293141cc406Sopenharmony_ci}; 294141cc406Sopenharmony_ci 295141cc406Sopenharmony_ci/* Global state */ 296141cc406Sopenharmony_cistatic struct hp_global_s { 297141cc406Sopenharmony_ci hp_bool_t is_up; 298141cc406Sopenharmony_ci hp_bool_t config_read; 299141cc406Sopenharmony_ci 300141cc406Sopenharmony_ci const SANE_Device ** devlist; 301141cc406Sopenharmony_ci 302141cc406Sopenharmony_ci HpDeviceList device_list; 303141cc406Sopenharmony_ci HpDeviceList handle_list; 304141cc406Sopenharmony_ci HpDeviceInfoList infolist; 305141cc406Sopenharmony_ci 306141cc406Sopenharmony_ci HpDeviceConfig config; 307141cc406Sopenharmony_ci} global; 308141cc406Sopenharmony_ci 309141cc406Sopenharmony_ci 310141cc406Sopenharmony_ci/* Get the info structure for a device. If not available in global list */ 311141cc406Sopenharmony_ci/* add new entry and return it */ 312141cc406Sopenharmony_cistatic HpDeviceInfo * 313141cc406Sopenharmony_cihp_device_info_create (const char *devname) 314141cc406Sopenharmony_ci 315141cc406Sopenharmony_ci{ 316141cc406Sopenharmony_ci HpDeviceInfoList *infolist = &(global.infolist); 317141cc406Sopenharmony_ci HpDeviceInfoList infolistelement; 318141cc406Sopenharmony_ci HpDeviceInfo *info; 319141cc406Sopenharmony_ci int k, found; 320141cc406Sopenharmony_ci 321141cc406Sopenharmony_ci if (!global.is_up) return 0; 322141cc406Sopenharmony_ci 323141cc406Sopenharmony_ci found = 0; 324141cc406Sopenharmony_ci infolistelement = 0; 325141cc406Sopenharmony_ci info = 0; 326141cc406Sopenharmony_ci while (*infolist) 327141cc406Sopenharmony_ci { 328141cc406Sopenharmony_ci infolistelement = *infolist; 329141cc406Sopenharmony_ci info = &(infolistelement->info); 330141cc406Sopenharmony_ci if (strcmp (info->devname, devname) == 0) /* Already in list ? */ 331141cc406Sopenharmony_ci { 332141cc406Sopenharmony_ci found = 1; 333141cc406Sopenharmony_ci break; 334141cc406Sopenharmony_ci } 335141cc406Sopenharmony_ci infolist = &(infolistelement->next); 336141cc406Sopenharmony_ci } 337141cc406Sopenharmony_ci 338141cc406Sopenharmony_ci if (found) /* Clear old entry */ 339141cc406Sopenharmony_ci { 340141cc406Sopenharmony_ci memset (infolistelement, 0, sizeof (*infolistelement)); 341141cc406Sopenharmony_ci } 342141cc406Sopenharmony_ci else /* New element */ 343141cc406Sopenharmony_ci { 344141cc406Sopenharmony_ci infolistelement = (HpDeviceInfoList) 345141cc406Sopenharmony_ci sanei_hp_allocz (sizeof (*infolistelement)); 346141cc406Sopenharmony_ci if (!infolistelement) return 0; 347141cc406Sopenharmony_ci info = &(infolistelement->info); 348141cc406Sopenharmony_ci *infolist = infolistelement; 349141cc406Sopenharmony_ci } 350141cc406Sopenharmony_ci 351141cc406Sopenharmony_ci k = sizeof (info->devname); 352141cc406Sopenharmony_ci strncpy (info->devname, devname, k); 353141cc406Sopenharmony_ci info->devname[k-1] = '\0'; 354141cc406Sopenharmony_ci info->max_model = -1; 355141cc406Sopenharmony_ci info->active_xpa = -1; 356141cc406Sopenharmony_ci 357141cc406Sopenharmony_ci return info; 358141cc406Sopenharmony_ci} 359141cc406Sopenharmony_ci 360141cc406Sopenharmony_cistatic void 361141cc406Sopenharmony_cihp_init_config (HpDeviceConfig *config) 362141cc406Sopenharmony_ci 363141cc406Sopenharmony_ci{ 364141cc406Sopenharmony_ci if (config) 365141cc406Sopenharmony_ci { 366141cc406Sopenharmony_ci config->connect = HP_CONNECT_SCSI; 367141cc406Sopenharmony_ci config->use_scsi_request = 1; 368141cc406Sopenharmony_ci config->use_image_buffering = 0; 369141cc406Sopenharmony_ci config->got_connect_type = 0; 370141cc406Sopenharmony_ci config->dumb_read = 0; 371141cc406Sopenharmony_ci } 372141cc406Sopenharmony_ci} 373141cc406Sopenharmony_ci 374141cc406Sopenharmony_cistatic HpDeviceConfig * 375141cc406Sopenharmony_cihp_global_config_get (void) 376141cc406Sopenharmony_ci 377141cc406Sopenharmony_ci{ 378141cc406Sopenharmony_ci if (!global.is_up) return 0; 379141cc406Sopenharmony_ci return &(global.config); 380141cc406Sopenharmony_ci} 381141cc406Sopenharmony_ci 382141cc406Sopenharmony_cistatic SANE_Status 383141cc406Sopenharmony_cihp_device_config_add (const char *devname) 384141cc406Sopenharmony_ci 385141cc406Sopenharmony_ci{ 386141cc406Sopenharmony_ci HpDeviceInfo *info; 387141cc406Sopenharmony_ci HpDeviceConfig *config; 388141cc406Sopenharmony_ci 389141cc406Sopenharmony_ci info = hp_device_info_create (devname); 390141cc406Sopenharmony_ci if (!info) return SANE_STATUS_INVAL; 391141cc406Sopenharmony_ci 392141cc406Sopenharmony_ci config = hp_global_config_get (); 393141cc406Sopenharmony_ci 394141cc406Sopenharmony_ci if (config) 395141cc406Sopenharmony_ci { 396141cc406Sopenharmony_ci memcpy (&(info->config), config, sizeof (info->config)); 397141cc406Sopenharmony_ci info->config_is_up = 1; 398141cc406Sopenharmony_ci } 399141cc406Sopenharmony_ci else /* Initialize with default configuration */ 400141cc406Sopenharmony_ci { 401141cc406Sopenharmony_ci DBG(3, "hp_device_config_add: No configuration found for device %s.\n\tUseing default\n", 402141cc406Sopenharmony_ci devname); 403141cc406Sopenharmony_ci hp_init_config (&(info->config)); 404141cc406Sopenharmony_ci info->config_is_up = 1; 405141cc406Sopenharmony_ci } 406141cc406Sopenharmony_ci return SANE_STATUS_GOOD; 407141cc406Sopenharmony_ci} 408141cc406Sopenharmony_ci 409141cc406Sopenharmony_ciHpDeviceInfo * 410141cc406Sopenharmony_cisanei_hp_device_info_get (const char *devname) 411141cc406Sopenharmony_ci 412141cc406Sopenharmony_ci{ 413141cc406Sopenharmony_ci HpDeviceInfoList *infolist; 414141cc406Sopenharmony_ci HpDeviceInfoList infolistelement; 415141cc406Sopenharmony_ci HpDeviceInfo *info; 416141cc406Sopenharmony_ci int retries = 1; 417141cc406Sopenharmony_ci 418141cc406Sopenharmony_ci if (!global.is_up) 419141cc406Sopenharmony_ci { 420141cc406Sopenharmony_ci DBG(17, "sanei_hp_device_info_get: global.is_up = %d\n", (int)global.is_up); 421141cc406Sopenharmony_ci return 0; 422141cc406Sopenharmony_ci } 423141cc406Sopenharmony_ci 424141cc406Sopenharmony_ci DBG(250, "sanei_hp_device_info_get: searching %s\n", devname); 425141cc406Sopenharmony_ci do 426141cc406Sopenharmony_ci { 427141cc406Sopenharmony_ci infolist = &(global.infolist); 428141cc406Sopenharmony_ci while (*infolist) 429141cc406Sopenharmony_ci { 430141cc406Sopenharmony_ci infolistelement = *infolist; 431141cc406Sopenharmony_ci info = &(infolistelement->info); 432141cc406Sopenharmony_ci DBG(250, "sanei_hp_device_info_get: check %s\n", info->devname); 433141cc406Sopenharmony_ci if (strcmp (info->devname, devname) == 0) /* Found ? */ 434141cc406Sopenharmony_ci { 435141cc406Sopenharmony_ci return info; 436141cc406Sopenharmony_ci } 437141cc406Sopenharmony_ci infolist = &(infolistelement->next); 438141cc406Sopenharmony_ci } 439141cc406Sopenharmony_ci 440141cc406Sopenharmony_ci /* No configuration found. Assume default */ 441141cc406Sopenharmony_ci DBG(1, "hp_device_info_get: device %s not configured. Using default\n", 442141cc406Sopenharmony_ci devname); 443141cc406Sopenharmony_ci if (hp_device_config_add (devname) != SANE_STATUS_GOOD) 444141cc406Sopenharmony_ci return 0; 445141cc406Sopenharmony_ci } 446141cc406Sopenharmony_ci while (retries-- > 0); 447141cc406Sopenharmony_ci 448141cc406Sopenharmony_ci return 0; 449141cc406Sopenharmony_ci} 450141cc406Sopenharmony_ci 451141cc406Sopenharmony_ciHpDevice 452141cc406Sopenharmony_cisanei_hp_device_get (const char *devname) 453141cc406Sopenharmony_ci{ 454141cc406Sopenharmony_ci HpDeviceList ptr; 455141cc406Sopenharmony_ci 456141cc406Sopenharmony_ci for (ptr = global.device_list; ptr; ptr = ptr->next) 457141cc406Sopenharmony_ci if (strcmp(sanei_hp_device_sanedevice(ptr->dev)->name, devname) == 0) 458141cc406Sopenharmony_ci return ptr->dev; 459141cc406Sopenharmony_ci 460141cc406Sopenharmony_ci return 0; 461141cc406Sopenharmony_ci} 462141cc406Sopenharmony_ci 463141cc406Sopenharmony_cistatic void 464141cc406Sopenharmony_cihp_device_info_remove (void) 465141cc406Sopenharmony_ci{ 466141cc406Sopenharmony_ci HpDeviceInfoList next, infolistelement = global.infolist; 467141cc406Sopenharmony_ci 468141cc406Sopenharmony_ci if (!global.is_up) return; 469141cc406Sopenharmony_ci 470141cc406Sopenharmony_ci while (infolistelement) 471141cc406Sopenharmony_ci { 472141cc406Sopenharmony_ci next = infolistelement->next; 473141cc406Sopenharmony_ci sanei_hp_free (infolistelement); 474141cc406Sopenharmony_ci infolistelement = next; 475141cc406Sopenharmony_ci } 476141cc406Sopenharmony_ci} 477141cc406Sopenharmony_ci 478141cc406Sopenharmony_cistatic SANE_Status 479141cc406Sopenharmony_cihp_device_list_add (HpDeviceList * list, HpDevice dev) 480141cc406Sopenharmony_ci{ 481141cc406Sopenharmony_ci HpDeviceList new = sanei_hp_alloc(sizeof(*new)); 482141cc406Sopenharmony_ci 483141cc406Sopenharmony_ci if (!new) 484141cc406Sopenharmony_ci return SANE_STATUS_NO_MEM; 485141cc406Sopenharmony_ci while (*list) 486141cc406Sopenharmony_ci list = &(*list)->next; 487141cc406Sopenharmony_ci 488141cc406Sopenharmony_ci *list = new; 489141cc406Sopenharmony_ci new->next = 0; 490141cc406Sopenharmony_ci new->dev = dev; 491141cc406Sopenharmony_ci return SANE_STATUS_GOOD; 492141cc406Sopenharmony_ci} 493141cc406Sopenharmony_ci 494141cc406Sopenharmony_cistatic SANE_Status 495141cc406Sopenharmony_cihp_device_list_remove (HpDeviceList * list, HpDevice dev) 496141cc406Sopenharmony_ci{ 497141cc406Sopenharmony_ci HpDeviceList old; 498141cc406Sopenharmony_ci 499141cc406Sopenharmony_ci while (*list && (*list)->dev != dev) 500141cc406Sopenharmony_ci list = &(*list)->next; 501141cc406Sopenharmony_ci 502141cc406Sopenharmony_ci if (!*list) 503141cc406Sopenharmony_ci return SANE_STATUS_INVAL; 504141cc406Sopenharmony_ci 505141cc406Sopenharmony_ci old = *list; 506141cc406Sopenharmony_ci *list = (*list)->next; 507141cc406Sopenharmony_ci sanei_hp_free(old); 508141cc406Sopenharmony_ci return SANE_STATUS_GOOD; 509141cc406Sopenharmony_ci} 510141cc406Sopenharmony_ci 511141cc406Sopenharmony_cistatic SANE_Status 512141cc406Sopenharmony_cihp_handle_list_add (HpDeviceList * list, HpHandle h) 513141cc406Sopenharmony_ci{ 514141cc406Sopenharmony_ci return hp_device_list_add(list, (HpDevice)h); 515141cc406Sopenharmony_ci} 516141cc406Sopenharmony_ci 517141cc406Sopenharmony_cistatic SANE_Status 518141cc406Sopenharmony_cihp_handle_list_remove (HpDeviceList * list, HpHandle h) 519141cc406Sopenharmony_ci{ 520141cc406Sopenharmony_ci return hp_device_list_remove(list, (HpDevice)h); 521141cc406Sopenharmony_ci} 522141cc406Sopenharmony_ci 523141cc406Sopenharmony_ci 524141cc406Sopenharmony_ci 525141cc406Sopenharmony_ci 526141cc406Sopenharmony_cistatic SANE_Status 527141cc406Sopenharmony_cihp_init (void) 528141cc406Sopenharmony_ci{ 529141cc406Sopenharmony_ci memset(&global, 0, sizeof(global)); 530141cc406Sopenharmony_ci global.is_up++; 531141cc406Sopenharmony_ci DBG(3, "hp_init: global.is_up = %d\n", (int)global.is_up); 532141cc406Sopenharmony_ci return SANE_STATUS_GOOD; 533141cc406Sopenharmony_ci} 534141cc406Sopenharmony_ci 535141cc406Sopenharmony_cistatic void 536141cc406Sopenharmony_cihp_destroy (void) 537141cc406Sopenharmony_ci{ 538141cc406Sopenharmony_ci if (global.is_up) 539141cc406Sopenharmony_ci { 540141cc406Sopenharmony_ci /* Close open handles */ 541141cc406Sopenharmony_ci while (global.handle_list) 542141cc406Sopenharmony_ci sane_close(global.handle_list->dev); 543141cc406Sopenharmony_ci 544141cc406Sopenharmony_ci /* Remove device infos */ 545141cc406Sopenharmony_ci hp_device_info_remove (); 546141cc406Sopenharmony_ci 547141cc406Sopenharmony_ci sanei_hp_free_all(); 548141cc406Sopenharmony_ci global.is_up = 0; 549141cc406Sopenharmony_ci DBG(3, "hp_destroy: global.is_up = %d\n", (int)global.is_up); 550141cc406Sopenharmony_ci } 551141cc406Sopenharmony_ci} 552141cc406Sopenharmony_ci 553141cc406Sopenharmony_cistatic SANE_Status 554141cc406Sopenharmony_cihp_get_dev (const char *devname, HpDevice* devp) 555141cc406Sopenharmony_ci{ 556141cc406Sopenharmony_ci HpDeviceList ptr; 557141cc406Sopenharmony_ci HpDevice new; 558141cc406Sopenharmony_ci const HpDeviceInfo *info; 559141cc406Sopenharmony_ci char *connect; 560141cc406Sopenharmony_ci HpConnect hp_connect; 561141cc406Sopenharmony_ci SANE_Status status; 562141cc406Sopenharmony_ci 563141cc406Sopenharmony_ci for (ptr = global.device_list; ptr; ptr = ptr->next) 564141cc406Sopenharmony_ci if (strcmp(sanei_hp_device_sanedevice(ptr->dev)->name, devname) == 0) 565141cc406Sopenharmony_ci { 566141cc406Sopenharmony_ci if (devp) 567141cc406Sopenharmony_ci *devp = ptr->dev; 568141cc406Sopenharmony_ci return SANE_STATUS_GOOD; 569141cc406Sopenharmony_ci } 570141cc406Sopenharmony_ci 571141cc406Sopenharmony_ci info = sanei_hp_device_info_get (devname); 572141cc406Sopenharmony_ci hp_connect = info->config.connect; 573141cc406Sopenharmony_ci 574141cc406Sopenharmony_ci if (hp_connect == HP_CONNECT_SCSI) connect = "scsi"; 575141cc406Sopenharmony_ci else if (hp_connect == HP_CONNECT_DEVICE) connect = "device"; 576141cc406Sopenharmony_ci else if (hp_connect == HP_CONNECT_PIO) connect = "pio"; 577141cc406Sopenharmony_ci else if (hp_connect == HP_CONNECT_USB) connect = "usb"; 578141cc406Sopenharmony_ci else if (hp_connect == HP_CONNECT_RESERVE) connect = "reserve"; 579141cc406Sopenharmony_ci else connect = "unknown"; 580141cc406Sopenharmony_ci 581141cc406Sopenharmony_ci DBG(3, "hp_get_dev: New device %s, connect-%s, scsi-request=%lu\n", 582141cc406Sopenharmony_ci devname, connect, (unsigned long)info->config.use_scsi_request); 583141cc406Sopenharmony_ci 584141cc406Sopenharmony_ci status = sanei_hp_device_new (&new, devname); 585141cc406Sopenharmony_ci if (status != SANE_STATUS_GOOD) 586141cc406Sopenharmony_ci return status; 587141cc406Sopenharmony_ci 588141cc406Sopenharmony_ci if (devp) 589141cc406Sopenharmony_ci *devp = new; 590141cc406Sopenharmony_ci 591141cc406Sopenharmony_ci RETURN_IF_FAIL( hp_device_list_add(&global.device_list, new) ); 592141cc406Sopenharmony_ci 593141cc406Sopenharmony_ci return SANE_STATUS_GOOD; 594141cc406Sopenharmony_ci} 595141cc406Sopenharmony_ci 596141cc406Sopenharmony_cistatic SANE_Status 597141cc406Sopenharmony_cihp_attach (const char *devname) 598141cc406Sopenharmony_ci{ 599141cc406Sopenharmony_ci DBG(7,"hp_attach: \"%s\"\n", devname); 600141cc406Sopenharmony_ci hp_device_config_add (devname); 601141cc406Sopenharmony_ci return hp_get_dev (devname, 0); 602141cc406Sopenharmony_ci} 603141cc406Sopenharmony_ci 604141cc406Sopenharmony_cistatic void 605141cc406Sopenharmony_cihp_attach_matching_devices (HpDeviceConfig *config, const char *devname) 606141cc406Sopenharmony_ci{ 607141cc406Sopenharmony_ci static int usb_initialized = 0; 608141cc406Sopenharmony_ci 609141cc406Sopenharmony_ci if (strncmp (devname, "usb", 3) == 0) 610141cc406Sopenharmony_ci { 611141cc406Sopenharmony_ci config->connect = HP_CONNECT_USB; 612141cc406Sopenharmony_ci config->use_scsi_request = 0; 613141cc406Sopenharmony_ci DBG(1,"hp_attach_matching_devices: usb attach matching \"%s\"\n",devname); 614141cc406Sopenharmony_ci if (!usb_initialized) 615141cc406Sopenharmony_ci { 616141cc406Sopenharmony_ci sanei_usb_init (); 617141cc406Sopenharmony_ci usb_initialized = 1; 618141cc406Sopenharmony_ci } 619141cc406Sopenharmony_ci sanei_usb_attach_matching_devices (devname, hp_attach); 620141cc406Sopenharmony_ci } 621141cc406Sopenharmony_ci else 622141cc406Sopenharmony_ci { 623141cc406Sopenharmony_ci DBG(1, "hp_attach_matching_devices: attach matching %s\n", devname); 624141cc406Sopenharmony_ci sanei_config_attach_matching_devices (devname, hp_attach); 625141cc406Sopenharmony_ci } 626141cc406Sopenharmony_ci} 627141cc406Sopenharmony_ci 628141cc406Sopenharmony_cistatic SANE_Status 629141cc406Sopenharmony_cihp_read_config (void) 630141cc406Sopenharmony_ci{ 631141cc406Sopenharmony_ci FILE * fp; 632141cc406Sopenharmony_ci char buf[PATH_MAX], arg1[PATH_MAX], arg2[PATH_MAX], arg3[PATH_MAX]; 633141cc406Sopenharmony_ci int nl, nargs; 634141cc406Sopenharmony_ci HpDeviceConfig *config, df_config, dev_config; 635141cc406Sopenharmony_ci hp_bool_t is_df_config; 636141cc406Sopenharmony_ci char cu_device[PATH_MAX]; 637141cc406Sopenharmony_ci 638141cc406Sopenharmony_ci if (!global.is_up) 639141cc406Sopenharmony_ci return SANE_STATUS_INVAL; 640141cc406Sopenharmony_ci if (global.config_read) 641141cc406Sopenharmony_ci return SANE_STATUS_GOOD; 642141cc406Sopenharmony_ci 643141cc406Sopenharmony_ci /* The default config will keep options set up until the first device is specified */ 644141cc406Sopenharmony_ci hp_init_config (&df_config); 645141cc406Sopenharmony_ci config = &df_config; 646141cc406Sopenharmony_ci is_df_config = 1; 647141cc406Sopenharmony_ci cu_device[0] = '\0'; 648141cc406Sopenharmony_ci 649141cc406Sopenharmony_ci DBG(1, "hp_read_config: hp backend v%s starts reading config file\n", 650141cc406Sopenharmony_ci hp_backend_version); 651141cc406Sopenharmony_ci 652141cc406Sopenharmony_ci if ((fp = sanei_config_open(HP_CONFIG_FILE)) != 0) 653141cc406Sopenharmony_ci { 654141cc406Sopenharmony_ci while (sanei_config_read(buf, sizeof(buf), fp)) 655141cc406Sopenharmony_ci { 656141cc406Sopenharmony_ci char *dev_name; 657141cc406Sopenharmony_ci 658141cc406Sopenharmony_ci nl = strlen (buf); 659141cc406Sopenharmony_ci while (nl > 0) 660141cc406Sopenharmony_ci { 661141cc406Sopenharmony_ci nl--; 662141cc406Sopenharmony_ci if ( (buf[nl] == ' ') || (buf[nl] == '\t') 663141cc406Sopenharmony_ci || (buf[nl] == '\r') || (buf[nl] == '\n')) 664141cc406Sopenharmony_ci buf[nl] = '\0'; 665141cc406Sopenharmony_ci else 666141cc406Sopenharmony_ci break; 667141cc406Sopenharmony_ci } 668141cc406Sopenharmony_ci 669141cc406Sopenharmony_ci DBG(1, "hp_read_config: processing line <%s>\n", buf); 670141cc406Sopenharmony_ci 671141cc406Sopenharmony_ci nargs = sscanf (buf, "%s%s%s", arg1, arg2, arg3); 672141cc406Sopenharmony_ci if ((nargs <= 0) || (arg1[0] == '#')) continue; 673141cc406Sopenharmony_ci 674141cc406Sopenharmony_ci /* Option to process ? */ 675141cc406Sopenharmony_ci if ((strcmp (arg1, "option") == 0) && (nargs >= 2)) 676141cc406Sopenharmony_ci { 677141cc406Sopenharmony_ci if (strcmp (arg2, "connect-scsi") == 0) 678141cc406Sopenharmony_ci { 679141cc406Sopenharmony_ci config->connect = HP_CONNECT_SCSI; 680141cc406Sopenharmony_ci config->got_connect_type = 1; 681141cc406Sopenharmony_ci } 682141cc406Sopenharmony_ci else if (strcmp (arg2, "connect-device") == 0) 683141cc406Sopenharmony_ci { 684141cc406Sopenharmony_ci config->connect = HP_CONNECT_DEVICE; 685141cc406Sopenharmony_ci config->got_connect_type = 1; 686141cc406Sopenharmony_ci config->use_scsi_request = 0; 687141cc406Sopenharmony_ci } 688141cc406Sopenharmony_ci else if (strcmp (arg2, "connect-pio") == 0) 689141cc406Sopenharmony_ci { 690141cc406Sopenharmony_ci config->connect = HP_CONNECT_PIO; 691141cc406Sopenharmony_ci config->got_connect_type = 1; 692141cc406Sopenharmony_ci config->use_scsi_request = 0; 693141cc406Sopenharmony_ci } 694141cc406Sopenharmony_ci else if (strcmp (arg2, "connect-usb") == 0) 695141cc406Sopenharmony_ci { 696141cc406Sopenharmony_ci config->connect = HP_CONNECT_USB; 697141cc406Sopenharmony_ci config->got_connect_type = 1; 698141cc406Sopenharmony_ci config->use_scsi_request = 0; 699141cc406Sopenharmony_ci } 700141cc406Sopenharmony_ci else if (strcmp (arg2, "connect-reserve") == 0) 701141cc406Sopenharmony_ci { 702141cc406Sopenharmony_ci config->connect = HP_CONNECT_RESERVE; 703141cc406Sopenharmony_ci config->got_connect_type = 1; 704141cc406Sopenharmony_ci config->use_scsi_request = 0; 705141cc406Sopenharmony_ci } 706141cc406Sopenharmony_ci else if (strcmp (arg2, "disable-scsi-request") == 0) 707141cc406Sopenharmony_ci { 708141cc406Sopenharmony_ci config->use_scsi_request = 0; 709141cc406Sopenharmony_ci } 710141cc406Sopenharmony_ci else if (strcmp (arg2, "enable-image-buffering") == 0) 711141cc406Sopenharmony_ci { 712141cc406Sopenharmony_ci config->use_image_buffering = 1; 713141cc406Sopenharmony_ci } 714141cc406Sopenharmony_ci else if (strcmp (arg2, "dumb-read") == 0) 715141cc406Sopenharmony_ci { 716141cc406Sopenharmony_ci config->dumb_read = 1; 717141cc406Sopenharmony_ci } 718141cc406Sopenharmony_ci else 719141cc406Sopenharmony_ci { 720141cc406Sopenharmony_ci DBG(1,"hp_read_config: Invalid option %s\n", arg2); 721141cc406Sopenharmony_ci } 722141cc406Sopenharmony_ci } 723141cc406Sopenharmony_ci else /* No option. This is the start of a new device */ 724141cc406Sopenharmony_ci { 725141cc406Sopenharmony_ci if (is_df_config) /* Did we only read default configurations ? */ 726141cc406Sopenharmony_ci { 727141cc406Sopenharmony_ci is_df_config = 0; /* Stop reading default config */ 728141cc406Sopenharmony_ci /* Initialize device config with default-config */ 729141cc406Sopenharmony_ci memcpy (&dev_config, &df_config, sizeof (dev_config)); 730141cc406Sopenharmony_ci config = &dev_config; /* Start reading a device config */ 731141cc406Sopenharmony_ci } 732141cc406Sopenharmony_ci if (cu_device[0] != '\0') /* Did we work on a device ? */ 733141cc406Sopenharmony_ci { 734141cc406Sopenharmony_ci memcpy (hp_global_config_get(), &dev_config,sizeof (dev_config)); 735141cc406Sopenharmony_ci hp_attach_matching_devices (hp_global_config_get(), cu_device); 736141cc406Sopenharmony_ci cu_device[0] = '\0'; 737141cc406Sopenharmony_ci } 738141cc406Sopenharmony_ci 739141cc406Sopenharmony_ci /* Initialize new device with default config */ 740141cc406Sopenharmony_ci memcpy (&dev_config, &df_config, sizeof (dev_config)); 741141cc406Sopenharmony_ci 742141cc406Sopenharmony_ci /* Cut off leading blanks of device name */ 743141cc406Sopenharmony_ci dev_name = buf+strspn (buf, " \t\n\r"); 744141cc406Sopenharmony_ci strcpy (cu_device, dev_name); /* Save the device name */ 745141cc406Sopenharmony_ci } 746141cc406Sopenharmony_ci } 747141cc406Sopenharmony_ci if (cu_device[0] != '\0') /* Did we work on a device ? */ 748141cc406Sopenharmony_ci { 749141cc406Sopenharmony_ci memcpy (hp_global_config_get (), &dev_config, sizeof (dev_config)); 750141cc406Sopenharmony_ci DBG(1, "hp_read_config: attach %s\n", cu_device); 751141cc406Sopenharmony_ci hp_attach_matching_devices (hp_global_config_get (), cu_device); 752141cc406Sopenharmony_ci cu_device[0] = '\0'; 753141cc406Sopenharmony_ci } 754141cc406Sopenharmony_ci fclose (fp); 755141cc406Sopenharmony_ci DBG(1, "hp_read_config: reset to default config\n"); 756141cc406Sopenharmony_ci memcpy (hp_global_config_get (), &df_config, sizeof (df_config)); 757141cc406Sopenharmony_ci } 758141cc406Sopenharmony_ci else 759141cc406Sopenharmony_ci { 760141cc406Sopenharmony_ci /* default to /dev/scanner instead of insisting on config file */ 761141cc406Sopenharmony_ci char *dev_name = "/dev/scanner"; 762141cc406Sopenharmony_ci 763141cc406Sopenharmony_ci memcpy (hp_global_config_get (), &df_config, sizeof (df_config)); 764141cc406Sopenharmony_ci hp_attach_matching_devices (hp_global_config_get (), dev_name); 765141cc406Sopenharmony_ci } 766141cc406Sopenharmony_ci 767141cc406Sopenharmony_ci global.config_read++; 768141cc406Sopenharmony_ci return SANE_STATUS_GOOD; 769141cc406Sopenharmony_ci} 770141cc406Sopenharmony_ci 771141cc406Sopenharmony_cistatic SANE_Status 772141cc406Sopenharmony_cihp_update_devlist (void) 773141cc406Sopenharmony_ci{ 774141cc406Sopenharmony_ci HpDeviceList devp; 775141cc406Sopenharmony_ci const SANE_Device **devlist; 776141cc406Sopenharmony_ci int count = 0; 777141cc406Sopenharmony_ci 778141cc406Sopenharmony_ci RETURN_IF_FAIL( hp_read_config() ); 779141cc406Sopenharmony_ci 780141cc406Sopenharmony_ci if (global.devlist) 781141cc406Sopenharmony_ci sanei_hp_free(global.devlist); 782141cc406Sopenharmony_ci 783141cc406Sopenharmony_ci for (devp = global.device_list; devp; devp = devp->next) 784141cc406Sopenharmony_ci count++; 785141cc406Sopenharmony_ci 786141cc406Sopenharmony_ci if (!(devlist = sanei_hp_alloc((count + 1) * sizeof(*devlist)))) 787141cc406Sopenharmony_ci return SANE_STATUS_NO_MEM; 788141cc406Sopenharmony_ci 789141cc406Sopenharmony_ci global.devlist = devlist; 790141cc406Sopenharmony_ci 791141cc406Sopenharmony_ci for (devp = global.device_list; devp; devp = devp->next) 792141cc406Sopenharmony_ci *devlist++ = sanei_hp_device_sanedevice(devp->dev); 793141cc406Sopenharmony_ci *devlist = 0; 794141cc406Sopenharmony_ci 795141cc406Sopenharmony_ci return SANE_STATUS_GOOD; 796141cc406Sopenharmony_ci} 797141cc406Sopenharmony_ci 798141cc406Sopenharmony_ci 799141cc406Sopenharmony_ci/* 800141cc406Sopenharmony_ci * 801141cc406Sopenharmony_ci */ 802141cc406Sopenharmony_ci 803141cc406Sopenharmony_ciSANE_Status 804141cc406Sopenharmony_cisane_init (SANE_Int *version_code, SANE_Auth_Callback __sane_unused__ authorize) 805141cc406Sopenharmony_ci{SANE_Status status; 806141cc406Sopenharmony_ci 807141cc406Sopenharmony_ci DBG_INIT(); 808141cc406Sopenharmony_ci DBG(3, "sane_init called\n"); 809141cc406Sopenharmony_ci sanei_thread_init (); 810141cc406Sopenharmony_ci 811141cc406Sopenharmony_ci sanei_hp_init_openfd (); 812141cc406Sopenharmony_ci hp_destroy(); 813141cc406Sopenharmony_ci 814141cc406Sopenharmony_ci if (version_code) 815141cc406Sopenharmony_ci *version_code = SANE_VERSION_CODE (SANE_CURRENT_MAJOR, SANE_CURRENT_MINOR, VERSIO); 816141cc406Sopenharmony_ci 817141cc406Sopenharmony_ci status = hp_init(); 818141cc406Sopenharmony_ci DBG(3, "sane_init will finish with %s\n", sane_strstatus (status)); 819141cc406Sopenharmony_ci return status; 820141cc406Sopenharmony_ci} 821141cc406Sopenharmony_ci 822141cc406Sopenharmony_civoid 823141cc406Sopenharmony_cisane_exit (void) 824141cc406Sopenharmony_ci{ 825141cc406Sopenharmony_ci DBG(3, "sane_exit called\n"); 826141cc406Sopenharmony_ci hp_destroy(); 827141cc406Sopenharmony_ci DBG(3, "sane_exit will finish\n"); 828141cc406Sopenharmony_ci} 829141cc406Sopenharmony_ci 830141cc406Sopenharmony_ciSANE_Status 831141cc406Sopenharmony_cisane_get_devices (const SANE_Device ***device_list, 832141cc406Sopenharmony_ci SANE_Bool __sane_unused__ local_only) 833141cc406Sopenharmony_ci{ 834141cc406Sopenharmony_ci DBG(3, "sane_get_devices called\n"); 835141cc406Sopenharmony_ci 836141cc406Sopenharmony_ci RETURN_IF_FAIL( hp_update_devlist() ); 837141cc406Sopenharmony_ci *device_list = global.devlist; 838141cc406Sopenharmony_ci DBG(3, "sane_get_devices will finish with %s\n", 839141cc406Sopenharmony_ci sane_strstatus (SANE_STATUS_GOOD)); 840141cc406Sopenharmony_ci return SANE_STATUS_GOOD; 841141cc406Sopenharmony_ci} 842141cc406Sopenharmony_ci 843141cc406Sopenharmony_ciSANE_Status 844141cc406Sopenharmony_cisane_open (SANE_String_Const devicename, SANE_Handle *handle) 845141cc406Sopenharmony_ci{ 846141cc406Sopenharmony_ci HpDevice dev = 0; 847141cc406Sopenharmony_ci HpHandle h; 848141cc406Sopenharmony_ci 849141cc406Sopenharmony_ci DBG(3, "sane_open called\n"); 850141cc406Sopenharmony_ci 851141cc406Sopenharmony_ci RETURN_IF_FAIL( hp_read_config() ); 852141cc406Sopenharmony_ci 853141cc406Sopenharmony_ci if (devicename[0]) 854141cc406Sopenharmony_ci RETURN_IF_FAIL( hp_get_dev(devicename, &dev) ); 855141cc406Sopenharmony_ci else 856141cc406Sopenharmony_ci { 857141cc406Sopenharmony_ci /* empty devicname -> use first device */ 858141cc406Sopenharmony_ci if (global.device_list) 859141cc406Sopenharmony_ci dev = global.device_list->dev; 860141cc406Sopenharmony_ci } 861141cc406Sopenharmony_ci if (!dev) 862141cc406Sopenharmony_ci return SANE_STATUS_INVAL; 863141cc406Sopenharmony_ci 864141cc406Sopenharmony_ci if (!(h = sanei_hp_handle_new(dev))) 865141cc406Sopenharmony_ci return SANE_STATUS_NO_MEM; 866141cc406Sopenharmony_ci 867141cc406Sopenharmony_ci RETURN_IF_FAIL( hp_handle_list_add(&global.handle_list, h) ); 868141cc406Sopenharmony_ci 869141cc406Sopenharmony_ci *handle = h; 870141cc406Sopenharmony_ci DBG(3, "sane_open will finish with %s\n", sane_strstatus (SANE_STATUS_GOOD)); 871141cc406Sopenharmony_ci return SANE_STATUS_GOOD; 872141cc406Sopenharmony_ci} 873141cc406Sopenharmony_ci 874141cc406Sopenharmony_civoid 875141cc406Sopenharmony_cisane_close (SANE_Handle handle) 876141cc406Sopenharmony_ci{ 877141cc406Sopenharmony_ci HpHandle h = handle; 878141cc406Sopenharmony_ci 879141cc406Sopenharmony_ci DBG(3, "sane_close called\n"); 880141cc406Sopenharmony_ci 881141cc406Sopenharmony_ci if (!FAILED( hp_handle_list_remove(&global.handle_list, h) )) 882141cc406Sopenharmony_ci sanei_hp_handle_destroy(h); 883141cc406Sopenharmony_ci 884141cc406Sopenharmony_ci DBG(3, "sane_close will finish\n"); 885141cc406Sopenharmony_ci} 886141cc406Sopenharmony_ci 887141cc406Sopenharmony_ciconst SANE_Option_Descriptor * 888141cc406Sopenharmony_cisane_get_option_descriptor (SANE_Handle handle, SANE_Int optnum) 889141cc406Sopenharmony_ci{ 890141cc406Sopenharmony_ci HpHandle h = handle; 891141cc406Sopenharmony_ci const SANE_Option_Descriptor *optd; 892141cc406Sopenharmony_ci 893141cc406Sopenharmony_ci DBG(10, "sane_get_option_descriptor called\n"); 894141cc406Sopenharmony_ci 895141cc406Sopenharmony_ci optd = sanei_hp_handle_saneoption(h, optnum); 896141cc406Sopenharmony_ci 897141cc406Sopenharmony_ci DBG(10, "sane_get_option_descriptor will finish\n"); 898141cc406Sopenharmony_ci 899141cc406Sopenharmony_ci return optd; 900141cc406Sopenharmony_ci} 901141cc406Sopenharmony_ci 902141cc406Sopenharmony_ciSANE_Status 903141cc406Sopenharmony_cisane_control_option (SANE_Handle handle, SANE_Int optnum, 904141cc406Sopenharmony_ci SANE_Action action, void *valp, SANE_Int *info) 905141cc406Sopenharmony_ci{ 906141cc406Sopenharmony_ci HpHandle h = handle; 907141cc406Sopenharmony_ci SANE_Status status; 908141cc406Sopenharmony_ci 909141cc406Sopenharmony_ci DBG(10, "sane_control_option called\n"); 910141cc406Sopenharmony_ci 911141cc406Sopenharmony_ci status = sanei_hp_handle_control(h, optnum, action, valp, info); 912141cc406Sopenharmony_ci 913141cc406Sopenharmony_ci DBG(10, "sane_control_option will finish with %s\n", 914141cc406Sopenharmony_ci sane_strstatus (status)); 915141cc406Sopenharmony_ci return status; 916141cc406Sopenharmony_ci} 917141cc406Sopenharmony_ci 918141cc406Sopenharmony_ciSANE_Status 919141cc406Sopenharmony_cisane_get_parameters (SANE_Handle handle, SANE_Parameters *params) 920141cc406Sopenharmony_ci{ 921141cc406Sopenharmony_ci HpHandle h = handle; 922141cc406Sopenharmony_ci SANE_Status status; 923141cc406Sopenharmony_ci 924141cc406Sopenharmony_ci DBG(10, "sane_get_parameters called\n"); 925141cc406Sopenharmony_ci 926141cc406Sopenharmony_ci status = sanei_hp_handle_getParameters(h, params); 927141cc406Sopenharmony_ci 928141cc406Sopenharmony_ci DBG(10, "sane_get_parameters will finish with %s\n", 929141cc406Sopenharmony_ci sane_strstatus (status)); 930141cc406Sopenharmony_ci return status; 931141cc406Sopenharmony_ci} 932141cc406Sopenharmony_ci 933141cc406Sopenharmony_ciSANE_Status 934141cc406Sopenharmony_cisane_start (SANE_Handle handle) 935141cc406Sopenharmony_ci{ 936141cc406Sopenharmony_ci HpHandle h = handle; 937141cc406Sopenharmony_ci SANE_Status status; 938141cc406Sopenharmony_ci 939141cc406Sopenharmony_ci DBG(3, "sane_start called\n"); 940141cc406Sopenharmony_ci 941141cc406Sopenharmony_ci status = sanei_hp_handle_startScan(h); 942141cc406Sopenharmony_ci 943141cc406Sopenharmony_ci DBG(3, "sane_start will finish with %s\n", sane_strstatus (status)); 944141cc406Sopenharmony_ci return status; 945141cc406Sopenharmony_ci} 946141cc406Sopenharmony_ci 947141cc406Sopenharmony_ciSANE_Status 948141cc406Sopenharmony_cisane_read (SANE_Handle handle, SANE_Byte *buf, SANE_Int max_len, SANE_Int *len) 949141cc406Sopenharmony_ci{ 950141cc406Sopenharmony_ci HpHandle h = handle; 951141cc406Sopenharmony_ci size_t length = max_len; 952141cc406Sopenharmony_ci SANE_Status status; 953141cc406Sopenharmony_ci 954141cc406Sopenharmony_ci DBG(16, "sane_read called\n"); 955141cc406Sopenharmony_ci 956141cc406Sopenharmony_ci status = sanei_hp_handle_read(h, buf, &length); 957141cc406Sopenharmony_ci *len = length; 958141cc406Sopenharmony_ci 959141cc406Sopenharmony_ci DBG(16, "sane_read will finish with %s\n", sane_strstatus (status)); 960141cc406Sopenharmony_ci return status; 961141cc406Sopenharmony_ci} 962141cc406Sopenharmony_ci 963141cc406Sopenharmony_civoid 964141cc406Sopenharmony_cisane_cancel (SANE_Handle handle) 965141cc406Sopenharmony_ci{ 966141cc406Sopenharmony_ci HpHandle h = handle; 967141cc406Sopenharmony_ci 968141cc406Sopenharmony_ci DBG(3, "sane_cancel called\n"); 969141cc406Sopenharmony_ci 970141cc406Sopenharmony_ci sanei_hp_handle_cancel(h); 971141cc406Sopenharmony_ci 972141cc406Sopenharmony_ci DBG(3, "sane_cancel will finish\n"); 973141cc406Sopenharmony_ci} 974141cc406Sopenharmony_ci 975141cc406Sopenharmony_ciSANE_Status 976141cc406Sopenharmony_cisane_set_io_mode (SANE_Handle handle, SANE_Bool non_blocking) 977141cc406Sopenharmony_ci{ 978141cc406Sopenharmony_ci HpHandle h = handle; 979141cc406Sopenharmony_ci SANE_Status status; 980141cc406Sopenharmony_ci 981141cc406Sopenharmony_ci DBG(3, "sane_set_io_mode called\n"); 982141cc406Sopenharmony_ci 983141cc406Sopenharmony_ci status = sanei_hp_handle_setNonblocking(h, non_blocking); 984141cc406Sopenharmony_ci 985141cc406Sopenharmony_ci DBG(3, "sane_set_io_mode will finish with %s\n", 986141cc406Sopenharmony_ci sane_strstatus (status)); 987141cc406Sopenharmony_ci return status; 988141cc406Sopenharmony_ci} 989141cc406Sopenharmony_ci 990141cc406Sopenharmony_ciSANE_Status 991141cc406Sopenharmony_cisane_get_select_fd (SANE_Handle handle, SANE_Int *fd) 992141cc406Sopenharmony_ci{ 993141cc406Sopenharmony_ci HpHandle h = handle; 994141cc406Sopenharmony_ci SANE_Status status; 995141cc406Sopenharmony_ci 996141cc406Sopenharmony_ci DBG(10, "sane_get_select_fd called\n"); 997141cc406Sopenharmony_ci 998141cc406Sopenharmony_ci status = sanei_hp_handle_getPipefd(h, fd); 999141cc406Sopenharmony_ci 1000141cc406Sopenharmony_ci DBG(10, "sane_get_select_fd will finish with %s\n", 1001141cc406Sopenharmony_ci sane_strstatus (status)); 1002141cc406Sopenharmony_ci return status; 1003141cc406Sopenharmony_ci} 1004