1 /* sane - Scanner Access Now Easy.
2
3 This file is part of the SANE package.
4
5 This program is free software; you can redistribute it and/or
6 modify it under the terms of the GNU General Public License as
7 published by the Free Software Foundation; either version 2 of the
8 License, or (at your option) any later version.
9
10 This program is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program. If not, see <https://www.gnu.org/licenses/>.
17
18 As a special exception, the authors of SANE give permission for
19 additional uses of the libraries contained in this release of SANE.
20
21 The exception is that, if you link a SANE library with other files
22 to produce an executable, this does not by itself cause the
23 resulting executable to be covered by the GNU General Public
24 License. Your use of that executable is in no way restricted on
25 account of linking the SANE library code into it.
26
27 This exception does not, however, invalidate any other reasons why
28 the executable file might be covered by the GNU General Public
29 License.
30
31 If you submit changes to SANE to the maintainers to be included in
32 a subsequent release, you agree by submitting the changes that
33 those changes may be distributed with this exception intact.
34
35 If you write modifications of your own for SANE, it is your choice
36 whether to permit this exception to apply to your modifications.
37 If you do not wish that, delete this exception notice.
38
39 This file implements a SANE backend for Fujitsu ScanParner 15C
40 flatbed/ADF scanners. It was derived from the COOLSCAN driver.
41 Written by Randolph Bentson <bentson@holmsjoen.com> */
42
43 /*
44 * Revision 1.17 2008/11/26 21:21:30 kitno-guest
45 * * backend/ *.[ch]: nearly every backend used V_MAJOR
46 * instead of SANE_CURRENT_MAJOR in sane_init()
47 * * backend/snapscan.c: remove EXPECTED_VERSION check
48 * since new SANE standard is forward compatible
49 *
50 * Revision 1.16 2008-07-26 03:53:44 kitno-guest
51 * separate x-resolution from resolution, and update all backends that use
52 * it, to prevent ui change
53 *
54 * Revision 1.15 2007-11-18 10:59:18 ellert-guest
55 * Fix handling of valid "negative" PIDs
56 *
57 * Revision 1.14 2007-10-26 14:56:38 jblache
58 * OPT_NUM_OPTS must be of type SANE_TYPE_INT.
59 *
60 * Revision 1.13 2006/03/29 20:48:50 hmg-guest
61 * Fixed ADF support. Patch from Andreas Degert <ad@papyrus-gmbh.de>.
62 *
63 * Revision 1.12 2005/10/01 17:06:25 hmg-guest
64 * Fixed some warnings (bug #302290).
65 *
66 * Revision 1.11 2005/07/15 18:12:49 hmg-guest
67 * Better 4->8 bit depth expansion algorithm (from Mattias Ellert
68 * <mattias.ellert@tsl.uu.se>).
69 *
70 * Revision 1.10 2004/10/06 15:59:40 hmg-guest
71 * Don't eject medium twice after each page.
72 *
73 * Revision 1.9 2004/06/20 00:34:10 ellert-guest
74 * Missed one...
75 *
76 * Revision 1.8 2004/05/29 10:27:47 hmg-guest
77 * Fixed the fix of the sanei_thread fix (from Mattias Ellert).
78 *
79 * Revision 1.7 2004/05/28 18:52:53 hmg-guest
80 * Fixed sanei_thread fix (bug #300634, by Mattias Ellert).
81 *
82 * Revision 1.6 2004/05/23 17:28:56 hmg-guest
83 * Use sanei_thread instead of fork() in the unmaintained backends.
84 * Patches from Mattias Ellert (bugs: 300635, 300634, 300633, 300629).
85 *
86 * Revision 1.5 2003/12/27 17:48:38 hmg-guest
87 * Silenced some compilation warnings.
88 *
89 * Revision 1.4 2001/05/31 18:01:39 hmg
90 * Fixed config_line[len-1] bug which could generate an access
91 * violation if len==0.
92 * Henning Meier-Geinitz <henning@meier-geinitz.de>
93 *
94 * Revision 1.3 2000/08/12 15:09:38 pere
95 * Merge devel (v1.0.3) into head branch.
96 *
97 * Revision 1.1.2.6 2000/07/30 11:16:06 hmg
98 * 2000-07-30 Henning Meier-Geinitz <hmg@gmx.de>
99 *
100 * * backend/mustek.*: Update to Mustek backend 1.0-95. Changed from
101 * wait() to waitpid() and removed unused code.
102 * * configure configure.in backend/m3096g.c backend/sp15c.c: Reverted
103 * the V_REV patch. V_REV should not be used in backends.
104 *
105 * Revision 1.1.2.5 2000/07/29 21:38:13 hmg
106 * 2000-07-29 Henning Meier-Geinitz <hmg@gmx.de>
107 *
108 * * backend/sp15.c backend/m3096g.c: Replace fgets with
109 * sanei_config_read, return V_REV as part of version_code string
110 * (patch from Randolph Bentson).
111 *
112 * Revision 1.1.2.4 2000/07/25 21:47:46 hmg
113 * 2000-07-25 Henning Meier-Geinitz <hmg@gmx.de>
114 *
115 * * backend/snapscan.c: Use DBG(0, ...) instead of fprintf (stderr, ...).
116 * * backend/abaton.c backend/agfafocus.c backend/apple.c backend/dc210.c
117 * backend/dll.c backend/dmc.c backend/microtek2.c backend/pint.c
118 * backend/qcam.c backend/ricoh.c backend/s9036.c backend/snapscan.c
119 * backend/tamarack.c: Use sanei_config_read instead of fgets.
120 * * backend/dc210.c backend/microtek.c backend/pnm.c: Added
121 * #include "../include/sane/config.h".
122 * * backend/dc25.c backend/m3096.c backend/sp15.c
123 * backend/st400.c: Moved #include "../include/sane/config.h" to the beginning.
124 * * AUTHORS: Changed agfa to agfafocus.
125 *
126 * Revision 1.1.2.3 2000/03/14 17:47:12 abel
127 * new version of the Sharp backend added.
128 *
129 * Revision 1.1.2.2 2000/01/26 03:51:48 pere
130 * Updated backends sp15c (v1.12) and m3096g (v1.11).
131 *
132 * Revision 1.12 2000/01/25 16:23:13 bentson
133 * tab expansion; add one debug message
134 *
135 * Revision 1.11 2000/01/05 05:21:37 bentson
136 * indent to barfable GNU style
137 *
138 * Revision 1.10 1999/12/06 17:36:55 bentson
139 * show default value for scan size at the start
140 *
141 * Revision 1.9 1999/12/04 00:30:35 bentson
142 * fold in 1.8.1.x versions
143 *
144 * Revision 1.8.1.2 1999/12/04 00:19:43 bentson
145 * bunch of changes to complete MEDIA CHECK use
146 *
147 * Revision 1.8.1.1 1999/12/03 20:44:56 bentson
148 * trial changes to use MEDIA CHECK command
149 *
150 * Revision 1.8 1999/12/03 18:30:56 bentson
151 * cosmetic changes
152 *
153 * Revision 1.7 1999/11/24 20:09:25 bentson
154 * fold in 1.6.1.x changes
155 *
156 * Revision 1.6.1.3 1999/11/24 15:56:48 bentson
157 * remove some debugging; final :-) fix to option constraint processing
158 *
159 * Revision 1.6.1.2 1999/11/24 15:37:42 bentson
160 * more constraint debugging
161 *
162 * Revision 1.6.1.1 1999/11/24 14:35:24 bentson
163 * fix some of the constraint handling
164 *
165 * Revision 1.6 1999/11/23 18:48:27 bentson
166 * add constraint checking and enforcement
167 *
168 * Revision 1.5 1999/11/23 08:26:03 bentson
169 * basic color seems to work
170 *
171 * Revision 1.4 1999/11/23 06:41:26 bentson
172 * 4-bit Grayscale works; now working on color
173 *
174 * Revision 1.3 1999/11/22 18:15:07 bentson
175 * more work on color support
176 *
177 * Revision 1.2 1999/11/19 17:30:54 bentson
178 * enhance control (works with xscanimage)
179 *
180 * Revision 1.1 1999/11/19 15:09:08 bentson
181 * cribbed from m3096g
182 *
183 */
184
185 /* SANE-FLOW-DIAGRAM
186
187 - sane_init() : initialize backend, attach scanners
188 . - sane_get_devices() : query list of scanner-devices
189 . - sane_open() : open a particular scanner-device
190 . . - sane_set_io_mode : set blocking-mode
191 . . - sane_get_select_fd : get scanner-fd
192 . . - sane_get_option_descriptor() : get option information
193 . . - sane_control_option() : change option values
194 . .
195 . . - sane_start() : start image acquisition
196 . . - sane_get_parameters() : returns actual scan-parameters
197 . . - sane_read() : read image-data (from pipe)
198 . .
199 . . - sane_cancel() : cancel operation
200 . - sane_close() : close opened scanner-device
201 - sane_exit() : terminate use of backend
202 */
203
204 /* ------------------------------------------------------------------------- */
205
206 #include "../include/sane/config.h"
207
208 #include <errno.h>
209 #include <fcntl.h>
210 #include <limits.h>
211 #include <signal.h>
212 #include <stdio.h>
213 #include <stdlib.h>
214 #include <string.h>
215
216 #include <sys/types.h>
217 #include <unistd.h>
218
219 #include "../include/sane/sanei_backend.h"
220 #include "../include/sane/sanei_scsi.h"
221 #include "../include/sane/saneopts.h"
222 #include "../include/sane/sanei_config.h"
223 #include "../include/sane/sanei_thread.h"
224
225 #include "sp15c-scsi.h"
226 #include "sp15c.h"
227
228 /* ------------------------------------------------------------------------- */
229
230 static const char negativeStr[] = "Negative";
231 static const char positiveStr[] = "Positive";
232 static SANE_String_Const type_list[] =
233 {positiveStr, negativeStr, 0};
234
235 static SANE_String_Const source_list[] =
236 {"ADF", "FB", NULL};
237
238 static const SANE_Int resolution_list[] =
239 {11, 0, 60, 75, 80, 100, 120, 150, 200, 240, 300, 600};
240
241 static const SANE_Int x_res_list[] =
242 {11, 0, 60, 75, 80, 100, 120, 150, 200, 240, 300, 600};
243
244 static const SANE_Int y_res_list[] =
245 {11, 0, 60, 75, 80, 100, 120, 150, 200, 240, 300, 600};
246
247 static const char lineStr[] = SANE_VALUE_SCAN_MODE_LINEART;
248 static const char halfStr[] = SANE_VALUE_SCAN_MODE_HALFTONE;
249 static const char gray4Str[] = "4-bit Gray";
250 static const char gray8Str[] = "8-bit Gray";
251 static const char colorStr[] = SANE_VALUE_SCAN_MODE_COLOR;
252 static SANE_String_Const scan_mode_list[] =
253 {lineStr, halfStr, gray4Str, gray8Str, colorStr, NULL};
254
255 /* how do the following work? */
256 static const SANE_Range brightness_range =
257 {0, 255, 32};
258 static const SANE_Range threshold_range =
259 {0, 255, 4};
260 static const SANE_Range x_range =
261 {0, SANE_FIX (216), 1};
262 static const SANE_Range y_range_fb =
263 {0, SANE_FIX (295), 1};
264 static const SANE_Range y_range_adf =
265 {0, SANE_FIX (356), 1};
266
267 /* ################# externally visible routines ################{ */
268
269
270 SANE_Status /* looks like frontend ignores results */
sane_init(SANE_Int * version_code, SANE_Auth_Callback authorize)271 sane_init (SANE_Int * version_code, SANE_Auth_Callback authorize)
272 {
273 char dev_name[PATH_MAX];
274 size_t len;
275 FILE *fp;
276 (void) authorize; /* silence compilation warnings */
277
278 DBG_INIT ();
279 DBG (10, "sane_init\n");
280
281 sanei_thread_init ();
282
283 if (version_code)
284 *version_code = SANE_VERSION_CODE (SANE_CURRENT_MAJOR, SANE_CURRENT_MINOR, 0);
285 fp = sanei_config_open (SP15C_CONFIG_FILE);
286 if (!fp)
287 {
288 attach_scanner ("/dev/scanner", 0); /* no config-file: /dev/scanner */
289 return SANE_STATUS_GOOD;
290 }
291
292 while (sanei_config_read (dev_name, sizeof (dev_name), fp))
293 {
294 if (dev_name[0] == '#')
295 continue;
296 len = strlen (dev_name);
297 if (!len)
298 continue;
299 sanei_config_attach_matching_devices (dev_name, attach_one);
300 }
301
302 fclose (fp);
303 return SANE_STATUS_GOOD;
304 } /* sane_init */
305
306
307 SANE_Status
sane_get_devices(const SANE_Device *** device_list, SANE_Bool local_only)308 sane_get_devices (const SANE_Device *** device_list, SANE_Bool local_only)
309 {
310 struct sp15c *dev;
311 int i;
312
313 (void) local_only; /* silence compilation warnings */
314
315 DBG (10, "sane_get_devices\n");
316
317 if (devlist)
318 free (devlist);
319 devlist = calloc (num_devices + 1, sizeof (devlist[0]));
320 if (!devlist)
321 return SANE_STATUS_NO_MEM;
322
323 for (dev = first_dev, i = 0; i < num_devices; dev = dev->next)
324 devlist[i++] = &dev->sane;
325 devlist[i++] = 0;
326
327 *device_list = devlist;
328
329 return SANE_STATUS_GOOD;
330 } /* sane_get_devices */
331
332
333 SANE_Status
sane_open(SANE_String_Const name, SANE_Handle * handle)334 sane_open (SANE_String_Const name, SANE_Handle * handle)
335 {
336 struct sp15c *dev = first_dev;
337
338 (void) name; /* silence compilation warnings */
339 /* Strange, name is not used? */
340
341 DBG (10, "sane_open\n");
342
343 if (!dev)
344 return SANE_STATUS_INVAL;
345
346 init_options (dev);
347 *handle = dev;
348
349 dev->use_adf = SANE_TRUE;
350
351 dev->x_res = 200;
352 dev->y_res = 200;
353 dev->tl_x = 0;
354 dev->tl_y = 0;
355 dev->br_x = 1200 * 17 / 2;
356 dev->br_y = 1200 * 11;
357 dev->brightness = 128;
358 dev->threshold = 128;
359 dev->contrast = 128;
360 dev->composition = WD_comp_LA;
361 dev->opt[OPT_BRIGHTNESS].cap = SANE_CAP_INACTIVE;
362 dev->opt[OPT_THRESHOLD].cap = SANE_CAP_SOFT_DETECT
363 | SANE_CAP_SOFT_SELECT;
364 dev->bitsperpixel = 1;
365 dev->halftone = 0;
366 dev->rif = 0;
367 dev->bitorder = 0;
368 dev->compress_type = 0;
369 dev->compress_arg = 0;
370 dev->vendor_id_code = 0;
371 dev->outline = 0;
372 dev->emphasis = 0;
373 dev->auto_sep = 0;
374 dev->mirroring = 0;
375 dev->var_rate_dyn_thresh = 0;
376 dev->white_level_follow = 0;
377 dev->paper_size = 0x87;
378 dev->paper_width_X = 1200 * 17 / 2;
379 dev->paper_length_Y = 1200 * 11;
380 dev->opt[OPT_TL_Y].constraint.range = &y_range_adf;
381 dev->opt[OPT_BR_Y].constraint.range = &y_range_adf;
382 adjust_width (dev, 0);
383
384 return SANE_STATUS_GOOD;
385 } /* sane_open */
386
387
388 SANE_Status
sane_set_io_mode(SANE_Handle h, SANE_Bool non_blocking)389 sane_set_io_mode (SANE_Handle h, SANE_Bool non_blocking)
390 {
391 (void) h;
392 (void) non_blocking; /* silence compilation warnings */
393
394 DBG (10, "sane_set_io_mode\n");
395 return SANE_STATUS_UNSUPPORTED;
396 } /* sane_set_io_mode */
397
398
399 SANE_Status
sane_get_select_fd(SANE_Handle h, SANE_Int * fdp)400 sane_get_select_fd (SANE_Handle h, SANE_Int * fdp)
401 {
402 (void) h;
403 (void) fdp; /* silence compilation warnings */
404
405 DBG (10, "sane_get_select_fd\n");
406 return SANE_STATUS_UNSUPPORTED;
407 } /* sane_get_select_fd */
408
409
410 const SANE_Option_Descriptor *
sane_get_option_descriptor(SANE_Handle handle, SANE_Int option)411 sane_get_option_descriptor (SANE_Handle handle, SANE_Int option)
412 {
413 struct sp15c *scanner = handle;
414
415 DBG (10, "sane_get_option_descriptor: \"%s\"\n",
416 scanner->opt[option].name);
417
418 if ((unsigned) option >= NUM_OPTIONS)
419 return 0;
420 return &scanner->opt[option];
421 } /* sane_get_option_descriptor */
422
423
424 SANE_Status
sane_control_option(SANE_Handle handle, SANE_Int option, SANE_Action action, void *val, SANE_Int * info)425 sane_control_option (SANE_Handle handle, SANE_Int option,
426 SANE_Action action, void *val,
427 SANE_Int * info)
428 {
429 struct sp15c *scanner = handle;
430 SANE_Status status;
431 SANE_Word cap;
432
433 if (info)
434 *info = 0;
435
436 if (scanner->scanning == SANE_TRUE)
437 {
438 DBG (5, "sane_control_option: device busy\n");
439 return SANE_STATUS_IO_ERROR;
440 }
441
442 if (option >= NUM_OPTIONS)
443 return SANE_STATUS_INVAL;
444
445 cap = scanner->opt[option].cap;
446
447 if (action == SANE_ACTION_GET_VALUE)
448 {
449 DBG (10, "sane_control_option: get value \"%s\"\n",
450 scanner->opt[option].name);
451 DBG (11, "\tcap = %d\n", cap);
452
453 if (!SANE_OPTION_IS_ACTIVE (cap))
454 {
455 DBG (10, "\tinactive\n");
456 return SANE_STATUS_INVAL;
457 }
458
459 switch (option)
460 {
461
462 case OPT_NUM_OPTS:
463 *(SANE_Word *) val = NUM_OPTIONS;
464 return SANE_STATUS_GOOD;
465
466 case OPT_SOURCE:
467 if (scanner->use_adf == SANE_TRUE)
468 {
469 strcpy (val, "ADF");
470 }
471 else
472 {
473 strcpy (val, "FB");
474 }
475 return SANE_STATUS_GOOD;
476
477 case OPT_MODE:
478 switch (scanner->composition)
479 {
480 case WD_comp_LA:
481 strcpy (val, lineStr);
482 break;
483 case WD_comp_HT:
484 strcpy (val, halfStr);
485 break;
486 case WD_comp_G4:
487 strcpy (val, gray4Str);
488 break;
489 case WD_comp_G8:
490 strcpy (val, gray8Str);
491 break;
492 case WD_comp_MC:
493 strcpy (val, colorStr);
494 break;
495 default:
496 return SANE_STATUS_INVAL;
497 }
498 return SANE_STATUS_GOOD;
499
500 case OPT_TYPE:
501 return SANE_STATUS_INVAL;
502
503 case OPT_PRESCAN:
504 return SANE_STATUS_INVAL;
505
506 case OPT_X_RES:
507 *(SANE_Word *) val = scanner->x_res;
508 return SANE_STATUS_GOOD;
509
510 case OPT_Y_RES:
511 *(SANE_Word *) val = scanner->y_res;
512 return SANE_STATUS_GOOD;
513
514 case OPT_PREVIEW_RES:
515 return SANE_STATUS_INVAL;
516
517 case OPT_TL_X:
518 *(SANE_Word *) val = SANE_FIX (iluToMm (scanner->tl_x));
519 return SANE_STATUS_GOOD;
520
521 case OPT_TL_Y:
522 *(SANE_Word *) val = SANE_FIX (iluToMm (scanner->tl_y));
523 return SANE_STATUS_GOOD;
524
525 case OPT_BR_X:
526 *(SANE_Word *) val = SANE_FIX (iluToMm (scanner->br_x));
527 return SANE_STATUS_GOOD;
528
529 case OPT_BR_Y:
530 *(SANE_Word *) val = SANE_FIX (iluToMm (scanner->br_y));
531 return SANE_STATUS_GOOD;
532
533 case OPT_AVERAGING:
534 return SANE_STATUS_INVAL;
535
536 case OPT_BRIGHTNESS:
537 *(SANE_Word *) val = scanner->brightness;
538 return SANE_STATUS_GOOD;
539
540 case OPT_THRESHOLD:
541 *(SANE_Word *) val = scanner->threshold;
542 return SANE_STATUS_GOOD;
543
544 case OPT_PREVIEW:
545 return SANE_STATUS_INVAL;
546
547 }
548
549 }
550 else if (action == SANE_ACTION_SET_VALUE)
551 {
552 DBG (10, "sane_control_option: set value \"%s\"\n",
553 scanner->opt[option].name);
554
555 if (!SANE_OPTION_IS_ACTIVE (cap))
556 {
557 DBG (10, "\tinactive\n");
558 return SANE_STATUS_INVAL;
559 }
560
561 if (!SANE_OPTION_IS_SETTABLE (cap))
562 {
563 DBG (10, "\tnot settable\n");
564 return SANE_STATUS_INVAL;
565 }
566
567 status = sanei_constrain_value (scanner->opt + option, val, info);
568 if (status != SANE_STATUS_GOOD)
569 {
570 DBG (10, "\tbad value\n");
571 return status;
572 }
573
574 switch (option)
575 {
576
577 case OPT_NUM_OPTS:
578 return SANE_STATUS_GOOD;
579
580 case OPT_SOURCE:
581 if (strcmp (val, "ADF") == 0)
582 {
583 if (scanner->use_adf == SANE_TRUE)
584 return SANE_STATUS_GOOD;
585 scanner->use_adf = SANE_TRUE;
586 scanner->opt[OPT_TL_Y].constraint.range = &y_range_adf;
587 scanner->opt[OPT_BR_Y].constraint.range = &y_range_adf;
588 apply_constraints (scanner, OPT_TL_Y, &scanner->tl_y, info);
589 apply_constraints (scanner, OPT_BR_Y, &scanner->br_y, info);
590 }
591 else if (strcmp (val, "FB") == 0)
592 {
593 if (scanner->use_adf == SANE_FALSE)
594 return SANE_STATUS_GOOD;
595 scanner->use_adf = SANE_FALSE;
596 scanner->opt[OPT_TL_Y].constraint.range = &y_range_fb;
597 scanner->opt[OPT_BR_Y].constraint.range = &y_range_fb;
598 apply_constraints (scanner, OPT_TL_Y, &scanner->tl_y, info);
599 apply_constraints (scanner, OPT_BR_Y, &scanner->br_y, info);
600 }
601 else
602 {
603 return SANE_STATUS_INVAL;
604 }
605 if (info)
606 {
607 *info |= SANE_INFO_RELOAD_PARAMS | SANE_INFO_RELOAD_OPTIONS;
608 }
609 return SANE_STATUS_GOOD;
610
611 case OPT_MODE:
612 if (strcmp (val, lineStr) == 0)
613 {
614 if (scanner->composition == WD_comp_LA)
615 return SANE_STATUS_GOOD;
616 scanner->composition = WD_comp_LA;
617 scanner->bitsperpixel = 1;
618 scanner->opt[OPT_BRIGHTNESS].cap = SANE_CAP_INACTIVE;
619 scanner->opt[OPT_THRESHOLD].cap = SANE_CAP_SOFT_DETECT
620 | SANE_CAP_SOFT_SELECT;
621 scanner->vendor_id_code = 0;
622 }
623 else if (strcmp (val, halfStr) == 0)
624 {
625 if (scanner->composition == WD_comp_HT)
626 return SANE_STATUS_GOOD;
627 scanner->composition = WD_comp_HT;
628 scanner->bitsperpixel = 1;
629 scanner->opt[OPT_BRIGHTNESS].cap = SANE_CAP_SOFT_DETECT
630 | SANE_CAP_SOFT_SELECT;
631 scanner->opt[OPT_THRESHOLD].cap = SANE_CAP_INACTIVE;
632 scanner->vendor_id_code = 0;
633 }
634 else if (strcmp (val, gray4Str) == 0)
635 {
636 if (scanner->composition == WD_comp_G4)
637 return SANE_STATUS_GOOD;
638 scanner->composition = WD_comp_G4;
639 scanner->bitsperpixel = 4;
640 scanner->opt[OPT_BRIGHTNESS].cap = SANE_CAP_INACTIVE;
641 scanner->opt[OPT_THRESHOLD].cap = SANE_CAP_INACTIVE;
642 scanner->vendor_id_code = 0;
643 }
644 else if (strcmp (val, gray8Str) == 0)
645 {
646 if (scanner->composition == WD_comp_G8)
647 return SANE_STATUS_GOOD;
648 scanner->composition = WD_comp_G8;
649 scanner->bitsperpixel = 8;
650 scanner->opt[OPT_BRIGHTNESS].cap = SANE_CAP_INACTIVE;
651 scanner->opt[OPT_THRESHOLD].cap = SANE_CAP_INACTIVE;
652 scanner->vendor_id_code = 0;
653 }
654 else if (strcmp (val, colorStr) == 0)
655 {
656 if (scanner->composition == WD_comp_MC)
657 return SANE_STATUS_GOOD;
658 scanner->composition = WD_comp_MC;
659 scanner->bitsperpixel = 8;
660 scanner->opt[OPT_BRIGHTNESS].cap = SANE_CAP_INACTIVE;
661 scanner->opt[OPT_THRESHOLD].cap = SANE_CAP_INACTIVE;
662 scanner->vendor_id_code = 0xff;
663 }
664 else
665 {
666 return SANE_STATUS_INVAL;
667 }
668 if (info)
669 {
670 *info |= SANE_INFO_RELOAD_PARAMS | SANE_INFO_RELOAD_OPTIONS;
671 }
672 return SANE_STATUS_GOOD;
673
674 case OPT_TYPE:
675 return SANE_STATUS_INVAL;
676
677 case OPT_PRESCAN:
678 return SANE_STATUS_INVAL;
679
680 case OPT_X_RES:
681 scanner->x_res = (*(SANE_Word *) val);
682 adjust_width (scanner, info);
683 if (info)
684 {
685 *info |= SANE_INFO_RELOAD_PARAMS;
686 }
687 return SANE_STATUS_GOOD;
688
689 case OPT_Y_RES:
690 scanner->y_res = (*(SANE_Word *) val);
691 if (info)
692 {
693 *info |= SANE_INFO_RELOAD_PARAMS;
694 }
695 return SANE_STATUS_GOOD;
696
697 case OPT_PREVIEW_RES:
698 return SANE_STATUS_INVAL;
699
700 case OPT_TL_X:
701 scanner->tl_x = mmToIlu (SANE_UNFIX (*(SANE_Word *) val));
702 adjust_width (scanner, info);
703 *(SANE_Word *) val = SANE_FIX (iluToMm (scanner->tl_x));
704 if (info)
705 {
706 *info |= SANE_INFO_RELOAD_PARAMS | SANE_INFO_INEXACT;
707 }
708 return SANE_STATUS_GOOD;
709
710 case OPT_TL_Y:
711 scanner->tl_y = mmToIlu (SANE_UNFIX (*(SANE_Word *) val));
712 *(SANE_Word *) val = SANE_FIX (iluToMm (scanner->tl_y));
713 if (info)
714 {
715 *info |= SANE_INFO_RELOAD_PARAMS | SANE_INFO_INEXACT;
716 }
717 return SANE_STATUS_GOOD;
718
719 case OPT_BR_X:
720 scanner->br_x = mmToIlu (SANE_UNFIX (*(SANE_Word *) val));
721 adjust_width (scanner, info);
722 *(SANE_Word *) val = SANE_FIX (iluToMm (scanner->br_x));
723 if (info)
724 {
725 *info |= SANE_INFO_RELOAD_PARAMS | SANE_INFO_INEXACT;
726 }
727 return SANE_STATUS_GOOD;
728
729 case OPT_BR_Y:
730 scanner->br_y = mmToIlu (SANE_UNFIX (*(SANE_Word *) val));
731 *(SANE_Word *) val = SANE_FIX (iluToMm (scanner->br_y));
732 if (info)
733 {
734 *info |= SANE_INFO_RELOAD_PARAMS | SANE_INFO_INEXACT;
735 }
736 return SANE_STATUS_GOOD;
737
738 case OPT_AVERAGING:
739 return SANE_STATUS_INVAL;
740
741 case OPT_BRIGHTNESS:
742 scanner->brightness = *(SANE_Word *) val;
743 return SANE_STATUS_GOOD;
744
745 case OPT_THRESHOLD:
746 scanner->threshold = *(SANE_Word *) val;
747 return SANE_STATUS_GOOD;
748
749 } /* switch */
750 } /* else */
751 return SANE_STATUS_INVAL;
752 } /* sane_control_option */
753
754
755 SANE_Status
sane_start(SANE_Handle handle)756 sane_start (SANE_Handle handle)
757 {
758 struct sp15c *scanner = handle;
759 int fds[2];
760 int ret;
761
762 DBG (10, "sane_start\n");
763 if (scanner->scanning == SANE_TRUE)
764 {
765 DBG (5, "sane_start: device busy\n");
766 return SANE_STATUS_DEVICE_BUSY;
767 }
768
769 if (scanner->sfd < 0)
770 { /* first call */
771 if (sanei_scsi_open (scanner->sane.name, &(scanner->sfd),
772 sense_handler, 0) != SANE_STATUS_GOOD)
773 {
774 DBG (1, "sane_start: open of %s failed:\n",
775 scanner->sane.name);
776 return SANE_STATUS_INVAL;
777 }
778 }
779 scanner->scanning = SANE_TRUE;
780
781
782 if ((ret = sp15c_check_values (scanner)) != 0)
783 { /* Verify values */
784 DBG (1, "sane_start: ERROR: invalid scan-values\n");
785 sanei_scsi_close (scanner->sfd);
786 scanner->scanning = SANE_FALSE;
787 scanner->sfd = -1;
788 return SANE_STATUS_INVAL;
789 }
790
791 if ((ret = sp15c_grab_scanner (scanner)))
792 {
793 DBG (5, "sane_start: unable to reserve scanner\n");
794 sanei_scsi_close (scanner->sfd);
795 scanner->scanning = SANE_FALSE;
796 scanner->sfd = -1;
797 return ret;
798 }
799
800 if ((ret = sp15c_set_window_param (scanner, 0)))
801 {
802 DBG (5, "sane_start: ERROR: failed to set window\n");
803 sp15c_free_scanner (scanner);
804 sanei_scsi_close (scanner->sfd);
805 scanner->scanning = SANE_FALSE;
806 scanner->sfd = -1;
807 return ret;
808 }
809
810 /* Since the SET WINDOW can specify the use of the ADF, and since the
811 ScanPartner 15C automatically pre-loads sheets from the ADF, it
812 is only necessary to see if any paper is available. The OEM
813 Manual offers the OBJECT POSITION command, but it causes the
814 carrier unit into a "homing" cycle. The undocumented MEDIA CHECK
815 command avoids the "homing" cycle. (Note the SET WINDOW command
816 had to use the color scanning vendor unique parameters, regardless
817 of scanning mode, so that it could invoke the ADF.) */
818 if (scanner->use_adf == SANE_TRUE
819 && (ret = sp15c_media_check (scanner)))
820 {
821 DBG (5, "sane_start: WARNING: ADF empty\n");
822 sp15c_free_scanner (scanner);
823 sanei_scsi_close (scanner->sfd);
824 scanner->scanning = SANE_FALSE;
825 scanner->sfd = -1;
826 return ret;
827 }
828
829 swap_res (scanner);
830
831 DBG (10, "\tbytes per line = %d\n", bytes_per_line (scanner));
832 DBG (10, "\tpixels_per_line = %d\n", pixels_per_line (scanner));
833 DBG (10, "\tlines = %d\n", lines_per_scan (scanner));
834 DBG (10, "\tbrightness (halftone) = %d\n", scanner->brightness);
835 DBG (10, "\tthreshold (line art) = %d\n", scanner->threshold);
836
837 if (scanner->composition == WD_comp_MC
838 && (ret = sp15c_start_scan (scanner)))
839 {
840 DBG (5, "sane_start: start_scan failed\n");
841 sp15c_free_scanner (scanner);
842 sanei_scsi_close (scanner->sfd);
843 scanner->scanning = SANE_FALSE;
844 scanner->sfd = -1;
845 return SANE_STATUS_INVAL;
846 }
847
848 /* create a pipe, fds[0]=read-fd, fds[1]=write-fd */
849 if (pipe (fds) < 0)
850 {
851 DBG (1, "ERROR: could not create pipe\n");
852 swap_res (scanner);
853 scanner->scanning = SANE_FALSE;
854 sp15c_free_scanner (scanner);
855 sanei_scsi_close (scanner->sfd);
856 scanner->sfd = -1;
857 return SANE_STATUS_IO_ERROR;
858 }
859
860 scanner->pipe = fds[0];
861 scanner->reader_pipe = fds[1];
862 scanner->reader_pid = sanei_thread_begin (reader_process, (void *) scanner);
863
864 if (sanei_thread_is_forked ())
865 close (scanner->reader_pipe);
866
867 DBG (10, "sane_start: ok\n");
868 return SANE_STATUS_GOOD;
869 } /* sane_start */
870
871
872 SANE_Status
sane_get_parameters(SANE_Handle handle, SANE_Parameters * params)873 sane_get_parameters (SANE_Handle handle, SANE_Parameters * params)
874 {
875 struct sp15c *scanner = handle;
876
877 DBG (10, "sane_get_parameters\n");
878 if (scanner->composition == WD_comp_MC)
879 {
880 params->format = SANE_FRAME_RGB;
881 params->depth = 8;
882 }
883 else if (scanner->composition == WD_comp_LA
884 || scanner->composition == WD_comp_HT)
885 {
886 params->format = SANE_FRAME_GRAY;
887 params->depth = 1;
888 }
889 else
890 {
891 params->format = SANE_FRAME_GRAY;
892 params->depth = 8;
893 }
894
895 params->pixels_per_line = pixels_per_line (scanner);
896 params->lines = lines_per_scan (scanner);
897 params->bytes_per_line = bytes_per_line (scanner);
898 params->last_frame = 1;
899
900 DBG (10, "\tdepth %d\n", params->depth);
901 DBG (10, "\tlines %d\n", params->lines);
902 DBG (10, "\tpixels_per_line %d\n", params->pixels_per_line);
903 DBG (10, "\tbytes_per_line %d\n", params->bytes_per_line);
904 /*************************/
905 DBG (10, "\tlength %d\n", scanner->br_y - scanner->tl_y);
906 DBG (10, "\t(nom.) width %d\n", scanner->br_x - scanner->tl_x);
907 DBG (10, "\tx res %d\n", scanner->x_res);
908 DBG (10, "\ty res %d\n", scanner->y_res);
909 /*************************/
910
911 return SANE_STATUS_GOOD;
912 } /* sane_get_parameters */
913
914
915 SANE_Status
sane_read(SANE_Handle handle, SANE_Byte * buf, SANE_Int max_len, SANE_Int * len)916 sane_read (SANE_Handle handle, SANE_Byte * buf,
917 SANE_Int max_len, SANE_Int * len)
918 {
919 struct sp15c *scanner = handle;
920 ssize_t nread;
921
922 DBG (10, "sane_read\n");
923 *len = 0;
924
925 nread = read (scanner->pipe, buf, max_len);
926 DBG (10, "sane_read: read %ld bytes of %ld\n",
927 (long) nread, (long) max_len);
928
929 if (scanner->scanning == SANE_FALSE)
930 {
931 /* PREDICATE WAS (!(scanner->scanning)) */
932 return do_cancel (scanner);
933 }
934
935 if (nread < 0)
936 {
937 if (errno == EAGAIN)
938 {
939 return SANE_STATUS_GOOD;
940 }
941 else
942 {
943 do_cancel (scanner);
944 return SANE_STATUS_IO_ERROR;
945 }
946 }
947
948 *len = nread;
949
950 if (nread == 0)
951 return do_eof (scanner); /* close pipe */
952
953 return SANE_STATUS_GOOD;
954 } /* sane_read */
955
956
957 void
sane_cancel(SANE_Handle h)958 sane_cancel (SANE_Handle h)
959 {
960 DBG (10, "sane_cancel\n");
961 do_cancel ((struct sp15c *) h);
962 } /* sane_cancel */
963
964
965 void
sane_close(SANE_Handle handle)966 sane_close (SANE_Handle handle)
967 {
968 DBG (10, "sane_close\n");
969 if (((struct sp15c *) handle)->scanning == SANE_TRUE)
970 do_cancel (handle);
971 } /* sane_close */
972
973
974 void
sane_exit(void)975 sane_exit (void)
976 {
977 struct sp15c *dev, *next;
978
979 DBG (10, "sane_exit\n");
980
981 for (dev = first_dev; dev; dev = next)
982 {
983 next = dev->next;
984 free (dev->devicename);
985 free (dev->buffer);
986 free (dev);
987 }
988
989 if (devlist)
990 free (devlist);
991 } /* sane_exit */
992
993 /* }################ internal (support) routines ################{ */
994
995 static SANE_Status
attach_scanner(const char *devicename, struct sp15c **devp)996 attach_scanner (const char *devicename, struct sp15c **devp)
997 {
998 struct sp15c *dev;
999 int sfd;
1000
1001 DBG (15, "attach_scanner: %s\n", devicename);
1002
1003 for (dev = first_dev; dev; dev = dev->next)
1004 {
1005 if (strcmp (dev->sane.name, devicename) == 0)
1006 {
1007 if (devp)
1008 {
1009 *devp = dev;
1010 }
1011 DBG (5, "attach_scanner: scanner already attached (is ok)!\n");
1012 return SANE_STATUS_GOOD;
1013 }
1014 }
1015
1016 DBG (15, "attach_scanner: opening %s\n", devicename);
1017 if (sanei_scsi_open (devicename, &sfd, sense_handler, 0) != 0)
1018 {
1019 DBG (5, "attach_scanner: open failed\n");
1020 return SANE_STATUS_INVAL;
1021 }
1022
1023 if (NULL == (dev = malloc (sizeof (*dev))))
1024 return SANE_STATUS_NO_MEM;
1025
1026 dev->row_bufsize = (sanei_scsi_max_request_size < (64 * 1024))
1027 ? sanei_scsi_max_request_size
1028 : 64 * 1024;
1029
1030 if ((dev->buffer = malloc (dev->row_bufsize)) == NULL)
1031 return SANE_STATUS_NO_MEM;
1032
1033 dev->devicename = strdup (devicename);
1034 dev->sfd = sfd;
1035
1036 if (sp15c_identify_scanner (dev) != 0)
1037 {
1038 DBG (5, "attach_scanner: scanner-identification failed\n");
1039 sanei_scsi_close (dev->sfd);
1040 free (dev->buffer);
1041 free (dev);
1042 return SANE_STATUS_INVAL;
1043 }
1044
1045 #if 0
1046 /* Get MUD (via mode_sense), internal info (via get_internal_info), and
1047 * initialize values */
1048 coolscan_initialize_values (dev);
1049 #endif
1050
1051 /* Why? */
1052 sanei_scsi_close (dev->sfd);
1053 dev->sfd = -1;
1054
1055 dev->sane.name = dev->devicename;
1056 dev->sane.vendor = dev->vendor;
1057 dev->sane.model = dev->product;
1058 dev->sane.type = "flatbed/ADF scanner";
1059
1060 ++num_devices;
1061 dev->next = first_dev;
1062 first_dev = dev;
1063
1064 if (devp)
1065 {
1066 *devp = dev;
1067 }
1068
1069 DBG (15, "attach_scanner: done\n");
1070
1071 return SANE_STATUS_GOOD;
1072 } /* attach_scanner */
1073
1074 static SANE_Status
attach_one(const char *name)1075 attach_one (const char *name)
1076 {
1077 return attach_scanner (name, 0);
1078 } /* attach_one */
1079
1080 static SANE_Status
sense_handler(int scsi_fd, u_char * result, void *arg)1081 sense_handler (int scsi_fd, u_char * result, void *arg)
1082 {
1083 (void) scsi_fd;
1084 (void) arg; /* silence compilation warnings */
1085
1086 return request_sense_parse (result);
1087 } /* sense_handler */
1088
1089 static int
request_sense_parse(u_char * sensed_data)1090 request_sense_parse (u_char * sensed_data)
1091 {
1092 unsigned int ret, sense, asc, ascq;
1093 sense = get_RS_sense_key (sensed_data);
1094 asc = get_RS_ASC (sensed_data);
1095 ascq = get_RS_ASCQ (sensed_data);
1096
1097 ret = SANE_STATUS_IO_ERROR;
1098
1099 switch (sense)
1100 {
1101 case 0x0: /* No Sense */
1102 DBG (5, "\t%d/%d/%d: Scanner ready\n", sense, asc, ascq);
1103 return SANE_STATUS_GOOD;
1104
1105 case 0x2: /* Not Ready */
1106 if ((0x00 == asc) && (0x00 == ascq))
1107 {
1108 DBG (1, "\t%d/%d/%d: Not Ready \n", sense, asc, ascq);
1109 }
1110 else
1111 {
1112 DBG (1, "\tUnknown - Sense=%d, ASC=%d, ASCQ=%d\n", sense, asc, ascq);
1113 }
1114 break;
1115
1116 case 0x3: /* Medium Error */
1117 if ((0x80 == asc) && (0x01 == ascq))
1118 {
1119 DBG (1, "\t%d/%d/%d: Jam \n", sense, asc, ascq);
1120 ret = SANE_STATUS_JAMMED;
1121 }
1122 else if ((0x80 == asc) && (0x02 == ascq))
1123 {
1124 DBG (1, "\t%d/%d/%d: ADF cover open \n", sense, asc, ascq);
1125 ret = SANE_STATUS_COVER_OPEN;
1126 }
1127 else if ((0x80 == asc) && (0x03 == ascq))
1128 {
1129 DBG (1, "\t%d/%d/%d: ADF empty \n", sense, asc, ascq);
1130 ret = SANE_STATUS_NO_DOCS;
1131 }
1132 else
1133 {
1134 DBG (1, "\tUnknown - Sense=%d, ASC=%d, ASCQ=%d\n", sense, asc, ascq);
1135 }
1136 break;
1137
1138 case 0x4: /* Hardware Error */
1139 if ((0x80 == asc) && (0x01 == ascq))
1140 {
1141 DBG (1, "\t%d/%d/%d: FB motor fuse \n", sense, asc, ascq);
1142 }
1143 else if ((0x80 == asc) && (0x02 == ascq))
1144 {
1145 DBG (1, "\t%d/%d/%d: heater fuse \n", sense, asc, ascq);
1146 }
1147 else if ((0x80 == asc) && (0x04 == ascq))
1148 {
1149 DBG (1, "\t%d/%d/%d: ADF motor fuse \n", sense, asc, ascq);
1150 }
1151 else if ((0x80 == asc) && (0x05 == ascq))
1152 {
1153 DBG (1, "\t%d/%d/%d: mechanical alarm \n", sense, asc, ascq);
1154 }
1155 else if ((0x80 == asc) && (0x06 == ascq))
1156 {
1157 DBG (1, "\t%d/%d/%d: optical alarm \n", sense, asc, ascq);
1158 }
1159 else if ((0x44 == asc) && (0x00 == ascq))
1160 {
1161 DBG (1, "\t%d/%d/%d: abnormal internal target \n", sense, asc, ascq);
1162 }
1163 else if ((0x47 == asc) && (0x00 == ascq))
1164 {
1165 DBG (1, "\t%d/%d/%d: SCSI parity error \n", sense, asc, ascq);
1166 }
1167 else
1168 {
1169 DBG (1, "\tUnknown - Sense=%d, ASC=%d, ASCQ=%d\n", sense, asc, ascq);
1170 }
1171 break;
1172
1173 case 0x5: /* Illegal Request */
1174 if ((0x20 == asc) && (0x00 == ascq))
1175 {
1176 DBG (1, "\t%d/%d/%d: Invalid command \n", sense, asc, ascq);
1177 ret = SANE_STATUS_INVAL;
1178 }
1179 else if ((0x24 == asc) && (0x00 == ascq))
1180 {
1181 DBG (1, "\t%d/%d/%d: Invalid field in CDB \n", sense, asc, ascq);
1182 ret = SANE_STATUS_INVAL;
1183 }
1184 else if ((0x25 == asc) && (0x00 == ascq))
1185 {
1186 DBG (1, "\t%d/%d/%d: Unsupported logical unit \n", sense, asc, ascq);
1187 ret = SANE_STATUS_UNSUPPORTED;
1188 }
1189 else if ((0x26 == asc) && (0x00 == ascq))
1190 {
1191 DBG (1, "\t%d/%d/%d: Invalid field in parm list \n", sense, asc, ascq);
1192 ret = SANE_STATUS_INVAL;
1193 }
1194 else if ((0x2C == asc) && (0x02 == ascq))
1195 {
1196 DBG (1, "\t%d/%d/%d: wrong window combination \n", sense, asc, ascq);
1197 ret = SANE_STATUS_INVAL;
1198 }
1199 else
1200 {
1201 DBG (1, "\tUnknown - Sense=%d, ASC=%d, ASCQ=%d\n", sense, asc, ascq);
1202 }
1203 break;
1204
1205 case 0x6: /* Unit Attention */
1206 if ((0x00 == asc) && (0x00 == ascq))
1207 {
1208 DBG (1, "\t%d/%d/%d: UNIT ATTENTION \n", sense, asc, ascq);
1209 }
1210 else
1211 {
1212 DBG (1, "\tUnknown - Sense=%d, ASC=%d, ASCQ=%d\n", sense, asc, ascq);
1213 }
1214 break;
1215
1216 case 0xb: /* Aborted Command */
1217 if ((0x43 == asc) && (0x00 == ascq))
1218 {
1219 DBG (1, "\t%d/%d/%d: Message error \n", sense, asc, ascq);
1220 }
1221 else if ((0x80 == asc) && (0x01 == ascq))
1222 {
1223 DBG (1, "\t%d/%d/%d: Image transfer error \n", sense, asc, ascq);
1224 }
1225 else
1226 {
1227 DBG (1, "\tUnknown - Sense=%d, ASC=%d, ASCQ=%d\n", sense, asc, ascq);
1228 }
1229 break;
1230
1231 default:
1232 DBG (1, "\tUnknown - Sense=%d, ASC=%d, ASCQ=%d\n", sense, asc, ascq);
1233 }
1234 return ret;
1235 } /* request_sense_parse */
1236
1237 static SANE_Status
sp15c_identify_scanner(struct sp15c *s)1238 sp15c_identify_scanner (struct sp15c *s)
1239 {
1240 char vendor[9];
1241 char product[0x11];
1242 char version[5];
1243 char *pp;
1244 SANE_Status ret;
1245
1246 DBG (10, "identify_scanner\n");
1247
1248 vendor[8] = product[0x10] = version[4] = 0;
1249
1250 if ((ret = sp15c_do_inquiry (s)))
1251 {
1252 DBG (5, "identify_scanner: inquiry failed\n");
1253 return ret;
1254 }
1255 if (get_IN_periph_devtype (s->buffer) != IN_periph_devtype_scanner)
1256 {
1257 DBG (5, "identify_scanner: not a scanner\n");
1258 return SANE_STATUS_INVAL;
1259 }
1260
1261 get_IN_vendor ((char *) s->buffer, vendor);
1262 get_IN_product ((char *)s->buffer, product);
1263 get_IN_version ((char *)s->buffer, version);
1264
1265 if (strncmp ("FCPA ", vendor, 8))
1266 {
1267 DBG (5, "identify_scanner: \"%s\" isn't a Fujitsu product\n", vendor);
1268 return 1;
1269 }
1270
1271 pp = &vendor[8];
1272 vendor[8] = ' ';
1273 while (*pp == ' ')
1274 {
1275 *pp-- = '\0';
1276 }
1277
1278 pp = &product[0x10];
1279 product[0x10] = ' ';
1280 while (*(pp - 1) == ' ')
1281 {
1282 *pp-- = '\0';
1283 } /* leave one blank at the end! */
1284
1285 pp = &version[4];
1286 version[4] = ' ';
1287 while (*pp == ' ')
1288 {
1289 *pp-- = '\0';
1290 }
1291
1292 if (get_IN_adf (s->buffer))
1293 {
1294 s->autofeeder = 1;
1295 }
1296 else
1297 {
1298 s->autofeeder = 0;
1299 }
1300
1301 DBG (10, "Found %s scanner %s version %s on device %s %x/%x/%x\n",
1302 vendor, product, version, s->devicename,
1303 s->autofeeder, get_IN_color_mode (s->buffer),
1304 get_IN_color_seq (s->buffer));
1305
1306 vendor[8] = '\0';
1307 product[16] = '\0';
1308 version[4] = '\0';
1309
1310 strncpy (s->vendor, vendor, 9);
1311 strncpy (s->product, product, 17);
1312 strncpy (s->version, version, 5);
1313
1314 return SANE_STATUS_GOOD;
1315 } /* sp15c_identify_scanner */
1316
1317 static SANE_Status
sp15c_do_inquiry(struct sp15c *s)1318 sp15c_do_inquiry (struct sp15c *s)
1319 {
1320 static SANE_Status ret;
1321
1322 DBG (10, "do_inquiry\n");
1323
1324 memset (s->buffer, '\0', 256); /* clear buffer */
1325 set_IN_return_size (inquiryB.cmd, 96);
1326
1327 ret = do_scsi_cmd (s->sfd, inquiryB.cmd, inquiryB.size, s->buffer, 96);
1328 return ret;
1329 } /* sp15c_do_inquiry */
1330
1331 static SANE_Status
do_scsi_cmd(int fd, unsigned char *cmd, int cmd_len, unsigned char *out, size_t out_len)1332 do_scsi_cmd (int fd, unsigned char *cmd, int cmd_len, unsigned char *out, size_t out_len)
1333 {
1334 SANE_Status ret;
1335 size_t ol = out_len;
1336
1337 hexdump (20, "<cmd<", cmd, cmd_len);
1338
1339 ret = sanei_scsi_cmd (fd, cmd, cmd_len, out, &ol);
1340 if ((out_len != 0) && (out_len != ol))
1341 {
1342 DBG (1, "sanei_scsi_cmd: asked %lu bytes, got %lu\n",
1343 (u_long) out_len, (u_long) ol);
1344 }
1345 if (ret)
1346 {
1347 DBG (1, "sanei_scsi_cmd: returning 0x%08x\n", ret);
1348 }
1349 DBG (10, "sanei_scsi_cmd: returning %lu bytes:\n", (u_long) ol);
1350 if (out != NULL && out_len != 0)
1351 hexdump (15, ">rslt>", out, (out_len > 0x60) ? 0x60 : out_len);
1352
1353 return ret;
1354 } /* do_scsi_cmd */
1355
1356 static void
hexdump(int level, char *comment, unsigned char *p, int l)1357 hexdump (int level, char *comment, unsigned char *p, int l)
1358 {
1359 int i;
1360 char line[128];
1361 char *ptr;
1362
1363 DBG (level, "%s\n", comment);
1364 ptr = line;
1365 for (i = 0; i < l; i++, p++)
1366 {
1367 if ((i % 16) == 0)
1368 {
1369 if (ptr != line)
1370 {
1371 *ptr = '\0';
1372 DBG (level, "%s\n", line);
1373 ptr = line;
1374 }
1375 sprintf (ptr, "%3.3d:", i);
1376 ptr += 4;
1377 }
1378 sprintf (ptr, " %2.2x", *p);
1379 ptr += 3;
1380 }
1381 *ptr = '\0';
1382 DBG (level, "%s\n", line);
1383 } /* hexdump */
1384
1385 static SANE_Status
init_options(struct sp15c *scanner)1386 init_options (struct sp15c *scanner)
1387 {
1388 int i;
1389
1390 DBG (10, "init_options\n");
1391
1392 memset (scanner->opt, 0, sizeof (scanner->opt));
1393
1394 for (i = 0; i < NUM_OPTIONS; ++i)
1395 {
1396 scanner->opt[i].size = sizeof (SANE_Word);
1397 scanner->opt[i].cap = SANE_CAP_INACTIVE;
1398 }
1399
1400 scanner->opt[OPT_NUM_OPTS].title = SANE_TITLE_NUM_OPTIONS;
1401 scanner->opt[OPT_NUM_OPTS].desc = SANE_DESC_NUM_OPTIONS;
1402 scanner->opt[OPT_NUM_OPTS].type = SANE_TYPE_INT;
1403 scanner->opt[OPT_NUM_OPTS].cap = SANE_CAP_SOFT_DETECT;
1404
1405 /************** "Mode" group: **************/
1406 scanner->opt[OPT_MODE_GROUP].title = "Scan Mode";
1407 scanner->opt[OPT_MODE_GROUP].desc = "";
1408 scanner->opt[OPT_MODE_GROUP].type = SANE_TYPE_GROUP;
1409 scanner->opt[OPT_MODE_GROUP].constraint_type = SANE_CONSTRAINT_NONE;
1410
1411 /* source */
1412
1413 scanner->opt[OPT_SOURCE].name = SANE_NAME_SCAN_SOURCE;
1414 scanner->opt[OPT_SOURCE].title = SANE_TITLE_SCAN_SOURCE;
1415 scanner->opt[OPT_SOURCE].desc = SANE_DESC_SCAN_SOURCE;
1416 scanner->opt[OPT_SOURCE].type = SANE_TYPE_STRING;
1417 scanner->opt[OPT_SOURCE].size = max_string_size (source_list);
1418 scanner->opt[OPT_SOURCE].constraint_type = SANE_CONSTRAINT_STRING_LIST;
1419 scanner->opt[OPT_SOURCE].constraint.string_list = source_list;
1420 if (scanner->autofeeder)
1421 {
1422 scanner->opt[OPT_SOURCE].cap = SANE_CAP_SOFT_SELECT
1423 | SANE_CAP_SOFT_DETECT;
1424 }
1425
1426 /* scan mode */
1427 scanner->opt[OPT_MODE].name = SANE_NAME_SCAN_MODE;
1428 scanner->opt[OPT_MODE].title = SANE_TITLE_SCAN_MODE;
1429 scanner->opt[OPT_MODE].desc = SANE_DESC_SCAN_MODE;
1430 scanner->opt[OPT_MODE].type = SANE_TYPE_STRING;
1431 scanner->opt[OPT_MODE].size = max_string_size (scan_mode_list);
1432 scanner->opt[OPT_MODE].constraint_type = SANE_CONSTRAINT_STRING_LIST;
1433 scanner->opt[OPT_MODE].constraint.string_list = scan_mode_list;
1434 scanner->opt[OPT_MODE].cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT;
1435
1436 /* negative */
1437 scanner->opt[OPT_TYPE].name = "type";
1438 scanner->opt[OPT_TYPE].title = "Film type";
1439 scanner->opt[OPT_TYPE].desc = "positive or negative image";
1440 scanner->opt[OPT_TYPE].type = SANE_TYPE_STRING;
1441 scanner->opt[OPT_TYPE].size = max_string_size (type_list);
1442 scanner->opt[OPT_TYPE].constraint_type = SANE_CONSTRAINT_STRING_LIST;
1443 scanner->opt[OPT_TYPE].constraint.string_list = type_list;
1444
1445 scanner->opt[OPT_PRESCAN].name = "prescan";
1446 scanner->opt[OPT_PRESCAN].title = "Prescan";
1447 scanner->opt[OPT_PRESCAN].desc = "Perform a prescan during preview";
1448 scanner->opt[OPT_PRESCAN].type = SANE_TYPE_BOOL;
1449 scanner->opt[OPT_PRESCAN].unit = SANE_UNIT_NONE;
1450
1451 /* resolution */
1452 scanner->opt[OPT_X_RES].name = SANE_NAME_SCAN_RESOLUTION;
1453 scanner->opt[OPT_X_RES].title = SANE_TITLE_SCAN_X_RESOLUTION;
1454 scanner->opt[OPT_X_RES].desc = SANE_DESC_SCAN_X_RESOLUTION;
1455 scanner->opt[OPT_X_RES].type = SANE_TYPE_INT;
1456 scanner->opt[OPT_X_RES].unit = SANE_UNIT_DPI;
1457 scanner->opt[OPT_X_RES].constraint_type = SANE_CONSTRAINT_WORD_LIST;
1458 scanner->opt[OPT_X_RES].constraint.word_list = x_res_list;
1459 scanner->opt[OPT_X_RES].cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT;
1460
1461 scanner->opt[OPT_Y_RES].name = SANE_NAME_SCAN_Y_RESOLUTION;
1462 scanner->opt[OPT_Y_RES].title = SANE_TITLE_SCAN_Y_RESOLUTION;
1463 scanner->opt[OPT_Y_RES].desc = SANE_DESC_SCAN_Y_RESOLUTION;
1464 scanner->opt[OPT_Y_RES].type = SANE_TYPE_INT;
1465 scanner->opt[OPT_Y_RES].unit = SANE_UNIT_DPI;
1466 scanner->opt[OPT_Y_RES].constraint_type = SANE_CONSTRAINT_WORD_LIST;
1467 scanner->opt[OPT_Y_RES].constraint.word_list = y_res_list;
1468 scanner->opt[OPT_Y_RES].cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT;
1469
1470 scanner->opt[OPT_PREVIEW_RES].name = "preview-resolution";
1471 scanner->opt[OPT_PREVIEW_RES].title = "Preview resolution";
1472 scanner->opt[OPT_PREVIEW_RES].desc = SANE_DESC_SCAN_RESOLUTION;
1473 scanner->opt[OPT_PREVIEW_RES].type = SANE_TYPE_INT;
1474 scanner->opt[OPT_PREVIEW_RES].unit = SANE_UNIT_DPI;
1475 scanner->opt[OPT_PREVIEW_RES].constraint_type = SANE_CONSTRAINT_WORD_LIST;
1476 scanner->opt[OPT_PREVIEW_RES].constraint.word_list = resolution_list;
1477
1478 /************** "Geometry" group: **************/
1479 scanner->opt[OPT_GEOMETRY_GROUP].title = "Geometry";
1480 scanner->opt[OPT_GEOMETRY_GROUP].desc = "";
1481 scanner->opt[OPT_GEOMETRY_GROUP].type = SANE_TYPE_GROUP;
1482 scanner->opt[OPT_GEOMETRY_GROUP].constraint_type = SANE_CONSTRAINT_NONE;
1483
1484 /* top-left x */
1485 scanner->opt[OPT_TL_X].name = SANE_NAME_SCAN_TL_X;
1486 scanner->opt[OPT_TL_X].title = SANE_TITLE_SCAN_TL_X;
1487 scanner->opt[OPT_TL_X].desc = SANE_DESC_SCAN_TL_X;
1488 scanner->opt[OPT_TL_X].type = SANE_TYPE_FIXED;
1489 scanner->opt[OPT_TL_X].unit = SANE_UNIT_MM;
1490 scanner->opt[OPT_TL_X].constraint_type = SANE_CONSTRAINT_RANGE;
1491 scanner->opt[OPT_TL_X].constraint.range = &x_range;
1492 scanner->opt[OPT_TL_X].cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT;
1493
1494 /* top-left y */
1495 scanner->opt[OPT_TL_Y].name = SANE_NAME_SCAN_TL_Y;
1496 scanner->opt[OPT_TL_Y].title = SANE_TITLE_SCAN_TL_Y;
1497 scanner->opt[OPT_TL_Y].desc = SANE_DESC_SCAN_TL_Y;
1498 scanner->opt[OPT_TL_Y].type = SANE_TYPE_FIXED;
1499 scanner->opt[OPT_TL_Y].unit = SANE_UNIT_MM;
1500 scanner->opt[OPT_TL_Y].constraint_type = SANE_CONSTRAINT_RANGE;
1501 scanner->opt[OPT_TL_Y].constraint.range = &y_range_fb;
1502 scanner->opt[OPT_TL_Y].cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT;
1503
1504 /* bottom-right x */
1505 scanner->opt[OPT_BR_X].name = SANE_NAME_SCAN_BR_X;
1506 scanner->opt[OPT_BR_X].title = SANE_TITLE_SCAN_BR_X;
1507 scanner->opt[OPT_BR_X].desc = SANE_DESC_SCAN_BR_X;
1508 scanner->opt[OPT_BR_X].type = SANE_TYPE_FIXED;
1509 scanner->opt[OPT_BR_X].unit = SANE_UNIT_MM;
1510 scanner->opt[OPT_BR_X].constraint_type = SANE_CONSTRAINT_RANGE;
1511 scanner->opt[OPT_BR_X].constraint.range = &x_range;
1512 scanner->opt[OPT_BR_X].cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT;
1513
1514 /* bottom-right y */
1515 scanner->opt[OPT_BR_Y].name = SANE_NAME_SCAN_BR_Y;
1516 scanner->opt[OPT_BR_Y].title = SANE_TITLE_SCAN_BR_Y;
1517 scanner->opt[OPT_BR_Y].desc = SANE_DESC_SCAN_BR_Y;
1518 scanner->opt[OPT_BR_Y].type = SANE_TYPE_FIXED;
1519 scanner->opt[OPT_BR_Y].unit = SANE_UNIT_MM;
1520 scanner->opt[OPT_BR_Y].constraint_type = SANE_CONSTRAINT_RANGE;
1521 scanner->opt[OPT_BR_Y].constraint.range = &y_range_fb;
1522 scanner->opt[OPT_BR_Y].cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT;
1523
1524
1525 /* ------------------------------ */
1526
1527 /************** "Enhancement" group: **************/
1528 scanner->opt[OPT_ENHANCEMENT_GROUP].title = "Enhancement";
1529 scanner->opt[OPT_ENHANCEMENT_GROUP].desc = "";
1530 scanner->opt[OPT_ENHANCEMENT_GROUP].type = SANE_TYPE_GROUP;
1531 scanner->opt[OPT_ENHANCEMENT_GROUP].constraint_type = SANE_CONSTRAINT_NONE;
1532
1533 scanner->opt[OPT_AVERAGING].name = "averaging";
1534 scanner->opt[OPT_AVERAGING].title = "Averaging";
1535 scanner->opt[OPT_AVERAGING].desc = "Averaging";
1536 scanner->opt[OPT_AVERAGING].type = SANE_TYPE_BOOL;
1537 scanner->opt[OPT_AVERAGING].unit = SANE_UNIT_NONE;
1538
1539 scanner->opt[OPT_BRIGHTNESS].name = SANE_NAME_BRIGHTNESS;
1540 scanner->opt[OPT_BRIGHTNESS].title = SANE_TITLE_BRIGHTNESS;
1541 scanner->opt[OPT_BRIGHTNESS].desc = SANE_DESC_BRIGHTNESS;
1542 scanner->opt[OPT_BRIGHTNESS].type = SANE_TYPE_INT;
1543 scanner->opt[OPT_BRIGHTNESS].unit = SANE_UNIT_NONE;
1544 scanner->opt[OPT_BRIGHTNESS].constraint_type = SANE_CONSTRAINT_RANGE;
1545 scanner->opt[OPT_BRIGHTNESS].constraint.range = &brightness_range;
1546 scanner->opt[OPT_BRIGHTNESS].cap = SANE_CAP_SOFT_DETECT;
1547
1548 scanner->opt[OPT_THRESHOLD].name = SANE_NAME_THRESHOLD;
1549 scanner->opt[OPT_THRESHOLD].title = SANE_TITLE_THRESHOLD;
1550 scanner->opt[OPT_THRESHOLD].desc = SANE_DESC_THRESHOLD;
1551 scanner->opt[OPT_THRESHOLD].type = SANE_TYPE_INT;
1552 scanner->opt[OPT_THRESHOLD].unit = SANE_UNIT_NONE;
1553 scanner->opt[OPT_THRESHOLD].constraint_type = SANE_CONSTRAINT_RANGE;
1554 scanner->opt[OPT_THRESHOLD].constraint.range = &threshold_range;
1555 scanner->opt[OPT_THRESHOLD].cap = SANE_CAP_SOFT_DETECT;
1556
1557 /* ------------------------------ */
1558
1559 /************** "Advanced" group: **************/
1560 scanner->opt[OPT_ADVANCED_GROUP].title = "Advanced";
1561 scanner->opt[OPT_ADVANCED_GROUP].desc = "";
1562 scanner->opt[OPT_ADVANCED_GROUP].type = SANE_TYPE_GROUP;
1563 scanner->opt[OPT_ADVANCED_GROUP].constraint_type = SANE_CONSTRAINT_NONE;
1564
1565 /* preview */
1566 scanner->opt[OPT_PREVIEW].name = SANE_NAME_PREVIEW;
1567 scanner->opt[OPT_PREVIEW].title = SANE_TITLE_PREVIEW;
1568 scanner->opt[OPT_PREVIEW].desc = SANE_DESC_PREVIEW;
1569 scanner->opt[OPT_PREVIEW].type = SANE_TYPE_BOOL;
1570
1571 DBG (10, "init_options:ok\n");
1572 return SANE_STATUS_GOOD;
1573 } /* init_options */
1574
1575 static int
sp15c_check_values(struct sp15c *s)1576 sp15c_check_values (struct sp15c *s)
1577 {
1578 if (s->use_adf == SANE_TRUE && s->autofeeder == 0)
1579 {
1580 DBG (1, "sp15c_check_values: %s\n",
1581 "ERROR: ADF-MODE NOT SUPPORTED BY SCANNER, ABORTING");
1582 return (1);
1583 }
1584 return (0);
1585 } /* sp15c_check_values */
1586
1587 /* sp15c_free_scanner should go through the following sequence:
1588 * OBJECT POSITION DISCHARGE
1589 * GOOD
1590 * RELEASE UNIT
1591 * GOOD
1592 */
1593 static int
sp15c_free_scanner(struct sp15c *s)1594 sp15c_free_scanner (struct sp15c *s)
1595 {
1596 int ret;
1597 DBG (10, "sp15c_free_scanner\n");
1598 #if 0
1599 /* hmg: reports from several people show that this code ejects two pages
1600 instead of one. So I've commented it out for now. */
1601 ret = sp15c_object_discharge (s);
1602 if (ret)
1603 return ret;
1604 #endif
1605
1606 wait_scanner (s);
1607
1608 ret = do_scsi_cmd (s->sfd, release_unitB.cmd, release_unitB.size, NULL, 0);
1609 if (ret)
1610 return ret;
1611
1612 DBG (10, "sp15c_free_scanner: ok\n");
1613 return ret;
1614 } /* sp15c_free_scanner */
1615
1616 /* sp15c_grab_scanner should go through the following command sequence:
1617 * TEST UNIT READY
1618 * CHECK CONDITION \
1619 * REQUEST SENSE > These should be handled automagically by
1620 * UNIT ATTENTION / the kernel if they happen (powerup/reset)
1621 * TEST UNIT READY
1622 * GOOD
1623 * RESERVE UNIT
1624 * GOOD
1625 *
1626 * It is then responsible for installing appropriate signal handlers
1627 * to call emergency_give_scanner() if user aborts.
1628 */
1629
1630 static int
sp15c_grab_scanner(struct sp15c *s)1631 sp15c_grab_scanner (struct sp15c *s)
1632 {
1633 int ret;
1634
1635 DBG (10, "sp15c_grab_scanner\n");
1636 wait_scanner (s);
1637
1638 ret = do_scsi_cmd (s->sfd, reserve_unitB.cmd, reserve_unitB.size, NULL, 0);
1639 if (ret)
1640 return ret;
1641
1642 DBG (10, "sp15c_grab_scanner: ok\n");
1643 return 0;
1644 } /* sp15c_grab_scanner */
1645
1646 /*
1647 * wait_scanner spins until TEST_UNIT_READY returns 0 (GOOD)
1648 * returns 0 on success,
1649 * returns -1 on error or timeout
1650 */
1651 static int
wait_scanner(struct sp15c *s)1652 wait_scanner (struct sp15c *s)
1653 {
1654 int ret = -1;
1655 int cnt = 0;
1656
1657 DBG (10, "wait_scanner\n");
1658
1659 while (ret != 0)
1660 {
1661 ret = do_scsi_cmd (s->sfd, test_unit_readyB.cmd,
1662 test_unit_readyB.size, 0, 0);
1663 if (ret == SANE_STATUS_DEVICE_BUSY)
1664 {
1665 usleep (50000); /* wait 0.05 seconds */
1666 /* 20 sec. max (prescan takes up to 15 sec.) */
1667 if (cnt++ > 400)
1668 {
1669 DBG (1, "wait_scanner: scanner does NOT get ready\n");
1670 return -1;
1671 }
1672 }
1673 else if (ret == SANE_STATUS_GOOD)
1674 {
1675 DBG (10, "wait_scanner: ok\n");
1676 return ret;
1677 }
1678 else
1679 {
1680 DBG (1, "wait_scanner: unit ready failed (%s)\n",
1681 sane_strstatus (ret));
1682 }
1683 }
1684 DBG (10, "wait_scanner: ok\n");
1685 return 0;
1686 } /* wait_scanner */
1687
1688 /* As noted above, this command has been supplanted by the
1689 MEDIA CHECK command. Nevertheless, it's still available
1690 here in case some future need is discovered. */
1691 static int
sp15c_object_position(struct sp15c *s)1692 sp15c_object_position (struct sp15c *s)
1693 {
1694 int ret;
1695 DBG (10, "sp15c_object_position\n");
1696 if (s->use_adf != SANE_TRUE)
1697 {
1698 return SANE_STATUS_GOOD;
1699 }
1700 if (s->autofeeder == 0)
1701 {
1702 DBG (10, "sp15c_object_position: Autofeeder not present.\n");
1703 return SANE_STATUS_UNSUPPORTED;
1704 }
1705 memcpy (s->buffer, object_positionB.cmd, object_positionB.size);
1706 set_OP_autofeed (s->buffer, OP_Feed);
1707 ret = do_scsi_cmd (s->sfd, s->buffer,
1708 object_positionB.size, NULL, 0);
1709 if (ret != SANE_STATUS_GOOD)
1710 {
1711 return ret;
1712 }
1713 wait_scanner (s);
1714 DBG (10, "sp15c_object_position: ok\n");
1715 return ret;
1716 } /* sp15c_object_position */
1717
1718 static int
sp15c_media_check(struct sp15c *s)1719 sp15c_media_check (struct sp15c *s)
1720 {
1721 static SANE_Status ret;
1722 DBG (10, "sp15c_media_check\n");
1723 if (s->use_adf != SANE_TRUE)
1724 {
1725 return SANE_STATUS_GOOD;
1726 }
1727 if (s->autofeeder == 0)
1728 {
1729 DBG (10, "sp15c_media_check: Autofeeder not present.\n");
1730 return SANE_STATUS_UNSUPPORTED;
1731 }
1732
1733 memset (s->buffer, '\0', 256); /* clear buffer */
1734 set_MC_return_size (media_checkB.cmd, 1);
1735
1736 ret = do_scsi_cmd (s->sfd, media_checkB.cmd, media_checkB.size, s->buffer, 1);
1737
1738 if (ret != SANE_STATUS_GOOD)
1739 {
1740 return ret;
1741 }
1742 wait_scanner (s);
1743
1744 if (get_MC_adf_status (s->buffer) == MC_ADF_OK)
1745 {
1746 DBG (10, "sp15c_media_check: ok\n");
1747 return SANE_STATUS_GOOD;
1748 }
1749 return SANE_STATUS_NO_DOCS;
1750
1751 } /* sp15c_media_check */
1752
1753 static SANE_Status
do_cancel(struct sp15c *scanner)1754 do_cancel (struct sp15c *scanner)
1755 {
1756 DBG (10, "do_cancel\n");
1757 swap_res (scanner);
1758
1759 do_eof (scanner); /* close pipe and reposition scanner */
1760
1761 if (sanei_thread_is_valid (scanner->reader_pid))
1762 {
1763 int exit_status;
1764 DBG (10, "do_cancel: kill reader_process\n");
1765 /* ensure child knows it's time to stop: */
1766 sanei_thread_kill (scanner->reader_pid);
1767 DBG (50, "wait for scanner to stop\n");
1768 sanei_thread_waitpid (scanner->reader_pid, &exit_status);
1769 sanei_thread_invalidate (scanner->reader_pid);
1770 }
1771
1772 if (scanner->sfd >= 0)
1773 {
1774 sp15c_free_scanner (scanner);
1775 DBG (10, "do_cancel: close filedescriptor\n");
1776 sanei_scsi_close (scanner->sfd);
1777 scanner->sfd = -1;
1778 }
1779
1780 return SANE_STATUS_CANCELLED;
1781 } /* do_cancel */
1782
1783 static void
swap_res(struct sp15c *s)1784 swap_res (struct sp15c *s)
1785 {
1786 (void) s; /* silence compilation warnings */
1787
1788 /* for the time being, do nothing */
1789 } /* swap_res */
1790
1791 static int
sp15c_object_discharge(struct sp15c *s)1792 sp15c_object_discharge (struct sp15c *s)
1793 {
1794 int ret;
1795
1796 DBG (10, "sp15c_object_discharge\n");
1797 if (s->use_adf != SANE_TRUE)
1798 {
1799 return SANE_STATUS_GOOD;
1800 }
1801
1802 memcpy (s->buffer, object_positionB.cmd, object_positionB.size);
1803 set_OP_autofeed (s->buffer, OP_Discharge);
1804 ret = do_scsi_cmd (s->sfd, s->buffer,
1805 object_positionB.size, NULL, 0);
1806 wait_scanner (s);
1807 DBG (10, "sp15c_object_discharge: ok\n");
1808 return ret;
1809 } /* sp15c_object_discharge */
1810
1811 static int
sp15c_set_window_param(struct sp15c *s, int prescan)1812 sp15c_set_window_param (struct sp15c *s, int prescan)
1813 {
1814 unsigned char buffer_r[WDB_size_max];
1815 int ret;
1816 int active_buffer_size;
1817
1818 (void) prescan; /* silence compilation warnings */
1819
1820 wait_scanner (s);
1821 DBG (10, "set_window_param\n");
1822 memset (buffer_r, '\0', WDB_size_max); /* clear buffer */
1823 memcpy (buffer_r, window_descriptor_blockB.cmd,
1824 window_descriptor_blockB.size); /* copy preset data */
1825
1826 set_WD_wid (buffer_r, WD_wid_all); /* window identifier */
1827
1828 set_WD_Xres (buffer_r, s->x_res); /* x resolution in dpi */
1829 set_WD_Yres (buffer_r, s->y_res); /* y resolution in dpi */
1830
1831 set_WD_ULX (buffer_r, s->tl_x); /* top left x */
1832 set_WD_ULY (buffer_r, s->tl_y); /* top left y */
1833
1834 set_WD_width (buffer_r, s->br_x - s->tl_x);
1835 set_WD_length (buffer_r, s->br_y - s->tl_y);
1836
1837 set_WD_brightness (buffer_r, s->brightness);
1838 set_WD_threshold (buffer_r, s->threshold);
1839 set_WD_contrast (buffer_r, s->contrast);
1840 set_WD_bitsperpixel (buffer_r, s->bitsperpixel);
1841 set_WD_rif (buffer_r, s->rif);
1842 set_WD_pad (buffer_r, 0x3);
1843 set_WD_halftone (buffer_r, s->halftone);
1844 set_WD_bitorder (buffer_r, s->bitorder);
1845 set_WD_compress_type (buffer_r, s->compress_type);
1846 set_WD_compress_arg (buffer_r, s->compress_arg);
1847 set_WD_composition (buffer_r, s->composition); /* may be overridden below */
1848 set_WD_vendor_id_code (buffer_r, 0xff);
1849 set_WD_adf (buffer_r, s->use_adf == SANE_TRUE ? 1 : 0);
1850 set_WD_source (buffer_r, 1);
1851 set_WD_highlight_color (buffer_r, 0xff);
1852 set_WD_shadow_value (buffer_r, 0x00);
1853
1854 switch (s->composition)
1855 {
1856 case WD_comp_LA:
1857 case WD_comp_HT:
1858 set_WD_line_width (buffer_r, ((s->br_x - s->tl_x) * s->x_res / 1200) / 8);
1859 set_WD_line_count (buffer_r, (s->br_y - s->tl_y) * s->y_res / 1200);
1860 goto b_and_w;
1861 case WD_comp_G4:
1862 set_WD_line_width (buffer_r, ((s->br_x - s->tl_x) * s->x_res / 1200) / 2);
1863 set_WD_line_count (buffer_r, (s->br_y - s->tl_y) * s->y_res / 1200);
1864 goto grayscale;
1865 case WD_comp_G8:
1866 set_WD_line_width (buffer_r, (s->br_x - s->tl_x) * s->x_res / 1200);
1867 set_WD_line_count (buffer_r, (s->br_y - s->tl_y) * s->y_res / 1200);
1868 grayscale:
1869 set_WD_composition (buffer_r, WD_comp_GS);
1870 b_and_w:
1871 set_WD_color (buffer_r, WD_color_greenx);
1872 break;
1873 case WD_comp_MC:
1874 set_WD_color (buffer_r, WD_color_rgb);
1875 set_WD_line_width (buffer_r, 3 * (s->br_x - s->tl_x) * s->x_res / 1200);
1876 set_WD_line_count (buffer_r, (s->br_y - s->tl_y) * s->y_res / 1200);
1877 break;
1878 case WD_comp_BC:
1879 case WD_comp_DC:
1880 default:
1881 return SANE_STATUS_INVAL;
1882 }
1883
1884 /* prepare SCSI-BUFFER */
1885 memcpy (s->buffer, set_windowB.cmd, set_windowB.size);
1886 memcpy ((s->buffer + set_windowB.size),
1887 window_parameter_data_blockB.cmd,
1888 window_parameter_data_blockB.size);
1889 memcpy ((s->buffer + set_windowB.size + window_parameter_data_blockB.size),
1890 buffer_r, window_descriptor_blockB.size);
1891
1892 set_SW_xferlen (s->buffer,
1893 (window_parameter_data_blockB.size
1894 + WDB_size_Color));
1895 set_WDPB_wdblen ((s->buffer
1896 + set_windowB.size),
1897 WDB_size_Color);
1898 set_WD_parm_length ((s->buffer
1899 + set_windowB.size
1900 + window_parameter_data_blockB.size),
1901 9);
1902
1903 DBG (10, "\tx_res=%d, y_res=%d\n",
1904 s->x_res, s->y_res);
1905 DBG (10, "\tupper left-x=%d, upper left-y=%d\n",
1906 s->tl_x, s->tl_y);
1907 DBG (10, "\twindow width=%d, length=%d\n",
1908 s->br_x - s->tl_x,
1909 s->br_y - s->tl_y);
1910
1911 active_buffer_size = set_windowB.size + get_SW_xferlen (s->buffer);
1912
1913 hexdump (15, "Window set", s->buffer, active_buffer_size);
1914
1915 ret = do_scsi_cmd (s->sfd, s->buffer, active_buffer_size, NULL, 0);
1916 if (ret)
1917 return ret;
1918
1919 DBG (10, "set_window_param: ok\n");
1920 return ret;
1921 } /* sp15c_set_window_param */
1922
1923 static size_t
max_string_size(const SANE_String_Const strings[])1924 max_string_size (const SANE_String_Const strings[])
1925 {
1926 size_t size, max_size = 0;
1927 int i;
1928
1929 for (i = 0; strings[i]; ++i)
1930 {
1931 size = strlen (strings[i]) + 1;
1932 if (size > max_size)
1933 max_size = size;
1934 }
1935 return max_size;
1936 } /* max_string_size */
1937
1938 static int
sp15c_start_scan(struct sp15c *s)1939 sp15c_start_scan (struct sp15c *s)
1940 {
1941 int ret;
1942 DBG (10, "sp15c_start_scan\n");
1943 ret = do_scsi_cmd (s->sfd, scanB.cmd, scanB.size, NULL, 0);
1944 if (ret)
1945 return ret;
1946 DBG (10, "sp15c_start_scan:ok\n");
1947 return ret;
1948 } /* sp15c_start_scan */
1949
1950 static void
sigterm_handler(int signal)1951 sigterm_handler (int signal)
1952 {
1953 (void) signal; /* silence compilation warnings */
1954
1955 sanei_scsi_req_flush_all (); /* flush SCSI queue */
1956 _exit (SANE_STATUS_GOOD);
1957 } /* sigterm_handler */
1958
1959 /* This function is executed as a child process. */
1960 static int
reader_process(void *data)1961 reader_process (void *data)
1962 {
1963 struct sp15c *scanner = (struct sp15c *) data;
1964 int pipe_fd = scanner->reader_pipe;
1965
1966 int status;
1967 unsigned int data_left;
1968 unsigned int data_to_read;
1969 FILE *fp;
1970 sigset_t ignore_set;
1971 sigset_t sigterm_set;
1972 struct SIGACTION act;
1973 unsigned int i;
1974 unsigned char *src, *dst;
1975
1976 DBG (10, "reader_process started\n");
1977
1978 if (sanei_thread_is_forked ())
1979 close (scanner->pipe);
1980
1981 sigfillset (&ignore_set);
1982 sigdelset (&ignore_set, SIGTERM);
1983 #if defined (__APPLE__) && defined (__MACH__)
1984 sigdelset (&ignore_set, SIGUSR2);
1985 #endif
1986 sigprocmask (SIG_SETMASK, &ignore_set, 0);
1987
1988 memset (&act, 0, sizeof (act));
1989 sigaction (SIGTERM, &act, 0);
1990
1991 sigemptyset (&sigterm_set);
1992 sigaddset (&sigterm_set, SIGTERM);
1993
1994 fp = fdopen (pipe_fd, "w");
1995 if (!fp)
1996 {
1997 DBG (1, "reader_process: couldn't open pipe!\n");
1998 return 1;
1999 }
2000
2001 DBG (10, "reader_process: starting to READ data\n");
2002
2003 data_left = bytes_per_line (scanner) *
2004 lines_per_scan (scanner);
2005
2006 sp15c_trim_rowbufsize (scanner); /* trim bufsize */
2007
2008 DBG (10, "reader_process: reading %u bytes in blocks of %u bytes\n",
2009 data_left, scanner->row_bufsize);
2010
2011 memset (&act, 0, sizeof (act));
2012
2013 act.sa_handler = sigterm_handler;
2014 sigaction (SIGTERM, &act, 0);
2015 /* wait_scanner(scanner); */
2016 do
2017 {
2018 data_to_read = (data_left < scanner->row_bufsize)
2019 ? data_left
2020 : scanner->row_bufsize;
2021
2022 if (scanner->composition == WD_comp_G4)
2023 {
2024 data_to_read /= 2; /* 'cause each byte holds two pixels */
2025 }
2026 status = sp15c_read_data_block (scanner, data_to_read);
2027 if (status == 0)
2028 {
2029 DBG (1, "reader_process: no data yet\n");
2030 fflush (stdout);
2031 fflush (stderr);
2032 usleep (50000);
2033 continue;
2034 }
2035 if (status == -1)
2036 {
2037 DBG (1, "reader_process: unable to get image data from scanner!\n");
2038 fflush (stdout);
2039 fflush (stderr);
2040 fclose (fp);
2041 return (-1);
2042 }
2043
2044 /* expand 4-bit pixels to 8-bit bytes */
2045 if (scanner->composition == WD_comp_G4)
2046 {
2047 src = &scanner->buffer[data_to_read - 1];
2048 dst = &scanner->buffer[data_to_read * 2 - 1];
2049 for (i = 0; i < data_to_read; i++)
2050 {
2051 *dst-- = ((*src << 4) & 0xf0) + ((*src) & 0x0f);
2052 *dst-- = ((*src) & 0xf0) + ((*src >> 4) & 0x0f);
2053 --src;
2054 }
2055 data_to_read *= 2;
2056 }
2057
2058 fwrite (scanner->buffer, 1, data_to_read, fp);
2059 fflush (fp);
2060
2061 data_left -= data_to_read;
2062 DBG (10, "reader_process: buffer of %d bytes read; %d bytes to go\n",
2063 data_to_read, data_left);
2064 fflush (stdout);
2065 fflush (stderr);
2066 }
2067 while (data_left);
2068
2069 fclose (fp);
2070
2071 DBG (10, "reader_process: finished\n");
2072
2073 return 0;
2074 } /* reader_process */
2075
2076 static SANE_Status
do_eof(struct sp15c *scanner)2077 do_eof (struct sp15c *scanner)
2078 {
2079 DBG (10, "do_eof\n");
2080
2081 scanner->scanning = SANE_FALSE;
2082 if (scanner->pipe >= 0)
2083 {
2084 close (scanner->pipe);
2085 scanner->pipe = -1;
2086 }
2087 return SANE_STATUS_EOF;
2088 } /* do_eof */
2089
2090 static int
pixels_per_line(struct sp15c *s)2091 pixels_per_line (struct sp15c *s)
2092 {
2093 int pixels;
2094 pixels = s->x_res * (s->br_x - s->tl_x) / 1200;
2095 return pixels;
2096 } /* pixels_per_line */
2097
2098 static int
lines_per_scan(struct sp15c *s)2099 lines_per_scan (struct sp15c *s)
2100 {
2101 int lines;
2102 lines = s->y_res * (s->br_y - s->tl_y) / 1200;
2103 return lines;
2104 } /* lines_per_scan */
2105
2106 static int
bytes_per_line(struct sp15c *s)2107 bytes_per_line (struct sp15c *s)
2108 {
2109 int bytes;
2110 /* SEE PAGE 29 OF SANE SPEC!!! */
2111 if (s->bitsperpixel == 1)
2112 {
2113 bytes = (pixels_per_line (s) + 7) / 8;
2114 }
2115 else
2116 {
2117 bytes = pixels_per_line (s);
2118 }
2119 if (s->composition == WD_comp_MC)
2120 {
2121 bytes *= 3;
2122 }
2123 return bytes;
2124 } /* bytes_per_line */
2125
2126 static void
sp15c_trim_rowbufsize(struct sp15c *s)2127 sp15c_trim_rowbufsize (struct sp15c *s)
2128 {
2129 unsigned int row_len;
2130 row_len = bytes_per_line (s);
2131 if (s->row_bufsize >= row_len)
2132 {
2133 s->row_bufsize = s->row_bufsize - (s->row_bufsize % row_len);
2134 DBG (10, "trim_rowbufsize to %d (%d lines)\n",
2135 s->row_bufsize, s->row_bufsize / row_len);
2136 }
2137 } /* sp15c_trim_rowbufsize */
2138
2139 static int
sp15c_read_data_block(struct sp15c *s, unsigned int length)2140 sp15c_read_data_block (struct sp15c *s, unsigned int length)
2141 {
2142 int r;
2143
2144 DBG (10, "sp15c_read_data_block (length = %d)\n", length);
2145 /*wait_scanner(s); */
2146
2147 set_R_datatype_code (readB.cmd, R_datatype_imagedata);
2148 set_R_xfer_length (readB.cmd, length);
2149
2150 r = do_scsi_cmd (s->sfd, readB.cmd, readB.size, s->buffer, length);
2151 #if 0
2152 return ((r != 0) ? -1 : length);
2153 #else
2154 if (r)
2155 {
2156 return -1;
2157 }
2158 else
2159 {
2160 return length;
2161 }
2162 #endif
2163 } /* sp15c_read_data_block */
2164
2165 /* Increase initial width by increasing bottom right X
2166 * until we have a HAPPY number of bytes in line.
2167 * Should be called whenever s->composition, s->x_res,
2168 * s->br_x, or s->tl_x are changed */
2169 static void
adjust_width(struct sp15c *s, SANE_Int * info)2170 adjust_width (struct sp15c *s, SANE_Int * info)
2171 {
2172 int pixels;
2173 int changed = 0;
2174 if (s->composition == WD_comp_MC)
2175 {
2176 while (pixels = s->x_res * (s->br_x - s->tl_x) / 1200,
2177 (s->bitsperpixel * pixels) % (8 * 4))
2178 {
2179 s->br_x--;
2180 changed++;
2181 }
2182 }
2183 else
2184 {
2185 while (pixels = s->x_res * (s->br_x - s->tl_x) / 1200,
2186 (s->bitsperpixel * pixels) % 8)
2187 {
2188 s->br_x--;
2189 changed++;
2190 }
2191 }
2192 if (changed && info)
2193 *info |= SANE_INFO_INEXACT;
2194
2195 return;
2196 } /* adjust_width */
2197
2198 static SANE_Status
apply_constraints(struct sp15c *scanner, SANE_Int opt, SANE_Int * target, SANE_Word * info)2199 apply_constraints (struct sp15c *scanner, SANE_Int opt,
2200 SANE_Int * target, SANE_Word * info)
2201 {
2202 SANE_Status status;
2203 status = sanei_constrain_value (scanner->opt + opt, target, info);
2204 if (status != SANE_STATUS_GOOD)
2205 {
2206 if (SANE_CONSTRAINT_RANGE ==
2207 scanner->opt[opt].constraint_type)
2208 {
2209 if (*target < scanner->opt[opt].constraint.range->min)
2210 {
2211 *target = scanner->opt[opt].constraint.range->min;
2212 return SANE_STATUS_GOOD;
2213 }
2214 else if (scanner->opt[opt].constraint.range->max < *target)
2215 {
2216 *target = scanner->opt[opt].constraint.range->max;
2217 return SANE_STATUS_GOOD;
2218 }
2219 }
2220 return status;
2221 }
2222 else
2223 {
2224 return SANE_STATUS_GOOD;
2225 }
2226 } /* apply_constraints */
2227
2228 /******************************************************************************
2229 }#############################################################################
2230 ******************************************************************************/
2231