• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* sane - Scanner Access Now Easy.
2    (C) 2003 Henning Meier-Geinitz <henning@meier-geinitz.de>.
3 
4    Based on the mustek (SCSI) backend.
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 scanners based on the Mustek
43    MA-1509 chipset. Currently the Mustek BearPaw 1200F is known to work.
44 */
45 
46 
47 /**************************************************************************/
48 /* ma1509 backend version                                                 */
49 #define BUILD 3
50 /**************************************************************************/
51 
52 #include "../include/sane/config.h"
53 
54 #include <ctype.h>
55 #include <stdio.h>
56 #include <stdlib.h>
57 #include <string.h>
58 #include <unistd.h>
59 #include <limits.h>
60 #include <sys/time.h>
61 #include <sys/types.h>
62 #include <errno.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_usb.h"
68 
69 #define BACKEND_NAME	ma1509
70 #include "../include/sane/sanei_backend.h"
71 #include "../include/sane/sanei_config.h"
72 
73 #include "ma1509.h"
74 
75 #ifndef SANE_I18N
76 #define SANE_I18N(text) text
77 #endif
78 
79 /* Debug level from sanei_init_debug */
80 static SANE_Int debug_level;
81 
82 static SANE_Int num_devices;
83 static Ma1509_Device *first_dev;
84 static Ma1509_Scanner *first_handle;
85 static const SANE_Device **devlist = 0;
86 
87 static int warmup_time = MA1509_WARMUP_TIME;
88 
89 /* Array of newly attached devices */
90 static Ma1509_Device **new_dev;
91 
92 /* Length of new_dev array */
93 static SANE_Int new_dev_len;
94 
95 /* Number of entries allocated for new_dev */
96 static SANE_Int new_dev_alloced;
97 
98 static SANE_String_Const mode_list[] = {
99   SANE_VALUE_SCAN_MODE_LINEART,
100   SANE_VALUE_SCAN_MODE_GRAY,
101   SANE_VALUE_SCAN_MODE_COLOR,
102   0
103 };
104 
105 static SANE_String_Const ta_source_list[] = {
106   SANE_I18N ("Flatbed"), SANE_I18N ("Transparency Adapter"),
107   0
108 };
109 
110 static SANE_Word resolution_list[] = {
111   9,
112   50, 100, 150, 200, 300, 400, 450, 500, 600
113 };
114 
115 static const SANE_Range u8_range = {
116   0,				/* minimum */
117   255,				/* maximum */
118   0				/* quantization */
119 };
120 
121 
122 /* "SCSI" command buffers used by the backend */
123 static const SANE_Byte scsi_inquiry[] = {
124   0x12, 0x01, 0x00, 0x00, 0x00, 0x00, INQ_LEN, 0x00
125 };
126 static const SANE_Byte scsi_test_unit_ready[] = {
127   0x03, 0x01, 0x01, 0x00, 0x00, 0x00, 0x04, 0x00
128 };
129 static const SANE_Byte scsi_set_window[] = {
130   0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00
131 };
132 
133 
134 static void
print_data_buffer(const SANE_Byte * buffer,size_t len)135 print_data_buffer (const SANE_Byte * buffer, size_t len)
136 {
137   SANE_Byte buffer_byte_list[50];
138   SANE_Byte buffer_byte[5];
139   const SANE_Byte *pp;
140 
141   buffer_byte_list[0] = '\0';
142   for (pp = buffer; pp < (buffer + len); pp++)
143     {
144       sprintf ((SANE_String) buffer_byte, " %02x", *pp);
145       strcat ((SANE_String) buffer_byte_list, (SANE_String) buffer_byte);
146       if (((pp - buffer) % 0x10 == 0x0f) || (pp >= (buffer + len - 1)))
147 	{
148 	  DBG (5, "buffer: %s\n", buffer_byte_list);
149 	  buffer_byte_list[0] = '\0';
150 	}
151     }
152 }
153 
154 static SANE_Status
ma1509_cmd(Ma1509_Scanner * s,const SANE_Byte * cmd,SANE_Byte * data,size_t * data_size)155 ma1509_cmd (Ma1509_Scanner * s, const SANE_Byte * cmd, SANE_Byte * data,
156 	    size_t * data_size)
157 {
158   SANE_Status status;
159   size_t size;
160 #define MA1509_WRITE_LIMIT (1024 * 64)
161 #define MA1509_READ_LIMIT (1024 * 256)
162 
163   DBG (5, "ma1509_cmd: fd=%d, cmd=%p, data=%p, data_size=%ld\n",
164        s->fd, (void *) cmd, (void *) data, (long int) (data_size ? *data_size : 0));
165   DBG (5, "ma1509_cmd: cmd = %02x %02x %02x %02x %02x %02x %02x %02x \n",
166        cmd[0], cmd[1], cmd[2], cmd[3], cmd[4], cmd[5], cmd[6], cmd[7]);
167 
168 
169   size = MA1509_COMMAND_LENGTH;
170   status = sanei_usb_write_bulk (s->fd, cmd, &size);
171   if (status != SANE_STATUS_GOOD || size != MA1509_COMMAND_LENGTH)
172     {
173       DBG (5,
174 	   "ma1509_cmd: sanei_usb_write_bulk returned %s (size = %ld, expected %d)\n",
175 	   sane_strstatus (status), (long int) size, MA1509_COMMAND_LENGTH);
176       return status;
177     }
178 
179   if (cmd[1] == 1)
180     {
181       /* receive data */
182       if (data && data_size && *data_size)
183 	{
184 	  size_t bytes_left = *data_size;
185 	  DBG (5, "ma1509_cmd: trying to receive %ld bytes of data\n",
186 	       (long int) *data_size);
187 
188 	  while (status == SANE_STATUS_GOOD && bytes_left > 0)
189 	    {
190 	      size = bytes_left;
191 	      if (size > MA1509_READ_LIMIT)
192 		size = MA1509_READ_LIMIT;
193 
194 	      status =
195 		sanei_usb_read_bulk (s->fd, data + *data_size - bytes_left,
196 				     &size);
197 
198 	      if (status != SANE_STATUS_GOOD)
199 		{
200 		  DBG (1, "ma1509_cmd: sanei_usb_read_bulk returned %s\n",
201 		       sane_strstatus (status));
202 		  return status;
203 		}
204 	      bytes_left -= size;
205 	      DBG (5, "ma1509_cmd: read %ld bytes, %ld bytes to go\n",
206 		   (long int) size, (long int) bytes_left);
207 	    }
208 	  if (debug_level >= 5)
209 	    print_data_buffer (data, *data_size);
210 	}
211     }
212   else
213     {
214       /* send data */
215       if (data && data_size && *data_size)
216 	{
217 	  size_t bytes_left = *data_size;
218 
219 	  DBG (5, "ma1509_cmd: sending %ld bytes of data\n",
220 	       (long int) *data_size);
221 	  if (debug_level >= 5)
222 	    print_data_buffer (data, *data_size);
223 
224 	  while (status == SANE_STATUS_GOOD && bytes_left > 0)
225 	    {
226 	      size = bytes_left;
227 	      if (size > MA1509_WRITE_LIMIT)
228 		size = MA1509_WRITE_LIMIT;
229 	      status =
230 		sanei_usb_write_bulk (s->fd, data + *data_size - bytes_left,
231 				      &size);
232 	      if (status != SANE_STATUS_GOOD)
233 		{
234 		  DBG (1, "ma1509_cmd: sanei_usb_write_bulk returned %s\n",
235 		       sane_strstatus (status));
236 		  return status;
237 		}
238 	      bytes_left -= size;
239 	      DBG (5, "ma1509_cmd: wrote %ld bytes, %ld bytes to go\n",
240 		   (long int) size, (long int) bytes_left);
241 	    }
242 
243 	}
244     }
245 
246   DBG (5, "ma1509_cmd: finished: data_size=%ld, status=%s\n",
247        (long int) (data_size ? *data_size : 0), sane_strstatus (status));
248   return status;
249 }
250 
251 static SANE_Status
test_unit_ready(Ma1509_Scanner * s)252 test_unit_ready (Ma1509_Scanner * s)
253 {
254   SANE_Status status;
255   SANE_Byte buffer[0x04];
256   size_t size = sizeof (buffer);
257 
258   status = ma1509_cmd (s, scsi_test_unit_ready, buffer, &size);
259   if (status != SANE_STATUS_GOOD)
260     {
261       DBG (1, "test_unit_ready: ma1509_cmd failed: %s\n",
262 	   sane_strstatus (status));
263       return status;
264     }
265   if (buffer[1] == 0x14)
266     s->hw->has_adf = SANE_TRUE;
267   else
268     s->hw->has_adf = SANE_FALSE;
269 
270   return status;
271 }
272 
273 static SANE_Status
attach(SANE_String_Const devname,Ma1509_Device ** devp)274 attach (SANE_String_Const devname, Ma1509_Device ** devp)
275 {
276   SANE_Int fw_revision;
277   SANE_Byte result[INQ_LEN];
278   SANE_Byte inquiry_byte_list[50], inquiry_text_list[17];
279   SANE_Byte inquiry_byte[5], inquiry_text[5];
280   SANE_Byte *model_name = result + 44;
281   Ma1509_Scanner s;
282   Ma1509_Device *dev, new_dev;
283   SANE_Status status;
284   size_t size;
285   SANE_Byte *pp;
286   SANE_Word vendor, product;
287 
288   if (devp)
289     *devp = 0;
290 
291   for (dev = first_dev; dev; dev = dev->next)
292     if (strcmp (dev->sane.name, devname) == 0)
293       {
294 	if (devp)
295 	  *devp = dev;
296 	return SANE_STATUS_GOOD;
297       }
298 
299   memset (&new_dev, 0, sizeof (new_dev));
300   memset (&s, 0, sizeof (s));
301   s.hw = &new_dev;
302 
303   DBG (3, "attach: trying device %s\n", devname);
304 
305   status = sanei_usb_open (devname, &s.fd);
306   if (status != SANE_STATUS_GOOD)
307     {
308       DBG (1, "attach: sanei_usb_open failed: %s\n", sane_strstatus (status));
309       return status;
310     }
311 
312   status = sanei_usb_get_vendor_product (s.fd, &vendor, &product);
313   if (status != SANE_STATUS_GOOD && status != SANE_STATUS_UNSUPPORTED)
314     {
315       DBG (1, "attach: sanei_usb_get_vendor_product failed: %s\n",
316 	   sane_strstatus (status));
317       sanei_usb_close (s.fd);
318       return status;
319     }
320   if (status == SANE_STATUS_UNSUPPORTED)
321     {
322       DBG (3, "attach: can't detect vendor/product, trying anyway\n");
323     }
324   else if (vendor != 0x055f || product != 0x0010)
325     {
326       DBG (1, "attach: unknown vendor/product (0x%x/0x%x)\n", vendor,
327 	   product);
328       sanei_usb_close (s.fd);
329       return SANE_STATUS_UNSUPPORTED;
330     }
331 
332   DBG (4, "attach: sending TEST_UNIT_READY\n");
333   status = test_unit_ready (&s);
334   if (status != SANE_STATUS_GOOD)
335     {
336       DBG (1, "attach: test_unit_ready device %s failed (%s)\n", devname,
337 	   sane_strstatus (status));
338       sanei_usb_close (s.fd);
339       return status;
340     }
341 
342   DBG (4, "attach: sending INQUIRY\n");
343   size = sizeof (result);
344   memset (result, 0, sizeof (result));
345   status = ma1509_cmd (&s, scsi_inquiry, result, &size);
346   if (status != SANE_STATUS_GOOD || size != INQ_LEN)
347     {
348       DBG (1, "attach: inquiry for device %s failed (%s)\n", devname,
349 	   sane_strstatus (status));
350       sanei_usb_close (s.fd);
351       return status;
352     }
353 
354   sanei_usb_close (s.fd);
355 
356   if ((result[0] & 0x1f) != 0x06)
357     {
358       DBG (1, "attach: device %s doesn't look like a scanner at all (%d)\n",
359 	   devname, result[0] & 0x1f);
360       return SANE_STATUS_INVAL;
361     }
362 
363   if (debug_level >= 5)
364     {
365       /* print out inquiry */
366       DBG (5, "attach: inquiry output:\n");
367       inquiry_byte_list[0] = '\0';
368       inquiry_text_list[0] = '\0';
369       for (pp = result; pp < (result + INQ_LEN); pp++)
370 	{
371 	  sprintf ((SANE_String) inquiry_text, "%c",
372 		   (*pp < 127) && (*pp > 31) ? *pp : '.');
373 	  strcat ((SANE_String) inquiry_text_list,
374 		  (SANE_String) inquiry_text);
375 	  sprintf ((SANE_String) inquiry_byte, " %02x", *pp);
376 	  strcat ((SANE_String) inquiry_byte_list,
377 		  (SANE_String) inquiry_byte);
378 	  if ((pp - result) % 0x10 == 0x0f)
379 	    {
380 	      DBG (5, "%s  %s\n", inquiry_byte_list, inquiry_text_list);
381 	      inquiry_byte_list[0] = '\0';
382 	      inquiry_text_list[0] = '\0';
383 	    }
384 	}
385     }
386 
387   /* get firmware revision as BCD number:             */
388   fw_revision = (result[32] - '0') << 8 | (result[34] - '0') << 4
389     | (result[35] - '0');
390   DBG (4, "attach: firmware revision %d.%02x\n", fw_revision >> 8,
391        fw_revision & 0xff);
392 
393   dev = malloc (sizeof (*dev));
394   if (!dev)
395     return SANE_STATUS_NO_MEM;
396 
397   memcpy (dev, &new_dev, sizeof (*dev));
398 
399   dev->name = strdup (devname);
400   if (!dev->name)
401     return SANE_STATUS_NO_MEM;
402   dev->sane.name = (SANE_String_Const) dev->name;
403   dev->sane.vendor = "Mustek";
404   dev->sane.type = "flatbed scanner";
405 
406   dev->x_range.min = 0;
407   dev->y_range.min = 0;
408   dev->x_range.quant = SANE_FIX (0.1);
409   dev->y_range.quant = SANE_FIX (0.1);
410   dev->x_trans_range.min = 0;
411   dev->y_trans_range.min = 0;
412   /* default to something really small to be on the safe side: */
413   dev->x_trans_range.max = SANE_FIX (8.0 * MM_PER_INCH);
414   dev->y_trans_range.max = SANE_FIX (5.0 * MM_PER_INCH);
415   dev->x_trans_range.quant = SANE_FIX (0.1);
416   dev->y_trans_range.quant = SANE_FIX (0.1);
417 
418   DBG (3, "attach: scanner id: %.11s\n", model_name);
419 
420   /* BearPaw 1200F (SCSI-over-USB) */
421   if (strncmp ((SANE_String) model_name, " B06", 4) == 0)
422     {
423       dev->x_range.max = SANE_FIX (211.3);
424       dev->y_range.min = SANE_FIX (0);
425       dev->y_range.max = SANE_FIX (296.7);
426 
427       dev->x_trans_range.min = SANE_FIX (0);
428       dev->y_trans_range.min = SANE_FIX (0);
429       dev->x_trans_range.max = SANE_FIX (150.0);
430       dev->y_trans_range.max = SANE_FIX (175.0);
431 
432       dev->sane.model = "BearPaw 1200F";
433     }
434   else
435     {
436       DBG (0, "attach: this scanner (ID: %s) is not supported yet\n",
437 	   model_name);
438       DBG (0, "attach: please set the debug level to 5 and send a debug "
439 	   "report\n");
440       DBG (0, "attach: to henning@meier-geinitz.de (export "
441 	   "SANE_DEBUG_MA1509=5\n");
442       DBG (0, "attach: scanimage -L 2>debug.txt). Thank you.\n");
443       free (dev);
444       return SANE_STATUS_INVAL;
445     }
446 
447   DBG (2, "attach: found Mustek %s %s %s%s\n",
448        dev->sane.model, dev->sane.type, dev->has_ta ? "(TA)" : "",
449        dev->has_adf ? "(ADF)" : "");
450 
451   ++num_devices;
452   dev->next = first_dev;
453   first_dev = dev;
454 
455   if (devp)
456     *devp = dev;
457   return SANE_STATUS_GOOD;
458 }
459 
460 
461 static size_t
max_string_size(const SANE_String_Const strings[])462 max_string_size (const SANE_String_Const strings[])
463 {
464   size_t size, max_size = 0;
465   SANE_Int i;
466 
467   for (i = 0; strings[i]; ++i)
468     {
469       size = strlen (strings[i]) + 1;
470       if (size > max_size)
471 	max_size = size;
472     }
473   return max_size;
474 }
475 
476 
477 static SANE_Status
init_options(Ma1509_Scanner * s)478 init_options (Ma1509_Scanner * s)
479 {
480   SANE_Int i;
481 
482   memset (s->opt, 0, sizeof (s->opt));
483   memset (s->val, 0, sizeof (s->val));
484 
485   for (i = 0; i < NUM_OPTIONS; ++i)
486     {
487       s->opt[i].size = sizeof (SANE_Word);
488       s->opt[i].cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT;
489     }
490 
491   s->opt[OPT_NUM_OPTS].name = "";
492   s->opt[OPT_NUM_OPTS].title = SANE_TITLE_NUM_OPTIONS;
493   s->opt[OPT_NUM_OPTS].desc = SANE_DESC_NUM_OPTIONS;
494   s->opt[OPT_NUM_OPTS].type = SANE_TYPE_INT;
495   s->opt[OPT_NUM_OPTS].cap = SANE_CAP_SOFT_DETECT;
496   s->val[OPT_NUM_OPTS].w = NUM_OPTIONS;
497 
498   /* "Mode" group: */
499   s->opt[OPT_MODE_GROUP].title = SANE_I18N ("Scan Mode");
500   s->opt[OPT_MODE_GROUP].desc = "";
501   s->opt[OPT_MODE_GROUP].type = SANE_TYPE_GROUP;
502   s->opt[OPT_MODE_GROUP].cap = 0;
503   s->opt[OPT_MODE_GROUP].size = 0;
504   s->opt[OPT_MODE_GROUP].constraint_type = SANE_CONSTRAINT_NONE;
505 
506   /* scan mode */
507   s->opt[OPT_MODE].name = SANE_NAME_SCAN_MODE;
508   s->opt[OPT_MODE].title = SANE_TITLE_SCAN_MODE;
509   s->opt[OPT_MODE].desc = SANE_DESC_SCAN_MODE;
510   s->opt[OPT_MODE].type = SANE_TYPE_STRING;
511   s->opt[OPT_MODE].constraint_type = SANE_CONSTRAINT_STRING_LIST;
512   s->opt[OPT_MODE].size = max_string_size (mode_list);
513   s->opt[OPT_MODE].constraint.string_list = mode_list;
514   s->val[OPT_MODE].s = strdup (mode_list[1]);
515   if (!s->val[OPT_MODE].s)
516     return SANE_STATUS_NO_MEM;
517 
518   /* resolution */
519   s->opt[OPT_RESOLUTION].name = SANE_NAME_SCAN_RESOLUTION;
520   s->opt[OPT_RESOLUTION].title = SANE_TITLE_SCAN_RESOLUTION;
521   s->opt[OPT_RESOLUTION].desc = SANE_DESC_SCAN_RESOLUTION;
522   s->opt[OPT_RESOLUTION].type = SANE_TYPE_INT;
523   s->opt[OPT_RESOLUTION].unit = SANE_UNIT_DPI;
524   s->opt[OPT_RESOLUTION].constraint_type = SANE_CONSTRAINT_WORD_LIST;
525   s->opt[OPT_RESOLUTION].constraint.word_list = resolution_list;
526   s->val[OPT_RESOLUTION].w = 50;
527 
528   /* source */
529   s->opt[OPT_SOURCE].name = SANE_NAME_SCAN_SOURCE;
530   s->opt[OPT_SOURCE].title = SANE_TITLE_SCAN_SOURCE;
531   s->opt[OPT_SOURCE].desc = SANE_DESC_SCAN_SOURCE;
532   s->opt[OPT_SOURCE].type = SANE_TYPE_STRING;
533   s->opt[OPT_SOURCE].size = max_string_size (ta_source_list);
534   s->opt[OPT_SOURCE].constraint_type = SANE_CONSTRAINT_STRING_LIST;
535   s->opt[OPT_SOURCE].constraint.string_list = ta_source_list;
536   s->val[OPT_SOURCE].s = strdup (ta_source_list[0]);
537   if (!s->val[OPT_SOURCE].s)
538     return SANE_STATUS_NO_MEM;
539   s->opt[OPT_SOURCE].cap |= SANE_CAP_INACTIVE;
540 
541   /* preview */
542   s->opt[OPT_PREVIEW].name = SANE_NAME_PREVIEW;
543   s->opt[OPT_PREVIEW].title = SANE_TITLE_PREVIEW;
544   s->opt[OPT_PREVIEW].desc = SANE_DESC_PREVIEW;
545   s->opt[OPT_PREVIEW].cap = SANE_CAP_SOFT_DETECT | SANE_CAP_SOFT_SELECT;
546   s->val[OPT_PREVIEW].w = 0;
547 
548   /* "Geometry" group: */
549   s->opt[OPT_GEOMETRY_GROUP].title = SANE_I18N ("Geometry");
550   s->opt[OPT_GEOMETRY_GROUP].desc = "";
551   s->opt[OPT_GEOMETRY_GROUP].type = SANE_TYPE_GROUP;
552   s->opt[OPT_GEOMETRY_GROUP].cap = SANE_CAP_ADVANCED;
553   s->opt[OPT_GEOMETRY_GROUP].size = 0;
554   s->opt[OPT_GEOMETRY_GROUP].constraint_type = SANE_CONSTRAINT_NONE;
555 
556   /* top-left x */
557   s->opt[OPT_TL_X].name = SANE_NAME_SCAN_TL_X;
558   s->opt[OPT_TL_X].title = SANE_TITLE_SCAN_TL_X;
559   s->opt[OPT_TL_X].desc = SANE_DESC_SCAN_TL_X;
560   s->opt[OPT_TL_X].type = SANE_TYPE_FIXED;
561   s->opt[OPT_TL_X].unit = SANE_UNIT_MM;
562   s->opt[OPT_TL_X].constraint_type = SANE_CONSTRAINT_RANGE;
563   s->opt[OPT_TL_X].constraint.range = &s->hw->x_range;
564   s->val[OPT_TL_X].w = s->hw->x_range.min;
565 
566   /* top-left y */
567   s->opt[OPT_TL_Y].name = SANE_NAME_SCAN_TL_Y;
568   s->opt[OPT_TL_Y].title = SANE_TITLE_SCAN_TL_Y;
569   s->opt[OPT_TL_Y].desc = SANE_DESC_SCAN_TL_Y;
570   s->opt[OPT_TL_Y].type = SANE_TYPE_FIXED;
571   s->opt[OPT_TL_Y].unit = SANE_UNIT_MM;
572   s->opt[OPT_TL_Y].constraint_type = SANE_CONSTRAINT_RANGE;
573   s->opt[OPT_TL_Y].constraint.range = &s->hw->y_range;
574   s->val[OPT_TL_Y].w = s->hw->y_range.min;
575 
576   /* bottom-right x */
577   s->opt[OPT_BR_X].name = SANE_NAME_SCAN_BR_X;
578   s->opt[OPT_BR_X].title = SANE_TITLE_SCAN_BR_X;
579   s->opt[OPT_BR_X].desc = SANE_DESC_SCAN_BR_X;
580   s->opt[OPT_BR_X].type = SANE_TYPE_FIXED;
581   s->opt[OPT_BR_X].unit = SANE_UNIT_MM;
582   s->opt[OPT_BR_X].constraint_type = SANE_CONSTRAINT_RANGE;
583   s->opt[OPT_BR_X].constraint.range = &s->hw->x_range;
584   s->val[OPT_BR_X].w = s->hw->x_range.max;
585 
586   /* bottom-right y */
587   s->opt[OPT_BR_Y].name = SANE_NAME_SCAN_BR_Y;
588   s->opt[OPT_BR_Y].title = SANE_TITLE_SCAN_BR_Y;
589   s->opt[OPT_BR_Y].desc = SANE_DESC_SCAN_BR_Y;
590   s->opt[OPT_BR_Y].type = SANE_TYPE_FIXED;
591   s->opt[OPT_BR_Y].unit = SANE_UNIT_MM;
592   s->opt[OPT_BR_Y].constraint_type = SANE_CONSTRAINT_RANGE;
593   s->opt[OPT_BR_Y].constraint.range = &s->hw->y_range;
594   s->val[OPT_BR_Y].w = s->hw->y_range.max;
595 
596   /* "Enhancement" group: */
597   s->opt[OPT_ENHANCEMENT_GROUP].title = SANE_I18N ("Enhancement");
598   s->opt[OPT_ENHANCEMENT_GROUP].desc = "";
599   s->opt[OPT_ENHANCEMENT_GROUP].type = SANE_TYPE_GROUP;
600   s->opt[OPT_ENHANCEMENT_GROUP].size = 0;
601   s->opt[OPT_ENHANCEMENT_GROUP].cap = 0;
602   s->opt[OPT_ENHANCEMENT_GROUP].constraint_type = SANE_CONSTRAINT_NONE;
603 
604   /* threshold */
605   s->opt[OPT_THRESHOLD].name = SANE_NAME_THRESHOLD;
606   s->opt[OPT_THRESHOLD].title = SANE_TITLE_THRESHOLD;
607   s->opt[OPT_THRESHOLD].desc = SANE_DESC_THRESHOLD;
608   s->opt[OPT_THRESHOLD].type = SANE_TYPE_INT;
609   s->opt[OPT_THRESHOLD].unit = SANE_UNIT_NONE;
610   s->opt[OPT_THRESHOLD].constraint_type = SANE_CONSTRAINT_RANGE;
611   s->opt[OPT_THRESHOLD].constraint.range = &u8_range;
612   s->opt[OPT_THRESHOLD].cap |= SANE_CAP_INACTIVE;
613   s->val[OPT_THRESHOLD].w = 128;
614 
615   /* custom-gamma table */
616   s->opt[OPT_CUSTOM_GAMMA].name = SANE_NAME_CUSTOM_GAMMA;
617   s->opt[OPT_CUSTOM_GAMMA].title = SANE_TITLE_CUSTOM_GAMMA;
618   s->opt[OPT_CUSTOM_GAMMA].desc = SANE_DESC_CUSTOM_GAMMA;
619   s->opt[OPT_CUSTOM_GAMMA].type = SANE_TYPE_BOOL;
620   s->val[OPT_CUSTOM_GAMMA].w = SANE_FALSE;
621 
622   /* red gamma vector */
623   s->opt[OPT_GAMMA_VECTOR_R].name = SANE_NAME_GAMMA_VECTOR_R;
624   s->opt[OPT_GAMMA_VECTOR_R].title = SANE_TITLE_GAMMA_VECTOR_R;
625   s->opt[OPT_GAMMA_VECTOR_R].desc = SANE_DESC_GAMMA_VECTOR_R;
626   s->opt[OPT_GAMMA_VECTOR_R].type = SANE_TYPE_INT;
627   s->opt[OPT_GAMMA_VECTOR_R].unit = SANE_UNIT_NONE;
628   s->opt[OPT_GAMMA_VECTOR_R].size = MA1509_GAMMA_SIZE * sizeof (SANE_Word);
629   s->val[OPT_GAMMA_VECTOR_R].wa = &s->red_gamma_table[0];
630   s->opt[OPT_GAMMA_VECTOR_R].constraint_type = SANE_CONSTRAINT_RANGE;
631   s->opt[OPT_GAMMA_VECTOR_R].constraint.range = &u8_range;
632   s->opt[OPT_GAMMA_VECTOR_R].cap |= SANE_CAP_INACTIVE;
633   for (i = 0; i < MA1509_GAMMA_SIZE; i++)
634     s->red_gamma_table[i] = i * MA1509_GAMMA_SIZE / 256;
635 
636   /* green gamma vector */
637   s->opt[OPT_GAMMA_VECTOR_G].name = SANE_NAME_GAMMA_VECTOR_G;
638   s->opt[OPT_GAMMA_VECTOR_G].title = SANE_TITLE_GAMMA_VECTOR_G;
639   s->opt[OPT_GAMMA_VECTOR_G].desc = SANE_DESC_GAMMA_VECTOR_G;
640   s->opt[OPT_GAMMA_VECTOR_G].type = SANE_TYPE_INT;
641   s->opt[OPT_GAMMA_VECTOR_G].unit = SANE_UNIT_NONE;
642   s->opt[OPT_GAMMA_VECTOR_G].size = MA1509_GAMMA_SIZE * sizeof (SANE_Word);
643   s->val[OPT_GAMMA_VECTOR_G].wa = &s->green_gamma_table[0];
644   s->opt[OPT_GAMMA_VECTOR_G].constraint_type = SANE_CONSTRAINT_RANGE;
645   s->opt[OPT_GAMMA_VECTOR_G].constraint.range = &u8_range;
646   s->opt[OPT_GAMMA_VECTOR_G].cap |= SANE_CAP_INACTIVE;
647   for (i = 0; i < MA1509_GAMMA_SIZE; i++)
648     s->green_gamma_table[i] = i * MA1509_GAMMA_SIZE / 256;
649 
650   /* blue gamma vector */
651   s->opt[OPT_GAMMA_VECTOR_B].name = SANE_NAME_GAMMA_VECTOR_B;
652   s->opt[OPT_GAMMA_VECTOR_B].title = SANE_TITLE_GAMMA_VECTOR_B;
653   s->opt[OPT_GAMMA_VECTOR_B].desc = SANE_DESC_GAMMA_VECTOR_B;
654   s->opt[OPT_GAMMA_VECTOR_B].type = SANE_TYPE_INT;
655   s->opt[OPT_GAMMA_VECTOR_B].unit = SANE_UNIT_NONE;
656   s->opt[OPT_GAMMA_VECTOR_B].size = MA1509_GAMMA_SIZE * sizeof (SANE_Word);
657   s->val[OPT_GAMMA_VECTOR_B].wa = &s->blue_gamma_table[0];
658   s->opt[OPT_GAMMA_VECTOR_B].constraint_type = SANE_CONSTRAINT_RANGE;
659   s->opt[OPT_GAMMA_VECTOR_B].constraint.range = &u8_range;
660   s->opt[OPT_GAMMA_VECTOR_B].cap |= SANE_CAP_INACTIVE;
661   for (i = 0; i < MA1509_GAMMA_SIZE; i++)
662     s->blue_gamma_table[i] = i * MA1509_GAMMA_SIZE / 256;
663 
664   return SANE_STATUS_GOOD;
665 }
666 
667 static SANE_Status
attach_one_device(SANE_String_Const devname)668 attach_one_device (SANE_String_Const devname)
669 {
670   Ma1509_Device *dev;
671 
672   attach (devname, &dev);
673   if (dev)
674     {
675       /* Keep track of newly attached devices so we can set options as
676          necessary.  */
677       if (new_dev_len >= new_dev_alloced)
678 	{
679 	  new_dev_alloced += 4;
680 	  if (new_dev)
681 	    new_dev =
682 	      realloc (new_dev, new_dev_alloced * sizeof (new_dev[0]));
683 	  else
684 	    new_dev = malloc (new_dev_alloced * sizeof (new_dev[0]));
685 	  if (!new_dev)
686 	    {
687 	      DBG (1, "attach_one_device: out of memory\n");
688 	      return SANE_STATUS_NO_MEM;
689 	    }
690 	}
691       new_dev[new_dev_len++] = dev;
692     }
693   return SANE_STATUS_GOOD;
694 }
695 
696 static SANE_Status
set_window(Ma1509_Scanner * s)697 set_window (Ma1509_Scanner * s)
698 {
699   SANE_Byte buffer[0x30], *cp;
700   double pixels_per_mm;
701   size_t size = sizeof (buffer);
702   SANE_Status status;
703   SANE_Int tlx, tly, width, height;
704   SANE_Int offset = 0;
705   struct timeval now;
706   long remaining_time;
707 
708   /* check if lamp is warmed up */
709   gettimeofday (&now, 0);
710   remaining_time = warmup_time - (now.tv_sec - s->lamp_time);
711   if (remaining_time > 0)
712     {
713       DBG (0, "Warm-up in progress: please wait %2ld seconds\n",
714 	   remaining_time);
715       sleep (remaining_time);
716     }
717 
718   memset (buffer, 0, size);
719   cp = buffer;
720 
721   STORE16B (cp, 0);		/* window identifier            */
722   STORE16B (cp, s->val[OPT_RESOLUTION].w);
723   STORE16B (cp, 0);		/* not used acc. to specs       */
724 
725   pixels_per_mm = s->val[OPT_RESOLUTION].w / MM_PER_INCH;
726 
727   tlx = SANE_UNFIX (s->val[OPT_TL_X].w) * pixels_per_mm + 0.5;
728   tly = SANE_UNFIX (s->val[OPT_TL_Y].w) * pixels_per_mm + 0.5;
729 
730   width = (SANE_UNFIX (s->val[OPT_BR_X].w) - SANE_UNFIX (s->val[OPT_TL_X].w))
731     * pixels_per_mm + 0.5;
732   height = (SANE_UNFIX (s->val[OPT_BR_Y].w) - SANE_UNFIX (s->val[OPT_TL_Y].w))
733     * pixels_per_mm + 0.5 + offset;
734 
735   if (strcmp (s->val[OPT_MODE].s, SANE_VALUE_SCAN_MODE_LINEART) == 0)
736     {
737       width /= 64;
738       width *= 64;
739       if (!width)
740 	width = 64;
741     }
742   else
743     {
744       width /= 8;
745       width *= 8;
746       if (!width)
747 	width = 8;
748     }
749 
750 
751   DBG (4, "set_window: tlx=%d (%d mm); tly=%d (%d mm); width=%d (%d mm); "
752        "height=%d (%d mm)\n", tlx, (int) (tlx / pixels_per_mm), tly,
753        (int) (tly / pixels_per_mm), width, (int) (width / pixels_per_mm),
754        height, (int) (height / pixels_per_mm));
755 
756 
757   STORE16B (cp, 0);
758   STORE16B (cp, tlx);
759   STORE16B (cp, 0);
760   STORE16B (cp, tly);
761   *cp++ = 0x14;
762   *cp++ = 0xc0;
763   STORE16B (cp, width);
764   *cp++ = 0x28;
765   *cp++ = 0x20;
766   STORE16B (cp, height);
767 
768   s->hw->ppl = width;
769   s->hw->bpl = s->hw->ppl;
770 
771   s->hw->lines = height;
772 
773   *cp++ = 0x00;			/* brightness, not impl.        */
774   /* threshold */
775   if (strcmp (s->val[OPT_MODE].s, SANE_VALUE_SCAN_MODE_LINEART) == 0)
776     *cp++ = (SANE_Byte) s->val[OPT_THRESHOLD].w;
777   else
778     *cp++ = 0x80;
779   *cp++ = 0x00;			/* contrast, not impl.          */
780   *cp++ = 0x00;			/* ???               .          */
781 
782   /* Note that 'image composition' has no meaning for the SE series     */
783   /* Mode selection is accomplished solely by bits/pixel (1, 8, 24)     */
784   if (strcmp (s->val[OPT_MODE].s, SANE_VALUE_SCAN_MODE_COLOR) == 0)
785     {
786       *cp++ = 24;		/* 24 bits/pixel in color mode  */
787       s->hw->bpl *= 3;
788     }
789   else if (strcmp (s->val[OPT_MODE].s, SANE_VALUE_SCAN_MODE_GRAY) == 0)
790     *cp++ = 8;			/* 8 bits/pixel in gray mode    */
791   else
792     {
793       *cp++ = 1;		/* 1 bit/pixel in lineart mode  */
794       s->hw->bpl /= 8;
795     }
796 
797   cp += 13;			/* skip reserved bytes          */
798   *cp++ = 0x00;			/* lamp mode  */
799   if (strcmp (s->val[OPT_MODE].s, SANE_VALUE_SCAN_MODE_LINEART) != 0)
800     *cp++ = 0x02;		/* ???  */
801 
802   status = ma1509_cmd (s, scsi_set_window, buffer, &size);
803   if (status != SANE_STATUS_GOOD)
804     {
805       DBG (1, "set_window: ma1509_cmd failed: %s\n", sane_strstatus (status));
806       return status;
807     }
808   return status;
809 }
810 
811 static SANE_Status
calibration(Ma1509_Scanner * s)812 calibration (Ma1509_Scanner * s)
813 {
814   SANE_Byte cmd[0x08], *buffer, *calibration_buffer;
815   SANE_Status status;
816   SANE_Int ppl = 5312;
817   SANE_Int lines = 40;
818   size_t total_size = lines * ppl;
819   SANE_Int color, column, line;
820 
821   buffer = malloc (total_size * 3);
822   if (!buffer)
823     {
824       DBG (1,
825 	   "calibration: couldn't malloc %lu bytes for calibration buffer\n",
826 	   (u_long) (total_size * 3));
827       return SANE_STATUS_NO_MEM;
828     }
829   memset (buffer, 0x00, total_size);
830 
831   memset (cmd, 0, 8);
832   cmd[0] = 0x28;		/* read data */
833   cmd[1] = 0x01;		/* read */
834   cmd[2] = 0x01;		/* calibration */
835   cmd[4] = (total_size >> 16) & 0xff;
836   cmd[5] = (total_size >> 8) & 0xff;
837   cmd[6] = total_size & 0xff;
838   total_size *= 3;
839   status = ma1509_cmd (s, cmd, buffer, &total_size);
840   if (status != SANE_STATUS_GOOD)
841     {
842       DBG (1, "calibration: ma1509_cmd read data failed: %s\n",
843 	   sane_strstatus (status));
844       free (buffer);
845       return status;
846     }
847 
848   calibration_buffer = malloc (ppl);
849   if (!calibration_buffer)
850     {
851       DBG (1,
852 	   "calibration: couldn't malloc %d bytes for calibration buffer\n",
853 	   ppl);
854       return SANE_STATUS_NO_MEM;
855     }
856   memset (calibration_buffer, 0x00, ppl);
857 
858   memset (cmd, 0, 8);
859   cmd[0] = 0x2a;		/* send data */
860   cmd[1] = 0x00;		/* write */
861   cmd[2] = 0x01;		/* calibration */
862   cmd[5] = (ppl >> 8) & 0xff;
863   cmd[6] = ppl & 0xff;
864 
865   for (color = 1; color < 4; color++)
866     {
867       cmd[4] = color;
868 
869       for (column = 0; column < ppl; column++)
870 	{
871 	  SANE_Int average = 0;
872 
873 	  for (line = 0; line < lines; line++)
874 	    average += buffer[line * ppl * 3 + column * 3 + (color - 1)];
875 	  average /= lines;
876 	  if (average < 1)
877 	    average = 1;
878 	  if (average > 255)
879 	    average = 255;
880 
881 	  average = (256 * 256) / average - 256;
882 	  if (average < 0)
883 	    average = 0;
884 	  if (average > 255)
885 	    average = 255;
886 	  calibration_buffer[column] = average;
887 	}
888 
889       total_size = ppl;
890       status = ma1509_cmd (s, cmd, calibration_buffer, &total_size);
891       if (status != SANE_STATUS_GOOD)
892 	{
893 	  DBG (1, "calibration: ma1509_cmd send data failed: %s\n",
894 	       sane_strstatus (status));
895 	  free (buffer);
896 	  free (calibration_buffer);
897 	  return status;
898 	}
899     }
900   free (buffer);
901   free (calibration_buffer);
902   DBG (4, "calibration: done\n");
903   return status;
904 }
905 
906 
907 static SANE_Status
send_gamma(Ma1509_Scanner * s)908 send_gamma (Ma1509_Scanner * s)
909 {
910   SANE_Byte cmd[0x08], *buffer;
911   SANE_Status status;
912   size_t total_size = MA1509_GAMMA_SIZE;
913   SANE_Int color;
914 
915   buffer = malloc (total_size);
916   if (!buffer)
917     {
918       DBG (1, "send_gamma: couldn't malloc %lu bytes for gamma  buffer\n",
919 	   (u_long) total_size);
920       return SANE_STATUS_NO_MEM;
921     }
922 
923   memset (cmd, 0, 8);
924   cmd[0] = 0x2a;		/* send data */
925   cmd[1] = 0x00;		/* write */
926   cmd[2] = 0x03;		/* gamma */
927   cmd[5] = (total_size >> 8) & 0xff;
928   cmd[6] = total_size & 0xff;
929   for (color = 1; color < 4; color++)
930     {
931       unsigned int i;
932 
933       if (s->val[OPT_CUSTOM_GAMMA].w)
934 	{
935 	  SANE_Int *int_buffer;
936 
937 	  if (color == 1)
938 	    int_buffer = s->red_gamma_table;
939 	  else if (color == 2)
940 	    int_buffer = s->green_gamma_table;
941 	  else
942 	    int_buffer = s->blue_gamma_table;
943 	  for (i = 0; i < total_size; i++)
944 	    buffer[i] = int_buffer[i];
945 	}
946       else
947 	{
948 	  /* linear tables */
949 	  for (i = 0; i < total_size; i++)
950 	    buffer[i] = i * 256 / total_size;
951 	}
952 
953       cmd[4] = color;
954       status = ma1509_cmd (s, cmd, buffer, &total_size);
955       if (status != SANE_STATUS_GOOD)
956 	{
957 	  DBG (1, "send_gamma: ma1509_cmd send data failed: %s\n",
958 	       sane_strstatus (status));
959 	  free (buffer);
960 	  return status;
961 	}
962     }
963   if (!s->val[OPT_CUSTOM_GAMMA].w)
964     free (buffer);
965   DBG (4, "send_gamma: done\n");
966   return status;
967 }
968 
969 
970 static SANE_Status
start_scan(Ma1509_Scanner * s)971 start_scan (Ma1509_Scanner * s)
972 {
973   SANE_Byte cmd[8];
974   SANE_Status status;
975 
976   DBG (4, "start_scan\n");
977   memset (cmd, 0, 8);
978 
979   cmd[0] = 0x1b;
980   cmd[1] = 0x01;
981   cmd[2] = 0x01;
982 
983   status = ma1509_cmd (s, cmd, NULL, NULL);
984   if (status != SANE_STATUS_GOOD)
985     {
986       DBG (1, "start_scan: ma1509_cmd failed: %s\n", sane_strstatus (status));
987       return status;
988     }
989   return status;
990 }
991 
992 static SANE_Status
turn_lamp(Ma1509_Scanner * s,SANE_Bool is_on)993 turn_lamp (Ma1509_Scanner * s, SANE_Bool is_on)
994 {
995   SANE_Status status;
996   SANE_Byte buffer[0x30];
997   size_t size = sizeof (buffer);
998   struct timeval lamp_time;
999 
1000   DBG (4, "turn_lamp %s\n", is_on ? "on" : "off");
1001   memset (buffer, 0, size);
1002   if (is_on)
1003     buffer[0x28] = 0x01;
1004   else
1005     buffer[0x28] = 0x02;
1006 
1007   status = ma1509_cmd (s, scsi_set_window, buffer, &size);
1008   if (status != SANE_STATUS_GOOD)
1009     {
1010       DBG (1, "turn_lamp: ma1509_cmd set_window failed: %s\n",
1011 	   sane_strstatus (status));
1012       return status;
1013     }
1014   gettimeofday (&lamp_time, 0);
1015   s->lamp_time = lamp_time.tv_sec;
1016   return status;
1017 }
1018 
1019 static SANE_Status
stop_scan(Ma1509_Scanner * s)1020 stop_scan (Ma1509_Scanner * s)
1021 {
1022   SANE_Byte cmd[8];
1023   SANE_Status status;
1024 
1025   DBG (4, "stop_scan\n");
1026   memset (cmd, 0, 8);
1027 
1028   cmd[0] = 0x1b;
1029   cmd[1] = 0x01;
1030   cmd[2] = 0x00;
1031 
1032   status = ma1509_cmd (s, cmd, NULL, NULL);
1033   if (status != SANE_STATUS_GOOD)
1034     {
1035       DBG (1, "stop_scan: ma1509_cmd failed: %s\n", sane_strstatus (status));
1036       return status;
1037     }
1038 
1039   DBG (4, "stop_scan: scan stopped\n");
1040   return status;
1041 }
1042 
1043 
1044 static SANE_Status
start_read_data(Ma1509_Scanner * s)1045 start_read_data (Ma1509_Scanner * s)
1046 {
1047   SANE_Byte cmd[8];
1048   SANE_Status status;
1049   SANE_Int total_size = s->hw->ppl * s->hw->lines;
1050 
1051   if (strcmp (s->val[OPT_MODE].s, SANE_VALUE_SCAN_MODE_LINEART) == 0)
1052     total_size /= 8;
1053 
1054   memset (cmd, 0, 8);
1055 
1056   cmd[0] = 0x28;		/* read data */
1057   cmd[1] = 0x01;		/* read */
1058   cmd[2] = 0x00;		/* scan data */
1059   cmd[3] = (total_size >> 24) & 0xff;
1060   cmd[4] = (total_size >> 16) & 0xff;
1061   cmd[5] = (total_size >> 8) & 0xff;
1062   cmd[6] = total_size & 0xff;
1063   status = ma1509_cmd (s, cmd, NULL, NULL);
1064   if (status != SANE_STATUS_GOOD)
1065     {
1066       DBG (1, "stop_scan: ma1509_cmd failed: %s\n", sane_strstatus (status));
1067       return status;
1068     }
1069   return status;
1070 }
1071 
1072 static SANE_Status
read_data(Ma1509_Scanner * s,SANE_Byte * buffer,SANE_Int * size)1073 read_data (Ma1509_Scanner * s, SANE_Byte * buffer, SANE_Int * size)
1074 {
1075   size_t local_size = *size;
1076   SANE_Status status;
1077 
1078   status = sanei_usb_read_bulk (s->fd, buffer, &local_size);
1079   if (status != SANE_STATUS_GOOD)
1080     {
1081       DBG (1, "read_data: sanei_usb_read_bulk failed: %s\n",
1082 	   sane_strstatus (status));
1083       return status;
1084     }
1085   *size = local_size;
1086   return status;
1087 }
1088 
1089 
1090 
1091 
1092 /**************************************************************************/
1093 /*                            SANE API calls                              */
1094 /**************************************************************************/
1095 
1096 SANE_Status
sane_init(SANE_Int * version_code,SANE_Auth_Callback authorize)1097 sane_init (SANE_Int * version_code, SANE_Auth_Callback authorize)
1098 {
1099   SANE_Char line[PATH_MAX], *word, *end;
1100   SANE_String_Const cp;
1101   SANE_Int linenumber;
1102   FILE *fp;
1103 
1104   DBG_INIT ();
1105 
1106 #ifdef DBG_LEVEL
1107   debug_level = DBG_LEVEL;
1108 #else
1109   debug_level = 0;
1110 #endif
1111 
1112   DBG (2, "SANE ma1509 backend version %d.%d build %d from %s\n", SANE_CURRENT_MAJOR,
1113        SANE_CURRENT_MINOR, BUILD, PACKAGE_STRING);
1114 
1115   if (version_code)
1116     *version_code = SANE_VERSION_CODE (SANE_CURRENT_MAJOR, SANE_CURRENT_MINOR, BUILD);
1117 
1118   DBG (4, "sane_init: authorize %s null\n", authorize ? "!=" : "==");
1119 
1120   sanei_usb_init ();
1121 
1122   num_devices = 0;
1123   first_dev = 0;
1124   first_handle = 0;
1125   devlist = 0;
1126   new_dev = 0;
1127   new_dev_len = 0;
1128   new_dev_alloced = 0;
1129 
1130   fp = sanei_config_open (MA1509_CONFIG_FILE);
1131   if (!fp)
1132     {
1133       /* default to /dev/usb/scanner0 instead of insisting on config file */
1134       DBG (3, "sane_init: couldn't find config file (%s), trying "
1135 	   "/dev/usb/scanner0 directly\n", MA1509_CONFIG_FILE);
1136       attach ("/dev/usb/scanner0", 0);
1137       return SANE_STATUS_GOOD;
1138     }
1139   linenumber = 0;
1140   DBG (4, "sane_init: reading config file `%s'\n", MA1509_CONFIG_FILE);
1141   while (sanei_config_read (line, sizeof (line), fp))
1142     {
1143       word = 0;
1144       linenumber++;
1145 
1146       cp = sanei_config_get_string (line, &word);
1147       if (!word || cp == line)
1148 	{
1149 	  DBG (5, "sane_init: config file line %d: ignoring empty line\n",
1150 	       linenumber);
1151 	  if (word)
1152 	    free (word);
1153 	  continue;
1154 	}
1155       if (word[0] == '#')
1156 	{
1157 	  DBG (5, "sane_init: config file line %d: ignoring comment line\n",
1158 	       linenumber);
1159 	  free (word);
1160 	  continue;
1161 	}
1162       if (strcmp (word, "option") == 0)
1163 	{
1164 	  free (word);
1165 	  word = 0;
1166 	  cp = sanei_config_get_string (cp, &word);
1167 
1168 	  if (!word)
1169 	    {
1170 	      DBG (1, "sane_init: config file line %d: missing quotation mark?\n",
1171 		   linenumber);
1172 	      continue;
1173 	    }
1174 
1175 	  if (strcmp (word, "warmup-time") == 0)
1176 	    {
1177 	      long local_warmup_time;
1178 
1179 	      free (word);
1180 	      word = 0;
1181 	      cp = sanei_config_get_string (cp, &word);
1182 
1183 	      if (!word)
1184 		{
1185 		  DBG (1, "sane_init: config file line %d: missing quotation mark?\n",
1186 		       linenumber);
1187 		  continue;
1188 		}
1189 
1190 	      errno = 0;
1191 	      local_warmup_time = strtol (word, &end, 0);
1192 
1193 	      if (end == word)
1194 		{
1195 		  DBG (3, "sane-init: config file line %d: warmup-time must "
1196 		       "have a parameter; using default (%d)\n",
1197 		       linenumber, warmup_time);
1198 		}
1199 	      else if (errno)
1200 		{
1201 		  DBG (3, "sane-init: config file line %d: warmup-time `%s' "
1202 		       "is invalid (%s); using default (%d)\n", linenumber,
1203 		       word, strerror (errno), warmup_time);
1204 		}
1205 	      else
1206 		{
1207 		  warmup_time = local_warmup_time;
1208 		  DBG (4,
1209 		       "sane_init: config file line %d: warmup-time set "
1210 		       "to %d seconds\n", linenumber, warmup_time);
1211 
1212 		}
1213 	      if (word)
1214 		free (word);
1215 	      word = 0;
1216 	    }
1217 	  else
1218 	    {
1219 	      DBG (3, "sane_init: config file line %d: ignoring unknown "
1220 		   "option `%s'\n", linenumber, word);
1221 	      if (word)
1222 		free (word);
1223 	      word = 0;
1224 	    }
1225 	}
1226       else
1227 	{
1228 	  new_dev_len = 0;
1229 	  DBG (4, "sane_init: config file line %d: trying to attach `%s'\n",
1230 	       linenumber, line);
1231 	  sanei_usb_attach_matching_devices (line, attach_one_device);
1232 	  if (word)
1233 	    free (word);
1234 	  word = 0;
1235 	}
1236     }
1237 
1238   if (new_dev_alloced > 0)
1239     {
1240       new_dev_len = new_dev_alloced = 0;
1241       free (new_dev);
1242     }
1243   fclose (fp);
1244   return SANE_STATUS_GOOD;
1245 }
1246 
1247 void
sane_exit(void)1248 sane_exit (void)
1249 {
1250   Ma1509_Device *dev, *next;
1251 
1252   DBG (4, "sane_exit\n");
1253   for (dev = first_dev; dev; dev = next)
1254     {
1255       next = dev->next;
1256       free (dev->name);
1257       free (dev);
1258     }
1259   if (devlist)
1260     free (devlist);
1261   devlist = 0;
1262   first_dev = 0;
1263 }
1264 
1265 SANE_Status
sane_get_devices(const SANE_Device *** device_list,SANE_Bool local_only)1266 sane_get_devices (const SANE_Device *** device_list, SANE_Bool local_only)
1267 {
1268   Ma1509_Device *dev;
1269   SANE_Int i;
1270 
1271   DBG (4, "sane_get_devices: %d devices %s\n", num_devices,
1272        local_only ? "(local only)" : "");
1273   if (devlist)
1274     free (devlist);
1275 
1276   devlist = malloc ((num_devices + 1) * sizeof (devlist[0]));
1277   if (!devlist)
1278     return SANE_STATUS_NO_MEM;
1279 
1280   i = 0;
1281   for (dev = first_dev; i < num_devices; dev = dev->next)
1282     devlist[i++] = &dev->sane;
1283   devlist[i++] = 0;
1284 
1285   *device_list = devlist;
1286   DBG (5, "sane_get_devices: end\n");
1287   return SANE_STATUS_GOOD;
1288 }
1289 
1290 SANE_Status
sane_open(SANE_String_Const devicename,SANE_Handle * handle)1291 sane_open (SANE_String_Const devicename, SANE_Handle * handle)
1292 {
1293   Ma1509_Device *dev;
1294   SANE_Status status;
1295   Ma1509_Scanner *s;
1296 
1297   if (!devicename)
1298     {
1299       DBG (1, "sane_open: devicename is null!\n");
1300       return SANE_STATUS_INVAL;
1301     }
1302   if (!handle)
1303     {
1304       DBG (1, "sane_open: handle is null!\n");
1305       return SANE_STATUS_INVAL;
1306     }
1307   DBG (4, "sane_open: devicename=%s\n", devicename);
1308 
1309   if (devicename[0])
1310     {
1311       for (dev = first_dev; dev; dev = dev->next)
1312 	if (strcmp (dev->sane.name, devicename) == 0)
1313 	  break;
1314 
1315       if (!dev)
1316 	{
1317 	  status = attach (devicename, &dev);
1318 	  if (status != SANE_STATUS_GOOD)
1319 	    return status;
1320 	}
1321     }
1322   else
1323     /* empty devicname -> use first device */
1324     dev = first_dev;
1325 
1326   if (!dev)
1327     {
1328       DBG (1, "sane_open: %s doesn't seem to exist\n", devicename);
1329       return SANE_STATUS_INVAL;
1330     }
1331 
1332   s = malloc (sizeof (*s));
1333   if (!s)
1334     return SANE_STATUS_NO_MEM;
1335   memset (s, 0, sizeof (*s));
1336   s->fd = -1;
1337   s->hw = dev;
1338   init_options (s);
1339 
1340   /* insert newly opened handle into list of open handles: */
1341   s->next = first_handle;
1342   first_handle = s;
1343 
1344   status = sanei_usb_open (s->hw->sane.name, &s->fd);
1345   if (status != SANE_STATUS_GOOD)
1346     {
1347       DBG (1, "sane_open: couldn't open %s: %s\n", s->hw->sane.name,
1348 	   sane_strstatus (status));
1349       return status;
1350     }
1351 
1352   status = turn_lamp (s, SANE_TRUE);
1353   if (status != SANE_STATUS_GOOD)
1354     {
1355       DBG (1, "sane_open: couldn't turn on lamp: %s\n",
1356 	   sane_strstatus (status));
1357       return status;
1358     }
1359 
1360   status = turn_lamp (s, SANE_TRUE);
1361   if (status != SANE_STATUS_GOOD)
1362     {
1363       DBG (1, "sane_open: couldn't turn on lamp: %s\n",
1364 	   sane_strstatus (status));
1365       return status;
1366     }
1367 
1368   *handle = s;
1369   DBG (5, "sane_open: finished (handle=%p)\n", (void *) s);
1370   return SANE_STATUS_GOOD;
1371 }
1372 
1373 void
sane_close(SANE_Handle handle)1374 sane_close (SANE_Handle handle)
1375 {
1376   Ma1509_Scanner *prev, *s;
1377   SANE_Status status;
1378 
1379   DBG (4, "sane_close: handle=%p\n", handle);
1380 
1381   /* remove handle from list of open handles: */
1382   prev = 0;
1383   for (s = first_handle; s; s = s->next)
1384     {
1385       if (s == handle)
1386 	break;
1387       prev = s;
1388     }
1389   if (!s)
1390     {
1391       DBG (1, "sane_close: invalid handle %p\n", handle);
1392       return;			/* oops, not a handle we know about */
1393     }
1394 
1395   if (s->val[OPT_MODE].s)
1396     free (s->val[OPT_MODE].s);
1397   if (s->val[OPT_SOURCE].s)
1398     free (s->val[OPT_SOURCE].s);
1399 
1400   status = turn_lamp (s, SANE_FALSE);
1401   if (status != SANE_STATUS_GOOD)
1402     {
1403       DBG (1, "sane_close: couldn't turn off lamp: %s\n",
1404 	   sane_strstatus (status));
1405       return;
1406     }
1407   sanei_usb_close (s->fd);
1408 
1409   if (prev)
1410     prev->next = s->next;
1411   else
1412     first_handle = s->next;
1413   free (handle);
1414   handle = 0;
1415 }
1416 
1417 const SANE_Option_Descriptor *
sane_get_option_descriptor(SANE_Handle handle,SANE_Int option)1418 sane_get_option_descriptor (SANE_Handle handle, SANE_Int option)
1419 {
1420   Ma1509_Scanner *s = handle;
1421 
1422   if (((unsigned) option >= NUM_OPTIONS) || (option < 0))
1423     {
1424       DBG (3, "sane_get_option_descriptor: option %d >= NUM_OPTIONS or < 0\n",
1425 	   option);
1426       return 0;
1427     }
1428   if (!s)
1429     {
1430       DBG (1, "sane_get_option_descriptor: handle is null!\n");
1431       return 0;
1432     }
1433   if (s->opt[option].name && s->opt[option].name[0] != 0)
1434     DBG (4, "sane_get_option_descriptor for option %s (%sactive%s)\n",
1435 	 s->opt[option].name,
1436 	 s->opt[option].cap & SANE_CAP_INACTIVE ? "in" : "",
1437 	 s->opt[option].cap & SANE_CAP_ADVANCED ? ", advanced" : "");
1438   else
1439     DBG (4, "sane_get_option_descriptor for option \"%s\" (%sactive%s)\n",
1440 	 s->opt[option].title,
1441 	 s->opt[option].cap & SANE_CAP_INACTIVE ? "in" : "",
1442 	 s->opt[option].cap & SANE_CAP_ADVANCED ? ", advanced" : "");
1443   return s->opt + option;
1444 }
1445 
1446 SANE_Status
sane_control_option(SANE_Handle handle,SANE_Int option,SANE_Action action,void * val,SANE_Int * info)1447 sane_control_option (SANE_Handle handle, SANE_Int option,
1448 		     SANE_Action action, void *val, SANE_Int * info)
1449 {
1450   Ma1509_Scanner *s = handle;
1451   SANE_Status status;
1452   SANE_Word cap;
1453   SANE_Word w;
1454 
1455   if (((unsigned) option >= NUM_OPTIONS) || (option < 0))
1456     {
1457       DBG (3, "sane_control_option: option %d < 0 or >= NUM_OPTIONS\n",
1458 	   option);
1459       return SANE_STATUS_INVAL;
1460     }
1461   if (!s)
1462     {
1463       DBG (1, "sane_control_option: handle is null!\n");
1464       return SANE_STATUS_INVAL;
1465     }
1466   if (!val && s->opt[option].type != SANE_TYPE_BUTTON)
1467     {
1468       DBG (1, "sane_control_option: val is null!\n");
1469       return SANE_STATUS_INVAL;
1470     }
1471 
1472   if (s->opt[option].name && s->opt[option].name[0] != 0)
1473     DBG (4, "sane_control_option (%s option %s)\n",
1474 	 action == SANE_ACTION_GET_VALUE ? "get" :
1475 	 (action == SANE_ACTION_SET_VALUE ? "set" : "unknown action with"),
1476 	 s->opt[option].name);
1477   else
1478     DBG (4, "sane_control_option (%s option \"%s\")\n",
1479 	 action == SANE_ACTION_GET_VALUE ? "get" :
1480 	 (action == SANE_ACTION_SET_VALUE ? "set" : "unknown action with"),
1481 	 s->opt[option].title);
1482 
1483   if (info)
1484     *info = 0;
1485 
1486   if (s->scanning)
1487     {
1488       DBG (3, "sane_control_option: don't use while scanning (option %s)\n",
1489 	   s->opt[option].name);
1490       return SANE_STATUS_DEVICE_BUSY;
1491     }
1492 
1493   cap = s->opt[option].cap;
1494 
1495   if (!SANE_OPTION_IS_ACTIVE (cap))
1496     {
1497       DBG (3, "sane_control_option: option %s is inactive\n",
1498 	   s->opt[option].name);
1499       return SANE_STATUS_INVAL;
1500     }
1501 
1502   if (action == SANE_ACTION_GET_VALUE)
1503     {
1504       switch (option)
1505 	{
1506 	  /* word options: */
1507 	case OPT_PREVIEW:
1508 	case OPT_RESOLUTION:
1509 	case OPT_TL_X:
1510 	case OPT_TL_Y:
1511 	case OPT_BR_X:
1512 	case OPT_BR_Y:
1513 	case OPT_THRESHOLD:
1514 	case OPT_CUSTOM_GAMMA:
1515 	case OPT_NUM_OPTS:
1516 	  *(SANE_Word *) val = s->val[option].w;
1517 	  return SANE_STATUS_GOOD;
1518 
1519 	  /* word-array options: */
1520 	case OPT_GAMMA_VECTOR_R:
1521 	case OPT_GAMMA_VECTOR_G:
1522 	case OPT_GAMMA_VECTOR_B:
1523 	  memcpy (val, s->val[option].wa, s->opt[option].size);
1524 	  return SANE_STATUS_GOOD;
1525 
1526 	  /* string options: */
1527 	case OPT_SOURCE:
1528 	case OPT_MODE:
1529 	  strcpy (val, s->val[option].s);
1530 	  return SANE_STATUS_GOOD;
1531 	}
1532     }
1533   else if (action == SANE_ACTION_SET_VALUE)
1534     {
1535       if (!SANE_OPTION_IS_SETTABLE (cap))
1536 	{
1537 	  DBG (3, "sane_control_option: option %s is not setable\n",
1538 	       s->opt[option].name);
1539 	  return SANE_STATUS_INVAL;
1540 	}
1541 
1542       status = sanei_constrain_value (s->opt + option, val, info);
1543       if (status != SANE_STATUS_GOOD)
1544 	{
1545 	  DBG (4, "sane_control_option: constrain_value error (option %s)\n",
1546 	       s->opt[option].name);
1547 	  return status;
1548 	}
1549 
1550       switch (option)
1551 	{
1552 	  /* (mostly) side-effect-free word options: */
1553 	case OPT_RESOLUTION:
1554 	case OPT_TL_X:
1555 	case OPT_BR_X:
1556 	case OPT_TL_Y:
1557 	case OPT_BR_Y:
1558 	  if (info)
1559 	    *info |= SANE_INFO_RELOAD_PARAMS;
1560 	  /* fall through */
1561 	case OPT_THRESHOLD:
1562 	case OPT_PREVIEW:
1563 	  s->val[option].w = *(SANE_Word *) val;
1564 	  return SANE_STATUS_GOOD;
1565 
1566 	  /* side-effect-free word-array options: */
1567 	case OPT_GAMMA_VECTOR_R:
1568 	case OPT_GAMMA_VECTOR_G:
1569 	case OPT_GAMMA_VECTOR_B:
1570 	  memcpy (s->val[option].wa, val, s->opt[option].size);
1571 	  return SANE_STATUS_GOOD;
1572 
1573 	case OPT_MODE:
1574 	  {
1575 	    SANE_Char *old_val = s->val[option].s;
1576 
1577 	    if (old_val)
1578 	      {
1579 		if (strcmp (old_val, val) == 0)
1580 		  return SANE_STATUS_GOOD;	/* no change */
1581 		free (old_val);
1582 	      }
1583 	    if (info)
1584 	      *info |= SANE_INFO_RELOAD_OPTIONS | SANE_INFO_RELOAD_PARAMS;
1585 
1586 	    s->val[option].s = strdup (val);
1587 	    if (!s->val[option].s)
1588 	      return SANE_STATUS_NO_MEM;
1589 
1590 	    s->opt[OPT_GAMMA_VECTOR_R].cap |= SANE_CAP_INACTIVE;
1591 	    s->opt[OPT_GAMMA_VECTOR_G].cap |= SANE_CAP_INACTIVE;
1592 	    s->opt[OPT_GAMMA_VECTOR_B].cap |= SANE_CAP_INACTIVE;
1593 	    s->opt[OPT_CUSTOM_GAMMA].cap |= SANE_CAP_INACTIVE;
1594 	    s->opt[OPT_THRESHOLD].cap |= SANE_CAP_INACTIVE;
1595 
1596 	    if (strcmp (s->val[option].s, SANE_VALUE_SCAN_MODE_LINEART) == 0)
1597 	      {
1598 		s->opt[OPT_THRESHOLD].cap &= ~SANE_CAP_INACTIVE;
1599 	      }
1600 	    else
1601 	      {
1602 		s->opt[OPT_CUSTOM_GAMMA].cap &= ~SANE_CAP_INACTIVE;
1603 		if (s->val[OPT_CUSTOM_GAMMA].w)
1604 		  {
1605 		    s->opt[OPT_GAMMA_VECTOR_R].cap &= ~SANE_CAP_INACTIVE;
1606 		    s->opt[OPT_GAMMA_VECTOR_G].cap &= ~SANE_CAP_INACTIVE;
1607 		    s->opt[OPT_GAMMA_VECTOR_B].cap &= ~SANE_CAP_INACTIVE;
1608 		  }
1609 	      }
1610 	    return SANE_STATUS_GOOD;
1611 	  }
1612 
1613 	case OPT_SOURCE:
1614 	  if (info)
1615 	    *info |= SANE_INFO_RELOAD_OPTIONS;
1616 	  if (s->val[option].s)
1617 	    free (s->val[option].s);
1618 	  s->val[option].s = strdup (val);
1619 	  if (!s->val[option].s)
1620 	    return SANE_STATUS_NO_MEM;
1621 
1622 	  if (strcmp (val, "Transparency Adapter") == 0)
1623 	    {
1624 	      s->opt[OPT_TL_X].constraint.range = &s->hw->x_trans_range;
1625 	      s->opt[OPT_TL_Y].constraint.range = &s->hw->y_trans_range;
1626 	      s->opt[OPT_BR_X].constraint.range = &s->hw->x_trans_range;
1627 	      s->opt[OPT_BR_Y].constraint.range = &s->hw->y_trans_range;
1628 	    }
1629 	  else
1630 	    {
1631 	      s->opt[OPT_TL_X].constraint.range = &s->hw->x_range;
1632 	      s->opt[OPT_TL_Y].constraint.range = &s->hw->y_range;
1633 	      s->opt[OPT_BR_X].constraint.range = &s->hw->x_range;
1634 	      s->opt[OPT_BR_Y].constraint.range = &s->hw->y_range;
1635 	    }
1636 	  return SANE_STATUS_GOOD;
1637 
1638 	  /* options with side-effects: */
1639 	case OPT_CUSTOM_GAMMA:
1640 	  w = *(SANE_Word *) val;
1641 
1642 	  if (w == s->val[OPT_CUSTOM_GAMMA].w)
1643 	    return SANE_STATUS_GOOD;	/* no change */
1644 
1645 	  if (info)
1646 	    *info |= SANE_INFO_RELOAD_OPTIONS;
1647 
1648 	  s->val[OPT_CUSTOM_GAMMA].w = w;
1649 
1650 	  s->opt[OPT_GAMMA_VECTOR_R].cap |= SANE_CAP_INACTIVE;
1651 	  s->opt[OPT_GAMMA_VECTOR_G].cap |= SANE_CAP_INACTIVE;
1652 	  s->opt[OPT_GAMMA_VECTOR_B].cap |= SANE_CAP_INACTIVE;
1653 
1654 	  if (w && strcmp (s->val[OPT_MODE].s, SANE_VALUE_SCAN_MODE_LINEART) != 0)
1655 	    {
1656 	      s->opt[OPT_GAMMA_VECTOR_R].cap &= ~SANE_CAP_INACTIVE;
1657 	      s->opt[OPT_GAMMA_VECTOR_G].cap &= ~SANE_CAP_INACTIVE;
1658 	      s->opt[OPT_GAMMA_VECTOR_B].cap &= ~SANE_CAP_INACTIVE;
1659 	    }
1660 	  return SANE_STATUS_GOOD;
1661 	}
1662 
1663     }
1664   DBG (4, "sane_control_option: unknown action for option %s\n",
1665        s->opt[option].name);
1666   return SANE_STATUS_INVAL;
1667 }
1668 
1669 SANE_Status
sane_get_parameters(SANE_Handle handle,SANE_Parameters * params)1670 sane_get_parameters (SANE_Handle handle, SANE_Parameters * params)
1671 {
1672   Ma1509_Scanner *s = handle;
1673   SANE_String_Const mode;
1674 
1675   if (!s)
1676     {
1677       DBG (1, "sane_get_parameters: handle is null!\n");
1678       return SANE_STATUS_INVAL;
1679     }
1680 
1681   if (!s->scanning)
1682     {
1683       double width, height, dpi;
1684 
1685       memset (&s->params, 0, sizeof (s->params));
1686 
1687       width = SANE_UNFIX (s->val[OPT_BR_X].w - s->val[OPT_TL_X].w);
1688       height = SANE_UNFIX (s->val[OPT_BR_Y].w - s->val[OPT_TL_Y].w);
1689       dpi = s->val[OPT_RESOLUTION].w;
1690 
1691       /* make best-effort guess at what parameters will look like once
1692          scanning starts.  */
1693       if (dpi > 0.0 && width > 0.0 && height > 0.0)
1694 	{
1695 	  double dots_per_mm = dpi / MM_PER_INCH;
1696 
1697 	  s->params.pixels_per_line = width * dots_per_mm;
1698 	  s->params.lines = height * dots_per_mm;
1699 	}
1700       mode = s->val[OPT_MODE].s;
1701       if (strcmp (mode, SANE_VALUE_SCAN_MODE_LINEART) == 0)
1702 	{
1703 	  s->params.format = SANE_FRAME_GRAY;
1704 	  s->params.bytes_per_line = (s->params.pixels_per_line + 7) / 8;
1705 	  s->params.depth = 1;
1706 	}
1707       else if (strcmp (mode, SANE_VALUE_SCAN_MODE_GRAY) == 0)
1708 	{
1709 	  s->params.format = SANE_FRAME_GRAY;
1710 	  s->params.bytes_per_line = s->params.pixels_per_line;
1711 	  s->params.depth = 8;
1712 	}
1713       else
1714 	{
1715 	  /* it's one of the color modes... */
1716 
1717 	  s->params.bytes_per_line = 3 * s->params.pixels_per_line;
1718 	  s->params.depth = 8;
1719 	  s->params.format = SANE_FRAME_RGB;
1720 	}
1721     }
1722   s->params.last_frame = SANE_TRUE;
1723   if (params)
1724     *params = s->params;
1725   DBG (4, "sane_get_parameters: frame = %d; last_frame = %s; depth = %d\n",
1726        s->params.format, s->params.last_frame ? "true" : "false",
1727        s->params.depth);
1728   DBG (4, "sane_get_parameters: lines = %d; ppl = %d; bpl = %d\n",
1729        s->params.lines, s->params.pixels_per_line, s->params.bytes_per_line);
1730 
1731   return SANE_STATUS_GOOD;
1732 }
1733 
1734 SANE_Status
sane_start(SANE_Handle handle)1735 sane_start (SANE_Handle handle)
1736 {
1737   Ma1509_Scanner *s = handle;
1738   SANE_Status status;
1739   struct timeval start;
1740 
1741   if (!s)
1742     {
1743       DBG (1, "sane_start: handle is null!\n");
1744       return SANE_STATUS_INVAL;
1745     }
1746 
1747   DBG (4, "sane_start\n");
1748 
1749   status = sane_get_parameters (s, 0);
1750   if (status != SANE_STATUS_GOOD)
1751     return status;
1752 
1753   /* Check for inconsistencies */
1754 
1755   if (s->val[OPT_TL_X].w > s->val[OPT_BR_X].w)
1756     {
1757       DBG (0, "sane_start: %s (%.1f mm) is bigger than %s (%.1f mm) "
1758 	   "-- aborting\n",
1759 	   s->opt[OPT_TL_X].title, SANE_UNFIX (s->val[OPT_TL_X].w),
1760 	   s->opt[OPT_BR_X].title, SANE_UNFIX (s->val[OPT_BR_X].w));
1761       return SANE_STATUS_INVAL;
1762     }
1763   if (s->val[OPT_TL_Y].w > s->val[OPT_BR_Y].w)
1764     {
1765       DBG (0, "sane_start: %s (%.1f mm) is bigger than %s (%.1f mm) "
1766 	   "-- aborting\n",
1767 	   s->opt[OPT_TL_Y].title, SANE_UNFIX (s->val[OPT_TL_Y].w),
1768 	   s->opt[OPT_BR_Y].title, SANE_UNFIX (s->val[OPT_BR_Y].w));
1769       return SANE_STATUS_INVAL;
1770     }
1771 
1772   s->total_bytes = 0;
1773   s->read_bytes = 0;
1774 
1775   /* save start time */
1776   gettimeofday (&start, 0);
1777   s->start_time = start.tv_sec;
1778 
1779   status = set_window (s);
1780   if (status != SANE_STATUS_GOOD)
1781     {
1782       DBG (1, "sane_start: set window command failed: %s\n",
1783 	   sane_strstatus (status));
1784       goto stop_scanner_and_return;
1785     }
1786 
1787   status = test_unit_ready (s);
1788   if (status != SANE_STATUS_GOOD)
1789     {
1790       DBG (1, "sane_start: test_unit_ready failed: %s\n",
1791 	   sane_strstatus (status));
1792       goto stop_scanner_and_return;
1793     }
1794 
1795   if (strcmp (s->val[OPT_MODE].s, SANE_VALUE_SCAN_MODE_LINEART) != 0)
1796     {
1797       status = calibration (s);
1798       if (status != SANE_STATUS_GOOD)
1799 	{
1800 	  DBG (1, "sane_start: calibration failed: %s\n",
1801 	       sane_strstatus (status));
1802 	  goto stop_scanner_and_return;
1803 	}
1804 
1805       status = send_gamma (s);
1806       if (status != SANE_STATUS_GOOD)
1807 	{
1808 	  DBG (1, "sane_start: send_gamma failed: %s\n",
1809 	       sane_strstatus (status));
1810 	  goto stop_scanner_and_return;
1811 	}
1812     }
1813 
1814   s->scanning = SANE_TRUE;
1815   s->cancelled = SANE_FALSE;
1816 
1817   status = start_scan (s);
1818   if (status != SANE_STATUS_GOOD)
1819     {
1820       DBG (1, "sane_start: start_scan command failed: %s\n",
1821 	   sane_strstatus (status));
1822       goto stop_scanner_and_return;
1823     }
1824 
1825   status = start_read_data (s);
1826   if (status != SANE_STATUS_GOOD)
1827     {
1828       DBG (1, "sane_start: start_read_data command failed: %s\n",
1829 	   sane_strstatus (status));
1830       goto stop_scanner_and_return;
1831     }
1832 
1833   s->params.bytes_per_line = s->hw->bpl;
1834   s->params.pixels_per_line = s->params.bytes_per_line;
1835   if (strcmp (s->val[OPT_MODE].s, SANE_VALUE_SCAN_MODE_COLOR) == 0)
1836     s->params.pixels_per_line /= 3;
1837   else if (strcmp (s->val[OPT_MODE].s, SANE_VALUE_SCAN_MODE_LINEART) == 0)
1838     s->params.pixels_per_line *= 8;
1839 
1840   s->params.lines = s->hw->lines;
1841 
1842   s->buffer = (SANE_Byte *) malloc (MA1509_BUFFER_SIZE);
1843   if (!s->buffer)
1844     return SANE_STATUS_NO_MEM;
1845   s->buffer_bytes = 0;
1846 
1847   DBG (5, "sane_start: finished\n");
1848   return SANE_STATUS_GOOD;
1849 
1850 stop_scanner_and_return:
1851   sanei_usb_close (s->fd);
1852   s->scanning = SANE_FALSE;
1853   return status;
1854 }
1855 
1856 SANE_Status
sane_read(SANE_Handle handle,SANE_Byte * buf,SANE_Int max_len,SANE_Int * len)1857 sane_read (SANE_Handle handle, SANE_Byte * buf, SANE_Int max_len,
1858 	   SANE_Int * len)
1859 {
1860   Ma1509_Scanner *s = handle;
1861   SANE_Status status;
1862   SANE_Int total_size = s->hw->lines * s->hw->bpl;
1863   SANE_Int i;
1864 
1865   if (!s)
1866     {
1867       DBG (1, "sane_read: handle is null!\n");
1868       return SANE_STATUS_INVAL;
1869     }
1870 
1871   if (!buf)
1872     {
1873       DBG (1, "sane_read: buf is null!\n");
1874       return SANE_STATUS_INVAL;
1875     }
1876 
1877   if (!len)
1878     {
1879       DBG (1, "sane_read: len is null!\n");
1880       return SANE_STATUS_INVAL;
1881     }
1882 
1883   DBG (5, "sane_read\n");
1884   *len = 0;
1885 
1886   if (s->cancelled)
1887     {
1888       DBG (4, "sane_read: scan was cancelled\n");
1889       return SANE_STATUS_CANCELLED;
1890     }
1891 
1892   if (!s->scanning)
1893     {
1894       DBG (1, "sane_read: must call sane_start before sane_read\n");
1895       return SANE_STATUS_INVAL;
1896     }
1897 
1898   if (total_size - s->read_bytes <= 0)
1899     {
1900       DBG (4, "sane_read: EOF\n");
1901       stop_scan (s);
1902       s->scanning = SANE_FALSE;
1903       return SANE_STATUS_EOF;
1904     }
1905 
1906   if (s->buffer_bytes == 0)
1907     {
1908       SANE_Int size = MA1509_BUFFER_SIZE;
1909       if (size > (total_size - s->total_bytes))
1910 	size = total_size - s->total_bytes;
1911       DBG (4, "sane_read: trying to read %d bytes\n", size);
1912       status = read_data (s, s->buffer, &size);
1913       if (status != SANE_STATUS_GOOD)
1914 	{
1915 	  DBG (1, "sane_read: read_data failed: %s\n",
1916 	       sane_strstatus (status));
1917 	  *len = 0;
1918 	  return status;
1919 	}
1920       s->total_bytes += size;
1921       s->buffer_start = s->buffer;
1922       s->buffer_bytes = size;
1923     }
1924 
1925   *len = max_len;
1926   if (*len > s->buffer_bytes)
1927     *len = s->buffer_bytes;
1928 
1929   memcpy (buf, s->buffer_start, *len);
1930   s->buffer_start += (*len);
1931   s->buffer_bytes -= (*len);
1932   s->read_bytes += (*len);
1933 
1934   /* invert for lineart mode */
1935   if (strcmp (s->val[OPT_MODE].s, SANE_VALUE_SCAN_MODE_LINEART) == 0)
1936     {
1937       for (i = 0; i < *len; i++)
1938 	buf[i] = ~buf[i];
1939     }
1940 
1941   DBG (4, "sane_read: read %d/%d bytes (%d bytes to go, %d total)\n", *len,
1942        max_len, total_size - s->read_bytes, total_size);
1943 
1944   return SANE_STATUS_GOOD;
1945 }
1946 
1947 void
sane_cancel(SANE_Handle handle)1948 sane_cancel (SANE_Handle handle)
1949 {
1950   Ma1509_Scanner *s = handle;
1951 
1952   if (!s)
1953     {
1954       DBG (1, "sane_cancel: handle is null!\n");
1955       return;
1956     }
1957 
1958   DBG (4, "sane_cancel\n");
1959   if (s->scanning)
1960     {
1961       s->cancelled = SANE_TRUE;
1962       stop_scan (s);
1963       free (s->buffer);
1964     }
1965   s->scanning = SANE_FALSE;
1966   DBG (4, "sane_cancel finished\n");
1967 }
1968 
1969 SANE_Status
sane_set_io_mode(SANE_Handle handle,SANE_Bool non_blocking)1970 sane_set_io_mode (SANE_Handle handle, SANE_Bool non_blocking)
1971 {
1972   Ma1509_Scanner *s = handle;
1973 
1974   if (!s)
1975     {
1976       DBG (1, "sane_set_io_mode: handle is null!\n");
1977       return SANE_STATUS_INVAL;
1978     }
1979 
1980   DBG (4, "sane_set_io_mode: %s\n",
1981        non_blocking ? "non-blocking" : "blocking");
1982 
1983   if (!s->scanning)
1984     {
1985       DBG (1, "sane_set_io_mode: call sane_start before sane_set_io_mode");
1986       return SANE_STATUS_INVAL;
1987     }
1988 
1989   if (non_blocking)
1990     return SANE_STATUS_UNSUPPORTED;
1991   return SANE_STATUS_GOOD;
1992 }
1993 
1994 SANE_Status
sane_get_select_fd(SANE_Handle handle,SANE_Int * fd)1995 sane_get_select_fd (SANE_Handle handle, SANE_Int * fd)
1996 {
1997   Ma1509_Scanner *s = handle;
1998 
1999   if (!s)
2000     {
2001       DBG (1, "sane_get_select_fd: handle is null!\n");
2002       return SANE_STATUS_INVAL;
2003     }
2004   if (!fd)
2005     {
2006       DBG (1, "sane_get_select_fd: fd is null!\n");
2007       return SANE_STATUS_INVAL;
2008     }
2009 
2010   DBG (4, "sane_get_select_fd\n");
2011   if (!s->scanning)
2012     return SANE_STATUS_INVAL;
2013 
2014   return SANE_STATUS_UNSUPPORTED;
2015 }
2016