1 /* sane - Scanner Access Now Easy.
2 
3    Copyright (C) 2000-2001 Kazuya Fukuda, based on sharp.c, which is
4    based on canon.c.
5 
6    This file is part of the SANE package.
7 
8    This program is free software; you can redistribute it and/or
9    modify it under the terms of the GNU General Public License as
10    published by the Free Software Foundation; either version 2 of the
11    License, or (at your option) any later version.
12 
13    This program is distributed in the hope that it will be useful, but
14    WITHOUT ANY WARRANTY; without even the implied warranty of
15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16    General Public License for more details.
17 
18    You should have received a copy of the GNU General Public License
19    along with this program.  If not, see <https://www.gnu.org/licenses/>.
20 
21    As a special exception, the authors of SANE give permission for
22    additional uses of the libraries contained in this release of SANE.
23 
24    The exception is that, if you link a SANE library with other files
25    to produce an executable, this does not by itself cause the
26    resulting executable to be covered by the GNU General Public
27    License.  Your use of that executable is in no way restricted on
28    account of linking the SANE library code into it.
29 
30    This exception does not, however, invalidate any other reasons why
31    the executable file might be covered by the GNU General Public
32    License.
33 
34    If you submit changes to SANE to the maintainers to be included in
35    a subsequent release, you agree by submitting the changes that
36    those changes may be distributed with this exception intact.
37 
38    If you write modifications of your own for SANE, it is your choice
39    whether to permit this exception to apply to your modifications.
40    If you do not wish that, delete this exception notice.
41 
42    This file implements a SANE backend for NEC flatbed scanners.  */
43 
44 /*
45    Version 0.12
46    - Remove references to sharp backend (grep for "JX").
47    - Check for HAVE_SYS_SHM_H before including sys/shm.h and
48      disable shared memory support if necessary.
49    - free devlist allocated in sane_get_devices() in sane_exit()
50    - resolution setting bug fixed(PC-IN500/4C 10dpi step)
51    - remove resolution list
52    Version 0.11
53    - get_data_buffer_status is not called in sane_get_parameter and
54      sane_read_direct, sane_read_shuffled.
55    - change some #include <> to ""
56    Version 0.10
57    - First release!
58    - supported scanner
59      PC-IN500/4C                    available
60      MultiReder 300U/300S series    not available
61      MultiReder 600U/600S series    not available
62      MultiReader PetiScan series    not available
63 */
64 #include "../include/sane/config.h"
65 
66 #include <limits.h>
67 #include <stdlib.h>
68 #include <stdarg.h>
69 #include <string.h>
70 #include <unistd.h>
71 #include <errno.h>
72 #include <math.h>
73 
74 #include "../include/sane/sane.h"
75 #include "../include/sane/saneopts.h"
76 #include "../include/sane/sanei_scsi.h"
77 
78 /* QUEUEDEBUG should be undefined unless you want to play
79    with the sanei_scsi.c under Linux and/or with the Linux's SG driver,
80    or your suspect problems with command queueing
81 */
82 #define QUEUEDEBUG
83 /*#define DEBUG*/
84 #ifdef DEBUG
85 #include <unistd.h>
86 #include <sys/time.h>
87 #endif
88 
89 /* USE_FORK: fork a special reader process
90    disable shared memory support.
91 */
92 #if 0
93 #ifdef HAVE_SYS_SHM_H
94 #define USE_FORK
95 #endif
96 #endif
97 
98 #ifdef USE_FORK
99 #include <signal.h>
100 #include <fcntl.h>
101 #include <sys/types.h>
102 #include <sys/wait.h>
103 
104 #include <sys/ipc.h>
105 #include <sys/shm.h>
106 
107 #endif /* USE_FORK */
108 
109 #ifndef USE_CUSTOM_GAMMA
110 #define USE_CUSTOM_GAMMA
111 #endif
112 #ifndef USE_COLOR_THRESHOLD
113 #define USE_COLOR_THRESHOLD
114 #endif
115 /* enable a short list of some standard resolutions. XSane provides
116    its own resolution list; therefore its is generally not reasonable
117    to enable this list, if you mainly using XSane. But it might be handy
118    if you are working with xscanimage
119 */
120 /* #define USE_RESOLUTION_LIST */
121 
122 #define BACKEND_NAME nec
123 #include "../include/sane/sanei_backend.h"
124 
125 #ifndef PATH_MAX
126 #define PATH_MAX	1024
127 #endif
128 
129 #define DEFAULT_MUD_1200 1200
130 
131 #define PIX_TO_MM(x, mud) ((x) * 25.4 / mud)
132 #define MM_TO_PIX(x, mud) ((x) * mud / 25.4)
133 
134 #include "../include/sane/sanei_config.h"
135 #define NEC_CONFIG_FILE "nec.conf"
136 
137 #include "nec.h"
138 
139 static int num_devices = 0;
140 static NEC_Device *first_dev = NULL;
141 static NEC_Scanner *first_handle = NULL;
142 static const SANE_Device **devlist = 0;
143 
144 typedef enum
145   {
146     MODES_LINEART  = 0,
147     MODES_GRAY,
148     MODES_COLOR,
149     MODES_LINEART_COLOR
150   }
151 Modes;
152 
153 #define M_LINEART            SANE_VALUE_SCAN_MODE_LINEART
154 #define M_GRAY               SANE_VALUE_SCAN_MODE_GRAY
155 #define M_LINEART_COLOR      "Lineart Color"
156 #define M_COLOR              SANE_VALUE_SCAN_MODE_COLOR
157 static const SANE_String_Const mode_list[] =
158 {
159 #if 0
160   M_LINEART, M_GRAY, M_LINEART_COLOR, M_COLOR,
161 #endif
162   M_LINEART, M_GRAY, M_COLOR,
163   0
164 };
165 
166 #define M_BILEVEL        "none"
167 #define M_BAYER          "Dither Bayer"
168 #define M_SPIRAL         "Dither Spiral"
169 #define M_DISPERSED      "Dither Dispersed"
170 #define M_ERRDIFFUSION   "Error Diffusion"
171 
172 #define M_DITHER1        "Dither 1"
173 #define M_DITHER2        "Dither 2"
174 #define M_DITHER3        "Dither 3"
175 #define M_DITHERUSER     "User defined"
176 
177 static const SANE_String_Const halftone_list[] =
178 {
179   M_BILEVEL, M_DITHER1, M_DITHER2, M_DITHER3,
180   0
181 };
182 
183 #define LIGHT_GREEN "green"
184 #define LIGHT_RED   "red"
185 #define LIGHT_BLUE  "blue"
186 #define LIGHT_NONE  "none"
187 #define LIGHT_WHITE "white"
188 
189 static const SANE_String_Const light_color_list[] =
190 {
191   LIGHT_GREEN, LIGHT_RED, LIGHT_BLUE, LIGHT_NONE,
192   0
193 };
194 
195 /* possible values for ADF/FSU selection */
196 static SANE_String use_adf = "Automatic Document Feeder";
197 static SANE_String use_fsu = "Transparency Adapter";
198 static SANE_String use_simple = "Flatbed";
199 
200 #define HAVE_FSU 1
201 #define HAVE_ADF 2
202 
203 /* The follow #defines are used in NEC_Scanner.adf_fsu_mode
204    and as indexes for the arrays x_ranges, y_ranges in NEC_Device
205 */
206 #define SCAN_SIMPLE 0
207 #define SCAN_WITH_FSU 1
208 #define SCAN_WITH_ADF 2
209 
210 #define LOAD_PAPER 1
211 #define UNLOAD_PAPER 0
212 
213 #define PAPER_MAX  10
214 #define W_LETTER "11\"x17\""
215 #define INVOICE  "8.5\"x5.5\""
216 static const SANE_String_Const paper_list_pcinxxx[] =
217 {
218   "A3", "A4", "A5", "A6", "B4", "B5",
219   W_LETTER, "Legal", "Letter", INVOICE,
220   0
221 };
222 
223 static const SANE_String_Const paper_list_pcin500[] =
224 {
225   "A4", "A5", "A6", "B5",
226   0
227 };
228 
229 
230 #define CRT1    "CRT1"
231 #define CRT2    "CRT2"
232 #define PRINTER1 "PRINTER1"
233 #define PRINTER2 "PRINTER2"
234 #define NONE    "NONE"
235 /* #define CUSTOM  "CUSTOM" */
236 static const SANE_String_Const gamma_list[] =
237 {
238   CRT1, CRT2, PRINTER1, PRINTER2, NONE,
239   0
240 };
241 
242 #if 0
243 #define SPEED_NORMAL    "Normal"
244 #define SPEED_FAST      "Fast"
245 static const SANE_String_Const speed_list[] =
246 {
247   SPEED_NORMAL, SPEED_FAST,
248   0
249 };
250 #endif
251 
252 #ifdef USE_RESOLUTION_LIST
253 #define RESOLUTION_MAX_PCINXXX 8
254 static const SANE_String_Const resolution_list_pcinxxx[] =
255 {
256   "50", "75", "100", "150", "200", "300", "400", "600", "Select",
257   0
258 };
259 
260 #define RESOLUTION_MAX_PCIN500 8
261 static const SANE_String_Const resolution_list_pcin500[] =
262 {
263   "50", "75", "100", "150", "200", "300", "400", "480", "Select",
264   0
265 };
266 #endif
267 
268 #define EDGE_NONE    "None"
269 #define EDGE_MIDDLE  "Middle"
270 #define EDGE_STRONG  "Strong"
271 #define EDGE_BLUR    "Blur"
272 static const SANE_String_Const edge_emphasis_list[] =
273 {
274   EDGE_NONE, EDGE_MIDDLE, EDGE_STRONG, EDGE_BLUR,
275   0
276 };
277 
278 #ifdef USE_CUSTOM_GAMMA
279 static const SANE_Range u8_range =
280   {
281       0,				/* minimum */
282     255,				/* maximum */
283       0				/* quantization */
284   };
285 #endif
286 
287 static SANE_Status
sense_handler(int fd, u_char *sense_buffer, void *ss)288 sense_handler(int fd, u_char *sense_buffer, void *ss)
289 {
290   int sense_key;
291   NEC_Sense_Data *sdat = (NEC_Sense_Data *) ss;
292 
293   (void) fd; /* silence compilation warnings */
294 
295   #define add_sense_code sense_buffer[12]
296   #define add_sense_qual sense_buffer[13]
297 
298   memcpy(sdat->sb, sense_buffer, 16);
299 
300   DBG(10, "sense code: %02x %02x %02x %02x %02x %02x %02x %02x "
301           "%02x %02x %02x %02x %02x %02x %02x %02x\n",
302           sense_buffer[0], sense_buffer[1], sense_buffer[2], sense_buffer[3],
303           sense_buffer[4], sense_buffer[5], sense_buffer[6], sense_buffer[7],
304           sense_buffer[8], sense_buffer[9], sense_buffer[10], sense_buffer[11],
305           sense_buffer[12], sense_buffer[13], sense_buffer[14], sense_buffer[15]);
306 
307   sense_key = sense_buffer[1] & 0x0F;
308   /* do we have additional information ? */
309   if (sense_buffer[7] >= 5)
310     {
311       if (sdat->model == PCIN500)
312         {
313           switch (sense_key)
314             {
315               case 0x02: /* not ready */
316                 switch (add_sense_code)
317                   {
318                     case 0x80:
319                       switch (add_sense_qual & 0xf0)
320                         {
321                           case 0x10:
322                             DBG(1, "Scanner not ready: memory error\n");
323                             return SANE_STATUS_IO_ERROR;
324                           case 0x20:
325                             DBG(1, "Scanner not ready: hardware error\n");
326                             return SANE_STATUS_IO_ERROR;
327                           case 0x30:
328                             DBG(1, "Scanner not ready: optical error\n");
329                             return SANE_STATUS_IO_ERROR;
330                           case 0x40:
331                             DBG(1, "Scanner not ready: optical error\n");
332                             return SANE_STATUS_IO_ERROR;
333                           case 0x50:
334                             DBG(1, "Scanner not ready: marker error\n");
335                             return SANE_STATUS_IO_ERROR;
336                           case 0x60:
337                             DBG(1, "Scanner not ready: mechanical error\n");
338                             return SANE_STATUS_IO_ERROR;
339                           case 0x70:
340                             DBG(1, "Scanner not ready: hardware error\n");
341                             return SANE_STATUS_IO_ERROR;
342                           case 0x80:
343                             DBG(1, "Scanner not ready: hardware error\n");
344                             return SANE_STATUS_IO_ERROR;
345                           case 0x90:
346                           default:
347                             DBG(5, "Scanner not ready: undocumented reason\n");
348                             return SANE_STATUS_IO_ERROR;
349                         }
350                     default:
351                       DBG(5, "Scanner not ready: unknown sense code\n");
352                       return SANE_STATUS_IO_ERROR;
353                   }
354               case 0x03: /* medium error */
355 		DBG(5, "medium error: undocumented reason\n");
356 		return SANE_STATUS_IO_ERROR;
357               case 0x04: /* hardware error */
358 		DBG(1, "general hardware error\n");
359 		return SANE_STATUS_IO_ERROR;
360               case 0x05: /* illegal request */
361                 DBG(10, "error: illegal request\n");
362                 return SANE_STATUS_IO_ERROR;
363               case 0x06: /* unit attention */
364 		DBG(5, "unit attention: exact reason not documented\n");
365 		return SANE_STATUS_IO_ERROR;
366               case 0x0B: /* data remains */
367                 DBG(5, "error: aborted command\n");
368                 return SANE_STATUS_IO_ERROR;
369               default:
370                 DBG(5, "error: sense code not documented\n");
371                 return SANE_STATUS_IO_ERROR;
372             }
373         }
374     }
375   return SANE_STATUS_IO_ERROR;
376 }
377 
378 static SANE_Status
test_unit_ready(int fd)379 test_unit_ready (int fd)
380 {
381   static u_char cmd[] = {TEST_UNIT_READY, 0, 0, 0, 0, 0};
382   SANE_Status status;
383   DBG (11, "<< test_unit_ready ");
384 
385   status = sanei_scsi_cmd (fd, cmd, sizeof (cmd), 0, 0);
386 
387   DBG (11, ">>\n");
388   return (status);
389 }
390 
391 #if 0
392 static SANE_Status
393 request_sense (int fd, void *sense_buf, size_t *sense_size)
394 {
395   static u_char cmd[] = {REQUEST_SENSE, 0, 0, 0, SENSE_LEN, 0};
396   SANE_Status status;
397   DBG (11, "<< request_sense ");
398 
399   status = sanei_scsi_cmd (fd, cmd, sizeof (cmd), sense_buf, sense_size);
400 
401   DBG (11, ">>\n");
402   return (status);
403 }
404 #endif
405 
406 static SANE_Status
inquiry(int fd, void *inq_buf, size_t *inq_size)407 inquiry (int fd, void *inq_buf, size_t *inq_size)
408 {
409   static u_char cmd[] = {INQUIRY, 0, 0, 0, INQUIRY_LEN, 0};
410   SANE_Status status;
411   DBG (11, "<< inquiry ");
412 
413   status = sanei_scsi_cmd (fd, cmd, sizeof (cmd), inq_buf, inq_size);
414 
415   DBG (11, ">>\n");
416   return (status);
417 }
418 
419 static SANE_Status
mode_select_mud(int fd, int mud)420 mode_select_mud (int fd, int mud)
421 {
422   static u_char cmd[6 + MODEPARAM_LEN] =
423   {MODE_SELECT6, 0x10, 0, 0, MODEPARAM_LEN, 0};
424   mode_select_param *mp;
425   SANE_Status status;
426   DBG (11, "<< mode_select_mud ");
427 
428   mp = (mode_select_param *)(cmd + 6);
429   memset (mp, 0, MODEPARAM_LEN);
430   mp->mode_param_header1 = 11;
431   mp->page_code = 3;
432   mp->page_length = 6;
433   mp->mud[0] = mud >> 8;
434   mp->mud[1] = mud & 0xFF;
435 
436   status = sanei_scsi_cmd (fd, cmd, sizeof (cmd), 0, 0);
437 
438   DBG (11, ">>\n");
439   return (status);
440 }
441 
442 #if 0
443 static SANE_Status
444 mode_select_adf_fsu (int fd, int mode)
445 {
446   static u_char cmd[6 + MODE_SUBDEV_LEN] =
447                         {MODE_SELECT6, 0x10, 0, 0, MODE_SUBDEV_LEN, 0};
448   mode_select_subdevice *mp;
449   SANE_Status status;
450   DBG (11, "<< mode_select_adf_fsu ");
451 
452   mp = (mode_select_subdevice *)(cmd + 6);
453   memset (mp, 0, MODE_SUBDEV_LEN);
454   mp->page_code = 0x20;
455   mp->page_length = 26;
456   switch (mode)
457     {
458       case SCAN_SIMPLE:
459         mp->a_mode = 0x40;
460         mp->f_mode = 0x40;
461         break;
462       case SCAN_WITH_FSU:
463         mp->a_mode = 0;
464         mp->f_mode = 0x40;
465         break;
466       case SCAN_WITH_ADF:
467         mp->a_mode = 0x40;
468         mp->f_mode = 0;
469         break;
470     }
471 
472   status = sanei_scsi_cmd (fd, cmd, sizeof (cmd), 0, 0);
473 
474   DBG (11, ">>\n");
475   return (status);
476 }
477 #endif
478 
479 static SANE_Status wait_ready(int fd);
480 
481 static SANE_Status
mode_sense(int fd, void *modeparam_buf, size_t * modeparam_size, int page)482 mode_sense (int fd, void *modeparam_buf, size_t * modeparam_size,
483             int page)
484 {
485   static u_char cmd[6] = {MODE_SENSE6, 0, 0, 0, 0, 0};
486   SANE_Status status;
487   DBG (11, "<< mode_sense ");
488   cmd[0] = 0x1a;
489   cmd[2] = page;
490   cmd[4] = *modeparam_size;
491   status = sanei_scsi_cmd (fd, cmd, sizeof (cmd), modeparam_buf,
492 			   modeparam_size);
493 
494   DBG (11, ">>\n");
495   return (status);
496 }
497 
498 static SANE_Status
scan(int fd)499 scan (int fd)
500 {
501   static u_char cmd[] = {SCAN, 0, 0, 0, 0, 0};
502   SANE_Status status;
503   DBG (11, "<< scan ");
504 
505   status = sanei_scsi_cmd (fd, cmd, sizeof (cmd), 0, 0);
506 
507   DBG (11, ">>\n");
508   return (status);
509 }
510 
511 #if 0
512 static SANE_Status
513 send_diagnostics (int fd)
514 {
515   static u_char cmd[] = {SEND_DIAGNOSTIC, 0x04, 0, 0, 0, 0};
516   SANE_Status status;
517   DBG (11, "<< send_diagnostics ");
518 
519   status = sanei_scsi_cmd (fd, cmd, sizeof (cmd), 0, 0);
520 
521   DBG (11, ">>\n");
522   return (status);
523 }
524 #endif
525 
526 static SANE_Status
set_window(int fd, window_param *wp, int len)527 set_window (int fd, window_param *wp, int len)
528 {
529   static u_char cmd[10 + WINDOW_LEN] =
530                         {SET_WINDOW, 0, 0, 0, 0, 0, 0, 0, 0, 0};
531   window_param *winp;
532   SANE_Status status;
533   DBG (11, "<< set_window ");
534 
535   cmd[8] = len;
536   winp = (window_param *)(cmd + 10);
537   memset (winp, 0, WINDOW_LEN);
538   memcpy (winp, wp, len);
539   status = sanei_scsi_cmd (fd, cmd, sizeof (cmd), 0, 0);
540 
541   DBG (11, ">>\n");
542   return (status);
543 
544 }
545 
546 static SANE_Status
get_window(int fd, void *buf, size_t * buf_size)547 get_window (int fd, void *buf, size_t * buf_size)
548 {
549   static u_char cmd[10] = {GET_WINDOW, 0, 0, 0, 0, 0, 0, 0, WINDOW_LEN, 0};
550   SANE_Status status;
551   DBG (11, "<< get_window ");
552 
553   cmd[8] = *buf_size;
554   status = sanei_scsi_cmd (fd, cmd, sizeof (cmd), buf, buf_size);
555 
556   DBG (11, ">>\n");
557   return (status);
558 }
559 
560 #if 0
561 static SANE_Status
562 get_data_buffer_status (int fd, void *buf, size_t *buf_size)
563 {
564   static u_char cmd[10] =
565                         {GET_DATA_BUFFER_STATUS, 0, 0, 0, 0, 0, 0, 0, 0, 0};
566   SANE_Status status;
567   DBG (11, "<< get_data_buffer_status ");
568 
569   cmd[8] = *buf_size;
570   status = sanei_scsi_cmd (fd, cmd, sizeof (cmd), buf, buf_size);
571 
572   DBG (11, ">>\n");
573   return (status);
574 }
575 #endif
576 
577 #ifdef USE_FORK
578 
579 /* the following four functions serve simply the purpose
580    to avoid "over-optimised" code when reader_process and
581    read_data wait for the buffer to become ready. The simple
582    while-loops in these functions which check the buffer
583    status may be optimised so that the machine code only
584    operates with registers instead of using the variable
585    values stored in memory. (This is only a workaround -
586    it would be better to set a compiler pragma, which ensures
587    that the program looks into the RAM in these while loops --
588    but unfortunately I could not find appropriate information
589    about this at least for gcc, not to speak about other
590    compilers...
591    Abel)
592 */
593 
594 static int
cancel_requested(NEC_Scanner *s)595 cancel_requested(NEC_Scanner *s)
596 {
597   return s->rdr_ctl->cancel;
598 }
599 
600 static SANE_Status
rdr_status(NEC_Scanner *s)601 rdr_status(NEC_Scanner *s)
602 {
603   return s->rdr_ctl->status;
604 }
605 
606 static int
buf_status(NEC_shmem_ctl *s)607 buf_status(NEC_shmem_ctl *s)
608 {
609   return s->shm_status;
610 }
611 
612 static int
reader_running(NEC_Scanner *s)613 reader_running(NEC_Scanner *s)
614 {
615   return s->rdr_ctl->running;
616 }
617 
618 static int
reader_process(NEC_Scanner *s)619 reader_process(NEC_Scanner *s)
620 {
621   SANE_Status status;
622   sigset_t sigterm_set;
623   static u_char cmd[] = {READ, 0, 0, 0, 0, 0, 0, 0, 0, 0};
624   int full_count = 0, counted;
625   size_t waitindex, cmdindex;
626   size_t bytes_to_queue;
627   size_t nread;
628   size_t max_bytes_per_read;
629   int max_queue;
630   int i;
631   NEC_shmem_ctl *bc;
632 
633   s->rdr_ctl->running = 1;
634   DBG(11, "<< reader_process\n");
635 
636   sigemptyset (&sigterm_set);
637 
638   bytes_to_queue = s->bytes_to_read;
639 
640   max_bytes_per_read = s->dev->info.bufsize / s->params.bytes_per_line;
641   if (max_bytes_per_read)
642     max_bytes_per_read *= s->params.bytes_per_line;
643   else
644     /* this is a really tiny buffer..*/
645     max_bytes_per_read = s->dev->info.bufsize;
646 
647   /*  wait_ready(s->fd); */
648 
649   if (s->dev->info.queued_reads <= s->dev->info.buffers)
650     max_queue = s->dev->info.queued_reads;
651   else
652     max_queue = s->dev->info.buffers;
653   for (i = 0; i < max_queue; i++)
654     {
655       bc = &s->rdr_ctl->buf_ctl[i];
656       if (bytes_to_queue)
657         {
658           nread = bytes_to_queue;
659           if (nread > max_bytes_per_read)
660             nread = max_bytes_per_read;
661           bc->used = nread;
662           cmd[6] = nread >> 16;
663           cmd[7] = nread >> 8;
664           cmd[8] = nread;
665 #ifdef QUEUEDEBUG
666           DBG(2, "reader: req_enter...\n");
667 #endif
668           status = sanei_scsi_req_enter (s->fd, cmd, sizeof (cmd),
669                      bc->buffer,
670                     &bc->used,
671                     &bc->qid);
672 #ifdef QUEUEDEBUG
673           DBG(2, "reader: req_enter ok\n");
674 #endif
675           if (status != SANE_STATUS_GOOD)
676             {
677               DBG(1, "reader_process: read command failed: %s",
678                   sane_strstatus(status));
679 #ifdef HAVE_SANEI_SCSI_OPEN_EXTENDED
680               sanei_scsi_req_flush_all_extended(s->fd);
681 #else
682                sanei_scsi_req_flush_all();
683 #endif
684               s->rdr_ctl->status = status;
685               s->rdr_ctl->running = 0;
686               return 2;
687             }
688           bc->shm_status = SHM_BUSY;
689           bc->nreq = bc->used;
690           bytes_to_queue -= bc->nreq;
691         }
692       else
693         {
694           bc->used = 0;
695           bc->shm_status = SHM_EMPTY;
696         }
697     }
698   waitindex = 0;
699   cmdindex = i % s->dev->info.buffers;
700 
701   while(s->bytes_to_read > 0)
702     {
703       if (cancel_requested(s))
704         {
705 #ifdef QUEUEDEBUG
706           DBG(2, "reader: flushing requests...\n");
707 #endif
708 #ifdef HAVE_SANEI_SCSI_OPEN_EXTENDED
709           sanei_scsi_req_flush_all_extended(s->fd);
710 #else
711           sanei_scsi_req_flush_all();
712 #endif
713 #ifdef QUEUEDEBUG
714           DBG(2, "reader: flushing requests ok\n");
715 #endif
716           s->rdr_ctl->cancel = 0;
717           s->rdr_ctl->status = SANE_STATUS_CANCELLED;
718           s->rdr_ctl->running = 0;
719           DBG(11, " reader_process (cancelled) >>\n");
720           return 1;
721         }
722 
723       bc = &s->rdr_ctl->buf_ctl[waitindex];
724       if (bc->shm_status == SHM_BUSY)
725         {
726 #ifdef DEBUG
727           {
728             struct timeval t;
729             gettimeofday(&t, 0);
730             DBG(2, "rd: waiting for data %li.%06li\n", t.tv_sec, t.tv_usec);
731           }
732 #endif
733 #ifdef QUEUEDEBUG
734           DBG(2, "reader: req_wait...\n");
735 #endif
736           status = sanei_scsi_req_wait(bc->qid);
737 #ifdef QUEUEDEBUG
738           DBG(2, "reader: req_wait ok\n");
739 #endif
740 #ifdef DEBUG
741           {
742             struct timeval t;
743             gettimeofday(&t, 0);
744             DBG(2, "rd: data received    %li.%06li\n", t.tv_sec, t.tv_usec);
745           }
746 #endif
747           if (status != SANE_STATUS_GOOD)
748             {
749               DBG(1, "reader_process: read command failed: %s",
750                   sane_strstatus(status));
751 #ifdef HAVE_SANEI_SCSI_OPEN_EXTENDED
752               sanei_scsi_req_flush_all_extended(s->fd);
753 #else
754               sanei_scsi_req_flush_all();
755 #endif
756               s->rdr_ctl->status = status;
757               s->rdr_ctl->running = 0;
758               return 2;
759             }
760           s->bytes_to_read -= bc->used;
761           bytes_to_queue += bc->nreq - bc->used;
762           bc->start = 0;
763           bc->shm_status = SHM_FULL;
764 
765           waitindex++;
766           if (waitindex == s->dev->info.buffers)
767             waitindex = 0;
768 
769         }
770 
771       if (bytes_to_queue)
772         {
773           /* wait until the next buffer is completely read via read_data */
774           bc = &s->rdr_ctl->buf_ctl[cmdindex];
775           counted = 0;
776           while (buf_status(bc) != SHM_EMPTY)
777             {
778               if (!counted)
779                 {
780                   counted = 1;
781                   full_count++;
782                 }
783               if (cancel_requested(s))
784                 {
785 #ifdef HAVE_SANEI_SCSI_OPEN_EXTENDED
786                   sanei_scsi_req_flush_all_extended(s->fd);
787 #else
788                   sanei_scsi_req_flush_all();
789 #endif
790                   s->rdr_ctl->cancel = 0;
791                   s->rdr_ctl->status = SANE_STATUS_CANCELLED;
792                   s->rdr_ctl->running = 0;
793                   DBG(11, " reader_process (cancelled) >>\n");
794                   return 1;
795                 }
796             }
797 
798           nread = bytes_to_queue;
799           if (nread > max_bytes_per_read)
800             nread = max_bytes_per_read;
801           bc->used = nread;
802           cmd[6] = nread >> 16;
803           cmd[7] = nread >> 8;
804           cmd[8] = nread;
805           status = sanei_scsi_req_enter (s->fd, cmd, sizeof (cmd),
806                     bc->buffer, &bc->used, &bc->qid);
807           if (status != SANE_STATUS_GOOD)
808             {
809               DBG(1, "reader_process: read command failed: %s",
810                   sane_strstatus(status));
811 #ifdef HAVE_SANEI_SCSI_OPEN_EXTENDED
812               sanei_scsi_req_flush_all_extended(s->fd);
813 #else
814               sanei_scsi_req_flush_all();
815 #endif
816               s->rdr_ctl->status = status;
817               s->rdr_ctl->running = 0;
818               return 2;
819             }
820           bc->shm_status = SHM_BUSY;
821           bc->nreq = nread;
822           bytes_to_queue -= nread;
823 
824           cmdindex++;
825           if (cmdindex == s->dev->info.buffers)
826             cmdindex = 0;
827         }
828 
829       if (cancel_requested(s))
830         {
831 #ifdef HAVE_SANEI_SCSI_OPEN_EXTENDED
832           sanei_scsi_req_flush_all_extended(s->fd);
833 #else
834           sanei_scsi_req_flush_all();
835 #endif
836           s->rdr_ctl->cancel = 0;
837           s->rdr_ctl->status = SANE_STATUS_CANCELLED;
838           s->rdr_ctl->running = 0;
839           DBG(11, " reader_process (cancelled) >>\n");
840           return 1;
841         }
842     }
843 
844   DBG(1, "buffer full conditions: %i\n", full_count);
845   DBG(11, " reader_process>>\n");
846 
847   s->rdr_ctl->running = 0;
848   return 0;
849 }
850 
851 static SANE_Status
read_data(NEC_Scanner *s, SANE_Byte *buf, size_t * buf_size)852 read_data (NEC_Scanner *s, SANE_Byte *buf, size_t * buf_size)
853 {
854   size_t copysize, copied = 0;
855   NEC_shmem_ctl *bc;
856 
857   DBG(11, "<< read_data ");
858 
859   bc = &s->rdr_ctl->buf_ctl[s->read_buff];
860 
861   while (copied < *buf_size)
862     {
863       /* wait until the reader process delivers data or a scanner error occurs: */
864       while (   buf_status(bc) != SHM_FULL
865              && rdr_status(s) == SANE_STATUS_GOOD)
866         {
867           usleep(10); /* could perhaps be longer. make this user configurable?? */
868         }
869 
870       if (rdr_status(s) != SANE_STATUS_GOOD)
871         {
872           return rdr_status(s);
873           DBG(11, ">>\n");
874         }
875 
876       copysize = bc->used - bc->start;
877 
878       if (copysize > *buf_size - copied )
879         copysize = *buf_size - copied;
880 
881       memcpy(buf, &(bc->buffer[bc->start]), copysize);
882 
883       copied += copysize;
884       buf = &buf[copysize];
885 
886       bc->start += copysize;
887       if (bc->start >= bc->used)
888         {
889           bc->start = 0;
890           bc->shm_status = SHM_EMPTY;
891           s->read_buff++;
892           if (s->read_buff == s->dev->info.buffers)
893             s->read_buff = 0;
894           bc = &s->rdr_ctl->buf_ctl[s->read_buff];
895         }
896     }
897 
898   DBG(11, ">>\n");
899   return SANE_STATUS_GOOD;
900 }
901 
902 #else /* don't USE_FORK: */
903 
904 static SANE_Status
read_data(NEC_Scanner *s, SANE_Byte *buf, size_t * buf_size)905 read_data (NEC_Scanner *s, SANE_Byte *buf, size_t * buf_size)
906 {
907   static u_char cmd[] = {READ, 0, 0, 0, 0, 0, 0, 0, 0, 0};
908   SANE_Status status = SANE_STATUS_GOOD;
909   size_t remain = *buf_size;
910   size_t nread;
911   DBG (11, "<< read_data ");
912 
913   /* sane_read_shuffled requires that read_data returns
914      exactly *buf_size bytes, so it must be guaranteed here.
915      Further make sure that not more bytes are read in than
916      sanei_scsi_max_request_size allows, to avoid a failure
917      of the read command
918   */
919   while (remain > 0)
920     {
921       nread = remain;
922       if (nread > s->dev->info.bufsize)
923         nread = s->dev->info.bufsize;
924       cmd[6] = nread >> 16;
925       cmd[7] = nread >> 8;
926       cmd[8] = nread;
927       status = sanei_scsi_cmd (s->fd, cmd, sizeof (cmd),
928                  &buf[*buf_size - remain], &nread);
929       if (status != SANE_STATUS_GOOD)
930         {
931           DBG(11, ">>\n");
932           return(status);
933         }
934       remain -= nread;
935     }
936   DBG (11, ">>\n");
937   return (status);
938 }
939 #endif
940 
941 static size_t
max_string_size(const SANE_String_Const strings[])942 max_string_size (const SANE_String_Const strings[])
943 {
944   size_t size, max_size = 0;
945   int i;
946   DBG (10, "<< max_string_size ");
947 
948   for (i = 0; strings[i]; ++i)
949     {
950       size = strlen (strings[i]) + 1;
951       if (size > max_size)
952 	max_size = size;
953     }
954 
955   DBG (10, ">>\n");
956   return max_size;
957 }
958 
959 static SANE_Status
wait_ready(int fd)960 wait_ready(int fd)
961 {
962   SANE_Status status;
963   int retry = 0;
964 
965   while ((status = test_unit_ready (fd)) != SANE_STATUS_GOOD)
966   {
967     DBG (5, "wait_ready failed (%d)\n", retry);
968     DBG (5, "wait_ready status = (%d)\n", status);
969     if (retry++ > 15){
970 	return SANE_STATUS_IO_ERROR;
971     }
972     sleep(3);
973   }
974   return (status);
975 
976 }
977 
978 static SANE_Status
attach(const char *devnam, NEC_Device ** devp)979 attach (const char *devnam, NEC_Device ** devp)
980 {
981   SANE_Status status;
982   NEC_Device *dev;
983   NEC_Sense_Data sensedat;
984 
985   int fd;
986   unsigned char inquiry_data[INQUIRY_LEN];
987   const unsigned char *model_name;
988   mode_sense_param msp;
989   size_t buf_size;
990   DBG (10, "<< attach ");
991 
992   for (dev = first_dev; dev; dev = dev->next)
993     {
994       if (strcmp (dev->sane.name, devnam) == 0)
995 	{
996 	  if (devp)
997 	    *devp = dev;
998 	  return (SANE_STATUS_GOOD);
999 	}
1000     }
1001 
1002   sensedat.model = unknown;
1003   sensedat.complain_on_adf_error = 0;
1004   DBG (3, "attach: opening %s\n", devnam);
1005 #ifdef HAVE_SANEI_SCSI_OPEN_EXTENDED
1006   {
1007     int bufsize = 4096;
1008     status = sanei_scsi_open_extended (devnam, &fd, &sense_handler, &sensedat, &bufsize);
1009     if (status != SANE_STATUS_GOOD)
1010       {
1011         DBG (1, "attach: open failed: %s\n", sane_strstatus (status));
1012         return (status);
1013       }
1014     if (bufsize < 4096)
1015       {
1016         DBG(1, "attach: open failed. no memory\n");
1017         sanei_scsi_close(fd);
1018         return SANE_STATUS_NO_MEM;
1019       }
1020   }
1021 #else
1022   status = sanei_scsi_open (devnam, &fd, &sense_handler, &sensedat);
1023   if (status != SANE_STATUS_GOOD)
1024     {
1025       DBG (1, "attach: open failed: %s\n", sane_strstatus (status));
1026       return (status);
1027     }
1028 #endif
1029 
1030   DBG (3, "attach: sending INQUIRY\n");
1031   memset (inquiry_data, 0, sizeof (inquiry_data));
1032   buf_size = sizeof (inquiry_data);
1033   status = inquiry (fd, inquiry_data, &buf_size);
1034   if (status != SANE_STATUS_GOOD)
1035     {
1036       DBG (1, "attach: inquiry failed: %s\n", sane_strstatus (status));
1037       sanei_scsi_close (fd);
1038       return (status);
1039     }
1040 
1041   if (inquiry_data[0] == 6 && strncmp ((char *)inquiry_data + 8, "NEC", 3) == 0)
1042     {
1043       if (strncmp ((char *)inquiry_data + 16, "PC-IN500/4C", 11) == 0)
1044         sensedat.model = PCIN500;
1045       else
1046         sensedat.model = unknown;
1047     }
1048 
1049   if (sensedat.model == unknown)
1050     {
1051       DBG (1, "attach: device doesn't look like a NEC scanner\n");
1052       DBG (1, "      : Only PC-IN500/4C is supported.\n");
1053       sanei_scsi_close (fd);
1054       return (SANE_STATUS_INVAL);
1055     }
1056 
1057   DBG (3, "attach: sending TEST_UNIT_READY\n");
1058   status = test_unit_ready (fd);
1059   if (status != SANE_STATUS_GOOD)
1060     {
1061       DBG (1, "attach: test unit ready failed (%s)\n",
1062 	   sane_strstatus (status));
1063       sanei_scsi_close (fd);
1064       return (status);
1065     }
1066   DBG (3, "attach: sending MODE SELECT\n");
1067 
1068   if (sensedat.model == PCIN500)
1069     status = mode_select_mud (fd, DEFAULT_MUD_1200);
1070 
1071   if (status != SANE_STATUS_GOOD)
1072     {
1073       DBG (1, "attach: MODE_SELECT_MUD failed\n");
1074       sanei_scsi_close (fd);
1075       return (SANE_STATUS_INVAL);
1076     }
1077 
1078   DBG (3, "attach: sending MODE SENSE/MUP page\n");
1079   memset (&msp, 0, sizeof (msp));
1080   buf_size = sizeof (msp);
1081   status = mode_sense (fd, &msp, &buf_size, 3);
1082   if (status != SANE_STATUS_GOOD)
1083     {
1084       DBG (1, "attach: MODE_SENSE/MUP page failed\n");
1085       sanei_scsi_close (fd);
1086       return (SANE_STATUS_INVAL);
1087     }
1088 #ifdef DEBUG_NEC
1089   DBG (3,"attach: MODE SENSE parameter\n");
1090       DBG(11, "%02x %02x %02x %02x "
1091               "%02x %02x %02x %02x %02x %02x %02x %02x\n",
1092               msp.mode_data_length,
1093 	      msp.mode_param_header2,
1094 	      msp.mode_param_header3,
1095 	      msp.mode_desciptor_length,
1096 	      msp.page_code,
1097 	      msp.page_length,
1098 	      msp.bmu,
1099 	      msp.res2,
1100 	      msp.mud[0],
1101 	      msp.mud[1],
1102 	      msp.res3,
1103 	      msp.res4);
1104 #endif
1105   dev = malloc (sizeof (*dev));
1106   if (!dev)
1107     return (SANE_STATUS_NO_MEM);
1108   memset (dev, 0, sizeof (*dev));
1109 
1110   dev->sane.name = (SANE_String) strdup (devnam);
1111   dev->sane.vendor = "NEC";
1112   model_name = inquiry_data + 16;
1113   dev->sane.model  = strndup ((const char *)model_name, 10);
1114   dev->sane.type = "flatbed scanner";
1115 
1116   dev->sensedat.model = sensedat.model;
1117 
1118   DBG (5, "dev->sane.name = %s\n", dev->sane.name);
1119   DBG (5, "dev->sane.vendor = %s\n", dev->sane.vendor);
1120   DBG (5, "dev->sane.model = %s\n", dev->sane.model);
1121   DBG (5, "dev->sane.type = %s\n", dev->sane.type);
1122 
1123   if (sensedat.model == PCIN500)
1124     dev->info.res_range.quant = 10;
1125   else
1126     dev->info.res_range.quant = 0;
1127 
1128   dev->info.tl_x_ranges[SCAN_SIMPLE].min = SANE_FIX(0);
1129   dev->info.br_x_ranges[SCAN_SIMPLE].min = SANE_FIX(1);
1130   dev->info.tl_y_ranges[SCAN_SIMPLE].min = SANE_FIX(0);
1131   dev->info.br_y_ranges[SCAN_SIMPLE].min = SANE_FIX(1);
1132   dev->info.tl_x_ranges[SCAN_SIMPLE].quant = SANE_FIX(0);
1133   dev->info.br_x_ranges[SCAN_SIMPLE].quant = SANE_FIX(0);
1134   dev->info.tl_y_ranges[SCAN_SIMPLE].quant = SANE_FIX(0);
1135   dev->info.br_y_ranges[SCAN_SIMPLE].quant = SANE_FIX(0);
1136 
1137   if (sensedat.model == PCIN500)
1138     dev->info.res_default = 15;
1139   else
1140     dev->info.res_default = 150;
1141   dev->info.tl_x_ranges[SCAN_SIMPLE].max = SANE_FIX(209);
1142   dev->info.br_x_ranges[SCAN_SIMPLE].max = SANE_FIX(210);
1143   dev->info.tl_y_ranges[SCAN_SIMPLE].max = SANE_FIX(296);
1144   dev->info.br_y_ranges[SCAN_SIMPLE].max = SANE_FIX(297);
1145 
1146   dev->info.bmu = msp.bmu;
1147   dev->info.mud = (msp.mud[0] << 8) + msp.mud[1];
1148 
1149   dev->info.adf_fsu_installed = 0;
1150   if (dev->sensedat.model == PCIN500)
1151     {
1152       dev->info.res_range.max = 48;
1153       dev->info.res_range.min = 5;
1154 
1155       dev->info.x_default = SANE_FIX(210);
1156       dev->info.tl_x_ranges[SCAN_SIMPLE].max = SANE_FIX(210); /* 304.8mm is the real max */
1157       dev->info.br_x_ranges[SCAN_SIMPLE].max = SANE_FIX(210); /* 304.8mm is the real max */
1158 
1159       dev->info.y_default = SANE_FIX(297);
1160       dev->info.tl_y_ranges[SCAN_SIMPLE].max = SANE_FIX(297); /* 431.8 is the real max */
1161       dev->info.br_y_ranges[SCAN_SIMPLE].max = SANE_FIX(297); /* 431.8 is the real max */
1162     }
1163   else
1164     {
1165       dev->info.res_range.max = 400;
1166       dev->info.res_range.min = 50;
1167 
1168       dev->info.x_default = SANE_FIX(210);
1169       dev->info.tl_x_ranges[SCAN_SIMPLE].max = SANE_FIX(210); /* 304.8mm is the real max */
1170       dev->info.br_x_ranges[SCAN_SIMPLE].max = SANE_FIX(210); /* 304.8mm is the real max */
1171 
1172       dev->info.y_default = SANE_FIX(297);
1173       dev->info.tl_y_ranges[SCAN_SIMPLE].max = SANE_FIX(297); /* 431.8 is the real max */
1174       dev->info.br_y_ranges[SCAN_SIMPLE].max = SANE_FIX(297); /* 431.8 is the real max */
1175     }
1176   sanei_scsi_close (fd);
1177 
1178   dev->info.threshold_range.min = 1;
1179   dev->info.threshold_range.max = 255;
1180   dev->info.threshold_range.quant = 0;
1181 
1182   dev->info.tint_range.min = 1;
1183   dev->info.tint_range.max = 255;
1184   dev->info.tint_range.quant = 0;
1185 
1186   dev->info.color_range.min = 1;
1187   dev->info.color_range.max = 255;
1188   dev->info.color_range.quant = 0;
1189 
1190   DBG (5, "res_default=%d\n", dev->info.res_default);
1191   DBG (5, "res_range.max=%d\n", dev->info.res_range.max);
1192   DBG (5, "res_range.min=%d\n", dev->info.res_range.min);
1193   DBG (5, "res_range.quant=%d\n", dev->info.res_range.quant);
1194 
1195   DBG (5, "x_default=%f\n", SANE_UNFIX(dev->info.x_default));
1196   DBG (5, "tl_x_range[0].max=%f\n", SANE_UNFIX(dev->info.tl_x_ranges[SCAN_SIMPLE].max));
1197   DBG (5, "tl_x_range[0].min=%f\n", SANE_UNFIX(dev->info.tl_x_ranges[SCAN_SIMPLE].min));
1198   DBG (5, "tl_x_range[0].quant=%d\n", dev->info.tl_x_ranges[SCAN_SIMPLE].quant);
1199   DBG (5, "br_x_range[0].max=%f\n", SANE_UNFIX(dev->info.br_x_ranges[SCAN_SIMPLE].max));
1200   DBG (5, "br_x_range[0].min=%f\n", SANE_UNFIX(dev->info.br_x_ranges[SCAN_SIMPLE].min));
1201   DBG (5, "br_x_range[0].quant=%d\n", dev->info.br_x_ranges[SCAN_SIMPLE].quant);
1202   DBG (5, "y_default=%f\n", SANE_UNFIX(dev->info.y_default));
1203   DBG (5, "tl_y_range[0].max=%f\n", SANE_UNFIX(dev->info.tl_y_ranges[SCAN_SIMPLE].max));
1204   DBG (5, "tl_y_range[0].min=%f\n", SANE_UNFIX(dev->info.tl_y_ranges[SCAN_SIMPLE].min));
1205   DBG (5, "tl_y_range[0].quant=%d\n", dev->info.tl_y_ranges[SCAN_SIMPLE].quant);
1206   DBG (5, "br_y_range[0].max=%f\n", SANE_UNFIX(dev->info.br_y_ranges[SCAN_SIMPLE].max));
1207   DBG (5, "br_y_range[0].min=%f\n", SANE_UNFIX(dev->info.br_y_ranges[SCAN_SIMPLE].min));
1208   DBG (5, "br_y_range[0].quant=%d\n", dev->info.br_y_ranges[SCAN_SIMPLE].quant);
1209 
1210   if (dev->info.adf_fsu_installed & HAVE_FSU)
1211     {
1212       DBG (5, "tl_x_range[1].max=%f\n", SANE_UNFIX(dev->info.tl_x_ranges[SCAN_WITH_FSU].max));
1213       DBG (5, "tl_x_range[1].min=%f\n", SANE_UNFIX(dev->info.tl_x_ranges[SCAN_WITH_FSU].min));
1214       DBG (5, "tl_x_range[1].quant=%d\n", dev->info.tl_x_ranges[SCAN_WITH_FSU].quant);
1215       DBG (5, "br_x_range[1].max=%f\n", SANE_UNFIX(dev->info.br_x_ranges[SCAN_WITH_FSU].max));
1216       DBG (5, "br_x_range[1].min=%f\n", SANE_UNFIX(dev->info.br_x_ranges[SCAN_WITH_FSU].min));
1217       DBG (5, "br_x_range[1].quant=%d\n", dev->info.br_x_ranges[SCAN_WITH_FSU].quant);
1218       DBG (5, "tl_y_range[1].max=%f\n", SANE_UNFIX(dev->info.tl_y_ranges[SCAN_WITH_FSU].max));
1219       DBG (5, "tl_y_range[1].min=%f\n", SANE_UNFIX(dev->info.tl_y_ranges[SCAN_WITH_FSU].min));
1220       DBG (5, "tl_y_range[1].quant=%d\n", dev->info.tl_y_ranges[SCAN_WITH_FSU].quant);
1221       DBG (5, "br_y_range[1].max=%f\n", SANE_UNFIX(dev->info.br_y_ranges[SCAN_WITH_FSU].max));
1222       DBG (5, "br_y_range[1].min=%f\n", SANE_UNFIX(dev->info.br_y_ranges[SCAN_WITH_FSU].min));
1223       DBG (5, "br_y_range[1].quant=%d\n", dev->info.br_y_ranges[SCAN_WITH_FSU].quant);
1224     }
1225 
1226   if (dev->info.adf_fsu_installed & HAVE_ADF)
1227     {
1228       DBG (5, "tl_x_range[2].max=%f\n", SANE_UNFIX(dev->info.tl_x_ranges[SCAN_WITH_ADF].max));
1229       DBG (5, "tl_x_range[2].min=%f\n", SANE_UNFIX(dev->info.tl_x_ranges[SCAN_WITH_ADF].min));
1230       DBG (5, "tl_x_range[2].quant=%d\n", dev->info.tl_x_ranges[SCAN_WITH_ADF].quant);
1231       DBG (5, "br_x_range[2].max=%f\n", SANE_UNFIX(dev->info.br_x_ranges[SCAN_WITH_ADF].max));
1232       DBG (5, "br_x_range[2].min=%f\n", SANE_UNFIX(dev->info.br_x_ranges[SCAN_WITH_ADF].min));
1233       DBG (5, "br_x_range[2].quant=%d\n", dev->info.br_x_ranges[SCAN_WITH_ADF].quant);
1234       DBG (5, "tl_y_range[2].max=%f\n", SANE_UNFIX(dev->info.tl_y_ranges[SCAN_WITH_ADF].max));
1235       DBG (5, "tl_y_range[2].min=%f\n", SANE_UNFIX(dev->info.tl_y_ranges[SCAN_WITH_ADF].min));
1236       DBG (5, "tl_y_range[2].quant=%d\n", dev->info.tl_y_ranges[SCAN_WITH_ADF].quant);
1237       DBG (5, "br_y_range[2].max=%f\n", SANE_UNFIX(dev->info.br_y_ranges[SCAN_WITH_ADF].max));
1238       DBG (5, "br_y_range[2].min=%f\n", SANE_UNFIX(dev->info.br_y_ranges[SCAN_WITH_ADF].min));
1239       DBG (5, "br_y_range[2].quant=%d\n", dev->info.br_y_ranges[SCAN_WITH_ADF].quant);
1240     }
1241 
1242   DBG (5, "bmu=%d\n", dev->info.bmu);
1243   DBG (5, "mud=%d\n", dev->info.mud);
1244 
1245   ++num_devices;
1246   dev->next = first_dev;
1247   first_dev = dev;
1248 
1249   if (devp)
1250     *devp = dev;
1251 
1252   DBG (10, ">>\n");
1253   return (SANE_STATUS_GOOD);
1254 }
1255 
1256 /* Enabling / disabling of gamma options.
1257    Depends on many user settable options, so lets put it into
1258    one function to be called by init_options and by sane_control_option
1259 
1260 */
1261 #ifdef USE_CUSTOM_GAMMA
1262 static void
set_gamma_caps(NEC_Scanner *s)1263 set_gamma_caps(NEC_Scanner *s)
1264 {
1265   /* neither fixed nor custom gamma for line art modes */
1266   if (   strcmp(s->val[OPT_MODE].s, M_LINEART) == 0
1267       || strcmp(s->val[OPT_MODE].s, M_LINEART_COLOR) == 0)
1268     {
1269       s->opt[OPT_GAMMA].cap |= SANE_CAP_INACTIVE;
1270       s->opt[OPT_CUSTOM_GAMMA].cap |= SANE_CAP_INACTIVE;
1271       s->opt[OPT_GAMMA_VECTOR].cap |= SANE_CAP_INACTIVE;
1272       s->opt[OPT_GAMMA_VECTOR_R].cap |= SANE_CAP_INACTIVE;
1273       s->opt[OPT_GAMMA_VECTOR_G].cap |= SANE_CAP_INACTIVE;
1274       s->opt[OPT_GAMMA_VECTOR_B].cap |= SANE_CAP_INACTIVE;
1275     }
1276   else if (strcmp(s->val[OPT_MODE].s, M_GRAY) == 0)
1277     {
1278       s->opt[OPT_CUSTOM_GAMMA].cap &= ~SANE_CAP_INACTIVE;
1279       if (s->val[OPT_CUSTOM_GAMMA].w == SANE_FALSE)
1280         {
1281           s->opt[OPT_GAMMA].cap &= ~SANE_CAP_INACTIVE;
1282           s->opt[OPT_GAMMA_VECTOR].cap |= SANE_CAP_INACTIVE;
1283         }
1284       else
1285         {
1286           s->opt[OPT_GAMMA].cap |= SANE_CAP_INACTIVE;
1287           s->opt[OPT_GAMMA_VECTOR].cap &= ~SANE_CAP_INACTIVE;
1288         }
1289       s->opt[OPT_GAMMA_VECTOR_R].cap |= SANE_CAP_INACTIVE;
1290       s->opt[OPT_GAMMA_VECTOR_G].cap |= SANE_CAP_INACTIVE;
1291       s->opt[OPT_GAMMA_VECTOR_B].cap |= SANE_CAP_INACTIVE;
1292     }
1293   else
1294     {
1295       /* color mode */
1296       s->opt[OPT_CUSTOM_GAMMA].cap &= ~SANE_CAP_INACTIVE;
1297       if (s->val[OPT_CUSTOM_GAMMA].w == SANE_FALSE)
1298         {
1299           s->opt[OPT_GAMMA].cap &= ~SANE_CAP_INACTIVE;
1300           s->opt[OPT_GAMMA_VECTOR_R].cap |= SANE_CAP_INACTIVE;
1301           s->opt[OPT_GAMMA_VECTOR_G].cap |= SANE_CAP_INACTIVE;
1302           s->opt[OPT_GAMMA_VECTOR_B].cap |= SANE_CAP_INACTIVE;
1303         }
1304       else
1305         {
1306           s->opt[OPT_GAMMA].cap |= SANE_CAP_INACTIVE;
1307           s->opt[OPT_GAMMA_VECTOR_R].cap &= ~SANE_CAP_INACTIVE;
1308           s->opt[OPT_GAMMA_VECTOR_G].cap &= ~SANE_CAP_INACTIVE;
1309           s->opt[OPT_GAMMA_VECTOR_B].cap &= ~SANE_CAP_INACTIVE;
1310         }
1311       s->opt[OPT_GAMMA_VECTOR].cap |= SANE_CAP_INACTIVE;
1312     }
1313 }
1314 #endif /* USE_CUSTOM_GAMMA */
1315 
1316 /* The next function is a slightly modified version of sanei_constrain_value
1317    Instead of returning status information like STATUS_INVAL, it adjusts
1318    an invalid value to the nearest allowed one.
1319 */
1320 static void
clip_value(const SANE_Option_Descriptor * opt, void * value)1321 clip_value (const SANE_Option_Descriptor * opt, void * value)
1322 {
1323   const SANE_String_Const * string_list;
1324   const SANE_Word * word_list;
1325   int i, num_matches, match;
1326   const SANE_Range * range;
1327   SANE_Word w, v;
1328   size_t len;
1329 
1330   switch (opt->constraint_type)
1331     {
1332     case SANE_CONSTRAINT_RANGE:
1333       w = *(SANE_Word *) value;
1334       range = opt->constraint.range;
1335 
1336       if (w < range->min)
1337         w = range->min;
1338       else if (w > range->max)
1339 	w = range->max;
1340 
1341       if (range->quant)
1342 	{
1343 	  v = (w - range->min + range->quant/2) / range->quant;
1344 	  w = v * range->quant + range->min;
1345 	  *(SANE_Word*) value = w;
1346 	}
1347       break;
1348 
1349     case SANE_CONSTRAINT_WORD_LIST:
1350       w = *(SANE_Word *) value;
1351       word_list = opt->constraint.word_list;
1352       for (i = 1; w != word_list[i]; ++i)
1353 	if (i >= word_list[0])
1354 	  /* somewhat arbitrary... Would be better to have a default value
1355 	     explicitly defined.
1356 	  */
1357 	  *(SANE_Word*) value = word_list[1];
1358       break;
1359 
1360     case SANE_CONSTRAINT_STRING_LIST:
1361       /* Matching algorithm: take the longest unique match ignoring
1362 	 case.  If there is an exact match, it is admissible even if
1363 	 the same string is a prefix of a longer option name. */
1364       string_list = opt->constraint.string_list;
1365       len = strlen (value);
1366 
1367       /* count how many matches of length LEN characters we have: */
1368       num_matches = 0;
1369       match = -1;
1370       for (i = 0; string_list[i]; ++i)
1371 	if (strncasecmp (value, string_list[i], len) == 0
1372 	    && len <= strlen (string_list[i]))
1373 	  {
1374 	    match = i;
1375 	    if (len == strlen (string_list[i]))
1376 	      {
1377 		/* exact match... */
1378 		if (strcmp (value, string_list[i]) != 0)
1379 		  /* ...but case differs */
1380 		  strcpy (value, string_list[match]);
1381 	      }
1382 	    ++num_matches;
1383 	  }
1384 
1385       if (num_matches > 1)
1386         /* xxx quite arbitrary... We could also choose the first match
1387         */
1388         strcpy(value, string_list[match]);
1389       else if (num_matches == 1)
1390         strcpy (value, string_list[match]);
1391       else
1392         strcpy (value, string_list[0]);
1393 
1394     default:
1395       break;
1396     }
1397 }
1398 
1399 /* make sure that enough memory is allocated for each string,
1400    so that the strcpy in sane_control_option / set value cannot
1401    write behind the end of the allocated memory.
1402 */
1403 static SANE_Status
init_string_option(NEC_Scanner *s, SANE_String_Const name, SANE_String_Const title, SANE_String_Const desc, const SANE_String_Const *string_list, int option, int default_index)1404 init_string_option(NEC_Scanner *s, SANE_String_Const name,
1405    SANE_String_Const title, SANE_String_Const desc,
1406    const SANE_String_Const *string_list, int option, int default_index)
1407 {
1408   int i;
1409 
1410   s->opt[option].name = name;
1411   s->opt[option].title = title;
1412   s->opt[option].desc = desc;
1413   s->opt[option].type = SANE_TYPE_STRING;
1414   s->opt[option].size = max_string_size (string_list);
1415   s->opt[option].constraint_type = SANE_CONSTRAINT_STRING_LIST;
1416   s->opt[option].constraint.string_list = string_list;
1417   s->val[option].s = malloc(s->opt[option].size);
1418   if (s->val[option].s == 0)
1419     {
1420       for (i = 1; i < NUM_OPTIONS; i++)
1421         {
1422           if (s->val[i].s && s->opt[i].type == SANE_TYPE_STRING)
1423             free(s->val[i].s);
1424         }
1425       return SANE_STATUS_NO_MEM;
1426     }
1427   strcpy(s->val[option].s, string_list[default_index]);
1428   return SANE_STATUS_GOOD;
1429 }
1430 
1431 static SANE_Status
init_options(NEC_Scanner * s)1432 init_options (NEC_Scanner * s)
1433 {
1434   int i, default_source;
1435   SANE_Word scalar;
1436   DBG (10, "<< init_options ");
1437 
1438   memset (s->opt, 0, sizeof (s->opt));
1439   memset (s->val, 0, sizeof (s->val));
1440 
1441   for (i = 0; i < NUM_OPTIONS; ++i)
1442     {
1443       s->opt[i].size = sizeof (SANE_Word);
1444       s->opt[i].cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT;
1445       s->val[i].s = 0;
1446     }
1447 
1448   s->opt[OPT_NUM_OPTS].title = SANE_TITLE_NUM_OPTIONS;
1449   s->opt[OPT_NUM_OPTS].desc = SANE_DESC_NUM_OPTIONS;
1450   s->opt[OPT_NUM_OPTS].type = SANE_TYPE_INT;
1451   s->opt[OPT_NUM_OPTS].cap = SANE_CAP_SOFT_DETECT;
1452   s->val[OPT_NUM_OPTS].w = NUM_OPTIONS;
1453 
1454   /* Mode group: */
1455   s->opt[OPT_MODE_GROUP].title = "Scan Mode";
1456   s->opt[OPT_MODE_GROUP].desc = "";
1457   s->opt[OPT_MODE_GROUP].type = SANE_TYPE_GROUP;
1458   s->opt[OPT_MODE_GROUP].cap = 0;
1459   s->opt[OPT_MODE_GROUP].constraint_type = SANE_CONSTRAINT_NONE;
1460 
1461   /* scan mode */
1462   init_string_option(s, SANE_NAME_SCAN_MODE, SANE_TITLE_SCAN_MODE,
1463     SANE_DESC_SCAN_MODE, mode_list, OPT_MODE, MODES_COLOR);
1464 
1465   /* half tone */
1466   init_string_option(s, SANE_NAME_HALFTONE_PATTERN, SANE_TITLE_HALFTONE_PATTERN,
1467     SANE_DESC_HALFTONE " (not support)", halftone_list, OPT_HALFTONE, 0);
1468 
1469   if (s->dev->sensedat.model == PCIN500)
1470     s->opt[OPT_HALFTONE].cap |= SANE_CAP_INACTIVE;
1471 
1472   i = 0;
1473   default_source = -1;
1474 
1475   if (s->dev->info.adf_fsu_installed & HAVE_ADF)
1476     {
1477       s->dev->info.scansources[i++] = use_adf;
1478       default_source = SCAN_WITH_ADF;
1479     }
1480   if (s->dev->info.adf_fsu_installed & HAVE_FSU)
1481     {
1482       s->dev->info.scansources[i++] = use_fsu;
1483       if (default_source < 0)
1484         default_source = SCAN_WITH_FSU;
1485     }
1486   s->dev->info.scansources[i++] = use_simple;
1487     if (default_source < 0)
1488       default_source = SCAN_SIMPLE;
1489   s->dev->info.scansources[i] = 0;
1490 
1491   init_string_option(s, SANE_NAME_SCAN_SOURCE, SANE_TITLE_SCAN_SOURCE,
1492     SANE_DESC_SCAN_SOURCE, (SANE_String_Const*)s->dev->info.scansources,
1493     OPT_SCANSOURCE, 0);
1494 
1495   if (i < 2)
1496     s->opt[OPT_SCANSOURCE].cap |= SANE_CAP_INACTIVE;
1497 
1498   if (s->dev->sensedat.model == PCIN500)
1499     init_string_option(s, "Paper size", "Paper size",
1500       "Paper size", paper_list_pcin500, OPT_PAPER, 0);
1501   else
1502     init_string_option(s, "Paper size", "Paper size",
1503       "Paper size", paper_list_pcinxxx, OPT_PAPER, 1);
1504 
1505   /* gamma */
1506   init_string_option(s, "Gamma", "Gamma", "Gamma", gamma_list, OPT_GAMMA, 0);
1507 
1508   /* Resolution Group */
1509   s->opt[OPT_RESOLUTION_GROUP].title = "Resolution";
1510   s->opt[OPT_RESOLUTION_GROUP].desc = "";
1511   s->opt[OPT_RESOLUTION_GROUP].type = SANE_TYPE_GROUP;
1512   s->opt[OPT_RESOLUTION_GROUP].cap = 0;
1513   s->opt[OPT_RESOLUTION_GROUP].constraint_type = SANE_CONSTRAINT_NONE;
1514 
1515 #ifdef USE_RESOLUTION_LIST
1516   /* select resolution */
1517   if (s->dev->sensedat.model == PCIN500)
1518     init_string_option(s, "Resolution", "Resolution", "Resolution",
1519       resolution_list_pcin500, OPT_RESOLUTION_LIST, RESOLUTION_MAX_PCIN500);
1520   else
1521     init_string_option(s, "Resolution", "Resolution", "Resolution",
1522       resolution_list_pcinxxx, OPT_RESOLUTION_LIST, RESOLUTION_MAX_PCINXXX);
1523 #endif
1524 
1525   /* x & y resolution */
1526   s->opt[OPT_RESOLUTION].name = SANE_NAME_SCAN_RESOLUTION;
1527   if (s->dev->sensedat.model == PCIN500)
1528       s->opt[OPT_RESOLUTION].title = SANE_TITLE_SCAN_RESOLUTION"(x 10)";
1529   else
1530       s->opt[OPT_RESOLUTION].title = SANE_TITLE_SCAN_RESOLUTION;
1531   s->opt[OPT_RESOLUTION].desc = SANE_DESC_SCAN_RESOLUTION;
1532   s->opt[OPT_RESOLUTION].type = SANE_TYPE_INT;
1533   s->opt[OPT_RESOLUTION].unit = SANE_UNIT_DPI;
1534   s->opt[OPT_RESOLUTION].constraint_type = SANE_CONSTRAINT_RANGE;
1535   s->opt[OPT_RESOLUTION].constraint.range = &s->dev->info.res_range;
1536   s->val[OPT_RESOLUTION].w = s->dev->info.res_default;
1537 
1538   /* "Geometry" group: */
1539   s->opt[OPT_GEOMETRY_GROUP].title = "Geometry";
1540   s->opt[OPT_GEOMETRY_GROUP].desc = "";
1541   s->opt[OPT_GEOMETRY_GROUP].type = SANE_TYPE_GROUP;
1542   s->opt[OPT_GEOMETRY_GROUP].cap = SANE_CAP_ADVANCED;
1543   s->opt[OPT_GEOMETRY_GROUP].constraint_type = SANE_CONSTRAINT_NONE;
1544 
1545   /* top-left x */
1546   s->opt[OPT_TL_X].name = SANE_NAME_SCAN_TL_X;
1547   s->opt[OPT_TL_X].title = SANE_TITLE_SCAN_TL_X;
1548   s->opt[OPT_TL_X].desc = SANE_DESC_SCAN_TL_X;
1549   s->opt[OPT_TL_X].type = SANE_TYPE_FIXED;
1550   s->opt[OPT_TL_X].unit = SANE_UNIT_MM;
1551   s->opt[OPT_TL_X].constraint_type = SANE_CONSTRAINT_RANGE;
1552   s->opt[OPT_TL_X].constraint.range = &s->dev->info.tl_x_ranges[default_source];
1553   s->val[OPT_TL_X].w = s->dev->info.tl_x_ranges[default_source].min;
1554 
1555   /* top-left y */
1556   s->opt[OPT_TL_Y].name = SANE_NAME_SCAN_TL_Y;
1557   s->opt[OPT_TL_Y].title = SANE_TITLE_SCAN_TL_Y;
1558   s->opt[OPT_TL_Y].desc = SANE_DESC_SCAN_TL_Y;
1559   s->opt[OPT_TL_Y].type = SANE_TYPE_FIXED;
1560   s->opt[OPT_TL_Y].unit = SANE_UNIT_MM;
1561   s->opt[OPT_TL_Y].constraint_type = SANE_CONSTRAINT_RANGE;
1562   s->opt[OPT_TL_Y].constraint.range = &s->dev->info.tl_y_ranges[default_source];
1563   s->val[OPT_TL_Y].w = s->dev->info.tl_y_ranges[default_source].min;
1564 
1565   /* bottom-right x */
1566   s->opt[OPT_BR_X].name = SANE_NAME_SCAN_BR_X;
1567   s->opt[OPT_BR_X].title = SANE_TITLE_SCAN_BR_X;
1568   s->opt[OPT_BR_X].desc = SANE_DESC_SCAN_BR_X;
1569   s->opt[OPT_BR_X].type = SANE_TYPE_FIXED;
1570   s->opt[OPT_BR_X].unit = SANE_UNIT_MM;
1571   s->opt[OPT_BR_X].constraint_type = SANE_CONSTRAINT_RANGE;
1572   s->opt[OPT_BR_X].constraint.range = &s->dev->info.br_x_ranges[default_source];
1573   scalar = s->dev->info.x_default;
1574   clip_value (&s->opt[OPT_BR_X], &scalar);
1575   s->val[OPT_BR_X].w = scalar;
1576 
1577   /* bottom-right y */
1578   s->opt[OPT_BR_Y].name = SANE_NAME_SCAN_BR_Y;
1579   s->opt[OPT_BR_Y].title = SANE_TITLE_SCAN_BR_Y;
1580   s->opt[OPT_BR_Y].desc = SANE_DESC_SCAN_BR_Y;
1581   s->opt[OPT_BR_Y].type = SANE_TYPE_FIXED;
1582   s->opt[OPT_BR_Y].unit = SANE_UNIT_MM;
1583   s->opt[OPT_BR_Y].constraint_type = SANE_CONSTRAINT_RANGE;
1584   s->opt[OPT_BR_Y].constraint.range = &s->dev->info.br_y_ranges[default_source];
1585   scalar = s->dev->info.y_default;
1586   clip_value (&s->opt[OPT_BR_X], &scalar);
1587   s->val[OPT_BR_Y].w = scalar;
1588 
1589   /* "Enhancement" group: */
1590   s->opt[OPT_ENHANCEMENT_GROUP].title = "Enhancement";
1591   s->opt[OPT_ENHANCEMENT_GROUP].desc = "";
1592   s->opt[OPT_ENHANCEMENT_GROUP].type = SANE_TYPE_GROUP;
1593   s->opt[OPT_ENHANCEMENT_GROUP].cap = 0;
1594   s->opt[OPT_ENHANCEMENT_GROUP].constraint_type = SANE_CONSTRAINT_NONE;
1595 
1596   /* edge emphasis */
1597   init_string_option(s, "Edge emphasis", "Edge emphasis",
1598     "Edge emphasis", edge_emphasis_list,
1599     OPT_EDGE_EMPHASIS, 0);
1600 
1601   if (s->dev->sensedat.model == PCIN500)
1602     s->opt[OPT_EDGE_EMPHASIS].cap |= SANE_CAP_INACTIVE;
1603 
1604   /* OR */
1605   s->opt[OPT_OR].name = "OR";
1606   s->opt[OPT_OR].title = "OR";
1607   s->opt[OPT_OR].desc = "Select OR emphancement";
1608   s->opt[OPT_OR].type = SANE_TYPE_BOOL;
1609   s->val[OPT_OR].w = SANE_FALSE;
1610 
1611   /* EDGE */
1612   s->opt[OPT_EDGE].name = "edge";
1613   s->opt[OPT_EDGE].title = "Edge";
1614   s->opt[OPT_EDGE].desc = "Select Edge emphancement";
1615   s->opt[OPT_EDGE].type = SANE_TYPE_BOOL;
1616   s->val[OPT_EDGE].w = SANE_FALSE;
1617 
1618   /* NR */
1619   s->opt[OPT_NR].name = "NR";
1620   s->opt[OPT_NR].title = "NR";
1621   s->opt[OPT_NR].desc = "Select noise reduction";
1622   s->opt[OPT_NR].type = SANE_TYPE_BOOL;
1623   s->val[OPT_NR].w = SANE_FALSE;
1624 
1625   if (s->dev->sensedat.model != PCIN500)
1626     {
1627       s->opt[OPT_EDGE].cap |= SANE_CAP_INACTIVE;
1628       s->opt[OPT_NR].cap |= SANE_CAP_INACTIVE;
1629       s->opt[OPT_OR].cap |= SANE_CAP_INACTIVE;
1630     }
1631   /* tint */
1632   s->opt[OPT_TINT].name = "tint";
1633   s->opt[OPT_TINT].title = "Tint";
1634   s->opt[OPT_TINT].desc = "Select tint";
1635   s->opt[OPT_TINT].type = SANE_TYPE_INT;
1636   s->opt[OPT_TINT].unit = SANE_UNIT_NONE;
1637   s->opt[OPT_TINT].constraint_type = SANE_CONSTRAINT_RANGE;
1638   s->opt[OPT_TINT].constraint.range = &s->dev->info.tint_range;
1639   s->val[OPT_TINT].w = 128;
1640   if (s->dev->sensedat.model != PCIN500)
1641     s->opt[OPT_TINT].cap |= SANE_CAP_INACTIVE;
1642 
1643   /* color */
1644   s->opt[OPT_COLOR].name = "color";
1645   s->opt[OPT_COLOR].title = "Color";
1646   s->opt[OPT_COLOR].desc = "Select color";
1647   s->opt[OPT_COLOR].type = SANE_TYPE_INT;
1648   s->opt[OPT_COLOR].unit = SANE_UNIT_NONE;
1649   s->opt[OPT_COLOR].constraint_type = SANE_CONSTRAINT_RANGE;
1650   s->opt[OPT_COLOR].constraint.range = &s->dev->info.color_range;
1651   s->val[OPT_COLOR].w = 128;
1652   if (s->dev->sensedat.model != PCIN500)
1653     s->opt[OPT_COLOR].cap |= SANE_CAP_INACTIVE;
1654 
1655   /* threshold */
1656   s->opt[OPT_THRESHOLD].name = SANE_NAME_THRESHOLD;
1657   s->opt[OPT_THRESHOLD].title = SANE_TITLE_THRESHOLD;
1658   s->opt[OPT_THRESHOLD].desc = SANE_DESC_THRESHOLD;
1659   s->opt[OPT_THRESHOLD].type = SANE_TYPE_INT;
1660   s->opt[OPT_THRESHOLD].unit = SANE_UNIT_NONE;
1661   s->opt[OPT_THRESHOLD].constraint_type = SANE_CONSTRAINT_RANGE;
1662   s->opt[OPT_THRESHOLD].constraint.range = &s->dev->info.threshold_range;
1663   s->val[OPT_THRESHOLD].w = 128;
1664   s->opt[OPT_THRESHOLD].cap |= SANE_CAP_INACTIVE;
1665 
1666 #ifdef USE_COLOR_THRESHOLD
1667   s->opt[OPT_THRESHOLD_R].name = SANE_NAME_THRESHOLD "-red";
1668   /* xxx the titles and descriptions are confusing:
1669      "set white point (red)"
1670      Any idea? maybe "threshold to get the red component on"
1671   */
1672   s->opt[OPT_THRESHOLD_R].title = SANE_TITLE_THRESHOLD " (red)";
1673   s->opt[OPT_THRESHOLD_R].desc = SANE_DESC_THRESHOLD " (red)";
1674   s->opt[OPT_THRESHOLD_R].type = SANE_TYPE_INT;
1675   s->opt[OPT_THRESHOLD_R].unit = SANE_UNIT_NONE;
1676   s->opt[OPT_THRESHOLD_R].constraint_type = SANE_CONSTRAINT_RANGE;
1677   s->opt[OPT_THRESHOLD_R].constraint.range = &s->dev->info.threshold_range;
1678   s->val[OPT_THRESHOLD_R].w = 128;
1679   s->opt[OPT_THRESHOLD_R].cap |= SANE_CAP_INACTIVE;
1680 
1681   s->opt[OPT_THRESHOLD_G].name = SANE_NAME_THRESHOLD "-green";
1682   s->opt[OPT_THRESHOLD_G].title = SANE_TITLE_THRESHOLD " (green)";
1683   s->opt[OPT_THRESHOLD_G].desc = SANE_DESC_THRESHOLD " (green)";
1684   s->opt[OPT_THRESHOLD_G].type = SANE_TYPE_INT;
1685   s->opt[OPT_THRESHOLD_G].unit = SANE_UNIT_NONE;
1686   s->opt[OPT_THRESHOLD_G].constraint_type = SANE_CONSTRAINT_RANGE;
1687   s->opt[OPT_THRESHOLD_G].constraint.range = &s->dev->info.threshold_range;
1688   s->val[OPT_THRESHOLD_G].w = 128;
1689   s->opt[OPT_THRESHOLD_G].cap |= SANE_CAP_INACTIVE;
1690 
1691   s->opt[OPT_THRESHOLD_B].name = SANE_NAME_THRESHOLD "-blue";
1692   s->opt[OPT_THRESHOLD_B].title = SANE_TITLE_THRESHOLD " (blue)";
1693   s->opt[OPT_THRESHOLD_B].desc = SANE_DESC_THRESHOLD " (blue)";
1694   s->opt[OPT_THRESHOLD_B].type = SANE_TYPE_INT;
1695   s->opt[OPT_THRESHOLD_B].unit = SANE_UNIT_NONE;
1696   s->opt[OPT_THRESHOLD_B].constraint_type = SANE_CONSTRAINT_RANGE;
1697   s->opt[OPT_THRESHOLD_B].constraint.range = &s->dev->info.threshold_range;
1698   s->val[OPT_THRESHOLD_B].w = 128;
1699   s->opt[OPT_THRESHOLD_B].cap |= SANE_CAP_INACTIVE;
1700 
1701 #endif
1702 
1703   /* light color (for gray scale and line art scans) */
1704   init_string_option(s, "LightColor", "LightColor", "LightColor",
1705     light_color_list, OPT_LIGHTCOLOR, 3);
1706   s->opt[OPT_LIGHTCOLOR].cap |= SANE_CAP_INACTIVE;
1707 
1708   s->opt[OPT_PREVIEW].name  = SANE_NAME_PREVIEW;
1709   s->opt[OPT_PREVIEW].title = SANE_TITLE_PREVIEW;
1710   s->opt[OPT_PREVIEW].desc  = SANE_DESC_PREVIEW;
1711   s->opt[OPT_PREVIEW].type  = SANE_TYPE_BOOL;
1712   s->opt[OPT_PREVIEW].cap = SANE_CAP_SOFT_DETECT | SANE_CAP_SOFT_SELECT;
1713   s->val[OPT_PREVIEW].w     = SANE_FALSE;
1714 
1715 
1716 #ifdef USE_CUSTOM_GAMMA
1717   /* custom-gamma table */
1718   s->opt[OPT_CUSTOM_GAMMA].name = SANE_NAME_CUSTOM_GAMMA;
1719   s->opt[OPT_CUSTOM_GAMMA].title = SANE_TITLE_CUSTOM_GAMMA;
1720   s->opt[OPT_CUSTOM_GAMMA].desc = SANE_DESC_CUSTOM_GAMMA;
1721   s->opt[OPT_CUSTOM_GAMMA].type = SANE_TYPE_BOOL;
1722   s->val[OPT_CUSTOM_GAMMA].w = SANE_FALSE;
1723 
1724   /* grayscale gamma vector */
1725   s->opt[OPT_GAMMA_VECTOR].name = SANE_NAME_GAMMA_VECTOR;
1726   s->opt[OPT_GAMMA_VECTOR].title = SANE_TITLE_GAMMA_VECTOR;
1727   s->opt[OPT_GAMMA_VECTOR].desc = SANE_DESC_GAMMA_VECTOR;
1728   s->opt[OPT_GAMMA_VECTOR].type = SANE_TYPE_INT;
1729 #if 0
1730   s->opt[OPT_GAMMA_VECTOR].cap |= SANE_CAP_INACTIVE;
1731 #endif
1732   s->opt[OPT_GAMMA_VECTOR].unit = SANE_UNIT_NONE;
1733   s->opt[OPT_GAMMA_VECTOR].size = 256 * sizeof (SANE_Word);
1734   s->opt[OPT_GAMMA_VECTOR].constraint_type = SANE_CONSTRAINT_RANGE;
1735   s->opt[OPT_GAMMA_VECTOR].constraint.range = &u8_range;
1736   s->val[OPT_GAMMA_VECTOR].wa = &s->gamma_table[0][0];
1737 
1738   /* red gamma vector */
1739   s->opt[OPT_GAMMA_VECTOR_R].name = SANE_NAME_GAMMA_VECTOR_R;
1740   s->opt[OPT_GAMMA_VECTOR_R].title = SANE_TITLE_GAMMA_VECTOR_R;
1741   s->opt[OPT_GAMMA_VECTOR_R].desc = SANE_DESC_GAMMA_VECTOR_R;
1742   s->opt[OPT_GAMMA_VECTOR_R].type = SANE_TYPE_INT;
1743 #if 0
1744   s->opt[OPT_GAMMA_VECTOR_R].cap |= SANE_CAP_INACTIVE;
1745 #endif
1746   s->opt[OPT_GAMMA_VECTOR_R].unit = SANE_UNIT_NONE;
1747   s->opt[OPT_GAMMA_VECTOR_R].size = 256 * sizeof (SANE_Word);
1748   s->opt[OPT_GAMMA_VECTOR_R].constraint_type = SANE_CONSTRAINT_RANGE;
1749   s->opt[OPT_GAMMA_VECTOR_R].constraint.range = &u8_range;
1750   s->val[OPT_GAMMA_VECTOR_R].wa = &s->gamma_table[1][0];
1751 
1752   /* green gamma vector */
1753   s->opt[OPT_GAMMA_VECTOR_G].name = SANE_NAME_GAMMA_VECTOR_G;
1754   s->opt[OPT_GAMMA_VECTOR_G].title = SANE_TITLE_GAMMA_VECTOR_G;
1755   s->opt[OPT_GAMMA_VECTOR_G].desc = SANE_DESC_GAMMA_VECTOR_G;
1756   s->opt[OPT_GAMMA_VECTOR_G].type = SANE_TYPE_INT;
1757 #if 0
1758   s->opt[OPT_GAMMA_VECTOR_G].cap |= SANE_CAP_INACTIVE;
1759 #endif
1760   s->opt[OPT_GAMMA_VECTOR_G].unit = SANE_UNIT_NONE;
1761   s->opt[OPT_GAMMA_VECTOR_G].size = 256 * sizeof (SANE_Word);
1762   s->opt[OPT_GAMMA_VECTOR_G].constraint_type = SANE_CONSTRAINT_RANGE;
1763   s->opt[OPT_GAMMA_VECTOR_G].constraint.range = &u8_range;
1764   s->val[OPT_GAMMA_VECTOR_G].wa = &s->gamma_table[2][0];
1765 
1766   /* blue gamma vector */
1767   s->opt[OPT_GAMMA_VECTOR_B].name = SANE_NAME_GAMMA_VECTOR_B;
1768   s->opt[OPT_GAMMA_VECTOR_B].title = SANE_TITLE_GAMMA_VECTOR_B;
1769   s->opt[OPT_GAMMA_VECTOR_B].desc = SANE_DESC_GAMMA_VECTOR_B;
1770   s->opt[OPT_GAMMA_VECTOR_B].type = SANE_TYPE_INT;
1771 #if 0
1772   s->opt[OPT_GAMMA_VECTOR_B].cap |= SANE_CAP_INACTIVE;
1773 #endif
1774   s->opt[OPT_GAMMA_VECTOR_B].unit = SANE_UNIT_NONE;
1775   s->opt[OPT_GAMMA_VECTOR_B].size = 256 * sizeof (SANE_Word);
1776   s->opt[OPT_GAMMA_VECTOR_B].constraint_type = SANE_CONSTRAINT_RANGE;
1777   s->opt[OPT_GAMMA_VECTOR_B].constraint.range = &u8_range;
1778   s->val[OPT_GAMMA_VECTOR_B].wa = &s->gamma_table[3][0];
1779   set_gamma_caps(s);
1780 #endif
1781 
1782   DBG (10, ">>\n");
1783   return SANE_STATUS_GOOD;
1784 }
1785 
1786 static SANE_Status
do_cancel(NEC_Scanner * s)1787 do_cancel (NEC_Scanner * s)
1788 {
1789   DBG (10, "<< do_cancel ");
1790 
1791 #ifdef USE_FORK
1792   if (s->reader_pid > 0)
1793     {
1794       int exit_status;
1795       int count = 0;
1796       /* ensure child knows it's time to stop: */
1797 
1798       DBG(11, "stopping reader process\n");
1799       s->rdr_ctl->cancel = 1;
1800       while(reader_running(s) && count < 100)
1801         {
1802           usleep(100000);
1803           count++;
1804         };
1805       if (reader_running(s))
1806         {
1807           kill(s->reader_pid, SIGKILL);
1808         }
1809       wait(&exit_status);
1810       DBG(11, "reader process stopped\n");
1811 
1812       s->reader_pid = 0;
1813     }
1814 
1815 #endif
1816   s->scanning = SANE_FALSE;
1817 
1818   if (s->fd >= 0)
1819     {
1820       sanei_scsi_close (s->fd);
1821       s->fd = -1;
1822     }
1823 #ifdef USE_FORK
1824   {
1825     struct shmid_ds ds;
1826     if (s->shmid != -1)
1827       shmctl(s->shmid, IPC_RMID, &ds);
1828     s->shmid = -1;
1829   }
1830 #endif
1831   if (s->buffer)
1832     free(s->buffer);
1833   s->buffer = 0;
1834 
1835   DBG (10, ">>\n");
1836   return (SANE_STATUS_CANCELLED);
1837 }
1838 
1839 static NEC_New_Device *new_devs = 0;
1840 static NEC_New_Device *new_dev_pool = 0;
1841 
1842 static SANE_Status
attach_and_list(const char *devnam)1843 attach_and_list(const char *devnam)
1844 {
1845   SANE_Status res;
1846   NEC_Device *devp;
1847   NEC_New_Device *np;
1848 
1849   res = attach(devnam, &devp);
1850   if (res == SANE_STATUS_GOOD)
1851     {
1852       if (new_dev_pool)
1853         {
1854           np = new_dev_pool;
1855           new_dev_pool = np->next;
1856         }
1857       else
1858         {
1859           np = malloc(sizeof(NEC_New_Device));
1860           if (np == 0)
1861             return SANE_STATUS_NO_MEM;
1862         }
1863       np->next =new_devs;
1864       np->dev = devp;
1865       new_devs = np;
1866     }
1867   return res;
1868 }
1869 
1870 SANE_Status
sane_init(SANE_Int * version_code, SANE_Auth_Callback authorize)1871 sane_init (SANE_Int * version_code, SANE_Auth_Callback authorize)
1872 {
1873   char devnam[PATH_MAX] = "/dev/scanner";
1874   char line[PATH_MAX];
1875   const char *lp;
1876   char *word;
1877   char *end;
1878   FILE *fp;
1879   int opt_index = 0;
1880   int buffers[2] = {DEFAULT_BUFFERS, DEFAULT_BUFFERS};
1881   int bufsize[2] = {DEFAULT_BUFSIZE, DEFAULT_BUFSIZE};
1882   int queued_reads[2] = {DEFAULT_QUEUED_READS, DEFAULT_QUEUED_READS};
1883   int linecount = 0;
1884 #if 1
1885   NEC_Device nd;
1886   NEC_Device *dp = &nd;
1887 #else
1888   NEC_Device *dp;
1889 #endif
1890   NEC_New_Device *np;
1891   int i;
1892 
1893   (void) authorize; /* silence compilation warnings */
1894 
1895   DBG_INIT ();
1896   DBG (10, "<< sane_init ");
1897 
1898   DBG (1, "sane_init: NEC (Ver %d.%d)\n", NEC_MAJOR, NEC_MINOR);
1899 
1900   if (version_code)
1901     *version_code = SANE_VERSION_CODE (SANE_CURRENT_MAJOR, SANE_CURRENT_MINOR, 0);
1902 
1903   fp = sanei_config_open (NEC_CONFIG_FILE);
1904   if (!fp)
1905     {
1906       /* use "/dev/scanner" as the default device name if no
1907          config file is available
1908       */
1909       attach (devnam, &dp);
1910       /* make sure that there are at least two buffers */
1911       if (DEFAULT_BUFFERS < 2)
1912         dp->info.buffers = DEFAULT_BUFFERS;
1913       else
1914         dp->info.buffers = 2;
1915       dp->info.wanted_bufsize = DEFAULT_BUFSIZE;
1916       dp->info.queued_reads = DEFAULT_QUEUED_READS;
1917       return SANE_STATUS_GOOD;
1918     }
1919 
1920   while (fgets(line, PATH_MAX, fp))
1921     {
1922       linecount++;
1923       word = 0;
1924       lp = sanei_config_get_string(line, &word);
1925       if (word)
1926         {
1927           if (word[0] != '#')
1928             {
1929               if (strcmp(word, "option") == 0)
1930                 {
1931                   free(word);
1932                   word = 0;
1933                   lp = sanei_config_get_string(lp, &word);
1934                   if (strcmp(word, "buffers") == 0)
1935                     {
1936                       free(word);
1937                       word = 0;
1938                       sanei_config_get_string(lp, &word);
1939                       i = strtol(word, &end, 0);
1940                       if (end == word)
1941                         {
1942                           DBG(1, "error in config file, line %i: number expected:\n",
1943                               linecount);
1944                           DBG(1, "%s\n", line);
1945                         }
1946                       else
1947                         if (i > 2)
1948                           buffers[opt_index] = i;
1949                         else
1950                           buffers[opt_index] = 2;
1951                     }
1952                   else if (strcmp(word, "buffersize") == 0)
1953                     {
1954                       free(word);
1955                       word = 0;
1956                       sanei_config_get_string(lp, &word);
1957                       i = strtol(word, &end, 0);
1958                       if (word == end)
1959                         {
1960                           DBG(1, "error in config file, line %i: number expected:\n",
1961                               linecount);
1962                           DBG(1, "%s\n", line);
1963                         }
1964                       else
1965                         bufsize[opt_index] = i;
1966                     }
1967                   else if (strcmp(word, "readqueue") == 0)
1968                     {
1969                       free(word);
1970                       word = 0;
1971                       sanei_config_get_string(lp, &word);
1972                       i = strtol(word, &end, 0);
1973                       if (word == end)
1974                         {
1975                           DBG(1, "error in config file, line %i: number expected:\n",
1976                               linecount);
1977                           DBG(1, "%s\n", line);
1978                         }
1979                       else
1980                         queued_reads[opt_index] = i;
1981                     }
1982                   else
1983                     {
1984                       DBG(1, "error in config file, line %i: unknown option\n",
1985                           linecount);
1986                       DBG(1, "%s\n", line);
1987                     }
1988                 }
1989               else
1990                 {
1991                   while (new_devs)
1992                     {
1993                       if (buffers[1] >= 2)
1994                         new_devs->dev->info.buffers = buffers[1];
1995                       else
1996                         new_devs->dev->info.buffers = 2;
1997                       if (bufsize[1] > 0)
1998                         new_devs->dev->info.wanted_bufsize = bufsize[1];
1999                       else
2000                         new_devs->dev->info.wanted_bufsize = DEFAULT_BUFSIZE;
2001                       if (queued_reads[1] >= 0)
2002                         new_devs->dev->info.queued_reads = queued_reads[1];
2003                       else
2004                         new_devs->dev->info.queued_reads = 0;
2005                       np = new_devs->next;
2006                       new_devs->next = new_dev_pool;
2007                       new_dev_pool = new_devs;
2008                       new_devs = np;
2009                     }
2010                   if (line[strlen(line)-1] == '\n')
2011                     line[strlen(line)-1] = 0;
2012                   sanei_config_attach_matching_devices(line, &attach_and_list);
2013                   buffers[1] = buffers[0];
2014                   bufsize[1] = bufsize[0];
2015                   queued_reads[1] = queued_reads[0];
2016                   opt_index = 1;
2017                 }
2018             }
2019           if (word) free(word);
2020         }
2021     }
2022 
2023   while (new_devs)
2024     {
2025       if (buffers[1] >= 2)
2026         new_devs->dev->info.buffers = buffers[1];
2027       else
2028         new_devs->dev->info.buffers = 2;
2029       if (bufsize[1] > 0)
2030         new_devs->dev->info.wanted_bufsize = bufsize[1];
2031       else
2032         new_devs->dev->info.wanted_bufsize = DEFAULT_BUFSIZE;
2033       if (queued_reads[1] >= 0)
2034         new_devs->dev->info.queued_reads = queued_reads[1];
2035       else
2036         new_devs->dev->info.queued_reads = 0;
2037       if (line[strlen(line)-1] == '\n')
2038         line[strlen(line)-1] = 0;
2039       np = new_devs->next;
2040       free(new_devs);
2041       new_devs = np;
2042     }
2043   while (new_dev_pool)
2044     {
2045       np = new_dev_pool->next;
2046       free(new_dev_pool);
2047       new_dev_pool = np;
2048     }
2049   fclose(fp);
2050   DBG (10, ">>\n");
2051   return (SANE_STATUS_GOOD);
2052 }
2053 
2054 void
sane_exit(void)2055 sane_exit (void)
2056 {
2057   NEC_Device *dev, *next;
2058   DBG (10, "<< sane_exit ");
2059 
2060   for (dev = first_dev; dev; dev = next)
2061     {
2062       next = dev->next;
2063       free ((void *) dev->sane.name);
2064       free ((void *) dev->sane.model);
2065       free (dev);
2066     }
2067   first_dev = 0;
2068 
2069   if (devlist)
2070     free(devlist);
2071 
2072   DBG (10, ">>\n");
2073 }
2074 
2075 SANE_Status
sane_get_devices(const SANE_Device *** device_list, SANE_Bool local_only)2076 sane_get_devices (const SANE_Device *** device_list, SANE_Bool local_only)
2077 {
2078   NEC_Device *dev;
2079   int i;
2080   DBG (10, "<< sane_get_devices ");
2081 
2082   (void) local_only; /* silence compilation warnings */
2083 
2084   if (devlist)
2085     free (devlist);
2086   devlist = malloc ((num_devices + 1) * sizeof (devlist[0]));
2087   if (!devlist)
2088     return (SANE_STATUS_NO_MEM);
2089 
2090   i = 0;
2091   for (dev = first_dev; dev; dev = dev->next)
2092     devlist[i++] = &dev->sane;
2093   devlist[i++] = 0;
2094 
2095   *device_list = devlist;
2096 
2097   DBG (10, ">>\n");
2098   return SANE_STATUS_GOOD;
2099 }
2100 
2101 SANE_Status
sane_open(SANE_String_Const devnam, SANE_Handle * handle)2102 sane_open (SANE_String_Const devnam, SANE_Handle * handle)
2103 {
2104   SANE_Status status;
2105   NEC_Device *dev;
2106   NEC_Scanner *s;
2107 #ifdef USE_CUSTOM_GAMMA
2108   int i, j;
2109 #endif
2110 
2111   DBG (10, "<< sane_open ");
2112 
2113   if (devnam[0])
2114     {
2115       for (dev = first_dev; dev; dev = dev->next)
2116 	{
2117 	  if (strcmp (dev->sane.name, devnam) == 0)
2118 	    break;
2119 	}
2120 
2121       if (!dev)
2122 	{
2123 	  status = attach (devnam, &dev);
2124 	  if (status != SANE_STATUS_GOOD)
2125 	    return (status);
2126 	}
2127     }
2128   else
2129     {
2130       dev = first_dev;
2131     }
2132 
2133   if (!dev)
2134     return (SANE_STATUS_INVAL);
2135 
2136   s = malloc (sizeof (*s));
2137   if (!s)
2138     return SANE_STATUS_NO_MEM;
2139   memset (s, 0, sizeof (*s));
2140 
2141   s->fd = -1;
2142   s->dev = dev;
2143 
2144   s->buffer = 0;
2145 #ifdef USE_CUSTOM_GAMMA
2146   for (i = 0; i < 4; ++i)
2147     for (j = 0; j < 256; ++j)
2148       s->gamma_table[i][j] = j;
2149 #endif
2150   status = init_options (s);
2151   if (status != SANE_STATUS_GOOD)
2152     {
2153       /* xxx clean up mallocs */
2154       return status;
2155     }
2156 
2157   s->next = first_handle;
2158   first_handle = s;
2159 
2160   *handle = s;
2161 
2162   DBG (10, ">>\n");
2163   return SANE_STATUS_GOOD;
2164 }
2165 
2166 void
sane_close(SANE_Handle handle)2167 sane_close (SANE_Handle handle)
2168 {
2169   NEC_Scanner *s = (NEC_Scanner *) handle;
2170   DBG (10, "<< sane_close ");
2171 
2172   if (s->fd != -1)
2173     sanei_scsi_close (s->fd);
2174 #ifdef USE_FORK
2175   {
2176     struct shmid_ds ds;
2177     if (s->shmid != -1)
2178       shmctl(s->shmid, IPC_RMID, &ds);
2179   }
2180 #endif
2181   if (s->buffer)
2182     free(s->buffer);
2183   free (s);
2184 
2185   DBG (10, ">>\n");
2186 }
2187 
2188 const SANE_Option_Descriptor *
sane_get_option_descriptor(SANE_Handle handle, SANE_Int option)2189 sane_get_option_descriptor (SANE_Handle handle, SANE_Int option)
2190 {
2191   NEC_Scanner *s = handle;
2192   DBG (10, "<< sane_get_option_descriptor ");
2193 
2194   if ((unsigned) option >= NUM_OPTIONS)
2195     return (0);
2196 
2197   DBG (10, ">>\n");
2198   return (s->opt + option);
2199 }
2200 
2201 SANE_Status
sane_control_option(SANE_Handle handle, SANE_Int option, SANE_Action action, void *val, SANE_Int * info)2202 sane_control_option (SANE_Handle handle, SANE_Int option,
2203 		     SANE_Action action, void *val, SANE_Int * info)
2204 {
2205   NEC_Scanner *s = handle;
2206   SANE_Status status;
2207 #ifdef USE_CUSTOM_GAMMA
2208   SANE_Word w, cap;
2209 #else
2210   SANE_Word cap;
2211 #endif
2212   int range_index;
2213   DBG (10, "<< sane_control_option %i", option);
2214 
2215   if (info)
2216     *info = 0;
2217 
2218   if (s->scanning)
2219     return (SANE_STATUS_DEVICE_BUSY);
2220   if (option >= NUM_OPTIONS)
2221     return (SANE_STATUS_INVAL);
2222 
2223   cap = s->opt[option].cap;
2224   if (!SANE_OPTION_IS_ACTIVE (cap))
2225     return (SANE_STATUS_INVAL);
2226 
2227   if (action == SANE_ACTION_GET_VALUE)
2228     {
2229       switch (option)
2230 	{
2231 	  /* word options: */
2232 	case OPT_RESOLUTION:
2233 	case OPT_TL_X:
2234 	case OPT_TL_Y:
2235 	case OPT_BR_X:
2236 	case OPT_BR_Y:
2237 	case OPT_NUM_OPTS:
2238 	case OPT_THRESHOLD:
2239 	case OPT_TINT:
2240 	case OPT_COLOR:
2241 #ifdef USE_COLOR_THRESHOLD
2242 	case OPT_THRESHOLD_R:
2243 	case OPT_THRESHOLD_G:
2244 	case OPT_THRESHOLD_B:
2245 #endif
2246 	case OPT_OR:
2247 	case OPT_NR:
2248 	case OPT_EDGE:
2249 	case OPT_PREVIEW:
2250 #ifdef USE_CUSTOM_GAMMA
2251 	case OPT_CUSTOM_GAMMA:
2252 #endif
2253 	  *(SANE_Word *) val = s->val[option].w;
2254 #if 0 /* here, values are read; reload should not be necessary */
2255 	  if (info)
2256 	    *info |= SANE_INFO_RELOAD_PARAMS;
2257 #endif
2258 	  return (SANE_STATUS_GOOD);
2259 
2260 #ifdef USE_CUSTOM_GAMMA
2261 	  /* word-array options: */
2262 	case OPT_GAMMA_VECTOR:
2263 	case OPT_GAMMA_VECTOR_R:
2264 	case OPT_GAMMA_VECTOR_G:
2265 	case OPT_GAMMA_VECTOR_B:
2266 	  memcpy (val, s->val[option].wa, s->opt[option].size);
2267 	  return SANE_STATUS_GOOD;
2268 #endif
2269 
2270 	  /* string options: */
2271 	case OPT_MODE:
2272 	case OPT_HALFTONE:
2273 	case OPT_PAPER:
2274 	case OPT_GAMMA:
2275 #ifdef USE_RESOLUTION_LIST
2276 	case OPT_RESOLUTION_LIST:
2277 #endif
2278 	case OPT_EDGE_EMPHASIS:
2279 	case OPT_LIGHTCOLOR:
2280 	case OPT_SCANSOURCE:
2281 	  strcpy (val, s->val[option].s);
2282 #if 0
2283 	  if (info)
2284 	    *info |= SANE_INFO_RELOAD_PARAMS;
2285 #endif
2286 
2287 	  return (SANE_STATUS_GOOD);
2288 
2289 	}
2290     }
2291   else if (action == SANE_ACTION_SET_VALUE)
2292     {
2293       if (!SANE_OPTION_IS_SETTABLE (cap))
2294 	return (SANE_STATUS_INVAL);
2295 
2296       status = sanei_constrain_value (s->opt + option, val, info);
2297       if (status != SANE_STATUS_GOOD)
2298 	return status;
2299 
2300       switch (option)
2301 	{
2302 	  /* (mostly) side-effect-free word options: */
2303 	case OPT_RESOLUTION:
2304 	case OPT_TL_X:
2305 	case OPT_TL_Y:
2306 	case OPT_BR_X:
2307 	case OPT_BR_Y:
2308 	  if (info && s->val[option].w != *(SANE_Word *) val)
2309 	    *info |= SANE_INFO_RELOAD_PARAMS;
2310           // fall through
2311 	case OPT_NUM_OPTS:
2312 	case OPT_THRESHOLD:
2313 	  /* xxx theoretically, we could use OPT_THRESHOLD in
2314 	     bi-level color mode to adjust all three other
2315 	     threshold together. But this would require to set
2316 	     the bit SANE_INFO_RELOAD_OPTIONS in *info, and that
2317 	     would unfortunately cause a crash in both xscanimage
2318 	     and xsane... Therefore, OPT_THRESHOLD is disabled
2319 	     for bi-level color scan right now.
2320 	  */
2321 	case OPT_TINT:
2322 	case OPT_COLOR:
2323 #ifdef USE_COLOR_THRESHOLD
2324 	case OPT_THRESHOLD_R:
2325 	case OPT_THRESHOLD_G:
2326 	case OPT_THRESHOLD_B:
2327 #endif
2328 	case OPT_OR:
2329 	case OPT_NR:
2330 	case OPT_EDGE:
2331 	case OPT_PREVIEW:
2332 	  s->val[option].w = *(SANE_Word *) val;
2333 	  return (SANE_STATUS_GOOD);
2334 
2335 	case OPT_MODE:
2336 	  if (strcmp (val, M_LINEART) == 0)
2337 	    {
2338 	      s->opt[OPT_LIGHTCOLOR].cap &= ~SANE_CAP_INACTIVE;
2339 	      s->opt[OPT_THRESHOLD].cap &= ~SANE_CAP_INACTIVE;
2340 	      s->opt[OPT_TINT].cap |= SANE_CAP_INACTIVE;
2341 	      s->opt[OPT_COLOR].cap |= SANE_CAP_INACTIVE;
2342 #ifdef USE_COLOR_THRESHOLD
2343 	      s->opt[OPT_THRESHOLD_R].cap |= SANE_CAP_INACTIVE;
2344 	      s->opt[OPT_THRESHOLD_G].cap |= SANE_CAP_INACTIVE;
2345 	      s->opt[OPT_THRESHOLD_B].cap |= SANE_CAP_INACTIVE;
2346 #endif
2347 	      if (s->dev->sensedat.model == PCIN500)
2348                 s->opt[OPT_HALFTONE].cap &= ~SANE_CAP_INACTIVE;
2349 	    }
2350 	  else if (strcmp (val, M_LINEART_COLOR) == 0)
2351 	    {
2352 	      s->opt[OPT_LIGHTCOLOR].cap |= SANE_CAP_INACTIVE;
2353 	      s->opt[OPT_THRESHOLD].cap |= SANE_CAP_INACTIVE;
2354 	      s->opt[OPT_TINT].cap |= SANE_CAP_INACTIVE;
2355 	      s->opt[OPT_COLOR].cap |= SANE_CAP_INACTIVE;
2356 #ifdef USE_COLOR_THRESHOLD
2357 	      s->opt[OPT_THRESHOLD_R].cap &= ~SANE_CAP_INACTIVE;
2358 	      s->opt[OPT_THRESHOLD_G].cap &= ~SANE_CAP_INACTIVE;
2359 	      s->opt[OPT_THRESHOLD_B].cap &= ~SANE_CAP_INACTIVE;
2360 #endif
2361 	      if (s->dev->sensedat.model == PCIN500)
2362                 s->opt[OPT_HALFTONE].cap &= ~SANE_CAP_INACTIVE;
2363 	    }
2364 	  else if (strcmp (val, M_GRAY) == 0)
2365 	    {
2366 	      s->opt[OPT_LIGHTCOLOR].cap &= ~SANE_CAP_INACTIVE;
2367 	      s->opt[OPT_THRESHOLD].cap |= SANE_CAP_INACTIVE;
2368 	      s->opt[OPT_TINT].cap |= SANE_CAP_INACTIVE;
2369 	      s->opt[OPT_COLOR].cap |= SANE_CAP_INACTIVE;
2370 #ifdef USE_COLOR_THRESHOLD
2371 	      s->opt[OPT_THRESHOLD_R].cap |= SANE_CAP_INACTIVE;
2372 	      s->opt[OPT_THRESHOLD_G].cap |= SANE_CAP_INACTIVE;
2373 	      s->opt[OPT_THRESHOLD_B].cap |= SANE_CAP_INACTIVE;
2374 #endif
2375               s->opt[OPT_HALFTONE].cap |= SANE_CAP_INACTIVE;
2376 	    }
2377 	  else
2378 	    {
2379 	      s->opt[OPT_LIGHTCOLOR].cap |= SANE_CAP_INACTIVE;
2380 	      s->opt[OPT_THRESHOLD].cap |= SANE_CAP_INACTIVE;
2381 	      s->opt[OPT_TINT].cap &= ~SANE_CAP_INACTIVE;
2382 	      s->opt[OPT_COLOR].cap &= ~SANE_CAP_INACTIVE;
2383 #ifdef USE_COLOR_THRESHOLD
2384 	      s->opt[OPT_THRESHOLD_R].cap |= SANE_CAP_INACTIVE;
2385 	      s->opt[OPT_THRESHOLD_G].cap |= SANE_CAP_INACTIVE;
2386 	      s->opt[OPT_THRESHOLD_B].cap |= SANE_CAP_INACTIVE;
2387 #endif
2388               s->opt[OPT_HALFTONE].cap |= SANE_CAP_INACTIVE;
2389             }
2390 #if 0
2391 	  if (   strcmp (val, M_LINEART) == 0
2392 	      || strcmp (val, M_GRAY) == 0)
2393             {
2394 	      s->opt[OPT_LIGHTCOLOR].cap &= ~SANE_CAP_INACTIVE;
2395             }
2396           else
2397             {
2398 	      s->opt[OPT_LIGHTCOLOR].cap |= SANE_CAP_INACTIVE;
2399             }
2400 #endif
2401           strcpy(s->val[option].s, val);
2402 #ifdef USE_CUSTOM_GAMMA
2403           set_gamma_caps(s);
2404 #endif
2405           if (info)
2406 	    *info |= SANE_INFO_RELOAD_OPTIONS | SANE_INFO_RELOAD_PARAMS;
2407 	  return (SANE_STATUS_GOOD);
2408 
2409 	case OPT_GAMMA:
2410 	case OPT_HALFTONE:
2411 	case OPT_EDGE_EMPHASIS:
2412 	case OPT_LIGHTCOLOR:
2413 #if 0
2414 	  if (s->val[option].s)
2415 	    free (s->val[option].s);
2416 	  s->val[option].s = strdup (val);
2417 #endif
2418           strcpy(s->val[option].s, val);
2419 	  return (SANE_STATUS_GOOD);
2420 
2421 	case OPT_SCANSOURCE:
2422 	  if (info && strcmp (s->val[option].s, (SANE_String) val))
2423 	    *info |= SANE_INFO_RELOAD_OPTIONS | SANE_INFO_RELOAD_PARAMS;
2424 #if 0
2425 	  if (s->val[option].s)
2426 	    free (s->val[option].s);
2427 	  s->val[option].s = strdup (val);
2428 #endif
2429           strcpy(s->val[option].s, val);
2430 	  if (strcmp(val, use_fsu) == 0)
2431 	    range_index = SCAN_WITH_FSU;
2432 	  else if (strcmp(val, use_adf) == 0)
2433 	    range_index = SCAN_WITH_ADF;
2434 	  else
2435 	    range_index = SCAN_SIMPLE;
2436 
2437           s->opt[OPT_TL_X].constraint.range
2438             = &s->dev->info.tl_x_ranges[range_index];
2439           clip_value (&s->opt[OPT_TL_X], &s->val[OPT_TL_X].w);
2440 
2441           s->opt[OPT_TL_Y].constraint.range
2442             = &s->dev->info.tl_y_ranges[range_index];
2443           clip_value (&s->opt[OPT_TL_Y], &s->val[OPT_TL_Y].w);
2444 
2445           s->opt[OPT_BR_X].constraint.range
2446             = &s->dev->info.br_x_ranges[range_index];
2447           clip_value (&s->opt[OPT_BR_X], &s->val[OPT_BR_X].w);
2448 
2449           s->opt[OPT_BR_Y].constraint.range
2450             = &s->dev->info.br_y_ranges[range_index];
2451           clip_value (&s->opt[OPT_BR_Y], &s->val[OPT_BR_Y].w);
2452 
2453 	  return (SANE_STATUS_GOOD);
2454 
2455 	case OPT_PAPER:
2456           if (info)
2457 	    *info |= SANE_INFO_RELOAD_OPTIONS | SANE_INFO_RELOAD_PARAMS;
2458 #if 0
2459 	  if (s->val[option].s)
2460 	    free (s->val[option].s);
2461 	  s->val[option].s = strdup (val);
2462 #endif
2463           strcpy(s->val[option].s, val);
2464 	  s->val[OPT_TL_X].w = SANE_FIX(0);
2465 	  s->val[OPT_TL_Y].w = SANE_FIX(0);
2466 	  if (strcmp (s->val[option].s, "A3") == 0){
2467 	      s->val[OPT_BR_X].w = SANE_FIX(297);
2468 	      s->val[OPT_BR_Y].w = SANE_FIX(420);
2469 	  }else if (strcmp (s->val[option].s, "A4") == 0){
2470 	      s->val[OPT_BR_X].w = SANE_FIX(210);
2471 	      s->val[OPT_BR_Y].w = SANE_FIX(297);
2472 	  }else if (strcmp (s->val[option].s, "A5") == 0){
2473 	      s->val[OPT_BR_X].w = SANE_FIX(148.5);
2474 	      s->val[OPT_BR_Y].w = SANE_FIX(210);
2475 	  }else if (strcmp (s->val[option].s, "A6") == 0){
2476 	      s->val[OPT_BR_X].w = SANE_FIX(105);
2477 	      s->val[OPT_BR_Y].w = SANE_FIX(148.5);
2478 	  }else if (strcmp (s->val[option].s, "B4") == 0){
2479 	      s->val[OPT_BR_X].w = SANE_FIX(250);
2480 	      s->val[OPT_BR_Y].w = SANE_FIX(353);
2481 	  }else if (strcmp (s->val[option].s, "B5") == 0){
2482 	      s->val[OPT_BR_X].w = SANE_FIX(182);
2483 	      s->val[OPT_BR_Y].w = SANE_FIX(257);
2484 	  }else if (strcmp (s->val[option].s, W_LETTER) == 0){
2485 	      s->val[OPT_BR_X].w = SANE_FIX(279.4);
2486 	      s->val[OPT_BR_Y].w = SANE_FIX(431.8);
2487 	  }else if (strcmp (s->val[option].s, "Legal") == 0){
2488 	      s->val[OPT_BR_X].w = SANE_FIX(215.9);
2489 	      s->val[OPT_BR_Y].w = SANE_FIX(355.6);
2490 	  }else if (strcmp (s->val[option].s, "Letter") == 0){
2491 	      s->val[OPT_BR_X].w = SANE_FIX(215.9);
2492 	      s->val[OPT_BR_Y].w = SANE_FIX(279.4);
2493 	  }else if (strcmp (s->val[option].s, INVOICE) == 0){
2494 	      s->val[OPT_BR_X].w = SANE_FIX(215.9);
2495 	      s->val[OPT_BR_Y].w = SANE_FIX(139.7);
2496 	  }else{
2497 	  }
2498 	  return (SANE_STATUS_GOOD);
2499 
2500 #ifdef USE_RESOLUTION_LIST
2501 	case OPT_RESOLUTION_LIST:
2502 	  if (info)
2503 	    *info |= SANE_INFO_RELOAD_OPTIONS | SANE_INFO_RELOAD_PARAMS;
2504 #if 0
2505 	  if (s->val[option].s)
2506 	    free (s->val[option].s);
2507 	  s->val[option].s = strdup (val);
2508 #endif
2509 	  for (i = 0; s->opt[OPT_RESOLUTION_LIST].constraint.string_list[i]; i++) {
2510 	    if (strcmp (val,
2511 	          s->opt[OPT_RESOLUTION_LIST].constraint.string_list[i]) == 0){
2512 	      s->val[OPT_RESOLUTION].w
2513 	        = atoi(s->opt[OPT_RESOLUTION_LIST].constraint.string_list[i]);
2514 	      if (info)
2515 	        *info |= SANE_INFO_RELOAD_PARAMS;
2516 	      break;
2517 	    }
2518 	  }
2519 	  return (SANE_STATUS_GOOD);
2520 #endif
2521 
2522 #ifdef USE_CUSTOM_GAMMA
2523 	  /* side-effect-free word-array options: */
2524 	case OPT_GAMMA_VECTOR:
2525 	case OPT_GAMMA_VECTOR_R:
2526 	case OPT_GAMMA_VECTOR_G:
2527 	case OPT_GAMMA_VECTOR_B:
2528 	  memcpy (s->val[option].wa, val, s->opt[option].size);
2529 	  return SANE_STATUS_GOOD;
2530 
2531 	case OPT_CUSTOM_GAMMA:
2532 	  w = *(SANE_Word *) val;
2533 
2534 	  if (w == s->val[OPT_CUSTOM_GAMMA].w)
2535 	    return SANE_STATUS_GOOD;		/* no change */
2536 
2537 	  if (info)
2538 	    *info |= SANE_INFO_RELOAD_OPTIONS;
2539 	  s->val[OPT_CUSTOM_GAMMA].w = w;
2540           set_gamma_caps(s);
2541 	  return SANE_STATUS_GOOD;
2542 #endif
2543 	}
2544     }
2545 
2546   DBG (10, ">>\n");
2547   return (SANE_STATUS_INVAL);
2548 }
2549 
2550 SANE_Status
sane_get_parameters(SANE_Handle handle, SANE_Parameters * params)2551 sane_get_parameters (SANE_Handle handle, SANE_Parameters * params)
2552 {
2553   int width, length, res;
2554   const char *mode;
2555   NEC_Scanner *s = handle;
2556   DBG (10, "<< sane_get_parameters ");
2557 
2558   res = s->val[OPT_RESOLUTION].w * s->dev->info.res_range.quant;
2559   if (!s->scanning)
2560     {
2561       /* make best-effort guess at what parameters will look like once
2562          scanning starts.  */
2563       memset (&s->params, 0, sizeof (s->params));
2564 
2565       width = MM_TO_PIX(  SANE_UNFIX(s->val[OPT_BR_X].w)
2566                         - SANE_UNFIX(s->val[OPT_TL_X].w),
2567 			s->dev->info.mud);
2568       length = MM_TO_PIX(  SANE_UNFIX(s->val[OPT_BR_Y].w)
2569                           - SANE_UNFIX(s->val[OPT_TL_Y].w),
2570 			 s->dev->info.mud);
2571 
2572       s->width = width;
2573       s->length = length;
2574       s->params.pixels_per_line = width * res / s->dev->info.mud;
2575       s->params.lines = length * res / s->dev->info.mud;
2576 
2577       if (s->dev->sensedat.model == PCIN500)
2578 	{
2579 	  s->params.pixels_per_line += 1;
2580 	  s->params.lines += 1;
2581 	}
2582       s->unscanned_lines = s->params.lines;
2583     }
2584 #if 0
2585   else
2586     {
2587       buffer_status bs;
2588       SANE_Status status;
2589       size_t len = sizeof (buffer_status);
2590       status = get_data_buffer_status (s->fd, &bs, &len);
2591       DBG (11, "<< get_data_buffer_status ");
2592 
2593       if (status != SANE_STATUS_GOOD)
2594 	{
2595 	  do_cancel(s);
2596 	  return (status);
2597 	}
2598       DBG (11, ">>\n ");
2599       {
2600 #ifdef DEBUG_NEC
2601 	int i;
2602 	u_char *buf = &bs;
2603 	DBG(11, "get data buffer status(debug):\n");
2604 	for (i = 0; i < len; i += 16)
2605 	  {
2606 	    DBG(1, "%2x %2x %2x %2x %2x %2x %2x %2x - %2x %2x %2x %2x \n",
2607 		buf[i], buf[i+1], buf[i+2], buf[i+3], buf[i+4], buf[i+5], buf[i+6], buf[i+7], buf[i+8],
2608 		buf[i+9], buf[i+10], buf[i+11]);
2609 	  }
2610 #endif
2611       }
2612     }
2613 #endif
2614   res = s->val[OPT_RESOLUTION].w * s->dev->info.res_range.quant;
2615 
2616   mode = s->val[OPT_MODE].s;
2617 
2618   if (strcmp (mode, M_LINEART) == 0)
2619      {
2620        s->params.format = SANE_FRAME_GRAY;
2621        s->params.bytes_per_line = (s->params.pixels_per_line + 7) / 8;
2622        s->params.depth = 1;
2623        s->modes = MODES_LINEART;
2624      }
2625   else if (strcmp (mode, M_GRAY) == 0)
2626      {
2627        s->params.format = SANE_FRAME_GRAY;
2628        s->params.bytes_per_line = s->params.pixels_per_line;
2629        s->params.depth = 8;
2630        s->modes = MODES_GRAY;
2631      }
2632   else if (strcmp (mode, M_LINEART_COLOR) == 0)
2633     {
2634        s->params.format = SANE_FRAME_RGB;
2635        s->params.bytes_per_line = 3 * (s->params.pixels_per_line + 7) / 8;
2636        s->params.depth = 8;
2637        s->modes = MODES_LINEART_COLOR;
2638     }
2639   else
2640      {
2641        s->params.format = SANE_FRAME_RGB;
2642        s->params.bytes_per_line = 3 * s->params.pixels_per_line;
2643        s->params.depth = 8;
2644        s->modes = MODES_COLOR;
2645      }
2646   s->params.last_frame = SANE_TRUE;
2647 
2648   if (params)
2649     *params = s->params;
2650 
2651   DBG (10, ">>\n");
2652   return (SANE_STATUS_GOOD);
2653 }
2654 
2655 #ifdef USE_CUSTOM_GAMMA
2656 
2657 static int
sprint_gamma(Option_Value val, SANE_Byte *dst)2658 sprint_gamma(Option_Value val, SANE_Byte *dst)
2659 {
2660   int i;
2661   SANE_Byte *p = dst;
2662 
2663   p += sprintf((char *) p, "%i", val.wa[0]);
2664   for (i = 1; i < 256; i++)
2665     p += sprintf((char *) p, ",%i", val.wa[i] > 255 ? 255 : val.wa[i]);
2666   return p - dst;
2667 }
2668 
2669 static SANE_Status
send_ascii_gamma_tables(NEC_Scanner *s)2670 send_ascii_gamma_tables (NEC_Scanner *s)
2671 {
2672   SANE_Status status;
2673   int i;
2674 
2675   DBG(11, "<< send_ascii_gamma_tables ");
2676 
2677   /* we need: 4 bytes for each gamma value (3 digits + delimiter)
2678              + 10 bytes for the command header
2679      i.e. 4 * 4 * 256 + 10 = 4106 bytes
2680   */
2681 
2682   if (s->dev->info.bufsize < 4106)
2683     return SANE_STATUS_NO_MEM;
2684 
2685   memset(s->buffer, 0, 4106);
2686 
2687   i = sprint_gamma(s->val[OPT_GAMMA_VECTOR_R], &s->buffer[10]);
2688   s->buffer[10+i++] = '/';
2689   i += sprint_gamma(s->val[OPT_GAMMA_VECTOR_G], &s->buffer[10+i]);
2690   s->buffer[10+i++] = '/';
2691   i += sprint_gamma(s->val[OPT_GAMMA_VECTOR_B], &s->buffer[10+i]);
2692   s->buffer[10+i++] = '/';
2693   i += sprint_gamma(s->val[OPT_GAMMA_VECTOR], &s->buffer[10+i]);
2694 
2695   DBG(12, "%s\n", &s->buffer[10]);
2696 
2697   s->buffer[0] = SEND;
2698   s->buffer[2] = 0x03;
2699   s->buffer[7] = i >> 8;
2700   s->buffer[8] = i & 0xff;
2701 
2702   wait_ready(s->fd);
2703   status = sanei_scsi_cmd (s->fd, s->buffer, i+10, 0, 0);
2704 
2705   DBG(11, ">>\n");
2706 
2707   return status;
2708 }
2709 #endif
2710 
2711 static SANE_Status
send_binary_g_table(NEC_Scanner *s, SANE_Word *a, int dtq)2712 send_binary_g_table(NEC_Scanner *s, SANE_Word *a, int dtq)
2713 {
2714   SANE_Status status;
2715   unsigned int i, j;
2716 
2717   (void) dtq; /* silence compilation warnings */
2718 
2719   DBG(11, "<< send_binary_g_table\n");
2720 
2721   i = 256;
2722   if (s->dev->info.bufsize < i)
2723     return SANE_STATUS_NO_MEM;
2724   memset(s->buffer, 0, i+10);
2725 
2726   s->buffer[0] = SEND;
2727   s->buffer[2] = 0x03;
2728   s->buffer[7] = i >> 8;
2729   s->buffer[8] = i & 0xff;
2730 
2731   for (i = 0; i < 256; i++)
2732     {
2733       s->buffer[i+11] = a[i&0xff] & 0xff;
2734     }
2735 
2736   for (j = 0; j < 256; j += 16)
2737     {
2738       DBG(11, "%02x %02x %02x %02x %02x %02x %02x %02x "
2739               "%02x %02x %02x %02x %02x %02x %02x %02x\n",
2740               a[j  ], a[j+1], a[j+2], a[j+3],
2741               a[j+4], a[j+5], a[j+6], a[j+7],
2742               a[j+8], a[j+9], a[j+10], a[j+11],
2743               a[j+12], a[j+13], a[j+14], a[j+15]);
2744     }
2745   DBG(12, "transfer length = %d\n", i);
2746   DBG(12, "buffer[7] = %d\n", s->buffer[7]);
2747   DBG(12, "buffer[8] = %d\n", s->buffer[8]);
2748 
2749   /*  wait_ready(s->fd); */
2750   status = sanei_scsi_cmd (s->fd, s->buffer, i+10, 0, 0);
2751 
2752   DBG(11, ">>\n");
2753 
2754   return status;
2755 }
2756 
2757 #ifdef USE_CUSTOM_GAMMA
2758 static SANE_Status
send_binary_gamma_tables(NEC_Scanner *s)2759 send_binary_gamma_tables (NEC_Scanner *s)
2760 {
2761   SANE_Status status;
2762 
2763   status = send_binary_g_table(s, s->val[OPT_GAMMA_VECTOR].wa, 0x10);
2764   if (status != SANE_STATUS_GOOD)
2765     return status;
2766   DBG(11, "send_binary_gamma_tables\n");
2767 #if 0
2768   status = send_binary_g_table(s, s->val[OPT_GAMMA_VECTOR_R].wa, 0x11);
2769   if (status != SANE_STATUS_GOOD)
2770     return status;
2771 
2772   status = send_binary_g_table(s, s->val[OPT_GAMMA_VECTOR_G].wa, 0x12);
2773   if (status != SANE_STATUS_GOOD)
2774     return status;
2775 
2776   status = send_binary_g_table(s, s->val[OPT_GAMMA_VECTOR_B].wa, 0x13);
2777 #endif
2778   return status;
2779 }
2780 
2781 static SANE_Status
send_gamma_tables(NEC_Scanner *s)2782 send_gamma_tables (NEC_Scanner *s)
2783 {
2784   if (s->dev->sensedat.model == PCIN500)
2785     {
2786       return send_binary_gamma_tables(s);
2787     }
2788   else
2789     {
2790       return send_ascii_gamma_tables(s);
2791     }
2792 
2793 }
2794 #endif
2795 
2796 #ifdef USE_COLOR_THRESHOLD
2797 /* not used? */
2798 #if 0
2799 static SANE_Status
2800 send_threshold_data(NEC_Scanner *s)
2801 {
2802   SANE_Status status;
2803   SANE_Byte cmd[26] = {SEND, 0, 0x82, 0, 0, 0, 0, 0, 0, 0};
2804   int len;
2805 
2806   memset(cmd, 0, sizeof(cmd));
2807   /* maximum string length: 3 bytes for each number (they are
2808      restricted to the range 0..255), 3 '/' and the null-byte,
2809      total: 16 bytes.
2810   */
2811   len = sprintf((char *) &cmd[10], "%i/%i/%i/%i",
2812                 s->val[OPT_THRESHOLD_R].w,
2813                 s->val[OPT_THRESHOLD_G].w,
2814                 s->val[OPT_THRESHOLD_B].w,
2815                 s->val[OPT_THRESHOLD].w);
2816   cmd[8] = len;
2817 
2818   wait_ready(s->fd);
2819   status = sanei_scsi_cmd(s->fd, cmd, len + 10, 0, 0);
2820   return status;
2821 }
2822 #endif
2823 #endif
2824 
2825 SANE_Status
sane_start(SANE_Handle handle)2826 sane_start (SANE_Handle handle)
2827 {
2828   char *mode, *halftone, *gamma, *edge, *lightcolor, *adf_fsu;
2829   NEC_Scanner *s = handle;
2830   SANE_Status status;
2831   size_t buf_size;
2832   window_param wp;
2833 
2834   DBG (10, "<< sane_start ");
2835 
2836   /* First make sure we have a current parameter set.  Some of the
2837      parameters will be overwritten below, but that's OK.  */
2838   status = sane_get_parameters (s, 0);
2839   if (status != SANE_STATUS_GOOD)
2840     return status;
2841 
2842   s->dev->sensedat.complain_on_adf_error = 1;
2843 
2844 #ifdef HAVE_SANEI_SCSI_OPEN_EXTENDED
2845   s->dev->info.bufsize = s->dev->info.wanted_bufsize;
2846   if (s->dev->info.bufsize < 32 * 1024)
2847     s->dev->info.bufsize = 32 * 1024;
2848   {
2849     int bsize = s->dev->info.bufsize;
2850     status = sanei_scsi_open_extended (s->dev->sane.name, &s->fd,
2851               &sense_handler, &s->dev->sensedat, &bsize);
2852     s->dev->info.bufsize = bsize;
2853   }
2854 
2855   if (status != SANE_STATUS_GOOD)
2856     {
2857       DBG (1, "open of %s failed: %s\n",
2858          s->dev->sane.name, sane_strstatus (status));
2859       return (status);
2860     }
2861 
2862   /* make sure that we got at least 32 kB. Even then, the scan will be
2863      awfully slow.
2864 
2865   */
2866   if (s->dev->info.bufsize < 32 * 1024)
2867     {
2868       sanei_scsi_close(s->fd);
2869       s->fd = -1;
2870       return SANE_STATUS_NO_MEM;
2871     }
2872 #else
2873   status = sanei_scsi_open(s->dev->sane.name, &s->fd, &sense_handler,
2874               &s->dev->sensedat);
2875   if (s->dev->info.wanted_bufsize < sanei_scsi_max_request_size)
2876     s->dev->info.bufsize = s->dev->info.wanted_bufsize;
2877   else
2878     s->dev->info.bufsize = sanei_scsi_max_request_size;
2879 
2880   if (status != SANE_STATUS_GOOD)
2881     {
2882       DBG (1, "open of %s failed: %s\n",
2883          s->dev->sane.name, sane_strstatus (status));
2884       return (status);
2885     }
2886 #endif
2887 
2888   s->buffer = malloc(s->dev->info.bufsize);
2889   if (!s->buffer) {
2890     sanei_scsi_close(s->fd);
2891     s->fd = -1;
2892     free(s);
2893     return SANE_STATUS_NO_MEM;
2894   }
2895 
2896 #ifdef USE_FORK
2897   {
2898     struct shmid_ds ds;
2899     size_t n;
2900 
2901     s->shmid = shmget(IPC_PRIVATE,
2902        sizeof(NEC_rdr_ctl)
2903        + s->dev->info.buffers *
2904          (sizeof(NEC_shmem_ctl) + s->dev->info.bufsize),
2905        IPC_CREAT | 0600);
2906     if (s->shmid == -1)
2907       {
2908         free(s->buffer);
2909         s->buffer = 0;
2910         sanei_scsi_close(s->fd);
2911         s->fd = -1;
2912         return SANE_STATUS_NO_MEM;
2913       }
2914     s->rdr_ctl = (NEC_rdr_ctl*) shmat(s->shmid, 0, 0);
2915     if ((int)s->rdr_ctl == -1)
2916      {
2917        shmctl(s->shmid, IPC_RMID, &ds);
2918        free(s->buffer);
2919        s->buffer = 0;
2920        sanei_scsi_close(s->fd);
2921        s->fd = -1;
2922        return SANE_STATUS_NO_MEM;
2923      }
2924 
2925     s->rdr_ctl->buf_ctl = (NEC_shmem_ctl*) &s->rdr_ctl[1];
2926     for (n = 0; n < s->dev->info.buffers; n++)
2927       {
2928         s->rdr_ctl->buf_ctl[n].buffer =
2929           (SANE_Byte*) &s->rdr_ctl->buf_ctl[s->dev->info.buffers]
2930             + n * s->dev->info.bufsize;
2931       }
2932   }
2933 #endif /* USE_FORK */
2934 
2935   DBG (5, "start: TEST_UNIT_READY\n");
2936   status = test_unit_ready (s->fd);
2937 
2938   if (status != SANE_STATUS_GOOD)
2939     {
2940       DBG (1, "TEST UNIT READY failed: %s\n", sane_strstatus (status));
2941       sanei_scsi_close (s->fd);
2942       s->fd = -1;
2943       return (status);
2944     }
2945 
2946   DBG (3, "start: sending MODE SELECT\n");
2947   status = mode_select_mud (s->fd, s->dev->info.mud);
2948   if (status != SANE_STATUS_GOOD)
2949     {
2950       DBG (1, "start: MODE_SELECT6 failed\n");
2951       sanei_scsi_close (s->fd);
2952       s->fd = -1;
2953       return (status);
2954     }
2955 
2956   mode = s->val[OPT_MODE].s;
2957   halftone = s->val[OPT_HALFTONE].s;
2958   gamma = s->val[OPT_GAMMA].s;
2959   edge = s->val[OPT_EDGE_EMPHASIS].s;
2960   lightcolor = s->val[OPT_LIGHTCOLOR].s;
2961   adf_fsu = s->val[OPT_SCANSOURCE].s;
2962 
2963   if (s->val[OPT_PREVIEW].w == SANE_FALSE)
2964     {
2965       s->res = s->val[OPT_RESOLUTION].w * s->dev->info.res_range.quant;
2966     }
2967   else
2968     {
2969       s->res = 75;
2970     }
2971   s->ulx = MM_TO_PIX(SANE_UNFIX(s->val[OPT_TL_X].w), s->dev->info.mud);
2972   s->uly = MM_TO_PIX(SANE_UNFIX(s->val[OPT_TL_Y].w), s->dev->info.mud);
2973   s->threshold = s->val[OPT_THRESHOLD].w;
2974 
2975   if (strcmp (mode, M_LINEART_COLOR) == 0)
2976     s->bpp = 1;
2977   else
2978     s->bpp = s->params.depth;
2979 
2980   s->adf_fsu_mode = SCAN_SIMPLE; /* default: scan without ADF and FSU */
2981 
2982   if (strcmp(adf_fsu, use_fsu) == 0)
2983     s->adf_fsu_mode = SCAN_WITH_FSU;
2984   else if (strcmp(adf_fsu, use_adf) == 0)
2985     s->adf_fsu_mode = SCAN_WITH_ADF;
2986   else if (strcmp(adf_fsu, use_adf) == 0)
2987     s->adf_fsu_mode = SCAN_SIMPLE;
2988 
2989   /* halftone must not set to be zero PC-IN500 */
2990   s->halftone = 0x01;
2991   if (strcmp (mode, M_LINEART) == 0)
2992     {
2993       s->reverse = 0;
2994       s->image_composition = 1;
2995       if (strcmp(halftone, M_BILEVEL) == 0)
2996 	{
2997 	  s->image_composition = 0;
2998 	  s->halftone = 0x01;
2999 	}
3000       else if (strcmp(halftone, M_DITHER1) == 0)
3001 	s->halftone = 0x01;
3002       else if (strcmp(halftone, M_DITHER2) == 0)
3003 	s->halftone = 0x10;
3004       else if (strcmp(halftone, M_DITHER3) == 0)
3005 	s->halftone = 0x20;
3006     }
3007   else if (strcmp (mode, M_GRAY) == 0)
3008     {
3009       s->image_composition = 2;
3010       s->reverse = 1;
3011     }
3012   else if (strcmp (mode, M_LINEART_COLOR) == 0)
3013     {
3014       s->reverse = 1;
3015       s->image_composition = 4;
3016       if (strcmp(halftone, M_BILEVEL) == 0)
3017 	{
3018 	  s->image_composition = 3;
3019 	  s->halftone = 0x01;
3020 	}
3021       else if (strcmp(halftone, M_DITHER1) == 0)
3022 	s->halftone = 0x01;
3023       else if (strcmp(halftone, M_DITHER2) == 0)
3024 	s->halftone = 0x10;
3025       else if (strcmp(halftone, M_DITHER3) == 0)
3026 	s->halftone = 0x20;
3027     }
3028   else if (strcmp (mode, M_COLOR) == 0)
3029     {
3030       s->image_composition = 5;
3031       s->reverse = 1;
3032     }
3033 
3034   if (s->dev->sensedat.model == PCIN500)
3035     {
3036       s->or = s->val[OPT_OR].w;
3037       s->nr = s->val[OPT_NR].w;
3038       s->edge = s->val[OPT_EDGE].w;
3039     }
3040   else
3041     {
3042       if (strcmp (edge, EDGE_NONE) == 0)
3043 	s->edge = 0;
3044       else if (strcmp (edge, EDGE_MIDDLE) == 0)
3045 	s->edge = 1;
3046       else if (strcmp (edge, EDGE_STRONG) == 0)
3047 	s->edge = 2;
3048       else if (strcmp (edge, EDGE_BLUR) == 0)
3049 	s->edge = 3;
3050     }
3051 
3052   s->lightcolor = 3;
3053   if (strcmp(lightcolor, LIGHT_GREEN) == 0)
3054     s->lightcolor = 0;
3055   else if (strcmp(lightcolor, LIGHT_RED) == 0)
3056     s->lightcolor = 1;
3057   else if (strcmp(lightcolor, LIGHT_BLUE) == 0)
3058     s->lightcolor = 2;
3059   else if (strcmp(lightcolor, LIGHT_NONE) == 0)
3060     s->lightcolor = 3;
3061 
3062   s->adf_scan = 0;
3063 
3064 #ifdef USE_CUSTOM_GAMMA
3065   if (s->val[OPT_CUSTOM_GAMMA].w == SANE_FALSE)
3066     {
3067 #endif
3068       if (s->dev->sensedat.model == PCIN500)
3069 	{
3070 	  if (strcmp (gamma, CRT1))
3071 	    s->gamma = 1;
3072 	  else if (strcmp (gamma, CRT2))
3073 	    s->gamma = 2;
3074 	  else if (strcmp (gamma, PRINTER1))
3075 	    s->gamma = 3;
3076 	  else if (strcmp (gamma, PRINTER2))
3077 	    s->gamma = 4;
3078 	  else if (strcmp (gamma, NONE))
3079 	    s->gamma = 5;
3080 	}
3081 #if 0
3082       if (s->dev->sensedat.model != PCIN500)
3083         {
3084           ss.dtc = 0x03;
3085           if (strcmp (gamma, GAMMA10) == 0)
3086 	    ss.dtq = 0x01;
3087           else
3088 	    ss.dtq = 0x02;
3089           ss.length = 0;
3090           DBG (5, "start: SEND\n");
3091           status = send (s->fd,  &ss);
3092           if (status != SANE_STATUS_GOOD)
3093             {
3094               DBG (1, "send failed: %s\n", sane_strstatus (status));
3095               sanei_scsi_close (s->fd);
3096               s->fd = -1;
3097               return (status);
3098             }
3099        }
3100      else
3101 #else
3102        {
3103          int i;
3104          SANE_Word gtbl[256];
3105 #if 0
3106          if (strcmp (gamma, GAMMA10) == 0)
3107            for (i = 0; i < 256; i++)
3108              gtbl[i] = i;
3109          else
3110 #endif
3111            {
3112              gtbl[0] = 0;
3113              for (i = 1; i < 256; i++)
3114                gtbl[i] = 255 * exp(0.45 * log(i/255.0));
3115            }
3116          send_binary_g_table(s, gtbl, 0x10);
3117          send_binary_g_table(s, gtbl, 0x11);
3118          send_binary_g_table(s, gtbl, 0x12);
3119          send_binary_g_table(s, gtbl, 0x13);
3120        }
3121 #endif /* DEBUG_NEC */
3122 #ifdef USE_CUSTOM_GAMMA
3123     }
3124   else
3125     {
3126       s->gamma = 9;
3127       status = send_gamma_tables(s);
3128     }
3129   if (status != SANE_STATUS_GOOD)
3130     {
3131       sanei_scsi_close (s->fd);
3132       s->fd = -1;
3133       return (status);
3134     }
3135 #endif
3136 
3137   s->tint = s->val[OPT_TINT].w;
3138   s->color = s->val[OPT_COLOR].w;
3139 
3140   memset (&wp, 0, sizeof (wp));
3141   /* every NEC scanner seems to have a different
3142      window descriptor block...
3143   */
3144   if (s->dev->sensedat.model == PCIN500)
3145     buf_size = sizeof(WDB) + sizeof(WDBX500);
3146   else
3147     buf_size = sizeof(WDB);
3148 
3149   wp.wpdh.wdl[0] = buf_size >> 8;
3150   wp.wpdh.wdl[1] = buf_size;
3151   wp.wdb.x_res[0] = s->res >> 8;
3152   wp.wdb.x_res[1] = s->res;
3153   wp.wdb.y_res[0] = s->res >> 8;
3154   wp.wdb.y_res[1] = s->res;
3155   wp.wdb.x_ul[0] = s->ulx >> 24;
3156   wp.wdb.x_ul[1] = s->ulx >> 16;
3157   wp.wdb.x_ul[2] = s->ulx >> 8;
3158   wp.wdb.x_ul[3] = s->ulx;
3159   wp.wdb.y_ul[0] = s->uly >> 24;
3160   wp.wdb.y_ul[1] = s->uly >> 16;
3161   wp.wdb.y_ul[2] = s->uly >> 8;
3162   wp.wdb.y_ul[3] = s->uly;
3163   wp.wdb.width[0] = s->width >> 24;
3164   wp.wdb.width[1] = s->width >> 16;
3165   wp.wdb.width[2] = s->width >> 8;
3166   wp.wdb.width[3] = s->width;
3167   wp.wdb.length[0] = s->length >> 24;
3168   wp.wdb.length[1] = s->length >> 16;
3169   wp.wdb.length[2] = s->length >> 8;
3170   wp.wdb.length[3] = s->length;
3171   wp.wdb.brightness = 0;
3172   wp.wdb.threshold = s->threshold;
3173   wp.wdb.brightness = 128;
3174   wp.wdb.contrast = 128;
3175   wp.wdb.image_composition = s->image_composition;
3176   if (s->image_composition <= 2 || s->image_composition >= 5)
3177     wp.wdb.bpp = s->bpp;
3178   else
3179     wp.wdb.bpp = 1;
3180   wp.wdb.ht_pattern[0] = 0;
3181   wp.wdb.ht_pattern[1] = 0;
3182   if (s->dev->sensedat.model == PCIN500)
3183     wp.wdb.ht_pattern[1] = s->halftone;
3184   wp.wdb.rif_padding = (s->reverse * 128) + 0;
3185 
3186   if (s->dev->sensedat.model == PCIN500)
3187     {
3188       wp.wdbx500.data_length = 0x07;
3189       wp.wdbx500.control = 0 | (s->or << 7) | (s->edge << 6) | (s->nr << 5) |
3190 	                   (s->lightcolor << 2);
3191       wp.wdbx500.format = 0;
3192       wp.wdbx500.gamma = s->gamma;
3193       wp.wdbx500.tint = s->tint;
3194       wp.wdbx500.color = s->color;
3195       wp.wdbx500.reserved1 = 0;
3196       wp.wdbx500.reserved2 = 0;
3197     }
3198 
3199   DBG (5, "wdl=%d\n", (wp.wpdh.wdl[0] << 8) + wp.wpdh.wdl[1]);
3200   DBG (5, "xres=%d\n", (wp.wdb.x_res[0] << 8) + wp.wdb.x_res[1]);
3201   DBG (5, "yres=%d\n", (wp.wdb.y_res[0] << 8) + wp.wdb.y_res[1]);
3202   DBG (5, "ulx=%d\n", (wp.wdb.x_ul[0] << 24) + (wp.wdb.x_ul[1] << 16) +
3203                       (wp.wdb.x_ul[2] << 8) + wp.wdb.x_ul[3]);
3204   DBG (5, "uly=%d\n", (wp.wdb.y_ul[0] << 24) + (wp.wdb.y_ul[1] << 16) +
3205                       (wp.wdb.y_ul[2] << 8) + wp.wdb.y_ul[3]);
3206   DBG (5, "width=%d\n", (wp.wdb.width[0] << 8) + (wp.wdb.width[1] << 16) +
3207                         (wp.wdb.width[2] << 8) + wp.wdb.width[3]);
3208   DBG (5, "length=%d\n", (wp.wdb.length[0] << 16) + (wp.wdb.length[1] << 16) +
3209                          (wp.wdb.length[2] << 8) + wp.wdb.length[3]);
3210 
3211   DBG (5, "threshold=%d\n", wp.wdb.threshold);
3212   DBG (5, "image_composition=%d\n", wp.wdb.image_composition);
3213   DBG (5, "bpp=%d\n", wp.wdb.bpp);
3214   DBG (5, "rif_padding=%d\n", wp.wdb.rif_padding);
3215 
3216 #ifdef DEBUG_NEC
3217   {
3218     window_param foo;
3219     size_t len = buf_size;
3220     len += sizeof(WPDH);
3221   DBG (5, "start: GET WINDOW\n");
3222   status = get_window (s->fd, &foo, &len);
3223   if (status != SANE_STATUS_GOOD)
3224     {
3225       DBG (1, "GET WINDOW failed: %s\n", sane_strstatus (status));
3226       sanei_scsi_close (s->fd);
3227       s->fd = -1;
3228       return (status);
3229     }
3230 #if 1
3231   {
3232     unsigned char *p = (unsigned char*) &foo;
3233     int i;
3234     DBG(11, "get window(debug):\n");
3235     for (i = 0; i < len; i += 16)
3236      {
3237       DBG(1, "%2x %2x %2x %2x %2x %2x %2x %2x - %2x %2x %2x %2x %2x %2x %2x %2x\n",
3238       p[i], p[i+1], p[i+2], p[i+3], p[i+4], p[i+5], p[i+6], p[i+7], p[i+8],
3239       p[i+9], p[i+10], p[i+11], p[i+12], p[i+13], p[i+14], p[i+15]);
3240      }
3241   }
3242 #endif
3243   foo.wpdh.wpdh[1] = 0;
3244   status = set_window (s->fd, &foo, len);
3245   if (status != SANE_STATUS_GOOD)
3246     {
3247       DBG (1, "SET WINDOW failed: %s\n", sane_strstatus (status));
3248       sanei_scsi_close (s->fd);
3249       s->fd = -1;
3250       return (status);
3251     }
3252 #if 1
3253   {
3254     unsigned char *p = (unsigned char*) &foo;
3255     int i;
3256     DBG(11, "set window(debug):\n");
3257     for (i = 0; i < len; i += 16)
3258      {
3259       DBG(1, "%2x %2x %2x %2x %2x %2x %2x %2x - %2x %2x %2x %2x %2x %2x %2x %2x\n",
3260       p[i], p[i+1], p[i+2], p[i+3], p[i+4], p[i+5], p[i+6], p[i+7], p[i+8],
3261       p[i+9], p[i+10], p[i+11], p[i+12], p[i+13], p[i+14], p[i+15]);
3262      }
3263   }
3264 #endif
3265   }
3266 #endif /* debug_nec */
3267 
3268 #ifdef DEBUG_NEC
3269   {
3270     unsigned char *p = (unsigned char*) &wp;
3271     int i;
3272     DBG(11, "set window(debug):\n");
3273     for (i = 0; i < sizeof(wp.wdb) + sizeof(wp.wdbx500); i += 16)
3274      {
3275       DBG(1, "%2x %2x %2x %2x %2x %2x %2x %2x - %2x %2x %2x %2x %2x %2x %2x %2x\n",
3276       p[i], p[i+1], p[i+2], p[i+3], p[i+4], p[i+5], p[i+6], p[i+7], p[i+8],
3277       p[i+9], p[i+10], p[i+11], p[i+12], p[i+13], p[i+14], p[i+15]);
3278      }
3279   }
3280 #endif /* debug_nec */
3281 
3282   buf_size += sizeof(WPDH);
3283   DBG (5, "start: SET WINDOW\n");
3284   status = set_window (s->fd, &wp, buf_size);
3285   if (status != SANE_STATUS_GOOD)
3286     {
3287       DBG (1, "SET WINDOW failed: %s\n", sane_strstatus (status));
3288       sanei_scsi_close (s->fd);
3289       s->fd = -1;
3290       return (status);
3291     }
3292 
3293   memset (&wp, 0, buf_size);
3294   DBG (5, "start: GET WINDOW\n");
3295   status = get_window (s->fd, &wp, &buf_size);
3296   if (status != SANE_STATUS_GOOD)
3297     {
3298       DBG (1, "GET WINDOW failed: %s\n", sane_strstatus (status));
3299       sanei_scsi_close (s->fd);
3300       s->fd = -1;
3301       return (status);
3302     }
3303 #ifdef DEBUG_NEC
3304   {
3305     unsigned char *p = (unsigned char*) &wp;
3306     int i;
3307     DBG(11, "get window(debug):\n");
3308     for (i = 0; i < buf_size; i += 16)
3309      {
3310       DBG(1, "%2x %2x %2x %2x %2x %2x %2x %2x - %2x %2x %2x %2x %2x %2x %2x %2x\n",
3311       p[i], p[i+1], p[i+2], p[i+3], p[i+4], p[i+5], p[i+6], p[i+7], p[i+8],
3312       p[i+9], p[i+10], p[i+11], p[i+12], p[i+13], p[i+14], p[i+15]);
3313      }
3314   }
3315 #endif
3316   DBG (5, "xres=%d\n", (wp.wdb.x_res[0] << 8) + wp.wdb.x_res[1]);
3317   DBG (5, "yres=%d\n", (wp.wdb.y_res[0] << 8) + wp.wdb.y_res[1]);
3318   DBG (5, "ulx=%d\n", (wp.wdb.x_ul[0] << 24) + (wp.wdb.x_ul[1] << 16) +
3319                       (wp.wdb.x_ul[2] << 8) + wp.wdb.x_ul[3]);
3320   DBG (5, "uly=%d\n", (wp.wdb.y_ul[0] << 24) + (wp.wdb.y_ul[1] << 16) +
3321        (wp.wdb.y_ul[2] << 8) + wp.wdb.y_ul[3]);
3322   DBG (5, "width=%d\n", (wp.wdb.width[0] << 24) + (wp.wdb.width[1] << 16) +
3323                         (wp.wdb.width[2] << 8) + wp.wdb.width[3]);
3324   DBG (5, "length=%d\n", (wp.wdb.length[0] << 24) + (wp.wdb.length[1] << 16) +
3325                          (wp.wdb.length[2] << 8) + wp.wdb.length[3]);
3326   DBG (5, "start: SCAN\n");
3327   s->scanning = SANE_TRUE;
3328   s->busy = SANE_TRUE;
3329   s->cancel = SANE_FALSE;
3330   s->get_params_called = 0;
3331 
3332   status = scan (s->fd);
3333 #ifdef DEBUG
3334           {
3335             struct timeval t;
3336             gettimeofday(&t, 0);
3337             DBG(2, "rd: scan started        %li.%06li\n", t.tv_sec, t.tv_usec);
3338           }
3339 #endif
3340   if (status != SANE_STATUS_GOOD)
3341     {
3342       DBG (1, "start of scan failed: %s\n", sane_strstatus (status));
3343       sanei_scsi_close (s->fd);
3344       s->fd = -1;
3345       s->busy = SANE_FALSE;
3346       s->cancel = SANE_FALSE;
3347       return (status);
3348     }
3349 
3350   /* ask the scanner for the scan size */
3351   /* wait_ready(s->fd); */
3352 #ifdef DEBUG
3353           {
3354             struct timeval t;
3355             gettimeofday(&t, 0);
3356             DBG(2, "rd: wait_ready ok       %li.%06li\n", t.tv_sec, t.tv_usec);
3357           }
3358 #endif
3359   sane_get_parameters(s, 0);
3360 #ifdef DEBUG
3361           {
3362             struct timeval t;
3363             gettimeofday(&t, 0);
3364             DBG(2, "rd: get_params ok       %li.%06li\n", t.tv_sec, t.tv_usec);
3365           }
3366 #endif
3367   if (strcmp (mode, M_LINEART_COLOR) != 0)
3368     s->bytes_to_read = s->params.bytes_per_line * s->params.lines;
3369   else
3370     {
3371       s->bytes_to_read = s->params.bytes_per_line * s->params.lines;
3372     }
3373 
3374 #ifdef USE_FORK
3375   {
3376     size_t i;
3377     for (i = 0; i < s->dev->info.buffers; i++)
3378       s->rdr_ctl->buf_ctl[i].shm_status = SHM_EMPTY;
3379     s->read_buff = 0;
3380     s->rdr_ctl->cancel = 0;
3381     s->rdr_ctl->running = 0;
3382     s->rdr_ctl->status  = SANE_STATUS_GOOD;
3383   }
3384   s->reader_pid = fork();
3385 #ifdef DEBUG
3386           {
3387             struct timeval t;
3388             gettimeofday(&t, 0);
3389             DBG(2, "rd: forked              %li.%06li %i\n", t.tv_sec, t.tv_usec,
3390               s->reader_pid);
3391           }
3392 #endif
3393   if (s->reader_pid == 0)
3394     {
3395       sigset_t ignore_set;
3396       struct SIGACTION act;
3397 
3398       sigfillset (&ignore_set);
3399       sigdelset (&ignore_set, SIGTERM);
3400       sigprocmask (SIG_SETMASK, &ignore_set, 0);
3401 
3402       memset (&act, 0, sizeof (act));
3403       sigaction (SIGTERM, &act, 0);
3404 
3405       /* don't use exit() since that would run the atexit() handlers... */
3406       _exit (reader_process (s));
3407     }
3408   else if (s->reader_pid == -1)
3409     {
3410       s->busy = SANE_FALSE;
3411       do_cancel(s);
3412       return SANE_STATUS_NO_MEM;
3413     }
3414 
3415 #endif /* USE_FORK */
3416 
3417 
3418   DBG (1, "%d pixels per line, %d bytes, %d lines high, total %lu bytes, "
3419        "dpi=%d\n", s->params.pixels_per_line, s->params.bytes_per_line,
3420        s->params.lines, (u_long) s->bytes_to_read, s->val[OPT_RESOLUTION].w);
3421 
3422   s->busy = SANE_FALSE;
3423   s->buf_used = 0;
3424   s->buf_pos = 0;
3425 
3426   if (s->cancel == SANE_TRUE)
3427     {
3428       do_cancel(s);
3429       DBG (10, ">>\n");
3430       return(SANE_STATUS_CANCELLED);
3431     }
3432 
3433   DBG (10, ">>\n");
3434   return (SANE_STATUS_GOOD);
3435 
3436 }
3437 
3438 static SANE_Status
sane_read_direct(SANE_Handle handle, SANE_Byte *dst_buf, SANE_Int max_len, SANE_Int * len)3439 sane_read_direct (SANE_Handle handle, SANE_Byte *dst_buf, SANE_Int max_len,
3440 	   SANE_Int * len)
3441 {
3442   NEC_Scanner *s = handle;
3443   SANE_Status status;
3444   size_t nread;
3445   DBG (10, "<< sane_read_direct ");
3446 
3447 #if 0
3448   {
3449     buffer_status bs;
3450     size_t len = sizeof (buffer_status);
3451     get_data_buffer_status (s->fd, &bs, &len);
3452     DBG (20, "buffer_status: %i ", bs.fdb[0]*256*256 + bs.fdb[1]*256 + bs.fdb[2]);
3453   }
3454 #endif
3455   DBG (20, "remaining: %lu ", (u_long)  s->bytes_to_read);
3456   *len = 0;
3457 
3458   if (s->bytes_to_read == 0)
3459     {
3460       do_cancel (s);
3461       return (SANE_STATUS_EOF);
3462     }
3463 
3464   if (!s->scanning)
3465     return (do_cancel (s));
3466   nread = max_len;
3467   if (nread > s->bytes_to_read)
3468     nread = s->bytes_to_read;
3469   if (nread > s->dev->info.bufsize)
3470     nread = s->dev->info.bufsize;
3471 
3472 #ifdef USE_FORK
3473   status = read_data(s, dst_buf, &nread);
3474 #else
3475 #ifdef NOTUSE_PCIN500
3476   wait_ready(s->fd);
3477 #endif
3478   status = read_data (s, dst_buf, &nread);
3479 #endif
3480   if (status != SANE_STATUS_GOOD)
3481     {
3482       do_cancel (s);
3483       return (SANE_STATUS_IO_ERROR);
3484     }
3485   *len = nread;
3486   s->bytes_to_read -= nread;
3487   DBG (20, "remaining: %lu ", (u_long) s->bytes_to_read);
3488 
3489   DBG (10, ">>\n");
3490   return (SANE_STATUS_GOOD);
3491 }
3492 
3493 static SANE_Status
sane_read_shuffled(SANE_Handle handle, SANE_Byte *dst_buf, SANE_Int max_len, SANE_Int * len, int eight_bit_data)3494 sane_read_shuffled (SANE_Handle handle, SANE_Byte *dst_buf, SANE_Int max_len,
3495 	   SANE_Int * len, int eight_bit_data)
3496 {
3497   NEC_Scanner *s = handle;
3498   SANE_Status status;
3499   SANE_Byte *dest, *red, *green, *blue, mask;
3500   SANE_Int transfer;
3501   size_t nread, ntest, pixel, max_pixel, line, max_line;
3502   size_t start_input, bytes_per_line_in;
3503   DBG (10, "<< sane_read_shuffled ");
3504 
3505 #if 0
3506   {
3507     buffer_status bs;
3508     size_t len = sizeof (buffer_status);
3509     get_data_buffer_status (s->fd, &bs, &len);
3510     DBG (20, "buffer_status: %i ", bs.fdb[0]*256*256 + bs.fdb[1]*256 + bs.fdb[2]);
3511   }
3512 #endif
3513   *len = 0;
3514   if (s->bytes_to_read == 0 && s->buf_pos == s->buf_used)
3515     {
3516       do_cancel (s);
3517       DBG (10, ">>\n");
3518       return (SANE_STATUS_EOF);
3519     }
3520 
3521   if (!s->scanning)
3522     {
3523       DBG (10, ">>\n");
3524       return(do_cancel(s));
3525     }
3526 
3527   if (s->buf_pos < s->buf_used)
3528     {
3529       transfer = s->buf_used - s->buf_pos;
3530       if (transfer > max_len)
3531         transfer = max_len;
3532 
3533       memcpy(dst_buf, &(s->buffer[s->buf_pos]), transfer);
3534       s->buf_pos += transfer;
3535       max_len -= transfer;
3536       *len = transfer;
3537     }
3538 
3539   while (max_len > 0 && s->bytes_to_read > 0)
3540     {
3541       if (eight_bit_data)
3542         {
3543           nread = s->dev->info.bufsize / s->params.bytes_per_line - 1;
3544           nread *= s->params.bytes_per_line;
3545           if (nread > s->bytes_to_read)
3546             nread = s->bytes_to_read;
3547           max_line = nread / s->params.bytes_per_line;
3548           start_input = s->params.bytes_per_line;
3549           bytes_per_line_in = s->params.bytes_per_line;
3550         }
3551       else
3552         {
3553           bytes_per_line_in = (s->params.pixels_per_line + 7) / 8;
3554           bytes_per_line_in *= 3;
3555           max_line = s->params.bytes_per_line + bytes_per_line_in;
3556           max_line = s->dev->info.bufsize / max_line;
3557           nread = max_line * bytes_per_line_in;
3558           if (nread > s->bytes_to_read)
3559             {
3560               nread = s->bytes_to_read;
3561               max_line = nread / bytes_per_line_in;
3562             }
3563           start_input = s->dev->info.bufsize - nread;
3564         }
3565       ntest = nread;
3566 
3567 #ifdef USE_FORK
3568       status = read_data (s, &(s->buffer[start_input]), &nread);
3569 #else
3570       status = read_data (s, &(s->buffer[start_input]), &nread);
3571 #endif
3572       if (status != SANE_STATUS_GOOD)
3573         {
3574           do_cancel (s);
3575           DBG (10, ">>\n");
3576           return (SANE_STATUS_IO_ERROR);
3577         }
3578 
3579       if (nread != ntest)
3580         {
3581           /* if this happens, something is wrong in the input buffer
3582              management...
3583           */
3584           DBG(1, "Warning: could not read an integral number of scan lines\n");
3585           DBG(1, "         image will be scrambled\n");
3586         }
3587 
3588 
3589       s->buf_used = max_line * s->params.bytes_per_line;
3590       s->buf_pos = 0;
3591       s->bytes_to_read -= nread;
3592       dest = s->buffer;
3593       max_pixel = s->params.pixels_per_line;
3594 
3595       if (eight_bit_data)
3596         for (line = 1; line <= max_line; line++)
3597           {
3598             red = &(s->buffer[line * s->params.bytes_per_line]);
3599             green = &(red[max_pixel]);
3600             blue = &(green[max_pixel]);
3601             for (pixel = 0; pixel < max_pixel; pixel++)
3602               {
3603                 *dest++ = *red++;
3604                 *dest++ = *green++;
3605                 *dest++ = *blue++;
3606               }
3607           }
3608       else
3609         for (line = 0; line < max_line; line++)
3610           {
3611             red = &(s->buffer[start_input + line * bytes_per_line_in]);
3612             green = &(red[(max_pixel+7)/8]);
3613             blue = &(green[(max_pixel+7)/8]);
3614             mask = 0x80;
3615             for (pixel = 0; pixel < max_pixel; pixel++)
3616               {
3617                 *dest++ = (*red & mask)   ? 0xff : 0;
3618                 *dest++ = (*green & mask) ? 0xff : 0;
3619                 *dest++ = (*blue & mask)  ? 0xff : 0;
3620                 mask = mask >> 1;
3621                 if (mask == 0)
3622                   {
3623                     mask = 0x80;
3624                     red++;
3625                     green++;
3626                     blue++;
3627                   }
3628               }
3629           }
3630 
3631       transfer = max_len;
3632       if (transfer > s->buf_used)
3633         transfer = s->buf_used;
3634       memcpy(&(dst_buf[*len]), s->buffer, transfer);
3635 
3636       max_len -= transfer;
3637       s->buf_pos += transfer;
3638       *len += transfer;
3639     }
3640 
3641   if (s->bytes_to_read == 0 && s->buf_pos == s->buf_used)
3642     do_cancel (s);
3643   DBG (10, ">>\n");
3644   return (SANE_STATUS_GOOD);
3645 }
3646 
3647 SANE_Status
sane_read(SANE_Handle handle, SANE_Byte *dst_buf, SANE_Int max_len, SANE_Int * len)3648 sane_read (SANE_Handle handle, SANE_Byte *dst_buf, SANE_Int max_len,
3649 	   SANE_Int * len)
3650 {
3651   NEC_Scanner *s = handle;
3652   SANE_Status status;
3653 
3654   DBG (10, "<< sane_read ");
3655   s->busy = SANE_TRUE;
3656   if (s->cancel == SANE_TRUE)
3657     {
3658       do_cancel(s);
3659       *len = 0;
3660       return (SANE_STATUS_CANCELLED);
3661     }
3662 
3663   if (s->image_composition <= 2)
3664     status = sane_read_direct(handle, dst_buf, max_len, len);
3665   else if (s->image_composition <= 4)
3666     status = sane_read_shuffled(handle, dst_buf, max_len, len, 0);
3667   else if (s->dev->sensedat.model == PCIN500)
3668     status = sane_read_direct(handle, dst_buf, max_len, len);
3669   else
3670     status = sane_read_shuffled(handle, dst_buf, max_len, len, 1);
3671 
3672   s->busy = SANE_FALSE;
3673   if (s->cancel == SANE_TRUE)
3674     {
3675       do_cancel(s);
3676       return (SANE_STATUS_CANCELLED);
3677     }
3678 
3679   DBG (10, ">> \n");
3680   return (status);
3681 }
3682 
3683 void
sane_cancel(SANE_Handle handle)3684 sane_cancel (SANE_Handle handle)
3685 {
3686   NEC_Scanner *s = handle;
3687   DBG (10, "<< sane_cancel ");
3688 
3689   s->cancel = SANE_TRUE;
3690   if (s->busy == SANE_FALSE)
3691       do_cancel(s);
3692 
3693   DBG (10, ">>\n");
3694 }
3695 
3696 SANE_Status
sane_set_io_mode(SANE_Handle handle, SANE_Bool non_blocking)3697 sane_set_io_mode (SANE_Handle handle, SANE_Bool non_blocking)
3698 {
3699   (void) handle;
3700   (void) non_blocking; /* silence compilation warnings */
3701 
3702   DBG (10, "<< sane_set_io_mode");
3703   DBG (10, ">>\n");
3704 
3705   return SANE_STATUS_UNSUPPORTED;
3706 }
3707 
3708 SANE_Status
sane_get_select_fd(SANE_Handle handle, SANE_Int * fd)3709 sane_get_select_fd (SANE_Handle handle, SANE_Int * fd)
3710 {
3711   (void) handle;
3712   (void) fd; /* silence compilation warnings */
3713 
3714   DBG (10, "<< sane_get_select_fd");
3715   DBG (10, ">>\n");
3716 
3717   return SANE_STATUS_UNSUPPORTED;
3718 }
3719