1 /* sane - Scanner Access Now Easy.
2 
3    Copyright (C) 1998 David Huggins-Daines, heavily based on the Apple
4    scanner driver (since Abaton scanners are very similar to old Apple
5    scanners), which is (C) 1998 Milon Firikis, which is, in turn, based
6    on the Mustek driver, (C) 1996-7 David Mosberger-Tang.
7 
8    This file is part of the SANE package.
9 
10    This program is free software; you can redistribute it and/or
11    modify it under the terms of the GNU General Public License as
12    published by the Free Software Foundation; either version 2 of the
13    License, or (at your option) any later version.
14 
15    This program is distributed in the hope that it will be useful, but
16    WITHOUT ANY WARRANTY; without even the implied warranty of
17    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
18    General Public License for more details.
19 
20    You should have received a copy of the GNU General Public License
21    along with this program.  If not, see <https://www.gnu.org/licenses/>.
22 
23    As a special exception, the authors of SANE give permission for
24    additional uses of the libraries contained in this release of SANE.
25 
26    The exception is that, if you link a SANE library with other files
27    to produce an executable, this does not by itself cause the
28    resulting executable to be covered by the GNU General Public
29    License.  Your use of that executable is in no way restricted on
30    account of linking the SANE library code into it.
31 
32    This exception does not, however, invalidate any other reasons why
33    the executable file might be covered by the GNU General Public
34    License.
35 
36    If you submit changes to SANE to the maintainers to be included in
37    a subsequent release, you agree by submitting the changes that
38    those changes may be distributed with this exception intact.
39 
40    If you write modifications of your own for SANE, it is your choice
41    whether to permit this exception to apply to your modifications.
42    If you do not wish that, delete this exception notice.
43 
44    This file implements a SANE backend for Abaton flatbed scanners.  */
45 
46 #include "../include/sane/config.h"
47 
48 #include <ctype.h>
49 #include <errno.h>
50 #include <fcntl.h>
51 #include <limits.h>
52 #include <signal.h>
53 #include <stdio.h>
54 #include <stdlib.h>
55 #include <string.h>
56 #include <unistd.h>
57 
58 #include <sys/time.h>
59 #include <sys/types.h>
60 #include <sys/wait.h>
61 
62 #include "../include/_stdint.h"
63 
64 #include "../include/sane/sane.h"
65 #include "../include/sane/sanei.h"
66 #include "../include/sane/saneopts.h"
67 #include "../include/sane/sanei_scsi.h"
68 
69 #define BACKEND_NAME	abaton
70 #include "../include/sane/sanei_backend.h"
71 
72 #ifndef PATH_MAX
73 # define PATH_MAX	1024
74 #endif
75 
76 #include "../include/sane/sanei_config.h"
77 #define ABATON_CONFIG_FILE "abaton.conf"
78 
79 #include "abaton.h"
80 
81 
82 
83 static const SANE_Device **devlist = 0;
84 static int num_devices;
85 static Abaton_Device *first_dev;
86 static Abaton_Scanner *first_handle;
87 
88 static SANE_String_Const mode_list[5];
89 
90 static const SANE_String_Const halftone_pattern_list[] =
91 {
92   "spiral", "bayer",
93   0
94 };
95 
96 static const SANE_Range dpi_range =
97 {
98   /* min, max, quant */
99   72,
100   300,
101   1
102 };
103 
104 static const SANE_Range enhance_range =
105 {
106   1,
107   255,
108   1
109 };
110 
111 static const SANE_Range x_range =
112 {
113   0,
114   8.5 * MM_PER_INCH,
115   1
116 };
117 
118 static const SANE_Range y_range =
119 {
120   0,
121   14.0 * MM_PER_INCH,
122   1
123 };
124 
125 #define ERROR_MESSAGE	1
126 #define USER_MESSAGE	5
127 #define FLOW_CONTROL	50
128 #define VARIABLE_CONTROL 70
129 #define DEBUG_SPECIAL	100
130 #define IO_MESSAGE	110
131 #define INNER_LOOP	120
132 
133 
134 /* SCSI commands that the Abaton scanners understand: */
135 #define TEST_UNIT_READY	0x00
136 #define REQUEST_SENSE	0x03
137 #define INQUIRY		0x12
138 #define START_STOP	0x1b
139 #define SET_WINDOW	0x24
140 #define READ_10		0x28
141 #define WRITE_10	0x2b	/* not used, AFAIK */
142 #define GET_DATA_STATUS	0x34
143 
144 
145 #define INQ_LEN	0x60
146 static const uint8_t inquiry[] =
147 {
148   INQUIRY, 0x00, 0x00, 0x00, INQ_LEN, 0x00
149 };
150 
151 static const uint8_t test_unit_ready[] =
152 {
153   TEST_UNIT_READY, 0x00, 0x00, 0x00, 0x00, 0x00
154 };
155 
156 /* convenience macros */
157 #define ENABLE(OPTION)  s->opt[OPTION].cap &= ~SANE_CAP_INACTIVE
158 #define DISABLE(OPTION) s->opt[OPTION].cap |=  SANE_CAP_INACTIVE
159 #define IS_ACTIVE(OPTION) (((s->opt[OPTION].cap) & SANE_CAP_INACTIVE) == 0)
160 
161 /* store an 8-bit-wide value at the location specified by ptr */
162 #define STORE8(ptr, val) (*((uint8_t *) ptr) = val)
163 
164 /* store a 16-bit-wide value in network (big-endian) byte order */
165 #define STORE16(ptr, val)			\
166   {						\
167   *((uint8_t *) ptr)     = (val >> 8) & 0xff;	\
168   *((uint8_t *) ptr+1)   = val & 0xff;		\
169   }
170 
171 /* store a 24-bit-wide value in network (big-endian) byte order */
172 #define STORE24(ptr, val)			\
173   {						\
174   *((uint8_t *) ptr)     = (val >> 16) & 0xff;	\
175   *((uint8_t *) ptr+1)   = (val >> 8) & 0xff;	\
176   *((uint8_t *) ptr+2)   = val & 0xff;		\
177   }
178 
179 /* store a 32-bit-wide value in network (big-endian) byte order */
180 #define STORE32(ptr, val)			\
181   {						\
182   *((uint8_t *) ptr)     = (val >> 24) & 0xff;	\
183   *((uint8_t *) ptr+1)   = (val >> 16) & 0xff;	\
184   *((uint8_t *) ptr+2)   = (val >> 8) & 0xff;	\
185   *((uint8_t *) ptr+3)   = val & 0xff;		\
186   }
187 
188 /* retrieve a 24-bit-wide big-endian value at ptr */
189 #define GET24(ptr) \
190   (*((uint8_t *) ptr) << 16)  + \
191   (*((uint8_t *) ptr+1) << 8) + \
192   (*((uint8_t *) ptr+2))
193 
194 static SANE_Status
wait_ready(int fd)195 wait_ready (int fd)
196 {
197 #define MAX_WAITING_TIME	60	/* one minute, at most */
198   struct timeval now, start;
199   SANE_Status status;
200 
201   gettimeofday (&start, 0);
202 
203   while (1)
204     {
205       DBG (USER_MESSAGE, "wait_ready: sending TEST_UNIT_READY\n");
206 
207       status = sanei_scsi_cmd (fd, test_unit_ready, sizeof (test_unit_ready),
208 			       0, 0);
209       switch (status)
210 	{
211 	default:
212 	  /* Ignore errors while waiting for scanner to become ready.
213 	     Some SCSI drivers return EIO while the scanner is
214 	     returning to the home position.  */
215 	  DBG (ERROR_MESSAGE, "wait_ready: test unit ready failed (%s)\n",
216 	       sane_strstatus (status));
217 	  /* fall through */
218 	case SANE_STATUS_DEVICE_BUSY:
219 	  gettimeofday (&now, 0);
220 	  if (now.tv_sec - start.tv_sec >= MAX_WAITING_TIME)
221 	    {
222 	      DBG (ERROR_MESSAGE, "wait_ready: timed out after %ld seconds\n",
223 		   (long) (now.tv_sec - start.tv_sec));
224 	      return SANE_STATUS_INVAL;
225 	    }
226 	  usleep (100000);	/* retry after 100ms */
227 	  break;
228 
229 	case SANE_STATUS_GOOD:
230 	  return status;
231 	}
232     }
233   return SANE_STATUS_INVAL;
234 }
235 
236 static SANE_Status
sense_handler(int scsi_fd,u_char * result,void * arg)237 sense_handler (int scsi_fd, u_char * result, void *arg)
238 {
239   scsi_fd = scsi_fd;			/* silence gcc */
240   arg = arg;					/* silence gcc */
241 
242   switch (result[2] & 0x0F)
243     {
244     case 0:
245       DBG (USER_MESSAGE, "Sense: No sense Error\n");
246       return SANE_STATUS_GOOD;
247     case 2:
248       DBG (ERROR_MESSAGE, "Sense: Scanner not ready\n");
249       return SANE_STATUS_DEVICE_BUSY;
250     case 4:
251       DBG (ERROR_MESSAGE, "Sense: Hardware Error. Read more...\n");
252       return SANE_STATUS_IO_ERROR;
253     case 5:
254       DBG (ERROR_MESSAGE, "Sense: Illegal request\n");
255       return SANE_STATUS_UNSUPPORTED;
256     case 6:
257       DBG (ERROR_MESSAGE, "Sense: Unit Attention (Wait until scanner "
258 	   "boots)\n");
259       return SANE_STATUS_DEVICE_BUSY;
260     case 9:
261       DBG (ERROR_MESSAGE, "Sense: Vendor Unique. Read more...\n");
262       return SANE_STATUS_IO_ERROR;
263     default:
264       DBG (ERROR_MESSAGE, "Sense: Unknown Sense Key. Read more...\n");
265       return SANE_STATUS_IO_ERROR;
266     }
267 
268   return SANE_STATUS_GOOD;
269 }
270 
271 static SANE_Status
request_sense(Abaton_Scanner * s)272 request_sense (Abaton_Scanner * s)
273 {
274   uint8_t cmd[6];
275   uint8_t result[22];
276   size_t size = sizeof (result);
277   SANE_Status status;
278 
279   memset (cmd, 0, sizeof (cmd));
280   memset (result, 0, sizeof (result));
281 
282   cmd[0] = REQUEST_SENSE;
283   STORE8 (cmd + 4, sizeof (result));
284   sanei_scsi_cmd (s->fd, cmd, sizeof (cmd), result, &size);
285 
286   if (result[7] != 14)
287     {
288       DBG (ERROR_MESSAGE, "Additional Length %u\n", (unsigned int) result[7]);
289       status = SANE_STATUS_IO_ERROR;
290     }
291 
292 
293   status = sense_handler (s->fd, result, NULL);
294   if (status == SANE_STATUS_IO_ERROR)
295     {
296 
297       /* Since I haven't figured out the vendor unique error codes on
298 	 this thing, I'll just handle the normal ones for now */
299 
300       if (result[18] & 0x80)
301 	DBG (ERROR_MESSAGE, "Sense: Dim Light (output of lamp below 70%%).\n");
302 
303       if (result[18] & 0x40)
304 	DBG (ERROR_MESSAGE, "Sense: No Light at all.\n");
305 
306       if (result[18] & 0x20)
307 	DBG (ERROR_MESSAGE, "Sense: No Home.\n");
308 
309       if (result[18] & 0x10)
310 	DBG (ERROR_MESSAGE, "Sense: No Limit. Tried to scan out of range.\n");
311     }
312 
313   DBG (USER_MESSAGE, "Sense: Optical gain %u.\n", (unsigned int) result[20]);
314   return status;
315 }
316 
317 static SANE_Status
set_window(Abaton_Scanner * s)318 set_window (Abaton_Scanner * s)
319 {
320   uint8_t cmd[10 + 40];
321   uint8_t *window = cmd + 10 + 8;
322   int invert;
323 
324   memset (cmd, 0, sizeof (cmd));
325   cmd[0] = SET_WINDOW;
326   cmd[8] = 40;
327 
328   /* Just like the Apple scanners, we put the resolution here */
329   STORE16 (window + 2, s->val[OPT_X_RESOLUTION].w);
330   STORE16 (window + 4, s->val[OPT_Y_RESOLUTION].w);
331 
332   /* Unlike Apple scanners, these are pixel values */
333   STORE16 (window + 6, s->ULx);
334   STORE16 (window + 8, s->ULy);
335   STORE16 (window + 10, s->Width);
336   STORE16 (window + 12, s->Height);
337 
338   STORE8 (window + 14, s->val[OPT_BRIGHTNESS].w);
339   STORE8 (window + 15, s->val[OPT_THRESHOLD].w);
340   STORE8 (window + 16, s->val[OPT_CONTRAST].w);
341 
342   invert = s->val[OPT_NEGATIVE].w;
343 
344   if (!strcmp (s->val[OPT_MODE].s, SANE_VALUE_SCAN_MODE_LINEART))
345     {
346       STORE8 (window + 17, 0);
347     }
348   else if (!strcmp (s->val[OPT_MODE].s, SANE_VALUE_SCAN_MODE_HALFTONE))
349     {
350       STORE8 (window + 17, 1);
351     }
352   else if (!strcmp (s->val[OPT_MODE].s, "Gray256")
353 	   || !strcmp (s->val[OPT_MODE].s, "Gray16"))
354     {
355       STORE8 (window + 17, 2);
356       invert = !s->val[OPT_NEGATIVE].w;
357     }
358   else
359     {
360       DBG (ERROR_MESSAGE, "Can't match mode %s\n", s->val[OPT_MODE].s);
361       return SANE_STATUS_INVAL;
362     }
363 
364   STORE8 (window + 18, s->bpp);
365 
366   if (!strcmp (s->val[OPT_HALFTONE_PATTERN].s, "spiral"))
367     {
368       STORE8 (window + 20, 0);
369     }
370   else if (!strcmp (s->val[OPT_HALFTONE_PATTERN].s, "bayer"))
371     {
372       STORE8 (window + 20, 1);
373     }
374   else
375     {
376       DBG (ERROR_MESSAGE, "Can't match haftone pattern %s\n",
377 	   s->val[OPT_HALFTONE_PATTERN].s);
378       return SANE_STATUS_INVAL;
379     }
380 
381   /* We have to invert these ones for some reason, so why not
382      let the scanner do it for us... */
383   STORE8 (window + 21, invert ? 0x80 : 0);
384 
385   STORE16 (window + 22, (s->val[OPT_MIRROR].w != 0));
386 
387   return sanei_scsi_cmd (s->fd, cmd, sizeof (cmd), 0, 0);
388 }
389 
390 static SANE_Status
start_scan(Abaton_Scanner * s)391 start_scan (Abaton_Scanner * s)
392 {
393   SANE_Status status;
394   uint8_t start[7];
395 
396 
397   memset (start, 0, sizeof (start));
398   start[0] = START_STOP;
399   start[4] = 1;
400 
401   status = sanei_scsi_cmd (s->fd, start, sizeof (start), 0, 0);
402   return status;
403 }
404 
405 static SANE_Status
attach(const char * devname,Abaton_Device ** devp,int may_wait)406 attach (const char *devname, Abaton_Device ** devp, int may_wait)
407 {
408   char result[INQ_LEN];
409   const char *model_name = result + 44;
410   int fd, abaton_scanner;
411   Abaton_Device *dev;
412   SANE_Status status;
413   size_t size;
414 
415   for (dev = first_dev; dev; dev = dev->next)
416     if (strcmp (dev->sane.name, devname) == 0)
417       {
418 	if (devp)
419 	  *devp = dev;
420 	return SANE_STATUS_GOOD;
421       }
422 
423   DBG (USER_MESSAGE, "attach: opening %s\n", devname);
424   status = sanei_scsi_open (devname, &fd, sense_handler, 0);
425   if (status != SANE_STATUS_GOOD)
426     {
427       DBG (ERROR_MESSAGE, "attach: open failed (%s)\n",
428 	   sane_strstatus (status));
429       return SANE_STATUS_INVAL;
430     }
431 
432   if (may_wait)
433     wait_ready (fd);
434 
435   DBG (USER_MESSAGE, "attach: sending INQUIRY\n");
436   size = sizeof (result);
437   status = sanei_scsi_cmd (fd, inquiry, sizeof (inquiry), result, &size);
438   if (status != SANE_STATUS_GOOD)
439     {
440       DBG (ERROR_MESSAGE, "attach: inquiry failed (%s)\n",
441 	   sane_strstatus (status));
442       sanei_scsi_close (fd);
443       return status;
444     }
445 
446   status = wait_ready (fd);
447   sanei_scsi_close (fd);
448   if (status != SANE_STATUS_GOOD)
449     return status;
450 
451   /* check that we've got an Abaton */
452   abaton_scanner = (strncmp (result + 8, "ABATON  ", 8) == 0);
453   model_name = result + 16;
454 
455   /* make sure it's a scanner ;-) */
456   abaton_scanner = abaton_scanner && (result[0] == 0x06);
457 
458   if (!abaton_scanner)
459     {
460       DBG (ERROR_MESSAGE, "attach: device doesn't look like an Abaton scanner "
461 	   "(result[0]=%#02x)\n", result[0]);
462       return SANE_STATUS_INVAL;
463     }
464 
465   dev = malloc (sizeof (*dev));
466   if (!dev)
467     return SANE_STATUS_NO_MEM;
468 
469   memset (dev, 0, sizeof (*dev));
470 
471   dev->sane.name = strdup (devname);
472   dev->sane.vendor = "Abaton";
473   dev->sane.model = strndup (model_name, 16);
474   dev->sane.type = "flatbed scanner";
475 
476   if (!strncmp (model_name, "SCAN 300/GS", 11))
477     {
478       dev->ScannerModel = ABATON_300GS;
479     }
480   else if (!strncmp (model_name, "SCAN 300/S", 10))
481     {
482       dev->ScannerModel = ABATON_300S;
483     }
484 
485   DBG (USER_MESSAGE, "attach: found Abaton scanner model %s (%s)\n",
486        dev->sane.model, dev->sane.type);
487 
488   ++num_devices;
489   dev->next = first_dev;
490   first_dev = dev;
491 
492   if (devp)
493     *devp = dev;
494 
495   return SANE_STATUS_GOOD;
496 }
497 
498 static SANE_Status
attach_one(const char * devname)499 attach_one (const char *devname)
500 {
501   return attach (devname, 0, SANE_FALSE);
502 }
503 
504 static SANE_Status
calc_parameters(Abaton_Scanner * s)505 calc_parameters (Abaton_Scanner * s)
506 {
507   SANE_String val = s->val[OPT_MODE].s;
508   SANE_Status status = SANE_STATUS_GOOD;
509   SANE_Int dpix = s->val[OPT_X_RESOLUTION].w;
510   SANE_Int dpiy = s->val[OPT_Y_RESOLUTION].w;
511   double ulx, uly, width, height;
512 
513   DBG (FLOW_CONTROL, "Entering calc_parameters\n");
514 
515   if (!strcmp (val, SANE_VALUE_SCAN_MODE_LINEART) || !strcmp (val, SANE_VALUE_SCAN_MODE_HALFTONE))
516     {
517       s->params.depth = 1;
518       s->bpp = 1;
519     }
520   else if (!strcmp (val, "Gray16"))
521     {
522       s->params.depth = 8;
523       s->bpp = 4;
524     }
525   else if (!strcmp (val, "Gray256"))
526     {
527       s->params.depth = 8;
528       s->bpp = 8;
529     }
530   else
531     {
532       DBG (ERROR_MESSAGE, "calc_parameters: Invalid mode %s\n", (char *) val);
533       status = SANE_STATUS_INVAL;
534     }
535 
536   /* in inches */
537   ulx    = (double) s->val[OPT_TL_X].w / MM_PER_INCH;
538   uly    = (double) s->val[OPT_TL_Y].w / MM_PER_INCH;
539   width  = (double) s->val[OPT_BR_X].w / MM_PER_INCH - ulx;
540   height = (double) s->val[OPT_BR_Y].w / MM_PER_INCH - uly;
541 
542   DBG (VARIABLE_CONTROL, "(inches) ulx: %f, uly: %f, width: %f, height: %f\n",
543        ulx, uly, width, height);
544 
545   /* turn 'em into pixel quantities */
546   s->ULx    = ulx    * dpix;
547   s->ULy    = uly    * dpiy;
548   s->Width  = width  * dpix;
549   s->Height = height * dpiy;
550 
551   DBG (VARIABLE_CONTROL, "(pixels) ulx: %d, uly: %d, width: %d, height: %d\n",
552        s->ULx, s->ULy, s->Width, s->Height);
553 
554   /* floor width to a byte multiple */
555   if ((s->Width * s->bpp) % 8)
556     {
557       s->Width /= 8;
558       s->Width *= 8;
559       DBG (VARIABLE_CONTROL, "Adapting to width %d\n", s->Width);
560     }
561 
562   s->params.pixels_per_line = s->Width;
563   s->params.lines = s->Height;
564   s->params.bytes_per_line = s->params.pixels_per_line * s->params.depth / 8;
565 
566 
567   DBG (VARIABLE_CONTROL, "format=%d\n", s->params.format);
568   DBG (VARIABLE_CONTROL, "last_frame=%d\n", s->params.last_frame);
569   DBG (VARIABLE_CONTROL, "lines=%d\n", s->params.lines);
570   DBG (VARIABLE_CONTROL, "depth=%d (%d)\n", s->params.depth, s->bpp);
571   DBG (VARIABLE_CONTROL, "pixels_per_line=%d\n", s->params.pixels_per_line);
572   DBG (VARIABLE_CONTROL, "bytes_per_line=%d\n", s->params.bytes_per_line);
573   DBG (VARIABLE_CONTROL, "Pixels %dx%dx%d\n",
574        s->params.pixels_per_line, s->params.lines, 1 << s->params.depth);
575 
576   DBG (FLOW_CONTROL, "Leaving calc_parameters\n");
577   return status;
578 }
579 
580 static SANE_Status
mode_update(SANE_Handle handle,char * val)581 mode_update (SANE_Handle handle, char *val)
582 {
583   Abaton_Scanner *s = handle;
584 
585   if (!strcmp (val, SANE_VALUE_SCAN_MODE_LINEART))
586     {
587       DISABLE (OPT_BRIGHTNESS);
588       DISABLE (OPT_CONTRAST);
589       ENABLE (OPT_THRESHOLD);
590       DISABLE (OPT_HALFTONE_PATTERN);
591     }
592   else if (!strcmp (val, SANE_VALUE_SCAN_MODE_HALFTONE))
593     {
594       ENABLE (OPT_BRIGHTNESS);
595       ENABLE (OPT_CONTRAST);
596       DISABLE (OPT_THRESHOLD);
597       ENABLE (OPT_HALFTONE_PATTERN);
598     }
599   else if (!strcmp (val, "Gray16") || !strcmp (val, "Gray256"))
600     {
601       ENABLE (OPT_BRIGHTNESS);
602       ENABLE (OPT_CONTRAST);
603       DISABLE (OPT_THRESHOLD);
604       DISABLE (OPT_HALFTONE_PATTERN);
605     }				/* End of Gray */
606   else
607     {
608       DBG (ERROR_MESSAGE, "Invalid mode %s\n", (char *) val);
609       return SANE_STATUS_INVAL;
610     }
611 
612   calc_parameters (s);
613 
614   return SANE_STATUS_GOOD;
615 }
616 
617 /* find the longest of a list of strings */
618 static size_t
max_string_size(const SANE_String_Const strings[])619 max_string_size (const SANE_String_Const strings[])
620 {
621   size_t size, max_size = 0;
622   int i;
623 
624   for (i = 0; strings[i]; ++i)
625     {
626       size = strlen (strings[i]) + 1;
627       if (size > max_size)
628 	max_size = size;
629     }
630 
631   return max_size;
632 }
633 
634 static SANE_Status
init_options(Abaton_Scanner * s)635 init_options (Abaton_Scanner * s)
636 {
637   int i;
638 
639   memset (s->opt, 0, sizeof (s->opt));
640   memset (s->val, 0, sizeof (s->val));
641 
642   for (i = 0; i < NUM_OPTIONS; ++i)
643     {
644       s->opt[i].size = sizeof (SANE_Word);
645       s->opt[i].cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT;
646     }
647 
648   s->opt[OPT_NUM_OPTS].title = SANE_TITLE_NUM_OPTIONS;
649   s->opt[OPT_NUM_OPTS].desc = SANE_DESC_NUM_OPTIONS;
650   s->opt[OPT_NUM_OPTS].type = SANE_TYPE_INT;
651   s->opt[OPT_NUM_OPTS].cap = SANE_CAP_SOFT_DETECT;
652   s->val[OPT_NUM_OPTS].w = NUM_OPTIONS;
653 
654 
655   /* "Mode" group: */
656   s->opt[OPT_MODE_GROUP].title = "Scan Mode";
657   s->opt[OPT_MODE_GROUP].desc = "";
658   s->opt[OPT_MODE_GROUP].type = SANE_TYPE_GROUP;
659   s->opt[OPT_MODE_GROUP].cap = 0;
660   s->opt[OPT_MODE_GROUP].constraint_type = SANE_CONSTRAINT_NONE;
661 
662   mode_list[0]=SANE_VALUE_SCAN_MODE_LINEART;
663 
664   switch (s->hw->ScannerModel)
665     {
666     case ABATON_300GS:
667       mode_list[1]=SANE_VALUE_SCAN_MODE_HALFTONE;
668       mode_list[2]="Gray16";
669       mode_list[3]="Gray256";
670       mode_list[4]=NULL;
671       break;
672     case ABATON_300S:
673     default:
674       mode_list[1]=NULL;
675       break;
676     }
677 
678   /* scan mode */
679   s->opt[OPT_MODE].name = SANE_NAME_SCAN_MODE;
680   s->opt[OPT_MODE].title = SANE_TITLE_SCAN_MODE;
681   s->opt[OPT_MODE].desc = SANE_DESC_SCAN_MODE;
682   s->opt[OPT_MODE].type = SANE_TYPE_STRING;
683   s->opt[OPT_MODE].constraint_type = SANE_CONSTRAINT_STRING_LIST;
684   s->opt[OPT_MODE].size = max_string_size (mode_list);
685   s->opt[OPT_MODE].constraint.string_list = mode_list;
686   s->val[OPT_MODE].s = strdup (mode_list[0]);
687 
688   /* resolution - horizontal */
689   s->opt[OPT_X_RESOLUTION].name = SANE_NAME_SCAN_RESOLUTION;
690   s->opt[OPT_X_RESOLUTION].title = SANE_TITLE_SCAN_X_RESOLUTION;
691   s->opt[OPT_X_RESOLUTION].desc = SANE_DESC_SCAN_X_RESOLUTION;
692   s->opt[OPT_X_RESOLUTION].type = SANE_TYPE_INT;
693   s->opt[OPT_X_RESOLUTION].unit = SANE_UNIT_DPI;
694   s->opt[OPT_X_RESOLUTION].constraint_type = SANE_CONSTRAINT_RANGE;
695   s->opt[OPT_X_RESOLUTION].constraint.range = &dpi_range;
696   s->val[OPT_X_RESOLUTION].w = 150;
697 
698   /* resolution - vertical */
699   s->opt[OPT_Y_RESOLUTION].name = SANE_NAME_SCAN_Y_RESOLUTION;
700   s->opt[OPT_Y_RESOLUTION].title = SANE_TITLE_SCAN_Y_RESOLUTION;
701   s->opt[OPT_Y_RESOLUTION].desc = SANE_DESC_SCAN_Y_RESOLUTION;
702   s->opt[OPT_Y_RESOLUTION].type = SANE_TYPE_INT;
703   s->opt[OPT_Y_RESOLUTION].unit = SANE_UNIT_DPI;
704   s->opt[OPT_Y_RESOLUTION].constraint_type = SANE_CONSTRAINT_RANGE;
705   s->opt[OPT_Y_RESOLUTION].constraint.range = &dpi_range;
706   s->val[OPT_Y_RESOLUTION].w = 150;
707 
708   /* constrain resolutions */
709   s->opt[OPT_RESOLUTION_BIND].name = SANE_NAME_RESOLUTION_BIND;
710   s->opt[OPT_RESOLUTION_BIND].title = SANE_TITLE_RESOLUTION_BIND;
711   s->opt[OPT_RESOLUTION_BIND].desc = SANE_DESC_RESOLUTION_BIND;
712   s->opt[OPT_RESOLUTION_BIND].type = SANE_TYPE_BOOL;
713   s->opt[OPT_RESOLUTION_BIND].unit = SANE_UNIT_NONE;
714   s->opt[OPT_RESOLUTION_BIND].constraint_type = SANE_CONSTRAINT_NONE;
715   /* until I fix it */
716   s->val[OPT_RESOLUTION_BIND].w = SANE_FALSE;
717 
718   /* preview mode */
719   s->opt[OPT_PREVIEW].name = SANE_NAME_PREVIEW;
720   s->opt[OPT_PREVIEW].title = SANE_TITLE_PREVIEW;
721   s->opt[OPT_PREVIEW].desc = SANE_DESC_PREVIEW;
722   s->opt[OPT_PREVIEW].cap = SANE_CAP_SOFT_DETECT | SANE_CAP_SOFT_SELECT;
723   s->opt[OPT_PREVIEW].type = SANE_TYPE_BOOL;
724   s->val[OPT_PREVIEW].w = SANE_FALSE;
725 
726   /* halftone pattern  */
727   s->opt[OPT_HALFTONE_PATTERN].name = SANE_NAME_HALFTONE_PATTERN;
728   s->opt[OPT_HALFTONE_PATTERN].title = SANE_TITLE_HALFTONE_PATTERN;
729   s->opt[OPT_HALFTONE_PATTERN].desc = SANE_DESC_HALFTONE_PATTERN;
730   s->opt[OPT_HALFTONE_PATTERN].size = max_string_size (halftone_pattern_list);
731   s->opt[OPT_HALFTONE_PATTERN].type = SANE_TYPE_STRING;
732   s->opt[OPT_HALFTONE_PATTERN].cap |= SANE_CAP_INACTIVE;
733   s->opt[OPT_HALFTONE_PATTERN].constraint_type = SANE_CONSTRAINT_STRING_LIST;
734   s->opt[OPT_HALFTONE_PATTERN].constraint.string_list = halftone_pattern_list;
735   s->val[OPT_HALFTONE_PATTERN].s = strdup (halftone_pattern_list[0]);
736 
737 
738   /* "Geometry" group: */
739   s->opt[OPT_GEOMETRY_GROUP].title = "Geometry";
740   s->opt[OPT_GEOMETRY_GROUP].desc = "";
741   s->opt[OPT_GEOMETRY_GROUP].type = SANE_TYPE_GROUP;
742   s->opt[OPT_GEOMETRY_GROUP].cap = SANE_CAP_ADVANCED;
743   s->opt[OPT_GEOMETRY_GROUP].constraint_type = SANE_CONSTRAINT_NONE;
744 
745   /* top-left x */
746   s->opt[OPT_TL_X].name = SANE_NAME_SCAN_TL_X;
747   s->opt[OPT_TL_X].title = SANE_TITLE_SCAN_TL_X;
748   s->opt[OPT_TL_X].desc = SANE_DESC_SCAN_TL_X;
749   s->opt[OPT_TL_X].type = SANE_TYPE_INT;
750   s->opt[OPT_TL_X].unit = SANE_UNIT_MM;
751   s->opt[OPT_TL_X].constraint_type = SANE_CONSTRAINT_RANGE;
752   s->opt[OPT_TL_X].constraint.range = &x_range;
753   s->val[OPT_TL_X].w = 0;
754 
755   /* top-left y */
756   s->opt[OPT_TL_Y].name = SANE_NAME_SCAN_TL_Y;
757   s->opt[OPT_TL_Y].title = SANE_TITLE_SCAN_TL_Y;
758   s->opt[OPT_TL_Y].desc = SANE_DESC_SCAN_TL_Y;
759   s->opt[OPT_TL_Y].type = SANE_TYPE_INT;
760   s->opt[OPT_TL_Y].unit = SANE_UNIT_MM;
761   s->opt[OPT_TL_Y].constraint_type = SANE_CONSTRAINT_RANGE;
762   s->opt[OPT_TL_Y].constraint.range = &y_range;
763   s->val[OPT_TL_Y].w = 0;
764 
765   /* bottom-right x */
766   s->opt[OPT_BR_X].name = SANE_NAME_SCAN_BR_X;
767   s->opt[OPT_BR_X].title = SANE_TITLE_SCAN_BR_X;
768   s->opt[OPT_BR_X].desc = SANE_DESC_SCAN_BR_X;
769   s->opt[OPT_BR_X].type = SANE_TYPE_INT;
770   s->opt[OPT_BR_X].unit = SANE_UNIT_MM;
771   s->opt[OPT_BR_X].constraint_type = SANE_CONSTRAINT_RANGE;
772   s->opt[OPT_BR_X].constraint.range = &x_range;
773   s->val[OPT_BR_X].w = x_range.max;
774 
775   /* bottom-right y */
776   s->opt[OPT_BR_Y].name = SANE_NAME_SCAN_BR_Y;
777   s->opt[OPT_BR_Y].title = SANE_TITLE_SCAN_BR_Y;
778   s->opt[OPT_BR_Y].desc = SANE_DESC_SCAN_BR_Y;
779   s->opt[OPT_BR_Y].type = SANE_TYPE_INT;
780   s->opt[OPT_BR_Y].unit = SANE_UNIT_MM;
781   s->opt[OPT_BR_Y].constraint_type = SANE_CONSTRAINT_RANGE;
782   s->opt[OPT_BR_Y].constraint.range = &y_range;
783   s->val[OPT_BR_Y].w = y_range.max;
784 
785 
786   /* "Enhancement" group: */
787   s->opt[OPT_ENHANCEMENT_GROUP].title = "Enhancement";
788   s->opt[OPT_ENHANCEMENT_GROUP].desc = "";
789   s->opt[OPT_ENHANCEMENT_GROUP].type = SANE_TYPE_GROUP;
790   s->opt[OPT_ENHANCEMENT_GROUP].cap = 0;
791   s->opt[OPT_ENHANCEMENT_GROUP].constraint_type = SANE_CONSTRAINT_NONE;
792 
793   /* brightness */
794   s->opt[OPT_BRIGHTNESS].name = SANE_NAME_BRIGHTNESS;
795   s->opt[OPT_BRIGHTNESS].title = SANE_TITLE_BRIGHTNESS;
796   s->opt[OPT_BRIGHTNESS].desc = SANE_DESC_BRIGHTNESS;
797   s->opt[OPT_BRIGHTNESS].type = SANE_TYPE_INT;
798   s->opt[OPT_BRIGHTNESS].unit = SANE_UNIT_NONE;
799   s->opt[OPT_BRIGHTNESS].cap |= SANE_CAP_INACTIVE;
800   s->opt[OPT_BRIGHTNESS].constraint_type = SANE_CONSTRAINT_RANGE;
801   s->opt[OPT_BRIGHTNESS].constraint.range = &enhance_range;
802   s->val[OPT_BRIGHTNESS].w = 150;
803 
804   /* contrast */
805   s->opt[OPT_CONTRAST].name = SANE_NAME_CONTRAST;
806   s->opt[OPT_CONTRAST].title = SANE_TITLE_CONTRAST;
807   s->opt[OPT_CONTRAST].desc = SANE_DESC_CONTRAST;
808   s->opt[OPT_CONTRAST].type = SANE_TYPE_INT;
809   s->opt[OPT_CONTRAST].unit = SANE_UNIT_NONE;
810   s->opt[OPT_CONTRAST].cap |= SANE_CAP_INACTIVE;
811   s->opt[OPT_CONTRAST].constraint_type = SANE_CONSTRAINT_RANGE;
812   s->opt[OPT_CONTRAST].constraint.range = &enhance_range;
813   s->val[OPT_CONTRAST].w = 150;
814 
815   /* threshold */
816   s->opt[OPT_THRESHOLD].name = SANE_NAME_THRESHOLD;
817   s->opt[OPT_THRESHOLD].title = SANE_TITLE_THRESHOLD;
818   s->opt[OPT_THRESHOLD].desc = SANE_DESC_THRESHOLD;
819   s->opt[OPT_THRESHOLD].type = SANE_TYPE_INT;
820   s->opt[OPT_THRESHOLD].unit = SANE_UNIT_NONE;
821   s->opt[OPT_THRESHOLD].constraint_type = SANE_CONSTRAINT_RANGE;
822   s->opt[OPT_THRESHOLD].constraint.range = &enhance_range;
823   s->val[OPT_THRESHOLD].w = 150;
824 
825   /* negative */
826   s->opt[OPT_NEGATIVE].name = SANE_NAME_NEGATIVE;
827   s->opt[OPT_NEGATIVE].title = SANE_TITLE_NEGATIVE;
828   s->opt[OPT_NEGATIVE].desc = SANE_DESC_NEGATIVE;
829   s->opt[OPT_NEGATIVE].type = SANE_TYPE_BOOL;
830   s->opt[OPT_NEGATIVE].unit = SANE_UNIT_NONE;
831   s->opt[OPT_NEGATIVE].constraint_type = SANE_CONSTRAINT_NONE;
832   s->val[OPT_NEGATIVE].w = SANE_FALSE;
833 
834   /* mirror-image */
835   s->opt[OPT_MIRROR].name = "mirror";
836   s->opt[OPT_MIRROR].title = "Mirror Image";
837   s->opt[OPT_MIRROR].desc = "Scan in mirror-image";
838   s->opt[OPT_MIRROR].type = SANE_TYPE_BOOL;
839   s->opt[OPT_MIRROR].unit = SANE_UNIT_NONE;
840   s->opt[OPT_MIRROR].constraint_type = SANE_CONSTRAINT_NONE;
841   s->val[OPT_MIRROR].w = SANE_FALSE;
842 
843   return SANE_STATUS_GOOD;
844 }
845 
846 SANE_Status
sane_init(SANE_Int * version_code,SANE_Auth_Callback authorize)847 sane_init (SANE_Int * version_code, SANE_Auth_Callback authorize)
848 {
849   char dev_name[PATH_MAX];
850   size_t len;
851   FILE *fp;
852 
853   authorize = authorize;		/* silence gcc */
854 
855   DBG_INIT ();
856 
857   if (version_code)
858     *version_code = SANE_VERSION_CODE (SANE_CURRENT_MAJOR, V_MINOR, 0);
859 
860   fp = sanei_config_open (ABATON_CONFIG_FILE);
861   if (!fp)
862     {
863       /* default to /dev/scanner instead of insisting on config file */
864       attach ("/dev/scanner", 0, SANE_FALSE);
865       return SANE_STATUS_GOOD;
866     }
867 
868   while (sanei_config_read (dev_name, sizeof (dev_name), fp))
869     {
870       if (dev_name[0] == '#')	/* ignore line comments */
871 	continue;
872 
873       len = strlen (dev_name);
874 
875       if (!len)
876 	continue;		/* ignore empty lines */
877 
878       if (strncmp (dev_name, "option", 6) == 0
879 	  && isspace (dev_name[6]))
880 	{
881 	  const char *str = dev_name + 7;
882 
883 	  while (isspace (*str))
884 	    ++str;
885 
886 	  continue;
887 	}
888 
889       sanei_config_attach_matching_devices (dev_name, attach_one);
890     }
891   fclose (fp);
892   return SANE_STATUS_GOOD;
893 }
894 
895 void
sane_exit(void)896 sane_exit (void)
897 {
898   Abaton_Device *dev, *next;
899 
900   for (dev = first_dev; dev; dev = next)
901     {
902       next = dev->next;
903       free ((void *) dev->sane.name);
904       free ((void *) dev->sane.model);
905       free (dev);
906     }
907 
908   if (devlist)
909     free (devlist);
910 }
911 
912 SANE_Status
sane_get_devices(const SANE_Device *** device_list,SANE_Bool local_only)913 sane_get_devices (const SANE_Device *** device_list, SANE_Bool local_only)
914 {
915   Abaton_Device *dev;
916   int i;
917 
918   local_only = local_only;		/* silence gcc */
919 
920   if (devlist)
921     free (devlist);
922 
923   devlist = malloc ((num_devices + 1) * sizeof (devlist[0]));
924   if (!devlist)
925     return SANE_STATUS_NO_MEM;
926 
927   i = 0;
928   for (dev = first_dev; i < num_devices; dev = dev->next)
929     devlist[i++] = &dev->sane;
930   devlist[i++] = 0;
931 
932   *device_list = devlist;
933   return SANE_STATUS_GOOD;
934 }
935 
936 SANE_Status
sane_open(SANE_String_Const devicename,SANE_Handle * handle)937 sane_open (SANE_String_Const devicename, SANE_Handle * handle)
938 {
939   Abaton_Device *dev;
940   SANE_Status status;
941   Abaton_Scanner *s;
942 
943   if (devicename[0])
944     {
945       for (dev = first_dev; dev; dev = dev->next)
946 	if (strcmp (dev->sane.name, devicename) == 0)
947 	  break;
948 
949       if (!dev)
950 	{
951 	  status = attach (devicename, &dev, SANE_TRUE);
952 	  if (status != SANE_STATUS_GOOD)
953 	    return status;
954 	}
955     }
956   else
957     /* empty devicname -> use first device */
958     dev = first_dev;
959 
960   if (!dev)
961     return SANE_STATUS_INVAL;
962 
963   s = malloc (sizeof (*s));
964   if (!s)
965     return SANE_STATUS_NO_MEM;
966   memset (s, 0, sizeof (*s));
967   s->fd = -1;
968   s->hw = dev;
969 
970   init_options (s);
971 
972   /* set up some universal parameters */
973   s->params.last_frame = SANE_TRUE;
974   s->params.format = SANE_FRAME_GRAY;
975 
976   /* insert newly opened handle into list of open handles: */
977   s->next = first_handle;
978   first_handle = s;
979 
980   *handle = s;
981   return SANE_STATUS_GOOD;
982 }
983 
984 void
sane_close(SANE_Handle handle)985 sane_close (SANE_Handle handle)
986 {
987   Abaton_Scanner *prev, *s;
988 
989   /* remove handle from list of open handles: */
990   prev = 0;
991   for (s = first_handle; s; s = s->next)
992     {
993       if (s == (Abaton_Scanner *) handle)
994 	break;
995       prev = s;
996     }
997   if (!s)
998     {
999       DBG (ERROR_MESSAGE, "close: invalid handle %p\n", handle);
1000       return;			/* oops, not a handle we know about */
1001     }
1002 
1003   if (prev)
1004     prev->next = s->next;
1005   else
1006     first_handle = s->next;
1007 
1008   free (handle);
1009 }
1010 
1011 const SANE_Option_Descriptor *
sane_get_option_descriptor(SANE_Handle handle,SANE_Int option)1012 sane_get_option_descriptor (SANE_Handle handle, SANE_Int option)
1013 {
1014   Abaton_Scanner *s = handle;
1015 
1016   if ((unsigned) option >= NUM_OPTIONS)
1017     return NULL;
1018 
1019   return s->opt + option;
1020 }
1021 
1022 SANE_Status
sane_control_option(SANE_Handle handle,SANE_Int option,SANE_Action action,void * val,SANE_Int * info)1023 sane_control_option (SANE_Handle handle, SANE_Int option,
1024 		     SANE_Action action, void *val, SANE_Int * info)
1025 {
1026   Abaton_Scanner *s = handle;
1027   SANE_Status status;
1028   SANE_Word cap;
1029 
1030 
1031   if (option < 0 || option >= NUM_OPTIONS)
1032     return SANE_STATUS_INVAL;
1033 
1034   if (info != NULL)
1035     *info = 0;
1036 
1037   if (s->scanning)
1038     return SANE_STATUS_DEVICE_BUSY;
1039 
1040   cap = s->opt[option].cap;
1041 
1042   if (!SANE_OPTION_IS_ACTIVE (cap))
1043     return SANE_STATUS_INVAL;
1044 
1045   if (action == SANE_ACTION_GET_VALUE)
1046     {
1047       switch (option)
1048 	{
1049 	  /* word options: */
1050 	case OPT_NUM_OPTS:
1051 	case OPT_X_RESOLUTION:
1052 	case OPT_Y_RESOLUTION:
1053 	case OPT_RESOLUTION_BIND:
1054 	case OPT_PREVIEW:
1055 	case OPT_TL_X:
1056 	case OPT_TL_Y:
1057 	case OPT_BR_X:
1058 	case OPT_BR_Y:
1059 	case OPT_BRIGHTNESS:
1060 	case OPT_CONTRAST:
1061 	case OPT_THRESHOLD:
1062 	case OPT_NEGATIVE:
1063 	case OPT_MIRROR:
1064 	  *(SANE_Word *) val = s->val[option].w;
1065 	  return SANE_STATUS_GOOD;
1066 
1067 	  /* string options */
1068 
1069 	case OPT_MODE:
1070 	case OPT_HALFTONE_PATTERN:
1071 	  status = sanei_constrain_value (s->opt + option, s->val[option].s,
1072 					  info);
1073 	  strcpy (val, s->val[option].s);
1074 	  return SANE_STATUS_GOOD;
1075 	}
1076     }
1077   else if (action == SANE_ACTION_SET_VALUE)
1078     {
1079       if (!SANE_OPTION_IS_SETTABLE (cap))
1080 	return SANE_STATUS_INVAL;
1081 
1082       status = sanei_constrain_value (s->opt + option, val, info);
1083 
1084       if (status != SANE_STATUS_GOOD)
1085 	return status;
1086 
1087 
1088       switch (option)
1089 	{
1090 	  /* resolution should be uniform for previews, or when the
1091 	     user says so. */
1092 	case OPT_PREVIEW:
1093 	  s->val[option].w = *(SANE_Word *) val;
1094 	  if (*(SANE_Word *) val) {
1095 	    s->val[OPT_Y_RESOLUTION].w = s->val[OPT_X_RESOLUTION].w;
1096 	    if (info)
1097 	      *info |= SANE_INFO_RELOAD_OPTIONS;
1098 	  }
1099 	  /* always recalculate! */
1100 	  calc_parameters (s);
1101 	  if (info)
1102 	    *info |= SANE_INFO_RELOAD_PARAMS;
1103 	  return SANE_STATUS_GOOD;
1104 
1105 	case OPT_RESOLUTION_BIND:
1106 	  s->val[option].w = *(SANE_Word *) val;
1107 	  if (*(SANE_Word *) val) {
1108 	    s->val[OPT_Y_RESOLUTION].w = s->val[OPT_X_RESOLUTION].w;
1109 	    calc_parameters (s);
1110 	    if (info)
1111 	      *info |= SANE_INFO_RELOAD_PARAMS |
1112 		SANE_INFO_RELOAD_OPTIONS;
1113 	  }
1114 	  return SANE_STATUS_GOOD;
1115 
1116 	case OPT_X_RESOLUTION:
1117 	  if (s->val[OPT_PREVIEW].w || s->val[OPT_RESOLUTION_BIND].w) {
1118 	    s->val[OPT_Y_RESOLUTION].w = *(SANE_Word *)val;
1119 	    if (info)
1120 	      *info |= SANE_INFO_RELOAD_OPTIONS;
1121 	  }
1122 	  s->val[option].w = *(SANE_Word *) val;
1123 	  calc_parameters (s);
1124 	  if (info)
1125 	    *info |= SANE_INFO_RELOAD_PARAMS;
1126 	  return SANE_STATUS_GOOD;
1127 
1128 	case OPT_Y_RESOLUTION:
1129 	  if (s->val[OPT_PREVIEW].w || s->val[OPT_RESOLUTION_BIND].w) {
1130 	    s->val[OPT_X_RESOLUTION].w = *(SANE_Word *)val;
1131 	    if (info)
1132 	      *info |= SANE_INFO_RELOAD_OPTIONS;
1133 	  }
1134 	  s->val[option].w = *(SANE_Word *) val;
1135 	  calc_parameters (s);
1136 	  if (info)
1137 	    *info |= SANE_INFO_RELOAD_PARAMS;
1138 	  return SANE_STATUS_GOOD;
1139 
1140 	  /* these ones don't have crazy side effects */
1141 	case OPT_TL_X:
1142 	case OPT_TL_Y:
1143 	case OPT_BR_Y:
1144 	  s->val[option].w = *(SANE_Word *) val;
1145 	  calc_parameters (s);
1146 	  if (info)
1147 	    *info |= SANE_INFO_RELOAD_PARAMS;
1148 	  return SANE_STATUS_GOOD;
1149 
1150 	  /* this one is somewhat imprecise */
1151 	case OPT_BR_X:
1152 	  s->val[option].w = *(SANE_Word *) val;
1153 	  calc_parameters (s);
1154 	  if (info)
1155 	    *info |= SANE_INFO_RELOAD_PARAMS
1156 	      | SANE_INFO_INEXACT;
1157 	  return SANE_STATUS_GOOD;
1158 
1159 	  /* no side-effects whatsoever */
1160 	case OPT_BRIGHTNESS:
1161 	case OPT_CONTRAST:
1162 	case OPT_THRESHOLD:
1163 	case OPT_NEGATIVE:
1164 	case OPT_MIRROR:
1165 
1166 	  s->val[option].w = *(SANE_Word *) val;
1167 	  return SANE_STATUS_GOOD;
1168 
1169 	  /* string options */
1170 	case OPT_HALFTONE_PATTERN:
1171 	  if (info)
1172 	    *info |= SANE_INFO_RELOAD_OPTIONS;
1173 	  if (s->val[option].s)
1174 	    free (s->val[option].s);
1175 	  s->val[option].s = strdup (val);
1176 	  return SANE_STATUS_GOOD;
1177 
1178 	case OPT_MODE:
1179 	  status = mode_update (s, val);
1180 	  if (status != SANE_STATUS_GOOD)
1181 	    return status;
1182 	  if (s->val[option].s)
1183 	    free (s->val[option].s);
1184 	  s->val[option].s = strdup (val);
1185 
1186 	  if (info)
1187 	    *info |= SANE_INFO_RELOAD_OPTIONS | SANE_INFO_RELOAD_PARAMS;
1188 	  return SANE_STATUS_GOOD;
1189 	}			/* End of switch */
1190     }				/* End of SET_VALUE */
1191   return SANE_STATUS_INVAL;
1192 }
1193 
1194 SANE_Status
sane_get_parameters(SANE_Handle handle,SANE_Parameters * params)1195 sane_get_parameters (SANE_Handle handle, SANE_Parameters * params)
1196 {
1197   Abaton_Scanner *s = handle;
1198 
1199   DBG (FLOW_CONTROL, "Entering sane_get_parameters\n");
1200   calc_parameters (s);
1201 
1202 
1203   if (params)
1204     *params = s->params;
1205   return SANE_STATUS_GOOD;
1206 }
1207 
1208 SANE_Status
sane_start(SANE_Handle handle)1209 sane_start (SANE_Handle handle)
1210 {
1211   Abaton_Scanner *s = handle;
1212   SANE_Status status;
1213 
1214   /* First make sure we have a current parameter set.  Some of the
1215      parameters will be overwritten below, but that's OK.  */
1216 
1217   calc_parameters (s);
1218 
1219   if (s->fd < 0)
1220     {
1221       /* this is the first (and maybe only) pass... */
1222 
1223       status = sanei_scsi_open (s->hw->sane.name, &s->fd, sense_handler, 0);
1224       if (status != SANE_STATUS_GOOD)
1225 	{
1226 	  DBG (ERROR_MESSAGE, "open: open of %s failed: %s\n",
1227 	       s->hw->sane.name, sane_strstatus (status));
1228 	  return status;
1229 	}
1230     }
1231 
1232   status = wait_ready (s->fd);
1233   if (status != SANE_STATUS_GOOD)
1234     {
1235       DBG (ERROR_MESSAGE, "open: wait_ready() failed: %s\n",
1236 	   sane_strstatus (status));
1237       goto stop_scanner_and_return;
1238     }
1239 
1240   status = request_sense (s);
1241   if (status != SANE_STATUS_GOOD)
1242     {
1243       DBG (ERROR_MESSAGE, "sane_start: request_sense revealed error: %s\n",
1244 	   sane_strstatus (status));
1245       goto stop_scanner_and_return;
1246     }
1247 
1248   status = set_window (s);
1249   if (status != SANE_STATUS_GOOD)
1250     {
1251       DBG (ERROR_MESSAGE, "open: set scan area command failed: %s\n",
1252 	   sane_strstatus (status));
1253       goto stop_scanner_and_return;
1254     }
1255 
1256   s->scanning = SANE_TRUE;
1257   s->AbortedByUser = SANE_FALSE;
1258 
1259   status = start_scan (s);
1260   if (status != SANE_STATUS_GOOD)
1261     goto stop_scanner_and_return;
1262 
1263   return SANE_STATUS_GOOD;
1264 
1265 stop_scanner_and_return:
1266   s->scanning = SANE_FALSE;
1267   s->AbortedByUser = SANE_FALSE;
1268   return status;
1269 }
1270 
1271 SANE_Status
sane_read(SANE_Handle handle,SANE_Byte * buf,SANE_Int max_len,SANE_Int * len)1272 sane_read (SANE_Handle handle, SANE_Byte * buf, SANE_Int max_len,
1273 	   SANE_Int * len)
1274 {
1275   Abaton_Scanner *s = handle;
1276   SANE_Status status;
1277 
1278   uint8_t get_data_status[10];
1279   uint8_t read[10];
1280 
1281   uint8_t result[12];
1282   size_t size;
1283   SANE_Int data_av = 0;
1284   SANE_Int data_length = 0;
1285   SANE_Int offset = 0;
1286   SANE_Int rread = 0;
1287   SANE_Bool Pseudo8bit = SANE_FALSE;
1288 
1289 
1290   *len = 0;
1291 
1292   /* don't let bogus read requests reach the scanner */
1293   /* this is a sub-optimal way of doing this, I'm sure */
1294   if (!s->scanning)
1295     return SANE_STATUS_EOF;
1296 
1297   if (!strcmp (s->val[OPT_MODE].s, "Gray16"))
1298     Pseudo8bit = SANE_TRUE;
1299 
1300   memset (get_data_status, 0, sizeof (get_data_status));
1301   get_data_status[0] = GET_DATA_STATUS;
1302   /* This means "block" for Apple scanners, it seems to be the same
1303      for Abaton.  The scanner will do non-blocking I/O, but I don't
1304      want to go there right now. */
1305   get_data_status[1] = 1;
1306   STORE8 (get_data_status + 8, sizeof (result));
1307 
1308   memset (read, 0, sizeof (read));
1309   read[0] = READ_10;
1310 
1311   do
1312     {
1313       size = sizeof (result);
1314       /* this isn't necessary */
1315       /*  memset (result, 0, size); */
1316       status = sanei_scsi_cmd (s->fd, get_data_status,
1317 			       sizeof (get_data_status), result, &size);
1318 
1319       if (status != SANE_STATUS_GOOD)
1320 	return status;
1321       if (!size)
1322 	{
1323 	  DBG (ERROR_MESSAGE, "sane_read: cannot get_data_status.\n");
1324 	  return SANE_STATUS_IO_ERROR;
1325 	}
1326 
1327       /* this is not an accurate name, but oh well... */
1328       data_length = GET24 (result);
1329       data_av = GET24 (result + 9);
1330 
1331       /* don't check result[3] here, because that screws things up
1332 	 somewhat */
1333       if (data_length) {
1334 	DBG (IO_MESSAGE,
1335 	     "sane_read: (status) Available in scanner buffer %u.\n",
1336 	     data_av);
1337 
1338 	if (Pseudo8bit)
1339 	  {
1340 	    if ((data_av * 2) + offset > max_len)
1341 	      rread = (max_len - offset) / 2;
1342 	    else
1343 	      rread = data_av;
1344 	  }
1345 	else if (data_av + offset > max_len)
1346 	  {
1347 	    rread = max_len - offset;
1348 	  }
1349 	else
1350 	  {
1351 	    rread = data_av;
1352 	  }
1353 
1354 	DBG (IO_MESSAGE,
1355 	     "sane_read: (action) Actual read request for %u bytes.\n",
1356 	     rread);
1357 
1358 	size = rread;
1359 
1360 	STORE24 (read + 6, rread);
1361 
1362 	status = sanei_scsi_cmd (s->fd, read, sizeof (read),
1363 				 buf + offset, &size);
1364 
1365 	if (Pseudo8bit)
1366 	  {
1367 	    SANE_Int byte;
1368 	    SANE_Int pos = offset + (rread << 1) - 1;
1369 	    SANE_Byte B;
1370 	    for (byte = offset + rread - 1; byte >= offset; byte--)
1371 	      {
1372 		B = buf[byte];
1373 		/* don't invert these! */
1374 		buf[pos--] = B << 4;   /* low (right) nibble */
1375 		buf[pos--] = B & 0xF0; /* high (left) nibble */
1376 	      }
1377 	    /* putting an end to bitop abuse here */
1378 	    offset += size * 2;
1379 	  }
1380 	else
1381 	  offset += size;
1382 
1383 	DBG (IO_MESSAGE, "sane_read: Buffer %u of %u full %g%%\n",
1384 	     offset, max_len, (double) (offset * 100. / max_len));
1385       }
1386     }
1387   while (offset < max_len && data_length != 0 && !s->AbortedByUser);
1388 
1389   if (s->AbortedByUser)
1390     {
1391       s->scanning = SANE_FALSE;
1392 
1393       if (status != SANE_STATUS_GOOD)
1394 	{
1395 	  DBG (ERROR_MESSAGE, "sane_read: request_sense revealed error: %s\n",
1396 	       sane_strstatus (status));
1397 	  return status;
1398 	}
1399 
1400       status = sanei_scsi_cmd (s->fd, test_unit_ready,
1401 			       sizeof (test_unit_ready), 0, 0);
1402       if (status != SANE_STATUS_GOOD || status != SANE_STATUS_INVAL)
1403 	return status;
1404       return SANE_STATUS_CANCELLED;
1405     }
1406 
1407   if (!data_length)
1408     {
1409       s->scanning = SANE_FALSE;
1410       DBG (IO_MESSAGE, "sane_read: (status) No more data...");
1411       if (!offset)
1412 	{
1413 	  /* this shouldn't happen */
1414 	  *len = 0;
1415 	  DBG (IO_MESSAGE, "EOF\n");
1416 	  return SANE_STATUS_EOF;
1417 	}
1418       else
1419 	{
1420 	  *len = offset;
1421 	  DBG (IO_MESSAGE, "GOOD\n");
1422 	  return SANE_STATUS_GOOD;
1423 	}
1424     }
1425 
1426 
1427   DBG (FLOW_CONTROL,
1428        "sane_read: Normal Exiting, Aborted=%u, data_length=%u\n",
1429        s->AbortedByUser, data_av);
1430   *len = offset;
1431 
1432   return SANE_STATUS_GOOD;
1433 }
1434 
1435 void
sane_cancel(SANE_Handle handle)1436 sane_cancel (SANE_Handle handle)
1437 {
1438   Abaton_Scanner *s = handle;
1439 
1440   if (s->scanning)
1441     {
1442       if (s->AbortedByUser)
1443 	{
1444 	  DBG (FLOW_CONTROL,
1445 	       "sane_cancel: Already Aborted. Please Wait...\n");
1446 	}
1447       else
1448 	{
1449 	  s->scanning = SANE_FALSE;
1450 	  s->AbortedByUser = SANE_TRUE;
1451 	  DBG (FLOW_CONTROL, "sane_cancel: Signal Caught! Aborting...\n");
1452 	}
1453     }
1454   else
1455     {
1456       if (s->AbortedByUser)
1457 	{
1458 	  DBG (FLOW_CONTROL, "sane_cancel: Scan has not been initiated yet."
1459 	       "we probably received a signal while writing data.\n");
1460 	  s->AbortedByUser = SANE_FALSE;
1461 	}
1462       else
1463 	{
1464 	  DBG (FLOW_CONTROL, "sane_cancel: Scan has not been initiated "
1465 	       "yet (or it's over).\n");
1466 	}
1467     }
1468 
1469   return;
1470 }
1471 
1472 SANE_Status
sane_set_io_mode(SANE_Handle handle,SANE_Bool non_blocking)1473 sane_set_io_mode (SANE_Handle handle, SANE_Bool non_blocking)
1474 {
1475   handle = handle;			/* silence gcc */
1476   non_blocking = non_blocking;	/* silence gcc */
1477 
1478   DBG (FLOW_CONTROL, "sane_set_io_mode: Don't call me please. "
1479        "Unimplemented function\n");
1480   return SANE_STATUS_UNSUPPORTED;
1481 }
1482 
1483 SANE_Status
sane_get_select_fd(SANE_Handle handle,SANE_Int * fd)1484 sane_get_select_fd (SANE_Handle handle, SANE_Int * fd)
1485 {
1486   handle = handle;			/* silence gcc */
1487   fd = fd;						/* silence gcc */
1488 
1489   DBG (FLOW_CONTROL, "sane_get_select_fd: Don't call me please. "
1490        "Unimplemented function\n");
1491   return SANE_STATUS_UNSUPPORTED;
1492 }
1493