• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* sane - Scanner Access Now Easy.
2    Copyright (C) 1997 BYTEC GmbH Germany
3    Written by Helmut Koeberle, Email: helmut.koeberle@bytec.de
4    Modified by Manuel Panea <Manuel.Panea@rzg.mpg.de>
5    and Markus Mertinat <Markus.Mertinat@Physik.Uni-Augsburg.DE>
6    FB620 and FB1200 support by Mitsuru Okaniwa <m-okaniwa@bea.hi-ho.ne.jp>
7    FS2710 support by Ulrich Deiters <ulrich.deiters@uni-koeln.de>
8 
9    backend version: 1.13e
10 
11    This file is part of the SANE package.
12 
13    This program is free software; you can redistribute it and/or
14    modify it under the terms of the GNU General Public License as
15    published by the Free Software Foundation; either version 2 of the
16    License, or (at your option) any later version.
17 
18    This program is distributed in the hope that it will be useful, but
19    WITHOUT ANY WARRANTY; without even the implied warranty of
20    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
21    General Public License for more details.
22 
23    You should have received a copy of the GNU General Public License
24    along with this program.  If not, see <https://www.gnu.org/licenses/>.
25 
26    As a special exception, the authors of SANE give permission for
27    additional uses of the libraries contained in this release of SANE.
28 
29    The exception is that, if you link a SANE library with other files
30    to produce an executable, this does not by itself cause the
31    resulting executable to be covered by the GNU General Public
32    License.  Your use of that executable is in no way restricted on
33    account of linking the SANE library code into it.
34 
35    This exception does not, however, invalidate any other reasons why
36    the executable file might be covered by the GNU General Public
37    License.
38 
39    If you submit changes to SANE to the maintainers to be included in
40    a subsequent release, you agree by submitting the changes that
41    those changes may be distributed with this exception intact.
42 
43    If you write modifications of your own for SANE, it is your choice
44    whether to permit this exception to apply to your modifications.
45    If you do not wish that, delete this exception notice. */
46 
47 /* This file implements the sane-api */
48 
49 /* SANE-FLOW-DIAGRAMM
50 
51    - sane_init() : initialize backend, attach scanners(devicename,0)
52    . - sane_get_devices() : query list of scanner-devices
53    . - sane_open() : open a particular scanner-device and attach_scanner(devicename,&dev)
54    . . - sane_set_io_mode : set blocking-mode
55    . . - sane_get_select_fd : get scanner-fd
56    . . - sane_get_option_descriptor() : get option information
57    . . - sane_control_option() : change option values
58    . .
59    . . - sane_start() : start image acquisition
60    . .   - sane_get_parameters() : returns actual scan-parameters
61    . .   - sane_read() : read image-data (from pipe)
62    . . - sane_cancel() : cancel operation, kill reader_process
63 
64    . - sane_close() : close opened scanner-device, do_cancel, free buffer and handle
65    - sane_exit() : terminate use of backend, free devicename and device-struture
66 */
67 
68 /* This driver's flow:
69 
70  - sane_init
71  . - attach_one
72  . . - inquiry
73  . . - test_unit_ready
74  . . - medium_position
75  . . - extended inquiry
76  . . - mode sense
77  . . - get_density_curve
78  - sane_get_devices
79  - sane_open
80  . - init_options
81  - sane_set_io_mode : set blocking-mode
82  - sane_get_select_fd : get scanner-fd
83  - sane_get_option_descriptor() : get option information
84  - sane_control_option() : change option values
85  - sane_start() : start image acquisition
86    - sane_get_parameters() : returns actual scan-parameters
87    - sane_read() : read image-data (from pipe)
88    - sane_cancel() : cancel operation, kill reader_process
89  - sane_close() : close opened scanner-device, do_cancel, free buffer and handle
90  - sane_exit() : terminate use of backend, free devicename and device-struture
91 */
92 
93 #include "../include/sane/config.h"
94 
95 #include <limits.h>
96 #include <stdlib.h>
97 #include <stdarg.h>
98 #include <string.h>
99 #include <math.h>
100 #include <unistd.h>
101 #include <time.h>
102 
103 #include <fcntl.h> /* for FB1200S */
104 #include <unistd.h> /* for FB1200S */
105 #include <errno.h> /* for FB1200S */
106 
107 #include "../include/sane/sane.h"
108 #include "../include/sane/saneopts.h"
109 #include "../include/sane/sanei_scsi.h"
110 
111 #define BACKEND_NAME canon
112 
113 #include "../include/sane/sanei_backend.h"
114 
115 #ifndef PATH_MAX
116 #define PATH_MAX	1024
117 #endif
118 
119 #include "../include/sane/sanei_config.h"
120 #define CANON_CONFIG_FILE "canon.conf"
121 
122 #include <canon.h>
123 
124 #ifndef SANE_I18N
125 #define SANE_I18N(text)	text
126 #endif
127 
128 
129 static SANE_Byte primaryHigh[256], primaryLow[256], secondaryHigh[256],
130 		 secondaryLow[256];	/* modification for FB1200S */
131 
132 static int num_devices = 0;
133 static CANON_Device *first_dev = NULL;
134 static CANON_Scanner *first_handle = NULL;
135 
136 static const SANE_String_Const mode_list[] = {
137   SANE_VALUE_SCAN_MODE_LINEART,
138   SANE_VALUE_SCAN_MODE_HALFTONE,
139   SANE_VALUE_SCAN_MODE_GRAY,
140   SANE_VALUE_SCAN_MODE_COLOR,
141   0
142 };
143 
144 /* modification for FS2710 */
145 static const SANE_String_Const mode_list_fs2710[] = {
146   SANE_VALUE_SCAN_MODE_COLOR,
147   SANE_I18N("Raw"), 0
148 };
149 
150 /* modification for FB620S */
151 static const SANE_String_Const mode_list_fb620[] = {
152   SANE_VALUE_SCAN_MODE_LINEART,
153   SANE_VALUE_SCAN_MODE_GRAY,
154   SANE_VALUE_SCAN_MODE_COLOR,
155   SANE_I18N("Fine color"), 0
156 };
157 
158 /* modification for FB1200S */
159 static const SANE_String_Const mode_list_fb1200[] = {
160   SANE_VALUE_SCAN_MODE_LINEART,
161   SANE_VALUE_SCAN_MODE_GRAY,
162   SANE_VALUE_SCAN_MODE_COLOR,
163   0
164 };
165 
166 static const SANE_String_Const tpu_dc_mode_list[] = {
167   SANE_I18N("No transparency correction"),
168   SANE_I18N("Correction according to film type"),
169   SANE_I18N("Correction according to transparency ratio"),
170   0
171 };
172 
173 static const SANE_String_Const filmtype_list[] = {
174   SANE_I18N("Negatives"), SANE_I18N("Slides"),
175   0
176 };
177 
178 static const SANE_String_Const negative_filmtype_list[] = {
179   "Kodak", "Fuji", "Agfa", "Konica",
180   0
181 };
182 
183 static const SANE_String_Const scanning_speed_list[] = {
184   SANE_I18N("Automatic"), SANE_I18N("Normal speed"),
185   SANE_I18N("1/2 normal speed"), SANE_I18N("1/3 normal speed"),
186   0
187 };
188 
189 static const SANE_String_Const tpu_filmtype_list[] = {
190   "Film 0", "Film 1", "Film 2", "Film 3",
191   0
192 };
193 
194 /**************************************************/
195 
196 static const SANE_Range u8_range = {
197   0,				/* minimum */
198   255,				/* maximum */
199   0				/* quantization */
200 };
201 
202 #include "canon-scsi.c"
203 
204 /**************************************************************************/
205 
206 static size_t
max_string_size(const SANE_String_Const strings[])207 max_string_size (const SANE_String_Const strings[])
208 {
209   size_t size, max_size = 0;
210   int i;
211   DBG (11, ">> max_string_size\n");
212 
213   for (i = 0; strings[i]; ++i)
214     {
215       size = strlen (strings[i]) + 1;
216       if (size > max_size)
217 	max_size = size;
218     }
219 
220   DBG (11, "<< max_string_size\n");
221   return max_size;
222 }
223 
224 /**************************************************************************/
225 
226 static void
get_tpu_stat(int fd,CANON_Device * dev)227 get_tpu_stat (int fd, CANON_Device * dev)
228 {
229   unsigned char tbuf[12 + 5];
230   size_t buf_size, i;
231   SANE_Status status;
232 
233   DBG (3, ">> get tpu stat\n");
234 
235   memset (tbuf, 0, sizeof (tbuf));
236   buf_size = sizeof (tbuf);
237   status = get_scan_mode (fd, TRANSPARENCY_UNIT, tbuf, &buf_size);
238   if (status != SANE_STATUS_GOOD)
239     {
240       DBG (1, "get scan mode failed: %s\n", sane_strstatus (status));
241       return;
242     }
243 
244   for (i = 0; i < buf_size; i++)
245     DBG (3, "scan mode control byte[%d] = %d\n", (int) i, tbuf[i]);
246   dev->tpu.Status = (tbuf[2 + 4 + 5] >> 7) ?
247     TPU_STAT_INACTIVE : TPU_STAT_NONE;
248   if (dev->tpu.Status != TPU_STAT_NONE)	/* TPU available */
249     {
250       dev->tpu.Status = (tbuf[2 + 4 + 5] & 0x04) ?
251 	TPU_STAT_INACTIVE : TPU_STAT_ACTIVE;
252     }
253   dev->tpu.ControlMode = tbuf[3 + 4 + 5] & 0x03;
254   dev->tpu.Transparency = tbuf[4 + 4 + 5] * 256 + tbuf[5 + 4 + 5];
255   dev->tpu.PosNeg = tbuf[6 + 4 + 5] & 0x01;
256   dev->tpu.FilmType = tbuf[7 + 4 + 5];
257   if(dev->tpu.FilmType > 3)
258     dev->tpu.FilmType = 0;
259 
260   DBG (11, "TPU Status: %d\n", dev->tpu.Status);
261   DBG (11, "TPU ControlMode: %d\n", dev->tpu.ControlMode);
262   DBG (11, "TPU Transparency: %d\n", dev->tpu.Transparency);
263   DBG (11, "TPU PosNeg: %d\n", dev->tpu.PosNeg);
264   DBG (11, "TPU FilmType: %d\n", dev->tpu.FilmType);
265 
266   DBG (3, "<< get tpu stat\n");
267 
268   return;
269 }
270 
271 /**************************************************************************/
272 
273 static void
get_adf_stat(int fd,CANON_Device * dev)274 get_adf_stat (int fd, CANON_Device * dev)
275 {
276   size_t buf_size = 0x0C, i;
277   unsigned char abuf[0x0C];
278   SANE_Status status;
279 
280   DBG (3, ">> get adf stat\n");
281 
282   memset (abuf, 0, buf_size);
283   status = get_scan_mode (fd, AUTO_DOC_FEEDER_UNIT, abuf, &buf_size);
284   if (status != SANE_STATUS_GOOD)
285     {
286       DBG (1, "get scan mode failed: %s\n", sane_strstatus (status));
287       perror ("get scan mode failed");
288       return;
289     }
290 
291   for (i = 0; i < buf_size; i++)
292     DBG (3, "scan mode control byte[%d] = %d\n", (int) i, abuf[i]);
293 
294   dev->adf.Status = (abuf[ADF_Status] & ADF_NOT_PRESENT) ?
295     ADF_STAT_NONE : ADF_STAT_INACTIVE;
296 
297   if (dev->adf.Status != ADF_STAT_NONE)	/* ADF available / INACTIVE */
298     {
299       dev->adf.Status = (abuf[ADF_Status] & ADF_PROBLEM) ?
300 	ADF_STAT_INACTIVE : ADF_STAT_ACTIVE;
301     }
302   dev->adf.Problem = (abuf[ADF_Status] & ADF_PROBLEM);
303   dev->adf.Priority = (abuf[ADF_Settings] & ADF_PRIORITY);
304   dev->adf.Feeder = (abuf[ADF_Settings] & ADF_FEEDER);
305 
306   DBG (11, "ADF Status: %d\n", dev->adf.Status);
307   DBG (11, "ADF Priority: %d\n", dev->adf.Priority);
308   DBG (11, "ADF Problem: %d\n", dev->adf.Problem);
309   DBG (11, "ADF Feeder: %d\n", dev->adf.Feeder);
310 
311   DBG (3, "<< get adf stat\n");
312   return;
313 }
314 
315 /**************************************************************************/
316 
317 static SANE_Status
sense_handler(int scsi_fd,u_char * result,void * arg)318 sense_handler (int scsi_fd, u_char * result, void *arg)
319 {
320   static char me[] = "canon_sense_handler";
321   u_char sense;
322   int asc;
323   char *sense_str = NULL;
324   SANE_Status status;
325 
326   DBG (1, ">> sense_handler\n");
327   DBG (11, "%s(%ld, %p, %p)\n", me, (long) scsi_fd, (void *) result,
328     (void *) arg);
329   DBG (11, "sense buffer: %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x "
330     "%02x %02x %02x %02x %02x %02x\n", result[0], result[1], result[2],
331     result[3], result[4], result[5], result[6], result[7], result[8],
332     result[9], result[10], result[11], result[12], result[13], result[14],
333     result[15]);
334 
335   status = SANE_STATUS_GOOD;
336 
337   DBG(11, "sense data interpretation for SCSI-2 devices\n");
338   sense = result[2] & 0x0f;		/* extract the sense key */
339   if (result[7] > 3)		/* additional sense code available? */
340     {
341       asc = (result[12] << 8) + result[13];	/* 12: additional sense code */
342     }					/* 13: a.s.c. qualifier */
343   else
344     asc = 0xffff;
345 
346   switch (sense)
347     {
348     case 0x00:
349       DBG(11, "sense category: no error\n");
350       status = SANE_STATUS_GOOD;
351       break;
352 
353     case 0x01:
354       DBG(11, "sense category: recovered error\n");
355       switch (asc)
356         {
357         case 0x3700:
358           sense_str = SANE_I18N("rounded parameter");
359           break;
360         default:
361           sense_str = SANE_I18N("unknown");
362         }
363       status = SANE_STATUS_GOOD;
364       break;
365 
366     case 0x03:
367       DBG(11, "sense category: medium error\n");
368       switch (asc)
369         {
370         case 0x8000:
371           sense_str = SANE_I18N("ADF jam");
372           break;
373         case 0x8001:
374           sense_str = SANE_I18N("ADF cover open");
375           break;
376         default:
377           sense_str = SANE_I18N("unknown");
378         }
379       status = SANE_STATUS_IO_ERROR;
380       break;
381 
382     case 0x04:
383       DBG(11, "sense category: hardware error\n");
384       switch (asc)
385         {
386         case 0x6000:
387           sense_str = SANE_I18N("lamp failure");
388           break;
389         case 0x6200:
390           sense_str = SANE_I18N("scan head positioning error");
391           break;
392         case 0x8001:
393           sense_str = SANE_I18N("CPU check error");
394           break;
395         case 0x8002:
396           sense_str = SANE_I18N("RAM check error");
397           break;
398         case 0x8003:
399           sense_str = SANE_I18N("ROM check error");
400           break;
401         case 0x8004:
402           sense_str = SANE_I18N("hardware check error");
403           break;
404         case 0x8005:
405           sense_str = SANE_I18N("transparency unit lamp failure");
406           break;
407         case 0x8006:
408           sense_str = SANE_I18N("transparency unit scan head "
409           "positioning failure");
410           break;
411         default:
412           sense_str = SANE_I18N("unknown");
413         }
414       status = SANE_STATUS_IO_ERROR;
415       break;
416 
417     case 0x05:
418       DBG(11, "sense category: illegal request\n");
419       switch (asc)
420         {
421         case 0x1a00:
422           sense_str = SANE_I18N("parameter list length error");
423           status = SANE_STATUS_IO_ERROR;
424           break;
425         case 0x2000:
426           sense_str = SANE_I18N("invalid command operation code");
427           status = SANE_STATUS_UNSUPPORTED;
428           break;
429         case 0x2400:
430           sense_str = SANE_I18N("invalid field in CDB");
431           status = SANE_STATUS_IO_ERROR;
432           break;
433         case 0x2500:
434           sense_str = SANE_I18N("unsupported LUN");
435           status = SANE_STATUS_UNSUPPORTED;
436           break;
437         case 0x2600:
438           sense_str = SANE_I18N("invalid field in parameter list");
439           status = SANE_STATUS_UNSUPPORTED;
440           break;
441         case 0x2c00:
442           sense_str = SANE_I18N("command sequence error");
443           status = SANE_STATUS_UNSUPPORTED;
444           break;
445         case 0x2c01:
446           sense_str = SANE_I18N("too many windows specified");
447           status = SANE_STATUS_UNSUPPORTED;
448           break;
449         case 0x3a00:
450           sense_str = SANE_I18N("medium not present");
451           status = SANE_STATUS_IO_ERROR;
452           break;
453         case 0x3d00:
454           sense_str = SANE_I18N("invalid bit IDENTIFY message");
455           status = SANE_STATUS_UNSUPPORTED;
456           break;
457         case 0x8002:
458           sense_str = SANE_I18N("option not correct");
459           status = SANE_STATUS_UNSUPPORTED;
460           break;
461         default:
462           sense_str = SANE_I18N("unknown");
463           status = SANE_STATUS_UNSUPPORTED;
464         }
465       break;
466 
467     case 0x06:
468       DBG(11, "sense category: unit attention\n");
469       switch (asc)
470         {
471         case 0x2900:
472           sense_str = SANE_I18N("power on reset / bus device reset");
473           status = SANE_STATUS_GOOD;
474           break;
475         case 0x2a00:
476           sense_str = SANE_I18N("parameter changed by another initiator");
477           status = SANE_STATUS_IO_ERROR;
478           break;
479         default:
480           sense_str = SANE_I18N("unknown");
481           status = SANE_STATUS_IO_ERROR;
482         }
483       break;
484 
485     case 0x0b:
486       DBG(11, "sense category: non-standard\n");
487       switch (asc)
488         {
489         case 0x0000:
490           sense_str = SANE_I18N("no additional sense information");
491           status = SANE_STATUS_IO_ERROR;
492           break;
493         case 0x4500:
494           sense_str = SANE_I18N("reselect failure");
495           status = SANE_STATUS_IO_ERROR;
496           break;
497         case 0x4700:
498           sense_str = SANE_I18N("SCSI parity error");
499           status = SANE_STATUS_IO_ERROR;
500           break;
501         case 0x4800:
502           sense_str = SANE_I18N("initiator detected error message "
503           "received");
504           status = SANE_STATUS_IO_ERROR;
505           break;
506         case 0x4900:
507           sense_str = SANE_I18N("invalid message error");
508           status = SANE_STATUS_UNSUPPORTED;
509           break;
510         case 0x8000:
511           sense_str = SANE_I18N("timeout error");
512           status = SANE_STATUS_IO_ERROR;
513           break;
514         case 0x8001:
515           sense_str = SANE_I18N("transparency unit shading error");
516           status = SANE_STATUS_IO_ERROR;
517           break;
518         case 0x8003:
519           sense_str = SANE_I18N("lamp not stabilized");
520           status = SANE_STATUS_IO_ERROR;
521           break;
522         default:
523           sense_str = SANE_I18N("unknown");
524           status = SANE_STATUS_IO_ERROR;
525         }
526       break;
527     default:
528       DBG(11, "sense category: else\n");
529     }
530   DBG (11, "sense message: %s\n", sense_str);
531 #if 0					/* superfluous? [U.D.] */
532   s->sense_str = sense_str;
533 #endif
534   DBG (1, "<< sense_handler\n");
535   return status;
536 }
537 
538 /***************************************************************/
539 static SANE_Status
do_gamma(CANON_Scanner * s)540 do_gamma (CANON_Scanner * s)
541 {
542   SANE_Status status;
543   u_char gbuf[256];
544   size_t buf_size;
545   int i, j, neg, transfer_data_type, from;
546 
547 
548   DBG (7, "sending SET_DENSITY_CURVE\n");
549   buf_size = 256 * sizeof (u_char);
550   transfer_data_type = 0x03;
551 
552   neg = (s->hw->info.is_filmscanner) ?
553     strcmp (filmtype_list[1], s->val[OPT_NEGATIVE].s)
554     : s->val[OPT_HNEGATIVE].w;
555 
556   if (!strcmp (s->val[OPT_MODE].s, SANE_VALUE_SCAN_MODE_GRAY))
557     {
558       /* If scanning in gray mode, use the first curve for the
559          scanner's monochrome gamma component                    */
560       for (j = 0; j < 256; j++)
561 	{
562 	  if (!neg)
563 	    {
564 	      gbuf[j] = (u_char) s->gamma_table[0][j];
565 	      DBG (22, "set_density %d: gbuf[%d] = [%d]\n", 0, j, gbuf[j]);
566 	    }
567 	  else
568 	    {
569 	      gbuf[255 - j] = (u_char) (255 - s->gamma_table[0][j]);
570 	      DBG (22, "set_density %d: gbuf[%d] = [%d]\n", 0, 255 - j,
571 		   gbuf[255 - j]);
572 	    }
573 	}
574       if ((status = set_density_curve (s->fd, 0, gbuf, &buf_size,
575 	transfer_data_type)) != SANE_STATUS_GOOD)
576 	{
577 	  DBG (7, "SET_DENSITY_CURVE\n");
578 	  sanei_scsi_close (s->fd);
579 	  s->fd = -1;
580 	  return (SANE_STATUS_INVAL);
581 	}
582     }
583   else
584     {				/* colour mode */
585       /* If in RGB mode but with gamma bind, use the first curve
586          for all 3 colors red, green, blue */
587       for (i = 1; i < 4; i++)
588 	{
589 	  from = (s->val[OPT_CUSTOM_GAMMA_BIND].w) ? 0 : i;
590 	  for (j = 0; j < 256; j++)
591 	    {
592 	      if (!neg)
593 		{
594 		  gbuf[j] = (u_char) s->gamma_table[from][j];
595 		  DBG (22, "set_density %d: gbuf[%d] = [%d]\n", i, j, gbuf[j]);
596 		}
597 	      else
598 		{
599 		  gbuf[255 - j] = (u_char) (255 - s->gamma_table[from][j]);
600 		  DBG (22, "set_density %d: gbuf[%d] = [%d]\n", i, 255 - j,
601 		       gbuf[255 - j]);
602 		}
603 	    }
604 	  if (s->hw->info.model == FS2710)
605 	    status = set_density_curve_fs2710 (s, i, gbuf);
606 	  else
607 	    {
608 	      if ((status = set_density_curve (s->fd, i, gbuf, &buf_size,
609 		transfer_data_type)) != SANE_STATUS_GOOD)
610 		{
611 		  DBG (7, "SET_DENSITY_CURVE\n");
612 		  sanei_scsi_close (s->fd);
613 		  s->fd = -1;
614 		  return (SANE_STATUS_INVAL);
615 		}
616 	    }
617 	}
618     }
619 
620   return (SANE_STATUS_GOOD);
621 }
622 
623 /**************************************************************************/
624 
625 static SANE_Status
attach(const char * devnam,CANON_Device ** devp)626 attach (const char *devnam, CANON_Device ** devp)
627 {
628   SANE_Status status;
629   CANON_Device *dev;
630 
631   int fd;
632   u_char ibuf[36], ebuf[74], mbuf[12];
633   size_t buf_size, i;
634   char *str;
635 
636   DBG (1, ">> attach\n");
637 
638   for (dev = first_dev; dev; dev = dev->next)
639     {
640       if (!strcmp (dev->sane.name, devnam))
641 	{
642 	  if (devp) *devp = dev;
643 	  return (SANE_STATUS_GOOD);
644 	}
645     }
646 
647   DBG (3, "attach: opening %s\n", devnam);
648   status = sanei_scsi_open (devnam, &fd, sense_handler, dev);
649   if (status != SANE_STATUS_GOOD)
650     {
651       DBG (1, "attach: open failed: %s\n", sane_strstatus (status));
652       return (status);
653     }
654 
655   DBG (3, "attach: sending (standard) INQUIRY\n");
656   memset (ibuf, 0, sizeof (ibuf));
657   buf_size = sizeof (ibuf);
658   status = inquiry (fd, 0, ibuf, &buf_size);
659   if (status != SANE_STATUS_GOOD)
660     {
661       DBG (1, "attach: inquiry failed: %s\n", sane_strstatus (status));
662       sanei_scsi_close (fd);
663       fd = -1;
664       return (status);
665     }
666 
667   if (ibuf[0] != 6
668       || strncmp ((char *) (ibuf + 8), "CANON", 5) != 0
669       || strncmp ((char *) (ibuf + 16), "IX-", 3) != 0)
670     {
671       DBG (1, "attach: device doesn't look like a Canon scanner\n");
672       sanei_scsi_close (fd);
673       fd = -1;
674       return (SANE_STATUS_INVAL);
675     }
676 
677   DBG (3, "attach: sending TEST_UNIT_READY\n");
678   status = test_unit_ready (fd);
679   if (status != SANE_STATUS_GOOD)
680     {
681       DBG (1, "attach: test unit ready failed (%s)\n",
682 	   sane_strstatus (status));
683       sanei_scsi_close (fd);
684       fd = -1;
685       return (status);
686     }
687 
688 #if 0
689   DBG (3, "attach: sending REQUEST SENSE\n");
690   memset (sbuf, 0, sizeof (sbuf));
691   buf_size = sizeof (sbuf);
692   status = request_sense (fd, sbuf, &buf_size);
693   if (status != SANE_STATUS_GOOD)
694     {
695       DBG (1, "attach: REQUEST_SENSE failed\n");
696       sanei_scsi_close (fd);
697       fd = -1;
698       return (SANE_STATUS_INVAL);
699     }
700 
701   DBG (3, "attach: sending MEDIUM POSITION\n");
702   status = medium_position (fd);
703   if (status != SANE_STATUS_GOOD)
704     {
705       DBG (1, "attach: MEDIUM POSITION failed\n");
706       sanei_scsi_close (fd);
707       fd = -1;
708       return (SANE_STATUS_INVAL);
709     }
710 /*   s->val[OPT_AF_NOW].w == SANE_TRUE; */
711 #endif
712 
713   DBG (3, "attach: sending RESERVE UNIT\n");
714   status = reserve_unit (fd);
715   if (status != SANE_STATUS_GOOD)
716     {
717       DBG (1, "attach: RESERVE UNIT failed\n");
718       sanei_scsi_close (fd);
719       fd = -1;
720       return (SANE_STATUS_INVAL);
721     }
722 
723 #if 0
724   DBG (3, "attach: sending GET SCAN MODE for transparency unit\n");
725   memset (ebuf, 0, sizeof (ebuf));
726   buf_size = sizeof (ebuf);
727   buf_size = 12;
728   status = get_scan_mode (fd, TRANSPARENCY_UNIT, ebuf, &buf_size);
729   if (status != SANE_STATUS_GOOD)
730     {
731       DBG (1, "attach: GET SCAN MODE for transparency unit failed\n");
732       sanei_scsi_close (fd);
733       return (SANE_STATUS_INVAL);
734     }
735   for (i = 0; i < buf_size; i++)
736     DBG(3, "scan mode trans byte[%d] = %d\n", i, ebuf[i]);
737 #endif
738 
739   DBG (3, "attach: sending GET SCAN MODE for scan control conditions\n");
740   memset (ebuf, 0, sizeof (ebuf));
741   buf_size = sizeof (ebuf);
742   status = get_scan_mode (fd, SCAN_CONTROL_CONDITIONS, ebuf, &buf_size);
743   if (status != SANE_STATUS_GOOD)
744     {
745       DBG (1, "attach: GET SCAN MODE for scan control conditions failed\n");
746       sanei_scsi_close (fd);
747       return (SANE_STATUS_INVAL);
748     }
749   for (i = 0; i < buf_size; i++)
750     {
751       DBG (3, "scan mode byte[%d] = %d\n", (int) i, ebuf[i]);
752     }
753 
754   DBG (3, "attach: sending (extended) INQUIRY\n");
755   memset (ebuf, 0, sizeof (ebuf));
756   buf_size = sizeof (ebuf);
757   status = inquiry (fd, 1, ebuf, &buf_size);
758   if (status != SANE_STATUS_GOOD)
759     {
760       DBG (1, "attach: (extended) INQUIRY failed\n");
761       sanei_scsi_close (fd);
762       fd = -1;
763       return (SANE_STATUS_INVAL);
764     }
765 
766 #if 0
767   DBG (3, "attach: sending GET SCAN MODE for transparency unit\n");
768   memset (ebuf, 0, sizeof (ebuf));
769   buf_size = 64;
770   status = get_scan_mode (fd, ALL_SCAN_MODE_PAGES,	/* transparency unit */
771 			  ebuf, &buf_size);
772   if (status != SANE_STATUS_GOOD)
773     {
774       DBG (1, "attach: GET SCAN MODE for scan control conditions failed\n");
775       sanei_scsi_close (fd);
776       return (SANE_STATUS_INVAL);
777     }
778   for (i = 0; i < buf_size; i++)
779     DBG (3, "scan mode control byte[%d] = %d\n", i, ebuf[i]);
780 #endif
781 
782 #if 0
783   DBG (3, "attach: sending GET SCAN MODE for all scan mode pages\n");
784   memset (ebuf, 0, sizeof (ebuf));
785   buf_size = 32;
786   status = get_scan_mode (fd, (u_char)ALL_SCAN_MODE_PAGES, ebuf, &buf_size);
787   if (status != SANE_STATUS_GOOD)
788     {
789       DBG (1, "attach: GET SCAN MODE for scan control conditions failed\n");
790       sanei_scsi_close (fd);
791       return (SANE_STATUS_INVAL);
792     }
793   for (i = 0; i < buf_size; i++)
794     DBG(3, "scan mode control byte[%d] = %d\n", i, ebuf[i]);
795 #endif
796 
797   DBG (3, "attach: sending MODE SENSE\n");
798   memset (mbuf, 0, sizeof (mbuf));
799   buf_size = sizeof (mbuf);
800   status = mode_sense (fd, mbuf, &buf_size);
801   if (status != SANE_STATUS_GOOD)
802     {
803       DBG (1, "attach: MODE_SENSE failed\n");
804       sanei_scsi_close (fd);
805       fd = -1;
806       return (SANE_STATUS_INVAL);
807     }
808 
809   dev = malloc (sizeof (*dev));
810   if (!dev)
811     {
812       sanei_scsi_close (fd);
813       fd = -1;
814       return (SANE_STATUS_NO_MEM);
815     }
816   memset (dev, 0, sizeof (*dev));
817 
818   dev->sane.name = strdup (devnam);
819   dev->sane.vendor = "CANON";
820   if ((str = strndup ((char *) ibuf + 16, 16)) == NULL)
821     {
822       sanei_scsi_close (fd);
823       fd = -1;
824       return (SANE_STATUS_NO_MEM);
825     }
826 
827   /* Register the fixed properties of the scanner below:
828      - whether it is a film scanner or a flatbed scanner
829      - whether it can have an automatic document feeder (ADF)
830      - whether it can be equipped with a transparency unit (TPU)
831      - whether it has got focus control
832      - whether it can optimize image parameters (autoexposure)
833      - whether it can calibrate itself
834      - whether it can diagnose itself
835      - whether it can eject the media
836      - whether it can mirror the scanned data
837      - whether it is a film scanner (or can be used as one)
838      - whether it has fixed, hardware-set scan resolutions only
839   */
840   if (!strncmp (str, "IX-27015", 8))		/* FS2700S */
841     {
842       dev->info.model = CS2700;
843       dev->sane.model = strdup("FS2700S");
844       dev->sane.type = SANE_I18N("film scanner");
845       dev->adf.Status = ADF_STAT_NONE;
846       dev->tpu.Status = TPU_STAT_NONE;
847       dev->info.can_focus = SANE_TRUE;
848       dev->info.can_autoexpose = SANE_TRUE;
849       dev->info.can_calibrate = SANE_FALSE;
850       dev->info.can_diagnose = SANE_FALSE;
851       dev->info.can_eject = SANE_TRUE;
852       dev->info.can_mirror = SANE_TRUE;
853       dev->info.is_filmscanner = SANE_TRUE;
854       dev->info.has_fixed_resolutions = SANE_TRUE;
855     }
856   else if (!strncmp (str, "IX-27025E", 9))	/* FS2710S */
857     {
858       dev->info.model = FS2710;
859       dev->sane.model = strdup("FS2710S");
860       dev->sane.type = SANE_I18N("film scanner");
861       dev->adf.Status = ADF_STAT_NONE;
862       dev->tpu.Status = TPU_STAT_NONE;
863       dev->info.can_focus = SANE_TRUE;
864       dev->info.can_autoexpose = SANE_TRUE;
865       dev->info.can_calibrate = SANE_FALSE;
866       dev->info.can_diagnose = SANE_FALSE;
867       dev->info.can_eject = SANE_TRUE;
868       dev->info.can_mirror = SANE_TRUE;
869       dev->info.is_filmscanner = SANE_TRUE;
870       dev->info.has_fixed_resolutions = SANE_TRUE;
871     }
872   else if (!strncmp (str, "IX-06035E", 9))	/* FB620S */
873     {
874       dev->info.model = FB620;
875       dev->sane.model = strdup("FB620S");
876       dev->sane.type = SANE_I18N("flatbed scanner");
877       dev->adf.Status = ADF_STAT_NONE;
878       dev->tpu.Status = TPU_STAT_NONE;
879       dev->info.can_focus = SANE_FALSE;
880       dev->info.can_autoexpose = SANE_FALSE;
881       dev->info.can_calibrate = SANE_TRUE;
882       dev->info.can_diagnose = SANE_TRUE;
883       dev->info.can_eject = SANE_FALSE;
884       dev->info.can_mirror = SANE_FALSE;
885       dev->info.is_filmscanner = SANE_FALSE;
886       dev->info.has_fixed_resolutions = SANE_TRUE;
887     }
888   else if (!strncmp (str, "IX-12015E", 9))	/* FB1200S */
889     {
890       dev->info.model = FB1200;
891       dev->sane.model = strdup("FB1200S");
892       dev->sane.type = SANE_I18N("flatbed scanner");
893       dev->adf.Status = ADF_STAT_INACTIVE;
894       dev->tpu.Status = TPU_STAT_INACTIVE;
895       dev->info.can_focus = SANE_FALSE;
896       dev->info.can_autoexpose = SANE_FALSE;
897       dev->info.can_calibrate = SANE_FALSE;
898       dev->info.can_diagnose = SANE_FALSE;
899       dev->info.can_eject = SANE_FALSE;
900       dev->info.can_mirror = SANE_FALSE;
901       dev->info.is_filmscanner = SANE_FALSE;
902       dev->info.has_fixed_resolutions = SANE_TRUE;
903     }
904   else if (!strncmp (str, "IX-4015", 7))	/* IX-4015 */
905     {
906       dev->info.model = IX4015;
907       dev->sane.type = SANE_I18N("flatbed scanner");
908       dev->adf.Status = ADF_STAT_INACTIVE;
909       dev->tpu.Status = TPU_STAT_INACTIVE;
910       dev->info.can_focus = SANE_FALSE;
911       dev->info.can_autoexpose = SANE_TRUE;
912       dev->info.can_calibrate = SANE_FALSE;
913       dev->info.can_diagnose = SANE_TRUE;
914       dev->info.can_eject = SANE_FALSE;
915       dev->info.can_mirror = SANE_TRUE;
916       dev->info.is_filmscanner = SANE_FALSE;
917       dev->info.has_fixed_resolutions = SANE_FALSE;
918     }
919   else						/* CS300, CS600 */
920     {
921       dev->info.model = CS3_600;
922       dev->sane.type = SANE_I18N("flatbed scanner");
923       dev->adf.Status = ADF_STAT_INACTIVE;
924       dev->tpu.Status = TPU_STAT_INACTIVE;
925       dev->info.can_focus = SANE_FALSE;
926       dev->info.can_autoexpose = SANE_FALSE;
927       dev->info.can_calibrate = SANE_FALSE;
928       dev->info.can_diagnose = SANE_FALSE;
929       dev->info.can_eject = SANE_FALSE;
930       dev->info.can_mirror = SANE_TRUE;
931       dev->info.is_filmscanner = SANE_FALSE;
932       dev->info.has_fixed_resolutions = SANE_FALSE;
933     }
934 
935   /*
936    * Use the model from the device if we don't have more
937    * common model name for the device, otherwise free the
938    * string with internal model name.
939    *
940    * Please keep the memory allocation source consistent
941    * for model string - allocate on the heap via dynamic
942    * allocation.
943    */
944   if (dev->sane.model == NULL)
945     dev->sane.model = str;
946   else
947     free(str);
948 
949   DBG (5, "dev->sane.name = '%s'\n", dev->sane.name);
950   DBG (5, "dev->sane.vendor = '%s'\n", dev->sane.vendor);
951   DBG (5, "dev->sane.model = '%s'\n", dev->sane.model);
952   DBG (5, "dev->sane.type = '%s'\n", dev->sane.type);
953 
954   if (dev->tpu.Status != TPU_STAT_NONE)
955     get_tpu_stat (fd, dev);		/* Query TPU */
956   if (dev->adf.Status != ADF_STAT_NONE)
957     get_adf_stat (fd, dev);		/* Query ADF */
958 
959   dev->info.bmu = mbuf[6];
960   DBG (5, "bmu=%d\n", dev->info.bmu);
961   dev->info.mud = (mbuf[8] << 8) + mbuf[9];
962   DBG (5, "mud=%d\n", dev->info.mud);
963 
964   dev->info.xres_default = (ebuf[5] << 8) + ebuf[6];
965   DBG (5, "xres_default=%d\n", dev->info.xres_default);
966   dev->info.xres_range.max = (ebuf[10] << 8) + ebuf[11];
967   DBG (5, "xres_range.max=%d\n", dev->info.xres_range.max);
968   dev->info.xres_range.min = (ebuf[14] << 8) + ebuf[15];
969   DBG (5, "xres_range.min=%d\n", dev->info.xres_range.min);
970   dev->info.xres_range.quant = ebuf[9] >> 4;
971   DBG (5, "xres_range.quant=%d\n", dev->info.xres_range.quant);
972 
973   dev->info.yres_default = (ebuf[7] << 8) + ebuf[8];
974   DBG (5, "yres_default=%d\n", dev->info.yres_default);
975   dev->info.yres_range.max = (ebuf[12] << 8) + ebuf[13];
976   DBG (5, "yres_range.max=%d\n", dev->info.yres_range.max);
977   dev->info.yres_range.min = (ebuf[16] << 8) + ebuf[17];
978   DBG (5, "yres_range.min=%d\n", dev->info.yres_range.min);
979   dev->info.yres_range.quant = ebuf[9] & 0x0f;
980   DBG (5, "xres_range.quant=%d\n", dev->info.xres_range.quant);
981 
982   dev->info.x_range.min = SANE_FIX (0.0);
983   dev->info.x_range.max = (ebuf[20] << 24) + (ebuf[21] << 16)
984     + (ebuf[22] << 8) + ebuf[23] - 1;
985   dev->info.x_range.max =
986     SANE_FIX (dev->info.x_range.max * MM_PER_INCH / dev->info.mud);
987   DBG (5, "x_range.max=%d\n", dev->info.x_range.max);
988   dev->info.x_range.quant = 0;
989 
990   dev->info.y_range.min = SANE_FIX (0.0);
991   dev->info.y_range.max = (ebuf[24] << 24) + (ebuf[25] << 16)
992     + (ebuf[26] << 8) + ebuf[27] - 1;
993   dev->info.y_range.max =
994     SANE_FIX (dev->info.y_range.max * MM_PER_INCH / dev->info.mud);
995   DBG (5, "y_range.max=%d\n", dev->info.y_range.max);
996   dev->info.y_range.quant = 0;
997 
998   dev->info.x_adf_range.max = (ebuf[30] << 24) + (ebuf[31] << 16)
999     + (ebuf[32] << 8) + ebuf[33] - 1;
1000   DBG (5, "x_adf_range.max=%d\n", dev->info.x_adf_range.max);
1001   dev->info.y_adf_range.max = (ebuf[34] << 24) + (ebuf[35] << 16)
1002     + (ebuf[36] << 8) + ebuf[37] - 1;
1003   DBG (5, "y_adf_range.max=%d\n", dev->info.y_adf_range.max);
1004 
1005   dev->info.brightness_range.min = 0;
1006   dev->info.brightness_range.max = 255;
1007   dev->info.brightness_range.quant = 0;
1008 
1009   dev->info.contrast_range.min = 1;
1010   dev->info.contrast_range.max = 255;
1011   dev->info.contrast_range.quant = 0;
1012 
1013   dev->info.threshold_range.min = 1;
1014   dev->info.threshold_range.max = 255;
1015   dev->info.threshold_range.quant = 0;
1016 
1017   dev->info.HiliteR_range.min = 0;
1018   dev->info.HiliteR_range.max = 255;
1019   dev->info.HiliteR_range.quant = 0;
1020 
1021   dev->info.ShadowR_range.min = 0;
1022   dev->info.ShadowR_range.max = 254;
1023   dev->info.ShadowR_range.quant = 0;
1024 
1025   dev->info.HiliteG_range.min = 0;
1026   dev->info.HiliteG_range.max = 255;
1027   dev->info.HiliteG_range.quant = 0;
1028 
1029   dev->info.ShadowG_range.min = 0;
1030   dev->info.ShadowG_range.max = 254;
1031   dev->info.ShadowG_range.quant = 0;
1032 
1033   dev->info.HiliteB_range.min = 0;
1034   dev->info.HiliteB_range.max = 255;
1035   dev->info.HiliteB_range.quant = 0;
1036 
1037   dev->info.ShadowB_range.min = 0;
1038   dev->info.ShadowB_range.max = 254;
1039   dev->info.ShadowB_range.quant = 0;
1040 
1041   dev->info.focus_range.min = 0;
1042   dev->info.focus_range.max = 255;
1043   dev->info.focus_range.quant = 0;
1044 
1045   dev->info.TPU_Transparency_range.min = 0;
1046   dev->info.TPU_Transparency_range.max = 10000;
1047   dev->info.TPU_Transparency_range.quant = 100;
1048 
1049   sanei_scsi_close (fd);
1050   fd = -1;
1051 
1052   ++num_devices;
1053   dev->next = first_dev;
1054   first_dev = dev;
1055 
1056   if (devp)
1057     *devp = dev;
1058 
1059   DBG (1, "<< attach\n");
1060   return (SANE_STATUS_GOOD);
1061 }
1062 
1063 /**************************************************************************/
1064 
1065 static SANE_Status
do_cancel(CANON_Scanner * s)1066 do_cancel (CANON_Scanner * s)
1067 {
1068   SANE_Status status;
1069 
1070   DBG (1, ">> do_cancel\n");
1071 
1072   s->scanning = SANE_FALSE;
1073 
1074   if (s->fd >= 0)
1075     {
1076       if (s->val[OPT_EJECT_AFTERSCAN].w && !(s->val[OPT_PREVIEW].w
1077 	&& s->hw->info.is_filmscanner))
1078 	{
1079 	  DBG (3, "do_cancel: sending MEDIUM POSITION\n");
1080 	  status = medium_position (s->fd);
1081 	  if (status != SANE_STATUS_GOOD)
1082 	    {
1083 	      DBG (1, "do_cancel: MEDIUM POSITION failed\n");
1084 	      return (SANE_STATUS_INVAL);
1085 	    }
1086 	  s->AF_NOW = SANE_TRUE;
1087 	  DBG (1, "do_cancel AF_NOW = '%d'\n", s->AF_NOW);
1088 	}
1089 
1090       DBG (21, "do_cancel: reset_flag = %d\n", s->reset_flag);
1091       if ((s->reset_flag == 1) && (s->hw->info.model == FB620))
1092 	{
1093 	  status = reset_scanner (s->fd);
1094 	  if (status != SANE_STATUS_GOOD)
1095 	    {
1096 	      DBG (21, "RESET SCANNER failed\n");
1097 	      sanei_scsi_close (s->fd);
1098 	      s->fd = -1;
1099 	      return (SANE_STATUS_INVAL);
1100 	    }
1101 	  DBG (21, "RESET SCANNER\n");
1102 	  s->reset_flag = 0;
1103 	  DBG (21, "do_cancel: reset_flag = %d\n", s->reset_flag);
1104 	  s->time0 = -1;
1105 	  DBG (21, "time0 = %ld\n", s->time0);
1106 	}
1107 
1108       if (s->hw->info.model == FB1200)
1109 	{
1110 	  DBG (3, "CANCEL FB1200S\n");
1111 	  status = cancel (s->fd);
1112 	  if (status != SANE_STATUS_GOOD)
1113 	    {
1114 	      DBG (1, "CANCEL FB1200S failed\n");
1115 	      return (SANE_STATUS_INVAL);
1116 	    }
1117 	  DBG (3, "CANCEL FB1200S OK\n");
1118 	}
1119 
1120       sanei_scsi_close (s->fd);
1121       s->fd = -1;
1122     }
1123 
1124   DBG (1, "<< do_cancel\n");
1125   return (SANE_STATUS_CANCELLED);
1126 }
1127 
1128 /**************************************************************************/
1129 
1130 static SANE_Status
init_options(CANON_Scanner * s)1131 init_options (CANON_Scanner * s)
1132 {
1133   int i;
1134   DBG (1, ">> init_options\n");
1135 
1136   memset (s->opt, 0, sizeof (s->opt));
1137   memset (s->val, 0, sizeof (s->val));
1138 
1139   s->AF_NOW = SANE_TRUE;
1140 
1141   for (i = 0; i < NUM_OPTIONS; ++i)
1142     {
1143       s->opt[i].size = sizeof (SANE_Word);
1144       s->opt[i].cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT;
1145     }
1146 
1147   s->opt[OPT_NUM_OPTS].title = SANE_TITLE_NUM_OPTIONS;
1148   s->opt[OPT_NUM_OPTS].desc = SANE_DESC_NUM_OPTIONS;
1149   s->opt[OPT_NUM_OPTS].type = SANE_TYPE_INT;
1150   s->opt[OPT_NUM_OPTS].cap = SANE_CAP_SOFT_DETECT;
1151   s->val[OPT_NUM_OPTS].w = NUM_OPTIONS;
1152 
1153   /* "Mode" group: */
1154   s->opt[OPT_MODE_GROUP].title = SANE_I18N("Scan mode");
1155   s->opt[OPT_MODE_GROUP].desc = "";
1156   s->opt[OPT_MODE_GROUP].type = SANE_TYPE_GROUP;
1157   s->opt[OPT_MODE_GROUP].cap = 0;
1158   s->opt[OPT_MODE_GROUP].constraint_type = SANE_CONSTRAINT_NONE;
1159 
1160   /* scan mode */
1161   s->opt[OPT_MODE].name = SANE_NAME_SCAN_MODE;
1162   s->opt[OPT_MODE].title = SANE_TITLE_SCAN_MODE;
1163   s->opt[OPT_MODE].desc = SANE_DESC_SCAN_MODE;
1164   s->opt[OPT_MODE].type = SANE_TYPE_STRING;
1165   s->opt[OPT_MODE].constraint_type = SANE_CONSTRAINT_STRING_LIST;
1166 
1167   switch (s->hw->info.model)
1168     {
1169     case FB620:
1170       s->opt[OPT_MODE].size = max_string_size (mode_list_fb620);
1171       s->opt[OPT_MODE].constraint.string_list = mode_list_fb620;
1172       s->val[OPT_MODE].s = strdup (mode_list_fb620[3]);
1173       break;
1174     case FB1200:
1175       s->opt[OPT_MODE].size = max_string_size (mode_list_fb1200);
1176       s->opt[OPT_MODE].constraint.string_list = mode_list_fb1200;
1177       s->val[OPT_MODE].s = strdup (mode_list_fb1200[2]);
1178       break;
1179     case FS2710:
1180       s->opt[OPT_MODE].size = max_string_size (mode_list_fs2710);
1181       s->opt[OPT_MODE].constraint.string_list = mode_list_fs2710;
1182       s->val[OPT_MODE].s = strdup (mode_list_fs2710[0]);
1183       break;
1184     default:
1185       s->opt[OPT_MODE].size = max_string_size (mode_list);
1186       s->opt[OPT_MODE].constraint.string_list = mode_list;
1187       s->val[OPT_MODE].s = strdup (mode_list[3]);
1188     }
1189 
1190   /* Slides or negatives */
1191   s->opt[OPT_NEGATIVE].name = "film-type";
1192   s->opt[OPT_NEGATIVE].title = SANE_I18N("Film type");
1193   s->opt[OPT_NEGATIVE].desc = SANE_I18N("Selects the film type, i.e. "
1194   "negatives or slides");
1195   s->opt[OPT_NEGATIVE].type = SANE_TYPE_STRING;
1196   s->opt[OPT_NEGATIVE].size = max_string_size (filmtype_list);
1197   s->opt[OPT_NEGATIVE].constraint_type = SANE_CONSTRAINT_STRING_LIST;
1198   s->opt[OPT_NEGATIVE].constraint.string_list = filmtype_list;
1199   s->opt[OPT_NEGATIVE].cap |=
1200     (s->hw->info.is_filmscanner)? 0 : SANE_CAP_INACTIVE;
1201   s->val[OPT_NEGATIVE].s = strdup (filmtype_list[1]);
1202 
1203   /* Negative film type */
1204   s->opt[OPT_NEGATIVE_TYPE].name = "negative-film-type";
1205   s->opt[OPT_NEGATIVE_TYPE].title = SANE_I18N("Negative film type");
1206   s->opt[OPT_NEGATIVE_TYPE].desc = SANE_I18N("Selects the negative film type");
1207   s->opt[OPT_NEGATIVE_TYPE].type = SANE_TYPE_STRING;
1208   s->opt[OPT_NEGATIVE_TYPE].size = max_string_size (negative_filmtype_list);
1209   s->opt[OPT_NEGATIVE_TYPE].constraint_type = SANE_CONSTRAINT_STRING_LIST;
1210   s->opt[OPT_NEGATIVE_TYPE].constraint.string_list = negative_filmtype_list;
1211   s->opt[OPT_NEGATIVE_TYPE].cap |= SANE_CAP_INACTIVE;
1212   s->val[OPT_NEGATIVE_TYPE].s = strdup (negative_filmtype_list[0]);
1213 
1214   /* Scanning speed */
1215   s->opt[OPT_SCANNING_SPEED].name = SANE_NAME_SCAN_SPEED;
1216   s->opt[OPT_SCANNING_SPEED].title = SANE_TITLE_SCAN_SPEED;
1217   s->opt[OPT_SCANNING_SPEED].desc = SANE_DESC_SCAN_SPEED;
1218   s->opt[OPT_SCANNING_SPEED].type = SANE_TYPE_STRING;
1219   s->opt[OPT_SCANNING_SPEED].size = max_string_size (scanning_speed_list);
1220   s->opt[OPT_SCANNING_SPEED].constraint_type = SANE_CONSTRAINT_STRING_LIST;
1221   s->opt[OPT_SCANNING_SPEED].constraint.string_list = scanning_speed_list;
1222   s->opt[OPT_SCANNING_SPEED].cap |=
1223     (s->hw->info.model == CS2700) ? 0 : SANE_CAP_INACTIVE;
1224   if (s->hw->info.model != CS2700)
1225     s->opt[OPT_SCANNING_SPEED].cap &= ~SANE_CAP_SOFT_SELECT;
1226   s->val[OPT_SCANNING_SPEED].s = strdup (scanning_speed_list[0]);
1227 
1228 
1229   /* "Resolution" group: */
1230   s->opt[OPT_RESOLUTION_GROUP].title = SANE_I18N("Scan resolution");
1231   s->opt[OPT_RESOLUTION_GROUP].desc = "";
1232   s->opt[OPT_RESOLUTION_GROUP].type = SANE_TYPE_GROUP;
1233   s->opt[OPT_RESOLUTION_GROUP].cap = 0;
1234   s->opt[OPT_RESOLUTION_GROUP].constraint_type = SANE_CONSTRAINT_NONE;
1235 
1236   /* bind resolution */
1237   s->opt[OPT_RESOLUTION_BIND].name = SANE_NAME_RESOLUTION_BIND;
1238   s->opt[OPT_RESOLUTION_BIND].title = SANE_TITLE_RESOLUTION_BIND;
1239   s->opt[OPT_RESOLUTION_BIND].desc = SANE_DESC_RESOLUTION_BIND;
1240   s->opt[OPT_RESOLUTION_BIND].type = SANE_TYPE_BOOL;
1241   s->val[OPT_RESOLUTION_BIND].w = SANE_TRUE;
1242 
1243   /* hardware resolutions only */
1244   s->opt[OPT_HW_RESOLUTION_ONLY].name = "hw-resolution-only";
1245   s->opt[OPT_HW_RESOLUTION_ONLY].title = SANE_I18N("Hardware resolution");
1246   s->opt[OPT_HW_RESOLUTION_ONLY].desc = SANE_I18N("Use only hardware "
1247   "resolutions");
1248   s->opt[OPT_HW_RESOLUTION_ONLY].type = SANE_TYPE_BOOL;
1249   s->val[OPT_HW_RESOLUTION_ONLY].w = SANE_TRUE;
1250   s->opt[OPT_HW_RESOLUTION_ONLY].cap |=
1251     (s->hw->info.has_fixed_resolutions)? 0 : SANE_CAP_INACTIVE;
1252 
1253   /* x-resolution */
1254   s->opt[OPT_X_RESOLUTION].name = SANE_NAME_SCAN_RESOLUTION;
1255   s->opt[OPT_X_RESOLUTION].title = SANE_TITLE_SCAN_RESOLUTION;
1256   s->opt[OPT_X_RESOLUTION].desc = SANE_DESC_SCAN_RESOLUTION;
1257   s->opt[OPT_X_RESOLUTION].type = SANE_TYPE_INT;
1258   s->opt[OPT_X_RESOLUTION].unit = SANE_UNIT_DPI;
1259   if (s->hw->info.has_fixed_resolutions)
1260     {
1261       int iCnt;
1262       float iRes;		/* modification for FB620S */
1263       s->opt[OPT_X_RESOLUTION].constraint_type = SANE_CONSTRAINT_WORD_LIST;
1264       iCnt = 0;
1265 
1266       iRes = s->hw->info.xres_range.max;
1267       DBG (5, "hw->info.xres_range.max=%d\n", s->hw->info.xres_range.max);
1268       s->opt[OPT_X_RESOLUTION].constraint.word_list = s->xres_word_list;
1269 
1270       /* go to minimum resolution by dividing by 2 */
1271       while (iRes >= s->hw->info.xres_range.min)
1272 	iRes /= 2;
1273       /* fill array up to maximum resolution */
1274       while (iRes < s->hw->info.xres_range.max)
1275 	{
1276 	  iRes *= 2;
1277 	  s->xres_word_list[++iCnt] = iRes;
1278 	}
1279       s->xres_word_list[0] = iCnt;
1280       s->val[OPT_X_RESOLUTION].w = s->xres_word_list[2];
1281     }
1282   else
1283     {
1284       s->opt[OPT_X_RESOLUTION].constraint_type = SANE_CONSTRAINT_RANGE;
1285       s->opt[OPT_X_RESOLUTION].constraint.range = &s->hw->info.xres_range;
1286       s->val[OPT_X_RESOLUTION].w = 300;
1287     }
1288 
1289   /* y-resolution */
1290   s->opt[OPT_Y_RESOLUTION].name = SANE_NAME_SCAN_Y_RESOLUTION;
1291   s->opt[OPT_Y_RESOLUTION].title = SANE_TITLE_SCAN_Y_RESOLUTION;
1292   s->opt[OPT_Y_RESOLUTION].desc = SANE_DESC_SCAN_Y_RESOLUTION;
1293   s->opt[OPT_Y_RESOLUTION].type = SANE_TYPE_INT;
1294   s->opt[OPT_Y_RESOLUTION].unit = SANE_UNIT_DPI;
1295   s->opt[OPT_Y_RESOLUTION].cap |= SANE_CAP_INACTIVE;
1296   if (s->hw->info.has_fixed_resolutions)
1297     {
1298       int iCnt;
1299       float iRes;		/* modification for FB620S */
1300       s->opt[OPT_Y_RESOLUTION].constraint_type = SANE_CONSTRAINT_WORD_LIST;
1301       iCnt = 0;
1302 
1303       iRes = s->hw->info.yres_range.max;
1304       DBG (5, "hw->info.yres_range.max=%d\n", s->hw->info.yres_range.max);
1305       s->opt[OPT_Y_RESOLUTION].constraint.word_list = s->yres_word_list;
1306 
1307       /* go to minimum resolution by dividing by 2 */
1308       while (iRes >= s->hw->info.yres_range.min)
1309 	iRes /= 2;
1310       /* fill array up to maximum resolution */
1311       while (iRes < s->hw->info.yres_range.max)
1312 	{
1313 	  iRes *= 2;
1314 	  s->yres_word_list[++iCnt] = iRes;
1315 	}
1316       s->yres_word_list[0] = iCnt;
1317       s->val[OPT_Y_RESOLUTION].w = s->yres_word_list[2];
1318     }
1319   else
1320     {
1321       s->opt[OPT_Y_RESOLUTION].constraint_type = SANE_CONSTRAINT_RANGE;
1322       s->opt[OPT_Y_RESOLUTION].constraint.range = &s->hw->info.yres_range;
1323       s->val[OPT_Y_RESOLUTION].w = 300;
1324     }
1325 
1326   /* Focus group: */
1327   s->opt[OPT_FOCUS_GROUP].title = SANE_I18N("Focus");
1328   s->opt[OPT_FOCUS_GROUP].desc = "";
1329   s->opt[OPT_FOCUS_GROUP].type = SANE_TYPE_GROUP;
1330   s->opt[OPT_FOCUS_GROUP].cap = SANE_CAP_ADVANCED;
1331   s->opt[OPT_FOCUS_GROUP].constraint_type = SANE_CONSTRAINT_NONE;
1332   s->opt[OPT_FOCUS_GROUP].cap |=
1333     (s->hw->info.can_focus) ? 0 : SANE_CAP_INACTIVE;
1334 
1335   /* Auto-Focus switch */
1336   s->opt[OPT_AF].name = "af";
1337   s->opt[OPT_AF].title = SANE_I18N("Auto focus");
1338   s->opt[OPT_AF].desc = SANE_I18N("Enable/disable auto focus");
1339   s->opt[OPT_AF].type = SANE_TYPE_BOOL;
1340   s->opt[OPT_AF].cap |= (s->hw->info.can_focus) ? 0 : SANE_CAP_INACTIVE;
1341   s->val[OPT_AF].w = s->hw->info.can_focus;
1342 
1343   /* Auto-Focus once switch */
1344   s->opt[OPT_AF_ONCE].name = "afonce";
1345   s->opt[OPT_AF_ONCE].title = SANE_I18N("Auto focus only once");
1346   s->opt[OPT_AF_ONCE].desc = SANE_I18N("Do auto focus only once between "
1347   "ejects");
1348   s->opt[OPT_AF_ONCE].type = SANE_TYPE_BOOL;
1349   s->opt[OPT_AF_ONCE].cap |= (s->hw->info.can_focus) ? 0 : SANE_CAP_INACTIVE;
1350   s->val[OPT_AF_ONCE].w = s->hw->info.can_focus;
1351 
1352   /* Manual focus */
1353   s->opt[OPT_FOCUS].name = "focus";
1354   s->opt[OPT_FOCUS].title = SANE_I18N("Manual focus position");
1355   s->opt[OPT_FOCUS].desc = SANE_I18N("Set the optical system's focus "
1356   "position by hand (default: 128).");
1357   s->opt[OPT_FOCUS].type = SANE_TYPE_INT;
1358   s->opt[OPT_FOCUS].unit = SANE_UNIT_NONE;
1359   s->opt[OPT_FOCUS].constraint_type = SANE_CONSTRAINT_RANGE;
1360   s->opt[OPT_FOCUS].constraint.range = &s->hw->info.focus_range;
1361   s->opt[OPT_FOCUS].cap |= (s->hw->info.can_focus) ? 0 : SANE_CAP_INACTIVE;
1362   s->val[OPT_FOCUS].w = (s->hw->info.can_focus) ? 128 : 0;
1363 
1364   /* Margins group: */
1365   s->opt[OPT_MARGINS_GROUP].title = SANE_I18N("Scan margins");
1366   s->opt[OPT_MARGINS_GROUP].desc = "";
1367   s->opt[OPT_MARGINS_GROUP].type = SANE_TYPE_GROUP;
1368   s->opt[OPT_MARGINS_GROUP].cap = SANE_CAP_ADVANCED;
1369   s->opt[OPT_MARGINS_GROUP].constraint_type = SANE_CONSTRAINT_NONE;
1370 
1371   /* top-left x */
1372   s->opt[OPT_TL_X].name = SANE_NAME_SCAN_TL_X;
1373   s->opt[OPT_TL_X].title = SANE_TITLE_SCAN_TL_X;
1374   s->opt[OPT_TL_X].desc = SANE_DESC_SCAN_TL_X;
1375   s->opt[OPT_TL_X].type = SANE_TYPE_FIXED;
1376   s->opt[OPT_TL_X].unit = SANE_UNIT_MM;
1377   s->opt[OPT_TL_X].constraint_type = SANE_CONSTRAINT_RANGE;
1378   s->opt[OPT_TL_X].constraint.range = &s->hw->info.x_range;
1379   s->val[OPT_TL_X].w = 0;
1380 
1381   /* top-left y */
1382   s->opt[OPT_TL_Y].name = SANE_NAME_SCAN_TL_Y;
1383   s->opt[OPT_TL_Y].title = SANE_TITLE_SCAN_TL_Y;
1384   s->opt[OPT_TL_Y].desc = SANE_DESC_SCAN_TL_Y;
1385   s->opt[OPT_TL_Y].type = SANE_TYPE_FIXED;
1386   s->opt[OPT_TL_Y].unit = SANE_UNIT_MM;
1387   s->opt[OPT_TL_Y].constraint_type = SANE_CONSTRAINT_RANGE;
1388   s->opt[OPT_TL_Y].constraint.range = &s->hw->info.y_range;
1389   s->val[OPT_TL_Y].w = 0;
1390 
1391   /* bottom-right x */
1392   s->opt[OPT_BR_X].name = SANE_NAME_SCAN_BR_X;
1393   s->opt[OPT_BR_X].title = SANE_TITLE_SCAN_BR_X;
1394   s->opt[OPT_BR_X].desc = SANE_DESC_SCAN_BR_X;
1395   s->opt[OPT_BR_X].type = SANE_TYPE_FIXED;
1396   s->opt[OPT_BR_X].unit = SANE_UNIT_MM;
1397   s->opt[OPT_BR_X].constraint_type = SANE_CONSTRAINT_RANGE;
1398   s->opt[OPT_BR_X].constraint.range = &s->hw->info.x_range;
1399   s->val[OPT_BR_X].w = s->hw->info.x_range.max;
1400 
1401   /* bottom-right y */
1402   s->opt[OPT_BR_Y].name = SANE_NAME_SCAN_BR_Y;
1403   s->opt[OPT_BR_Y].title = SANE_TITLE_SCAN_BR_Y;
1404   s->opt[OPT_BR_Y].desc = SANE_DESC_SCAN_BR_Y;
1405   s->opt[OPT_BR_Y].type = SANE_TYPE_FIXED;
1406   s->opt[OPT_BR_Y].unit = SANE_UNIT_MM;
1407   s->opt[OPT_BR_Y].constraint_type = SANE_CONSTRAINT_RANGE;
1408   s->opt[OPT_BR_Y].constraint.range = &s->hw->info.y_range;
1409   s->val[OPT_BR_Y].w = s->hw->info.y_range.max;
1410 
1411   /* Colors group: */
1412   s->opt[OPT_COLORS_GROUP].title = SANE_I18N("Extra color adjustments");
1413   s->opt[OPT_COLORS_GROUP].desc = "";
1414   s->opt[OPT_COLORS_GROUP].type = SANE_TYPE_GROUP;
1415   s->opt[OPT_COLORS_GROUP].cap = SANE_CAP_ADVANCED;
1416   s->opt[OPT_COLORS_GROUP].constraint_type = SANE_CONSTRAINT_NONE;
1417 
1418   /* Positive/Negative switch for the CanoScan 300/600 models */
1419   s->opt[OPT_HNEGATIVE].name = SANE_NAME_NEGATIVE;
1420   s->opt[OPT_HNEGATIVE].title = SANE_TITLE_NEGATIVE;
1421   s->opt[OPT_HNEGATIVE].desc = SANE_DESC_NEGATIVE;
1422   s->opt[OPT_HNEGATIVE].type = SANE_TYPE_BOOL;
1423   s->opt[OPT_HNEGATIVE].cap |=
1424     (s->hw->info.model == CS2700 || s->hw->info.model == FS2710) ?
1425     SANE_CAP_INACTIVE : 0;
1426   s->val[OPT_HNEGATIVE].w = SANE_FALSE;
1427 
1428   /* Same values for highlight and shadow points for red, green, blue */
1429   s->opt[OPT_BIND_HILO].name = "bind-highlight-shadow-points";
1430   s->opt[OPT_BIND_HILO].title = SANE_TITLE_RGB_BIND;
1431   s->opt[OPT_BIND_HILO].desc = SANE_DESC_RGB_BIND;
1432   s->opt[OPT_BIND_HILO].type = SANE_TYPE_BOOL;
1433   s->opt[OPT_BIND_HILO].cap |= (s->hw->info.model == FB620 ||
1434     s->hw->info.model == IX4015) ? SANE_CAP_INACTIVE : 0;
1435   s->val[OPT_BIND_HILO].w = SANE_TRUE;
1436 
1437   /* highlight point for red   */
1438   s->opt[OPT_HILITE_R].name = SANE_NAME_HIGHLIGHT_R;
1439   s->opt[OPT_HILITE_R].title = SANE_TITLE_HIGHLIGHT_R;
1440   s->opt[OPT_HILITE_R].desc = SANE_DESC_HIGHLIGHT_R;
1441   s->opt[OPT_HILITE_R].type = SANE_TYPE_INT;
1442   s->opt[OPT_HILITE_R].unit = SANE_UNIT_NONE;
1443   s->opt[OPT_HILITE_R].constraint_type = SANE_CONSTRAINT_RANGE;
1444   s->opt[OPT_HILITE_R].constraint.range = &s->hw->info.HiliteR_range;
1445   s->opt[OPT_HILITE_R].cap |= SANE_CAP_INACTIVE;
1446   s->val[OPT_HILITE_R].w = 255;
1447 
1448   /* shadow point for red   */
1449   s->opt[OPT_SHADOW_R].name = SANE_NAME_SHADOW_R;
1450   s->opt[OPT_SHADOW_R].title = SANE_TITLE_SHADOW_R;
1451   s->opt[OPT_SHADOW_R].desc = SANE_DESC_SHADOW_R;
1452   s->opt[OPT_SHADOW_R].type = SANE_TYPE_INT;
1453   s->opt[OPT_SHADOW_R].unit = SANE_UNIT_NONE;
1454   s->opt[OPT_SHADOW_R].constraint_type = SANE_CONSTRAINT_RANGE;
1455   s->opt[OPT_SHADOW_R].constraint.range = &s->hw->info.ShadowR_range;
1456   s->opt[OPT_SHADOW_R].cap |= SANE_CAP_INACTIVE;
1457   s->val[OPT_SHADOW_R].w = 0;
1458 
1459   /* highlight point for green */
1460   s->opt[OPT_HILITE_G].name = SANE_NAME_HIGHLIGHT;
1461   s->opt[OPT_HILITE_G].title = SANE_TITLE_HIGHLIGHT;
1462   s->opt[OPT_HILITE_G].desc = SANE_DESC_HIGHLIGHT;
1463   s->opt[OPT_HILITE_G].type = SANE_TYPE_INT;
1464   s->opt[OPT_HILITE_G].unit = SANE_UNIT_NONE;
1465   s->opt[OPT_HILITE_G].constraint_type = SANE_CONSTRAINT_RANGE;
1466   s->opt[OPT_HILITE_G].constraint.range = &s->hw->info.HiliteG_range;
1467   s->opt[OPT_HILITE_G].cap |=
1468     (s->hw->info.model == IX4015) ? SANE_CAP_INACTIVE : 0;
1469   s->val[OPT_HILITE_G].w = 255;
1470 
1471   /* shadow point for green */
1472   s->opt[OPT_SHADOW_G].name = SANE_NAME_SHADOW;
1473   s->opt[OPT_SHADOW_G].title = SANE_TITLE_SHADOW;
1474   s->opt[OPT_SHADOW_G].desc = SANE_DESC_SHADOW;
1475   s->opt[OPT_SHADOW_G].type = SANE_TYPE_INT;
1476   s->opt[OPT_SHADOW_G].unit = SANE_UNIT_NONE;
1477   s->opt[OPT_SHADOW_G].constraint_type = SANE_CONSTRAINT_RANGE;
1478   s->opt[OPT_SHADOW_G].constraint.range = &s->hw->info.ShadowG_range;
1479   s->opt[OPT_SHADOW_G].cap |=
1480     (s->hw->info.model == IX4015) ? SANE_CAP_INACTIVE : 0;
1481   s->val[OPT_SHADOW_G].w = 0;
1482 
1483   /* highlight point for blue  */
1484   s->opt[OPT_HILITE_B].name = SANE_NAME_HIGHLIGHT_B;
1485   s->opt[OPT_HILITE_B].title = SANE_TITLE_HIGHLIGHT_B;
1486   s->opt[OPT_HILITE_B].desc = SANE_DESC_HIGHLIGHT_B;
1487   s->opt[OPT_HILITE_B].type = SANE_TYPE_INT;
1488   s->opt[OPT_HILITE_B].unit = SANE_UNIT_NONE;
1489   s->opt[OPT_HILITE_B].constraint_type = SANE_CONSTRAINT_RANGE;
1490   s->opt[OPT_HILITE_B].constraint.range = &s->hw->info.HiliteB_range;
1491   s->opt[OPT_HILITE_B].cap |= SANE_CAP_INACTIVE;
1492   s->val[OPT_HILITE_B].w = 255;
1493 
1494   /* shadow point for blue  */
1495   s->opt[OPT_SHADOW_B].name = SANE_NAME_SHADOW_B;
1496   s->opt[OPT_SHADOW_B].title = SANE_TITLE_SHADOW_B;
1497   s->opt[OPT_SHADOW_B].desc = SANE_DESC_SHADOW_B;
1498   s->opt[OPT_SHADOW_B].type = SANE_TYPE_INT;
1499   s->opt[OPT_SHADOW_B].unit = SANE_UNIT_NONE;
1500   s->opt[OPT_SHADOW_B].constraint_type = SANE_CONSTRAINT_RANGE;
1501   s->opt[OPT_SHADOW_B].constraint.range = &s->hw->info.ShadowB_range;
1502   s->opt[OPT_SHADOW_B].cap |= SANE_CAP_INACTIVE;
1503   s->val[OPT_SHADOW_B].w = 0;
1504 
1505 
1506   /* "Enhancement" group: */
1507   s->opt[OPT_ENHANCEMENT_GROUP].title = SANE_I18N("Enhancement");
1508   s->opt[OPT_ENHANCEMENT_GROUP].desc = "";
1509   s->opt[OPT_ENHANCEMENT_GROUP].type = SANE_TYPE_GROUP;
1510   s->opt[OPT_ENHANCEMENT_GROUP].cap = 0;
1511   s->opt[OPT_ENHANCEMENT_GROUP].constraint_type = SANE_CONSTRAINT_NONE;
1512 
1513   /* brightness */
1514   s->opt[OPT_BRIGHTNESS].name = SANE_NAME_BRIGHTNESS;
1515   s->opt[OPT_BRIGHTNESS].title = SANE_TITLE_BRIGHTNESS;
1516   s->opt[OPT_BRIGHTNESS].desc = SANE_DESC_BRIGHTNESS;
1517   s->opt[OPT_BRIGHTNESS].type = SANE_TYPE_INT;
1518   s->opt[OPT_BRIGHTNESS].unit = SANE_UNIT_NONE;
1519   s->opt[OPT_BRIGHTNESS].constraint_type = SANE_CONSTRAINT_RANGE;
1520   s->opt[OPT_BRIGHTNESS].constraint.range = &s->hw->info.brightness_range;
1521   s->opt[OPT_BRIGHTNESS].cap |= 0;
1522   s->val[OPT_BRIGHTNESS].w = 128;
1523 
1524   /* contrast */
1525   s->opt[OPT_CONTRAST].name = SANE_NAME_CONTRAST;
1526   s->opt[OPT_CONTRAST].title = SANE_TITLE_CONTRAST;
1527   s->opt[OPT_CONTRAST].desc = SANE_DESC_CONTRAST;
1528   s->opt[OPT_CONTRAST].type = SANE_TYPE_INT;
1529   s->opt[OPT_CONTRAST].unit = SANE_UNIT_NONE;
1530   s->opt[OPT_CONTRAST].constraint_type = SANE_CONSTRAINT_RANGE;
1531   s->opt[OPT_CONTRAST].constraint.range = &s->hw->info.contrast_range;
1532   s->opt[OPT_CONTRAST].cap |= 0;
1533   s->val[OPT_CONTRAST].w = 128;
1534 
1535   /* threshold */
1536   s->opt[OPT_THRESHOLD].name = SANE_NAME_THRESHOLD;
1537   s->opt[OPT_THRESHOLD].title = SANE_TITLE_THRESHOLD;
1538   s->opt[OPT_THRESHOLD].desc = SANE_DESC_THRESHOLD;
1539   s->opt[OPT_THRESHOLD].type = SANE_TYPE_INT;
1540   s->opt[OPT_THRESHOLD].unit = SANE_UNIT_NONE;
1541   s->opt[OPT_THRESHOLD].constraint_type = SANE_CONSTRAINT_RANGE;
1542   s->opt[OPT_THRESHOLD].constraint.range = &s->hw->info.threshold_range;
1543   s->opt[OPT_THRESHOLD].cap |= SANE_CAP_INACTIVE;
1544   s->val[OPT_THRESHOLD].w = 128;
1545 
1546   s->opt[OPT_MIRROR].name = "mirror";
1547   s->opt[OPT_MIRROR].title = SANE_I18N("Mirror image");
1548   s->opt[OPT_MIRROR].desc = SANE_I18N("Mirror the image horizontally");
1549   s->opt[OPT_MIRROR].type = SANE_TYPE_BOOL;
1550   s->opt[OPT_MIRROR].cap |= (s->hw->info.can_mirror) ? 0: SANE_CAP_INACTIVE;
1551   s->val[OPT_MIRROR].w = SANE_FALSE;
1552 
1553   /* analog-gamma curve */
1554   s->opt[OPT_CUSTOM_GAMMA].name = SANE_NAME_CUSTOM_GAMMA;
1555   s->opt[OPT_CUSTOM_GAMMA].title = SANE_TITLE_CUSTOM_GAMMA;
1556   s->opt[OPT_CUSTOM_GAMMA].desc = SANE_DESC_CUSTOM_GAMMA;
1557   s->opt[OPT_CUSTOM_GAMMA].type = SANE_TYPE_BOOL;
1558   s->val[OPT_CUSTOM_GAMMA].w = SANE_FALSE;
1559 
1560   /* bind analog-gamma */
1561   s->opt[OPT_CUSTOM_GAMMA_BIND].name = "bind-custom-gamma";
1562   s->opt[OPT_CUSTOM_GAMMA_BIND].title = SANE_TITLE_RGB_BIND;
1563   s->opt[OPT_CUSTOM_GAMMA_BIND].desc = SANE_DESC_RGB_BIND;
1564   s->opt[OPT_CUSTOM_GAMMA_BIND].type = SANE_TYPE_BOOL;
1565   s->opt[OPT_CUSTOM_GAMMA_BIND].cap |= SANE_CAP_INACTIVE;
1566   s->val[OPT_CUSTOM_GAMMA_BIND].w = SANE_TRUE;
1567 
1568   /* grayscale gamma vector */
1569   s->opt[OPT_GAMMA_VECTOR].name = SANE_NAME_GAMMA_VECTOR;
1570   s->opt[OPT_GAMMA_VECTOR].title = SANE_TITLE_GAMMA_VECTOR;
1571   s->opt[OPT_GAMMA_VECTOR].desc = SANE_DESC_GAMMA_VECTOR;
1572   s->opt[OPT_GAMMA_VECTOR].type = SANE_TYPE_INT;
1573   s->opt[OPT_GAMMA_VECTOR].cap |= SANE_CAP_INACTIVE;
1574   s->opt[OPT_GAMMA_VECTOR].unit = SANE_UNIT_NONE;
1575   s->opt[OPT_GAMMA_VECTOR].size = 256 * sizeof (SANE_Word);
1576   s->opt[OPT_GAMMA_VECTOR].constraint_type = SANE_CONSTRAINT_RANGE;
1577   s->opt[OPT_GAMMA_VECTOR].constraint.range = &u8_range;
1578   s->val[OPT_GAMMA_VECTOR].wa = &s->gamma_table[0][0];
1579 
1580   /* red gamma vector */
1581   s->opt[OPT_GAMMA_VECTOR_R].name = SANE_NAME_GAMMA_VECTOR_R;
1582   s->opt[OPT_GAMMA_VECTOR_R].title = SANE_TITLE_GAMMA_VECTOR_R;
1583   s->opt[OPT_GAMMA_VECTOR_R].desc = SANE_DESC_GAMMA_VECTOR_R;
1584   s->opt[OPT_GAMMA_VECTOR_R].type = SANE_TYPE_INT;
1585   s->opt[OPT_GAMMA_VECTOR_R].cap |= SANE_CAP_INACTIVE;
1586   s->opt[OPT_GAMMA_VECTOR_R].unit = SANE_UNIT_NONE;
1587   s->opt[OPT_GAMMA_VECTOR_R].size = 256 * sizeof (SANE_Word);
1588   s->opt[OPT_GAMMA_VECTOR_R].constraint_type = SANE_CONSTRAINT_RANGE;
1589   s->opt[OPT_GAMMA_VECTOR_R].constraint.range = &u8_range;
1590   s->val[OPT_GAMMA_VECTOR_R].wa = &s->gamma_table[1][0];
1591 
1592   /* green gamma vector */
1593   s->opt[OPT_GAMMA_VECTOR_G].name = SANE_NAME_GAMMA_VECTOR_G;
1594   s->opt[OPT_GAMMA_VECTOR_G].title = SANE_TITLE_GAMMA_VECTOR_G;
1595   s->opt[OPT_GAMMA_VECTOR_G].desc = SANE_DESC_GAMMA_VECTOR_G;
1596   s->opt[OPT_GAMMA_VECTOR_G].type = SANE_TYPE_INT;
1597   s->opt[OPT_GAMMA_VECTOR_G].cap |= SANE_CAP_INACTIVE;
1598   s->opt[OPT_GAMMA_VECTOR_G].unit = SANE_UNIT_NONE;
1599   s->opt[OPT_GAMMA_VECTOR_G].size = 256 * sizeof (SANE_Word);
1600   s->opt[OPT_GAMMA_VECTOR_G].constraint_type = SANE_CONSTRAINT_RANGE;
1601   s->opt[OPT_GAMMA_VECTOR_G].constraint.range = &u8_range;
1602   s->val[OPT_GAMMA_VECTOR_G].wa = &s->gamma_table[2][0];
1603 
1604   /* blue gamma vector */
1605   s->opt[OPT_GAMMA_VECTOR_B].name = SANE_NAME_GAMMA_VECTOR_B;
1606   s->opt[OPT_GAMMA_VECTOR_B].title = SANE_TITLE_GAMMA_VECTOR_B;
1607   s->opt[OPT_GAMMA_VECTOR_B].desc = SANE_DESC_GAMMA_VECTOR_B;
1608   s->opt[OPT_GAMMA_VECTOR_B].type = SANE_TYPE_INT;
1609   s->opt[OPT_GAMMA_VECTOR_B].cap |= SANE_CAP_INACTIVE;
1610   s->opt[OPT_GAMMA_VECTOR_B].unit = SANE_UNIT_NONE;
1611   s->opt[OPT_GAMMA_VECTOR_B].size = 256 * sizeof (SANE_Word);
1612   s->opt[OPT_GAMMA_VECTOR_B].constraint_type = SANE_CONSTRAINT_RANGE;
1613   s->opt[OPT_GAMMA_VECTOR_B].constraint.range = &u8_range;
1614   s->val[OPT_GAMMA_VECTOR_B].wa = &s->gamma_table[3][0];
1615 
1616   s->opt[OPT_AE].name = "ae";
1617   s->opt[OPT_AE].title = SANE_I18N("Auto exposure");
1618   s->opt[OPT_AE].desc = SANE_I18N("Enable/disable the auto exposure feature");
1619   s->opt[OPT_AE].cap |= (s->hw->info.can_autoexpose) ? 0 : SANE_CAP_INACTIVE;
1620   s->opt[OPT_AE].type = SANE_TYPE_BOOL;
1621   s->val[OPT_AE].w = SANE_FALSE;
1622 
1623 
1624   /* "Calibration" group */
1625   s->opt[OPT_CALIBRATION_GROUP].title = SANE_I18N("Calibration");
1626   s->opt[OPT_CALIBRATION_GROUP].desc = "";
1627   s->opt[OPT_CALIBRATION_GROUP].type = SANE_TYPE_GROUP;
1628   s->opt[OPT_CALIBRATION_GROUP].cap |= (s->hw->info.can_calibrate ||
1629     s->hw->info.can_diagnose) ? 0 : SANE_CAP_INACTIVE;
1630   s->opt[OPT_CALIBRATION_GROUP].constraint_type = SANE_CONSTRAINT_NONE;
1631 
1632   /* calibration now */
1633   s->opt[OPT_CALIBRATION_NOW].name = "calibration-now";
1634   s->opt[OPT_CALIBRATION_NOW].title = SANE_I18N("Calibration now");
1635   s->opt[OPT_CALIBRATION_NOW].desc = SANE_I18N("Execute calibration *now*");
1636   s->opt[OPT_CALIBRATION_NOW].type = SANE_TYPE_BUTTON;
1637   s->opt[OPT_CALIBRATION_NOW].unit = SANE_UNIT_NONE;
1638   s->opt[OPT_CALIBRATION_NOW].cap |=
1639     (s->hw->info.can_calibrate) ? 0 : SANE_CAP_INACTIVE;
1640   s->opt[OPT_CALIBRATION_NOW].constraint_type = SANE_CONSTRAINT_NONE;
1641   s->opt[OPT_CALIBRATION_NOW].constraint.range = NULL;
1642 
1643   /* scanner self diagnostic */
1644   s->opt[OPT_SCANNER_SELF_DIAGNOSTIC].name = "self-diagnostic";
1645   s->opt[OPT_SCANNER_SELF_DIAGNOSTIC].title = SANE_I18N("Self diagnosis");
1646   s->opt[OPT_SCANNER_SELF_DIAGNOSTIC].desc = SANE_I18N("Perform scanner "
1647   "self diagnosis");
1648   s->opt[OPT_SCANNER_SELF_DIAGNOSTIC].type = SANE_TYPE_BUTTON;
1649   s->opt[OPT_SCANNER_SELF_DIAGNOSTIC].unit = SANE_UNIT_NONE;
1650   s->opt[OPT_SCANNER_SELF_DIAGNOSTIC].cap |=
1651     (s->hw->info.can_diagnose) ? 0 : SANE_CAP_INACTIVE;
1652   s->opt[OPT_SCANNER_SELF_DIAGNOSTIC].constraint_type = SANE_CONSTRAINT_NONE;
1653   s->opt[OPT_SCANNER_SELF_DIAGNOSTIC].constraint.range = NULL;
1654 
1655   /* reset scanner for FB620S */
1656   s->opt[OPT_RESET_SCANNER].name = "reset-scanner";
1657   s->opt[OPT_RESET_SCANNER].title = SANE_I18N("Reset scanner");
1658   s->opt[OPT_RESET_SCANNER].desc = SANE_I18N("Reset the scanner");
1659   s->opt[OPT_RESET_SCANNER].type = SANE_TYPE_BUTTON;
1660   s->opt[OPT_RESET_SCANNER].unit = SANE_UNIT_NONE;
1661   s->opt[OPT_RESET_SCANNER].cap |=
1662     (s->hw->info.model == FB620) ? 0 : SANE_CAP_INACTIVE;
1663   s->opt[OPT_RESET_SCANNER].constraint_type = SANE_CONSTRAINT_NONE;
1664   s->opt[OPT_RESET_SCANNER].constraint.range = NULL;
1665 
1666 
1667   /* "Eject" group (active only for film scanners) */
1668   s->opt[OPT_EJECT_GROUP].title = SANE_I18N("Medium handling");
1669   s->opt[OPT_EJECT_GROUP].desc = "";
1670   s->opt[OPT_EJECT_GROUP].type = SANE_TYPE_GROUP;
1671   s->opt[OPT_EJECT_GROUP].cap |=
1672     (s->hw->info.can_eject) ? 0 : SANE_CAP_INACTIVE;
1673   s->opt[OPT_EJECT_GROUP].constraint_type = SANE_CONSTRAINT_NONE;
1674 
1675   /* eject after scan */
1676   s->opt[OPT_EJECT_AFTERSCAN].name = "eject-after-scan";
1677   s->opt[OPT_EJECT_AFTERSCAN].title = SANE_I18N("Eject film after each scan");
1678   s->opt[OPT_EJECT_AFTERSCAN].desc = SANE_I18N("Automatically eject the "
1679   "film from the device after each scan");
1680   s->opt[OPT_EJECT_AFTERSCAN].cap |=
1681     (s->hw->info.can_eject) ? 0 : SANE_CAP_INACTIVE;
1682   s->opt[OPT_EJECT_AFTERSCAN].type = SANE_TYPE_BOOL;
1683   /* IX-4015 requires medium_position command after cancel */
1684   s->val[OPT_EJECT_AFTERSCAN].w =
1685     (s->hw->info.model == IX4015) ? SANE_TRUE : SANE_FALSE;
1686 
1687   /* eject before exit */
1688   s->opt[OPT_EJECT_BEFOREEXIT].name = "eject-before-exit";
1689   s->opt[OPT_EJECT_BEFOREEXIT].title = SANE_I18N("Eject film before exit");
1690   s->opt[OPT_EJECT_BEFOREEXIT].desc = SANE_I18N("Automatically eject the "
1691   "film from the device before exiting the program");
1692   s->opt[OPT_EJECT_BEFOREEXIT].cap |=
1693     (s->hw->info.can_eject) ? 0 : SANE_CAP_INACTIVE;
1694   s->opt[OPT_EJECT_BEFOREEXIT].type = SANE_TYPE_BOOL;
1695   s->val[OPT_EJECT_BEFOREEXIT].w = s->hw->info.can_eject;
1696 
1697   /* eject now */
1698   s->opt[OPT_EJECT_NOW].name = "eject-now";
1699   s->opt[OPT_EJECT_NOW].title = SANE_I18N("Eject film now");
1700   s->opt[OPT_EJECT_NOW].desc = SANE_I18N("Eject the film *now*");
1701   s->opt[OPT_EJECT_NOW].type = SANE_TYPE_BUTTON;
1702   s->opt[OPT_EJECT_NOW].unit = SANE_UNIT_NONE;
1703   s->opt[OPT_EJECT_NOW].cap |=
1704     (s->hw->info.can_eject) ? 0 : SANE_CAP_INACTIVE;
1705   s->opt[OPT_EJECT_NOW].constraint_type = SANE_CONSTRAINT_NONE;
1706   s->opt[OPT_EJECT_NOW].constraint.range = NULL;
1707 
1708   /* "NO-ADF" option: */
1709   s->opt[OPT_ADF_GROUP].title = SANE_I18N("Document feeder extras");
1710   s->opt[OPT_ADF_GROUP].desc = "";
1711   s->opt[OPT_ADF_GROUP].type = SANE_TYPE_GROUP;
1712   s->opt[OPT_ADF_GROUP].cap = 0;
1713   s->opt[OPT_ADF_GROUP].constraint_type = SANE_CONSTRAINT_NONE;
1714 
1715   s->opt[OPT_FLATBED_ONLY].name = "noadf";
1716   s->opt[OPT_FLATBED_ONLY].title = SANE_I18N("Flatbed only");
1717   s->opt[OPT_FLATBED_ONLY].desc = SANE_I18N("Disable auto document feeder "
1718   "and use flatbed only");
1719   s->opt[OPT_FLATBED_ONLY].type = SANE_TYPE_BOOL;
1720   s->opt[OPT_FLATBED_ONLY].unit = SANE_UNIT_NONE;
1721   s->opt[OPT_FLATBED_ONLY].size = sizeof (SANE_Word);
1722   s->opt[OPT_FLATBED_ONLY].cap |=
1723     (s->hw->adf.Status == ADF_STAT_NONE) ? SANE_CAP_INACTIVE : 0;
1724   s->val[OPT_FLATBED_ONLY].w = SANE_FALSE;
1725 
1726   /* "TPU" group: */
1727   s->opt[OPT_TPU_GROUP].title = SANE_I18N("Transparency unit");
1728   s->opt[OPT_TPU_GROUP].desc = "";
1729   s->opt[OPT_TPU_GROUP].type = SANE_TYPE_GROUP;
1730   s->opt[OPT_TPU_GROUP].cap = 0;
1731   s->opt[OPT_TPU_GROUP].constraint_type = SANE_CONSTRAINT_NONE;
1732   s->opt[OPT_TPU_GROUP].cap |=
1733     (s->hw->tpu.Status != TPU_STAT_NONE) ? 0 : SANE_CAP_INACTIVE;
1734 
1735   /* Transparency Unit (FAU, Film Adapter Unit) */
1736   s->opt[OPT_TPU_ON].name = "transparency-unit-on-off";
1737   s->opt[OPT_TPU_ON].title = SANE_I18N("Transparency unit");
1738   s->opt[OPT_TPU_ON].desc = SANE_I18N("Switch on/off the transparency unit "
1739   "(FAU, film adapter unit)");
1740   s->opt[OPT_TPU_ON].type = SANE_TYPE_BOOL;
1741   s->opt[OPT_TPU_ON].unit = SANE_UNIT_NONE;
1742   s->val[OPT_TPU_ON].w =
1743     (s->hw->tpu.Status == TPU_STAT_ACTIVE) ? SANE_TRUE : SANE_FALSE;
1744   s->opt[OPT_TPU_ON].cap |=
1745     (s->hw->tpu.Status != TPU_STAT_NONE) ? 0 : SANE_CAP_INACTIVE;
1746 
1747   s->opt[OPT_TPU_PN].name = "transparency-unit-negative-film";
1748   s->opt[OPT_TPU_PN].title = SANE_I18N("Negative film");
1749   s->opt[OPT_TPU_PN].desc = SANE_I18N("Positive or negative film");
1750   s->opt[OPT_TPU_PN].type = SANE_TYPE_BOOL;
1751   s->opt[OPT_TPU_PN].unit = SANE_UNIT_NONE;
1752   s->val[OPT_TPU_PN].w = s->hw->tpu.PosNeg;
1753   s->opt[OPT_TPU_PN].cap |=
1754     (s->hw->tpu.Status == TPU_STAT_ACTIVE) ? 0 : SANE_CAP_INACTIVE;
1755 
1756   /* density control mode */
1757   s->opt[OPT_TPU_DCM].name = "TPMDC";
1758   s->opt[OPT_TPU_DCM].title = SANE_I18N("Density control");
1759   s->opt[OPT_TPU_DCM].desc = SANE_I18N("Set density control mode");
1760   s->opt[OPT_TPU_DCM].type = SANE_TYPE_STRING;
1761   s->opt[OPT_TPU_DCM].size = max_string_size (tpu_dc_mode_list);
1762   s->opt[OPT_TPU_DCM].constraint_type = SANE_CONSTRAINT_STRING_LIST;
1763   s->opt[OPT_TPU_DCM].constraint.string_list = tpu_dc_mode_list;
1764   s->val[OPT_TPU_DCM].s = strdup (tpu_dc_mode_list[s->hw->tpu.ControlMode]);
1765   s->opt[OPT_TPU_DCM].cap |=
1766     (s->hw->tpu.Status == TPU_STAT_ACTIVE) ? 0 : SANE_CAP_INACTIVE;
1767 
1768   /* Transparency Ratio */
1769   s->opt[OPT_TPU_TRANSPARENCY].name = "Transparency-Ratio";
1770   s->opt[OPT_TPU_TRANSPARENCY].title = SANE_I18N("Transparency ratio");
1771   s->opt[OPT_TPU_TRANSPARENCY].desc = "";
1772   s->opt[OPT_TPU_TRANSPARENCY].type = SANE_TYPE_INT;
1773   s->opt[OPT_TPU_TRANSPARENCY].unit = SANE_UNIT_NONE;
1774   s->opt[OPT_TPU_TRANSPARENCY].constraint_type = SANE_CONSTRAINT_RANGE;
1775   s->opt[OPT_TPU_TRANSPARENCY].constraint.range =
1776     &s->hw->info.TPU_Transparency_range;
1777   s->val[OPT_TPU_TRANSPARENCY].w = s->hw->tpu.Transparency;
1778   s->opt[OPT_TPU_TRANSPARENCY].cap |=
1779     (s->hw->tpu.Status == TPU_STAT_ACTIVE &&
1780      s->hw->tpu.ControlMode == 3) ? 0 : SANE_CAP_INACTIVE;
1781 
1782   /* Select Film type */
1783   s->opt[OPT_TPU_FILMTYPE].name = "Filmtype";
1784   s->opt[OPT_TPU_FILMTYPE].title = SANE_I18N("Select film type");
1785   s->opt[OPT_TPU_FILMTYPE].desc = SANE_I18N("Select the film type");
1786   s->opt[OPT_TPU_FILMTYPE].type = SANE_TYPE_STRING;
1787   s->opt[OPT_TPU_FILMTYPE].size = max_string_size (tpu_filmtype_list);
1788   s->opt[OPT_TPU_FILMTYPE].constraint_type = SANE_CONSTRAINT_STRING_LIST;
1789   s->opt[OPT_TPU_FILMTYPE].constraint.string_list = tpu_filmtype_list;
1790   s->val[OPT_TPU_FILMTYPE].s =
1791     strdup (tpu_filmtype_list[s->hw->tpu.FilmType]);
1792   s->opt[OPT_TPU_FILMTYPE].cap |=
1793     (s->hw->tpu.Status == TPU_STAT_ACTIVE && s->hw->tpu.ControlMode == 1) ?
1794     0 : SANE_CAP_INACTIVE;
1795 
1796 
1797   /* preview */
1798   s->opt[OPT_PREVIEW].name = SANE_NAME_PREVIEW;
1799   s->opt[OPT_PREVIEW].title = SANE_TITLE_PREVIEW;
1800   s->opt[OPT_PREVIEW].desc = SANE_DESC_PREVIEW;
1801   s->opt[OPT_PREVIEW].type = SANE_TYPE_BOOL;
1802   s->opt[OPT_PREVIEW].cap = SANE_CAP_SOFT_DETECT | SANE_CAP_SOFT_SELECT;
1803   s->val[OPT_PREVIEW].w = SANE_FALSE;
1804 
1805   DBG (1, "<< init_options\n");
1806   return SANE_STATUS_GOOD;
1807 }
1808 
1809 /**************************************************************************/
1810 
1811 static SANE_Status
attach_one(const char * dev)1812 attach_one (const char *dev)
1813 {
1814   DBG (1, ">> attach_one\n");
1815   attach (dev, 0);
1816   DBG (1, "<< attach_one\n");
1817   return SANE_STATUS_GOOD;
1818 }
1819 
1820 /**************************************************************************/
1821 
1822 static SANE_Status
do_focus(CANON_Scanner * s)1823 do_focus (CANON_Scanner * s)
1824 {
1825   SANE_Status status;
1826   u_char ebuf[74];
1827   size_t buf_size;
1828 
1829   DBG (3, "do_focus: sending GET FILM STATUS\n");
1830   memset (ebuf, 0, sizeof (ebuf));
1831   buf_size = 4;
1832   status = get_film_status (s->fd, ebuf, &buf_size);
1833   if (status != SANE_STATUS_GOOD)
1834     {
1835       DBG (1, "do_focus: GET FILM STATUS failed\n");
1836       if (status == SANE_STATUS_UNSUPPORTED)
1837 	return (SANE_STATUS_GOOD);
1838       else
1839 	{
1840 	  DBG (1, "do_focus: ... for unknown reasons\n");
1841 	  sanei_scsi_close (s->fd);
1842 	  s->fd = -1;
1843 	  return (SANE_STATUS_INVAL);
1844 	}
1845     }
1846   DBG (3, "focus point before autofocus : %d\n", ebuf[3]);
1847 
1848   status = execute_auto_focus (s->fd, s->val[OPT_AF].w,
1849     (s->scanning_speed == 0 && !s->RIF && s->hw->info.model == CS2700),
1850     (int) s->AE, s->val[OPT_FOCUS].w);
1851   if (status != SANE_STATUS_GOOD)
1852     {
1853       DBG (7, "execute_auto_focus failed\n");
1854       if (status == SANE_STATUS_UNSUPPORTED)
1855 	  return (SANE_STATUS_GOOD);
1856       else
1857 	{
1858 	  DBG (1, "do_focus: ... for unknown reasons\n");
1859 	  sanei_scsi_close (s->fd);
1860 	  s->fd = -1;
1861 	  return (SANE_STATUS_INVAL);
1862 	}
1863     }
1864 
1865   DBG (3, "do_focus: sending GET FILM STATUS\n");
1866   memset (ebuf, 0, sizeof (ebuf));
1867   buf_size = 4;
1868   status = get_film_status (s->fd, ebuf, &buf_size);
1869   if (status != SANE_STATUS_GOOD)
1870     {
1871       DBG (1, "do_focus: GET FILM STATUS failed\n");
1872       if (status == SANE_STATUS_UNSUPPORTED)
1873 	  return (SANE_STATUS_GOOD);
1874       else
1875 	{
1876 	  DBG (1, "do_focus: ... for unknown reasons\n");
1877 	  sanei_scsi_close (s->fd);
1878 	  s->fd = -1;
1879 	  return (SANE_STATUS_INVAL);
1880 	}
1881     }
1882   else
1883       DBG (3, "focus point after autofocus : %d\n", ebuf[3]);
1884 
1885   return (SANE_STATUS_GOOD);
1886 }
1887 
1888 /**************************************************************************/
1889 
1890 #include "canon-sane.c"
1891