1 /* sane - Scanner Access Now Easy.
2    Copyright (C) 1999,2000 Tom Martone
3    This file is part of a SANE backend for Bell and Howell Copiscan II
4    Scanners using the Remote SCSI Controller(RSC).
5 
6    This file is part of the SANE package.
7 
8    This program is free software; you can redistribute it and/or
9    modify it under the terms of the GNU General Public License as
10    published by the Free Software Foundation; either version 2 of the
11    License, or (at your option) any later version.
12 
13    This program is distributed in the hope that it will be useful, but
14    WITHOUT ANY WARRANTY; without even the implied warranty of
15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16    General Public License for more details.
17 
18    You should have received a copy of the GNU General Public License
19    along with this program.  If not, see <https://www.gnu.org/licenses/>.
20 
21    As a special exception, the authors of SANE give permission for
22    additional uses of the libraries contained in this release of SANE.
23 
24    The exception is that, if you link a SANE library with other files
25    to produce an executable, this does not by itself cause the
26    resulting executable to be covered by the GNU General Public
27    License.  Your use of that executable is in no way restricted on
28    account of linking the SANE library code into it.
29 
30    This exception does not, however, invalidate any other reasons why
31    the executable file might be covered by the GNU General Public
32    License.
33 
34    If you submit changes to SANE to the maintainers to be included in
35    a subsequent release, you agree by submitting the changes that
36    those changes may be distributed with this exception intact.
37 
38    If you write modifications of your own for SANE, it is your choice
39    whether to permit this exception to apply to your modifications.
40    If you do not wish that, delete this exception notice.
41 
42 */
43 #include "../include/sane/config.h"
44 #include <limits.h>
45 #include <errno.h>
46 #include <fcntl.h>
47 #include <ctype.h>
48 #include <stdlib.h>
49 #include <string.h>
50 #include <stdio.h>
51 #include <unistd.h>
52 #include <sys/types.h>
53 #include "../include/sane/sane.h"
54 #include "../include/sane/saneopts.h"
55 #include "../include/sane/sanei_scsi.h"
56 #include "../include/sane/sanei_config.h"
57 
58 #define BACKEND_NAME bh
59 #include "../include/sane/sanei_backend.h"
60 #define BUILD 4
61 
62 #include "bh.h"
63 
64 #define MIN(x,y) ((x)<(y) ? (x) : (y))
65 #define MAX(x,y) ((x)>(y) ? (x) : (y))
66 
67 static const SANE_Device **devlist = 0;
68 static int num_devices = 0;
69 static BH_Device *first_dev = NULL;
70 static BH_Scanner *first_handle = NULL;
71 static SANE_Char inquiry_data[255] = "Bell+Howell scanner";
72 static SANE_Int disable_optional_frames = 0;
73 static SANE_Int fake_inquiry = 0;
74 
allblank(const char *s)75 static int allblank(const char *s)
76 {
77   while (s && *s)
78     if (!isspace(*s++))
79       return 0;
80 
81   return 1;
82 }
83 
84 static size_t
max_string_size(const SANE_String_Const strings[])85 max_string_size (const SANE_String_Const strings[])
86 {
87   size_t size, max_size = 0;
88   int i;
89 
90   for (i = 0; strings[i]; ++i)
91     {
92       size = strlen (strings[i]) + 1;
93       if (size > max_size)
94         max_size = size;
95     }
96 
97   return max_size;
98 }
99 
100 static void
trim_spaces(char *s, size_t n)101 trim_spaces(char *s, size_t n)
102 {
103   for (s += (n-1); n > 0; n--, s--)
104     {
105       if (*s && !isspace(*s))
106 	break;
107       *s = '\0';
108     }
109 }
110 
111 static SANE_String_Const
print_devtype(SANE_Byte devtype)112 print_devtype (SANE_Byte devtype)
113 {
114   static SANE_String devtypes[] =
115   {
116     "disk",
117     "tape",
118     "printer",
119     "processor",
120     "CD-writer",
121     "CD-drive",
122     "scanner",
123     "optical-drive",
124     "jukebox",
125     "communicator"
126   };
127 
128   return (devtype > 0 && devtype < NELEMS(devtypes)) ?
129     devtypes[devtype] :
130     "unknown-device";
131 }
132 
133 static SANE_String_Const
print_barcodetype(SANE_Int i)134 print_barcodetype (SANE_Int i)
135 {
136   return (i > 0 && i < NELEMS(barcode_search_bar_list)) ?
137     barcode_search_bar_list[i] :
138     (SANE_String_Const) "unknown";
139 }
140 
141 static SANE_String_Const
print_orientation(SANE_Int i)142 print_orientation (SANE_Int i)
143 {
144   switch(i)
145     {
146     case 0:
147     case 7:
148       return "vertical upwards";
149     case 1:
150     case 2:
151       return "horizontal right";
152     case 3:
153     case 4:
154       return "vertical downwards";
155     case 5:
156     case 6:
157       return "horizontal left";
158     default:
159       return "unknown";
160     }
161 }
162 
163 static SANE_String_Const
print_read_type(SANE_Int i)164 print_read_type (SANE_Int i)
165 {
166   static char buf[32];
167   SANE_Int n;
168 
169   /* translate BH_SCSI_READ_TYPE_ codes to a human-readable string */
170   if (i == BH_SCSI_READ_TYPE_FRONT)
171     {
172       strcpy(buf, "front page");
173     }
174   else if (i == BH_SCSI_READ_TYPE_BACK)
175     {
176       strcpy(buf, "back page");
177     }
178   else if (i > BH_SCSI_READ_TYPE_FRONT &&
179 	   i <= BH_SCSI_READ_TYPE_FRONT + NUM_SECTIONS)
180     {
181       n = i - BH_SCSI_READ_TYPE_FRONT;
182       sprintf(buf, "front section %d", n);
183     }
184   else if (i > BH_SCSI_READ_TYPE_BACK &&
185 	   i <= BH_SCSI_READ_TYPE_BACK + NUM_SECTIONS)
186     {
187       n = i - BH_SCSI_READ_TYPE_BACK;
188       sprintf(buf, "back section %d", n);
189     }
190   else if (i == BH_SCSI_READ_TYPE_FRONT_BARCODE)
191     {
192       strcpy(buf, "front page barcode");
193     }
194   else if (i == BH_SCSI_READ_TYPE_BACK_BARCODE)
195     {
196       strcpy(buf, "back page barcode");
197     }
198   else if (i > BH_SCSI_READ_TYPE_FRONT_BARCODE &&
199 	   i <= BH_SCSI_READ_TYPE_FRONT_BARCODE + NUM_SECTIONS)
200     {
201       n = i - BH_SCSI_READ_TYPE_FRONT_BARCODE;
202       sprintf(buf, "front barcode section %d", n);
203     }
204   else if (i > BH_SCSI_READ_TYPE_BACK_BARCODE &&
205 	   i <= BH_SCSI_READ_TYPE_BACK_BARCODE + NUM_SECTIONS)
206     {
207       n = i - BH_SCSI_READ_TYPE_BACK_BARCODE;
208       sprintf(buf, "back barcode section %d", n);
209     }
210   else if (i == BH_SCSI_READ_TYPE_FRONT_PATCHCODE)
211     {
212       strcpy(buf, "front page patchcode");
213     }
214   else if (i == BH_SCSI_READ_TYPE_BACK_PATCHCODE)
215     {
216       strcpy(buf, "back page patchcode");
217     }
218   else if (i > BH_SCSI_READ_TYPE_FRONT_PATCHCODE &&
219 	   i <= BH_SCSI_READ_TYPE_FRONT_PATCHCODE + NUM_SECTIONS)
220     {
221       n = i - BH_SCSI_READ_TYPE_FRONT_PATCHCODE;
222       sprintf(buf, "front patchcode section %d", n);
223     }
224   else if (i > BH_SCSI_READ_TYPE_BACK_PATCHCODE &&
225 	   i <= BH_SCSI_READ_TYPE_BACK_PATCHCODE + NUM_SECTIONS)
226     {
227       n = i - BH_SCSI_READ_TYPE_BACK_PATCHCODE;
228       sprintf(buf, "back patchcode section %d", n);
229     }
230   else if (i == BH_SCSI_READ_TYPE_FRONT_ICON)
231     {
232       strcpy(buf, "front page icon");
233     }
234   else if (i == BH_SCSI_READ_TYPE_BACK_ICON)
235     {
236       strcpy(buf, "back page icon");
237     }
238   else if (i == BH_SCSI_READ_TYPE_SENDBARFILE)
239     {
240       strcpy(buf, "transmit bar/patch codes");
241     }
242   else
243     {
244       strcpy(buf, "unknown");
245     }
246 
247   return buf;
248 }
249 
250 static SANE_Int
get_rotation_id(char *s)251 get_rotation_id(char *s)
252 {
253   SANE_Int i;
254 
255   for (i = 0; rotation_list[i]; i++)
256     if (strcmp(s, rotation_list[i]) == 0)
257       break;
258 
259   /* unknown strings are treated as '0' */
260   return rotation_list[i] ? i : 0;
261 }
262 
263 static SANE_Int
get_compression_id(char *s)264 get_compression_id(char *s)
265 {
266   SANE_Int i;
267 
268   for (i = 0; compression_list[i]; i++)
269     if (strcmp(s, compression_list[i]) == 0)
270       break;
271 
272   /* unknown strings are treated as 'none' */
273   return compression_list[i] ?  i : 0;
274 }
275 
276 static SANE_Int
get_barcode_id(char *s)277 get_barcode_id(char *s)
278 {
279   SANE_Int i;
280 
281   for (i = 0; barcode_search_bar_list[i]; i++)
282     if (strcmp(s, barcode_search_bar_list[i]) == 0)
283       break;
284 
285   /* unknown strings are treated as 'none' */
286   return barcode_search_bar_list[i] ?  i : 0;
287 }
288 
289 static SANE_Int
get_scan_mode_id(char *s)290 get_scan_mode_id(char *s)
291 {
292   SANE_Int i;
293 
294   for (i = 0; scan_mode_list[i]; i++)
295     if (strcmp(s, scan_mode_list[i]) == 0)
296       break;
297 
298   /* unknown strings are treated as 'lineart' */
299   return scan_mode_list[i] ?  i : 0;
300 }
301 
302 static SANE_Int
get_paper_id(char *s)303 get_paper_id(char *s)
304 {
305   SANE_Int i;
306 
307   for (i = 0; paper_list[i]; i++)
308     if (strcmp(s, paper_list[i]) == 0)
309       break;
310 
311   /* unknown strings are treated as 'custom' */
312   return paper_list[i] ?  i : 0;
313 }
314 
315 static SANE_Int
get_barcode_search_mode(char *s)316 get_barcode_search_mode(char *s)
317 {
318   SANE_Int i;
319 
320   if (strcmp(s, "horizontal") == 0)
321     {
322       i = 1;
323     }
324   else if (strcmp(s, "vertical") == 0)
325     {
326       i = 2;
327     }
328   else if (strcmp(s, "vert-horiz") == 0)
329     {
330       i = 6;
331     }
332   else if (strcmp(s, "horiz-vert") == 0)
333     {
334       i = 9;
335     }
336   else
337     {
338       /* unknown strings are treated as 'horiz-vert' */
339       DBG(1, "get_barcode_search_mode: unrecognized string `%s'\n", s);
340       i = 9;
341     }
342 
343   return i;
344 }
345 
346 static void
appendStdList(BH_Info *sc, SANE_Int res)347 appendStdList(BH_Info *sc, SANE_Int res)
348 {
349   /*  append entry to resolution list - a SANE_WORD_LIST */
350   sc->resStdList[sc->resStdList[0]+1] = res;
351   sc->resStdList[0]++;
352 }
353 
354 static void
ScannerDump(BH_Scanner *s)355 ScannerDump(BH_Scanner *s)
356 {
357   int i;
358   BH_Info *info;
359   SANE_Device *sdev;
360 
361   info = &s->hw->info;
362   sdev = &s->hw->sane;
363 
364   DBG (1, "SANE Device: '%s' Vendor: '%s' Model: '%s' Type: '%s'\n",
365 	 sdev->name,
366 	 sdev->vendor,
367 	 sdev->model,
368 	 sdev->type);
369 
370   DBG (1, "Type: '%s' Vendor: '%s' Product: '%s' Revision: '%s'\n",
371 	 print_devtype(info->devtype),
372 	 info->vendor,
373 	 info->product,
374 	 info->revision);
375 
376   DBG (1, "Automatic Document Feeder:%s\n",
377 	 info->canADF ? " <Installed>" : " <Not Installed>");
378 
379   DBG (1, "Colors:%s%s\n", info->colorBandW ? " <Black and White>" : "",
380 	 info->colorHalftone ? " <Halftone>" : "");
381 
382   DBG (1, "Data processing:%s%s%s%s%s%s\n",
383 	 info->canWhiteFrame ? " <White Frame>" : "",
384 	 info->canBlackFrame ? " <Black Frame>" : "",
385 	 info->canEdgeExtract ? " <Edge Extraction>" : "",
386 	 info->canNoiseFilter ? " <Noise Filter>" : "",
387 	 info->canSmooth ? " <Smooth>" : "",
388 	 info->canLineBold ? " <Line Bolding>" : "");
389 
390   DBG (1, "Compression:%s%s%s\n",
391 	 info->comprG3_1D ? " <Group 3, 1D>" : "",
392 	 info->comprG3_2D ? " <Group 3, 2D>" : "",
393 	 info->comprG4 ? " <Group 4>" : "");
394 
395   DBG (1, "Optional Features:%s%s%s%s\n",
396 	 info->canBorderRecog ? " <Border Recognition>" : "",
397 	 info->canBarCode ? " <BarCode Decoding>" : "",
398 	 info->canIcon ? " <Icon Generation>" : "",
399 	 info->canSection ? " <Section Support>" : "");
400 
401   DBG (1, "Max bytes per scan-line: %d (%d pixels)\n",
402 	 info->lineMaxBytes,
403 	 info->lineMaxBytes * 8);
404 
405   DBG (1, "Basic resolution (X/Y): %d/%d\n",
406 	 info->resBasicX,
407 	 info->resBasicY);
408 
409   DBG (1, "Maximum resolution (X/Y): %d/%d\n",
410 	 info->resMaxX,
411 	 info->resMaxY);
412 
413   DBG (1, "Minimum resolution (X/Y): %d/%d\n",
414 	 info->resMinX,
415 	 info->resMinY);
416 
417   DBG (1, "Standard Resolutions:\n");
418   for (i = 0; i < info->resStdList[0]; i++)
419     DBG (1, " %d\n", info->resStdList[i+1]);
420 
421   DBG (1, "Window Width/Height (in basic res) %d/%d (%.2f/%.2f inches)\n",
422 	 info->winWidth,
423 	 info->winHeight,
424 	 (info->resBasicX != 0) ? ((float) info->winWidth) / info->resBasicX : 0.0,
425 	 (info->resBasicY) ? ((float) info->winHeight) / info->resBasicY : 0.0);
426 
427   DBG (1, "Summary:%s%s%s\n",
428 	 info->canDuplex ? "Duplex Scanner" : "Simplex Scanner",
429 	 info->canACE ? " (ACE capable)" : "",
430 	 info->canCheckADF ? " (ADF Paper Sensor capable)" : "");
431 
432   sprintf(inquiry_data, "Vendor: %s Product: %s Rev: %s %s%s%s\n",
433 	 info->vendor,
434 	 info->product,
435 	 info->revision,
436 	 info->canDuplex ? "Duplex Scanner" : "Simplex Scanner",
437 	 info->canACE ? " (ACE capable)" : "",
438 	 info->canCheckADF ? " (ADF Paper Sensor capable)" : "");
439 
440   DBG (5, "autoborder_default=%d\n", info->autoborder_default);
441   DBG (5, "batch_default=%d\n", info->batch_default);
442   DBG (5, "deskew_default=%d\n", info->deskew_default);
443   DBG (5, "check_adf_default=%d\n", info->check_adf_default);
444   DBG (5, "duplex_default=%d\n", info->duplex_default);
445   DBG (5, "timeout_adf_default=%d\n", info->timeout_adf_default);
446   DBG (5, "timeout_manual_default=%d\n", info->timeout_manual_default);
447   DBG (5, "control_panel_default=%d\n", info->control_panel_default);
448 
449 }
450 
451 static SANE_Status
test_unit_ready(int fd)452 test_unit_ready (int fd)
453 {
454   static SANE_Byte cmd[6];
455   SANE_Status status;
456   DBG (3, "test_unit_ready called\n");
457 
458   cmd[0] = BH_SCSI_TEST_UNIT_READY;
459   memset (cmd, 0, sizeof (cmd));
460   status = sanei_scsi_cmd (fd, cmd, sizeof (cmd), 0, 0);
461 
462   return status;
463 }
464 
465 static SANE_Status
object_position(BH_Scanner *s)466 object_position (BH_Scanner *s)
467 {
468   static SANE_Byte cmd[10];
469   SANE_Status status;
470   DBG (3, "object_position called\n");
471 
472   memset (cmd, 0, sizeof (cmd));
473   cmd[0] = BH_SCSI_OBJECT_POSITION;
474   cmd[1] = 0x01;
475   status = sanei_scsi_cmd (s->fd, cmd, sizeof (cmd), 0, 0);
476 
477   return status;
478 }
479 
480 static SANE_Status
read_barcode_data(BH_Scanner *s, FILE *fp)481 read_barcode_data (BH_Scanner *s, FILE *fp)
482 {
483   static SANE_Byte cmd[10];
484   SANE_Status status;
485   SANE_Int num_found = 0;
486   double w, l, x, y, res;
487   struct barcode_data buf;
488   size_t buf_size = sizeof(buf);
489   DBG (3, "read_barcode_data called\n");
490 
491   memset (&cmd, 0, sizeof (cmd));
492   cmd[0] = BH_SCSI_READ_SCANNED_DATA;
493   cmd[2] = s->readlist[s->readptr];
494   _lto3b(buf_size, &cmd[6]); /* transfer length */
495 
496   s->barcode_not_found = SANE_FALSE;
497   do {
498     memset (&buf, 0, sizeof(buf));
499     status = sanei_scsi_cmd (s->fd, &cmd, sizeof (cmd), &buf, &buf_size);
500     if (status != SANE_STATUS_GOOD)
501       break;
502     if (s->barcode_not_found == SANE_TRUE)
503       break;
504 
505     num_found++;
506 
507     buf.barcodedata[sizeof(buf.barcodedata)-1] = '\0';
508 
509     /* calculate the bounding rectangle */
510     x = MIN((int) _2btol(buf.posxb), (int) _2btol(buf.posxa));
511     y = MIN((int) _2btol(buf.posyb), (int) _2btol(buf.posyd));
512     w = MAX((int) _2btol(buf.posxd), (int) _2btol(buf.posxd)) - x;
513     l = MAX((int) _2btol(buf.posya), (int) _2btol(buf.posyc)) - y;
514     /* convert from pixels to mm */
515     res = _OPT_VAL_WORD(s, OPT_RESOLUTION);
516     if (res <= 0.0)
517       {
518 	/* avoid divide by zero */
519 	DBG(1, "read_barcode_data: warning: "
520 	    "encountered bad resolution value '%f', replacing with '%f'\n",
521 	    res, 200.0);
522 	res = 200.0;
523       }
524     x = x * MM_PER_INCH / res;
525     y = y * MM_PER_INCH / res;
526     w = w * MM_PER_INCH / res;
527     l = l * MM_PER_INCH / res;
528     /* add a bit of a border around the edges */
529     x = MAX(0.0, x - BH_DECODE_FUDGE);
530     y = MAX(0.0, y - BH_DECODE_FUDGE);
531     w += (BH_DECODE_FUDGE * 4);
532     l += (BH_DECODE_FUDGE * 4);
533 
534     /* write the decoded barcode data into the file */
535     fprintf(fp, "<barcode>\n <section>%s</section>\n",
536 	    print_read_type((int) s->readlist[s->readptr]));
537     fprintf(fp, " <type>%s</type>\n <status-flag>%d</status-flag>\n",
538 	    print_barcodetype((int) _2btol(buf.barcodetype)),
539 	    (int) _2btol(buf.statusflag));
540     fprintf(fp, " <orientation>%s</orientation>\n",
541 	    print_orientation((int) _2btol(buf.barcodeorientation)));
542     fprintf(fp, " <location>\n  <tl><x>%d</x><y>%d</y></tl>\n",
543 	    (int) _2btol(buf.posxb), (int) _2btol(buf.posyb));
544     fprintf(fp, "  <tr><x>%d</x><y>%d</y></tr>\n",
545 	    (int) _2btol(buf.posxd), (int) _2btol(buf.posyd));
546     fprintf(fp, "  <bl><x>%d</x><y>%d</y></bl>\n",
547 	    (int) _2btol(buf.posxa), (int) _2btol(buf.posya));
548     fprintf(fp, "  <br><x>%d</x><y>%d</y></br>\n </location>\n",
549 	    (int) _2btol(buf.posxc), (int) _2btol(buf.posyc));
550     fprintf(fp, " <rectangle>%.2fx%.2f+%.2f+%.2f</rectangle>\n",
551 	    w, l, x, y);
552     fprintf(fp, " <search-time>%d</search-time>\n <length>%d</length>\n",
553 	    (int) _2btol(buf.barcodesearchtime),
554 	    (int) buf.barcodelen);
555     fprintf(fp, " <data>%s</data>\n</barcode>\n",
556 	    buf.barcodedata);
557   } while (num_found <= BH_DECODE_TRIES);
558 
559   DBG (3, "read_barcode_data: found %d barcodes, returning %s\n",
560        num_found, sane_strstatus(status));
561 
562   return status;
563 }
564 
565 static SANE_Status
read_icon_data(BH_Scanner *s)566 read_icon_data (BH_Scanner *s)
567 {
568   static SANE_Byte cmd[10];
569   SANE_Status status;
570   struct icon_data buf;
571   size_t buf_size = sizeof(buf);
572   DBG (3, "read_icon_data called\n");
573 
574   memset (&cmd, 0, sizeof (cmd));
575   cmd[0] = BH_SCSI_READ_SCANNED_DATA;
576   cmd[2] = s->readlist[s->readptr];
577   _lto3b(buf_size, &cmd[6]); /* transfer length */
578 
579   memset (&buf, 0, sizeof(buf));
580 
581   status = sanei_scsi_cmd (s->fd, &cmd, sizeof (cmd), &buf, &buf_size);
582 
583   /* set the fields in the scanner handle for later reference */
584   s->iconwidth = _4btol(buf.iconwidth);
585   s->iconlength = _4btol(buf.iconlength);
586 
587   DBG(3, "read_icon_data: windowwidth:%lu, windowlength:%lu\n",
588       _4btol(buf.windowwidth),
589       _4btol(buf.windowlength));
590   DBG(3, "read_icon_data: iconwidth:%lu, iconlength:%lu, iconwidth(bytes):%lu\n",
591       _4btol(buf.iconwidth),
592       _4btol(buf.iconlength),
593       _4btol(buf.iconwidthbytes));
594   DBG(3, "read_icon_data: bitordering:%02x, icondatalen:%lu\n",
595       buf.bitordering,
596       _4btol(buf.icondatalen));
597 
598   DBG (3, "read_icon_data returning %d\n", status);
599 
600   return status;
601 }
602 
603 static SANE_Status
read_barfile(BH_Scanner *s, void *buf, size_t *buf_size)604 read_barfile (BH_Scanner *s, void *buf, size_t *buf_size)
605 {
606   SANE_Status status = SANE_STATUS_GOOD;
607   size_t nread;
608   DBG (3, "read_barfile called (%lu bytes)\n", (u_long) *buf_size);
609 
610   if (s->barf != NULL)
611     {
612       /* this function needs to set InvalidBytes so it looks
613        * like a B&H scsi EOF
614        */
615       if ((nread = fread(buf, 1, *buf_size, s->barf)) < *buf_size)
616 	{
617 	  /* set InvalidBytes */
618 	  s->InvalidBytes = *buf_size - nread;
619 
620 	  if (ferror(s->barf))
621 	    {
622 	      status = SANE_STATUS_IO_ERROR;
623 	      fclose(s->barf);
624 	      s->barf = NULL;
625 	      unlink(s->barfname);
626 	    }
627 	  else if (feof(s->barf))
628 	    {
629 	      /* it also needs to close the file and delete it when EOF is
630 	       * reached.
631 	       */
632 	      fclose(s->barf);
633 	      s->barf = NULL;
634 	      unlink(s->barfname);
635 	    }
636 	}
637     }
638   else
639     {
640       /* set InvalidBytes */
641       s->InvalidBytes = *buf_size;
642     }
643 
644   return status;
645 }
646 
647 static SANE_Status
read_data(BH_Scanner *s, void *buf, size_t *buf_size)648 read_data (BH_Scanner *s, void *buf, size_t *buf_size)
649 {
650   static SANE_Byte cmd[10];
651   SANE_Status status;
652   DBG (3, "read_data called (%lu bytes)\n", (u_long) *buf_size);
653 
654   if (s->readlist[s->readptr] == BH_SCSI_READ_TYPE_SENDBARFILE)
655     {
656       /* call special barcode data read function. */
657       status = read_barfile(s, buf, buf_size);
658     }
659   else
660     {
661       memset (&cmd, 0, sizeof (cmd));
662       cmd[0] = BH_SCSI_READ_SCANNED_DATA;
663       cmd[2] = s->readlist[s->readptr];
664       _lto3b(*buf_size, &cmd[6]); /* transfer length */
665 
666       status = sanei_scsi_cmd (s->fd, &cmd, sizeof (cmd), buf, buf_size);
667     }
668 
669   return status;
670 }
671 
672 static SANE_Status
mode_select_measurement(BH_Scanner *s)673 mode_select_measurement (BH_Scanner *s)
674 {
675   static struct {
676     SANE_Byte cmd[6];
677     struct mode_page_03 mp;
678   } select_cmd;
679   SANE_Status status;
680 
681   DBG (3, "mode_select_measurement called (bmu:%d mud:%d)\n",
682        s->bmu, s->mud);
683 
684   memset (&select_cmd, 0, sizeof (select_cmd));
685   select_cmd.cmd[0] = BH_SCSI_MODE_SELECT;
686   select_cmd.cmd[1] = 0x10;
687   select_cmd.cmd[4] = sizeof(select_cmd.mp);
688 
689   select_cmd.mp.pagecode = BH_MODE_MEASUREMENT_PAGE_CODE;
690   select_cmd.mp.paramlen = 0x06;
691   select_cmd.mp.bmu = s->bmu;
692   _lto2b(s->mud, select_cmd.mp.mud);
693 
694   status = sanei_scsi_cmd (s->fd, &select_cmd, sizeof (select_cmd), 0, 0);
695 
696   return status;
697 }
698 
699 static SANE_Status
mode_select_timeout(BH_Scanner *s)700 mode_select_timeout (BH_Scanner *s)
701 {
702   static struct {
703     SANE_Byte cmd[6];
704     struct mode_page_20 mp;
705   } select_cmd;
706   SANE_Status status;
707 
708   DBG (3, "mode_select_timeout called\n");
709 
710   memset (&select_cmd, 0, sizeof (select_cmd));
711   select_cmd.cmd[0] = BH_SCSI_MODE_SELECT;
712   select_cmd.cmd[1] = 0x10;
713   select_cmd.cmd[4] = sizeof(select_cmd.mp);
714 
715   select_cmd.mp.pagecode = BH_MODE_TIMEOUT_PAGE_CODE;
716   select_cmd.mp.paramlen = 0x06;
717   select_cmd.mp.timeoutmanual = _OPT_VAL_WORD(s, OPT_TIMEOUT_MANUAL);
718   select_cmd.mp.timeoutadf = _OPT_VAL_WORD(s, OPT_TIMEOUT_ADF);
719 
720   status = sanei_scsi_cmd (s->fd, &select_cmd, sizeof (select_cmd), 0, 0);
721 
722   return status;
723 }
724 
725 static SANE_Status
mode_select_icon(BH_Scanner *s)726 mode_select_icon (BH_Scanner *s)
727 {
728   static struct {
729     SANE_Byte cmd[6];
730     struct mode_page_21 mp;
731   } select_cmd;
732   SANE_Status status;
733 
734   DBG (3, "mode_select_icon called\n");
735 
736   memset (&select_cmd, 0, sizeof (select_cmd));
737   select_cmd.cmd[0] = BH_SCSI_MODE_SELECT;
738   select_cmd.cmd[1] = 0x10;
739   select_cmd.cmd[4] = sizeof(select_cmd.mp);
740 
741   select_cmd.mp.pagecode = BH_MODE_ICON_PAGE_CODE;
742   select_cmd.mp.paramlen = 0x06;
743   _lto2b(_OPT_VAL_WORD(s, OPT_ICON_WIDTH), select_cmd.mp.iconwidth);
744   _lto2b(_OPT_VAL_WORD(s, OPT_ICON_LENGTH), select_cmd.mp.iconlength);
745 
746   status = sanei_scsi_cmd (s->fd, &select_cmd, sizeof (select_cmd), 0, 0);
747 
748   return status;
749 }
750 
751 static SANE_Status
mode_select_barcode_priority(BH_Scanner *s)752 mode_select_barcode_priority (BH_Scanner *s)
753 {
754   static struct {
755     SANE_Byte cmd[6];
756     struct mode_page_30 mp;
757   } select_cmd;
758   SANE_Status status;
759   int i;
760 
761   DBG (3, "mode_select_barcode_priority called\n");
762 
763   memset (&select_cmd, 0, sizeof (select_cmd));
764   select_cmd.cmd[0] = BH_SCSI_MODE_SELECT;
765   select_cmd.cmd[1] = 0x10;
766   select_cmd.cmd[4] = sizeof(select_cmd.mp);
767 
768   select_cmd.mp.pagecode = BH_MODE_BARCODE_PRIORITY_PAGE_CODE;
769   select_cmd.mp.paramlen = 0x06;
770 
771   for (i = 0; i < NUM_SEARCH_BARS; i++)
772     {
773       /* anything after a 'none' is ignored */
774       if ((select_cmd.mp.priority[i] = s->search_bars[i]) == 0) break;
775     }
776 
777   status = sanei_scsi_cmd (s->fd, &select_cmd, sizeof (select_cmd), 0, 0);
778 
779   return status;
780 }
781 
782 static SANE_Status
mode_select_barcode_param1(BH_Scanner *s)783 mode_select_barcode_param1 (BH_Scanner *s)
784 {
785   static struct {
786     SANE_Byte cmd[6];
787     struct mode_page_31 mp;
788   } select_cmd;
789   SANE_Status status;
790 
791   DBG (3, "mode_select_barcode_param1 called\n");
792 
793   memset (&select_cmd, 0, sizeof (select_cmd));
794   select_cmd.cmd[0] = BH_SCSI_MODE_SELECT;
795   select_cmd.cmd[1] = 0x10;
796   select_cmd.cmd[4] = sizeof(select_cmd.mp);
797 
798   select_cmd.mp.pagecode = BH_MODE_BARCODE_PARAM1_PAGE_CODE;
799   select_cmd.mp.paramlen = 0x06;
800 
801   _lto2b((SANE_Int)_OPT_VAL_WORD_THOUSANDTHS(s, OPT_BARCODE_HMIN), select_cmd.mp.minbarheight);
802   select_cmd.mp.searchcount = _OPT_VAL_WORD(s, OPT_BARCODE_SEARCH_COUNT);
803   select_cmd.mp.searchmode =
804     get_barcode_search_mode(_OPT_VAL_STRING(s, OPT_BARCODE_SEARCH_MODE));
805   _lto2b(_OPT_VAL_WORD(s, OPT_BARCODE_SEARCH_TIMEOUT), select_cmd.mp.searchtimeout);
806 
807   status = sanei_scsi_cmd (s->fd, &select_cmd, sizeof (select_cmd), 0, 0);
808 
809   return status;
810 }
811 
812 static SANE_Status
mode_select_barcode_param2(BH_Scanner *s)813 mode_select_barcode_param2 (BH_Scanner *s)
814 {
815   static struct {
816     SANE_Byte cmd[6];
817     struct mode_page_32 mp;
818   } select_cmd;
819   SANE_Status status;
820   size_t len;
821 
822   DBG (3, "mode_select_barcode_param2 called\n");
823 
824   /* first we'll do a mode sense, then we'll overwrite with
825    * our new values, and then do a mode select
826    */
827   memset (&select_cmd, 0, sizeof (select_cmd));
828   select_cmd.cmd[0] = BH_SCSI_MODE_SENSE;
829   select_cmd.cmd[2] = BH_MODE_BARCODE_PARAM2_PAGE_CODE;
830   select_cmd.cmd[4] = sizeof(select_cmd.mp);
831 
832   len = sizeof(select_cmd.mp);
833   status = sanei_scsi_cmd (s->fd, &select_cmd.cmd, sizeof (select_cmd.cmd),
834 			   &select_cmd.mp, &len);
835 
836   if (status == SANE_STATUS_GOOD)
837     {
838       DBG(8, "mode_select_barcode_param2: sensed values: relmax:%d barmin:%d barmax:%d\n",
839 	  (int) _2btol(select_cmd.mp.relmax),
840 	  (int) _2btol(select_cmd.mp.barmin),
841 	  (int) _2btol(select_cmd.mp.barmax));
842 
843       memset (&select_cmd.cmd, 0, sizeof (select_cmd.cmd));
844       select_cmd.cmd[0] = BH_SCSI_MODE_SELECT;
845       select_cmd.cmd[1] = 0x10;
846       select_cmd.cmd[4] = sizeof(select_cmd.mp);
847 
848       select_cmd.mp.modedatalen = 0x00;
849       select_cmd.mp.mediumtype = 0x00;
850       select_cmd.mp.devicespecificparam = 0x00;
851       select_cmd.mp.blockdescriptorlen = 0x00;
852 
853       select_cmd.mp.pagecode = BH_MODE_BARCODE_PARAM2_PAGE_CODE;
854       select_cmd.mp.paramlen = 0x06;
855 
856       /* only overwrite the default values if the option is non-zero */
857       if (_OPT_VAL_WORD(s, OPT_BARCODE_RELMAX) != 0)
858 	{
859 	  _lto2b(_OPT_VAL_WORD(s, OPT_BARCODE_RELMAX), select_cmd.mp.relmax);
860 	}
861       if (_OPT_VAL_WORD(s, OPT_BARCODE_BARMIN) != 0)
862 	{
863 	  _lto2b(_OPT_VAL_WORD(s, OPT_BARCODE_BARMIN), select_cmd.mp.barmin);
864 	}
865       if (_OPT_VAL_WORD(s, OPT_BARCODE_BARMAX) != 0)
866 	{
867 	  _lto2b(_OPT_VAL_WORD(s, OPT_BARCODE_BARMAX), select_cmd.mp.barmax);
868 	}
869 
870       DBG(8, "mode_select_barcode_param2: param values: relmax:%d barmin:%d barmax:%d\n",
871 	  (int) _OPT_VAL_WORD(s, OPT_BARCODE_RELMAX),
872 	  (int) _OPT_VAL_WORD(s, OPT_BARCODE_BARMIN),
873 	  (int) _OPT_VAL_WORD(s, OPT_BARCODE_BARMAX));
874 
875       DBG(8, "mode_select_barcode_param2: select values: relmax:%d barmin:%d barmax:%d\n",
876 	  (int) _2btol(select_cmd.mp.relmax),
877 	  (int) _2btol(select_cmd.mp.barmin),
878 	  (int) _2btol(select_cmd.mp.barmax));
879 
880       status = sanei_scsi_cmd (s->fd, &select_cmd, sizeof (select_cmd), 0, 0);
881     }
882 
883   return status;
884 }
885 
886 static SANE_Status
mode_select_barcode_param3(BH_Scanner *s)887 mode_select_barcode_param3 (BH_Scanner *s)
888 {
889   static struct {
890     SANE_Byte cmd[6];
891     struct mode_page_33 mp;
892   } select_cmd;
893   SANE_Status status;
894   size_t len;
895 
896   DBG (3, "mode_select_barcode_param3 called\n");
897 
898   /* first we'll do a mode sense, then we'll overwrite with
899    * our new values, and then do a mode select
900    */
901   memset (&select_cmd, 0, sizeof (select_cmd));
902   select_cmd.cmd[0] = BH_SCSI_MODE_SENSE;
903   select_cmd.cmd[2] = BH_MODE_BARCODE_PARAM3_PAGE_CODE;
904   select_cmd.cmd[4] = sizeof(select_cmd.mp);
905 
906   len = sizeof(select_cmd.mp);
907   status = sanei_scsi_cmd (s->fd, &select_cmd.cmd, sizeof (select_cmd.cmd),
908 			   &select_cmd.mp, &len);
909 
910   if (status == SANE_STATUS_GOOD)
911     {
912       DBG(8, "mode_select_barcode_param3: sensed values: contrast:%d patchmode:%d\n",
913 	  (int) _2btol(select_cmd.mp.barcodecontrast),
914 	  (int) _2btol(select_cmd.mp.patchmode));
915 
916       memset (&select_cmd.cmd, 0, sizeof (select_cmd.cmd));
917       select_cmd.cmd[0] = BH_SCSI_MODE_SELECT;
918       select_cmd.cmd[1] = 0x10;
919       select_cmd.cmd[4] = sizeof(select_cmd.mp);
920 
921       select_cmd.mp.modedatalen = 0x00;
922       select_cmd.mp.mediumtype = 0x00;
923       select_cmd.mp.devicespecificparam = 0x00;
924       select_cmd.mp.blockdescriptorlen = 0x00;
925 
926       select_cmd.mp.pagecode = BH_MODE_BARCODE_PARAM3_PAGE_CODE;
927       select_cmd.mp.paramlen = 0x06;
928 
929       /* only overwrite the default values if the option is non-zero */
930       if (_OPT_VAL_WORD(s, OPT_BARCODE_CONTRAST) != 0)
931 	{
932 	  _lto2b(_OPT_VAL_WORD(s, OPT_BARCODE_CONTRAST), select_cmd.mp.barcodecontrast);
933 	}
934       if (_OPT_VAL_WORD(s, OPT_BARCODE_PATCHMODE) != 0)
935 	{
936 	  _lto2b(_OPT_VAL_WORD(s, OPT_BARCODE_PATCHMODE), select_cmd.mp.patchmode);
937 	}
938 
939       DBG(8, "mode_select_barcode_param3: param values: contrast:%d patchmode:%d\n",
940 	  (int) _OPT_VAL_WORD(s, OPT_BARCODE_CONTRAST),
941 	  (int) _OPT_VAL_WORD(s, OPT_BARCODE_PATCHMODE));
942 
943       DBG(8, "mode_select_barcode_param3: select values: contrast:%d patchmode:%d\n",
944 	  (int) _2btol(select_cmd.mp.barcodecontrast),
945 	  (int) _2btol(select_cmd.mp.patchmode));
946 
947       status = sanei_scsi_cmd (s->fd, &select_cmd, sizeof (select_cmd), 0, 0);
948     }
949 
950   return status;
951 }
952 
953 static SANE_Status
inquiry(int fd, void *buf, size_t *buf_size, SANE_Byte evpd, SANE_Byte page_code)954 inquiry (int fd, void *buf, size_t *buf_size, SANE_Byte evpd, SANE_Byte page_code)
955 {
956   static SANE_Byte cmd[6];
957   SANE_Status status;
958   DBG (3, "inquiry called\n");
959 
960   memset (cmd, 0, sizeof (cmd));
961   cmd[0] = BH_SCSI_INQUIRY;
962   cmd[1] = evpd;
963   cmd[2] = page_code;
964   cmd[4] = *buf_size;
965 
966   status = sanei_scsi_cmd (fd, cmd, sizeof (cmd), buf, buf_size);
967 
968   return status;
969 }
970 
971 static SANE_Status
set_window(BH_Scanner *s, SANE_Byte batchmode)972 set_window (BH_Scanner *s, SANE_Byte batchmode)
973 {
974   static struct {
975     SANE_Byte cmd[10];
976     SANE_Byte hdr[8];
977     struct window_data window;
978   } set_window_cmd;
979   SANE_Status status;
980   SANE_Int width, length, i, format, rotation, deskew ;
981 
982   DBG (3, "set_window called\n");
983 
984   /* set to thousandths for set_window */
985   s->bmu = BH_UNIT_INCH;
986   s->mud = 1000;
987   status = mode_select_measurement(s);
988   if (status != SANE_STATUS_GOOD)
989     return status;
990 
991   memset (&set_window_cmd, 0, sizeof (set_window_cmd));
992   set_window_cmd.cmd[0] = BH_SCSI_SET_WINDOW;
993   DBG(3, "set_window: sizeof(hdr) %d, sizeof(window): %d\n",
994       (int)sizeof(set_window_cmd.hdr), (int)sizeof(set_window_cmd.window));
995 
996   _lto3b(sizeof(set_window_cmd.hdr) + sizeof(set_window_cmd.window),
997 	 &set_window_cmd.cmd[6]);
998 
999   _lto2b(256, &set_window_cmd.hdr[6]);
1000 
1001   set_window_cmd.window.windowid = 0;
1002   set_window_cmd.window.autoborder = _OPT_VAL_WORD(s, OPT_AUTOBORDER);
1003   DBG (5, "autoborder set to=%d\n", set_window_cmd.window.autoborder);
1004   _lto2b(_OPT_VAL_WORD(s, OPT_RESOLUTION), set_window_cmd.window.xres);
1005   _lto2b(_OPT_VAL_WORD(s, OPT_RESOLUTION), set_window_cmd.window.yres);
1006   _lto4b((int) _OPT_VAL_WORD_THOUSANDTHS(s, OPT_TL_X), set_window_cmd.window.ulx);
1007   _lto4b((int) _OPT_VAL_WORD_THOUSANDTHS(s, OPT_TL_Y), set_window_cmd.window.uly);
1008 
1009   width = (SANE_Int) (_OPT_VAL_WORD_THOUSANDTHS(s, OPT_BR_X) -
1010 	 _OPT_VAL_WORD_THOUSANDTHS(s, OPT_TL_X));
1011   length = (SANE_Int) (_OPT_VAL_WORD_THOUSANDTHS(s, OPT_BR_Y) -
1012 	 _OPT_VAL_WORD_THOUSANDTHS(s, OPT_TL_Y));
1013 
1014   _lto4b(width, set_window_cmd.window.windowwidth);
1015   _lto4b(length, set_window_cmd.window.windowlength);
1016 
1017   /* brightness (1-255) 0 is default, aka 128.  Ignored with ACE scanners */
1018   set_window_cmd.window.brightness = _OPT_VAL_WORD(s, OPT_BRIGHTNESS);
1019   /* threshold (1-255) 0 is default, aka 128.  Ignored with ACE scanners */
1020   set_window_cmd.window.threshold = _OPT_VAL_WORD(s, OPT_THRESHOLD);
1021   /*!!! contrast (not used) */
1022   /*!!! set_window_cmd.window.contrast = _OPT_VAL_WORD(s, OPT_CONTRAST); */
1023   /* imagecomposition 0x00 lineart, 0x01 dithered/halftone, 0x02 grayscale*/
1024   set_window_cmd.window.imagecomposition =
1025     get_scan_mode_id(_OPT_VAL_STRING(s, OPT_SCAN_MODE));
1026 
1027   set_window_cmd.window.bitsperpixel = 0x01;
1028   /*!!! halftone code (not used) */
1029   /*!!! halftone id (not used) */
1030 
1031   set_window_cmd.window.paddingtype = 0x03; /* truncate byte */
1032   if (_OPT_VAL_WORD(s, OPT_NEGATIVE) == SANE_TRUE) {
1033     /* reverse image format (valid when bitsperpixel=1)
1034      * 0x00 normal, 0x01 reversed.  This is bit 7 of paddingtype.
1035      */
1036     set_window_cmd.window.paddingtype |= 0x80;
1037   }
1038 
1039   set_window_cmd.window.bitordering[0] = 0x00;
1040 
1041   /* we must always sent plain gray data in preview mode */
1042   format = (_OPT_VAL_WORD(s, OPT_PREVIEW)) ?
1043     BH_COMP_NONE :
1044     get_compression_id(_OPT_VAL_STRING(s, OPT_COMPRESSION));
1045 
1046   switch (format)
1047     {
1048     case BH_COMP_G31D:
1049       set_window_cmd.window.compressiontype = 0x01;
1050       set_window_cmd.window.compressionarg = 0x00;
1051       set_window_cmd.window.bitordering[1] = 0x01; /* Bit ordering LSB */
1052       break;
1053     case BH_COMP_G32D:
1054       set_window_cmd.window.compressiontype = 0x02;
1055       set_window_cmd.window.compressionarg = 0x04;
1056       set_window_cmd.window.bitordering[1] = 0x01; /* Bit ordering LSB */
1057       break;
1058     case BH_COMP_G42D:
1059       set_window_cmd.window.compressiontype = 0x03;
1060       set_window_cmd.window.compressionarg = 0x00;
1061       set_window_cmd.window.bitordering[1] = 0x01; /* Bit ordering LSB */
1062       break;
1063     case BH_COMP_NONE:
1064     default:
1065       set_window_cmd.window.compressiontype = 0x00;
1066       set_window_cmd.window.compressionarg = 0x00;
1067       set_window_cmd.window.bitordering[1] = 0x00; /* n/a */
1068       break;
1069     }
1070 
1071   /* rotation and deskew settings, if autoborder is turned on */
1072   if(set_window_cmd.window.autoborder){ /*--- setting byte 46 of the window descriptor block only works with autoborder */
1073     rotation = get_rotation_id(_OPT_VAL_STRING(s, OPT_ROTATION));
1074     if (_OPT_VAL_WORD(s, OPT_DESKEW) == SANE_TRUE) deskew = BH_DESKEW_ENABLE;
1075     else deskew = BH_DESKEW_DISABLE;
1076     set_window_cmd.window.border_rotation = ( rotation | deskew );  /*--- deskew assumes autoborder */
1077   }
1078 
1079   /* remote - 0x00 ACE set in window; 0x01 ACE set by control panel */
1080   set_window_cmd.window.remote = _OPT_VAL_WORD(s, OPT_CONTROL_PANEL);
1081   if (set_window_cmd.window.remote == 0x00) {
1082     /* acefunction (ignored on non-ACE scanners) */
1083     set_window_cmd.window.acefunction = _OPT_VAL_WORD(s, OPT_ACE_FUNCTION);
1084     /* acesensitivity (ignored on non-ACE scanners) */
1085     set_window_cmd.window.acesensitivity = _OPT_VAL_WORD(s, OPT_ACE_SENSITIVITY);
1086   }
1087 
1088   set_window_cmd.window.batchmode = batchmode;
1089 
1090   /* fill in the section descriptor blocks */
1091   for (i = 0; i < s->num_sections; i++)
1092     {
1093       BH_SectionBlock *b;
1094 
1095       b = &set_window_cmd.window.sectionblock[i];
1096 
1097       _lto4b(s->sections[i].left, b->ul_x);
1098       _lto4b(s->sections[i].top, b->ul_y);
1099       _lto4b(s->sections[i].width, b->width);
1100       _lto4b(s->sections[i].length, b->length);
1101       b->compressiontype = s->sections[i].compressiontype;
1102       b->compressionarg = s->sections[i].compressionarg;
1103     }
1104 
1105   status = sanei_scsi_cmd (s->fd, &set_window_cmd, sizeof (set_window_cmd), 0, 0);
1106   DBG (5, "sanei_scsi_cmd executed, status=%d\n", status );
1107   if (status != SANE_STATUS_GOOD)
1108     return status;
1109 
1110   /* set to points for reading */
1111   s->bmu = BH_UNIT_POINT;
1112   s->mud = 1;
1113   status = mode_select_measurement(s);
1114 
1115   return status;
1116 }
1117 
1118 static SANE_Status
get_window(BH_Scanner *s, SANE_Int *w, SANE_Int *h, SANE_Bool backpage)1119 get_window (BH_Scanner *s, SANE_Int *w, SANE_Int *h, SANE_Bool backpage)
1120 {
1121   SANE_Byte cmd[10];
1122   static struct {
1123     SANE_Byte hdr[8];
1124     struct window_data window;
1125   } get_window_data;
1126   SANE_Status status;
1127   SANE_Int x, y, i = 0, get_window_delay = 1;
1128   SANE_Bool autoborder;
1129   size_t len;
1130 
1131   DBG (3, "get_window called\n");
1132 
1133   autoborder = _OPT_VAL_WORD(s, OPT_AUTOBORDER) == 1;
1134 
1135   while (1)
1136     {
1137       i++;
1138       memset (&cmd, 0, sizeof (cmd));
1139       memset (&get_window_data, 0, sizeof (get_window_data));
1140 
1141       cmd[0] = BH_SCSI_GET_WINDOW;
1142       _lto3b(sizeof(get_window_data), &cmd[6]);
1143 
1144       _lto2b(256, &get_window_data.hdr[6]);
1145 
1146       get_window_data.window.windowid = (backpage == SANE_TRUE) ? 1 : 0;
1147 
1148       len = sizeof(get_window_data);
1149       status = sanei_scsi_cmd (s->fd, &cmd, sizeof (cmd),
1150 			       &get_window_data, &len);
1151       if (status == SANE_STATUS_GOOD)
1152 	{
1153 	  x =_4btol(get_window_data.window.ulx);
1154 	  y =_4btol(get_window_data.window.uly);
1155 	  *w =_4btol(get_window_data.window.windowwidth);
1156 	  *h =_4btol(get_window_data.window.windowlength);
1157 
1158 	  if (autoborder)
1159 	    {
1160 	      /* we try repeatedly until we get the autoborder bit set */
1161 	      if (get_window_data.window.autoborder != 1 &&
1162 		  i < BH_AUTOBORDER_TRIES)
1163 		{
1164 	          DBG (5, "waiting %d second[s], try: %d\n",get_window_delay,i);
1165 		  sleep(get_window_delay);  /*--- page 4-5 of B&H Copiscan 8000 ESC OEM Tech Manual */
1166                                             /*--- requires at least 50ms wait between each GET WINDOW command */
1167                                             /*--- experience shows that this can take 3 to 4 seconds */
1168 		  continue;
1169 		}
1170 	      if (get_window_data.window.autoborder != 1)
1171 		{
1172 		  DBG(1, "Automatic Border Detection not done within %d tries\n",
1173 		      BH_AUTOBORDER_TRIES);
1174 		  status = SANE_STATUS_IO_ERROR;
1175 		}
1176              DBG (0, "page dimension: wide:%d high:%d \n",*w,*h);
1177 	    }
1178 	  DBG (3, "*** Window size: %dx%d+%d+%d\n", *w, *h, x, y);
1179 	  DBG (5, "*** get_window found autoborder=%02xh\n", get_window_data.window.autoborder);
1180 	  DBG (5, "*** get_window found border_rotation=%02xh\n", get_window_data.window.border_rotation);
1181 	}
1182 
1183       /* we are 'outta here' */
1184       break;
1185     }
1186 
1187   return status;
1188 }
1189 
1190 static SANE_Status
get_parameters(SANE_Handle handle, SANE_Parameters *params)1191 get_parameters (SANE_Handle handle, SANE_Parameters *params)
1192 {
1193   BH_Scanner *s = handle;
1194   SANE_Int width, length, res, comp;
1195   double br_x, tl_x, br_y, tl_y;
1196   SANE_Frame format;
1197 
1198   DBG(3, "get_parameters called\n");
1199 
1200   memset (&s->params, 0, sizeof (s->params));
1201 
1202   res = _OPT_VAL_WORD(s, OPT_RESOLUTION);
1203 
1204   /* make best-effort guess at what parameters will look like once
1205      the scan starts.  */
1206 
1207   br_x = _OPT_VAL_WORD_THOUSANDTHS(s, OPT_BR_X);
1208   br_y = _OPT_VAL_WORD_THOUSANDTHS(s, OPT_BR_Y);
1209   tl_x = _OPT_VAL_WORD_THOUSANDTHS(s, OPT_TL_X);
1210   tl_y = _OPT_VAL_WORD_THOUSANDTHS(s, OPT_TL_Y);
1211 
1212   width = (br_x - tl_x + 1) * res / 1000.0;
1213   length = (br_y - tl_y + 1) * res / 1000.0;
1214 
1215   /* figure out the default image format for front/back pages */
1216   comp = get_compression_id(_OPT_VAL_STRING(s, OPT_COMPRESSION));
1217   switch (comp)
1218     {
1219     case BH_COMP_G31D:
1220       format = SANE_FRAME_G31D;
1221       break;
1222     case BH_COMP_G32D:
1223       format = SANE_FRAME_G32D;
1224       break;
1225     case BH_COMP_G42D:
1226       format = SANE_FRAME_G42D;
1227       break;
1228     case BH_COMP_NONE:
1229     default:
1230       format = SANE_FRAME_GRAY;
1231       break;
1232     }
1233 
1234   if (s->scanning)
1235     {
1236       SANE_Int w, l, status;
1237       SANE_Byte itemtype;
1238 
1239       itemtype = s->readlist[s->readptr];
1240       /* update parameters based on the current item */
1241 
1242       status = SANE_STATUS_GOOD;
1243       if (itemtype == BH_SCSI_READ_TYPE_FRONT)
1244 	{
1245 	  DBG (3, "get_parameters: sending GET WINDOW (front)\n");
1246 	  status = get_window (s, &w, &l, SANE_FALSE);
1247 	  if (status == SANE_STATUS_GOOD)
1248 	    {
1249 	      width = w;
1250 	      length = l;
1251 	    }
1252 	}
1253       else if (itemtype == BH_SCSI_READ_TYPE_BACK)
1254 	{
1255 	  DBG (3, "get_parameters: sending GET WINDOW (back)\n");
1256 	  status = get_window (s, &w, &l, SANE_TRUE);
1257 	  if (status == SANE_STATUS_GOOD)
1258 	    {
1259 	      width = w;
1260 	      length = l;
1261 	    }
1262 	}
1263       else if (itemtype == BH_SCSI_READ_TYPE_FRONT_ICON ||
1264 	       itemtype == BH_SCSI_READ_TYPE_BACK_ICON)
1265 	{
1266 	  /* the icon is never compressed */
1267 	  format = SANE_FRAME_GRAY;
1268 	  width = s->iconwidth;
1269 	  length = s->iconlength;
1270 	}
1271       else if (itemtype > BH_SCSI_READ_TYPE_FRONT &&
1272 	       itemtype <= (BH_SCSI_READ_TYPE_FRONT + NUM_SECTIONS))
1273 	{
1274 	  /* a front section */
1275 	  SANE_Int sectnum = itemtype - BH_SCSI_READ_TYPE_FRONT;
1276 
1277 	  format = s->sections[sectnum - 1].format;
1278 	  /* convert from thousandths to pixels */
1279 	  width = s->sections[sectnum - 1].width * res / 1000.0;
1280 	  length = s->sections[sectnum - 1].length * res / 1000.0;
1281 	}
1282       else if (itemtype > BH_SCSI_READ_TYPE_BACK &&
1283 	       itemtype <= (BH_SCSI_READ_TYPE_BACK + NUM_SECTIONS))
1284 	{
1285 	  /* a back section */
1286 	  SANE_Int sectnum = itemtype - BH_SCSI_READ_TYPE_BACK;
1287 
1288 	  format = s->sections[sectnum - 1].format;
1289 	  /* convert from thousandths to pixels */
1290 	  width = s->sections[sectnum - 1].width * res / 1000.0;
1291 	  length = s->sections[sectnum - 1].length * res / 1000.0;
1292 	}
1293       else if ( (itemtype >= BH_SCSI_READ_TYPE_BACK_BARCODE &&
1294 		 itemtype <= (BH_SCSI_READ_TYPE_BACK_BARCODE + NUM_SECTIONS)) ||
1295 		(itemtype >= BH_SCSI_READ_TYPE_FRONT_BARCODE &&
1296 		 itemtype <= (BH_SCSI_READ_TYPE_FRONT_BARCODE + NUM_SECTIONS)) )
1297 	{
1298 	  /* decoded barcode data */
1299 	  format = SANE_FRAME_TEXT;
1300 	  width = 8;
1301 	  length = -1;
1302 	}
1303       else if (itemtype == BH_SCSI_READ_TYPE_SENDBARFILE)
1304 	{
1305 	  /* decoded barcode data file */
1306 	  format = SANE_FRAME_TEXT;
1307 	  width = 8;
1308 	  length = -1;
1309 	}
1310       else
1311 	{
1312 	  format = SANE_FRAME_GRAY;
1313 	  width = 8;
1314 	  length = -1;
1315 	  DBG(1, "get_parameters: unrecognized read itemtype: %d\n",
1316 	      itemtype);
1317 	}
1318 
1319       if (status != SANE_STATUS_GOOD)
1320 	{
1321 	  DBG(1, "get_parameters: failed\n");
1322 	  return status;
1323 	}
1324     }
1325 
1326   if (res <= 0 || width <= 0)
1327     {
1328       DBG(1, "get_parameters:illegal parameters res=%d, width=%d, length=%d\n",
1329 	  res, width, length);
1330       return SANE_STATUS_INVAL;
1331     }
1332 
1333   /* we disable our compression/barcode formats in preview as well
1334    * as with the disable_optional_frames configuration option.  NOTE:
1335    * we may still be delivering 'wierd' data and lying about it being _GRAY!
1336    */
1337   if (format != SANE_FRAME_GRAY &&
1338       (_OPT_VAL_WORD(s, OPT_PREVIEW) || disable_optional_frames))
1339     {
1340       DBG(1, "get_parameters: warning: delivering %s data as gray",
1341 	  sane_strframe(format));
1342       format = SANE_FRAME_GRAY;
1343     }
1344 
1345   s->params.format = format;
1346   s->params.depth = 1;
1347   s->params.last_frame = SANE_TRUE;
1348   s->params.pixels_per_line = width;
1349   s->params.lines = length;
1350   s->params.bytes_per_line = (s->params.pixels_per_line + 7) / 8;
1351   /* The Bell and Howell truncates to the byte */
1352   s->params.pixels_per_line = s->params.bytes_per_line * 8;
1353 
1354   if (params)
1355     *params = s->params;
1356 
1357   DBG (1, "get_parameters: format=%d, pixels/line=%d, bytes/line=%d, "
1358        "lines=%d, dpi=%d\n",
1359        (int) s->params.format,
1360        s->params.pixels_per_line,
1361        s->params.bytes_per_line,
1362        s->params.lines,
1363        res);
1364 
1365   return SANE_STATUS_GOOD;
1366 }
1367 
1368 static SANE_Status
section_parse(const char *val, BH_Section *sect, SANE_Int res, SANE_Int comp)1369 section_parse(const char *val, BH_Section *sect, SANE_Int res, SANE_Int comp)
1370 {
1371   SANE_Status status = SANE_STATUS_INVAL;
1372   char buf[255+1], *x, *y, *w, *l, *f, *ep;
1373   const char *seps = "x+:";
1374   double mm, fpixels;
1375   u_long pixels;
1376 
1377   DBG(3, "section_parse called\n");
1378 
1379   /* a section option looks something like this:
1380    * <width>x<length>+<tl-x>+<tl-y>:<functioncodes>
1381    * Example:
1382    * 76.2x25.4+50.8+0:frontbar:back:front
1383    * the width, length, tl-x, and tl-y are in mm.
1384    * the function codes are one or more of:
1385    * front, back, frontbar, backbar, frontpatch, backpatch
1386    */
1387   if (strlen(val) > sizeof(buf) - 1)
1388     {
1389       DBG(1, "section_parse: option string too long\n");
1390       status = SANE_STATUS_INVAL;
1391     }
1392   else
1393     {
1394       do {
1395 	strcpy(buf, val);
1396 
1397 	x = y = w = l = f = NULL;
1398 	w = strtok(buf, seps);
1399 	if (w) l = strtok(NULL, seps);
1400 	if (l) x = strtok(NULL, seps);
1401 	if (x) y = strtok(NULL, seps);
1402 	if (y) f = strtok(NULL, seps);
1403 	if (!x || !y || !w || !l) break;
1404 
1405 	mm = strtod(x, &ep);
1406 	if (*ep != '\0' || errno == ERANGE || mm < 0.0) break;
1407 	sect->left = mm * 1000.0 / MM_PER_INCH;
1408 
1409 	mm = strtod(y, &ep);
1410 	if (*ep != '\0' || errno == ERANGE || mm < 0.0) break;
1411 	sect->top = mm * 1000.0 / MM_PER_INCH;
1412 
1413 	mm = strtod(w, &ep);
1414 	if (*ep != '\0' || errno == ERANGE || mm < 0.0) break;
1415 	sect->width = mm * 1000.0 / MM_PER_INCH;
1416 	/* the window width must be truncated to 16 bit points */
1417 	fpixels = sect->width * res / 1000.0;
1418 	pixels = fpixels / 16;
1419 	sect->width = pixels * 16 * 1000 / res;
1420 
1421 	mm = strtod(l, &ep);
1422 	if (*ep != '\0' || errno == ERANGE || mm < 0.0) break;
1423 	sect->length = mm * 1000.0 / MM_PER_INCH;
1424 
1425 	status = SANE_STATUS_GOOD;
1426 	while (f)
1427 	  {
1428 	    /* parse the function modifiers and set flags */
1429 	    if (strcmp(f, "front") == 0)
1430 	      sect->flags |= BH_SECTION_FRONT_IMAGE;
1431 	    else if (strcmp(f, "frontbar") == 0)
1432 	      sect->flags |= BH_SECTION_FRONT_BAR;
1433 	    else if (strcmp(f, "frontpatch") == 0)
1434 	      sect->flags |= BH_SECTION_FRONT_PATCH;
1435 	    else if (strcmp(f, "back") == 0)
1436 		sect->flags |= BH_SECTION_BACK_IMAGE;
1437 	    else if (strcmp(f, "backbar") == 0)
1438 		sect->flags |= BH_SECTION_BACK_BAR;
1439 	    else if (strcmp(f, "backpatch") == 0)
1440 		sect->flags |= BH_SECTION_BACK_PATCH;
1441 	    else if (strcmp(f, "g42d") == 0)
1442 		comp = BH_COMP_G42D;
1443 	    else if (strcmp(f, "g32d") == 0)
1444 		comp = BH_COMP_G32D;
1445 	    else if (strcmp(f, "g31d") == 0)
1446 		comp = BH_COMP_G31D;
1447 	    else if (strcmp(f, "none") == 0)
1448 		comp = BH_COMP_NONE;
1449 	    else
1450 	      DBG(1, "section_parse: ignoring unrecognized function "
1451 		  "code '%s'\n", f);
1452 
1453 	    f = strtok(NULL, seps);
1454 	  }
1455 
1456 	switch (comp)
1457 	  {
1458 	  case BH_COMP_G31D:
1459 	    sect->compressiontype = 0x01;
1460 	    sect->compressionarg = 0x00;
1461 	    sect->format = SANE_FRAME_G31D;
1462 	    break;
1463 	  case BH_COMP_G32D:
1464 	    sect->compressiontype = 0x02;
1465 	    sect->compressionarg = 0x04;
1466 	    sect->format = SANE_FRAME_G32D;
1467 	    break;
1468 	  case BH_COMP_G42D:
1469 	    sect->compressiontype = 0x03;
1470 	    sect->compressionarg = 0x00;
1471 	    sect->format = SANE_FRAME_G42D;
1472 	    break;
1473 	  case BH_COMP_NONE:
1474 	  default:
1475 	    sect->compressiontype = 0x00;
1476 	    sect->compressionarg = 0x00;
1477 	    sect->format = SANE_FRAME_GRAY;
1478 	    break;
1479 	  }
1480 
1481 	DBG(3, "section_parse: converted '%s' (mm) to "
1482 	    "%ldx%ld+%ld+%ld (thousandths) "
1483 	    "flags=%02x compression=[%d,%d] frame=%s\n",
1484 	    val,
1485 	    sect->width, sect->length, sect->left, sect->top,
1486 	    sect->flags,
1487 	    sect->compressiontype, sect->compressionarg,
1488 	    sane_strframe(sect->format));
1489 
1490       } while (0); /* perform 'loop' once */
1491     }
1492 
1493   return status;
1494 }
1495 
1496 static SANE_Status
setup_sections(BH_Scanner *s, const char *val)1497 setup_sections (BH_Scanner *s, const char *val)
1498 {
1499   SANE_Status status = SANE_STATUS_GOOD;
1500   SANE_Int sectnum = 0;
1501   char buf[255+1], *section;
1502 
1503   DBG(3, "setup_sections called\n");
1504 
1505   memset(s->sections, '\0', sizeof(s->sections));
1506   if (strlen(val) > sizeof(buf) - 1)
1507     {
1508       DBG(1, "setup_sections: option string too long\n");
1509       status = SANE_STATUS_INVAL;
1510     }
1511   else
1512     {
1513       strcpy(buf, val);
1514 
1515       section = strtok(buf, ",");
1516       while (section != NULL && sectnum < NUM_SECTIONS)
1517 	{
1518 	  if (!allblank(section))
1519 	    {
1520 	      SANE_Int res = _OPT_VAL_WORD(s, OPT_RESOLUTION);
1521 	      SANE_Int format =
1522 		get_compression_id(_OPT_VAL_STRING(s, OPT_COMPRESSION));
1523 
1524 	      status = section_parse(section, &s->sections[sectnum],
1525 				     res, format);
1526 	      if (status != SANE_STATUS_GOOD)
1527 		{
1528 		  DBG(1,
1529 		      "setup_sections: error parsing section `%s'\n",
1530 		      section);
1531 		  break;
1532 		}
1533 
1534 	      sectnum++;
1535 	    }
1536 	  section += strlen(section) + 1;
1537 	  if (section > buf + strlen(val)) break;
1538 
1539 	  section = strtok(section, ",");
1540 	}
1541     }
1542   s->num_sections = sectnum;
1543 
1544   return status;
1545 }
1546 
1547 static SANE_Status
start_setup(BH_Scanner *s)1548 start_setup (BH_Scanner *s)
1549 {
1550   SANE_Status status;
1551   SANE_Bool duplex;
1552   SANE_Int i, imagecnt;
1553   SANE_Byte batchmode;
1554 
1555   DBG(3, "start_setup called\n");
1556 
1557   duplex = _OPT_VAL_WORD(s, OPT_DUPLEX);
1558 
1559   /* get the _SECTION option, parse it and fill in the sections */
1560   status = setup_sections(s, _OPT_VAL_STRING(s, OPT_SECTION));
1561   if (status != SANE_STATUS_GOOD)
1562     {
1563       DBG(1, "start_setup: setup_sections failed: %s\n",
1564 	  sane_strstatus(status));
1565       return status;
1566     }
1567 
1568   /* see whether we'll be decoding barcodes and
1569    * set the barcodes flag appropriately
1570    */
1571   if (s->search_bars[0] == 0)
1572     {
1573       s->barcodes = SANE_FALSE;
1574     }
1575   else
1576     {
1577       s->barcodes = SANE_TRUE;
1578     }
1579 
1580   /* see whether we'll be handling icons (thumbnails)
1581    * set the icons flag appropriately
1582    */
1583   if (_OPT_VAL_WORD(s, OPT_ICON_WIDTH) >= 8 &&
1584       _OPT_VAL_WORD(s, OPT_ICON_LENGTH) >= 8)
1585     {
1586       s->icons = SANE_TRUE;
1587     }
1588   else
1589     {
1590       s->icons = SANE_FALSE;
1591     }
1592 
1593 
1594   /* calculate a new readlist for this 'batch' */
1595   s->readptr = s->readcnt = 0;
1596 
1597   /* always read the front image */
1598   s->readlist[s->readcnt++] = BH_SCSI_READ_TYPE_FRONT;
1599 
1600   /* read back page only if duplex is true */
1601   if (duplex == SANE_TRUE)
1602     {
1603       s->readlist[s->readcnt++] = BH_SCSI_READ_TYPE_BACK;
1604     }
1605 
1606   /* add image section reads to the readlist */
1607   for (i = 0; i < s->num_sections; i++)
1608     {
1609       SANE_Word flags = s->sections[i].flags;
1610 
1611       if (flags & BH_SECTION_FRONT_IMAGE)
1612 	s->readlist[s->readcnt++] = BH_SCSI_READ_TYPE_FRONT + i + 1;
1613       if (flags & BH_SECTION_BACK_IMAGE)
1614 	s->readlist[s->readcnt++] = BH_SCSI_READ_TYPE_BACK + i + 1;
1615     }
1616 
1617 
1618   /* icons (thumbnails) */
1619   if (s->icons)
1620     {
1621       s->readlist[s->readcnt++] = BH_SCSI_READ_TYPE_FRONT_ICON;
1622       /* read back icon only if duplex is true */
1623       if (duplex == SANE_TRUE)
1624 	{
1625 	  s->readlist[s->readcnt++] = BH_SCSI_READ_TYPE_BACK_ICON;
1626 	}
1627     }
1628 
1629   /* NOTE: It is important that all of the image data comes before
1630    * the barcode/patchcode data.
1631    */
1632   /* barcodes */
1633   imagecnt = s->readcnt;
1634   if (s->barcodes)
1635     {
1636       if (s->num_sections == 0)
1637 	{
1638 	  /* we only decode the entire page(s) if there are no
1639 	   * sections defined
1640 	   */
1641 	  s->readlist[s->readcnt++] = BH_SCSI_READ_TYPE_FRONT_BARCODE;
1642 	  /* read back barcode only if duplex is true */
1643 	  if (duplex == SANE_TRUE)
1644 	    {
1645 	      s->readlist[s->readcnt++] = BH_SCSI_READ_TYPE_BACK_BARCODE;
1646 	    }
1647 	}
1648       else
1649 	{
1650 	  /* add barcode section reads to the readlist */
1651 	  for (i = 0; i < s->num_sections; i++)
1652 	    {
1653 	      SANE_Word flags = s->sections[i].flags;
1654 
1655 	      if (flags & BH_SECTION_FRONT_BAR)
1656 		s->readlist[s->readcnt++] =
1657 		  BH_SCSI_READ_TYPE_FRONT_BARCODE + i + 1;
1658 	      if (flags & BH_SECTION_BACK_BAR)
1659 		s->readlist[s->readcnt++] =
1660 		  BH_SCSI_READ_TYPE_BACK_BARCODE + i + 1;
1661 	    }
1662 	}
1663     }
1664 
1665   /* patchcodes */
1666   if (s->patchcodes)
1667     {
1668       if (s->num_sections == 0)
1669 	{
1670 	  /* we only decode the entire page(s) if there are no
1671 	   * sections defined
1672 	   */
1673 	  s->readlist[s->readcnt++] = BH_SCSI_READ_TYPE_FRONT_PATCHCODE;
1674 	  /* read back patchcode only if duplex is true */
1675 	  if (duplex == SANE_TRUE)
1676 	    {
1677 	      s->readlist[s->readcnt++] = BH_SCSI_READ_TYPE_BACK_PATCHCODE;
1678 	    }
1679 	}
1680       else
1681 	{
1682 	  /* add patchcode section reads to the readlist */
1683 	  for (i = 0; i < s->num_sections; i++)
1684 	    {
1685 	      SANE_Word flags = s->sections[i].flags;
1686 
1687 	      if (flags & BH_SECTION_FRONT_PATCH)
1688 		s->readlist[s->readcnt++] =
1689 		  BH_SCSI_READ_TYPE_FRONT_PATCHCODE + i + 1;
1690 	      if (flags & BH_SECTION_BACK_PATCH)
1691 		s->readlist[s->readcnt++] =
1692 		  BH_SCSI_READ_TYPE_BACK_PATCHCODE + i + 1;
1693 	    }
1694 	}
1695     }
1696 
1697   /* add the special item to the read list which transfers the barcode
1698    * file that's built as a result of processing barcode and patchcode
1699    * readitems.  NOTE: this one must be last!
1700    */
1701   if (s->readcnt > imagecnt)
1702     {
1703       s->readlist[s->readcnt++] = BH_SCSI_READ_TYPE_SENDBARFILE;
1704     }
1705 
1706   if (_OPT_VAL_WORD(s, OPT_BATCH) == SANE_TRUE)
1707     {
1708       /* if batchmode is enabled, then call set_window to
1709        * abort the batch (even though there might not (and probably
1710        * isn't) a batch in progress).  This avoids a batch start error
1711        * in the case where a previous batch was not aborted.
1712        */
1713       DBG(5, "start_setup: calling set_window to abort batch\n");
1714       set_window(s, BH_BATCH_ABORT);
1715 
1716       batchmode = BH_BATCH_ENABLE;
1717     }
1718   else
1719     {
1720       batchmode = BH_BATCH_DISABLE;
1721     }
1722 
1723   DBG(5, "start_setup: duplex=%s, barcodes=%s, patchcodes=%s, "
1724       "icons=%s, batch=%s\n",
1725       (duplex == SANE_TRUE) ? "yes" : "no",
1726       (s->barcodes == SANE_TRUE) ? "yes" : "no",
1727       (s->patchcodes == SANE_TRUE) ? "yes" : "no",
1728       (s->icons == SANE_TRUE) ? "yes" : "no",
1729       (batchmode == BH_BATCH_ENABLE) ? "yes" : "no");
1730   DBG(5, "start_setup: sections=%d\n", s->num_sections);
1731   for (i = 0; i < s->num_sections; i++)
1732     {
1733       DBG(5, "start_setup:  "
1734 	  "[%d] %lux%lu+%lu+%lu flags=%02x compression=[%d,%d]\n",
1735 	  i+1,
1736 	  s->sections[i].width, s->sections[i].length,
1737 	  s->sections[i].left, s->sections[i].top,
1738 	  s->sections[i].flags,
1739 	  s->sections[i].compressiontype, s->sections[i].compressionarg);
1740     }
1741   DBG(5, "start_setup: read list length=%d\n", s->readcnt);
1742   for (i = 0; i < s->readcnt; i++)
1743     {
1744       DBG(5, "start_setup:  [%d] %s\n", i+1, print_read_type(s->readlist[i]));
1745     }
1746 
1747   DBG(5, "start_setup: sending SET WINDOW\n");
1748   status = set_window(s, batchmode);
1749   if (status != SANE_STATUS_GOOD)
1750     {
1751       DBG(1, "start_setup: SET WINDOW failed: %s\n",
1752 	   sane_strstatus(status));
1753       return status;
1754     }
1755 
1756   DBG(5, "start_setup: sending mode_select_timeout\n");
1757   status = mode_select_timeout(s);
1758   if (status != SANE_STATUS_GOOD)
1759     {
1760       DBG(1, "start_setup: mode_select_timeout failed: %s\n",
1761 	   sane_strstatus(status));
1762       return status;
1763     }
1764 
1765   if (s->icons == SANE_TRUE)
1766     {
1767       DBG(5, "start_setup: sending mode_select_icon\n");
1768       status = mode_select_icon(s);
1769       if (status != SANE_STATUS_GOOD)
1770 	{
1771 	  DBG(1, "start_setup: mode_select_icon failed: %s\n",
1772 	       sane_strstatus(status));
1773 	  return status;
1774 	}
1775     }
1776 
1777   if (s->barcodes == SANE_TRUE)
1778     {
1779       DBG(5, "start_setup: sending mode_select_barcode_priority\n");
1780       status = mode_select_barcode_priority(s);
1781       if (status != SANE_STATUS_GOOD)
1782 	{
1783 	  DBG(1, "start_setup: mode_select_barcode_priority failed: %s\n",
1784 	       sane_strstatus(status));
1785 	  return status;
1786 	}
1787 
1788       DBG(5, "start_setup: sending mode_select_barcode_param1\n");
1789       status = mode_select_barcode_param1(s);
1790       if (status != SANE_STATUS_GOOD)
1791 	{
1792 	  DBG(1, "start_setup: mode_select_barcode_param1 failed: %s\n",
1793 	       sane_strstatus(status));
1794 	  return status;
1795 	}
1796 
1797       DBG(5, "start_setup: sending mode_select_barcode_param2\n");
1798       status = mode_select_barcode_param2(s);
1799       if (status != SANE_STATUS_GOOD)
1800 	{
1801 	  DBG(1, "start_setup: mode_select_barcode_param2 failed: %s\n",
1802 	       sane_strstatus(status));
1803 	  return status;
1804 	}
1805 
1806       DBG(5, "start_setup: sending mode_select_barcode_param3\n");
1807       status = mode_select_barcode_param3(s);
1808       if (status != SANE_STATUS_GOOD)
1809 	{
1810 	  DBG(1, "start_setup: mode_select_barcode_param3 failed: %s\n",
1811 	       sane_strstatus(status));
1812 	  return status;
1813 	}
1814     }
1815 
1816   return status;
1817 }
1818 
1819 static SANE_Status
start_scan(BH_Scanner *s)1820 start_scan (BH_Scanner *s)
1821 {
1822   static SANE_Byte cmd[8];
1823   SANE_Status status = SANE_STATUS_GOOD;
1824   SANE_Bool check_adf, duplex;
1825   DBG (3, "start_scan called\n");
1826 
1827   /* SANE front ends will call this function between 'FRAMES'.
1828    * A single scan on the B&H may result in up to 56 different
1829    * things to read (20 are SANE image frames, 36 are non-SANE
1830    * data - decoded bar/patch codes).
1831    */
1832 
1833   if (s->readcnt > 1 && s->scanning == SANE_TRUE)
1834     {
1835       DBG(3, "start_scan: any more items in the readlist?\n");
1836       /* we've been reading data from this scan, so we just
1837        * move on to the next item in the readlist without
1838        * starting a new scan.
1839        */
1840       s->readptr++;
1841       if (s->readptr < s->readcnt)
1842 	{
1843 	  SANE_Byte itemtype;
1844 
1845 	  for (; s->readptr < s->readcnt; s->readptr++)
1846 	    {
1847 
1848 	      itemtype = s->readlist[s->readptr];
1849 
1850 	      DBG(3, "start_scan: advance readlist(%d, %d)\n",
1851 		  s->readptr,
1852 		  (int) itemtype);
1853 
1854 	      /* 'dance' by the non-SANE data streams
1855 	       * like bar/patch code data
1856 	       */
1857 	      if (!BH_HAS_IMAGE_DATA(itemtype))
1858 		{
1859 		  int fd;
1860 		  FILE *fp;
1861 
1862 		  strncpy(s->barfname, "/tmp/bhXXXXXX", sizeof(s->barfname));
1863 		  s->barfname[sizeof(s->barfname)-1] = '\0';
1864 		  fd = mkstemp(s->barfname);
1865 
1866 		  if (fd !=-1 && (fp = fdopen(fd, "w")) != NULL)
1867 		    {
1868 		      fprintf(fp, "<xml-stream>\n");
1869 
1870 		      for (;
1871 			   s->readptr < s->readcnt &&
1872 			     status == SANE_STATUS_GOOD;
1873 			   s->readptr++)
1874 			{
1875 			  if (s->readlist[s->readptr] ==
1876 			      BH_SCSI_READ_TYPE_SENDBARFILE) {
1877 			    break;
1878 			  }
1879 			  status = read_barcode_data(s, fp);
1880 			  if (status != SANE_STATUS_GOOD) break;
1881 			}
1882 
1883 		      fprintf(fp, "</xml-stream>\n");
1884 
1885 		      /* close file; re-open for read(setting s->barfd) */
1886 		      fclose(fp);
1887 		      if ((s->barf = fopen(s->barfname, "r")) == NULL)
1888 			{
1889 			  DBG(1, "sane_start: error opening barfile `%s'\n",
1890 			      s->barfname);
1891 			  status = SANE_STATUS_IO_ERROR;
1892 			}
1893 		    }
1894 		  else
1895 		    {
1896 		      DBG(1, "sane_start: error opening barfile `%s'\n",
1897 			  s->barfname);
1898 		      if (fd !=-1)
1899 		        {
1900 		          close(fd);
1901 		          unlink(s->barfname);
1902 		        }
1903 		      status = SANE_STATUS_IO_ERROR;
1904 		    }
1905 		}
1906 	      else if (itemtype == BH_SCSI_READ_TYPE_FRONT_ICON ||
1907 		       itemtype == BH_SCSI_READ_TYPE_BACK_ICON)
1908 		{
1909 		  /* read the icon header setting the iconwidth and iconlength
1910 		   * to the actual values so get_parameters will have them.
1911 		   * Subsequent calls to sane_read will get pure image data
1912 		   * since the icon header has been consumed.
1913 		   */
1914 
1915 		  status = read_icon_data(s);
1916 		}
1917 
1918 	      if (status == SANE_STATUS_GOOD)
1919 		{
1920 		  /* update our parameters to reflect the new item */
1921 		  status = get_parameters (s, 0);
1922 		}
1923 
1924 	      if (status != SANE_STATUS_GOOD) s->scanning = SANE_FALSE;
1925 
1926 	      return status;
1927 	    }
1928 	  /* if we reach here, we're finished with the readlist and
1929 	   * will drop through to start a new scan
1930 	   */
1931 	}
1932     }
1933 
1934   s->readptr = 0;
1935 
1936   check_adf = _OPT_VAL_WORD(s, OPT_CHECK_ADF);
1937   duplex = _OPT_VAL_WORD(s, OPT_DUPLEX);
1938 
1939   memset (&cmd, 0, sizeof (cmd));
1940   cmd[0] = BH_SCSI_START_SCAN;
1941   cmd[4] = (duplex == SANE_TRUE) ? 2 : 1;
1942 
1943   cmd[6] = 0;
1944   cmd[7] = 1;
1945 
1946   if (check_adf)
1947     {
1948       status = object_position(s);
1949       if (status != SANE_STATUS_GOOD)
1950 	{
1951 	  DBG(3, "object_position: returned %d\n", status);
1952 	  return status;
1953 	}
1954     }
1955 
1956   status = sanei_scsi_cmd (s->fd, &cmd, sizeof (cmd), 0, 0);
1957   if (status == SANE_STATUS_GOOD)
1958     {
1959       s->scanning = SANE_TRUE;
1960 
1961       /* update our parameters,
1962        * now that we're scanning we'll do a GET_WINDOW
1963        */
1964       status = get_parameters (s, 0);
1965       if (status != SANE_STATUS_GOOD)
1966 	{
1967 	  s->scanning = SANE_FALSE;
1968 	}
1969     }
1970 
1971   return status;
1972 }
1973 
1974 /* a sensible sense handler, courtesy of Franck;
1975    arg is a pointer to the associated BH_Scanner structure */
1976 static SANE_Status
sense_handler(int scsi_fd, u_char *result, void *arg)1977 sense_handler (int scsi_fd, u_char *result, void *arg)
1978 {
1979   BH_Scanner *s = (BH_Scanner *) arg;
1980   u_char sense, asc, ascq, EOM, ILI, ErrorCode, ValidData;
1981   u_long InvalidBytes;
1982   char *sense_str = "", *as_str = "";
1983   SANE_Int i;
1984   SANE_Status status = SANE_STATUS_INVAL;
1985   SANE_Char print_sense[(16 * 3) + 1];
1986 
1987   (void) scsi_fd; /* get rid of compiler warning */
1988   ErrorCode = result[0] & 0x7F;
1989   ValidData = (result[0] & 0x80) != 0;
1990   sense = result[2] & 0x0f; /* Key */
1991   asc = result[12]; /* Code */
1992   ascq = result[13]; /* Qual */
1993   EOM = (result[2] & 0x40) != 0; /* End Of Media */
1994   ILI = (result[2] & 0x20) != 0; /* Invalid Length Indicator */
1995   InvalidBytes = ValidData ? _4btol(&result[3]) : 0;
1996 
1997   DBG(3, "sense_handler: result=%x, sense=%x, asc=%x, ascq=%x\n",
1998       result[0], sense, asc, ascq);
1999   DBG(3, "sense_handler: ErrorCode %02x ValidData: %d "
2000       "EOM: %d ILI: %d InvalidBytes: %lu\n",
2001       ErrorCode, ValidData, EOM, ILI, InvalidBytes);
2002 
2003   memset(print_sense, '\0', sizeof(print_sense));
2004   for (i = 0; i < 16; i++)
2005     {
2006       sprintf(print_sense + strlen(print_sense), "%02x ", result[i]);
2007     }
2008   DBG(5, "sense_handler: sense=%s\n", print_sense);
2009 
2010   if (ErrorCode != 0x70 && ErrorCode != 0x71)
2011     {
2012       DBG (3, "sense_handler: error code is invalid.\n");
2013       return SANE_STATUS_IO_ERROR;	/* error code is invalid */
2014     }
2015 
2016   /* handle each sense key;
2017    * RSC supports 0x00, 0x02, 0x03, 0x04, 0x05, 0x06, 0x0B
2018    */
2019   switch (sense)
2020     {
2021     case 0x00:
2022       /* no sense */
2023       sense_str = "No sense.";
2024       status = SANE_STATUS_GOOD;
2025       if (ILI && asc == 0x00 && ascq == 0x05)
2026 	{
2027 	  /* from read_data function */
2028 	  as_str = "ILI bit is set.";
2029 	  if (s != NULL)
2030 	    {
2031 	      s->InvalidBytes = InvalidBytes;
2032 	    }
2033 	  status = SANE_STATUS_GOOD;
2034 	}
2035       else if (EOM && asc == 0x00 && ascq == 0x02)
2036 	{
2037 	  /* from adfStatus or startScan function */
2038 	  as_str = "Out of paper in the hopper.";
2039 	  status = SANE_STATUS_NO_DOCS;
2040 	}
2041       else if (EOM)
2042 	{
2043 	  /* from adfStatus or startScan function */
2044 	  as_str = "Out of paper in the hopper.";
2045 	  status = SANE_STATUS_NO_DOCS;
2046 	}
2047       break;
2048     case 0x01:
2049       /* recovered error */
2050       sense_str = "Recovered error.";
2051       status = SANE_STATUS_GOOD;
2052       break;
2053     case 0x02:
2054       /* not ready */
2055       sense_str = "Not ready.";
2056       status = SANE_STATUS_DEVICE_BUSY;
2057       if (asc == 0x40 && ascq == 0x01)
2058 	{
2059 	  as_str = "P.O.D. error: Scanner not found.";
2060 	  status = SANE_STATUS_INVAL;
2061 	}
2062       else if (asc == 0x40 && ascq == 0x02)
2063 	{
2064 	  as_str = "P.O.D. error: Scanner not ready(paper in transport).";
2065 	  status = SANE_STATUS_DEVICE_BUSY;
2066 	}
2067       else if (asc == 0x40 && ascq == 0x03)
2068 	{
2069 	  as_str = "P.O.D. error: Unknown scanner.";
2070 	  status = SANE_STATUS_INVAL;
2071 	}
2072       break;
2073     case 0x03:
2074       /* medium error */
2075       sense_str = "Medium error.";
2076       status = SANE_STATUS_IO_ERROR;
2077       if (asc == 0x00 && ascq == 0x00)
2078 	{
2079 	  as_str = "Scanner error: paper jam detected.";
2080 	  status = SANE_STATUS_JAMMED;
2081 	}
2082       break;
2083     case 0x04:
2084       /* hardware error */
2085       sense_str = "Hardware error.";
2086       status = SANE_STATUS_IO_ERROR;
2087       if (asc == 0x60 && ascq == 0x00)
2088 	{
2089 	  as_str = "Scanner error: illumination lamps failure.";
2090 	  status = SANE_STATUS_IO_ERROR;
2091 	}
2092       else if (asc == 0x80 && ascq == 0x03)
2093 	{
2094 	  as_str = "Communication error between RSC and scanner.";
2095 	  status = SANE_STATUS_IO_ERROR;
2096 	}
2097       else if (asc == 0x80 && ascq == 0x06)
2098 	{
2099 	  as_str = "Scanner error: page detected but lamps are off.";
2100 	  status = SANE_STATUS_IO_ERROR;
2101 	}
2102       else if (asc == 0x80 && ascq == 0x07)
2103 	{
2104 	  as_str = "Scanner error: camera white level problem.";
2105 	  status = SANE_STATUS_IO_ERROR;
2106 	}
2107       else if (asc == 0x80 && ascq == 0x08)
2108 	{
2109 	  /* could be caught from start_scan or read_data */
2110 	  /* stop button pressed */
2111 	  as_str = "Scanner error: operator pressed the Stop key.";
2112 	  status = SANE_STATUS_NO_DOCS;
2113 	}
2114       else if (asc == 0x80 && ascq == 0x12)
2115 	{
2116 	  as_str = "Scanner error: transport motor failure.";
2117 	  status = SANE_STATUS_IO_ERROR;
2118 	}
2119       else if (asc == 0x80 && ascq == 0x15)
2120 	{
2121 	  as_str = "Scanner error: device / page sensor(s) bouncing.";
2122 	  status = SANE_STATUS_IO_ERROR;
2123 	}
2124       else if (asc == 0x80 && ascq == 0x16)
2125 	{
2126 	  as_str = "Scanner error: feeder is not attached.";
2127 	  status = SANE_STATUS_IO_ERROR;
2128 	}
2129       else if (asc == 0x80 && ascq == 0x18)
2130 	{
2131 	  as_str = "Scanner error: logic system general failure.";
2132 	  status = SANE_STATUS_IO_ERROR;
2133 	}
2134       else if (asc == 0x80 && ascq == 0x34)
2135 	{
2136 	  as_str = "Scanner error: no dual logic communication.";
2137 	  status = SANE_STATUS_IO_ERROR;
2138 	}
2139       break;
2140     case 0x05:
2141       /* illegal request */
2142       sense_str = "Illegal request.";
2143       status = SANE_STATUS_INVAL;
2144       if (asc == 0x1a && ascq == 0x00)
2145 	{
2146 	  as_str = "Parameter list length error.";
2147 	  status = SANE_STATUS_INVAL;
2148 	}
2149       else if (asc == 0x20 && ascq == 0x00)
2150 	{
2151 	  as_str = "Invalid command operation code.";
2152 	  status = SANE_STATUS_INVAL;
2153 	}
2154       else if (asc == 0x24 && ascq == 0x00)
2155 	{
2156 	  /* caught from object_position (via reverse engineering) */
2157 	  /* Not supported? */
2158 	  as_str = "Invalid field in CDB.";
2159 	  status = SANE_STATUS_INVAL;
2160 	}
2161       else if (asc == 0x25 && ascq == 0x00)
2162 	{
2163 	  as_str = "Unsupported LUN.";
2164 	  status = SANE_STATUS_INVAL;
2165 	}
2166       else if (asc == 0x26 && ascq == 0x00)
2167 	{
2168 	  /* caught from mode_select (as well as others) */
2169 	  /* Bar/Patch code detection support not installed */
2170 	  /* See Appendix A, Section A.5 */
2171 	  as_str = "Invalid field in parameter list.";
2172 	  status = SANE_STATUS_INVAL;
2173 	}
2174       else if (asc == 0x2c && ascq == 0x00)
2175 	{
2176 	  /* we were getting this in read_data during the time
2177 	     that the ADF was misbehaving.  Hopefully we will
2178 	     not see it anymore.
2179 	  */
2180 	  as_str = "Command out of sequence.";
2181 	  status = SANE_STATUS_INVAL;
2182 	}
2183       else if (asc == 0x2c && ascq == 0x01)
2184 	{
2185 	  as_str = "Too many windows defined.";
2186 	  status = SANE_STATUS_INVAL;
2187 	}
2188       else if (asc == 0x2c && ascq == 0x02)
2189 	{
2190 	  as_str = "Batch start error.";
2191 	  status = SANE_STATUS_INVAL;
2192 	}
2193       else if (asc == 0x2c && ascq == 0x03)
2194 	{
2195 	  as_str = "Batch abort error.";
2196 	  status = SANE_STATUS_INVAL;
2197 	}
2198       else if (asc == 0x3d && ascq == 0x00)
2199 	{
2200 	  as_str = "Invalid bits in IDENTIFY message.";
2201 	  status = SANE_STATUS_INVAL;
2202 	}
2203       break;
2204     case 0x06:
2205       /* unit attention */
2206       sense_str = "Unit attention.";
2207       status = SANE_STATUS_IO_ERROR;
2208       if (asc == 0x04 && ascq == 0x01)
2209 	{
2210 	  as_str = "Reset detected, LUN is becoming ready.";
2211 	  status = SANE_STATUS_DEVICE_BUSY;
2212 	}
2213       break;
2214     case 0x07:
2215       /* data protect */
2216       sense_str = "Data protect.";
2217       status = SANE_STATUS_IO_ERROR;
2218       break;
2219     case 0x08:
2220       /* blank check */
2221       sense_str = "Blank check.";
2222       status = SANE_STATUS_IO_ERROR;
2223       break;
2224     case 0x09:
2225       /* vendor specific */
2226       sense_str = "Vendor specific.";
2227       status = SANE_STATUS_IO_ERROR;
2228       break;
2229     case 0x0A:
2230       /* copy aborted */
2231       sense_str = "Copy aborted.";
2232       status = SANE_STATUS_IO_ERROR;
2233       break;
2234     case 0x0B:
2235       /* aborted command */
2236       sense_str = "Aborted command.";
2237       status = SANE_STATUS_IO_ERROR;
2238       if (asc == 0x00 && ascq == 0x00)
2239 	{
2240 	  as_str = "Aborted command (unspecified error).";
2241 	  status = SANE_STATUS_IO_ERROR;
2242 	}
2243       else if (asc == 0x08 && ascq == 0x01)
2244 	{
2245 	  /* caught from start_scan */
2246 	  /* manual feed timeout */
2247 	  as_str = "SCSI Time-out, paper Time-out (SCAN command).";
2248 	  status = SANE_STATUS_NO_DOCS;
2249 	}
2250       else if (asc == 0x47 && ascq == 0x00)
2251 	{
2252 	  as_str = "SCSI parity error.";
2253 	  status = SANE_STATUS_IO_ERROR;
2254 	}
2255       else if (asc == 0x80 && ascq == 0x00)
2256 	{
2257 	  as_str = "Aborted command due to memory error.";
2258 	  status = SANE_STATUS_IO_ERROR;
2259 	}
2260       else if (asc == 0x80 && ascq == 0x01)
2261 	{
2262 	  /* caught from read_data */
2263 	  /* section border error; border is outside the main window */
2264 	  /* See Appendix A, Section A.4 */
2265 	  as_str = "Section Read error (out of border).";
2266 	  status = SANE_STATUS_INVAL;
2267 	}
2268       else if (asc == 0x80 && ascq == 0x02)
2269 	{
2270 	  /* caught from read_data */
2271 	  /* No code found; no barcode data is found */
2272 	  /* See Appendix A, Section A.5 */
2273 	  s->barcode_not_found = SANE_TRUE;
2274 	  as_str = "No Bar/Patch Code found.";
2275 	  status = SANE_STATUS_GOOD;
2276 	}
2277       else if (asc == 0x80 && ascq == 0x03)
2278 	{
2279 	  as_str = "Icon Read error (out of border).";
2280 	  status = SANE_STATUS_INVAL;
2281 	}
2282       break;
2283     case 0x0C:
2284       /* equal */
2285       sense_str = "Equal.";
2286       status = SANE_STATUS_IO_ERROR;
2287       break;
2288     case 0x0D:
2289       /* volume overflow */
2290       sense_str = "Volume overflow.";
2291       status = SANE_STATUS_IO_ERROR;
2292       break;
2293     case 0x0E:
2294       /* miscompare */
2295       sense_str = "Miscompare.";
2296       status = SANE_STATUS_IO_ERROR;
2297       break;
2298     case 0x0F:
2299       /* reserved */
2300       sense_str = "Reserved.";
2301       status = SANE_STATUS_IO_ERROR;
2302       break;
2303     default:
2304       sense_str = "Unhandled case.";
2305       status = SANE_STATUS_IO_ERROR;
2306       break;
2307     }
2308 
2309   DBG(3, "sense_handler: '%s' '%s' return:%d\n",
2310       sense_str, as_str, status);
2311 
2312   return status;
2313 }
2314 
2315 static SANE_Status
init_options(BH_Scanner * s)2316 init_options (BH_Scanner * s)
2317 {
2318   int i;
2319   DBG (3, "init_options called\n");
2320 
2321   memset (s->opt, 0, sizeof (s->opt));
2322   memset (s->val, 0, sizeof (s->val));
2323 
2324   for (i = 0; i < NUM_OPTIONS; ++i)
2325     {
2326       s->opt[i].size = sizeof (SANE_Word);
2327       s->opt[i].cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT;
2328     }
2329 
2330   s->opt[OPT_NUM_OPTS].title = SANE_TITLE_NUM_OPTIONS;
2331   s->opt[OPT_NUM_OPTS].desc = SANE_DESC_NUM_OPTIONS;
2332   s->opt[OPT_NUM_OPTS].cap = SANE_CAP_SOFT_DETECT;
2333   s->opt[OPT_NUM_OPTS].type = SANE_TYPE_INT;
2334   s->val[OPT_NUM_OPTS].w = NUM_OPTIONS;
2335 
2336   /* "Scan Mode" group: */
2337   s->opt[OPT_MODE_GROUP].name = "";
2338   s->opt[OPT_MODE_GROUP].title = SANE_TITLE_SCAN_MODE_GROUP;
2339   s->opt[OPT_MODE_GROUP].desc = "";
2340   s->opt[OPT_MODE_GROUP].type = SANE_TYPE_GROUP;
2341   s->opt[OPT_MODE_GROUP].cap = 0;
2342   s->opt[OPT_MODE_GROUP].constraint_type = SANE_CONSTRAINT_NONE;
2343 
2344   /* Preview: */
2345   s->opt[OPT_PREVIEW].name = SANE_NAME_PREVIEW;
2346   s->opt[OPT_PREVIEW].title = SANE_TITLE_PREVIEW;
2347   s->opt[OPT_PREVIEW].desc = SANE_DESC_PREVIEW;
2348   s->opt[OPT_PREVIEW].type = SANE_TYPE_BOOL;
2349   s->opt[OPT_PREVIEW].constraint_type = SANE_CONSTRAINT_NONE;
2350   s->val[OPT_PREVIEW].w = 0;
2351 
2352   /* Inquiry */
2353   s->opt[OPT_INQUIRY].name = SANE_NAME_INQUIRY;
2354   s->opt[OPT_INQUIRY].title = SANE_TITLE_INQUIRY;
2355   s->opt[OPT_INQUIRY].desc = SANE_DESC_INQUIRY;
2356   s->opt[OPT_INQUIRY].type = SANE_TYPE_STRING;
2357   s->opt[OPT_INQUIRY].size = sizeof(inquiry_data);
2358   s->opt[OPT_INQUIRY].constraint_type = SANE_CONSTRAINT_NONE;
2359   s->val[OPT_INQUIRY].s = strdup(inquiry_data);
2360   s->opt[OPT_INQUIRY].cap = SANE_CAP_SOFT_DETECT;
2361 
2362   /* scan mode */
2363   s->opt[OPT_SCAN_MODE].name = SANE_NAME_SCAN_MODE;
2364   s->opt[OPT_SCAN_MODE].title = SANE_TITLE_SCAN_MODE;
2365   s->opt[OPT_SCAN_MODE].desc = SANE_DESC_SCAN_MODE;
2366   s->opt[OPT_SCAN_MODE].type = SANE_TYPE_STRING;
2367   s->opt[OPT_SCAN_MODE].size = max_string_size (scan_mode_list);
2368   s->opt[OPT_SCAN_MODE].constraint_type = SANE_CONSTRAINT_STRING_LIST;
2369   s->opt[OPT_SCAN_MODE].constraint.string_list = scan_mode_list;
2370   s->val[OPT_SCAN_MODE].s = strdup (scan_mode_list[0]);
2371 
2372   /* Standard resolutions */
2373   s->opt[OPT_RESOLUTION].name = SANE_NAME_SCAN_RESOLUTION;
2374   s->opt[OPT_RESOLUTION].title = SANE_TITLE_SCAN_RESOLUTION;
2375   s->opt[OPT_RESOLUTION].desc = SANE_DESC_SCAN_RESOLUTION;
2376   s->opt[OPT_RESOLUTION].type = SANE_TYPE_INT;
2377   s->opt[OPT_RESOLUTION].unit = SANE_UNIT_DPI;
2378   s->opt[OPT_RESOLUTION].constraint_type = SANE_CONSTRAINT_WORD_LIST;
2379   s->opt[OPT_RESOLUTION].constraint.word_list = s->hw->info.resStdList;
2380   s->val[OPT_RESOLUTION].w = s->hw->info.res_default;
2381 
2382   /* compression */
2383   s->opt[OPT_COMPRESSION].name = SANE_NAME_COMPRESSION;
2384   s->opt[OPT_COMPRESSION].title = SANE_TITLE_COMPRESSION;
2385   s->opt[OPT_COMPRESSION].desc = SANE_DESC_COMPRESSION;
2386   s->opt[OPT_COMPRESSION].type = SANE_TYPE_STRING;
2387   s->opt[OPT_COMPRESSION].size = max_string_size (compression_list);
2388   s->opt[OPT_COMPRESSION].constraint_type = SANE_CONSTRAINT_STRING_LIST;
2389   s->opt[OPT_COMPRESSION].constraint.string_list = compression_list;
2390   s->val[OPT_COMPRESSION].s = strdup (compression_list[0]);
2391 
2392   if (s->hw->info.colorHalftone == SANE_FALSE)
2393     {
2394       s->opt[OPT_SCAN_MODE].size = max_string_size (scan_mode_min_list);
2395       s->opt[OPT_SCAN_MODE].constraint.string_list = scan_mode_min_list;
2396     }
2397 
2398   if (s->hw->info.comprG3_1D == SANE_FALSE ||
2399       s->hw->info.comprG3_2D == SANE_FALSE ||
2400       s->hw->info.comprG4 == SANE_FALSE)
2401     {
2402       s->opt[OPT_COMPRESSION].cap |= SANE_CAP_INACTIVE;
2403     }
2404 
2405   /* "Geometry" group: */
2406   s->opt[OPT_GEOMETRY_GROUP].name = "";
2407   s->opt[OPT_GEOMETRY_GROUP].title = SANE_TITLE_GEOMETRY_GROUP;
2408   s->opt[OPT_GEOMETRY_GROUP].desc = "";
2409   s->opt[OPT_GEOMETRY_GROUP].type = SANE_TYPE_GROUP;
2410   s->opt[OPT_GEOMETRY_GROUP].cap = 0;
2411   s->opt[OPT_GEOMETRY_GROUP].constraint_type = SANE_CONSTRAINT_NONE;
2412 
2413   /* Autoborder: */
2414   s->opt[OPT_AUTOBORDER].name = SANE_NAME_AUTOBORDER;
2415   s->opt[OPT_AUTOBORDER].title = SANE_TITLE_AUTOBORDER;
2416   s->opt[OPT_AUTOBORDER].desc = SANE_DESC_AUTOBORDER;
2417   s->opt[OPT_AUTOBORDER].type = SANE_TYPE_BOOL;
2418   s->opt[OPT_AUTOBORDER].constraint_type = SANE_CONSTRAINT_NONE;
2419   s->val[OPT_AUTOBORDER].w = s->hw->info.autoborder_default;
2420 
2421   /* Paper Size */
2422   s->opt[OPT_PAPER_SIZE].name = SANE_NAME_PAPER_SIZE;
2423   s->opt[OPT_PAPER_SIZE].title = SANE_TITLE_PAPER_SIZE;
2424   s->opt[OPT_PAPER_SIZE].desc = SANE_DESC_PAPER_SIZE;
2425   s->opt[OPT_PAPER_SIZE].type = SANE_TYPE_STRING;
2426   s->opt[OPT_PAPER_SIZE].size = max_string_size (paper_list);
2427   s->opt[OPT_PAPER_SIZE].constraint_type = SANE_CONSTRAINT_STRING_LIST;
2428   s->opt[OPT_PAPER_SIZE].constraint.string_list = paper_list;
2429   s->val[OPT_PAPER_SIZE].s = strdup (paper_list[0]);
2430 
2431   /* rotation */
2432   s->opt[OPT_ROTATION].name = SANE_NAME_ROTATION;
2433   s->opt[OPT_ROTATION].title = SANE_TITLE_ROTATION;
2434   s->opt[OPT_ROTATION].desc = SANE_DESC_ROTATION;
2435   s->opt[OPT_ROTATION].type = SANE_TYPE_STRING;
2436   s->opt[OPT_ROTATION].size = max_string_size (rotation_list);
2437   s->opt[OPT_ROTATION].constraint_type = SANE_CONSTRAINT_STRING_LIST;
2438   s->opt[OPT_ROTATION].constraint.string_list = rotation_list;
2439   s->val[OPT_ROTATION].s = strdup (rotation_list[0]);
2440 
2441   /* Deskew: */
2442   s->opt[OPT_DESKEW].name = SANE_NAME_DESKEW;
2443   s->opt[OPT_DESKEW].title = SANE_TITLE_DESKEW;
2444   s->opt[OPT_DESKEW].desc = SANE_DESC_DESKEW;
2445   s->opt[OPT_DESKEW].type = SANE_TYPE_BOOL;
2446   s->opt[OPT_DESKEW].constraint_type = SANE_CONSTRAINT_NONE;
2447   s->val[OPT_DESKEW].w =  s->hw->info.deskew_default;
2448 
2449   /* top-left x */
2450   s->opt[OPT_TL_X].name = SANE_NAME_SCAN_TL_X;
2451   s->opt[OPT_TL_X].title = SANE_TITLE_SCAN_TL_X;
2452   s->opt[OPT_TL_X].desc = SANE_DESC_SCAN_TL_X;
2453   s->opt[OPT_TL_X].type = SANE_TYPE_FIXED;
2454   s->opt[OPT_TL_X].unit = SANE_UNIT_MM;
2455   s->opt[OPT_TL_X].constraint_type = SANE_CONSTRAINT_RANGE;
2456   s->opt[OPT_TL_X].constraint.range = &(s->hw->info.x_range);
2457   s->val[OPT_TL_X].w = SANE_FIX(0.0);
2458 
2459   /* top-left y */
2460   s->opt[OPT_TL_Y].name = SANE_NAME_SCAN_TL_Y;
2461   s->opt[OPT_TL_Y].title = SANE_TITLE_SCAN_TL_Y;
2462   s->opt[OPT_TL_Y].desc = SANE_DESC_SCAN_TL_Y;
2463   s->opt[OPT_TL_Y].type = SANE_TYPE_FIXED;
2464   s->opt[OPT_TL_Y].unit = SANE_UNIT_MM;
2465   s->opt[OPT_TL_Y].constraint_type = SANE_CONSTRAINT_RANGE;
2466   s->opt[OPT_TL_Y].constraint.range = &(s->hw->info.y_range);
2467   s->val[OPT_TL_Y].w = SANE_FIX(0.0);
2468 
2469   /* bottom-right x */
2470   s->opt[OPT_BR_X].name = SANE_NAME_SCAN_BR_X;
2471   s->opt[OPT_BR_X].title = SANE_TITLE_SCAN_BR_X;
2472   s->opt[OPT_BR_X].desc = SANE_DESC_SCAN_BR_X;
2473   s->opt[OPT_BR_X].type = SANE_TYPE_FIXED;
2474   s->opt[OPT_BR_X].unit = SANE_UNIT_MM;
2475   s->opt[OPT_BR_X].constraint_type = SANE_CONSTRAINT_RANGE;
2476   s->opt[OPT_BR_X].constraint.range = &(s->hw->info.x_range);
2477   s->val[OPT_BR_X].w = s->hw->info.x_range.max;
2478 
2479   /* bottom-right y */
2480   s->opt[OPT_BR_Y].name = SANE_NAME_SCAN_BR_Y;
2481   s->opt[OPT_BR_Y].title = SANE_TITLE_SCAN_BR_Y;
2482   s->opt[OPT_BR_Y].desc = SANE_DESC_SCAN_BR_Y;
2483   s->opt[OPT_BR_Y].type = SANE_TYPE_FIXED;
2484   s->opt[OPT_BR_Y].unit = SANE_UNIT_MM;
2485   s->opt[OPT_BR_Y].constraint_type = SANE_CONSTRAINT_RANGE;
2486   s->opt[OPT_BR_Y].constraint.range = &(s->hw->info.y_range);
2487   s->val[OPT_BR_Y].w = s->hw->info.y_range.max;
2488 
2489   if (s->hw->info.canBorderRecog == SANE_FALSE)
2490     {
2491       s->opt[OPT_AUTOBORDER].cap |= SANE_CAP_INACTIVE;
2492     }
2493 
2494   /* "Feeder" group: */
2495   s->opt[OPT_FEEDER_GROUP].name = "";
2496   s->opt[OPT_FEEDER_GROUP].title = SANE_TITLE_FEEDER_GROUP;
2497   s->opt[OPT_FEEDER_GROUP].desc = "";
2498   s->opt[OPT_FEEDER_GROUP].type = SANE_TYPE_GROUP;
2499   s->opt[OPT_FEEDER_GROUP].cap = SANE_CAP_ADVANCED;
2500   s->opt[OPT_FEEDER_GROUP].constraint_type = SANE_CONSTRAINT_NONE;
2501 
2502   /* scan source */
2503   s->opt[OPT_SCAN_SOURCE].name = SANE_NAME_SCAN_SOURCE;
2504   s->opt[OPT_SCAN_SOURCE].title = SANE_TITLE_SCAN_SOURCE;
2505   s->opt[OPT_SCAN_SOURCE].desc = SANE_DESC_SCAN_SOURCE;
2506   s->opt[OPT_SCAN_SOURCE].type = SANE_TYPE_STRING;
2507   s->opt[OPT_SCAN_SOURCE].size = max_string_size (scan_source_list);
2508   s->opt[OPT_SCAN_SOURCE].constraint_type = SANE_CONSTRAINT_STRING_LIST;
2509   s->opt[OPT_SCAN_SOURCE].constraint.string_list = scan_source_list;
2510   s->val[OPT_SCAN_SOURCE].s = strdup (scan_source_list[0]);
2511 
2512   /* Batch: */
2513   s->opt[OPT_BATCH].name = SANE_NAME_BATCH;
2514   s->opt[OPT_BATCH].title = SANE_TITLE_BATCH;
2515   s->opt[OPT_BATCH].desc = SANE_DESC_BATCH;
2516   s->opt[OPT_BATCH].type = SANE_TYPE_BOOL;
2517   s->opt[OPT_BATCH].constraint_type = SANE_CONSTRAINT_NONE;
2518   s->val[OPT_BATCH].w =  s->hw->info.batch_default;
2519 
2520   /* Check ADF: */
2521   s->opt[OPT_CHECK_ADF].name = SANE_NAME_CHECK_ADF;
2522   s->opt[OPT_CHECK_ADF].title = SANE_TITLE_CHECK_ADF;
2523   s->opt[OPT_CHECK_ADF].desc = SANE_DESC_CHECK_ADF;
2524   s->opt[OPT_CHECK_ADF].type = SANE_TYPE_BOOL;
2525   s->opt[OPT_CHECK_ADF].constraint_type = SANE_CONSTRAINT_NONE;
2526   s->val[OPT_CHECK_ADF].w =  s->hw->info.check_adf_default;
2527 
2528   /* Duplex: */
2529   s->opt[OPT_DUPLEX].name = SANE_NAME_DUPLEX;
2530   s->opt[OPT_DUPLEX].title = SANE_TITLE_DUPLEX;
2531   s->opt[OPT_DUPLEX].desc = SANE_DESC_DUPLEX;
2532   s->opt[OPT_DUPLEX].type = SANE_TYPE_BOOL;
2533   s->opt[OPT_DUPLEX].constraint_type = SANE_CONSTRAINT_NONE;
2534   s->val[OPT_DUPLEX].w = s->hw->info.duplex_default;
2535 
2536   /* timeout adf */
2537   s->opt[OPT_TIMEOUT_ADF].name = SANE_NAME_TIMEOUT_ADF;
2538   s->opt[OPT_TIMEOUT_ADF].title = SANE_TITLE_TIMEOUT_ADF;
2539   s->opt[OPT_TIMEOUT_ADF].desc = SANE_DESC_TIMEOUT_ADF;
2540   s->opt[OPT_TIMEOUT_ADF].type = SANE_TYPE_INT;
2541   s->opt[OPT_TIMEOUT_ADF].unit = SANE_UNIT_NONE;
2542   s->opt[OPT_TIMEOUT_ADF].constraint_type = SANE_CONSTRAINT_RANGE;
2543   s->opt[OPT_TIMEOUT_ADF].constraint.range = &u8_range;
2544   s->val[OPT_TIMEOUT_ADF].w =  s->hw->info.timeout_adf_default;
2545 
2546   /* timeout manual */
2547   s->opt[OPT_TIMEOUT_MANUAL].name = SANE_NAME_TIMEOUT_MANUAL;
2548   s->opt[OPT_TIMEOUT_MANUAL].title = SANE_TITLE_TIMEOUT_MANUAL;
2549   s->opt[OPT_TIMEOUT_MANUAL].desc = SANE_DESC_TIMEOUT_MANUAL;
2550   s->opt[OPT_TIMEOUT_MANUAL].type = SANE_TYPE_INT;
2551   s->opt[OPT_TIMEOUT_MANUAL].unit = SANE_UNIT_NONE;
2552   s->opt[OPT_TIMEOUT_MANUAL].constraint_type = SANE_CONSTRAINT_RANGE;
2553   s->opt[OPT_TIMEOUT_MANUAL].constraint.range = &u8_range;
2554   s->val[OPT_TIMEOUT_MANUAL].w =  s->hw->info.timeout_manual_default;
2555 
2556   if (s->hw->info.canCheckADF == SANE_FALSE)
2557     {
2558       s->opt[OPT_CHECK_ADF].cap |= SANE_CAP_INACTIVE;
2559     }
2560 
2561   if (s->hw->info.canDuplex == SANE_FALSE)
2562     {
2563       s->opt[OPT_DUPLEX].cap |= SANE_CAP_INACTIVE;
2564     }
2565 
2566   if (s->hw->info.canADF == SANE_FALSE)
2567     {
2568       s->opt[OPT_TIMEOUT_ADF].cap |= SANE_CAP_INACTIVE;
2569     }
2570 
2571   /* "Enhancement" group: */
2572   s->opt[OPT_ENHANCEMENT_GROUP].name = "";
2573   s->opt[OPT_ENHANCEMENT_GROUP].title = SANE_TITLE_ENHANCEMENT_GROUP;
2574   s->opt[OPT_ENHANCEMENT_GROUP].desc = "";
2575   s->opt[OPT_ENHANCEMENT_GROUP].type = SANE_TYPE_GROUP;
2576   s->opt[OPT_ENHANCEMENT_GROUP].cap = SANE_CAP_ADVANCED;
2577   s->opt[OPT_ENHANCEMENT_GROUP].constraint_type = SANE_CONSTRAINT_NONE;
2578 
2579   /* Control Panel: */
2580   s->opt[OPT_CONTROL_PANEL].name = SANE_NAME_CONTROL_PANEL;
2581   s->opt[OPT_CONTROL_PANEL].title = SANE_TITLE_CONTROL_PANEL;
2582   s->opt[OPT_CONTROL_PANEL].desc = SANE_DESC_CONTROL_PANEL;
2583   s->opt[OPT_CONTROL_PANEL].type = SANE_TYPE_BOOL;
2584   s->opt[OPT_CONTROL_PANEL].constraint_type = SANE_CONSTRAINT_NONE;
2585   s->val[OPT_CONTROL_PANEL].w =  s->hw->info.control_panel_default;
2586 
2587   /* Ace_Function */
2588   s->opt[OPT_ACE_FUNCTION].name = SANE_NAME_ACE_FUNCTION;
2589   s->opt[OPT_ACE_FUNCTION].title = SANE_TITLE_ACE_FUNCTION;
2590   s->opt[OPT_ACE_FUNCTION].desc = SANE_DESC_ACE_FUNCTION;
2591   s->opt[OPT_ACE_FUNCTION].type = SANE_TYPE_INT;
2592   s->opt[OPT_ACE_FUNCTION].unit = SANE_UNIT_NONE;
2593   s->opt[OPT_ACE_FUNCTION].constraint_type = SANE_CONSTRAINT_RANGE;
2594   s->opt[OPT_ACE_FUNCTION].constraint.range = &ace_function_range;
2595   s->val[OPT_ACE_FUNCTION].w = 0;
2596 
2597   /* Ace_Sensitivity */
2598   s->opt[OPT_ACE_SENSITIVITY].name = SANE_NAME_ACE_SENSITIVITY;
2599   s->opt[OPT_ACE_SENSITIVITY].title = SANE_TITLE_ACE_SENSITIVITY;
2600   s->opt[OPT_ACE_SENSITIVITY].desc = SANE_DESC_ACE_SENSITIVITY;
2601   s->opt[OPT_ACE_SENSITIVITY].type = SANE_TYPE_INT;
2602   s->opt[OPT_ACE_SENSITIVITY].unit = SANE_UNIT_NONE;
2603   s->opt[OPT_ACE_SENSITIVITY].constraint_type = SANE_CONSTRAINT_RANGE;
2604   s->opt[OPT_ACE_SENSITIVITY].constraint.range = &ace_sensitivity_range;
2605   s->val[OPT_ACE_SENSITIVITY].w = 4;
2606 
2607   /* Brightness */
2608   s->opt[OPT_BRIGHTNESS].name = SANE_NAME_BRIGHTNESS;
2609   s->opt[OPT_BRIGHTNESS].title = SANE_TITLE_BRIGHTNESS;
2610   s->opt[OPT_BRIGHTNESS].desc = SANE_DESC_BRIGHTNESS;
2611   s->opt[OPT_BRIGHTNESS].type = SANE_TYPE_INT;
2612   s->opt[OPT_BRIGHTNESS].unit = SANE_UNIT_NONE;
2613   s->opt[OPT_BRIGHTNESS].constraint_type = SANE_CONSTRAINT_RANGE;
2614   s->opt[OPT_BRIGHTNESS].constraint.range = &u8_range;
2615   s->val[OPT_BRIGHTNESS].w = 0;
2616 
2617   /* Threshold */
2618   s->opt[OPT_THRESHOLD].name = SANE_NAME_THRESHOLD;
2619   s->opt[OPT_THRESHOLD].title = SANE_TITLE_THRESHOLD;
2620   s->opt[OPT_THRESHOLD].desc = SANE_DESC_THRESHOLD;
2621   s->opt[OPT_THRESHOLD].type = SANE_TYPE_INT;
2622   s->opt[OPT_THRESHOLD].unit = SANE_UNIT_NONE;
2623   s->opt[OPT_THRESHOLD].constraint_type = SANE_CONSTRAINT_RANGE;
2624   s->opt[OPT_THRESHOLD].constraint.range = &u8_range;
2625   s->val[OPT_THRESHOLD].w = 0;
2626 
2627   /* Contrast */
2628   s->opt[OPT_CONTRAST].name = SANE_NAME_CONTRAST;
2629   s->opt[OPT_CONTRAST].title = SANE_TITLE_CONTRAST;
2630   s->opt[OPT_CONTRAST].desc = SANE_DESC_CONTRAST;
2631   s->opt[OPT_CONTRAST].type = SANE_TYPE_INT;
2632   s->opt[OPT_CONTRAST].unit = SANE_UNIT_NONE;
2633   s->opt[OPT_CONTRAST].constraint_type = SANE_CONSTRAINT_RANGE;
2634   s->opt[OPT_CONTRAST].constraint.range = &u8_range;
2635   s->val[OPT_CONTRAST].w = 0;
2636 
2637   /* Negative: */
2638   s->opt[OPT_NEGATIVE].name = SANE_NAME_NEGATIVE;
2639   s->opt[OPT_NEGATIVE].title = SANE_TITLE_NEGATIVE;
2640   s->opt[OPT_NEGATIVE].desc = SANE_DESC_NEGATIVE;
2641   s->opt[OPT_NEGATIVE].type = SANE_TYPE_BOOL;
2642   s->opt[OPT_NEGATIVE].constraint_type = SANE_CONSTRAINT_NONE;
2643   s->val[OPT_NEGATIVE].w = SANE_FALSE;
2644 
2645   /* Contrast is not used in any case; why did we add it? */
2646   s->opt[OPT_CONTRAST].cap |= SANE_CAP_INACTIVE;
2647   if (s->hw->info.control_panel_default == SANE_TRUE)
2648     {
2649       s->opt[OPT_ACE_FUNCTION].cap |= SANE_CAP_INACTIVE;
2650       s->opt[OPT_ACE_SENSITIVITY].cap |= SANE_CAP_INACTIVE;
2651       s->opt[OPT_BRIGHTNESS].cap |= SANE_CAP_INACTIVE;
2652       s->opt[OPT_THRESHOLD].cap |= SANE_CAP_INACTIVE;
2653     }
2654   else if (s->hw->info.canACE == SANE_FALSE)
2655     {
2656       s->opt[OPT_ACE_FUNCTION].cap |= SANE_CAP_INACTIVE;
2657       s->opt[OPT_ACE_SENSITIVITY].cap |= SANE_CAP_INACTIVE;
2658     }
2659   else
2660     {
2661       s->opt[OPT_BRIGHTNESS].cap |= SANE_CAP_INACTIVE;
2662       s->opt[OPT_THRESHOLD].cap |= SANE_CAP_INACTIVE;
2663     }
2664 
2665   /* "ICON" group: */
2666   s->opt[OPT_ICON_GROUP].name = "";
2667   s->opt[OPT_ICON_GROUP].title = SANE_TITLE_ICON_GROUP;
2668   s->opt[OPT_ICON_GROUP].desc = "";
2669   s->opt[OPT_ICON_GROUP].type = SANE_TYPE_GROUP;
2670   s->opt[OPT_ICON_GROUP].cap = SANE_CAP_ADVANCED;
2671   s->opt[OPT_ICON_GROUP].constraint_type = SANE_CONSTRAINT_NONE;
2672 
2673   /* Icon_Width */
2674   s->opt[OPT_ICON_WIDTH].name = SANE_NAME_ICON_WIDTH;
2675   s->opt[OPT_ICON_WIDTH].title = SANE_TITLE_ICON_WIDTH;
2676   s->opt[OPT_ICON_WIDTH].desc = SANE_DESC_ICON_WIDTH;
2677   s->opt[OPT_ICON_WIDTH].type = SANE_TYPE_INT;
2678   s->opt[OPT_ICON_WIDTH].unit = SANE_UNIT_PIXEL;
2679   s->opt[OPT_ICON_WIDTH].constraint_type = SANE_CONSTRAINT_RANGE;
2680   s->opt[OPT_ICON_WIDTH].constraint.range = &icon_range;
2681   s->val[OPT_ICON_WIDTH].w = 0;
2682 
2683   /* Icon_Length */
2684   s->opt[OPT_ICON_LENGTH].name = SANE_NAME_ICON_LENGTH;
2685   s->opt[OPT_ICON_LENGTH].title = SANE_TITLE_ICON_LENGTH;
2686   s->opt[OPT_ICON_LENGTH].desc = SANE_DESC_ICON_LENGTH;
2687   s->opt[OPT_ICON_LENGTH].type = SANE_TYPE_INT;
2688   s->opt[OPT_ICON_LENGTH].unit = SANE_UNIT_PIXEL;
2689   s->opt[OPT_ICON_LENGTH].constraint_type = SANE_CONSTRAINT_RANGE;
2690   s->opt[OPT_ICON_LENGTH].constraint.range = &icon_range;
2691   s->val[OPT_ICON_LENGTH].w = 0;
2692 
2693   if (s->hw->info.canIcon == SANE_FALSE)
2694     {
2695       s->opt[OPT_ICON_GROUP].cap |= SANE_CAP_INACTIVE;
2696       s->opt[OPT_ICON_WIDTH].cap |= SANE_CAP_INACTIVE;
2697       s->opt[OPT_ICON_LENGTH].cap |= SANE_CAP_INACTIVE;
2698     }
2699 
2700   /* "Barcode" group: */
2701   s->opt[OPT_BARCODE_GROUP].name = "";
2702   s->opt[OPT_BARCODE_GROUP].title = SANE_TITLE_BARCODE_GROUP;
2703   s->opt[OPT_BARCODE_GROUP].desc = "";
2704   s->opt[OPT_BARCODE_GROUP].type = SANE_TYPE_GROUP;
2705   s->opt[OPT_BARCODE_GROUP].cap = SANE_CAP_ADVANCED;
2706   s->opt[OPT_BARCODE_GROUP].constraint_type = SANE_CONSTRAINT_NONE;
2707 
2708   /* Add <name> to barcode search priority. */
2709   s->opt[OPT_BARCODE_SEARCH_BAR].name = SANE_NAME_BARCODE_SEARCH_BAR;
2710   s->opt[OPT_BARCODE_SEARCH_BAR].title = SANE_TITLE_BARCODE_SEARCH_BAR;
2711   s->opt[OPT_BARCODE_SEARCH_BAR].desc = SANE_DESC_BARCODE_SEARCH_BAR;
2712   s->opt[OPT_BARCODE_SEARCH_BAR].type = SANE_TYPE_STRING;
2713   s->opt[OPT_BARCODE_SEARCH_BAR].unit = SANE_UNIT_NONE;
2714   s->opt[OPT_BARCODE_SEARCH_BAR].constraint_type = SANE_CONSTRAINT_STRING_LIST;
2715   s->opt[OPT_BARCODE_SEARCH_BAR].constraint.string_list = barcode_search_bar_list;
2716   s->opt[OPT_BARCODE_SEARCH_BAR].size = max_string_size (barcode_search_bar_list);
2717   s->val[OPT_BARCODE_SEARCH_BAR].s = strdup (barcode_search_bar_list[0]);
2718 
2719   /* Barcode search count (1-7, default 1). */
2720   s->opt[OPT_BARCODE_SEARCH_COUNT].name = SANE_NAME_BARCODE_SEARCH_COUNT;
2721   s->opt[OPT_BARCODE_SEARCH_COUNT].title = SANE_TITLE_BARCODE_SEARCH_COUNT;
2722   s->opt[OPT_BARCODE_SEARCH_COUNT].desc = SANE_DESC_BARCODE_SEARCH_COUNT;
2723   s->opt[OPT_BARCODE_SEARCH_COUNT].type = SANE_TYPE_INT;
2724   s->opt[OPT_BARCODE_SEARCH_COUNT].unit = SANE_UNIT_NONE;
2725   s->opt[OPT_BARCODE_SEARCH_COUNT].constraint_type = SANE_CONSTRAINT_RANGE;
2726   s->opt[OPT_BARCODE_SEARCH_COUNT].constraint.range = &barcode_search_count_range;
2727   s->val[OPT_BARCODE_SEARCH_COUNT].w =  3;
2728 
2729   /* Barcode search mode. horiz-vert, horizontal, vertical, vert-horiz */
2730   s->opt[OPT_BARCODE_SEARCH_MODE].name = SANE_NAME_BARCODE_SEARCH_MODE;
2731   s->opt[OPT_BARCODE_SEARCH_MODE].title = SANE_TITLE_BARCODE_SEARCH_MODE;
2732   s->opt[OPT_BARCODE_SEARCH_MODE].desc = SANE_DESC_BARCODE_SEARCH_MODE;
2733   s->opt[OPT_BARCODE_SEARCH_MODE].type = SANE_TYPE_STRING;
2734   s->opt[OPT_BARCODE_SEARCH_MODE].size = max_string_size (barcode_search_mode_list);
2735   s->opt[OPT_BARCODE_SEARCH_MODE].constraint_type = SANE_CONSTRAINT_STRING_LIST;
2736   s->opt[OPT_BARCODE_SEARCH_MODE].constraint.string_list = barcode_search_mode_list;
2737   s->val[OPT_BARCODE_SEARCH_MODE].s = strdup(barcode_search_mode_list[0]);
2738 
2739   /* Patch code min height (def=5mm) */
2740   s->opt[OPT_BARCODE_HMIN].name = SANE_NAME_BARCODE_HMIN;
2741   s->opt[OPT_BARCODE_HMIN].title = SANE_TITLE_BARCODE_HMIN;
2742   s->opt[OPT_BARCODE_HMIN].desc = SANE_DESC_BARCODE_HMIN;
2743   s->opt[OPT_BARCODE_HMIN].type = SANE_TYPE_INT;
2744   s->opt[OPT_BARCODE_HMIN].unit = SANE_UNIT_MM;
2745   s->opt[OPT_BARCODE_HMIN].constraint_type = SANE_CONSTRAINT_RANGE;
2746   s->opt[OPT_BARCODE_HMIN].constraint.range = &barcode_hmin_range;
2747   s->val[OPT_BARCODE_HMIN].w =  5;
2748 
2749   /* Barcode search timeout in ms (20-65535,default is 10000). */
2750   s->opt[OPT_BARCODE_SEARCH_TIMEOUT].name = SANE_NAME_BARCODE_SEARCH_TIMEOUT;
2751   s->opt[OPT_BARCODE_SEARCH_TIMEOUT].title = SANE_TITLE_BARCODE_SEARCH_TIMEOUT;
2752   s->opt[OPT_BARCODE_SEARCH_TIMEOUT].desc = SANE_DESC_BARCODE_SEARCH_TIMEOUT;
2753   s->opt[OPT_BARCODE_SEARCH_TIMEOUT].type = SANE_TYPE_INT;
2754   s->opt[OPT_BARCODE_SEARCH_TIMEOUT].unit = SANE_UNIT_MICROSECOND;
2755   s->opt[OPT_BARCODE_SEARCH_TIMEOUT].constraint_type = SANE_CONSTRAINT_RANGE;
2756   s->opt[OPT_BARCODE_SEARCH_TIMEOUT].constraint.range = &barcode_search_timeout_range;
2757   s->val[OPT_BARCODE_SEARCH_TIMEOUT].w =  10000;
2758 
2759   /* Specify image sections and functions */
2760   s->opt[OPT_SECTION].name = SANE_NAME_SECTION;
2761   s->opt[OPT_SECTION].title = SANE_TITLE_SECTION;
2762   s->opt[OPT_SECTION].desc = SANE_DESC_SECTION;
2763   s->opt[OPT_SECTION].type = SANE_TYPE_STRING;
2764   s->opt[OPT_SECTION].unit = SANE_UNIT_NONE;
2765   s->opt[OPT_SECTION].constraint_type = SANE_CONSTRAINT_NONE;
2766   s->opt[OPT_SECTION].size = 255;
2767   s->val[OPT_SECTION].s = strdup ("");
2768 
2769   /* Barcode_Relmax */
2770   s->opt[OPT_BARCODE_RELMAX].name = SANE_NAME_BARCODE_RELMAX;
2771   s->opt[OPT_BARCODE_RELMAX].title = SANE_TITLE_BARCODE_RELMAX;
2772   s->opt[OPT_BARCODE_RELMAX].desc = SANE_DESC_BARCODE_RELMAX;
2773   s->opt[OPT_BARCODE_RELMAX].type = SANE_TYPE_INT;
2774   s->opt[OPT_BARCODE_RELMAX].unit = SANE_UNIT_NONE;
2775   s->opt[OPT_BARCODE_RELMAX].constraint_type = SANE_CONSTRAINT_RANGE;
2776   s->opt[OPT_BARCODE_RELMAX].constraint.range = &u8_range;
2777   s->val[OPT_BARCODE_RELMAX].w = 0;
2778 
2779   /* Barcode_Barmin */
2780   s->opt[OPT_BARCODE_BARMIN].name = SANE_NAME_BARCODE_BARMIN;
2781   s->opt[OPT_BARCODE_BARMIN].title = SANE_TITLE_BARCODE_BARMIN;
2782   s->opt[OPT_BARCODE_BARMIN].desc = SANE_DESC_BARCODE_BARMIN;
2783   s->opt[OPT_BARCODE_BARMIN].type = SANE_TYPE_INT;
2784   s->opt[OPT_BARCODE_BARMIN].unit = SANE_UNIT_NONE;
2785   s->opt[OPT_BARCODE_BARMIN].constraint_type = SANE_CONSTRAINT_RANGE;
2786   s->opt[OPT_BARCODE_BARMIN].constraint.range = &u8_range;
2787   s->val[OPT_BARCODE_BARMIN].w = 0;
2788 
2789   /* Barcode_Barmax */
2790   s->opt[OPT_BARCODE_BARMAX].name = SANE_NAME_BARCODE_BARMAX;
2791   s->opt[OPT_BARCODE_BARMAX].title = SANE_TITLE_BARCODE_BARMAX;
2792   s->opt[OPT_BARCODE_BARMAX].desc = SANE_DESC_BARCODE_BARMAX;
2793   s->opt[OPT_BARCODE_BARMAX].type = SANE_TYPE_INT;
2794   s->opt[OPT_BARCODE_BARMAX].unit = SANE_UNIT_NONE;
2795   s->opt[OPT_BARCODE_BARMAX].constraint_type = SANE_CONSTRAINT_RANGE;
2796   s->opt[OPT_BARCODE_BARMAX].constraint.range = &u8_range;
2797   s->val[OPT_BARCODE_BARMAX].w = 0;
2798 
2799   /* Barcode_Contrast */
2800   s->opt[OPT_BARCODE_CONTRAST].name = SANE_NAME_BARCODE_CONTRAST;
2801   s->opt[OPT_BARCODE_CONTRAST].title = SANE_TITLE_BARCODE_CONTRAST;
2802   s->opt[OPT_BARCODE_CONTRAST].desc = SANE_DESC_BARCODE_CONTRAST;
2803   s->opt[OPT_BARCODE_CONTRAST].type = SANE_TYPE_INT;
2804   s->opt[OPT_BARCODE_CONTRAST].unit = SANE_UNIT_NONE;
2805   s->opt[OPT_BARCODE_CONTRAST].constraint_type = SANE_CONSTRAINT_RANGE;
2806   s->opt[OPT_BARCODE_CONTRAST].constraint.range = &barcode_contrast_range;
2807   s->val[OPT_BARCODE_CONTRAST].w = 3;
2808 
2809   /* Barcode_Patchmode */
2810   s->opt[OPT_BARCODE_PATCHMODE].name = SANE_NAME_BARCODE_PATCHMODE;
2811   s->opt[OPT_BARCODE_PATCHMODE].title = SANE_TITLE_BARCODE_PATCHMODE;
2812   s->opt[OPT_BARCODE_PATCHMODE].desc = SANE_DESC_BARCODE_PATCHMODE;
2813   s->opt[OPT_BARCODE_PATCHMODE].type = SANE_TYPE_INT;
2814   s->opt[OPT_BARCODE_PATCHMODE].unit = SANE_UNIT_NONE;
2815   s->opt[OPT_BARCODE_PATCHMODE].constraint_type = SANE_CONSTRAINT_RANGE;
2816   s->opt[OPT_BARCODE_PATCHMODE].constraint.range = &barcode_patchmode_range;
2817   s->val[OPT_BARCODE_PATCHMODE].w = 0;
2818 
2819   if (s->hw->info.canSection == SANE_FALSE)
2820     {
2821       s->opt[OPT_SECTION].cap |= SANE_CAP_INACTIVE;
2822     }
2823 
2824   if (s->hw->info.canBarCode == SANE_FALSE)
2825     {
2826       s->opt[OPT_BARCODE_GROUP].cap |= SANE_CAP_INACTIVE;
2827       s->opt[OPT_BARCODE_SEARCH_BAR].cap |= SANE_CAP_INACTIVE;
2828       s->opt[OPT_BARCODE_SEARCH_COUNT].cap |= SANE_CAP_INACTIVE;
2829       s->opt[OPT_BARCODE_SEARCH_MODE].cap |= SANE_CAP_INACTIVE;
2830       s->opt[OPT_BARCODE_HMIN].cap |= SANE_CAP_INACTIVE;
2831       s->opt[OPT_BARCODE_SEARCH_TIMEOUT].cap |= SANE_CAP_INACTIVE;
2832       s->opt[OPT_BARCODE_RELMAX].cap |= SANE_CAP_INACTIVE;
2833       s->opt[OPT_BARCODE_BARMIN].cap |= SANE_CAP_INACTIVE;
2834       s->opt[OPT_BARCODE_BARMAX].cap |= SANE_CAP_INACTIVE;
2835       s->opt[OPT_BARCODE_CONTRAST].cap |= SANE_CAP_INACTIVE;
2836       s->opt[OPT_BARCODE_PATCHMODE].cap |= SANE_CAP_INACTIVE;
2837     }
2838 
2839   return SANE_STATUS_GOOD;
2840 }
2841 
2842 static SANE_Status
attach(const char *devnam, BH_Device ** devp)2843 attach (const char *devnam, BH_Device ** devp)
2844 {
2845   SANE_Status status;
2846   BH_Device *dev;
2847   struct inquiry_standard_data ibuf;
2848   struct inquiry_vpd_data vbuf;
2849   struct inquiry_jis_data jbuf;
2850   size_t buf_size;
2851   int fd = -1;
2852   double mm;
2853 
2854   DBG (3, "attach called\n");
2855 
2856   for (dev = first_dev; dev; dev = dev->next)
2857     {
2858       if (strcmp (dev->sane.name, devnam) == 0)
2859         {
2860           if (devp)
2861             *devp = dev;
2862           return SANE_STATUS_GOOD;
2863         }
2864     }
2865 
2866 #ifdef FAKE_INQUIRY
2867   if (fake_inquiry)
2868     {
2869       DBG (3, "attach: faking inquiry of %s\n", devnam);
2870 
2871       memset (&ibuf, 0, sizeof (ibuf));
2872       ibuf.devtype = 6;
2873       memcpy(ibuf.vendor, "**FAKE**", 8);
2874       memcpy(ibuf.product, "COPISCAN II 6338", 16);
2875       memcpy(ibuf.revision, "0016", 4);
2876 
2877       DBG (1, "attach: reported devtype='%d', vendor='%.8s', "
2878 	   "product='%.16s', revision='%.4s'\n",
2879 	   ibuf.devtype, ibuf.vendor,
2880 	   ibuf.product, ibuf.revision);
2881 
2882       memset (&vbuf, 0, sizeof (vbuf));
2883       memset (&jbuf, 0, sizeof (jbuf));
2884     }
2885   else
2886 #endif
2887     {
2888       DBG (3, "attach: opening %s\n", devnam);
2889       status = sanei_scsi_open (devnam, &fd, sense_handler, NULL);
2890       if (status != SANE_STATUS_GOOD)
2891 	{
2892 	  DBG (1, "attach: open failed: %s\n", sane_strstatus (status));
2893 	  return status;
2894 	}
2895 
2896       DBG (3, "attach: sending TEST_UNIT_READY\n");
2897       status = test_unit_ready (fd);
2898       if (status != SANE_STATUS_GOOD)
2899 	{
2900 	  DBG (1, "attach: test unit ready failed (%s)\n",
2901 	       sane_strstatus (status));
2902 	  sanei_scsi_close (fd);
2903 	  return status;
2904 	}
2905 
2906       DBG (3, "attach: sending INQUIRY (standard data)\n");
2907       memset (&ibuf, 0, sizeof (ibuf));
2908       buf_size = sizeof(ibuf);
2909       status = inquiry (fd, &ibuf, &buf_size, 0,
2910 			BH_INQUIRY_STANDARD_PAGE_CODE);
2911       if (status != SANE_STATUS_GOOD)
2912 	{
2913 	  DBG (1, "attach: inquiry (standard data) failed: %s\n",
2914 	       sane_strstatus (status));
2915 	  sanei_scsi_close (fd);
2916 	  return status;
2917 	}
2918 
2919       DBG (1, "attach: reported devtype='%d', vendor='%.8s', "
2920 	   "product='%.16s', revision='%.4s'\n",
2921 	   ibuf.devtype, ibuf.vendor,
2922 	   ibuf.product, ibuf.revision);
2923 
2924       if (ibuf.devtype != 6
2925 	  || strncmp ((char *)ibuf.vendor, "B&H SCSI", 8) != 0
2926 	  || strncmp ((char *)ibuf.product, "COPISCAN ", 9) != 0)
2927 	{
2928 	  DBG (1,
2929 	       "attach: device is not a recognized Bell and Howell scanner\n");
2930 	  sanei_scsi_close (fd);
2931 	  return SANE_STATUS_INVAL;
2932 	}
2933 
2934       DBG (3, "attach: sending INQUIRY (vpd data)\n");
2935       memset (&vbuf, 0, sizeof (vbuf));
2936       buf_size = sizeof(vbuf);
2937       status = inquiry (fd, &vbuf, &buf_size, 1,
2938 			BH_INQUIRY_VPD_PAGE_CODE);
2939       if (status != SANE_STATUS_GOOD)
2940 	{
2941 	  DBG (1, "attach: inquiry (vpd data) failed: %s\n",
2942 	       sane_strstatus (status));
2943 	  sanei_scsi_close (fd);
2944 	  return status;
2945 	}
2946 
2947       DBG (3, "attach: sending INQUIRY (jis data)\n");
2948       memset (&jbuf, 0, sizeof (jbuf));
2949       buf_size = sizeof(jbuf);
2950       status = inquiry (fd, &jbuf, &buf_size, 1,
2951 			BH_INQUIRY_JIS_PAGE_CODE);
2952       if (status != SANE_STATUS_GOOD)
2953 	{
2954 	  DBG (1, "attach: inquiry (jis data) failed: %s\n",
2955 	       sane_strstatus (status));
2956 	  sanei_scsi_close (fd);
2957 	  return status;
2958 	}
2959 
2960       sanei_scsi_close (fd);
2961     }
2962 
2963   dev = malloc (sizeof (*dev));
2964   if (!dev)
2965     return SANE_STATUS_NO_MEM;
2966   memset (dev, 0, sizeof (*dev));
2967 
2968 
2969   dev->info.devtype = ibuf.devtype;
2970   sprintf(dev->info.vendor, "%.8s", ibuf.vendor);
2971   trim_spaces(dev->info.vendor, sizeof(dev->info.vendor));
2972   sprintf(dev->info.product, "%.16s", ibuf.product);
2973   trim_spaces(dev->info.product, sizeof(dev->info.product));
2974   sprintf(dev->info.revision, "%.4s", ibuf.revision);
2975   trim_spaces(dev->info.revision, sizeof(dev->info.revision));
2976 
2977   dev->sane.name = strdup (devnam);
2978   dev->sane.vendor = strdup(dev->info.vendor);
2979   dev->sane.model = strdup(dev->info.product);;
2980   dev->sane.type = strdup(print_devtype(dev->info.devtype));
2981 
2982   /* set capabilities from vpd */
2983   dev->info.canADF = vbuf.adf & 0x01;
2984   dev->info.colorBandW = vbuf.imagecomposition & 0x01;
2985   dev->info.colorHalftone = vbuf.imagecomposition & 0x02;
2986   dev->info.canWhiteFrame = vbuf.imagedataprocessing[1] & 0x01;
2987   dev->info.canBlackFrame = vbuf.imagedataprocessing[1] & 0x02;
2988   dev->info.canEdgeExtract = vbuf.imagedataprocessing[1] & 0x04;
2989   dev->info.canNoiseFilter = vbuf.imagedataprocessing[1] & 0x08;
2990   dev->info.canSmooth = vbuf.imagedataprocessing[1] & 0x10;
2991   dev->info.canLineBold = vbuf.imagedataprocessing[1] & 0x20;
2992   dev->info.comprG3_1D = vbuf.compression & 0x01;
2993   dev->info.comprG3_2D = vbuf.compression & 0x02;
2994   dev->info.comprG4 = vbuf.compression & 0x04;
2995   dev->info.canBorderRecog = vbuf.sizerecognition & 0x01;
2996   dev->info.canBarCode = vbuf.optionalfeatures & 0x01;
2997   dev->info.canIcon = vbuf.optionalfeatures & 0x02;
2998   dev->info.canSection = vbuf.optionalfeatures & 0x04;
2999   dev->info.lineMaxBytes = _2btol(vbuf.xmaxoutputbytes);
3000 
3001 #ifdef FAKE_INQUIRY
3002   if (fake_inquiry)
3003     {
3004       dev->info.canADF = SANE_FALSE;
3005       dev->info.colorBandW = SANE_TRUE;
3006       dev->info.colorHalftone = SANE_TRUE;
3007       dev->info.canWhiteFrame = SANE_TRUE;
3008       dev->info.canBlackFrame = SANE_TRUE;
3009       dev->info.canEdgeExtract = SANE_TRUE;
3010       dev->info.canNoiseFilter = SANE_TRUE;
3011       dev->info.canSmooth = SANE_TRUE;
3012       dev->info.canLineBold = SANE_TRUE;
3013       dev->info.comprG3_1D = SANE_TRUE;
3014       dev->info.comprG3_2D = SANE_TRUE;
3015       dev->info.comprG4 = SANE_TRUE;
3016       dev->info.canBorderRecog = SANE_TRUE;
3017       dev->info.canBarCode = SANE_TRUE;
3018       dev->info.canIcon = SANE_TRUE;
3019       dev->info.canSection = SANE_TRUE;
3020       dev->info.lineMaxBytes = 450;
3021     }
3022 #endif
3023 
3024   /* set capabilities from jis */
3025   dev->info.resBasicX = _2btol(jbuf.basicxres);
3026   dev->info.resBasicY = _2btol(jbuf.basicyres);
3027   dev->info.resMaxX = _2btol(jbuf.maxxres);
3028   dev->info.resMaxY = _2btol(jbuf.maxyres);
3029   dev->info.resMinX = _2btol(jbuf.minxres);
3030   dev->info.resMinY = _2btol(jbuf.minyres);
3031 
3032   /* set the length of the list to zero first, then append standard resolutions */
3033   dev->info.resStdList[0] = 0;
3034   if (jbuf.standardres[0] & 0x80) appendStdList(&dev->info, 60);
3035   if (jbuf.standardres[0] & 0x40) appendStdList(&dev->info, 75);
3036   if (jbuf.standardres[0] & 0x20) appendStdList(&dev->info, 100);
3037   if (jbuf.standardres[0] & 0x10) appendStdList(&dev->info, 120);
3038   if (jbuf.standardres[0] & 0x08) appendStdList(&dev->info, 150);
3039   if (jbuf.standardres[0] & 0x04) appendStdList(&dev->info, 160);
3040   if (jbuf.standardres[0] & 0x02) appendStdList(&dev->info, 180);
3041   if (jbuf.standardres[0] & 0x01) appendStdList(&dev->info, 200);
3042   if (jbuf.standardres[1] & 0x80) appendStdList(&dev->info, 240);
3043   if (jbuf.standardres[1] & 0x40) appendStdList(&dev->info, 300);
3044   if (jbuf.standardres[1] & 0x20) appendStdList(&dev->info, 320);
3045   if (jbuf.standardres[1] & 0x10) appendStdList(&dev->info, 400);
3046   if (jbuf.standardres[1] & 0x08) appendStdList(&dev->info, 480);
3047   if (jbuf.standardres[1] & 0x04) appendStdList(&dev->info, 600);
3048   if (jbuf.standardres[1] & 0x02) appendStdList(&dev->info, 800);
3049   if (jbuf.standardres[1] & 0x01) appendStdList(&dev->info, 1200);
3050   if (dev->info.resStdList[0] == 0)
3051     {
3052       /* make a default standard resolutions for 200 and 300dpi */
3053       DBG(1, "attach: no standard resolutions reported\n");
3054       dev->info.resStdList[0] = 2;
3055       dev->info.resStdList[1] = 200;
3056       dev->info.resStdList[2] = 300;
3057       dev->info.resBasicX = dev->info.resBasicY = 300;
3058     }
3059 
3060   dev->info.winWidth = _4btol(jbuf.windowwidth);
3061   dev->info.winHeight = _4btol(jbuf.windowlength);
3062 
3063   if (dev->info.winWidth <= 0)
3064     {
3065       dev->info.winWidth = (SANE_Int) (dev->info.resBasicX * 8.5);
3066       DBG(1, "attach: invalid window width reported, using %d\n", dev->info.winWidth);
3067     }
3068   if (dev->info.winHeight <= 0)
3069     {
3070       dev->info.winHeight = dev->info.resBasicY * 14;
3071       DBG(1, "attach: invalid window height reported, using %d\n", dev->info.winHeight);
3072     }
3073 
3074   mm = (dev->info.resBasicX > 0) ?
3075     ((double) dev->info.winWidth / (double) dev->info.resBasicX * MM_PER_INCH) :
3076     0.0;
3077   dev->info.x_range.min = SANE_FIX(0.0);
3078   dev->info.x_range.max = SANE_FIX(mm);
3079   dev->info.x_range.quant = SANE_FIX(0.0);
3080 
3081   mm = (dev->info.resBasicY > 0) ?
3082     ((double) dev->info.winHeight / (double) dev->info.resBasicY * MM_PER_INCH) :
3083     0.0;
3084   dev->info.y_range.min = SANE_FIX(0.0);
3085   dev->info.y_range.max = SANE_FIX(mm);
3086   dev->info.y_range.quant = SANE_FIX(0.0);
3087 
3088   /* set additional discovered/guessed capabilities */
3089 
3090   /* if all of the ACE capabilities are present, declare it ACE capable */
3091   dev->info.canACE = dev->info.canEdgeExtract &&
3092     dev->info.canNoiseFilter &&
3093     dev->info.canSmooth &&
3094     dev->info.canLineBold;
3095 
3096   /* if the model is known to be a duplex, declare it duplex capable */
3097   if (strcmp(dev->info.product, "COPISCAN II 6338") == 0)
3098     {
3099       dev->info.canDuplex = SANE_TRUE;
3100     }
3101   else
3102     {
3103       dev->info.canDuplex = SANE_FALSE;
3104     }
3105 
3106   /* the paper sensor requires RSC revision 1.4 or higher and an
3107    * installed feeder.  NOTE: It also requires SW-4 on and the
3108    * AccufeedPlus feeder, but we cannot discover that.
3109    */
3110   if (strcmp(dev->info.revision, "0014") >= 0)
3111     {
3112       dev->info.canCheckADF = dev->info.canADF;
3113     }
3114   else
3115     {
3116       dev->info.canCheckADF = SANE_FALSE;
3117     }
3118 
3119   /* set option defaults based on inquiry information */
3120   dev->info.res_default = dev->info.resBasicX;
3121   dev->info.autoborder_default = dev->info.canBorderRecog;
3122   dev->info.batch_default = SANE_FALSE;
3123   dev->info.deskew_default = SANE_FALSE;
3124   dev->info.check_adf_default = SANE_FALSE;
3125   dev->info.duplex_default = SANE_FALSE;
3126   dev->info.timeout_adf_default = 0;
3127   dev->info.timeout_manual_default = 0;
3128   dev->info.control_panel_default = dev->info.canACE;
3129 
3130   ++num_devices;
3131   dev->next = first_dev;
3132   first_dev = dev;
3133 
3134   if (devp)
3135     *devp = dev;
3136 
3137   return SANE_STATUS_GOOD;
3138 }
3139 
3140 static SANE_Status
attach_one(const char *devnam)3141 attach_one(const char *devnam)
3142 {
3143   attach (devnam, NULL);
3144   return SANE_STATUS_GOOD;
3145 }
3146 
3147 SANE_Status
sane_init(SANE_Int *version_code, SANE_Auth_Callback authorize)3148 sane_init (SANE_Int *version_code, SANE_Auth_Callback authorize)
3149 {
3150     char devnam[PATH_MAX] = "/dev/scanner";
3151     FILE *fp;
3152 
3153     (void) authorize; /* get rid of compiler warning */
3154 
3155     DBG_INIT();
3156     DBG(3, "sane_init called\n");
3157     DBG(1, "Bell+Howell SANE backend %d.%d build %d %s endian\n",
3158 	SANE_CURRENT_MAJOR, SANE_CURRENT_MINOR, BUILD,
3159 	_is_host_little_endian() ? "little" : "big");
3160 
3161     if (version_code)
3162 	*version_code = SANE_VERSION_CODE (SANE_CURRENT_MAJOR, SANE_CURRENT_MINOR, BUILD);
3163 
3164     fp = sanei_config_open(BH_CONFIG_FILE);
3165     if (fp)
3166 	{
3167 	    char line[PATH_MAX];
3168 	    const char *lp;
3169 	    size_t len;
3170 
3171 	    /* read config file */
3172 	    while (sanei_config_read (line, sizeof (line), fp))
3173 		{
3174 		  if (line[0] == '#')           /* ignore line comments */
3175 		    continue;
3176 		  len = strlen (line);
3177 
3178 		  if (!len)
3179 		    continue;                   /* ignore empty lines */
3180 
3181 		  lp = sanei_config_skip_whitespace (line);
3182 
3183 		  DBG(16,
3184 		      "sane_init: processing config file line '%s'\n",
3185 		      line);
3186 		  if (strncmp(lp, "option", 6) == 0 &&
3187 		      (isspace (lp[6]) || lp[6] == '\0'))
3188 		    {
3189 		      lp += 6;
3190 		      lp = sanei_config_skip_whitespace (lp);
3191 
3192 		      if (strncmp(lp, "disable-optional-frames", 23) == 0)
3193 			{
3194 			  DBG(1, "sane_init: configuration option "
3195 			      "'disable-optional-frames' set\n");
3196 			  disable_optional_frames = 1;
3197 			}
3198 		      else if (strncmp(lp, "fake-inquiry", 12) == 0)
3199 			{
3200 			  DBG(1, "sane_init: configuration option "
3201 			      "'fake-inquiry' set\n");
3202 			  fake_inquiry = 1;
3203 			}
3204 		      else
3205 			{
3206 			  DBG(1, "sane_init: ignoring unknown "
3207 			      "configuration option '%s'\n",
3208 			      lp);
3209 			}
3210 		    }
3211 		  else
3212 		    {
3213 		      DBG(16,
3214 			  "sane_init: found a device: line '%s'\n",
3215 			  lp);
3216 		      strncpy (devnam, lp, sizeof(devnam));
3217 		      devnam[sizeof(devnam)-1] = '\0';
3218 
3219 		      sanei_config_attach_matching_devices(devnam,
3220 							   attach_one);
3221 		    }
3222 		}
3223 	    fclose (fp);
3224 	}
3225     else
3226 	{
3227 	    /* configure the /dev/scanner device in the absence of config file */
3228 	    sanei_config_attach_matching_devices ("/dev/scanner", attach_one);
3229 	}
3230 
3231     return SANE_STATUS_GOOD;
3232 }
3233 
3234 SANE_Status
sane_get_devices(const SANE_Device ***device_list, SANE_Bool local)3235 sane_get_devices (const SANE_Device ***device_list, SANE_Bool local)
3236 {
3237     BH_Device *dev;
3238     int i;
3239     DBG(3, "sane_get_devices called\n");
3240 
3241     (void) local; /* get rid of compiler warning */
3242     if (devlist)
3243 	free (devlist);
3244     devlist = malloc ((num_devices + 1) * sizeof (devlist[0]));
3245     if (!devlist)
3246 	return SANE_STATUS_NO_MEM;
3247 
3248     i = 0;
3249     for (dev = first_dev; dev; dev = dev->next)
3250 	devlist[i++] = &dev->sane;
3251     devlist[i++] = 0;
3252 
3253     *device_list = devlist;
3254 
3255     return SANE_STATUS_GOOD;
3256 }
3257 
3258 SANE_Status
sane_open(SANE_String_Const devnam, SANE_Handle *handle)3259 sane_open (SANE_String_Const devnam, SANE_Handle *handle)
3260 {
3261     SANE_Status status;
3262     BH_Device *dev;
3263     BH_Scanner *s;
3264     DBG(3, "sane_open called\n");
3265 
3266     if (devnam[0] != '\0')
3267 	{
3268 	    for (dev = first_dev; dev; dev = dev->next)
3269 		{
3270 		    if (strcmp (dev->sane.name, devnam) == 0)
3271 		      break;
3272 		}
3273 
3274 	    if (!dev)
3275 		{
3276 		    status = attach (devnam, &dev);
3277 		    if (status != SANE_STATUS_GOOD)
3278 			return status;
3279 		}
3280 	}
3281     else
3282 	{
3283 	    dev = first_dev;
3284 	}
3285 
3286     if (!dev)
3287 	return SANE_STATUS_INVAL;
3288 
3289     s = malloc (sizeof (*s));
3290     if (!s)
3291 	return SANE_STATUS_NO_MEM;
3292     memset (s, 0, sizeof (*s));
3293 
3294     s->fd = -1;
3295     s->hw = dev;
3296 
3297     s->bmu = BH_UNIT_POINT;
3298     s->mud = 1;
3299 
3300     ScannerDump(s);
3301 
3302     init_options (s);
3303 
3304     s->next = first_handle;
3305     first_handle = s;
3306 
3307     /* initialize our parameters */
3308     get_parameters(s, 0);
3309 
3310     *handle = s;
3311 
3312 #ifdef FAKE_INQUIRY
3313     if (fake_inquiry)
3314       {
3315 	DBG (1, "sane_open: faking open of %s\n",
3316 	     s->hw->sane.name);
3317       }
3318     else
3319 #endif
3320       {
3321 	status = sanei_scsi_open (s->hw->sane.name, &s->fd, sense_handler, s);
3322 	if (status != SANE_STATUS_GOOD)
3323 	  {
3324 	    DBG (1, "sane_open: open of %s failed: %s\n",
3325 		 s->hw->sane.name, sane_strstatus (status));
3326 	    return status;
3327 	  }
3328       }
3329 
3330     return SANE_STATUS_GOOD;
3331 }
3332 
3333 const SANE_Option_Descriptor *
sane_get_option_descriptor(SANE_Handle handle, SANE_Int option)3334 sane_get_option_descriptor (SANE_Handle handle, SANE_Int option)
3335 {
3336   BH_Scanner *s = handle;
3337   DBG(3, "sane_get_option_descriptor called (option:%d)\n", option);
3338 
3339   if ((unsigned) option >= NUM_OPTIONS)
3340       return 0;
3341 
3342   return (s->opt + option);
3343 }
3344 
3345 SANE_Status
sane_control_option(SANE_Handle handle, SANE_Int option, SANE_Action action, void *val, SANE_Word *info)3346 sane_control_option (SANE_Handle handle, SANE_Int option, SANE_Action action,
3347 		     void *val, SANE_Word *info)
3348 {
3349   BH_Scanner *s = handle;
3350   SANE_Status status;
3351   SANE_Word cap;
3352   SANE_String_Const name;
3353 
3354   DBG(3, "sane_control_option called\n");
3355 
3356   name = s->opt[option].name ? s->opt[option].name : "(nil)";
3357 
3358   if (info)
3359     *info = 0;
3360 
3361   if (s->scanning && action == SANE_ACTION_SET_VALUE)
3362     return SANE_STATUS_DEVICE_BUSY;
3363   if (option >= NUM_OPTIONS)
3364     return SANE_STATUS_INVAL;
3365 
3366   cap = s->opt[option].cap;
3367   if (!SANE_OPTION_IS_ACTIVE (cap))
3368     return SANE_STATUS_INVAL;
3369 
3370   if (action == SANE_ACTION_GET_VALUE)
3371     {
3372       DBG(16, "sane_control_option: get_value %s [#%d]\n", name, option);
3373       switch (option)
3374 	{
3375 	  /* word options: */
3376 	case OPT_RESOLUTION:
3377 	case OPT_TL_X:
3378 	case OPT_TL_Y:
3379 	case OPT_BR_X:
3380 	case OPT_BR_Y:
3381 	case OPT_TIMEOUT_ADF:
3382 	case OPT_TIMEOUT_MANUAL:
3383 	case OPT_ACE_FUNCTION:
3384 	case OPT_ACE_SENSITIVITY:
3385 	case OPT_BRIGHTNESS:
3386 	case OPT_THRESHOLD:
3387 	case OPT_CONTRAST:
3388 	case OPT_ICON_WIDTH:
3389 	case OPT_ICON_LENGTH:
3390 	case OPT_BARCODE_SEARCH_COUNT:
3391 	case OPT_BARCODE_HMIN:
3392 	case OPT_BARCODE_SEARCH_TIMEOUT:
3393 	case OPT_BARCODE_RELMAX:
3394 	case OPT_BARCODE_BARMIN:
3395 	case OPT_BARCODE_BARMAX:
3396 	case OPT_BARCODE_CONTRAST:
3397 	case OPT_BARCODE_PATCHMODE:
3398 	case OPT_NUM_OPTS:
3399 	  *(SANE_Word *) val = s->val[option].w;
3400 	  return SANE_STATUS_GOOD;
3401 
3402 	  /* string options: */
3403 	case OPT_INQUIRY:
3404 	case OPT_SCAN_SOURCE:
3405 	case OPT_SCAN_MODE:
3406 	case OPT_COMPRESSION:
3407 	case OPT_PAPER_SIZE:
3408 	case OPT_ROTATION:
3409 	case OPT_BARCODE_SEARCH_BAR:
3410 	case OPT_BARCODE_SEARCH_MODE:
3411 	case OPT_SECTION:
3412 	  strcpy (val, s->val[option].s);
3413 	  return SANE_STATUS_GOOD;
3414 
3415 	  /* boolean options: */
3416 	case OPT_PREVIEW:
3417 	case OPT_AUTOBORDER:
3418 	case OPT_DESKEW:
3419 	case OPT_BATCH:
3420 	case OPT_CHECK_ADF:
3421 	case OPT_DUPLEX:
3422 	case OPT_CONTROL_PANEL:
3423 	case OPT_NEGATIVE:
3424 	  *(SANE_Word *) val = s->val[option].w;
3425 	  return SANE_STATUS_GOOD;
3426 
3427 	default:
3428 	  DBG(1, "sane_control_option:invalid option number %d\n", option);
3429 	  return SANE_STATUS_INVAL;
3430 	}
3431     }
3432   else if (action == SANE_ACTION_SET_VALUE)
3433     {
3434       switch (s->opt[option].type)
3435 	{
3436 	case SANE_TYPE_BOOL:
3437 	case SANE_TYPE_INT:
3438 	  DBG(16, "sane_control_option: set_value %s [#%d] to %d\n",
3439 	      name, option, *(SANE_Word *) val);
3440 	  break;
3441 
3442 	case SANE_TYPE_FIXED:
3443 	  DBG(16, "sane_control_option: set_value %s [#%d] to %f\n",
3444 	      name, option, SANE_UNFIX(*(SANE_Word *) val));
3445 	  break;
3446 
3447 	case SANE_TYPE_STRING:
3448 	  DBG(16, "sane_control_option: set_value %s [#%d] to %s\n",
3449 	      name, option, (char *) val);
3450 	  break;
3451 
3452 	default:
3453 	  DBG(16, "sane_control_option: set_value %s [#%d]\n",
3454 	      name, option);
3455 	}
3456 
3457       if (!SANE_OPTION_IS_SETTABLE (cap))
3458 	return SANE_STATUS_INVAL;
3459 
3460       status = sanei_constrain_value (s->opt + option, val, info);
3461       if (status != SANE_STATUS_GOOD)
3462 	return status;
3463 
3464       switch (option)
3465 	{
3466 	  /* (mostly) side-effect-free word options: */
3467 	case OPT_TL_X:
3468 	case OPT_TL_Y:
3469 	case OPT_BR_X:
3470 	case OPT_BR_Y:
3471 	  /* make sure that paper-size is set to custom */
3472 	  if (s->val[option].w != *(SANE_Word *) val)
3473 	    {
3474 	      if (info) *info |= SANE_INFO_RELOAD_PARAMS;
3475 
3476 	      if (get_paper_id(_OPT_VAL_STRING(s, OPT_PAPER_SIZE)) != 0)
3477 		{
3478 		  if (info) *info |= SANE_INFO_RELOAD_OPTIONS;
3479 
3480 		  /* set paper size to 'custom' */
3481 		  free (s->val[OPT_PAPER_SIZE].s);
3482 		  s->val[OPT_PAPER_SIZE].s = strdup(paper_list[0]);
3483 		}
3484 	    }
3485 	  /* fall through */
3486 	case OPT_RESOLUTION:
3487 	  if (info && s->val[option].w != *(SANE_Word *) val)
3488 	    *info |= SANE_INFO_RELOAD_PARAMS;
3489 	  /* fall through */
3490 	case OPT_TIMEOUT_ADF:
3491 	case OPT_TIMEOUT_MANUAL:
3492 	case OPT_ACE_FUNCTION:
3493 	case OPT_ACE_SENSITIVITY:
3494 	case OPT_BRIGHTNESS:
3495 	case OPT_THRESHOLD:
3496 	case OPT_CONTRAST:
3497 	case OPT_ICON_WIDTH:
3498 	case OPT_ICON_LENGTH:
3499 	case OPT_BARCODE_SEARCH_COUNT:
3500 	case OPT_BARCODE_HMIN:
3501 	case OPT_BARCODE_SEARCH_TIMEOUT:
3502 	case OPT_BARCODE_RELMAX:
3503 	case OPT_BARCODE_BARMIN:
3504 	case OPT_BARCODE_BARMAX:
3505 	case OPT_BARCODE_CONTRAST:
3506 	case OPT_BARCODE_PATCHMODE:
3507 	case OPT_NUM_OPTS:
3508 	  s->val[option].w = *(SANE_Word *) val;
3509 	  return SANE_STATUS_GOOD;
3510 
3511 	  /* string options */
3512 	case OPT_BARCODE_SEARCH_BAR:
3513 	  /*!!! we're supporting only a single barcode type via the option */
3514 	  s->search_bars[0] = get_barcode_id(val);
3515 	  /* fall through */
3516 	case OPT_SCAN_SOURCE:
3517 	case OPT_COMPRESSION:
3518 	case OPT_ROTATION:
3519 	case OPT_BARCODE_SEARCH_MODE:
3520 	case OPT_SECTION:
3521 	  if (s->val[option].s)
3522 	    free (s->val[option].s);
3523 	  s->val[option].s = strdup (val);
3524 	  return SANE_STATUS_GOOD;
3525 
3526 	  /* boolean options: */
3527 	case OPT_AUTOBORDER:
3528 	  /*!!! autoborder true disables geometry controls
3529 	   * and sets them to defaults?
3530 	   */
3531 	  /* fall through */
3532 	case OPT_PREVIEW:
3533 	case OPT_BATCH:
3534 	case OPT_DESKEW:
3535 	case OPT_CHECK_ADF:
3536 	case OPT_DUPLEX:
3537 	case OPT_NEGATIVE:
3538 	  s->val[option].w = *(SANE_Word *) val;
3539 	  return SANE_STATUS_GOOD;
3540 
3541 	  /* options with side effects */
3542 	case OPT_CONTROL_PANEL:
3543 	  /* a boolean option */
3544 	  /* control-panel true enables/disables some enhancement controls */
3545 	  if (s->val[option].w != *(SANE_Word *) val)
3546 	    {
3547 	      if (info) *info |= SANE_INFO_RELOAD_OPTIONS;
3548 
3549 	      s->val[option].w = *(SANE_Word *) val;
3550 
3551 	      if (*(SANE_Word *) val == SANE_TRUE)
3552 		{
3553 		  if (s->hw->info.canACE == SANE_TRUE)
3554 		    {
3555 		      s->opt[OPT_ACE_FUNCTION].cap |= SANE_CAP_INACTIVE;
3556 		      s->opt[OPT_ACE_SENSITIVITY].cap |= SANE_CAP_INACTIVE;
3557 		    }
3558 		  else
3559 		    {
3560 		      s->opt[OPT_BRIGHTNESS].cap |= SANE_CAP_INACTIVE;
3561 		      s->opt[OPT_THRESHOLD].cap |= SANE_CAP_INACTIVE;
3562 		    }
3563 		}
3564 	      else
3565 		{
3566 		  if (s->hw->info.canACE == SANE_TRUE)
3567 		    {
3568 		      s->opt[OPT_ACE_FUNCTION].cap &= ~SANE_CAP_INACTIVE;
3569 		      s->opt[OPT_ACE_SENSITIVITY].cap &= ~SANE_CAP_INACTIVE;
3570 		    }
3571 		  else
3572 		    {
3573 		      s->opt[OPT_BRIGHTNESS].cap &= ~SANE_CAP_INACTIVE;
3574 		      s->opt[OPT_THRESHOLD].cap &= ~SANE_CAP_INACTIVE;
3575 		    }
3576 		}
3577 	    }
3578 	  return SANE_STATUS_GOOD;
3579 
3580 	case OPT_SCAN_MODE:
3581 	  /* a string option */
3582 	  /* scan mode != lineart disables compression, setting it to
3583 	   * 'none'
3584 	   */
3585 	  if (strcmp (s->val[option].s, (SANE_String) val))
3586 	    {
3587 	      if (info) *info |= SANE_INFO_RELOAD_OPTIONS;
3588 	      if (get_scan_mode_id((SANE_String) val) != 0)
3589 		{
3590 		  /* scan mode is not lineart, disable compression
3591 		   * and set compression to 'none'
3592 		   */
3593 		  s->opt[OPT_COMPRESSION].cap |= SANE_CAP_INACTIVE;
3594 		  if (s->val[OPT_COMPRESSION].s &&
3595 		      get_compression_id(s->val[OPT_COMPRESSION].s) != 0)
3596 		    {
3597 		      free (s->val[OPT_COMPRESSION].s);
3598 		      s->val[OPT_COMPRESSION].s = strdup(compression_list[0]);
3599 		    }
3600 		}
3601 	      else
3602 		{
3603 		  /* scan mode is lineart, enable compression */
3604 		  s->opt[OPT_COMPRESSION].cap &= ~SANE_CAP_INACTIVE;
3605 		}
3606 	      free (s->val[option].s);
3607 	      s->val[option].s = strdup (val);
3608 	    }
3609 	  return SANE_STATUS_GOOD;
3610 
3611 	case OPT_PAPER_SIZE:
3612 	  /* a string option */
3613 	  /* changes geometry options, therefore _RELOAD_PARAMS and _RELOAD_OPTIONS */
3614 	  if (strcmp (s->val[option].s, (SANE_String) val))
3615 	    {
3616 	      SANE_Int paper_id = get_paper_id((SANE_String) val);
3617 
3618 	      /* paper_id 0 is a special case (custom) that
3619 	       * disables the paper size control of geometry
3620 	       */
3621 	      if (paper_id != 0)
3622 		{
3623 		  double left, x_max, y_max, x, y;
3624 
3625 		  x_max = SANE_UNFIX(s->hw->info.x_range.max);
3626 		  y_max = SANE_UNFIX(s->hw->info.y_range.max);
3627 		  /* a dimension of 0.0 (or less) is replaced with the max value */
3628 		  x = (paper_sizes[paper_id].width <= 0.0) ? x_max :
3629 		    paper_sizes[paper_id].width;
3630 		  y = (paper_sizes[paper_id].length <= 0.0) ? y_max :
3631 		    paper_sizes[paper_id].length;
3632 
3633 		  if (info) *info |= SANE_INFO_RELOAD_PARAMS | SANE_INFO_RELOAD_OPTIONS;
3634 
3635 		  /* set geometry options based on paper size */
3636 		  /* set geometry options based on paper size */
3637 		  if (s->hw->info.canADF)
3638 		    {
3639 		      /* when the feeder is used the paper is centered in the
3640 		       * hopper; with the manual feed it is aligned left.
3641 		       */
3642 		      left = (x_max - x) / 2.0;
3643 		      if (left < 0.0) left = 0.0;
3644 		    }
3645 		  else
3646 		    {
3647 		      left = 0.0;
3648 		    }
3649 
3650 		  s->val[OPT_TL_X].w = SANE_FIX(left);
3651 		  s->val[OPT_TL_Y].w = SANE_FIX(0.0);
3652 		  s->val[OPT_BR_X].w = SANE_FIX(MIN(x + left, x_max));
3653 		  s->val[OPT_BR_Y].w = SANE_FIX(MIN(y, y_max));
3654 		}
3655 	      free (s->val[option].s);
3656 	      s->val[option].s = strdup (val);
3657 	    }
3658 	  return SANE_STATUS_GOOD;
3659 
3660 	default:
3661 	  DBG(1, "sane_control_option:invalid option number %d\n", option);
3662 	  return SANE_STATUS_INVAL;
3663 	}
3664     }
3665 
3666   return SANE_STATUS_INVAL;
3667 }
3668 
3669 SANE_Status
sane_get_parameters(SANE_Handle handle, SANE_Parameters *params)3670 sane_get_parameters (SANE_Handle handle, SANE_Parameters *params)
3671 {
3672   BH_Scanner *s = handle;
3673   SANE_Int status = SANE_STATUS_GOOD;
3674 
3675   DBG(3, "sane_get_parameters called\n");
3676 
3677   if (params)
3678     {
3679       SANE_Int res;
3680 
3681       if (!s->scanning)
3682 	{
3683 	  /* update our parameters ONLY if we're not scanning */
3684 	  status = get_parameters(s, 0);
3685 	}
3686 
3687       *params = s->params;
3688 
3689       res = _OPT_VAL_WORD(s, OPT_RESOLUTION);
3690 
3691       DBG (1, "get_parameters: format=%d, pixels/line=%d, bytes/line=%d, "
3692 	   "lines=%d, dpi=%d\n",
3693 	   (int) s->params.format,
3694 	   s->params.pixels_per_line,
3695 	   s->params.bytes_per_line,
3696 	   s->params.lines,
3697 	   res);
3698     }
3699 
3700   return status;
3701 }
3702 
3703 SANE_Status
sane_start(SANE_Handle handle)3704 sane_start (SANE_Handle handle)
3705 {
3706   BH_Scanner *s = handle;
3707   SANE_Status status;
3708 
3709   DBG(3, "sane_start called\n");
3710   s->cancelled = SANE_FALSE;
3711 
3712   if (s->scanning == SANE_FALSE)
3713     {
3714       /* get preliminary parameters */
3715       status = get_parameters (s, 0);
3716       if (status != SANE_STATUS_GOOD)
3717 	{
3718 	  DBG (1, "sane_start: get_parameters failed: %s\n",
3719 	       sane_strstatus (status));
3720 	  return status;
3721 	}
3722 
3723       /* Do the setup once per 'batch'.  The SANE standard requires the
3724        * frontend to call sane_cancel once all desired frames have been
3725        * acquired.  That is when scanning is set back to SANE_FALSE and
3726        * the 'batch' is considered done.
3727        */
3728       status = start_setup (s);
3729       if (status != SANE_STATUS_GOOD)
3730 	{
3731 	  DBG (1, "sane_start: start_setup failed: %s\n",
3732 	       sane_strstatus (status));
3733 	  return status;
3734 	}
3735     }
3736 
3737   status = start_scan (s);
3738   if (status != SANE_STATUS_GOOD)
3739     {
3740       DBG (1, "sane_start: start_scan failed: %s\n",
3741 	   sane_strstatus (status));
3742       return status;
3743     }
3744 
3745   return SANE_STATUS_GOOD;
3746 }
3747 
3748 SANE_Status
sane_read(SANE_Handle handle, SANE_Byte *buf, SANE_Int maxlen, SANE_Int *len)3749 sane_read (SANE_Handle handle, SANE_Byte *buf, SANE_Int maxlen, SANE_Int *len)
3750 {
3751   BH_Scanner *s = handle;
3752   SANE_Status status;
3753   size_t nread;
3754 
3755   DBG(3, "sane_read called\n");
3756 
3757   *len = 0;
3758 
3759   if (s->cancelled) {
3760     DBG (3, "sane_read: cancelled!\n");
3761     return SANE_STATUS_CANCELLED;
3762   }
3763 
3764   if (!s->scanning) {
3765     DBG (3, "sane_read: scanning is false!\n");
3766     sane_cancel(s);
3767     return SANE_STATUS_CANCELLED;
3768   }
3769 
3770   nread = maxlen;
3771 
3772   DBG (3, "sane_read: request %lu bytes\n", (u_long) nread);
3773   /* set InvalidBytes to 0 before read; sense_handler will set it
3774    * to non-zero if we do the last partial read.
3775    */
3776   s->InvalidBytes = 0;
3777   status = read_data (s, buf, &nread);
3778   if (status != SANE_STATUS_GOOD)
3779     {
3780       DBG (1, "sane_read: read_data failed %s\n",
3781 	   sane_strstatus(status));
3782       sane_cancel (s);
3783       return status;
3784     }
3785   nread = maxlen - s->InvalidBytes;
3786   DBG (3, "sane_read: got %lu bytes\n", (u_long) nread);
3787   *len = nread;
3788 
3789   return (maxlen != 0 && nread == 0) ? SANE_STATUS_EOF : SANE_STATUS_GOOD;
3790 }
3791 
3792 SANE_Status
sane_set_io_mode(SANE_Handle handle, SANE_Bool non_blocking)3793 sane_set_io_mode (SANE_Handle handle, SANE_Bool non_blocking)
3794 {
3795 #ifdef NONBLOCKSUPPORTED
3796   BH_Scanner *s = handle;
3797 #endif
3798   DBG(3, "sane_set_io_mode called: non_blocking=%d\n", non_blocking);
3799 
3800 #ifdef NONBLOCKSUPPORTED
3801   if (s->fd < 0)
3802     {
3803       return SANE_STATUS_INVAL;
3804     }
3805 
3806   if (fcntl (s->fd, F_SETFL, non_blocking ? O_NONBLOCK : 0) < 0)
3807     {
3808       DBG(1, "sane_set_io_mode: error setting io mode\n");
3809       return SANE_STATUS_IO_ERROR;
3810     }
3811 
3812  return SANE_STATUS_GOOD;
3813 #else
3814  (void) handle; /* get rid of compiler warning */
3815  return (non_blocking == 1) ? SANE_STATUS_UNSUPPORTED : SANE_STATUS_GOOD;
3816 #endif
3817 }
3818 
3819 SANE_Status
sane_get_select_fd(SANE_Handle handle, SANE_Int *fd)3820 sane_get_select_fd (SANE_Handle handle, SANE_Int *fd)
3821 {
3822 #ifdef NONBLOCKSUPPORTED
3823   BH_Scanner *s = handle;
3824 #endif
3825   DBG(3, "sane_get_select_fd called\n");
3826 
3827 #ifdef NONBLOCKSUPPORTED
3828   if (s->fd < 0)
3829     {
3830       return SANE_STATUS_INVAL;
3831     }
3832   *fd = s->fd;
3833 
3834   return SANE_STATUS_GOOD;
3835 #else
3836   (void) handle; (void) fd; /* get rid of compiler warning */
3837   return SANE_STATUS_UNSUPPORTED;
3838 #endif
3839 }
3840 
3841 void
sane_cancel(SANE_Handle handle)3842 sane_cancel (SANE_Handle handle)
3843 {
3844   BH_Scanner *s = (BH_Scanner *) handle;
3845   DBG(3, "sane_cancel called\n");
3846   if (s->scanning)
3847     {
3848       /* if batchmode is enabled, then call set_window to
3849        * abort the batch
3850        */
3851       if (_OPT_VAL_WORD(s, OPT_BATCH) == SANE_TRUE)
3852 	{
3853 	  DBG(5, "sane_cancel: calling set_window to abort batch\n");
3854 	  set_window(s, BH_BATCH_ABORT);
3855 	}
3856     }
3857   s->scanning = SANE_FALSE;
3858   s->cancelled = SANE_TRUE;
3859 }
3860 
3861 void
sane_close(SANE_Handle handle)3862 sane_close (SANE_Handle handle)
3863 {
3864   BH_Scanner *s = (BH_Scanner *) handle;
3865   DBG(3, "sane_close called\n");
3866 
3867   if (s->fd != -1)
3868     sanei_scsi_close (s->fd);
3869   s->fd = -1;
3870   free (s);
3871 }
3872 
3873 void
sane_exit(void)3874 sane_exit (void)
3875 {
3876   BH_Device *dev, *next;
3877   DBG(3, "sane_exit called\n");
3878 
3879   for (dev = first_dev; dev; dev = next)
3880     {
3881       next = dev->next;
3882       free (dev);
3883     }
3884 
3885   if (devlist)
3886     free (devlist);
3887 }
3888