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