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