• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* sane - Scanner Access Now Easy.
2    Copyright (C) 1997 Geoffrey T. Dairiki
3    Support for HP PhotoSmart Photoscanner by Peter Kirchgessner
4    This file is part of the SANE package.
5 
6    This program is free software; you can redistribute it and/or
7    modify it under the terms of the GNU General Public License as
8    published by the Free Software Foundation; either version 2 of the
9    License, or (at your option) any later version.
10 
11    This program is distributed in the hope that it will be useful, but
12    WITHOUT ANY WARRANTY; without even the implied warranty of
13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14    General Public License for more details.
15 
16    You should have received a copy of the GNU General Public License
17    along with this program.  If not, see <https://www.gnu.org/licenses/>.
18 
19    As a special exception, the authors of SANE give permission for
20    additional uses of the libraries contained in this release of SANE.
21 
22    The exception is that, if you link a SANE library with other files
23    to produce an executable, this does not by itself cause the
24    resulting executable to be covered by the GNU General Public
25    License.  Your use of that executable is in no way restricted on
26    account of linking the SANE library code into it.
27 
28    This exception does not, however, invalidate any other reasons why
29    the executable file might be covered by the GNU General Public
30    License.
31 
32    If you submit changes to SANE to the maintainers to be included in
33    a subsequent release, you agree by submitting the changes that
34    those changes may be distributed with this exception intact.
35 
36    If you write modifications of your own for SANE, it is your choice
37    whether to permit this exception to apply to your modifications.
38    If you do not wish that, delete this exception notice.
39 
40    This file is part of a SANE backend for HP Scanners supporting
41    HP Scanner Control Language (SCL).
42 */
43 
44 static char *hp_backend_version = "1.06";
45 /* Changes:
46 
47    V 1.06:
48    Revision 1.22  2008/11/26 21:21:25  kitno-guest
49    * backend/ *.[ch]: nearly every backend used V_MAJOR
50    instead of SANE_CURRENT_MAJOR in sane_init()
51    * backend/snapscan.c: remove EXPECTED_VERSION check
52    since new SANE standard is forward compatible
53 
54    Revision 1.21  2004-10-04 18:09:05  kig-guest
55    Rename global function hp_init_openfd to sanei_hp_init_openfd
56 
57    Revision 1.20  2004/03/27 13:52:39  kig-guest
58    Keep USB-connection open (was problem with Linux 2.6.x)
59 
60 
61    V 1.05:
62    Revision 1.19  2003/10/24 17:26:07  kig-guest
63    Use new sanei-thread-interface
64 
65    Revision 1.18  2003/10/09 19:37:29  kig-guest
66    Redo when TEST UNIT READY failed
67    Redo when read returns with 0 bytes (non-SCSI only)
68    Bug #300241: fix inverse image on 3c/4c/6100C at 10 bit depth
69 
70    Revision 1.17  2003/10/06 19:54:07  kig-guest
71    Bug #300248: correct "Negatives" to "Negative" in option description
72 
73 
74    V 1.04, 24-Jul-2003, PK (peter@kirchgessner.net)
75       - Add internationalization
76 
77    V 1.03, 14-Apr-2003, PK (peter@kirchgessner.net)
78       - check valp in call of sane_control_option()
79 
80    V 1.02, 02-Feb-2003, PK (peter@kirchgessner.net)
81       - add OS/2-support by Franz Bakan
82 
83    V 1.01, 06-Dec-2002, PK (peter@kirchgessner.net)
84       - add option dumb-read to work around problems
85         with BusLogic SCSI driver (error during device I/O)
86 
87    V 1.00, 17-Nov-2002, PK (peter@kirchgessner.net)
88       - add libusb support
89 
90    V 0.96, 05-Aug-2002, PK (peter@kirchgessner.net)
91       - check USB device names
92 
93    V 0.95, 07-Jul-2001, PK (peter@kirchgessner.net)
94       - add support for active XPA
95       - check if paper in ADF for ADF scan
96       - add option lamp off
97       - remove some really unused parameters
98 
99    V 0.94, 31-Dec-2000, PK (peter@kirchgessner.net)
100       - always switch off lamp after scan
101 
102    V 0.93, 04-Dec-2000, PK (peter@kirchgessner.net)
103       - fix problem with ADF-support on ScanJet 6350 (and maybe others)
104 
105    V 0.92, 03-Oct-2000, Rupert W. Curwen (rcurwen@uk.research.att.com):
106       - try to not allocate accessors twice (only for accessors
107         that have fixed length)
108       - fix problem with leaving connection open for some error conditions
109 
110    V 0.91, 04-Sep-2000, David Paschal (paschal@rcsis.com):
111       - Added support for flatbed HP OfficeJets
112       - (PK) fix problem with cancel preview
113 
114    V 0.90, 02-Sep-2000, PK:
115       - fix timing problem between killing child and writing to pipe
116       - change fprintf(stderr,...) to DBG
117       - change include <sane..> to "sane.." in hp.h
118       - change handling of options that have global effects.
119         i.e. if option scanmode is received (has global effect),
120         all options that "may change" are send to the scanner again.
121         This fixes a problem that --resolution specified infront of
122         --mode on command line of scanimage was ignored.
123         NOTE: This change does not allow to specify --depth 12 infront of
124         --mode color, because --depth is only enabled with --mode color.
125       - add depth greater 8 bits for mode grayscale
126       - add option for 8 bit output but 10/12 bit scanning
127    V 0.88, 25-Jul-2000, PK:
128       - remove inlines
129    V 0.88, 20-Jul-2000, PK:
130       - Use sanei_config_read()
131       - don't write chars < 32 to DBG
132    V 0.88, 09-Jul-2000, PK:
133       - Add front button support by Chris S. Cowles, Houston, Texas,
134         c_cowles@ieee.org
135    V 0.87, 28-Jun-2000, PK:
136       - ADF-support for ScanJet IIp
137       - Return error SANE_STATUS_NO_DOCS if no paper in ADF
138    V 0.86, 12-Feb-2000, PK:
139       - fix gcc warnings
140       - fix problems with bitdepths > 8
141       - allow hp_data_resize to be called with newsize==bufsiz
142         (Jens Heise, <heisbeee@calvados.zrz.TU-Berlin.DE>)
143       - add option enable-image-buffering
144    V 0.85, 30-Jan-2000, PK:
145       - correct and enhance data widths > 8 (Ewald de Wit  <ewald@pobox.com>)
146       - enable data width for all scanners
147       - PhotoSmart: exposure "Off" changed to "Default"
148       - PhotoSmart: even if max. datawidth 24 is reported, allow 30 bits.
149       - change keyword -data-width to -depth and use value for bits per sample
150       - change keyword -halftone-type to -halftone-pattern
151       - change keyword -scantype to -source
152       - fix problem with multiple definition of sanei_debug_hp
153    V 0.83, 04-Jul-99, PK:
154       - reset scanner before downloading parameters (fixes problem
155         with sleep mode of scanners)
156       - fix problem with coredump if non-scanner HP SCSI devices
157         are connected (CDR)
158       - option scan-from-adf replaced by scantype normal/adf/xpa
159       - change value "Film strip" to "Film-strip" for option
160         --media-type
161       - PhotoScanner: allow only scanning at multiple of 300 dpi
162         for scanning slides/film strips. This also fixes a problem with the
163         preview which uses arbitrary resolutions.
164       - Marian Szebenyi: close pipe (endless loop on Digital UNIX)
165 
166    V 0.82, 28-Feb-99, Ewald de Wit <ewald@pobox.com>:
167       - add options 'exposure time' and 'data width'
168 
169    V 0.81, 11-Jan-99, PK:
170       - occasionally 'scan from ADF' was active for Photoscanner
171 
172    V 0.80, 10-Jan-99, PK:
173       - fix problem with scan size for ADF-scan
174         (thanks to Christop Biardzki <cbi@allgaeu.org> for tests)
175       - add option "unload after scan" for HP PhotoScanner
176       - no blanks in command line options
177       - fix problem with segmentation fault for scanimage -d hp:/dev/sga
178         with /dev/sga not included in hp.conf
179 
180    V 0.72, 25-Dec-98, PK:
181       - add patches from mike@easysw.com to fix problems:
182         - core dumps by memory alignment
183         - config file to accept matching devices (scsi HP)
184       - add simulation for brightness/contrast/custom gamma table
185         if not supported by scanner
186       - add configuration options for connect-...
187 
188    V 0.72c, 04-Dec-98, PK:
189       - use sanei_pio
190       - try ADF support
191 
192    V 0.72b, 29-Nov-98 James Carter <james@cs.york.ac.uk>, PK:
193       - try to add parallel scanner support
194 
195    V 0.71, 14-Nov-98 PK:
196       - add HP 6200 C
197       - cleanup hp_scsi_s structure
198       - show calibrate button on photoscanner only for print media
199       - suppress halftone mode on photoscanner
200       - add media selection for photoscanner
201 
202    V 0.70, 26-Jul-98 PK:
203       - Rename global symbols to sanei_...
204         Change filenames to hp-...
205         Use backend name hp
206 
207    V 0.65, 18-Jul-98 PK:
208       - Dont use pwd.h for VACPP-Compiler to get home-directory,
209         check $SANE_HOME_XHP instead
210 
211    V 0.64, 12-Jul-98 PK:
212       - only download calibration file for media = 1 (prints)
213       - Changes for VACPP-Compiler (check macros __IBMC__, __IBMCPP__)
214 
215    V 0.63, 07-Jun-98 PK:
216       - fix problem with custom gamma table
217       - Add unload button
218 
219    V 0.62, 25-May-98 PK:
220       - make it compilable under sane V 0.73
221 
222    V 0.61, 28-Mar-98, Peter Kirchgessner <pkirchg@aol.com>:
223       - Add support for HP PhotoSmart Photoscanner
224       - Use more inquiries to see what the scanner supports
225       - Add options: calibrate/Mirror horizontal+vertical
226       - Upload/download calibration data
227 */
228 
229 #define VERSIO                                8
230 
231 #include "../include/sane/config.h"
232 #include "hp.h"
233 
234 #include <string.h>
235 /* #include <sys/types.h> */
236 /* #include "../include/sane/sane.h" */
237 #include "../include/sane/sanei_config.h"
238 #include "../include/sane/sanei_backend.h"
239 #include "../include/sane/sanei_usb.h"
240 #include "../include/sane/sanei_thread.h"
241 /* #include "../include/sane/sanei_debug.h" */
242 #include "hp-device.h"
243 #include "hp-handle.h"
244 
245 #ifndef PATH_MAX
246 # define PATH_MAX	1024
247 #endif
248 
249 #ifndef NDEBUG
250 #include <ctype.h>
251 void
sanei_hp_dbgdump(const void * bufp,size_t len)252 sanei_hp_dbgdump (const void * bufp, size_t len)
253 {
254   const hp_byte_t *buf	= bufp;
255   int		offset	= 0;
256   int		i;
257   char line[128], pt[32];
258 
259   for (offset = 0; offset < (int)len; offset += 16)
260     {
261       sprintf (line," 0x%04X ", offset);
262       for (i = offset; i < offset + 16 && i < (int)len; i++)
263       {
264 	  sprintf (pt," %02X", buf[i]);
265           strcat (line, pt);
266       }
267       while (i++ < offset + 16)
268 	  strcat (line, "   ");
269       strcat (line, "  ");
270       for (i = offset; i < offset + 16 && i < (int)len; i++)
271       {
272 	  sprintf (pt, "%c", isprint(buf[i]) ? buf[i] : '.');
273           strcat (line, pt);
274       }
275       DBG(16,"%s\n",line);
276     }
277 }
278 
279 #endif
280 
281 typedef struct info_list_el_s * HpDeviceInfoList;
282 struct info_list_el_s
283 {
284     HpDeviceInfoList    next;
285     HpDeviceInfo        info;
286 };
287 
288 typedef struct device_list_el_s * HpDeviceList;
289 struct device_list_el_s
290 {
291     HpDeviceList	next;
292     HpDevice	 	dev;
293 };
294 
295 /* Global state */
296 static struct hp_global_s {
297     hp_bool_t	is_up;
298     hp_bool_t	config_read;
299 
300     const SANE_Device ** devlist;
301 
302     HpDeviceList	device_list;
303     HpDeviceList	handle_list;
304     HpDeviceInfoList    infolist;
305 
306     HpDeviceConfig      config;
307 } global;
308 
309 
310 /* Get the info structure for a device. If not available in global list */
311 /* add new entry and return it */
312 static HpDeviceInfo *
hp_device_info_create(const char * devname)313 hp_device_info_create (const char *devname)
314 
315 {
316  HpDeviceInfoList  *infolist = &(global.infolist);
317  HpDeviceInfoList  infolistelement;
318  HpDeviceInfo *info;
319  int k, found;
320 
321  if (!global.is_up) return 0;
322 
323  found = 0;
324  infolistelement = 0;
325  info = 0;
326  while (*infolist)
327  {
328    infolistelement = *infolist;
329    info = &(infolistelement->info);
330    if (strcmp (info->devname, devname) == 0)  /* Already in list ? */
331    {
332      found = 1;
333      break;
334    }
335    infolist = &(infolistelement->next);
336  }
337 
338  if (found)  /* Clear old entry */
339  {
340    memset (infolistelement, 0, sizeof (*infolistelement));
341  }
342  else   /* New element */
343  {
344    infolistelement = (HpDeviceInfoList)
345                         sanei_hp_allocz (sizeof (*infolistelement));
346    if (!infolistelement) return 0;
347    info = &(infolistelement->info);
348    *infolist = infolistelement;
349  }
350 
351  k = sizeof (info->devname);
352  strncpy (info->devname, devname, k);
353  info->devname[k-1] = '\0';
354  info->max_model = -1;
355  info->active_xpa = -1;
356 
357  return info;
358 }
359 
360 static void
hp_init_config(HpDeviceConfig * config)361 hp_init_config (HpDeviceConfig *config)
362 
363 {
364   if (config)
365   {
366     config->connect = HP_CONNECT_SCSI;
367     config->use_scsi_request = 1;
368     config->use_image_buffering = 0;
369     config->got_connect_type = 0;
370     config->dumb_read = 0;
371   }
372 }
373 
374 static HpDeviceConfig *
hp_global_config_get(void)375 hp_global_config_get (void)
376 
377 {
378  if (!global.is_up) return 0;
379  return &(global.config);
380 }
381 
382 static SANE_Status
hp_device_config_add(const char * devname)383 hp_device_config_add (const char *devname)
384 
385 {
386  HpDeviceInfo *info;
387  HpDeviceConfig *config;
388 
389  info = hp_device_info_create (devname);
390  if (!info) return SANE_STATUS_INVAL;
391 
392  config = hp_global_config_get ();
393 
394  if (config)
395  {
396    memcpy (&(info->config), config, sizeof (info->config));
397    info->config_is_up = 1;
398  }
399  else     /* Initialize with default configuration */
400  {
401    DBG(3, "hp_device_config_add: No configuration found for device %s.\n\tUseing default\n",
402        devname);
403    hp_init_config (&(info->config));
404    info->config_is_up = 1;
405  }
406  return SANE_STATUS_GOOD;
407 }
408 
409 HpDeviceInfo *
sanei_hp_device_info_get(const char * devname)410 sanei_hp_device_info_get (const char *devname)
411 
412 {
413  HpDeviceInfoList  *infolist;
414  HpDeviceInfoList  infolistelement;
415  HpDeviceInfo *info;
416  int retries = 1;
417 
418  if (!global.is_up)
419  {
420    DBG(17, "sanei_hp_device_info_get: global.is_up = %d\n", (int)global.is_up);
421    return 0;
422  }
423 
424  DBG(250, "sanei_hp_device_info_get: searching %s\n", devname);
425  do
426  {
427  infolist = &(global.infolist);
428  while (*infolist)
429  {
430    infolistelement = *infolist;
431    info = &(infolistelement->info);
432    DBG(250, "sanei_hp_device_info_get: check %s\n", info->devname);
433    if (strcmp (info->devname, devname) == 0)  /* Found ? */
434    {
435      return info;
436    }
437    infolist = &(infolistelement->next);
438  }
439 
440  /* No configuration found. Assume default */
441  DBG(1, "hp_device_info_get: device %s not configured. Using default\n",
442      devname);
443  if (hp_device_config_add (devname) != SANE_STATUS_GOOD)
444    return 0;
445  }
446  while (retries-- > 0);
447 
448  return 0;
449 }
450 
451 HpDevice
sanei_hp_device_get(const char * devname)452 sanei_hp_device_get (const char *devname)
453 {
454   HpDeviceList  ptr;
455 
456   for (ptr = global.device_list; ptr; ptr = ptr->next)
457       if (strcmp(sanei_hp_device_sanedevice(ptr->dev)->name, devname) == 0)
458 	  return ptr->dev;
459 
460   return 0;
461 }
462 
463 static void
hp_device_info_remove(void)464 hp_device_info_remove (void)
465 {
466  HpDeviceInfoList  next, infolistelement = global.infolist;
467 
468  if (!global.is_up) return;
469 
470  while (infolistelement)
471  {
472    next = infolistelement->next;
473    sanei_hp_free (infolistelement);
474    infolistelement = next;
475  }
476 }
477 
478 static SANE_Status
hp_device_list_add(HpDeviceList * list,HpDevice dev)479 hp_device_list_add (HpDeviceList * list, HpDevice dev)
480 {
481   HpDeviceList new = sanei_hp_alloc(sizeof(*new));
482 
483   if (!new)
484       return SANE_STATUS_NO_MEM;
485   while (*list)
486       list = &(*list)->next;
487 
488   *list = new;
489   new->next = 0;
490   new->dev = dev;
491   return SANE_STATUS_GOOD;
492 }
493 
494 static SANE_Status
hp_device_list_remove(HpDeviceList * list,HpDevice dev)495 hp_device_list_remove (HpDeviceList * list, HpDevice dev)
496 {
497   HpDeviceList old;
498 
499   while (*list && (*list)->dev != dev)
500       list = &(*list)->next;
501 
502   if (!*list)
503       return SANE_STATUS_INVAL;
504 
505   old = *list;
506   *list = (*list)->next;
507   sanei_hp_free(old);
508   return SANE_STATUS_GOOD;
509 }
510 
511 static SANE_Status
hp_handle_list_add(HpDeviceList * list,HpHandle h)512 hp_handle_list_add (HpDeviceList * list, HpHandle h)
513 {
514   return hp_device_list_add(list, (HpDevice)h);
515 }
516 
517 static SANE_Status
hp_handle_list_remove(HpDeviceList * list,HpHandle h)518 hp_handle_list_remove (HpDeviceList * list, HpHandle h)
519 {
520   return hp_device_list_remove(list, (HpDevice)h);
521 }
522 
523 
524 
525 
526 static SANE_Status
hp_init(void)527 hp_init (void)
528 {
529   memset(&global, 0, sizeof(global));
530   global.is_up++;
531   DBG(3, "hp_init: global.is_up = %d\n", (int)global.is_up);
532   return SANE_STATUS_GOOD;
533 }
534 
535 static void
hp_destroy(void)536 hp_destroy (void)
537 {
538   if (global.is_up)
539     {
540       /* Close open handles */
541       while (global.handle_list)
542 	  sane_close(global.handle_list->dev);
543 
544       /* Remove device infos */
545       hp_device_info_remove ();
546 
547       sanei_hp_free_all();
548       global.is_up = 0;
549       DBG(3, "hp_destroy: global.is_up = %d\n", (int)global.is_up);
550     }
551 }
552 
553 static SANE_Status
hp_get_dev(const char * devname,HpDevice * devp)554 hp_get_dev (const char *devname, HpDevice* devp)
555 {
556   HpDeviceList  ptr;
557   HpDevice	new;
558   const HpDeviceInfo *info;
559   char         *connect;
560   HpConnect     hp_connect;
561   SANE_Status   status;
562 
563   for (ptr = global.device_list; ptr; ptr = ptr->next)
564       if (strcmp(sanei_hp_device_sanedevice(ptr->dev)->name, devname) == 0)
565 	{
566 	  if (devp)
567 	      *devp = ptr->dev;
568 	  return SANE_STATUS_GOOD;
569 	}
570 
571   info = sanei_hp_device_info_get (devname);
572   hp_connect = info->config.connect;
573 
574   if (hp_connect == HP_CONNECT_SCSI) connect = "scsi";
575   else if (hp_connect == HP_CONNECT_DEVICE) connect = "device";
576   else if (hp_connect == HP_CONNECT_PIO) connect = "pio";
577   else if (hp_connect == HP_CONNECT_USB) connect = "usb";
578   else if (hp_connect == HP_CONNECT_RESERVE) connect = "reserve";
579   else connect = "unknown";
580 
581   DBG(3, "hp_get_dev: New device %s, connect-%s, scsi-request=%lu\n",
582       devname, connect, (unsigned long)info->config.use_scsi_request);
583 
584   status = sanei_hp_device_new (&new, devname);
585   if (status != SANE_STATUS_GOOD)
586       return status;
587 
588   if (devp)
589       *devp = new;
590 
591   RETURN_IF_FAIL( hp_device_list_add(&global.device_list, new) );
592 
593   return SANE_STATUS_GOOD;
594 }
595 
596 static SANE_Status
hp_attach(const char * devname)597 hp_attach (const char *devname)
598 {
599   DBG(7,"hp_attach: \"%s\"\n", devname);
600   hp_device_config_add (devname);
601   return hp_get_dev (devname, 0);
602 }
603 
604 static void
hp_attach_matching_devices(HpDeviceConfig * config,const char * devname)605 hp_attach_matching_devices (HpDeviceConfig *config, const char *devname)
606 {
607  static int usb_initialized = 0;
608 
609  if (strncmp (devname, "usb", 3) == 0)
610  {
611    config->connect = HP_CONNECT_USB;
612    config->use_scsi_request = 0;
613    DBG(1,"hp_attach_matching_devices: usb attach matching \"%s\"\n",devname);
614    if (!usb_initialized)
615    {
616       sanei_usb_init ();
617       usb_initialized = 1;
618    }
619    sanei_usb_attach_matching_devices (devname, hp_attach);
620  }
621  else
622  {
623    DBG(1, "hp_attach_matching_devices: attach matching %s\n", devname);
624    sanei_config_attach_matching_devices (devname, hp_attach);
625  }
626 }
627 
628 static SANE_Status
hp_read_config(void)629 hp_read_config (void)
630 {
631   FILE *	fp;
632   char		 buf[PATH_MAX], arg1[PATH_MAX], arg2[PATH_MAX], arg3[PATH_MAX];
633   int           nl, nargs;
634   HpDeviceConfig *config, df_config, dev_config;
635   hp_bool_t     is_df_config;
636   char          cu_device[PATH_MAX];
637 
638   if (!global.is_up)
639       return SANE_STATUS_INVAL;
640   if (global.config_read)
641       return SANE_STATUS_GOOD;
642 
643   /* The default config will keep options set up until the first device is specified */
644   hp_init_config (&df_config);
645   config = &df_config;
646   is_df_config = 1;
647   cu_device[0] = '\0';
648 
649   DBG(1, "hp_read_config: hp backend v%s starts reading config file\n",
650       hp_backend_version);
651 
652   if ((fp = sanei_config_open(HP_CONFIG_FILE)) != 0)
653     {
654       while (sanei_config_read(buf, sizeof(buf), fp))
655 	{
656 	  char *dev_name;
657 
658           nl = strlen (buf);
659           while (nl > 0)
660           {
661             nl--;
662             if (   (buf[nl] == ' ') || (buf[nl] == '\t')
663                 || (buf[nl] == '\r') || (buf[nl] == '\n'))
664               buf[nl] = '\0';
665             else
666               break;
667           }
668 
669           DBG(1, "hp_read_config: processing line <%s>\n", buf);
670 
671           nargs = sscanf (buf, "%s%s%s", arg1, arg2, arg3);
672           if ((nargs <= 0) || (arg1[0] == '#')) continue;
673 
674           /* Option to process ? */
675           if ((strcmp (arg1, "option") == 0) && (nargs >= 2))
676           {
677             if (strcmp (arg2, "connect-scsi") == 0)
678             {
679               config->connect = HP_CONNECT_SCSI;
680               config->got_connect_type = 1;
681             }
682             else if (strcmp (arg2, "connect-device") == 0)
683             {
684               config->connect = HP_CONNECT_DEVICE;
685               config->got_connect_type = 1;
686               config->use_scsi_request = 0;
687             }
688             else if (strcmp (arg2, "connect-pio") == 0)
689             {
690               config->connect = HP_CONNECT_PIO;
691               config->got_connect_type = 1;
692               config->use_scsi_request = 0;
693             }
694             else if (strcmp (arg2, "connect-usb") == 0)
695             {
696               config->connect = HP_CONNECT_USB;
697               config->got_connect_type = 1;
698               config->use_scsi_request = 0;
699             }
700             else if (strcmp (arg2, "connect-reserve") == 0)
701             {
702               config->connect = HP_CONNECT_RESERVE;
703               config->got_connect_type = 1;
704               config->use_scsi_request = 0;
705             }
706             else if (strcmp (arg2, "disable-scsi-request") == 0)
707             {
708               config->use_scsi_request = 0;
709             }
710             else if (strcmp (arg2, "enable-image-buffering") == 0)
711             {
712               config->use_image_buffering = 1;
713             }
714             else if (strcmp (arg2, "dumb-read") == 0)
715             {
716               config->dumb_read = 1;
717             }
718             else
719             {
720               DBG(1,"hp_read_config: Invalid option %s\n", arg2);
721             }
722           }
723           else   /* No option. This is the start of a new device */
724           {
725             if (is_df_config) /* Did we only read default configurations ? */
726             {
727               is_df_config = 0;  /* Stop reading default config */
728                           /* Initialize device config with default-config */
729               memcpy (&dev_config, &df_config, sizeof (dev_config));
730               config = &dev_config;   /* Start reading a device config */
731             }
732             if (cu_device[0] != '\0')  /* Did we work on a device ? */
733             {
734               memcpy (hp_global_config_get(), &dev_config,sizeof (dev_config));
735               hp_attach_matching_devices (hp_global_config_get(), cu_device);
736               cu_device[0] = '\0';
737             }
738 
739             /* Initialize new device with default config */
740             memcpy (&dev_config, &df_config, sizeof (dev_config));
741 
742             /* Cut off leading blanks of device name */
743             dev_name = buf+strspn (buf, " \t\n\r");
744             strcpy (cu_device, dev_name);    /* Save the device name */
745           }
746         }
747         if (cu_device[0] != '\0')  /* Did we work on a device ? */
748         {
749           memcpy (hp_global_config_get (), &dev_config, sizeof (dev_config));
750           DBG(1, "hp_read_config: attach %s\n", cu_device);
751           hp_attach_matching_devices (hp_global_config_get (), cu_device);
752           cu_device[0] = '\0';
753         }
754       fclose (fp);
755       DBG(1, "hp_read_config: reset to default config\n");
756       memcpy (hp_global_config_get (), &df_config, sizeof (df_config));
757     }
758   else
759     {
760       /* default to /dev/scanner instead of insisting on config file */
761       char *dev_name = "/dev/scanner";
762 
763       memcpy (hp_global_config_get (), &df_config, sizeof (df_config));
764       hp_attach_matching_devices (hp_global_config_get (), dev_name);
765     }
766 
767   global.config_read++;
768   return SANE_STATUS_GOOD;
769 }
770 
771 static SANE_Status
hp_update_devlist(void)772 hp_update_devlist (void)
773 {
774   HpDeviceList	devp;
775   const SANE_Device **devlist;
776   int		count	= 0;
777 
778   RETURN_IF_FAIL( hp_read_config() );
779 
780   if (global.devlist)
781       sanei_hp_free(global.devlist);
782 
783   for (devp = global.device_list; devp; devp = devp->next)
784       count++;
785 
786   if (!(devlist = sanei_hp_alloc((count + 1) * sizeof(*devlist))))
787       return SANE_STATUS_NO_MEM;
788 
789   global.devlist = devlist;
790 
791   for (devp = global.device_list; devp; devp = devp->next)
792       *devlist++ = sanei_hp_device_sanedevice(devp->dev);
793   *devlist = 0;
794 
795   return SANE_STATUS_GOOD;
796 }
797 
798 
799 /*
800  *
801  */
802 
803 SANE_Status
sane_init(SANE_Int * version_code,SANE_Auth_Callback __sane_unused__ authorize)804 sane_init (SANE_Int *version_code, SANE_Auth_Callback __sane_unused__ authorize)
805 {SANE_Status status;
806 
807   DBG_INIT();
808   DBG(3, "sane_init called\n");
809   sanei_thread_init ();
810 
811   sanei_hp_init_openfd ();
812   hp_destroy();
813 
814   if (version_code)
815     *version_code = SANE_VERSION_CODE (SANE_CURRENT_MAJOR, SANE_CURRENT_MINOR, VERSIO);
816 
817   status = hp_init();
818   DBG(3, "sane_init will finish with %s\n", sane_strstatus (status));
819   return status;
820 }
821 
822 void
sane_exit(void)823 sane_exit (void)
824 {
825   DBG(3, "sane_exit called\n");
826   hp_destroy();
827   DBG(3, "sane_exit will finish\n");
828 }
829 
830 SANE_Status
sane_get_devices(const SANE_Device *** device_list,SANE_Bool __sane_unused__ local_only)831 sane_get_devices (const SANE_Device ***device_list,
832                   SANE_Bool __sane_unused__ local_only)
833 {
834   DBG(3, "sane_get_devices called\n");
835 
836   RETURN_IF_FAIL( hp_update_devlist() );
837   *device_list = global.devlist;
838   DBG(3, "sane_get_devices will finish with %s\n",
839       sane_strstatus (SANE_STATUS_GOOD));
840   return SANE_STATUS_GOOD;
841 }
842 
843 SANE_Status
sane_open(SANE_String_Const devicename,SANE_Handle * handle)844 sane_open (SANE_String_Const devicename, SANE_Handle *handle)
845 {
846   HpDevice	dev	= 0;
847   HpHandle	h;
848 
849   DBG(3, "sane_open called\n");
850 
851   RETURN_IF_FAIL( hp_read_config() );
852 
853   if (devicename[0])
854       RETURN_IF_FAIL( hp_get_dev(devicename, &dev) );
855   else
856     {
857       /* empty devicname -> use first device */
858       if (global.device_list)
859 	  dev = global.device_list->dev;
860     }
861   if (!dev)
862       return SANE_STATUS_INVAL;
863 
864   if (!(h = sanei_hp_handle_new(dev)))
865       return SANE_STATUS_NO_MEM;
866 
867   RETURN_IF_FAIL( hp_handle_list_add(&global.handle_list, h) );
868 
869   *handle = h;
870   DBG(3, "sane_open will finish with %s\n", sane_strstatus (SANE_STATUS_GOOD));
871   return SANE_STATUS_GOOD;
872 }
873 
874 void
sane_close(SANE_Handle handle)875 sane_close (SANE_Handle handle)
876 {
877   HpHandle	h  = handle;
878 
879   DBG(3, "sane_close called\n");
880 
881   if (!FAILED( hp_handle_list_remove(&global.handle_list, h) ))
882       sanei_hp_handle_destroy(h);
883 
884   DBG(3, "sane_close will finish\n");
885 }
886 
887 const SANE_Option_Descriptor *
sane_get_option_descriptor(SANE_Handle handle,SANE_Int optnum)888 sane_get_option_descriptor (SANE_Handle handle, SANE_Int optnum)
889 {
890   HpHandle 	h = handle;
891   const SANE_Option_Descriptor *optd;
892 
893   DBG(10, "sane_get_option_descriptor called\n");
894 
895   optd = sanei_hp_handle_saneoption(h, optnum);
896 
897   DBG(10, "sane_get_option_descriptor will finish\n");
898 
899   return optd;
900 }
901 
902 SANE_Status
sane_control_option(SANE_Handle handle,SANE_Int optnum,SANE_Action action,void * valp,SANE_Int * info)903 sane_control_option (SANE_Handle handle, SANE_Int optnum,
904 		     SANE_Action action, void *valp, SANE_Int *info)
905 {
906   HpHandle h = handle;
907   SANE_Status status;
908 
909   DBG(10, "sane_control_option called\n");
910 
911   status = sanei_hp_handle_control(h, optnum, action, valp, info);
912 
913   DBG(10, "sane_control_option will finish with %s\n",
914       sane_strstatus (status));
915   return status;
916 }
917 
918 SANE_Status
sane_get_parameters(SANE_Handle handle,SANE_Parameters * params)919 sane_get_parameters (SANE_Handle handle, SANE_Parameters *params)
920 {
921   HpHandle h = handle;
922   SANE_Status status;
923 
924   DBG(10, "sane_get_parameters called\n");
925 
926   status = sanei_hp_handle_getParameters(h, params);
927 
928   DBG(10, "sane_get_parameters will finish with %s\n",
929       sane_strstatus (status));
930   return status;
931 }
932 
933 SANE_Status
sane_start(SANE_Handle handle)934 sane_start (SANE_Handle handle)
935 {
936   HpHandle h = handle;
937   SANE_Status status;
938 
939   DBG(3, "sane_start called\n");
940 
941   status = sanei_hp_handle_startScan(h);
942 
943   DBG(3, "sane_start will finish with %s\n", sane_strstatus (status));
944   return status;
945 }
946 
947 SANE_Status
sane_read(SANE_Handle handle,SANE_Byte * buf,SANE_Int max_len,SANE_Int * len)948 sane_read (SANE_Handle handle, SANE_Byte *buf, SANE_Int max_len, SANE_Int *len)
949 {
950   HpHandle	h 	= handle;
951   size_t	length	= max_len;
952   SANE_Status	status;
953 
954   DBG(16, "sane_read called\n");
955 
956   status =  sanei_hp_handle_read(h, buf, &length);
957   *len = length;
958 
959   DBG(16, "sane_read will finish with %s\n", sane_strstatus (status));
960   return status;
961 }
962 
963 void
sane_cancel(SANE_Handle handle)964 sane_cancel (SANE_Handle handle)
965 {
966   HpHandle h = handle;
967 
968   DBG(3, "sane_cancel called\n");
969 
970   sanei_hp_handle_cancel(h);
971 
972   DBG(3, "sane_cancel will finish\n");
973 }
974 
975 SANE_Status
sane_set_io_mode(SANE_Handle handle,SANE_Bool non_blocking)976 sane_set_io_mode (SANE_Handle handle, SANE_Bool non_blocking)
977 {
978   HpHandle h = handle;
979   SANE_Status status;
980 
981   DBG(3, "sane_set_io_mode called\n");
982 
983   status = sanei_hp_handle_setNonblocking(h, non_blocking);
984 
985   DBG(3, "sane_set_io_mode will finish with %s\n",
986       sane_strstatus (status));
987   return status;
988 }
989 
990 SANE_Status
sane_get_select_fd(SANE_Handle handle,SANE_Int * fd)991 sane_get_select_fd (SANE_Handle handle, SANE_Int *fd)
992 {
993   HpHandle h = handle;
994   SANE_Status status;
995 
996   DBG(10, "sane_get_select_fd called\n");
997 
998   status = sanei_hp_handle_getPipefd(h, fd);
999 
1000   DBG(10, "sane_get_select_fd will finish with %s\n",
1001       sane_strstatus (status));
1002   return status;
1003 }
1004