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