1 /* sane - Scanner Access Now Easy.
2
3 Copyright (C) 2002-2006 Henning Meier-Geinitz <henning@meier-geinitz.de>
4 Changes according to the sanei_thread usage by
5 Gerhard Jaeger <gerhard@gjaeger.de>
6
7 This file is part of the SANE package.
8
9 This program is free software; you can redistribute it and/or
10 modify it under the terms of the GNU General Public License as
11 published by the Free Software Foundation; either version 2 of the
12 License, or (at your option) any later version.
13
14 This program is distributed in the hope that it will be useful, but
15 WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 General Public License for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with this program. If not, see <https://www.gnu.org/licenses/>.
21
22 As a special exception, the authors of SANE give permission for
23 additional uses of the libraries contained in this release of SANE.
24
25 The exception is that, if you link a SANE library with other files
26 to produce an executable, this does not by itself cause the
27 resulting executable to be covered by the GNU General Public
28 License. Your use of that executable is in no way restricted on
29 account of linking the SANE library code into it.
30
31 This exception does not, however, invalidate any other reasons why
32 the executable file might be covered by the GNU General Public
33 License.
34
35 If you submit changes to SANE to the maintainers to be included in
36 a subsequent release, you agree by submitting the changes that
37 those changes may be distributed with this exception intact.
38
39 If you write modifications of your own for SANE, it is your choice
40 whether to permit this exception to apply to your modifications.
41 If you do not wish that, delete this exception notice.
42
43 This backend is for testing frontends.
44 */
45
46 #define BUILD 28
47
48 #include "../include/sane/config.h"
49
50 #include <errno.h>
51 #include <signal.h>
52 #include <stdio.h>
53 #include <stdlib.h>
54 #include <string.h>
55 #include <sys/types.h>
56 #include <time.h>
57 #include <unistd.h>
58 #include <fcntl.h>
59
60 #include "../include/_stdint.h"
61
62 #include "../include/sane/sane.h"
63 #include "../include/sane/sanei.h"
64 #include "../include/sane/saneopts.h"
65 #include "../include/sane/sanei_config.h"
66 #include "../include/sane/sanei_thread.h"
67
68 #define BACKEND_NAME test
69 #include "../include/sane/sanei_backend.h"
70
71 #include "test.h"
72
73 #include "test-picture.c"
74
75 #define TEST_CONFIG_FILE "test.conf"
76
77 static SANE_Bool inited = SANE_FALSE;
78 static SANE_Device **sane_device_list = 0;
79 static Test_Device *first_test_device = 0;
80
81 static SANE_Range geometry_range = {
82 SANE_FIX (0.0),
83 SANE_FIX (200.0),
84 SANE_FIX (1.0)
85 };
86
87 static SANE_Range resolution_range = {
88 SANE_FIX (1.0),
89 SANE_FIX (1200.0),
90 SANE_FIX (1.0)
91 };
92
93 static SANE_Range ppl_loss_range = {
94 0,
95 128,
96 1
97 };
98
99 static SANE_Range read_limit_size_range = {
100 1,
101 64 * 1024, /* 64 KB ought to be enough for everyone :-) */
102 1
103 };
104
105 static SANE_Range read_delay_duration_range = {
106 1000,
107 200 * 1000, /* 200 msec */
108 1000
109 };
110
111 static SANE_Range int_constraint_range = {
112 4,
113 192,
114 2
115 };
116
117 static SANE_Range gamma_range = {
118 0,
119 255,
120 1
121 };
122
123 static SANE_Range fixed_constraint_range = {
124 SANE_FIX (-42.17),
125 SANE_FIX (32767.9999),
126 SANE_FIX (2.0)
127 };
128
129 static SANE_String_Const mode_list[] = {
130 SANE_VALUE_SCAN_MODE_GRAY,
131 SANE_VALUE_SCAN_MODE_COLOR,
132 0
133 };
134
135 static SANE_String_Const order_list[] = {
136 "RGB", "RBG", "GBR", "GRB", "BRG", "BGR",
137 0
138 };
139
140 static SANE_String_Const test_picture_list[] = {
141 SANE_I18N ("Solid black"), SANE_I18N ("Solid white"),
142 SANE_I18N ("Color pattern"), SANE_I18N ("Grid"),
143 0
144 };
145
146 static SANE_String_Const read_status_code_list[] = {
147 SANE_I18N ("Default"), "SANE_STATUS_UNSUPPORTED", "SANE_STATUS_CANCELLED",
148 "SANE_STATUS_DEVICE_BUSY", "SANE_STATUS_INVAL", "SANE_STATUS_EOF",
149 "SANE_STATUS_JAMMED", "SANE_STATUS_NO_DOCS", "SANE_STATUS_COVER_OPEN",
150 "SANE_STATUS_IO_ERROR", "SANE_STATUS_NO_MEM", "SANE_STATUS_ACCESS_DENIED",
151 0
152 };
153
154 static SANE_Int depth_list[] = {
155 3, 1, 8, 16
156 };
157
158 static SANE_Int int_constraint_word_list[] = {
159 9, -42, -8, 0, 17, 42, 256, 65536, 256 * 256 * 256, 256 * 256 * 256 * 64
160 };
161
162 static SANE_Int fixed_constraint_word_list[] = {
163 4, SANE_FIX (-32.7), SANE_FIX (12.1), SANE_FIX (42.0), SANE_FIX (129.5)
164 };
165
166 static SANE_String_Const string_constraint_string_list[] = {
167 SANE_I18N ("First entry"), SANE_I18N ("Second entry"),
168 SANE_I18N
169 ("This is the very long third entry. Maybe the frontend has an idea how to "
170 "display it"),
171 0
172 };
173
174 static SANE_String_Const string_constraint_long_string_list[] = {
175 SANE_I18N ("First entry"), SANE_I18N ("Second entry"), "3", "4", "5", "6",
176 "7", "8", "9", "10",
177 "11", "12", "13", "14", "15", "16", "17", "18", "19", "20", "21", "22",
178 "23", "24", "25", "26", "27", "28", "29", "30", "31", "32", "33", "34",
179 "35", "36", "37", "38", "39", "40", "41", "42", "43", "44", "45", "46",
180 0
181 };
182
183 static SANE_Int int_array[] = {
184 -17, 0, -5, 42, 91, 256 * 256 * 256 * 64
185 };
186
187 static SANE_Int int_array_constraint_range[] = {
188 48, 6, 4, 92, 190, 16
189 };
190
191 #define GAMMA_RED_SIZE 256
192 #define GAMMA_GREEN_SIZE 256
193 #define GAMMA_BLUE_SIZE 256
194 #define GAMMA_ALL_SIZE 4096
195 static SANE_Int gamma_red[GAMMA_RED_SIZE]; // initialized in init_options()
196 static SANE_Int gamma_green[GAMMA_GREEN_SIZE];
197 static SANE_Int gamma_blue[GAMMA_BLUE_SIZE];
198 static SANE_Int gamma_all[GAMMA_ALL_SIZE];
199
200 static void
init_gamma_table(SANE_Int *tablePtr, SANE_Int count, SANE_Int max)201 init_gamma_table(SANE_Int *tablePtr, SANE_Int count, SANE_Int max)
202 {
203 for (int i=0; i<count; ++i) {
204 tablePtr[i] = (SANE_Int)(((double)i * max)/(double)count);
205 }
206 }
207
208 static void
print_gamma_table(SANE_Int *tablePtr, SANE_Int count)209 print_gamma_table(SANE_Int *tablePtr, SANE_Int count)
210 {
211 char str[200];
212 str[0] = '\0';
213 DBG (5, "Gamma Table Size: %d\n", count);
214 for (int i=0; i<count; ++i) {
215 if (i%16 == 0 && strlen(str) > 0) {
216 DBG (5, "%s\n", str);
217 str[0] = '\0';
218 }
219 sprintf (str + strlen(str), " %04X", tablePtr[i]);
220 }
221 if (strlen(str) > 0) {
222 DBG (5, "%s\n", str);
223 }
224 }
225
226
227 static SANE_Int int_array_constraint_word_list[] = {
228 -42, 0, -8, 17, 42, 42
229 };
230
231 static SANE_String_Const source_list[] = {
232 SANE_I18N ("Flatbed"), SANE_I18N ("Automatic Document Feeder"),
233 0
234 };
235
236 static double random_factor; /* use for fuzzyness of parameters */
237
238 /* initial values. Initial string values are set in sane_init() */
239 static SANE_Word init_number_of_devices = 2;
240 static SANE_Fixed init_tl_x = SANE_FIX (0.0);
241 static SANE_Fixed init_tl_y = SANE_FIX (0.0);
242 static SANE_Fixed init_br_x = SANE_FIX (80.0);
243 static SANE_Fixed init_br_y = SANE_FIX (100.0);
244 static SANE_Word init_resolution = 50;
245 static SANE_String init_mode = NULL;
246 static SANE_Word init_depth = 8;
247 static SANE_Bool init_hand_scanner = SANE_FALSE;
248 static SANE_Bool init_three_pass = SANE_FALSE;
249 static SANE_String init_three_pass_order = NULL;
250 static SANE_String init_scan_source = NULL;
251 static SANE_String init_test_picture = NULL;
252 static SANE_Bool init_invert_endianess = SANE_FALSE;
253 static SANE_Bool init_read_limit = SANE_FALSE;
254 static SANE_Word init_read_limit_size = 1;
255 static SANE_Bool init_read_delay = SANE_FALSE;
256 static SANE_Word init_read_delay_duration = 1000;
257 static SANE_String init_read_status_code = NULL;
258 static SANE_Bool init_fuzzy_parameters = SANE_FALSE;
259 static SANE_Word init_ppl_loss = 0;
260 static SANE_Bool init_non_blocking = SANE_FALSE;
261 static SANE_Bool init_select_fd = SANE_FALSE;
262 static SANE_Bool init_enable_test_options = SANE_FALSE;
263 static SANE_String init_string = NULL;
264 static SANE_String init_string_constraint_string_list = NULL;
265 static SANE_String init_string_constraint_long_string_list = NULL;
266
267 /* Test if this machine is little endian (from coolscan.c) */
268 static SANE_Bool
little_endian(void)269 little_endian (void)
270 {
271 SANE_Int testvalue = 255;
272 uint8_t *firstbyte = (uint8_t *) & testvalue;
273
274 if (*firstbyte == 255)
275 return SANE_TRUE;
276 return SANE_FALSE;
277 }
278
279 static void
swap_double(double *a, double *b)280 swap_double (double *a, double *b)
281 {
282 double c;
283
284 c = *a;
285 *a = *b;
286 *b = c;
287
288 return;
289 }
290
291 static size_t
max_string_size(const SANE_String_Const strings[])292 max_string_size (const SANE_String_Const strings[])
293 {
294 size_t size, max_size = 0;
295 SANE_Int i;
296
297 for (i = 0; strings[i]; ++i)
298 {
299 size = strlen (strings[i]) + 1;
300 if (size > max_size)
301 max_size = size;
302 }
303 return max_size;
304 }
305
306 static SANE_Bool
check_handle(SANE_Handle handle)307 check_handle (SANE_Handle handle)
308 {
309 Test_Device *test_device = first_test_device;
310
311 while (test_device)
312 {
313 if (test_device == (Test_Device *) handle)
314 return SANE_TRUE;
315 test_device = test_device->next;
316 }
317 return SANE_FALSE;
318 }
319
320 static void
cleanup_options(Test_Device * test_device)321 cleanup_options (Test_Device * test_device)
322 {
323 DBG (2, "cleanup_options: test_device=%p\n", (void *) test_device);
324
325 free(test_device->val[opt_mode].s);
326 test_device->val[opt_mode].s = NULL;
327
328 free(test_device->val[opt_three_pass_order].s);
329 test_device->val[opt_three_pass_order].s = NULL;
330
331 free(test_device->val[opt_scan_source].s);
332 test_device->val[opt_scan_source].s = NULL;
333
334 free(test_device->val[opt_test_picture].s);
335 test_device->val[opt_test_picture].s = NULL;
336
337 free(test_device->val[opt_read_status_code].s);
338 test_device->val[opt_read_status_code].s = NULL;
339
340 free(test_device->val[opt_string].s);
341 test_device->val[opt_string].s = NULL;
342
343 free(test_device->val[opt_string_constraint_string_list].s);
344 test_device->val[opt_string_constraint_string_list].s = NULL;
345
346 free(test_device->val[opt_string_constraint_long_string_list].s);
347 test_device->val[opt_string_constraint_long_string_list].s = NULL;
348
349 test_device->options_initialized = SANE_FALSE;
350 }
351
352 static SANE_Status
init_options(Test_Device * test_device)353 init_options (Test_Device * test_device)
354 {
355 SANE_Option_Descriptor *od;
356
357 DBG (2, "init_options: test_device=%p\n", (void *) test_device);
358
359 /* opt_num_opts */
360 od = &test_device->opt[opt_num_opts];
361 od->name = "";
362 od->title = SANE_TITLE_NUM_OPTIONS;
363 od->desc = SANE_DESC_NUM_OPTIONS;
364 od->type = SANE_TYPE_INT;
365 od->unit = SANE_UNIT_NONE;
366 od->size = sizeof (SANE_Word);
367 od->cap = SANE_CAP_SOFT_DETECT;
368 od->constraint_type = SANE_CONSTRAINT_NONE;
369 od->constraint.range = 0;
370 test_device->val[opt_num_opts].w = num_options;
371
372 test_device->loaded[opt_num_opts] = 1;
373
374 /* opt_mode_group */
375 od = &test_device->opt[opt_mode_group];
376 od->name = "";
377 od->title = SANE_I18N ("Scan Mode");
378 od->desc = "";
379 od->type = SANE_TYPE_GROUP;
380 od->unit = SANE_UNIT_NONE;
381 od->size = 0;
382 od->cap = 0;
383 od->constraint_type = SANE_CONSTRAINT_NONE;
384 od->constraint.range = 0;
385 test_device->val[opt_mode_group].w = 0;
386
387 /* opt_mode */
388 od = &test_device->opt[opt_mode];
389 od->name = SANE_NAME_SCAN_MODE;
390 od->title = SANE_TITLE_SCAN_MODE;
391 od->desc = SANE_DESC_SCAN_MODE;
392 od->type = SANE_TYPE_STRING;
393 od->unit = SANE_UNIT_NONE;
394 od->size = (SANE_Int) max_string_size (mode_list);
395 od->cap = SANE_CAP_SOFT_DETECT | SANE_CAP_SOFT_SELECT;
396 od->constraint_type = SANE_CONSTRAINT_STRING_LIST;
397 od->constraint.string_list = mode_list;
398 test_device->val[opt_mode].s = malloc ((size_t) od->size);
399 if (!test_device->val[opt_mode].s)
400 goto fail;
401 strcpy (test_device->val[opt_mode].s, init_mode);
402
403 /* opt_depth */
404 od = &test_device->opt[opt_depth];
405 od->name = SANE_NAME_BIT_DEPTH;
406 od->title = SANE_TITLE_BIT_DEPTH;
407 od->desc = SANE_DESC_BIT_DEPTH;
408 od->type = SANE_TYPE_INT;
409 od->unit = SANE_UNIT_NONE;
410 od->size = sizeof (SANE_Word);
411 od->cap = SANE_CAP_SOFT_DETECT | SANE_CAP_SOFT_SELECT;
412 od->constraint_type = SANE_CONSTRAINT_WORD_LIST;
413 od->constraint.word_list = depth_list;
414 test_device->val[opt_depth].w = init_depth;
415
416 /* opt_hand_scanner */
417 od = &test_device->opt[opt_hand_scanner];
418 od->name = "hand-scanner";
419 od->title = SANE_I18N ("Hand-scanner simulation");
420 od->desc = SANE_I18N ("Simulate a hand-scanner. Hand-scanners do not "
421 "know the image height a priori. Instead, they "
422 "return a height of -1. Setting this option allows one "
423 "to test whether a frontend can handle this "
424 "correctly. This option also enables a fixed width "
425 "of 11 cm.");
426 od->type = SANE_TYPE_BOOL;
427 od->unit = SANE_UNIT_NONE;
428 od->size = sizeof (SANE_Word);
429 od->cap = SANE_CAP_SOFT_DETECT | SANE_CAP_SOFT_SELECT;
430 od->constraint_type = SANE_CONSTRAINT_NONE;
431 od->constraint.range = 0;
432 test_device->val[opt_hand_scanner].w = init_hand_scanner;
433
434 /* opt_three_pass */
435 od = &test_device->opt[opt_three_pass];
436 od->name = "three-pass";
437 od->title = SANE_I18N ("Three-pass simulation");
438 od->desc = SANE_I18N ("Simulate a three-pass scanner. In color mode, three "
439 "frames are transmitted.");
440 od->type = SANE_TYPE_BOOL;
441 od->unit = SANE_UNIT_NONE;
442 od->size = sizeof (SANE_Word);
443 od->cap = SANE_CAP_SOFT_DETECT | SANE_CAP_SOFT_SELECT;
444 if (strcmp (init_mode, SANE_VALUE_SCAN_MODE_COLOR) != 0)
445 od->cap |= SANE_CAP_INACTIVE;
446 od->constraint_type = SANE_CONSTRAINT_NONE;
447 od->constraint.range = 0;
448 test_device->val[opt_three_pass].w = init_three_pass;
449
450 /* opt_three_pass_order */
451 od = &test_device->opt[opt_three_pass_order];
452 od->name = "three-pass-order";
453 od->title = SANE_I18N ("Set the order of frames");
454 od->desc = SANE_I18N ("Set the order of frames in three-pass color mode.");
455 od->type = SANE_TYPE_STRING;
456 od->unit = SANE_UNIT_NONE;
457 od->size = (SANE_Int) max_string_size (order_list);
458 od->cap = SANE_CAP_SOFT_DETECT | SANE_CAP_SOFT_SELECT;
459 if (strcmp (init_mode, SANE_VALUE_SCAN_MODE_COLOR) != 0)
460 od->cap |= SANE_CAP_INACTIVE;
461 if (!init_three_pass)
462 od->cap |= SANE_CAP_INACTIVE;
463 od->constraint_type = SANE_CONSTRAINT_STRING_LIST;
464 od->constraint.string_list = order_list;
465 test_device->val[opt_three_pass_order].s = malloc ((size_t) od->size);
466 if (!test_device->val[opt_three_pass_order].s)
467 goto fail;
468 strcpy (test_device->val[opt_three_pass_order].s, init_three_pass_order);
469
470 /* opt_resolution */
471 od = &test_device->opt[opt_resolution];
472 od->name = SANE_NAME_SCAN_RESOLUTION;
473 od->title = SANE_TITLE_SCAN_RESOLUTION;
474 od->desc = SANE_DESC_SCAN_RESOLUTION;
475 od->type = SANE_TYPE_FIXED;
476 od->unit = SANE_UNIT_DPI;
477 od->size = sizeof (SANE_Word);
478 od->cap = SANE_CAP_SOFT_DETECT | SANE_CAP_SOFT_SELECT;
479 od->constraint_type = SANE_CONSTRAINT_RANGE;
480 od->constraint.range = &resolution_range;
481 test_device->val[opt_resolution].w = init_resolution;
482
483 /* opt_scan_source */
484 od = &test_device->opt[opt_scan_source];
485 od->name = SANE_NAME_SCAN_SOURCE;
486 od->title = SANE_TITLE_SCAN_SOURCE;
487 od->desc = SANE_I18N("If Automatic Document Feeder is selected, the feeder will be 'empty' after 10 scans.");
488 od->type = SANE_TYPE_STRING;
489 od->unit = SANE_UNIT_NONE;
490 od->size = (SANE_Int) max_string_size (source_list);
491 od->cap = SANE_CAP_SOFT_DETECT | SANE_CAP_SOFT_SELECT;
492 od->constraint_type = SANE_CONSTRAINT_STRING_LIST;
493 od->constraint.string_list = source_list;
494 test_device->val[opt_scan_source].s = malloc ((size_t) od->size);
495 if (!test_device->val[opt_scan_source].s)
496 goto fail;
497 strcpy (test_device->val[opt_scan_source].s, init_scan_source);
498
499 /* opt_special_group */
500 od = &test_device->opt[opt_special_group];
501 od->name = "";
502 od->title = SANE_I18N ("Special Options");
503 od->desc = "";
504 od->type = SANE_TYPE_GROUP;
505 od->unit = SANE_UNIT_NONE;
506 od->size = 0;
507 od->cap = 0;
508 od->constraint_type = SANE_CONSTRAINT_NONE;
509 od->constraint.range = 0;
510 test_device->val[opt_special_group].w = 0;
511
512 /* opt_test_picture */
513 od = &test_device->opt[opt_test_picture];
514 od->name = "test-picture";
515 od->title = SANE_I18N ("Select the test picture");
516 od->desc =
517 SANE_I18N ("Select the kind of test picture. Available options:\n"
518 "Solid black: fills the whole scan with black.\n"
519 "Solid white: fills the whole scan with white.\n"
520 "Color pattern: draws various color test patterns "
521 "depending on the mode.\n"
522 "Grid: draws a black/white grid with a width and "
523 "height of 10 mm per square.");
524 od->type = SANE_TYPE_STRING;
525 od->unit = SANE_UNIT_NONE;
526 od->size = (SANE_Int) max_string_size (test_picture_list);
527 od->cap = SANE_CAP_SOFT_DETECT | SANE_CAP_SOFT_SELECT;
528 od->constraint_type = SANE_CONSTRAINT_STRING_LIST;
529 od->constraint.string_list = test_picture_list;
530 test_device->val[opt_test_picture].s = malloc ((size_t) od->size);
531 if (!test_device->val[opt_test_picture].s)
532 goto fail;
533 strcpy (test_device->val[opt_test_picture].s, init_test_picture);
534
535 /* opt_invert_endianness */
536 od = &test_device->opt[opt_invert_endianess];
537 od->name = "invert-endianess";
538 od->title = SANE_I18N ("Invert endianness");
539 od->desc = SANE_I18N ("Exchange upper and lower byte of image data in 16 "
540 "bit modes. This option can be used to test the 16 "
541 "bit modes of frontends, e.g. if the frontend uses "
542 "the correct endianness.");
543 od->type = SANE_TYPE_BOOL;
544 od->unit = SANE_UNIT_NONE;
545 od->size = sizeof (SANE_Word);
546 od->cap = SANE_CAP_SOFT_DETECT | SANE_CAP_SOFT_SELECT;
547 od->cap |= SANE_CAP_INACTIVE;
548 od->constraint_type = SANE_CONSTRAINT_NONE;
549 od->constraint.range = 0;
550 test_device->val[opt_invert_endianess].w = init_invert_endianess;
551
552 /* opt_read_limit */
553 od = &test_device->opt[opt_read_limit];
554 od->name = "read-limit";
555 od->title = SANE_I18N ("Read limit");
556 od->desc = SANE_I18N ("Limit the amount of data transferred with each "
557 "call to sane_read().");
558 od->type = SANE_TYPE_BOOL;
559 od->unit = SANE_UNIT_NONE;
560 od->size = sizeof (SANE_Word);
561 od->cap = SANE_CAP_SOFT_DETECT | SANE_CAP_SOFT_SELECT;
562 od->constraint_type = SANE_CONSTRAINT_NONE;
563 od->constraint.range = 0;
564 test_device->val[opt_read_limit].w = init_read_limit;
565
566 /* opt_read_limit_size */
567 od = &test_device->opt[opt_read_limit_size];
568 od->name = "read-limit-size";
569 od->title = SANE_I18N ("Size of read-limit");
570 od->desc = SANE_I18N ("The (maximum) amount of data transferred with each "
571 "call to sane_read().");
572 od->type = SANE_TYPE_INT;
573 od->unit = SANE_UNIT_NONE;
574 od->size = sizeof (SANE_Word);
575 od->cap = SANE_CAP_SOFT_DETECT | SANE_CAP_SOFT_SELECT;
576 if (!init_read_limit)
577 od->cap |= SANE_CAP_INACTIVE;
578 od->constraint_type = SANE_CONSTRAINT_RANGE;
579 od->constraint.range = &read_limit_size_range;
580 test_device->val[opt_read_limit_size].w = init_read_limit_size;
581
582 /* opt_read_delay */
583 od = &test_device->opt[opt_read_delay];
584 od->name = "read-delay";
585 od->title = SANE_I18N ("Read delay");
586 od->desc = SANE_I18N ("Delay the transfer of data to the pipe.");
587 od->type = SANE_TYPE_BOOL;
588 od->unit = SANE_UNIT_NONE;
589 od->size = sizeof (SANE_Word);
590 od->cap = SANE_CAP_SOFT_DETECT | SANE_CAP_SOFT_SELECT;
591 od->constraint_type = SANE_CONSTRAINT_NONE;
592 od->constraint.range = 0;
593 test_device->val[opt_read_delay].w = init_read_delay;
594
595 /* opt_read_delay_duration */
596 od = &test_device->opt[opt_read_delay_duration];
597 od->name = "read-delay-duration";
598 od->title = SANE_I18N ("Duration of read-delay");
599 od->desc = SANE_I18N ("How long to wait after transferring each buffer of "
600 "data through the pipe.");
601 od->type = SANE_TYPE_INT;
602 od->unit = SANE_UNIT_MICROSECOND;
603 od->size = sizeof (SANE_Word);
604 od->cap = SANE_CAP_SOFT_DETECT | SANE_CAP_SOFT_SELECT;
605 if (!init_read_delay)
606 od->cap |= SANE_CAP_INACTIVE;
607 od->constraint_type = SANE_CONSTRAINT_RANGE;
608 od->constraint.range = &read_delay_duration_range;
609 test_device->val[opt_read_delay_duration].w = init_read_delay_duration;
610
611 /* opt_read_status_code */
612 od = &test_device->opt[opt_read_status_code];
613 od->name = "read-return-value";
614 od->title = SANE_I18N ("Return-value of sane_read");
615 od->desc =
616 SANE_I18N ("Select the return-value of sane_read(). \"Default\" "
617 "is the normal handling for scanning. All other status "
618 "codes are for testing how the frontend handles them.");
619 od->type = SANE_TYPE_STRING;
620 od->unit = SANE_UNIT_NONE;
621 od->size = (SANE_Int) max_string_size (read_status_code_list);
622 od->cap = SANE_CAP_SOFT_DETECT | SANE_CAP_SOFT_SELECT;
623 od->constraint_type = SANE_CONSTRAINT_STRING_LIST;
624 od->constraint.string_list = read_status_code_list;
625 test_device->val[opt_read_status_code].s = malloc ((size_t) od->size);
626 if (!test_device->val[opt_read_status_code].s)
627 goto fail;
628 strcpy (test_device->val[opt_read_status_code].s, init_read_status_code);
629
630 /* opt_ppl_loss */
631 od = &test_device->opt[opt_ppl_loss];
632 od->name = "ppl-loss";
633 od->title = SANE_I18N ("Loss of pixels per line");
634 od->desc =
635 SANE_I18N ("The number of pixels that are wasted at the end of each "
636 "line.");
637 od->type = SANE_TYPE_INT;
638 od->unit = SANE_UNIT_PIXEL;
639 od->size = sizeof (SANE_Word);
640 od->cap = SANE_CAP_SOFT_DETECT | SANE_CAP_SOFT_SELECT;
641 od->constraint_type = SANE_CONSTRAINT_RANGE;
642 od->constraint.range = &ppl_loss_range;
643 test_device->val[opt_ppl_loss].w = init_ppl_loss;
644
645 /* opt_fuzzy_parameters */
646 od = &test_device->opt[opt_fuzzy_parameters];
647 od->name = "fuzzy-parameters";
648 od->title = SANE_I18N ("Fuzzy parameters");
649 od->desc = SANE_I18N ("Return fuzzy lines and bytes per line when "
650 "sane_parameters() is called before sane_start().");
651 od->type = SANE_TYPE_BOOL;
652 od->unit = SANE_UNIT_NONE;
653 od->size = sizeof (SANE_Word);
654 od->cap = SANE_CAP_SOFT_DETECT | SANE_CAP_SOFT_SELECT;
655 od->constraint_type = SANE_CONSTRAINT_NONE;
656 od->constraint.range = 0;
657 test_device->val[opt_fuzzy_parameters].w = init_fuzzy_parameters;
658
659 /* opt_non_blocking */
660 od = &test_device->opt[opt_non_blocking];
661 od->name = "non-blocking";
662 od->title = SANE_I18N ("Use non-blocking IO");
663 od->desc = SANE_I18N ("Use non-blocking IO for sane_read() if supported "
664 "by the frontend.");
665 od->type = SANE_TYPE_BOOL;
666 od->unit = SANE_UNIT_NONE;
667 od->size = sizeof (SANE_Word);
668 od->cap = SANE_CAP_SOFT_DETECT | SANE_CAP_SOFT_SELECT;
669 od->constraint_type = SANE_CONSTRAINT_NONE;
670 od->constraint.range = 0;
671 test_device->val[opt_non_blocking].w = init_non_blocking;
672
673 /* opt_select_fd */
674 od = &test_device->opt[opt_select_fd];
675 od->name = "select-fd";
676 od->title = SANE_I18N ("Offer select file descriptor");
677 od->desc = SANE_I18N ("Offer a select filedescriptor for detecting if "
678 "sane_read() will return data.");
679 od->type = SANE_TYPE_BOOL;
680 od->unit = SANE_UNIT_NONE;
681 od->size = sizeof (SANE_Word);
682 od->cap = SANE_CAP_SOFT_DETECT | SANE_CAP_SOFT_SELECT;
683 od->constraint_type = SANE_CONSTRAINT_NONE;
684 od->constraint.range = 0;
685 test_device->val[opt_select_fd].w = init_select_fd;
686
687 /* opt_enable_test_options */
688 od = &test_device->opt[opt_enable_test_options];
689 od->name = "enable-test-options";
690 od->title = SANE_I18N ("Enable test options");
691 od->desc = SANE_I18N ("Enable various test options. This is for testing "
692 "the ability of frontends to view and modify all the "
693 "different SANE option types.");
694 od->type = SANE_TYPE_BOOL;
695 od->unit = SANE_UNIT_NONE;
696 od->size = sizeof (SANE_Word);
697 od->cap = SANE_CAP_SOFT_DETECT | SANE_CAP_SOFT_SELECT;
698 od->constraint_type = SANE_CONSTRAINT_NONE;
699 od->constraint.range = 0;
700 test_device->val[opt_enable_test_options].w = init_enable_test_options;
701
702 /* opt_print_options */
703 od = &test_device->opt[opt_print_options];
704 od->name = "print-options";
705 od->title = SANE_I18N ("Print options");
706 od->desc = SANE_I18N ("Print a list of all options.");
707 od->type = SANE_TYPE_BUTTON;
708 od->unit = SANE_UNIT_NONE;
709 od->size = 0;
710 od->cap = SANE_CAP_SOFT_DETECT | SANE_CAP_SOFT_SELECT;
711 od->constraint_type = SANE_CONSTRAINT_NONE;
712 od->constraint.string_list = 0;
713 test_device->val[opt_print_options].w = 0;
714
715 /* opt_geometry_group */
716 od = &test_device->opt[opt_geometry_group];
717 od->name = "";
718 od->title = SANE_I18N ("Geometry");
719 od->desc = "";
720 od->type = SANE_TYPE_GROUP;
721 od->unit = SANE_UNIT_NONE;
722 od->size = 0;
723 od->cap = 0;
724 od->constraint_type = SANE_CONSTRAINT_NONE;
725 od->constraint.range = 0;
726 test_device->val[opt_geometry_group].w = 0;
727
728 /* opt_tl_x */
729 od = &test_device->opt[opt_tl_x];
730 od->name = SANE_NAME_SCAN_TL_X;
731 od->title = SANE_TITLE_SCAN_TL_X;
732 od->desc = SANE_DESC_SCAN_TL_X;
733 od->type = SANE_TYPE_FIXED;
734 od->unit = SANE_UNIT_MM;
735 od->size = sizeof (SANE_Word);
736 od->cap = SANE_CAP_SOFT_DETECT | SANE_CAP_SOFT_SELECT;
737 od->constraint_type = SANE_CONSTRAINT_RANGE;
738 od->constraint.range = &geometry_range;
739 test_device->val[opt_tl_x].w = init_tl_x;
740
741 /* opt_tl_y */
742 od = &test_device->opt[opt_tl_y];
743 od->name = SANE_NAME_SCAN_TL_Y;
744 od->title = SANE_TITLE_SCAN_TL_Y;
745 od->desc = SANE_DESC_SCAN_TL_Y;
746 od->type = SANE_TYPE_FIXED;
747 od->unit = SANE_UNIT_MM;
748 od->size = sizeof (SANE_Word);
749 od->cap = SANE_CAP_SOFT_DETECT | SANE_CAP_SOFT_SELECT;
750 od->constraint_type = SANE_CONSTRAINT_RANGE;
751 od->constraint.range = &geometry_range;
752 test_device->val[opt_tl_y].w = init_tl_y;
753
754 /* opt_br_x */
755 od = &test_device->opt[opt_br_x];
756 od->name = SANE_NAME_SCAN_BR_X;
757 od->title = SANE_TITLE_SCAN_BR_X;
758 od->desc = SANE_DESC_SCAN_BR_X;
759 od->type = SANE_TYPE_FIXED;
760 od->unit = SANE_UNIT_MM;
761 od->size = sizeof (SANE_Word);
762 od->cap = SANE_CAP_SOFT_DETECT | SANE_CAP_SOFT_SELECT;
763 od->constraint_type = SANE_CONSTRAINT_RANGE;
764 od->constraint.range = &geometry_range;
765 test_device->val[opt_br_x].w = init_br_x;
766
767 /* opt_br_y */
768 od = &test_device->opt[opt_br_y];
769 od->name = SANE_NAME_SCAN_BR_Y;
770 od->title = SANE_TITLE_SCAN_BR_Y;
771 od->desc = SANE_DESC_SCAN_BR_Y;
772 od->type = SANE_TYPE_FIXED;
773 od->unit = SANE_UNIT_MM;
774 od->size = sizeof (SANE_Word);
775 od->cap = SANE_CAP_SOFT_DETECT | SANE_CAP_SOFT_SELECT;
776 od->constraint_type = SANE_CONSTRAINT_RANGE;
777 od->constraint.range = &geometry_range;
778 test_device->val[opt_br_y].w = init_br_y;
779
780 /* opt_bool_group */
781 od = &test_device->opt[opt_bool_group];
782 od->name = "";
783 od->title = SANE_I18N ("Bool test options");
784 od->desc = "";
785 od->type = SANE_TYPE_GROUP;
786 od->unit = SANE_UNIT_NONE;
787 od->size = 0;
788 od->cap = SANE_CAP_ADVANCED;
789 od->constraint_type = SANE_CONSTRAINT_NONE;
790 od->constraint.range = 0;
791 test_device->val[opt_bool_group].w = 0;
792
793 /* opt_bool_soft_select_soft_detect */
794 od = &test_device->opt[opt_bool_soft_select_soft_detect];
795 od->name = "bool-soft-select-soft-detect";
796 od->title = SANE_I18N ("(1/6) Bool soft select soft detect");
797 od->desc =
798 SANE_I18N ("(1/6) Bool test option that has soft select and soft "
799 "detect (and advanced) capabilities. That's just a "
800 "normal bool option.");
801 od->type = SANE_TYPE_BOOL;
802 od->unit = SANE_UNIT_NONE;
803 od->size = sizeof (SANE_Word);
804 od->cap = SANE_CAP_SOFT_DETECT | SANE_CAP_SOFT_SELECT | SANE_CAP_ADVANCED;
805 if (init_enable_test_options == SANE_FALSE)
806 od->cap |= SANE_CAP_INACTIVE;
807 od->constraint_type = SANE_CONSTRAINT_NONE;
808 od->constraint.range = 0;
809 test_device->val[opt_bool_soft_select_soft_detect].w = SANE_FALSE;
810
811 /* opt_bool_hard_select_soft_detect */
812 od = &test_device->opt[opt_bool_hard_select_soft_detect];
813 od->name = "bool-hard-select-soft-detect";
814 od->title = SANE_I18N ("(2/6) Bool hard select soft detect");
815 od->desc =
816 SANE_I18N ("(2/6) Bool test option that has hard select and soft "
817 "detect (and advanced) capabilities. That means the "
818 "option can't be set by the frontend but by the user "
819 "(e.g. by pressing a button at the device).");
820 od->type = SANE_TYPE_BOOL;
821 od->unit = SANE_UNIT_NONE;
822 od->size = sizeof (SANE_Word);
823 od->cap = SANE_CAP_SOFT_DETECT | SANE_CAP_HARD_SELECT | SANE_CAP_ADVANCED;
824 if (init_enable_test_options == SANE_FALSE)
825 od->cap |= SANE_CAP_INACTIVE;
826 od->constraint_type = SANE_CONSTRAINT_NONE;
827 od->constraint.range = 0;
828 test_device->val[opt_bool_hard_select_soft_detect].w = SANE_FALSE;
829
830 /* opt_bool_hard_select */
831 od = &test_device->opt[opt_bool_hard_select];
832 od->name = "bool-hard-select";
833 od->title = SANE_I18N ("(3/6) Bool hard select");
834 od->desc = SANE_I18N ("(3/6) Bool test option that has hard select "
835 "(and advanced) capabilities. That means the option "
836 "can't be set by the frontend but by the user "
837 "(e.g. by pressing a button at the device) and can't "
838 "be read by the frontend.");
839 od->type = SANE_TYPE_BOOL;
840 od->unit = SANE_UNIT_NONE;
841 od->size = sizeof (SANE_Word);
842 od->cap = SANE_CAP_HARD_SELECT | SANE_CAP_ADVANCED;
843 if (init_enable_test_options == SANE_FALSE)
844 od->cap |= SANE_CAP_INACTIVE;
845 od->constraint_type = SANE_CONSTRAINT_NONE;
846 od->constraint.range = 0;
847 test_device->val[opt_bool_hard_select].w = SANE_FALSE;
848
849 /* opt_bool_soft_detect */
850 od = &test_device->opt[opt_bool_soft_detect];
851 od->name = "bool-soft-detect";
852 od->title = SANE_I18N ("(4/6) Bool soft detect");
853 od->desc = SANE_I18N ("(4/6) Bool test option that has soft detect "
854 "(and advanced) capabilities. That means the option "
855 "is read-only.");
856 od->type = SANE_TYPE_BOOL;
857 od->unit = SANE_UNIT_NONE;
858 od->size = sizeof (SANE_Word);
859 od->cap = SANE_CAP_SOFT_DETECT | SANE_CAP_ADVANCED;
860 if (init_enable_test_options == SANE_FALSE)
861 od->cap |= SANE_CAP_INACTIVE;
862 od->constraint_type = SANE_CONSTRAINT_NONE;
863 od->constraint.range = 0;
864 test_device->val[opt_bool_soft_detect].w = SANE_FALSE;
865
866 /* opt_bool_soft_select_soft_detect_emulated */
867 od = &test_device->opt[opt_bool_soft_select_soft_detect_emulated];
868 od->name = "bool-soft-select-soft-detect-emulated";
869 od->title = SANE_I18N ("(5/6) Bool soft select soft detect emulated");
870 od->desc = SANE_I18N ("(5/6) Bool test option that has soft select, soft "
871 "detect, and emulated (and advanced) capabilities.");
872 od->type = SANE_TYPE_BOOL;
873 od->unit = SANE_UNIT_NONE;
874 od->size = sizeof (SANE_Word);
875 od->cap = SANE_CAP_SOFT_DETECT | SANE_CAP_SOFT_SELECT | SANE_CAP_ADVANCED
876 | SANE_CAP_EMULATED;
877 if (init_enable_test_options == SANE_FALSE)
878 od->cap |= SANE_CAP_INACTIVE;
879 od->constraint_type = SANE_CONSTRAINT_NONE;
880 od->constraint.range = 0;
881 test_device->val[opt_bool_soft_select_soft_detect_emulated].w = SANE_FALSE;
882
883 /* opt_bool_soft_select_soft_detect_auto */
884 od = &test_device->opt[opt_bool_soft_select_soft_detect_auto];
885 od->name = "bool-soft-select-soft-detect-auto";
886 od->title = SANE_I18N ("(6/6) Bool soft select soft detect auto");
887 od->desc = SANE_I18N ("(6/6) Bool test option that has soft select, soft "
888 "detect, and automatic (and advanced) capabilities. "
889 "This option can be automatically set by the backend.");
890 od->type = SANE_TYPE_BOOL;
891 od->unit = SANE_UNIT_NONE;
892 od->size = sizeof (SANE_Word);
893 od->cap = SANE_CAP_SOFT_DETECT | SANE_CAP_SOFT_SELECT | SANE_CAP_ADVANCED
894 | SANE_CAP_AUTOMATIC;
895 if (init_enable_test_options == SANE_FALSE)
896 od->cap |= SANE_CAP_INACTIVE;
897 od->constraint_type = SANE_CONSTRAINT_NONE;
898 od->constraint.range = 0;
899 test_device->val[opt_bool_soft_select_soft_detect_auto].w = SANE_FALSE;
900
901 /* opt_int_group */
902 od = &test_device->opt[opt_int_group];
903 od->name = "";
904 od->title = SANE_I18N ("Int test options");
905 od->desc = "";
906 od->type = SANE_TYPE_GROUP;
907 od->unit = SANE_UNIT_NONE;
908 od->size = 0;
909 od->cap = SANE_CAP_ADVANCED;
910 od->constraint_type = SANE_CONSTRAINT_NONE;
911 od->constraint.range = 0;
912 test_device->val[opt_int_group].w = 0;
913
914 /* opt_int */
915 od = &test_device->opt[opt_int];
916 od->name = "int";
917 od->title = SANE_I18N ("(1/7) Int");
918 od->desc = SANE_I18N ("(1/7) Int test option with no unit and no "
919 "constraint set.");
920 od->type = SANE_TYPE_INT;
921 od->unit = SANE_UNIT_NONE;
922 od->size = sizeof (SANE_Word);
923 od->cap = SANE_CAP_SOFT_DETECT | SANE_CAP_SOFT_SELECT | SANE_CAP_ADVANCED;
924 if (init_enable_test_options == SANE_FALSE)
925 od->cap |= SANE_CAP_INACTIVE;
926 od->constraint_type = SANE_CONSTRAINT_NONE;
927 od->constraint.range = 0;
928 test_device->val[opt_int].w = 42;
929
930 /* opt_int_constraint_range */
931 od = &test_device->opt[opt_int_constraint_range];
932 od->name = "int-constraint-range";
933 od->title = SANE_I18N ("(2/7) Int constraint range");
934 od->desc = SANE_I18N ("(2/7) Int test option with unit pixel and "
935 "constraint range set. Minimum is 4, maximum 192, and "
936 "quant is 2.");
937 od->type = SANE_TYPE_INT;
938 od->unit = SANE_UNIT_PIXEL;
939 od->size = sizeof (SANE_Word);
940 od->cap = SANE_CAP_SOFT_DETECT | SANE_CAP_SOFT_SELECT | SANE_CAP_ADVANCED;
941 if (init_enable_test_options == SANE_FALSE)
942 od->cap |= SANE_CAP_INACTIVE;
943 od->constraint_type = SANE_CONSTRAINT_RANGE;
944 od->constraint.range = &int_constraint_range;
945 test_device->val[opt_int_constraint_range].w = 26;
946
947 /* opt_int_constraint_word_list */
948 od = &test_device->opt[opt_int_constraint_word_list];
949 od->name = "int-constraint-word-list";
950 od->title = SANE_I18N ("(3/7) Int constraint word list");
951 od->desc = SANE_I18N ("(3/7) Int test option with unit bits and "
952 "constraint word list set.");
953 od->type = SANE_TYPE_INT;
954 od->unit = SANE_UNIT_BIT;
955 od->size = sizeof (SANE_Word);
956 od->cap = SANE_CAP_SOFT_DETECT | SANE_CAP_SOFT_SELECT | SANE_CAP_ADVANCED;
957 if (init_enable_test_options == SANE_FALSE)
958 od->cap |= SANE_CAP_INACTIVE;
959 od->constraint_type = SANE_CONSTRAINT_WORD_LIST;
960 od->constraint.word_list = int_constraint_word_list;
961 test_device->val[opt_int_constraint_word_list].w = 42;
962
963 /* opt_int_array */
964 od = &test_device->opt[opt_int_array];
965 od->name = "int-constraint-array";
966 od->title = SANE_I18N ("(4/7) Int array");
967 od->desc = SANE_I18N ("(4/7) Int test option with unit mm and using "
968 "an array without constraints.");
969 od->type = SANE_TYPE_INT;
970 od->unit = SANE_UNIT_MM;
971 od->size = 6 * sizeof (SANE_Word);
972 od->cap = SANE_CAP_SOFT_DETECT | SANE_CAP_SOFT_SELECT | SANE_CAP_ADVANCED;
973 if (init_enable_test_options == SANE_FALSE)
974 od->cap |= SANE_CAP_INACTIVE;
975 od->constraint_type = SANE_CONSTRAINT_NONE;
976 od->constraint.range = 0;
977 test_device->val[opt_int_array].wa = &int_array[0];
978
979 /* opt_int_array_constraint_range */
980 od = &test_device->opt[opt_int_array_constraint_range];
981 od->name = "int-constraint-array-constraint-range";
982 od->title = SANE_I18N ("(5/7) Int array constraint range");
983 od->desc = SANE_I18N ("(5/7) Int test option with unit dpi and using "
984 "an array with a range constraint. Minimum is 4, "
985 "maximum 192, and quant is 2.");
986 od->type = SANE_TYPE_INT;
987 od->unit = SANE_UNIT_DPI;
988 od->size = 6 * sizeof (SANE_Word);
989 od->cap = SANE_CAP_SOFT_DETECT | SANE_CAP_SOFT_SELECT | SANE_CAP_ADVANCED;
990 if (init_enable_test_options == SANE_FALSE)
991 od->cap |= SANE_CAP_INACTIVE;
992 od->constraint_type = SANE_CONSTRAINT_RANGE;
993 od->constraint.range = &int_constraint_range;
994 test_device->val[opt_int_array_constraint_range].wa =
995 &int_array_constraint_range[0];
996
997 /* opt_int_array_constraint_word_list */
998 od = &test_device->opt[opt_int_array_constraint_word_list];
999 od->name = "int-constraint-array-constraint-word-list";
1000 od->title = SANE_I18N ("(6/7) Int array constraint word list");
1001 od->desc = SANE_I18N ("(6/7) Int test option with unit percent and using "
1002 "an array with a word list constraint.");
1003 od->type = SANE_TYPE_INT;
1004 od->unit = SANE_UNIT_PERCENT;
1005 od->size = 6 * sizeof (SANE_Word);
1006 od->cap = SANE_CAP_SOFT_DETECT | SANE_CAP_SOFT_SELECT | SANE_CAP_ADVANCED;
1007 if (init_enable_test_options == SANE_FALSE)
1008 od->cap |= SANE_CAP_INACTIVE;
1009 od->constraint_type = SANE_CONSTRAINT_WORD_LIST;
1010 od->constraint.word_list = int_constraint_word_list;
1011 test_device->val[opt_int_array_constraint_word_list].wa =
1012 &int_array_constraint_word_list[0];
1013
1014 /* opt_int_inexact */
1015 od = &test_device->opt[opt_int_inexact];
1016 od->name = "int-inexact";
1017 od->title = SANE_I18N ("(7/7) Int inexact");
1018 od->desc = SANE_I18N ("(7/7) Int test option that modifies the value "
1019 "and returns SANE_INFO_INEXACT.");
1020 od->type = SANE_TYPE_INT;
1021 od->unit = SANE_UNIT_NONE;
1022 od->size = sizeof (SANE_Word);
1023 od->cap = SANE_CAP_SOFT_DETECT | SANE_CAP_SOFT_SELECT | SANE_CAP_ADVANCED;
1024 if (init_enable_test_options == SANE_FALSE)
1025 od->cap |= SANE_CAP_INACTIVE;
1026 od->constraint_type = SANE_CONSTRAINT_NONE;
1027 od->constraint.range = 0;
1028 test_device->val[opt_int_inexact].w = 67;
1029
1030
1031 /* opt_gamma_red */
1032 init_gamma_table(gamma_red, GAMMA_RED_SIZE, gamma_range.max);
1033 od = &test_device->opt[opt_gamma_red];
1034 od->name = SANE_NAME_GAMMA_VECTOR_R;
1035 od->title = SANE_TITLE_GAMMA_VECTOR_R;
1036 od->desc = SANE_DESC_GAMMA_VECTOR_R;
1037 od->type = SANE_TYPE_INT;
1038 od->unit = SANE_UNIT_NONE;
1039 od->size = 256 * sizeof (SANE_Word);
1040 od->cap = SANE_CAP_SOFT_DETECT | SANE_CAP_SOFT_SELECT | SANE_CAP_ADVANCED;
1041 od->constraint_type = SANE_CONSTRAINT_RANGE;
1042 od->constraint.range = &gamma_range;
1043 test_device->val[opt_gamma_red].wa = &gamma_red[0];
1044
1045 /* opt_gamma_green */
1046 init_gamma_table(gamma_green, GAMMA_GREEN_SIZE, gamma_range.max);
1047 od = &test_device->opt[opt_gamma_green];
1048 od->name = SANE_NAME_GAMMA_VECTOR_G;
1049 od->title = SANE_TITLE_GAMMA_VECTOR_G;
1050 od->desc = SANE_DESC_GAMMA_VECTOR_G;
1051 od->type = SANE_TYPE_INT;
1052 od->unit = SANE_UNIT_NONE;
1053 od->size = 256 * sizeof (SANE_Word);
1054 od->cap = SANE_CAP_SOFT_DETECT | SANE_CAP_SOFT_SELECT | SANE_CAP_ADVANCED;
1055 od->constraint_type = SANE_CONSTRAINT_RANGE;
1056 od->constraint.range = &gamma_range;
1057 test_device->val[opt_gamma_green].wa = &gamma_green[0];
1058
1059 /* opt_gamma_blue */
1060 init_gamma_table(gamma_blue, GAMMA_BLUE_SIZE, gamma_range.max);
1061 od = &test_device->opt[opt_gamma_blue];
1062 od->name = SANE_NAME_GAMMA_VECTOR_B;
1063 od->title = SANE_TITLE_GAMMA_VECTOR_B;
1064 od->desc = SANE_DESC_GAMMA_VECTOR_B;
1065 od->type = SANE_TYPE_INT;
1066 od->unit = SANE_UNIT_NONE;
1067 od->size = 256 * sizeof (SANE_Word);
1068 od->cap = SANE_CAP_SOFT_DETECT | SANE_CAP_SOFT_SELECT | SANE_CAP_ADVANCED;
1069 od->constraint_type = SANE_CONSTRAINT_RANGE;
1070 od->constraint.range = &gamma_range;
1071 test_device->val[opt_gamma_blue].wa = &gamma_blue[0];
1072
1073 /* opt_gamma_all */
1074 init_gamma_table(gamma_all, GAMMA_ALL_SIZE, gamma_range.max);
1075 print_gamma_table(gamma_all, GAMMA_ALL_SIZE);
1076 od = &test_device->opt[opt_gamma_all];
1077 od->name = SANE_NAME_GAMMA_VECTOR;
1078 od->title = SANE_TITLE_GAMMA_VECTOR;
1079 od->desc = SANE_DESC_GAMMA_VECTOR;
1080 od->type = SANE_TYPE_INT;
1081 od->unit = SANE_UNIT_NONE;
1082 od->size = GAMMA_ALL_SIZE * sizeof (SANE_Word);
1083 od->cap = SANE_CAP_SOFT_DETECT | SANE_CAP_SOFT_SELECT | SANE_CAP_ADVANCED;
1084 od->constraint_type = SANE_CONSTRAINT_RANGE;
1085 od->constraint.range = &gamma_range;
1086 test_device->val[opt_gamma_all].wa = &gamma_all[0];
1087
1088 /* opt_fixed_group */
1089 od = &test_device->opt[opt_fixed_group];
1090 od->name = "";
1091 od->title = SANE_I18N ("Fixed test options");
1092 od->desc = "";
1093 od->type = SANE_TYPE_GROUP;
1094 od->unit = SANE_UNIT_NONE;
1095 od->size = 0;
1096 od->cap = SANE_CAP_ADVANCED;
1097 od->constraint_type = SANE_CONSTRAINT_NONE;
1098 od->constraint.range = 0;
1099 test_device->val[opt_fixed_group].w = 0;
1100
1101 /* opt_fixed */
1102 od = &test_device->opt[opt_fixed];
1103 od->name = "fixed";
1104 od->title = SANE_I18N ("(1/3) Fixed");
1105 od->desc = SANE_I18N ("(1/3) Fixed test option with no unit and no "
1106 "constraint set.");
1107 od->type = SANE_TYPE_FIXED;
1108 od->unit = SANE_UNIT_NONE;
1109 od->size = sizeof (SANE_Word);
1110 od->cap = SANE_CAP_SOFT_DETECT | SANE_CAP_SOFT_SELECT | SANE_CAP_ADVANCED;
1111 if (init_enable_test_options == SANE_FALSE)
1112 od->cap |= SANE_CAP_INACTIVE;
1113 od->constraint_type = SANE_CONSTRAINT_NONE;
1114 od->constraint.range = 0;
1115 test_device->val[opt_fixed].w = SANE_FIX (42.0);
1116
1117 /* opt_fixed_constraint_range */
1118 od = &test_device->opt[opt_fixed_constraint_range];
1119 od->name = "fixed-constraint-range";
1120 od->title = SANE_I18N ("(2/3) Fixed constraint range");
1121 od->desc = SANE_I18N ("(2/3) Fixed test option with unit microsecond and "
1122 "constraint range set. Minimum is -42.17, maximum "
1123 "32767.9999, and quant is 2.0.");
1124 od->type = SANE_TYPE_FIXED;
1125 od->unit = SANE_UNIT_MICROSECOND;
1126 od->size = sizeof (SANE_Word);
1127 od->cap = SANE_CAP_SOFT_DETECT | SANE_CAP_SOFT_SELECT | SANE_CAP_ADVANCED;
1128 if (init_enable_test_options == SANE_FALSE)
1129 od->cap |= SANE_CAP_INACTIVE;
1130 od->constraint_type = SANE_CONSTRAINT_RANGE;
1131 od->constraint.range = &fixed_constraint_range;
1132 test_device->val[opt_fixed_constraint_range].w = SANE_FIX (41.83);
1133
1134 /* opt_fixed_constraint_word_list */
1135 od = &test_device->opt[opt_fixed_constraint_word_list];
1136 od->name = "fixed-constraint-word-list";
1137 od->title = SANE_I18N ("(3/3) Fixed constraint word list");
1138 od->desc = SANE_I18N ("(3/3) Fixed test option with no unit and "
1139 "constraint word list set.");
1140 od->type = SANE_TYPE_FIXED;
1141 od->unit = SANE_UNIT_NONE;
1142 od->size = sizeof (SANE_Word);
1143 od->cap = SANE_CAP_SOFT_DETECT | SANE_CAP_SOFT_SELECT | SANE_CAP_ADVANCED;
1144 if (init_enable_test_options == SANE_FALSE)
1145 od->cap |= SANE_CAP_INACTIVE;
1146 od->constraint_type = SANE_CONSTRAINT_WORD_LIST;
1147 od->constraint.word_list = fixed_constraint_word_list;
1148 test_device->val[opt_fixed_constraint_word_list].w = SANE_FIX (42.0);
1149
1150 /* opt_string_group */
1151 od = &test_device->opt[opt_string_group];
1152 od->name = "";
1153 od->title = SANE_I18N ("String test options");
1154 od->desc = "";
1155 od->type = SANE_TYPE_GROUP;
1156 od->unit = SANE_UNIT_NONE;
1157 od->size = 0;
1158 od->cap = 0;
1159 od->constraint_type = SANE_CONSTRAINT_NONE;
1160 od->constraint.range = 0;
1161 test_device->val[opt_string_group].w = 0;
1162
1163 /* opt_string */
1164 od = &test_device->opt[opt_string];
1165 od->name = "string";
1166 od->title = SANE_I18N ("(1/3) String");
1167 od->desc = SANE_I18N ("(1/3) String test option without constraint.");
1168 od->type = SANE_TYPE_STRING;
1169 od->unit = SANE_UNIT_NONE;
1170 od->size = (SANE_Int) strlen (init_string) + 1;
1171 od->cap = SANE_CAP_SOFT_DETECT | SANE_CAP_SOFT_SELECT;
1172 if (init_enable_test_options == SANE_FALSE)
1173 od->cap |= SANE_CAP_INACTIVE;
1174 od->constraint_type = SANE_CONSTRAINT_NONE;
1175 od->constraint.string_list = 0;
1176 test_device->val[opt_string].s = malloc ((size_t) od->size);
1177 if (!test_device->val[opt_string].s)
1178 goto fail;
1179 strcpy (test_device->val[opt_string].s, init_string);
1180
1181 /* opt_string_constraint_string_list */
1182 od = &test_device->opt[opt_string_constraint_string_list];
1183 od->name = "string-constraint-string-list";
1184 od->title = SANE_I18N ("(2/3) String constraint string list");
1185 od->desc = SANE_I18N ("(2/3) String test option with string list "
1186 "constraint.");
1187 od->type = SANE_TYPE_STRING;
1188 od->unit = SANE_UNIT_NONE;
1189 od->size = (SANE_Int) max_string_size (string_constraint_string_list);
1190 od->cap = SANE_CAP_SOFT_DETECT | SANE_CAP_SOFT_SELECT;
1191 if (init_enable_test_options == SANE_FALSE)
1192 od->cap |= SANE_CAP_INACTIVE;
1193 od->constraint_type = SANE_CONSTRAINT_STRING_LIST;
1194 od->constraint.string_list = string_constraint_string_list;
1195 test_device->val[opt_string_constraint_string_list].s = malloc ((size_t) od->size);
1196 if (!test_device->val[opt_string_constraint_string_list].s)
1197 goto fail;
1198 strcpy (test_device->val[opt_string_constraint_string_list].s,
1199 init_string_constraint_string_list);
1200
1201 /* opt_string_constraint_long_string_list */
1202 od = &test_device->opt[opt_string_constraint_long_string_list];
1203 od->name = "string-constraint-long-string-list";
1204 od->title = SANE_I18N ("(3/3) String constraint long string list");
1205 od->desc = SANE_I18N ("(3/3) String test option with string list "
1206 "constraint. Contains some more entries...");
1207 od->type = SANE_TYPE_STRING;
1208 od->unit = SANE_UNIT_NONE;
1209 od->size = (SANE_Int) max_string_size (string_constraint_long_string_list);
1210 od->cap = SANE_CAP_SOFT_DETECT | SANE_CAP_SOFT_SELECT;
1211 if (init_enable_test_options == SANE_FALSE)
1212 od->cap |= SANE_CAP_INACTIVE;
1213 od->constraint_type = SANE_CONSTRAINT_STRING_LIST;
1214 od->constraint.string_list = string_constraint_long_string_list;
1215 test_device->val[opt_string_constraint_long_string_list].s =
1216 malloc ((size_t) od->size);
1217 if (!test_device->val[opt_string_constraint_long_string_list].s)
1218 goto fail;
1219 strcpy (test_device->val[opt_string_constraint_long_string_list].s,
1220 init_string_constraint_long_string_list);
1221
1222 /* opt_button_group */
1223 od = &test_device->opt[opt_button_group];
1224 od->name = "";
1225 od->title = SANE_I18N ("Button test options");
1226 od->desc = "";
1227 od->type = SANE_TYPE_GROUP;
1228 od->unit = SANE_UNIT_NONE;
1229 od->size = 0;
1230 od->cap = 0;
1231 od->constraint_type = SANE_CONSTRAINT_NONE;
1232 od->constraint.range = 0;
1233 test_device->val[opt_button_group].w = 0;
1234
1235 /* opt_button */
1236 od = &test_device->opt[opt_button];
1237 od->name = "button";
1238 od->title = SANE_I18N ("(1/1) Button");
1239 od->desc = SANE_I18N ("(1/1) Button test option. Prints some text...");
1240 od->type = SANE_TYPE_BUTTON;
1241 od->unit = SANE_UNIT_NONE;
1242 od->size = 0;
1243 od->cap = SANE_CAP_SOFT_DETECT | SANE_CAP_SOFT_SELECT;
1244 if (init_enable_test_options == SANE_FALSE)
1245 od->cap |= SANE_CAP_INACTIVE;
1246 od->constraint_type = SANE_CONSTRAINT_NONE;
1247 od->constraint.string_list = 0;
1248 test_device->val[opt_button].w = 0;
1249
1250 return SANE_STATUS_GOOD;
1251
1252 fail:
1253 cleanup_options (test_device);
1254 return SANE_STATUS_NO_MEM;
1255 }
1256
1257 static void
cleanup_initial_string_valuesnull1258 cleanup_initial_string_values ()
1259 {
1260 // Cleanup backing memory for initial values of string options.
1261 free (init_mode);
1262 init_mode = NULL;
1263 free (init_three_pass_order);
1264 init_three_pass_order = NULL;
1265 free (init_scan_source);
1266 init_scan_source = NULL;
1267 free (init_test_picture);
1268 init_test_picture = NULL;
1269 free (init_read_status_code);
1270 init_read_status_code = NULL;
1271 free (init_string);
1272 init_string = NULL;
1273 free (init_string_constraint_string_list);
1274 init_string_constraint_string_list = NULL;
1275 free (init_string_constraint_long_string_list);
1276 init_string_constraint_long_string_list = NULL;
1277 }
1278
1279 static void
cleanup_test_device(Test_Device * test_device)1280 cleanup_test_device (Test_Device * test_device)
1281 {
1282 DBG (2, "cleanup_test_device: test_device=%p\n", (void *) test_device);
1283 if (test_device->options_initialized)
1284 cleanup_options (test_device);
1285 if (test_device->name)
1286 free (test_device->name);
1287 free (test_device);
1288 }
1289
1290 static SANE_Status
read_option(SANE_String line, SANE_String option_string, parameter_type p_type, void *value)1291 read_option (SANE_String line, SANE_String option_string,
1292 parameter_type p_type, void *value)
1293 {
1294 SANE_String_Const cp;
1295 SANE_Char *word, *end;
1296
1297 word = 0;
1298
1299 cp = sanei_config_get_string (line, &word);
1300
1301 if (!word)
1302 return SANE_STATUS_INVAL;
1303
1304 if (strcmp (word, option_string) != 0)
1305 {
1306 free(word);
1307 return SANE_STATUS_INVAL;
1308 }
1309
1310 free (word);
1311 word = 0;
1312
1313 switch (p_type)
1314 {
1315 case param_none:
1316 return SANE_STATUS_GOOD;
1317 case param_bool:
1318 {
1319 cp = sanei_config_get_string (cp, &word);
1320 if (!word)
1321 return SANE_STATUS_INVAL;
1322 if (strlen (word) == 0)
1323 {
1324 DBG (3, "read_option: option `%s' requires parameter\n",
1325 option_string);
1326 return SANE_STATUS_INVAL;
1327 }
1328 if (strcmp (word, "true") != 0 && strcmp (word, "false") != 0)
1329 {
1330 DBG (3, "read_option: option `%s' requires parameter "
1331 "`true' or `false'\n", option_string);
1332 return SANE_STATUS_INVAL;
1333 }
1334 else if (strcmp (word, "true") == 0)
1335 *(SANE_Bool *) value = SANE_TRUE;
1336 else
1337 *(SANE_Bool *) value = SANE_FALSE;
1338 DBG (3, "read_option: set option `%s' to %s\n", option_string,
1339 *(SANE_Bool *) value == SANE_TRUE ? "true" : "false");
1340 break;
1341 }
1342 case param_int:
1343 {
1344 SANE_Int int_value;
1345
1346 cp = sanei_config_get_string (cp, &word);
1347 if (!word)
1348 return SANE_STATUS_INVAL;
1349 errno = 0;
1350 int_value = (SANE_Int) strtol (word, &end, 0);
1351 if (end == word)
1352 {
1353 DBG (3, "read_option: option `%s' requires parameter\n",
1354 option_string);
1355 return SANE_STATUS_INVAL;
1356 }
1357 else if (errno)
1358 {
1359 DBG (3, "read_option: option `%s': can't parse parameter `%s' "
1360 "(%s)\n", option_string, word, strerror (errno));
1361 return SANE_STATUS_INVAL;
1362 }
1363 else
1364 {
1365 DBG (3, "read_option: set option `%s' to %d\n", option_string,
1366 int_value);
1367 *(SANE_Int *) value = int_value;
1368 }
1369 break;
1370 }
1371 case param_fixed:
1372 {
1373 double double_value;
1374 SANE_Fixed fixed_value;
1375
1376 cp = sanei_config_get_string (cp, &word);
1377 if (!word)
1378 return SANE_STATUS_INVAL;
1379 errno = 0;
1380 double_value = strtod (word, &end);
1381 if (end == word)
1382 {
1383 DBG (3, "read_option: option `%s' requires parameter\n",
1384 option_string);
1385 return SANE_STATUS_INVAL;
1386 }
1387 else if (errno)
1388 {
1389 DBG (3, "read_option: option `%s': can't parse parameter `%s' "
1390 "(%s)\n", option_string, word, strerror (errno));
1391 return SANE_STATUS_INVAL;
1392 }
1393 else
1394 {
1395 DBG (3, "read_option: set option `%s' to %.0f\n", option_string,
1396 double_value);
1397 fixed_value = SANE_FIX (double_value);
1398 *(SANE_Fixed *) value = fixed_value;
1399 }
1400 break;
1401 }
1402 case param_string:
1403 {
1404 cp = sanei_config_get_string (cp, &word);
1405 if (!word)
1406 return SANE_STATUS_INVAL;
1407 if (strlen (word) == 0)
1408 {
1409 DBG (3, "read_option: option `%s' requires parameter\n",
1410 option_string);
1411 return SANE_STATUS_INVAL;
1412 }
1413 else
1414 {
1415 DBG (3, "read_option: set option `%s' to `%s'\n", option_string,
1416 word);
1417 if (*(SANE_String *) value)
1418 free (*(SANE_String *) value);
1419 *(SANE_String *) value = strdup (word);
1420 if (!*(SANE_String *) value)
1421 return SANE_STATUS_NO_MEM;
1422 }
1423 break;
1424 }
1425 default:
1426 DBG (1, "read_option: unknown param_type %d\n", p_type);
1427 return SANE_STATUS_INVAL;
1428 } /* switch */
1429
1430 if (word)
1431 free (word);
1432 return SANE_STATUS_GOOD;
1433 }
1434
1435 static SANE_Status
reader_process(Test_Device * test_device, SANE_Int fd)1436 reader_process (Test_Device * test_device, SANE_Int fd)
1437 {
1438 SANE_Status status;
1439 size_t byte_count = 0;
1440 size_t bytes_total;
1441 SANE_Byte *buffer = 0;
1442 ssize_t bytes_written = 0;
1443 size_t buffer_size = 0, write_count = 0;
1444
1445 DBG (2, "(child) reader_process: test_device=%p, fd=%d\n",
1446 (void *) test_device, fd);
1447
1448 bytes_total = (size_t) test_device->lines * (size_t) test_device->bytes_per_line;
1449 status = init_picture_buffer (test_device, &buffer, &buffer_size);
1450 if (status != SANE_STATUS_GOOD)
1451 return status;
1452
1453 DBG (2, "(child) reader_process: buffer=%p, buffersize=%lu\n",
1454 (void *) buffer, (u_long) buffer_size);
1455
1456 while (byte_count < bytes_total)
1457 {
1458 if (write_count == 0)
1459 {
1460 write_count = buffer_size;
1461 if (byte_count + (size_t) write_count > bytes_total)
1462 write_count = (size_t) bytes_total - (size_t) byte_count;
1463
1464 if (test_device->val[opt_read_delay].w == SANE_TRUE)
1465 usleep ((useconds_t) test_device->val[opt_read_delay_duration].w);
1466 }
1467 bytes_written = write (fd, buffer, write_count);
1468 if (bytes_written < 0)
1469 {
1470 DBG (1, "(child) reader_process: write returned %s\n",
1471 strerror (errno));
1472 return SANE_STATUS_IO_ERROR;
1473 }
1474 byte_count += (size_t) bytes_written;
1475 DBG (4, "(child) reader_process: wrote %ld bytes of %lu (%zu total)\n",
1476 bytes_written, write_count, byte_count);
1477 write_count -= (size_t) bytes_written;
1478 }
1479
1480 free (buffer);
1481
1482 if (sanei_thread_is_forked ())
1483 {
1484 DBG (4, "(child) reader_process: finished, wrote %zu bytes, expected %zu "
1485 "bytes, now waiting\n", byte_count, bytes_total);
1486 while (SANE_TRUE)
1487 sleep (10);
1488 DBG (4, "(child) reader_process: this should have never happened...");
1489 close (fd);
1490 }
1491 else
1492 {
1493 DBG (4, "(child) reader_process: finished, wrote %zu bytes, expected %zu "
1494 "bytes\n", byte_count, bytes_total);
1495 }
1496 return SANE_STATUS_GOOD;
1497 }
1498
1499 /*
1500 * this code either runs in child or thread context...
1501 */
1502 static int
reader_task(void *data)1503 reader_task (void *data)
1504 {
1505 SANE_Status status;
1506 struct SIGACTION act;
1507 struct Test_Device *test_device = (struct Test_Device *) data;
1508
1509 DBG (2, "reader_task started\n");
1510 if (sanei_thread_is_forked ())
1511 {
1512 DBG (3, "reader_task started (forked)\n");
1513 close (test_device->pipe);
1514 test_device->pipe = -1;
1515
1516 }
1517 else
1518 {
1519 DBG (3, "reader_task started (as thread)\n");
1520 }
1521
1522 memset (&act, 0, sizeof (act));
1523 sigaction (SIGTERM, &act, 0);
1524
1525 status = reader_process (test_device, test_device->reader_fds);
1526 DBG (2, "(child) reader_task: reader_process finished (%s)\n",
1527 sane_strstatus (status));
1528 return (int) status;
1529 }
1530
1531 static SANE_Status
finish_pass(Test_Device * test_device)1532 finish_pass (Test_Device * test_device)
1533 {
1534 SANE_Status return_status = SANE_STATUS_GOOD;
1535
1536 DBG (2, "finish_pass: test_device=%p\n", (void *) test_device);
1537 test_device->scanning = SANE_FALSE;
1538 if (test_device->pipe >= 0)
1539 {
1540 DBG (2, "finish_pass: closing pipe\n");
1541 close (test_device->pipe);
1542 DBG (2, "finish_pass: pipe closed\n");
1543 test_device->pipe = -1;
1544 }
1545 if (sanei_thread_is_valid (test_device->reader_pid))
1546 {
1547 int status;
1548 SANE_Pid pid;
1549
1550 DBG (2, "finish_pass: terminating reader process %ld\n",
1551 (long) test_device->reader_pid);
1552 sanei_thread_kill (test_device->reader_pid);
1553 pid = sanei_thread_waitpid (test_device->reader_pid, &status);
1554 if (!sanei_thread_is_valid (pid))
1555 {
1556 DBG (1,
1557 "finish_pass: sanei_thread_waitpid failed, already terminated? (%s)\n",
1558 strerror (errno));
1559 }
1560 else
1561 {
1562 DBG (2, "finish_pass: reader process terminated with status: %s\n",
1563 sane_strstatus (status));
1564 }
1565 sanei_thread_invalidate (test_device->reader_pid);
1566 }
1567 /* this happens when running in thread context... */
1568 if (test_device->reader_fds >= 0)
1569 {
1570 DBG (2, "finish_pass: closing reader pipe\n");
1571 close (test_device->reader_fds);
1572 DBG (2, "finish_pass: reader pipe closed\n");
1573 test_device->reader_fds = -1;
1574 }
1575 return return_status;
1576 }
1577
1578 static void
print_options(Test_Device * test_device)1579 print_options (Test_Device * test_device)
1580 {
1581 SANE_Option_Descriptor *od;
1582 SANE_Word option_number;
1583 SANE_Char caps[1024];
1584
1585 for (option_number = 0; option_number < num_options; option_number++)
1586 {
1587 od = &test_device->opt[option_number];
1588 DBG (0, "-----> number: %d\n", option_number);
1589 DBG (0, " name: `%s'\n", od->name);
1590 DBG (0, " title: `%s'\n", od->title);
1591 DBG (0, " description: `%s'\n", od->desc);
1592 DBG (0, " type: %s\n",
1593 od->type == SANE_TYPE_BOOL ? "SANE_TYPE_BOOL" :
1594 od->type == SANE_TYPE_INT ? "SANE_TYPE_INT" :
1595 od->type == SANE_TYPE_FIXED ? "SANE_TYPE_FIXED" :
1596 od->type == SANE_TYPE_STRING ? "SANE_TYPE_STRING" :
1597 od->type == SANE_TYPE_BUTTON ? "SANE_TYPE_BUTTON" :
1598 od->type == SANE_TYPE_GROUP ? "SANE_TYPE_GROUP" : "unknown");
1599 DBG (0, " unit: %s\n",
1600 od->unit == SANE_UNIT_NONE ? "SANE_UNIT_NONE" :
1601 od->unit == SANE_UNIT_PIXEL ? "SANE_UNIT_PIXEL" :
1602 od->unit == SANE_UNIT_BIT ? "SANE_UNIT_BIT" :
1603 od->unit == SANE_UNIT_MM ? "SANE_UNIT_MM" :
1604 od->unit == SANE_UNIT_DPI ? "SANE_UNIT_DPI" :
1605 od->unit == SANE_UNIT_PERCENT ? "SANE_UNIT_PERCENT" :
1606 od->unit == SANE_UNIT_MICROSECOND ? "SANE_UNIT_MICROSECOND" :
1607 "unknown");
1608 DBG (0, " size: %d\n", od->size);
1609 caps[0] = '\0';
1610 if (od->cap & SANE_CAP_SOFT_SELECT)
1611 strcat (caps, "SANE_CAP_SOFT_SELECT ");
1612 if (od->cap & SANE_CAP_HARD_SELECT)
1613 strcat (caps, "SANE_CAP_HARD_SELECT ");
1614 if (od->cap & SANE_CAP_SOFT_DETECT)
1615 strcat (caps, "SANE_CAP_SOFT_DETECT ");
1616 if (od->cap & SANE_CAP_EMULATED)
1617 strcat (caps, "SANE_CAP_EMULATED ");
1618 if (od->cap & SANE_CAP_AUTOMATIC)
1619 strcat (caps, "SANE_CAP_AUTOMATIC ");
1620 if (od->cap & SANE_CAP_INACTIVE)
1621 strcat (caps, "SANE_CAP_INACTIVE ");
1622 if (od->cap & SANE_CAP_ADVANCED)
1623 strcat (caps, "SANE_CAP_ADVANCED ");
1624 DBG (0, " capabilities: %s\n", caps);
1625 DBG (0, "constraint type: %s\n",
1626 od->constraint_type == SANE_CONSTRAINT_NONE ?
1627 "SANE_CONSTRAINT_NONE" :
1628 od->constraint_type == SANE_CONSTRAINT_RANGE ?
1629 "SANE_CONSTRAINT_RANGE" :
1630 od->constraint_type == SANE_CONSTRAINT_WORD_LIST ?
1631 "SANE_CONSTRAINT_WORD_LIST" :
1632 od->constraint_type == SANE_CONSTRAINT_STRING_LIST ?
1633 "SANE_CONSTRAINT_STRING_LIST" : "unknown");
1634 }
1635 }
1636
1637 /***************************** SANE API ****************************/
1638
1639
1640 SANE_Status
sane_init(SANE_Int * __sane_unused__ version_code, SANE_Auth_Callback __sane_unused__ authorize)1641 sane_init (SANE_Int * __sane_unused__ version_code, SANE_Auth_Callback __sane_unused__ authorize)
1642 {
1643 FILE *fp;
1644 SANE_Int linenumber;
1645 SANE_Char line[PATH_MAX], *word = NULL;
1646 SANE_String_Const cp;
1647 SANE_Device *sane_device;
1648 Test_Device *test_device, *previous_device;
1649 SANE_Int num;
1650
1651 DBG_INIT ();
1652 sanei_thread_init ();
1653
1654 test_device = 0;
1655 previous_device = 0;
1656
1657 DBG (1, "sane_init: SANE test backend version %d.%d.%d from %s\n", SANE_CURRENT_MAJOR,
1658 SANE_CURRENT_MINOR, BUILD, PACKAGE_STRING);
1659
1660 if (version_code)
1661 *version_code = SANE_VERSION_CODE (SANE_CURRENT_MAJOR, SANE_CURRENT_MINOR, BUILD);
1662
1663 if (inited)
1664 DBG (3, "sane_init: warning: already inited\n");
1665
1666 // Setup initial values of string options. Call free initially in case we've
1667 // already called sane_init and these values are already non-null.
1668 free (init_mode);
1669 init_mode = strdup (SANE_VALUE_SCAN_MODE_GRAY);
1670 if (!init_mode)
1671 goto fail;
1672
1673 free (init_three_pass_order);
1674 init_three_pass_order = strdup ("RGB");
1675 if (!init_three_pass_order)
1676 goto fail;
1677
1678 free (init_scan_source);
1679 init_scan_source = strdup ("Flatbed");
1680 if (!init_scan_source)
1681 goto fail;
1682
1683 free (init_test_picture);
1684 init_test_picture = strdup ("Solid black");
1685 if (!init_test_picture)
1686 goto fail;
1687
1688 free (init_read_status_code);
1689 init_read_status_code = strdup ("Default");
1690 if (!init_read_status_code)
1691 goto fail;
1692
1693 free (init_string);
1694 init_string = strdup ("This is the contents of the string option. "
1695 "Fill some more words to see how the frontend behaves.");
1696 if (!init_string)
1697 goto fail;
1698
1699 free (init_string_constraint_string_list);
1700 init_string_constraint_string_list = strdup ("First entry");
1701 if (!init_string_constraint_string_list)
1702 goto fail;
1703
1704 free (init_string_constraint_long_string_list);
1705 init_string_constraint_long_string_list = strdup ("First entry");
1706 if (!init_string_constraint_long_string_list)
1707 goto fail;
1708
1709 fp = sanei_config_open (TEST_CONFIG_FILE);
1710 if (fp)
1711 {
1712 linenumber = 0;
1713 DBG (4, "sane_init: reading config file `%s'\n", TEST_CONFIG_FILE);
1714 while (sanei_config_read (line, sizeof (line), fp))
1715 {
1716 if (word)
1717 free (word);
1718 word = NULL;
1719 linenumber++;
1720
1721 cp = sanei_config_get_string (line, &word);
1722 if (!word || cp == line)
1723 {
1724 DBG (5,
1725 "sane_init: config file line %3d: ignoring empty line\n",
1726 linenumber);
1727 continue;
1728 }
1729 if (word[0] == '#')
1730 {
1731 DBG (5,
1732 "sane_init: config file line %3d: ignoring comment line\n",
1733 linenumber);
1734 continue;
1735 }
1736
1737 DBG (5, "sane_init: config file line %3d: `%s'\n",
1738 linenumber, line);
1739 if (read_option (line, "number_of_devices", param_int,
1740 &init_number_of_devices) == SANE_STATUS_GOOD)
1741 continue;
1742 if (read_option (line, "mode", param_string,
1743 &init_mode) == SANE_STATUS_GOOD)
1744 continue;
1745 if (read_option (line, "hand-scanner", param_bool,
1746 &init_hand_scanner) == SANE_STATUS_GOOD)
1747 continue;
1748 if (read_option (line, "three-pass", param_bool,
1749 &init_three_pass) == SANE_STATUS_GOOD)
1750 continue;
1751 if (read_option (line, "three-pass-order", param_string,
1752 &init_three_pass_order) == SANE_STATUS_GOOD)
1753 continue;
1754 if (read_option (line, "resolution_min", param_fixed,
1755 &resolution_range.min) == SANE_STATUS_GOOD)
1756 continue;
1757 if (read_option (line, "resolution_max", param_fixed,
1758 &resolution_range.max) == SANE_STATUS_GOOD)
1759 continue;
1760 if (read_option (line, "resolution_quant", param_fixed,
1761 &resolution_range.quant) == SANE_STATUS_GOOD)
1762 continue;
1763 if (read_option (line, "resolution", param_fixed,
1764 &init_resolution) == SANE_STATUS_GOOD)
1765 continue;
1766 if (read_option (line, "depth", param_int,
1767 &init_depth) == SANE_STATUS_GOOD)
1768 continue;
1769 if (read_option (line, "scan-source", param_string,
1770 &init_scan_source) == SANE_STATUS_GOOD)
1771 continue;
1772 if (read_option (line, "test-picture", param_string,
1773 &init_test_picture) == SANE_STATUS_GOOD)
1774 continue;
1775 if (read_option (line, "invert-endianess", param_bool,
1776 &init_invert_endianess) == SANE_STATUS_GOOD)
1777 continue;
1778 if (read_option (line, "read-limit", param_bool,
1779 &init_read_limit) == SANE_STATUS_GOOD)
1780 continue;
1781 if (read_option (line, "read-limit-size", param_int,
1782 &init_read_limit_size) == SANE_STATUS_GOOD)
1783 continue;
1784 if (read_option (line, "read-delay", param_bool,
1785 &init_read_delay) == SANE_STATUS_GOOD)
1786 continue;
1787 if (read_option (line, "read-delay-duration", param_int,
1788 &init_read_delay_duration) == SANE_STATUS_GOOD)
1789 continue;
1790 if (read_option (line, "read-status-code", param_string,
1791 &init_read_status_code) == SANE_STATUS_GOOD)
1792 continue;
1793 if (read_option (line, "ppl-loss", param_int,
1794 &init_ppl_loss) == SANE_STATUS_GOOD)
1795 continue;
1796 if (read_option (line, "fuzzy-parameters", param_bool,
1797 &init_fuzzy_parameters) == SANE_STATUS_GOOD)
1798 continue;
1799 if (read_option (line, "non-blocking", param_bool,
1800 &init_non_blocking) == SANE_STATUS_GOOD)
1801 continue;
1802 if (read_option (line, "select-fd", param_bool,
1803 &init_select_fd) == SANE_STATUS_GOOD)
1804 continue;
1805 if (read_option (line, "enable-test-options", param_bool,
1806 &init_enable_test_options) == SANE_STATUS_GOOD)
1807 continue;
1808 if (read_option (line, "geometry_min", param_fixed,
1809 &geometry_range.min) == SANE_STATUS_GOOD)
1810 continue;
1811 if (read_option (line, "geometry_max", param_fixed,
1812 &geometry_range.max) == SANE_STATUS_GOOD)
1813 continue;
1814 if (read_option (line, "geometry_quant", param_fixed,
1815 &geometry_range.quant) == SANE_STATUS_GOOD)
1816 continue;
1817 if (read_option (line, "tl_x", param_fixed,
1818 &init_tl_x) == SANE_STATUS_GOOD)
1819 continue;
1820 if (read_option (line, "tl_y", param_fixed,
1821 &init_tl_y) == SANE_STATUS_GOOD)
1822 continue;
1823 if (read_option (line, "br_x", param_fixed,
1824 &init_br_x) == SANE_STATUS_GOOD)
1825 continue;
1826 if (read_option (line, "br_y", param_fixed,
1827 &init_br_y) == SANE_STATUS_GOOD)
1828 continue;
1829
1830 DBG (3, "sane-init: I don't know how to handle option `%s'\n",
1831 word);
1832 } /* while */
1833 if (word)
1834 free (word);
1835 fclose (fp);
1836 } /* if */
1837 else
1838 {
1839 DBG (3, "sane_init: couldn't find config file (%s), using default "
1840 "settings\n", TEST_CONFIG_FILE);
1841 }
1842
1843 /* create devices */
1844 sane_device_list =
1845 malloc ((size_t) (init_number_of_devices + 1) * sizeof (sane_device));
1846 if (!sane_device_list)
1847 goto fail;
1848 for (num = 0; num < init_number_of_devices; num++)
1849 {
1850 SANE_Char number_string[PATH_MAX];
1851
1852 test_device = calloc (sizeof (*test_device), 1);
1853 if (!test_device)
1854 goto fail_device;
1855 test_device->sane.vendor = "Noname";
1856 test_device->sane.type = "virtual device";
1857 test_device->sane.model = "frontend-tester";
1858 snprintf (number_string, sizeof (number_string), "%d", num);
1859 number_string[sizeof (number_string) - 1] = '\0';
1860 test_device->name = strdup (number_string);
1861 if (!test_device->name)
1862 goto fail_name;
1863 test_device->sane.name = test_device->name;
1864 if (previous_device)
1865 previous_device->next = test_device;
1866 previous_device = test_device;
1867 if (num == 0)
1868 first_test_device = test_device;
1869 sane_device_list[num] = &test_device->sane;
1870 test_device->open = SANE_FALSE;
1871 test_device->eof = SANE_FALSE;
1872 test_device->scanning = SANE_FALSE;
1873 test_device->cancelled = SANE_FALSE;
1874 test_device->options_initialized = SANE_FALSE;
1875 sanei_thread_initialize (test_device->reader_pid);
1876 test_device->pipe = -1;
1877 DBG (4, "sane_init: new device: `%s' is a %s %s %s\n",
1878 test_device->sane.name, test_device->sane.vendor,
1879 test_device->sane.model, test_device->sane.type);
1880 }
1881 test_device->next = 0;
1882 sane_device_list[num] = 0;
1883 srand ((unsigned int) time (NULL));
1884 random_factor = ((double) rand ()) / RAND_MAX + 0.5;
1885 inited = SANE_TRUE;
1886 return SANE_STATUS_GOOD;
1887
1888 fail_name:
1889 // test_device refers to the last device we were creating, which has not
1890 // yet been added to the linked list of devices.
1891 free (test_device);
1892 fail_device:
1893 // Now, iterate through the linked list of devices to clean up any successful
1894 // devices.
1895 test_device = first_test_device;
1896 while (test_device)
1897 {
1898 previous_device = test_device;
1899 test_device = test_device->next;
1900 cleanup_test_device (previous_device);
1901 }
1902 free (sane_device_list);
1903 fail:
1904 cleanup_initial_string_values ();
1905 return SANE_STATUS_NO_MEM;
1906 }
1907
1908 void
sane_exit(void)1909 sane_exit (void)
1910 {
1911 Test_Device *test_device, *previous_device;
1912
1913 DBG (2, "sane_exit\n");
1914 if (!inited)
1915 {
1916 DBG (1, "sane_exit: not inited, call sane_init() first\n");
1917 return;
1918 }
1919
1920 test_device = first_test_device;
1921 while (test_device)
1922 {
1923 DBG (4, "sane_exit: freeing device %s\n", test_device->name);
1924 previous_device = test_device;
1925 test_device = test_device->next;
1926 cleanup_test_device (previous_device);
1927 }
1928 DBG (4, "sane_exit: freeing device list\n");
1929 if (sane_device_list)
1930 free (sane_device_list);
1931 sane_device_list = NULL;
1932 first_test_device = NULL;
1933
1934 cleanup_initial_string_values ();
1935 inited = SANE_FALSE;
1936 return;
1937 }
1938
1939
1940 SANE_Status
sane_get_devices(const SANE_Device *** device_list, SANE_Bool local_only)1941 sane_get_devices (const SANE_Device *** device_list, SANE_Bool local_only)
1942 {
1943
1944 DBG (2, "sane_get_devices: device_list=%p, local_only=%d\n",
1945 (void *) device_list, local_only);
1946 if (!inited)
1947 {
1948 DBG (1, "sane_get_devices: not inited, call sane_init() first\n");
1949 return SANE_STATUS_INVAL;
1950 }
1951
1952 if (!device_list)
1953 {
1954 DBG (1, "sane_get_devices: device_list == 0\n");
1955 return SANE_STATUS_INVAL;
1956 }
1957 *device_list = (const SANE_Device **) sane_device_list;
1958 return SANE_STATUS_GOOD;
1959 }
1960
1961 SANE_Status
sane_open(SANE_String_Const devicename, SANE_Handle * handle)1962 sane_open (SANE_String_Const devicename, SANE_Handle * handle)
1963 {
1964 Test_Device *test_device = first_test_device;
1965 SANE_Status status;
1966
1967 DBG (2, "sane_open: devicename = \"%s\", handle=%p\n",
1968 devicename, (void *) handle);
1969 if (!inited)
1970 {
1971 DBG (1, "sane_open: not inited, call sane_init() first\n");
1972 return SANE_STATUS_INVAL;
1973 }
1974
1975 if (!handle)
1976 {
1977 DBG (1, "sane_open: handle == 0\n");
1978 return SANE_STATUS_INVAL;
1979 }
1980
1981 if (!devicename || strlen (devicename) == 0)
1982 {
1983 DBG (2, "sane_open: device name NULL or empty\n");
1984 }
1985 else
1986 {
1987 for (test_device = first_test_device; test_device;
1988 test_device = test_device->next)
1989 {
1990 if (strcmp (devicename, test_device->name) == 0)
1991 break;
1992 }
1993 }
1994 if (!test_device)
1995 {
1996 DBG (1, "sane_open: device `%s' not found\n", devicename);
1997 return SANE_STATUS_INVAL;
1998 }
1999 if (test_device->open)
2000 {
2001 DBG (1, "sane_open: device `%s' already open\n", devicename);
2002 return SANE_STATUS_DEVICE_BUSY;
2003 }
2004 DBG (2, "sane_open: opening device `%s', handle = %p\n", test_device->name,
2005 (void *) test_device);
2006 test_device->open = SANE_TRUE;
2007 *handle = test_device;
2008
2009 if (!test_device->options_initialized) {
2010 status = init_options (test_device);
2011 if (status != SANE_STATUS_GOOD)
2012 return status;
2013 test_device->options_initialized = SANE_TRUE;
2014 }
2015
2016 test_device->open = SANE_TRUE;
2017 test_device->scanning = SANE_FALSE;
2018 test_device->cancelled = SANE_FALSE;
2019 test_device->eof = SANE_FALSE;
2020 test_device->bytes_total = 0;
2021 test_device->pass = 0;
2022 test_device->number_of_scans = 0;
2023
2024 return SANE_STATUS_GOOD;
2025 }
2026
2027 void
sane_close(SANE_Handle handle)2028 sane_close (SANE_Handle handle)
2029 {
2030 Test_Device *test_device = handle;
2031
2032 DBG (2, "sane_close: handle=%p\n", (void *) handle);
2033 if (!inited)
2034 {
2035 DBG (1, "sane_close: not inited, call sane_init() first\n");
2036 return;
2037 }
2038
2039 if (!check_handle (handle))
2040 {
2041 DBG (1, "sane_close: handle %p unknown\n", (void *) handle);
2042 return;
2043 }
2044 if (!test_device->open)
2045 {
2046 DBG (1, "sane_close: handle %p not open\n", (void *) handle);
2047 return;
2048 }
2049 test_device->open = SANE_FALSE;
2050 return;
2051 }
2052
2053 const SANE_Option_Descriptor *
sane_get_option_descriptor(SANE_Handle handle, SANE_Int option)2054 sane_get_option_descriptor (SANE_Handle handle, SANE_Int option)
2055 {
2056 Test_Device *test_device = handle;
2057
2058 DBG (4, "sane_get_option_descriptor: handle=%p, option = %d\n",
2059 (void *) handle, option);
2060 if (!inited)
2061 {
2062 DBG (1, "sane_get_option_descriptor: not inited, call sane_init() "
2063 "first\n");
2064 return 0;
2065 }
2066
2067 if (!check_handle (handle))
2068 {
2069 DBG (1, "sane_get_option_descriptor: handle %p unknown\n",
2070 (void *) handle);
2071 return 0;
2072 }
2073 if (!test_device->open)
2074 {
2075 DBG (1, "sane_get_option_descriptor: not open\n");
2076 return 0;
2077 }
2078 if (option < 0 || option >= num_options)
2079 {
2080 DBG (3, "sane_get_option_descriptor: option < 0 || "
2081 "option > num_options\n");
2082 return 0;
2083 }
2084
2085 test_device->loaded[option] = 1;
2086
2087 return &test_device->opt[option];
2088 }
2089
2090 SANE_Status
sane_control_option(SANE_Handle handle, SANE_Int option, SANE_Action action, void *value, SANE_Int * info)2091 sane_control_option (SANE_Handle handle, SANE_Int option, SANE_Action action,
2092 void *value, SANE_Int * info)
2093 {
2094 Test_Device *test_device = handle;
2095 SANE_Int myinfo = 0;
2096 SANE_Status status;
2097
2098 DBG (4, "sane_control_option: handle=%p, opt=%d, act=%d, val=%p, info=%p\n",
2099 (void *) handle, option, action, (void *) value, (void *) info);
2100 if (!inited)
2101 {
2102 DBG (1, "sane_control_option: not inited, call sane_init() first\n");
2103 return SANE_STATUS_INVAL;
2104 }
2105
2106 if (!check_handle (handle))
2107 {
2108 DBG (1, "sane_control_option: handle %p unknown\n", (void *) handle);
2109 return SANE_STATUS_INVAL;
2110 }
2111 if (!test_device->open)
2112 {
2113 DBG (1, "sane_control_option: not open\n");
2114 return SANE_STATUS_INVAL;
2115 }
2116 if (test_device->scanning)
2117 {
2118 DBG (1, "sane_control_option: is scanning\n");
2119 return SANE_STATUS_INVAL;
2120 }
2121 if (option < 0 || option >= num_options)
2122 {
2123 DBG (1, "sane_control_option: option < 0 || option > num_options\n");
2124 return SANE_STATUS_INVAL;
2125 }
2126
2127 if (!test_device->loaded[option])
2128 {
2129 DBG (1, "sane_control_option: option not loaded\n");
2130 return SANE_STATUS_INVAL;
2131 }
2132
2133 if (!SANE_OPTION_IS_ACTIVE (test_device->opt[option].cap))
2134 {
2135 DBG (1, "sane_control_option: option is inactive\n");
2136 return SANE_STATUS_INVAL;
2137 }
2138
2139 if (test_device->opt[option].type == SANE_TYPE_GROUP)
2140 {
2141 DBG (1, "sane_control_option: option is a group\n");
2142 return SANE_STATUS_INVAL;
2143 }
2144
2145 switch (action)
2146 {
2147 case SANE_ACTION_SET_AUTO:
2148 if (!SANE_OPTION_IS_SETTABLE (test_device->opt[option].cap))
2149 {
2150 DBG (1, "sane_control_option: option is not setable\n");
2151 return SANE_STATUS_INVAL;
2152 }
2153 if (!(test_device->opt[option].cap & SANE_CAP_AUTOMATIC))
2154 {
2155 DBG (1, "sane_control_option: option is not automatically "
2156 "setable\n");
2157 return SANE_STATUS_INVAL;
2158 }
2159 switch (option)
2160 {
2161 case opt_bool_soft_select_soft_detect_auto:
2162 test_device->val[option].w = SANE_TRUE;
2163 DBG (4, "sane_control_option: set option %d (%s) automatically "
2164 "to %s\n", option, test_device->opt[option].name,
2165 test_device->val[option].w == SANE_TRUE ? "true" : "false");
2166 break;
2167
2168 default:
2169 DBG (1, "sane_control_option: trying to automatically set "
2170 "unexpected option\n");
2171 return SANE_STATUS_INVAL;
2172 }
2173 break;
2174
2175 case SANE_ACTION_SET_VALUE:
2176 if (!SANE_OPTION_IS_SETTABLE (test_device->opt[option].cap))
2177 {
2178 DBG (1, "sane_control_option: option is not setable\n");
2179 return SANE_STATUS_INVAL;
2180 }
2181 status = sanei_constrain_value (&test_device->opt[option],
2182 value, &myinfo);
2183 if (status != SANE_STATUS_GOOD)
2184 {
2185 DBG (3, "sane_control_option: sanei_constrain_value returned %s\n",
2186 sane_strstatus (status));
2187 return status;
2188 }
2189 switch (option)
2190 {
2191 case opt_tl_x: /* Fixed with parameter reloading */
2192 case opt_tl_y:
2193 case opt_br_x:
2194 case opt_br_y:
2195 case opt_resolution:
2196 if (test_device->val[option].w == *(SANE_Fixed *) value)
2197 {
2198 DBG (4, "sane_control_option: option %d (%s) not changed\n",
2199 option, test_device->opt[option].name);
2200 break;
2201 }
2202 test_device->val[option].w = *(SANE_Fixed *) value;
2203 myinfo |= SANE_INFO_RELOAD_PARAMS;
2204 DBG (4, "sane_control_option: set option %d (%s) to %.0f %s\n",
2205 option, test_device->opt[option].name,
2206 SANE_UNFIX (*(SANE_Fixed *) value),
2207 test_device->opt[option].unit == SANE_UNIT_MM ? "mm" : "dpi");
2208 break;
2209 case opt_fixed: /* Fixed */
2210 case opt_fixed_constraint_range:
2211 if (test_device->val[option].w == *(SANE_Fixed *) value)
2212 {
2213 DBG (4, "sane_control_option: option %d (%s) not changed\n",
2214 option, test_device->opt[option].name);
2215 break;
2216 }
2217 test_device->val[option].w = *(SANE_Fixed *) value;
2218 DBG (4, "sane_control_option: set option %d (%s) to %.0f\n",
2219 option, test_device->opt[option].name,
2220 SANE_UNFIX (*(SANE_Fixed *) value));
2221 break;
2222 case opt_read_limit_size: /* Int */
2223 case opt_ppl_loss:
2224 case opt_read_delay_duration:
2225 case opt_int:
2226 case opt_int_constraint_range:
2227 if (test_device->val[option].w == *(SANE_Int *) value)
2228 {
2229 DBG (4, "sane_control_option: option %d (%s) not changed\n",
2230 option, test_device->opt[option].name);
2231 break;
2232 }
2233 test_device->val[option].w = *(SANE_Int *) value;
2234 DBG (4, "sane_control_option: set option %d (%s) to %d\n",
2235 option, test_device->opt[option].name, *(SANE_Int *) value);
2236 break;
2237 case opt_int_inexact:
2238 if (test_device->val[option].w == *(SANE_Int *) value)
2239 {
2240 DBG (4, "sane_control_option: option %d (%s) not changed\n",
2241 option, test_device->opt[option].name);
2242 break;
2243 }
2244 *(SANE_Int *) value += 1;
2245 test_device->val[option].w = *(SANE_Int *) value;
2246 myinfo |= SANE_INFO_INEXACT;
2247 DBG (4, "sane_control_option: set option %d (%s) to %d\n",
2248 option, test_device->opt[option].name, *(SANE_Int *) value);
2249 break;
2250 case opt_fuzzy_parameters: /* Bool with parameter reloading */
2251 if (test_device->val[option].w == *(SANE_Bool *) value)
2252 {
2253 DBG (4, "sane_control_option: option %d (%s) not changed\n",
2254 option, test_device->opt[option].name);
2255 break;
2256 }
2257 test_device->val[option].w = *(SANE_Bool *) value;
2258 myinfo |= SANE_INFO_RELOAD_PARAMS;
2259 DBG (4, "sane_control_option: set option %d (%s) to %s\n",
2260 option, test_device->opt[option].name,
2261 *(SANE_Bool *) value == SANE_TRUE ? "true" : "false");
2262 break;
2263 case opt_invert_endianess: /* Bool */
2264 case opt_non_blocking:
2265 case opt_select_fd:
2266 case opt_bool_soft_select_soft_detect:
2267 case opt_bool_soft_select_soft_detect_auto:
2268 case opt_bool_soft_select_soft_detect_emulated:
2269 if (test_device->val[option].w == *(SANE_Bool *) value)
2270 {
2271 DBG (4, "sane_control_option: option %d (%s) not changed\n",
2272 option, test_device->opt[option].name);
2273 break;
2274 }
2275 test_device->val[option].w = *(SANE_Bool *) value;
2276 DBG (4, "sane_control_option: set option %d (%s) to %s\n",
2277 option, test_device->opt[option].name,
2278 *(SANE_Bool *) value == SANE_TRUE ? "true" : "false");
2279 break;
2280 case opt_depth: /* Word list with parameter and options reloading */
2281 if (test_device->val[option].w == *(SANE_Int *) value)
2282 {
2283 DBG (4, "sane_control_option: option %d (%s) not changed\n",
2284 option, test_device->opt[option].name);
2285 break;
2286 }
2287 test_device->val[option].w = *(SANE_Int *) value;
2288 if (test_device->val[option].w == 16)
2289 test_device->opt[opt_invert_endianess].cap &= ~SANE_CAP_INACTIVE;
2290 else
2291 test_device->opt[opt_invert_endianess].cap |= SANE_CAP_INACTIVE;
2292
2293 myinfo |= SANE_INFO_RELOAD_PARAMS;
2294 myinfo |= SANE_INFO_RELOAD_OPTIONS;
2295 DBG (4, "sane_control_option: set option %d (%s) to %d\n",
2296 option, test_device->opt[option].name, *(SANE_Int *) value);
2297 break;
2298 case opt_three_pass_order: /* String list with parameter reload */
2299 if (strcmp (test_device->val[option].s, value) == 0)
2300 {
2301 DBG (4, "sane_control_option: option %d (%s) not changed\n",
2302 option, test_device->opt[option].name);
2303 break;
2304 }
2305 strcpy (test_device->val[option].s, (SANE_String) value);
2306 myinfo |= SANE_INFO_RELOAD_PARAMS;
2307 DBG (4, "sane_control_option: set option %d (%s) to %s\n",
2308 option, test_device->opt[option].name, (SANE_String) value);
2309 break;
2310 case opt_int_constraint_word_list: /* Word list */
2311 case opt_fixed_constraint_word_list:
2312 if (test_device->val[option].w == *(SANE_Int *) value)
2313 {
2314 DBG (4, "sane_control_option: option %d (%s) not changed\n",
2315 option, test_device->opt[option].name);
2316 break;
2317 }
2318 test_device->val[option].w = *(SANE_Int *) value;
2319 DBG (4, "sane_control_option: set option %d (%s) to %d\n",
2320 option, test_device->opt[option].name, *(SANE_Int *) value);
2321 break;
2322 case opt_read_status_code: /* String (list) */
2323 case opt_test_picture:
2324 case opt_string:
2325 case opt_string_constraint_string_list:
2326 case opt_string_constraint_long_string_list:
2327 case opt_scan_source:
2328 if (strcmp (test_device->val[option].s, value) == 0)
2329 {
2330 DBG (4, "sane_control_option: option %d (%s) not changed\n",
2331 option, test_device->opt[option].name);
2332 break;
2333 }
2334 strcpy (test_device->val[option].s, (SANE_String) value);
2335 DBG (4, "sane_control_option: set option %d (%s) to `%s'\n",
2336 option, test_device->opt[option].name, (SANE_String) value);
2337 break;
2338 case opt_int_array: /* Word array */
2339 case opt_int_array_constraint_range:
2340 case opt_gamma_red:
2341 case opt_gamma_green:
2342 case opt_gamma_blue:
2343 case opt_gamma_all:
2344 case opt_int_array_constraint_word_list:
2345 memcpy (test_device->val[option].wa, value,
2346 (size_t) test_device->opt[option].size);
2347 DBG (4, "sane_control_option: set option %d (%s) to %p\n",
2348 option, test_device->opt[option].name, (void *) value);
2349 if (option == opt_gamma_all) {
2350 print_gamma_table(gamma_all, GAMMA_ALL_SIZE);
2351 }
2352 if (option == opt_gamma_red) {
2353 print_gamma_table(gamma_red, GAMMA_RED_SIZE);
2354 }
2355 break;
2356 /* options with side-effects */
2357 case opt_print_options:
2358 DBG (4, "sane_control_option: set option %d (%s)\n",
2359 option, test_device->opt[option].name);
2360 print_options (test_device);
2361 break;
2362 case opt_button:
2363 DBG (0, "Yes! You pressed me!\n");
2364 DBG (4, "sane_control_option: set option %d (%s)\n",
2365 option, test_device->opt[option].name);
2366 break;
2367 case opt_mode:
2368 if (strcmp (test_device->val[option].s, value) == 0)
2369 {
2370 DBG (4, "sane_control_option: option %d (%s) not changed\n",
2371 option, test_device->opt[option].name);
2372 break;
2373 }
2374 strcpy (test_device->val[option].s, (SANE_String) value);
2375 myinfo |= SANE_INFO_RELOAD_PARAMS;
2376 myinfo |= SANE_INFO_RELOAD_OPTIONS;
2377 if (strcmp (test_device->val[option].s, SANE_VALUE_SCAN_MODE_COLOR) == 0)
2378 {
2379 test_device->opt[opt_three_pass].cap &= ~SANE_CAP_INACTIVE;
2380 if (test_device->val[opt_three_pass].w == SANE_TRUE)
2381 test_device->opt[opt_three_pass_order].cap
2382 &= ~SANE_CAP_INACTIVE;
2383 }
2384 else
2385 {
2386 test_device->opt[opt_three_pass].cap |= SANE_CAP_INACTIVE;
2387 test_device->opt[opt_three_pass_order].cap |= SANE_CAP_INACTIVE;
2388 }
2389 DBG (4, "sane_control_option: set option %d (%s) to %s\n",
2390 option, test_device->opt[option].name, (SANE_String) value);
2391 break;
2392 case opt_three_pass:
2393 if (test_device->val[option].w == *(SANE_Bool *) value)
2394 {
2395 DBG (4, "sane_control_option: option %d (%s) not changed\n",
2396 option, test_device->opt[option].name);
2397 break;
2398 }
2399 test_device->val[option].w = *(SANE_Bool *) value;
2400 myinfo |= SANE_INFO_RELOAD_PARAMS;
2401 myinfo |= SANE_INFO_RELOAD_OPTIONS;
2402 if (test_device->val[option].w == SANE_TRUE)
2403 test_device->opt[opt_three_pass_order].cap &= ~SANE_CAP_INACTIVE;
2404 else
2405 test_device->opt[opt_three_pass_order].cap |= SANE_CAP_INACTIVE;
2406 DBG (4, "sane_control_option: set option %d (%s) to %s\n",
2407 option, test_device->opt[option].name,
2408 *(SANE_Bool *) value == SANE_TRUE ? "true" : "false");
2409 break;
2410 case opt_hand_scanner:
2411 if (test_device->val[option].w == *(SANE_Bool *) value)
2412 {
2413 DBG (4, "sane_control_option: option %d (%s) not changed\n",
2414 option, test_device->opt[option].name);
2415 break;
2416 }
2417 test_device->val[option].w = *(SANE_Bool *) value;
2418 myinfo |= SANE_INFO_RELOAD_PARAMS;
2419 myinfo |= SANE_INFO_RELOAD_OPTIONS;
2420 if (test_device->val[option].w == SANE_TRUE)
2421 {
2422 test_device->opt[opt_tl_x].cap |= SANE_CAP_INACTIVE;
2423 test_device->opt[opt_tl_y].cap |= SANE_CAP_INACTIVE;
2424 test_device->opt[opt_br_x].cap |= SANE_CAP_INACTIVE;
2425 test_device->opt[opt_br_y].cap |= SANE_CAP_INACTIVE;
2426 }
2427 else
2428 {
2429 test_device->opt[opt_tl_x].cap &= ~SANE_CAP_INACTIVE;
2430 test_device->opt[opt_tl_y].cap &= ~SANE_CAP_INACTIVE;
2431 test_device->opt[opt_br_x].cap &= ~SANE_CAP_INACTIVE;
2432 test_device->opt[opt_br_y].cap &= ~SANE_CAP_INACTIVE;
2433 }
2434 DBG (4, "sane_control_option: set option %d (%s) to %s\n",
2435 option, test_device->opt[option].name,
2436 *(SANE_Bool *) value == SANE_TRUE ? "true" : "false");
2437 break;
2438 case opt_read_limit:
2439 if (test_device->val[option].w == *(SANE_Bool *) value)
2440 {
2441 DBG (4, "sane_control_option: option %d (%s) not changed\n",
2442 option, test_device->opt[option].name);
2443 break;
2444 }
2445 test_device->val[option].w = *(SANE_Bool *) value;
2446 myinfo |= SANE_INFO_RELOAD_OPTIONS;
2447 if (test_device->val[option].w == SANE_TRUE)
2448 test_device->opt[opt_read_limit_size].cap &= ~SANE_CAP_INACTIVE;
2449 else
2450 test_device->opt[opt_read_limit_size].cap |= SANE_CAP_INACTIVE;
2451 DBG (4, "sane_control_option: set option %d (%s) to %s\n",
2452 option, test_device->opt[option].name,
2453 *(SANE_Bool *) value == SANE_TRUE ? "true" : "false");
2454 break;
2455 case opt_read_delay:
2456 if (test_device->val[option].w == *(SANE_Bool *) value)
2457 {
2458 DBG (4, "sane_control_option: option %d (%s) not changed\n",
2459 option, test_device->opt[option].name);
2460 break;
2461 }
2462 test_device->val[option].w = *(SANE_Bool *) value;
2463 myinfo |= SANE_INFO_RELOAD_OPTIONS;
2464 if (test_device->val[option].w == SANE_TRUE)
2465 test_device->opt[opt_read_delay_duration].cap
2466 &= ~SANE_CAP_INACTIVE;
2467 else
2468 test_device->opt[opt_read_delay_duration].cap |=
2469 SANE_CAP_INACTIVE;
2470 DBG (4, "sane_control_option: set option %d (%s) to %s\n", option,
2471 test_device->opt[option].name,
2472 *(SANE_Bool *) value == SANE_TRUE ? "true" : "false");
2473 break;
2474 case opt_enable_test_options:
2475 {
2476 int option_number;
2477 if (test_device->val[option].w == *(SANE_Bool *) value)
2478 {
2479 DBG (4, "sane_control_option: option %d (%s) not changed\n",
2480 option, test_device->opt[option].name);
2481 break;
2482 }
2483 test_device->val[option].w = *(SANE_Bool *) value;
2484 myinfo |= SANE_INFO_RELOAD_OPTIONS;
2485 for (option_number = opt_bool_soft_select_soft_detect;
2486 option_number < num_options; option_number++)
2487 {
2488 if (test_device->opt[option_number].type == SANE_TYPE_GROUP)
2489 continue;
2490 if (test_device->val[option].w == SANE_TRUE)
2491 test_device->opt[option_number].cap &= ~SANE_CAP_INACTIVE;
2492 else
2493 test_device->opt[option_number].cap |= SANE_CAP_INACTIVE;
2494 }
2495 DBG (4, "sane_control_option: set option %d (%s) to %s\n",
2496 option, test_device->opt[option].name,
2497 *(SANE_Bool *) value == SANE_TRUE ? "true" : "false");
2498 break;
2499 }
2500 default:
2501 DBG (1, "sane_control_option: trying to set unexpected option\n");
2502 return SANE_STATUS_INVAL;
2503 }
2504 break;
2505
2506 case SANE_ACTION_GET_VALUE:
2507 switch (option)
2508 {
2509 case opt_num_opts:
2510 *(SANE_Word *) value = num_options;
2511 DBG (4, "sane_control_option: get option 0, value = %d\n",
2512 num_options);
2513 break;
2514 case opt_tl_x: /* Fixed options */
2515 case opt_tl_y:
2516 case opt_br_x:
2517 case opt_br_y:
2518 case opt_resolution:
2519 case opt_fixed:
2520 case opt_fixed_constraint_range:
2521 case opt_fixed_constraint_word_list:
2522 {
2523 *(SANE_Fixed *) value = test_device->val[option].w;
2524 DBG (4,
2525 "sane_control_option: get option %d (%s), value=%.1f %s\n",
2526 option, test_device->opt[option].name,
2527 SANE_UNFIX (*(SANE_Fixed *) value),
2528 test_device->opt[option].unit ==
2529 SANE_UNIT_MM ? "mm" : SANE_UNIT_DPI ? "dpi" : "");
2530 break;
2531 }
2532 case opt_hand_scanner: /* Bool options */
2533 case opt_three_pass:
2534 case opt_invert_endianess:
2535 case opt_read_limit:
2536 case opt_read_delay:
2537 case opt_fuzzy_parameters:
2538 case opt_non_blocking:
2539 case opt_select_fd:
2540 case opt_bool_soft_select_soft_detect:
2541 case opt_bool_hard_select_soft_detect:
2542 case opt_bool_soft_detect:
2543 case opt_enable_test_options:
2544 case opt_bool_soft_select_soft_detect_emulated:
2545 case opt_bool_soft_select_soft_detect_auto:
2546 *(SANE_Bool *) value = test_device->val[option].w;
2547 DBG (4,
2548 "sane_control_option: get option %d (%s), value=%s\n",
2549 option, test_device->opt[option].name,
2550 *(SANE_Bool *) value == SANE_TRUE ? "true" : "false");
2551 break;
2552 case opt_mode: /* String (list) options */
2553 case opt_three_pass_order:
2554 case opt_read_status_code:
2555 case opt_test_picture:
2556 case opt_string:
2557 case opt_string_constraint_string_list:
2558 case opt_string_constraint_long_string_list:
2559 case opt_scan_source:
2560 strcpy (value, test_device->val[option].s);
2561 DBG (4, "sane_control_option: get option %d (%s), value=`%s'\n",
2562 option, test_device->opt[option].name, (SANE_String) value);
2563 break;
2564 case opt_depth: /* Int + word list options */
2565 case opt_read_limit_size:
2566 case opt_ppl_loss:
2567 case opt_read_delay_duration:
2568 case opt_int:
2569 case opt_int_inexact:
2570 case opt_int_constraint_range:
2571 case opt_int_constraint_word_list:
2572 *(SANE_Int *) value = test_device->val[option].w;
2573 DBG (4, "sane_control_option: get option %d (%s), value=%d\n",
2574 option, test_device->opt[option].name, *(SANE_Int *) value);
2575 break;
2576 case opt_int_array: /* Int array */
2577 case opt_int_array_constraint_range:
2578 case opt_gamma_red:
2579 case opt_gamma_green:
2580 case opt_gamma_blue:
2581 case opt_gamma_all:
2582 case opt_int_array_constraint_word_list:
2583 memcpy (value, test_device->val[option].wa,
2584 (size_t) test_device->opt[option].size);
2585 DBG (4, "sane_control_option: get option %d (%s), value=%p\n",
2586 option, test_device->opt[option].name, (void *) value);
2587 break;
2588 default:
2589 DBG (1, "sane_control_option: trying to get unexpected option\n");
2590 return SANE_STATUS_INVAL;
2591 }
2592 break;
2593 default:
2594 DBG (1, "sane_control_option: trying unexpected action %d\n", action);
2595 return SANE_STATUS_INVAL;
2596 }
2597
2598 if (info)
2599 *info = myinfo;
2600
2601 if(myinfo & SANE_INFO_RELOAD_OPTIONS){
2602 SANE_Int i = 0;
2603 for(i=1;i<num_options;i++){
2604 test_device->loaded[i] = 0;
2605 }
2606 }
2607
2608 DBG (4, "sane_control_option: finished, info=%s %s %s \n",
2609 myinfo & SANE_INFO_INEXACT ? "inexact" : "",
2610 myinfo & SANE_INFO_RELOAD_PARAMS ? "reload_parameters" : "",
2611 myinfo & SANE_INFO_RELOAD_OPTIONS ? "reload_options" : "");
2612
2613 return SANE_STATUS_GOOD;
2614 }
2615
2616
2617 SANE_Status
sane_get_parameters(SANE_Handle handle, SANE_Parameters * params)2618 sane_get_parameters (SANE_Handle handle, SANE_Parameters * params)
2619 {
2620 Test_Device *test_device = handle;
2621 SANE_Parameters *p;
2622 double res, tl_x = 0, tl_y = 0, br_x = 0, br_y = 0;
2623 SANE_String text_format, mode;
2624 SANE_Int channels = 1;
2625
2626 DBG (2, "sane_get_parameters: handle=%p, params=%p\n",
2627 (void *) handle, (void *) params);
2628 if (!inited)
2629 {
2630 DBG (1, "sane_get_parameters: not inited, call sane_init() first\n");
2631 return SANE_STATUS_INVAL;
2632 }
2633 if (!check_handle (handle))
2634 {
2635 DBG (1, "sane_get_parameters: handle %p unknown\n", (void *) handle);
2636 return SANE_STATUS_INVAL;
2637 }
2638 if (!test_device->open)
2639 {
2640 DBG (1, "sane_get_parameters: handle %p not open\n", (void *) handle);
2641 return SANE_STATUS_INVAL;
2642 }
2643
2644 res = SANE_UNFIX (test_device->val[opt_resolution].w);
2645 mode = test_device->val[opt_mode].s;
2646 p = &test_device->params;
2647 p->depth = test_device->val[opt_depth].w;
2648
2649 if (test_device->val[opt_hand_scanner].w == SANE_TRUE)
2650 {
2651 tl_x = 0.0;
2652 br_x = 110.0;
2653 tl_y = 0.0;
2654 br_y = 170.0;
2655 p->lines = -1;
2656 test_device->lines = (SANE_Word) (res * (br_y - tl_y) / MM_PER_INCH);
2657 }
2658 else
2659 {
2660 tl_x = SANE_UNFIX (test_device->val[opt_tl_x].w);
2661 tl_y = SANE_UNFIX (test_device->val[opt_tl_y].w);
2662 br_x = SANE_UNFIX (test_device->val[opt_br_x].w);
2663 br_y = SANE_UNFIX (test_device->val[opt_br_y].w);
2664 if (tl_x > br_x)
2665 swap_double (&tl_x, &br_x);
2666 if (tl_y > br_y)
2667 swap_double (&tl_y, &br_y);
2668 test_device->lines = (SANE_Word) (res * (br_y - tl_y) / MM_PER_INCH);
2669 if (test_device->lines < 1)
2670 test_device->lines = 1;
2671 p->lines = test_device->lines;
2672 if (test_device->val[opt_fuzzy_parameters].w == SANE_TRUE
2673 && test_device->scanning == SANE_FALSE)
2674 p->lines *= (SANE_Int) random_factor;
2675 }
2676
2677 if (strcmp (mode, SANE_VALUE_SCAN_MODE_GRAY) == 0)
2678 {
2679 p->format = SANE_FRAME_GRAY;
2680 p->last_frame = SANE_TRUE;
2681 }
2682 else /* Color */
2683 {
2684 if (test_device->val[opt_three_pass].w == SANE_TRUE)
2685 {
2686 if (test_device->val[opt_three_pass_order].s[test_device->pass]
2687 == 'R')
2688 p->format = SANE_FRAME_RED;
2689 else if (test_device->val[opt_three_pass_order].s[test_device->pass]
2690 == 'G')
2691 p->format = SANE_FRAME_GREEN;
2692 else
2693 p->format = SANE_FRAME_BLUE;
2694 if (test_device->pass > 1)
2695 p->last_frame = SANE_TRUE;
2696 else
2697 p->last_frame = SANE_FALSE;
2698 }
2699 else
2700 {
2701 p->format = SANE_FRAME_RGB;
2702 p->last_frame = SANE_TRUE;
2703 }
2704 }
2705
2706 p->pixels_per_line = (SANE_Int) (res * (br_x - tl_x) / MM_PER_INCH);
2707 if (test_device->val[opt_fuzzy_parameters].w == SANE_TRUE
2708 && test_device->scanning == SANE_FALSE)
2709 p->pixels_per_line *= (SANE_Int) random_factor;
2710 if (p->pixels_per_line < 1)
2711 p->pixels_per_line = 1;
2712
2713 if (p->format == SANE_FRAME_RGB)
2714 channels = 3;
2715
2716 if (p->depth == 1)
2717 p->bytes_per_line = channels * (int) ((p->pixels_per_line + 7) / 8);
2718 else /* depth == 8 || depth == 16 */
2719 p->bytes_per_line = channels * p->pixels_per_line * ((p->depth + 7) / 8);
2720
2721 test_device->bytes_per_line = p->bytes_per_line;
2722
2723 p->pixels_per_line -= test_device->val[opt_ppl_loss].w;
2724 if (p->pixels_per_line < 1)
2725 p->pixels_per_line = 1;
2726 test_device->pixels_per_line = p->pixels_per_line;
2727
2728 switch (p->format)
2729 {
2730 case SANE_FRAME_GRAY:
2731 text_format = "gray";
2732 break;
2733 case SANE_FRAME_RGB:
2734 text_format = "rgb";
2735 break;
2736 case SANE_FRAME_RED:
2737 text_format = "red";
2738 break;
2739 case SANE_FRAME_GREEN:
2740 text_format = "green";
2741 break;
2742 case SANE_FRAME_BLUE:
2743 text_format = "blue";
2744 break;
2745 default:
2746 text_format = "unknown";
2747 break;
2748 }
2749
2750 DBG (3, "sane_get_parameters: format=%s\n", text_format);
2751 DBG (3, "sane_get_parameters: last_frame=%s\n",
2752 p->last_frame ? "true" : "false");
2753 DBG (3, "sane_get_parameters: lines=%d\n", p->lines);
2754 DBG (3, "sane_get_parameters: depth=%d\n", p->depth);
2755 DBG (3, "sane_get_parameters: pixels_per_line=%d\n", p->pixels_per_line);
2756 DBG (3, "sane_get_parameters: bytes_per_line=%d\n", p->bytes_per_line);
2757
2758 if (params)
2759 *params = *p;
2760
2761 return SANE_STATUS_GOOD;
2762 }
2763
2764 SANE_Status
sane_start(SANE_Handle handle)2765 sane_start (SANE_Handle handle)
2766 {
2767 Test_Device *test_device = handle;
2768 int pipe_descriptor[2];
2769
2770 DBG (2, "sane_start: handle=%p\n", handle);
2771 if (!inited)
2772 {
2773 DBG (1, "sane_start: not inited, call sane_init() first\n");
2774 return SANE_STATUS_INVAL;
2775 }
2776 if (!check_handle (handle))
2777 {
2778 DBG (1, "sane_start: handle %p unknown\n", handle);
2779 return SANE_STATUS_INVAL;
2780 }
2781 if (!test_device->open)
2782 {
2783 DBG (1, "sane_start: not open\n");
2784 return SANE_STATUS_INVAL;
2785 }
2786 if (test_device->scanning
2787 && (test_device->val[opt_three_pass].w == SANE_FALSE
2788 && strcmp (test_device->val[opt_mode].s, SANE_VALUE_SCAN_MODE_COLOR) == 0))
2789 {
2790 DBG (1, "sane_start: already scanning\n");
2791 return SANE_STATUS_INVAL;
2792 }
2793 if (strcmp (test_device->val[opt_mode].s, SANE_VALUE_SCAN_MODE_COLOR) == 0
2794 && test_device->val[opt_three_pass].w == SANE_TRUE
2795 && test_device->pass > 2)
2796 {
2797 DBG (1, "sane_start: already in last pass of three\n");
2798 return SANE_STATUS_INVAL;
2799 }
2800
2801 if (test_device->pass == 0)
2802 {
2803 test_device->number_of_scans++;
2804 DBG (3, "sane_start: scanning page %d\n", test_device->number_of_scans);
2805
2806 if ((strcmp (test_device->val[opt_scan_source].s, "Automatic Document Feeder") == 0) &&
2807 (((test_device->number_of_scans) % 11) == 0))
2808 {
2809 DBG (1, "sane_start: Document feeder is out of documents!\n");
2810 return SANE_STATUS_NO_DOCS;
2811 }
2812 }
2813
2814 test_device->scanning = SANE_TRUE;
2815 test_device->cancelled = SANE_FALSE;
2816 test_device->eof = SANE_FALSE;
2817 test_device->bytes_total = 0;
2818
2819 sane_get_parameters (handle, 0);
2820
2821 if (test_device->params.lines == 0)
2822 {
2823 DBG (1, "sane_start: lines == 0\n");
2824 test_device->scanning = SANE_FALSE;
2825 return SANE_STATUS_INVAL;
2826 }
2827 if (test_device->params.pixels_per_line == 0)
2828 {
2829 DBG (1, "sane_start: pixels_per_line == 0\n");
2830 test_device->scanning = SANE_FALSE;
2831 return SANE_STATUS_INVAL;
2832 }
2833 if (test_device->params.bytes_per_line == 0)
2834 {
2835 DBG (1, "sane_start: bytes_per_line == 0\n");
2836 test_device->scanning = SANE_FALSE;
2837 return SANE_STATUS_INVAL;
2838 }
2839
2840 if (pipe (pipe_descriptor) < 0)
2841 {
2842 DBG (1, "sane_start: pipe failed (%s)\n", strerror (errno));
2843 return SANE_STATUS_IO_ERROR;
2844 }
2845
2846 /* create reader routine as new process or thread */
2847 test_device->pipe = pipe_descriptor[0];
2848 test_device->reader_fds = pipe_descriptor[1];
2849 test_device->reader_pid =
2850 sanei_thread_begin (reader_task, (void *) test_device);
2851
2852 if (!sanei_thread_is_valid (test_device->reader_pid))
2853 {
2854 DBG (1, "sane_start: sanei_thread_begin failed (%s)\n",
2855 strerror (errno));
2856 return SANE_STATUS_NO_MEM;
2857 }
2858
2859 if (sanei_thread_is_forked ())
2860 {
2861 close (test_device->reader_fds);
2862 test_device->reader_fds = -1;
2863 }
2864
2865 return SANE_STATUS_GOOD;
2866 }
2867
2868
2869 SANE_Status
sane_read(SANE_Handle handle, SANE_Byte * data, SANE_Int max_length, SANE_Int * length)2870 sane_read (SANE_Handle handle, SANE_Byte * data,
2871 SANE_Int max_length, SANE_Int * length)
2872 {
2873 Test_Device *test_device = handle;
2874 SANE_Int max_scan_length;
2875 ssize_t bytes_read;
2876 size_t read_count;
2877 size_t bytes_total = (size_t) test_device->lines * (size_t) test_device->bytes_per_line;
2878
2879
2880 DBG (4, "sane_read: handle=%p, data=%p, max_length = %d, length=%p\n",
2881 handle, (void *) data, max_length, (void *) length);
2882 if (!inited)
2883 {
2884 DBG (1, "sane_read: not inited, call sane_init() first\n");
2885 return SANE_STATUS_INVAL;
2886 }
2887 if (!check_handle (handle))
2888 {
2889 DBG (1, "sane_read: handle %p unknown\n", handle);
2890 return SANE_STATUS_INVAL;
2891 }
2892 if (!length)
2893 {
2894 DBG (1, "sane_read: length == NULL\n");
2895 return SANE_STATUS_INVAL;
2896 }
2897
2898 if (strcmp (test_device->val[opt_read_status_code].s, "Default") != 0)
2899 {
2900 SANE_String_Const sc = test_device->val[opt_read_status_code].s;
2901 DBG (3, "sane_read: setting return status to %s\n", sc);
2902 if (strcmp (sc, "SANE_STATUS_UNSUPPORTED") == 0)
2903 return SANE_STATUS_UNSUPPORTED;
2904 if (strcmp (sc, "SANE_STATUS_CANCELLED") == 0)
2905 return SANE_STATUS_CANCELLED;
2906 if (strcmp (sc, "SANE_STATUS_DEVICE_BUSY") == 0)
2907 return SANE_STATUS_DEVICE_BUSY;
2908 if (strcmp (sc, "SANE_STATUS_INVAL") == 0)
2909 return SANE_STATUS_INVAL;
2910 if (strcmp (sc, "SANE_STATUS_EOF") == 0)
2911 return SANE_STATUS_EOF;
2912 if (strcmp (sc, "SANE_STATUS_JAMMED") == 0)
2913 return SANE_STATUS_JAMMED;
2914 if (strcmp (sc, "SANE_STATUS_NO_DOCS") == 0)
2915 return SANE_STATUS_NO_DOCS;
2916 if (strcmp (sc, "SANE_STATUS_COVER_OPEN") == 0)
2917 return SANE_STATUS_COVER_OPEN;
2918 if (strcmp (sc, "SANE_STATUS_IO_ERROR") == 0)
2919 return SANE_STATUS_IO_ERROR;
2920 if (strcmp (sc, "SANE_STATUS_NO_MEM") == 0)
2921 return SANE_STATUS_NO_MEM;
2922 if (strcmp (sc, "SANE_STATUS_ACCESS_DENIED") == 0)
2923 return SANE_STATUS_ACCESS_DENIED;
2924 }
2925
2926 max_scan_length = max_length;
2927 if (test_device->val[opt_read_limit].w == SANE_TRUE
2928 && test_device->val[opt_read_limit_size].w < max_scan_length)
2929 {
2930 max_scan_length = test_device->val[opt_read_limit_size].w;
2931 DBG (3, "sane_read: limiting max_scan_length to %d bytes\n",
2932 max_scan_length);
2933 }
2934
2935 *length = 0;
2936
2937 if (!data)
2938 {
2939 DBG (1, "sane_read: data == NULL\n");
2940 return SANE_STATUS_INVAL;
2941 }
2942 if (!test_device->open)
2943 {
2944 DBG (1, "sane_read: not open\n");
2945 return SANE_STATUS_INVAL;
2946 }
2947 if (test_device->cancelled)
2948 {
2949 DBG (1, "sane_read: scan was cancelled\n");
2950 return SANE_STATUS_CANCELLED;
2951 }
2952 if (test_device->eof)
2953 {
2954 DBG (2, "sane_read: No more data available, sending EOF\n");
2955 return SANE_STATUS_EOF;
2956 }
2957 if (!test_device->scanning)
2958 {
2959 DBG (1, "sane_read: not scanning (call sane_start first)\n");
2960 return SANE_STATUS_INVAL;
2961 }
2962 read_count = (size_t) max_scan_length;
2963
2964 bytes_read = read (test_device->pipe, data, read_count);
2965 if (bytes_read == 0
2966 || ((size_t) bytes_read + (size_t) test_device->bytes_total >= bytes_total))
2967 {
2968 SANE_Status status;
2969 DBG (2, "sane_read: EOF reached\n");
2970 status = finish_pass (test_device);
2971 if (status != SANE_STATUS_GOOD)
2972 {
2973 DBG (1, "sane_read: finish_pass returned `%s'\n",
2974 sane_strstatus (status));
2975 return status;
2976 }
2977 test_device->eof = SANE_TRUE;
2978 if (strcmp (test_device->val[opt_mode].s, SANE_VALUE_SCAN_MODE_COLOR) == 0
2979 && test_device->val[opt_three_pass].w == SANE_TRUE)
2980 {
2981 test_device->pass++;
2982 if (test_device->pass > 2)
2983 test_device->pass = 0;
2984 }
2985 if (bytes_read == 0)
2986 return SANE_STATUS_EOF;
2987 }
2988 else if (bytes_read < 0)
2989 {
2990 if (errno == EAGAIN)
2991 {
2992 DBG (2, "sane_read: no data available, try again\n");
2993 return SANE_STATUS_GOOD;
2994 }
2995 else
2996 {
2997 DBG (1, "sane_read: read returned error: %s\n", strerror (errno));
2998 return SANE_STATUS_IO_ERROR;
2999 }
3000 }
3001 *length = (SANE_Int) bytes_read;
3002 test_device->bytes_total += (size_t) bytes_read;
3003
3004 DBG (2, "sane_read: read %zu bytes of %zu, total %zu\n", (size_t) bytes_read,
3005 (size_t) max_scan_length, (size_t) test_device->bytes_total);
3006 return SANE_STATUS_GOOD;
3007 }
3008
3009 void
sane_cancel(SANE_Handle handle)3010 sane_cancel (SANE_Handle handle)
3011 {
3012 Test_Device *test_device = handle;
3013
3014 DBG (2, "sane_cancel: handle = %p\n", handle);
3015 if (!inited)
3016 {
3017 DBG (1, "sane_cancel: not inited, call sane_init() first\n");
3018 return;
3019 }
3020 if (!check_handle (handle))
3021 {
3022 DBG (1, "sane_cancel: handle %p unknown\n", handle);
3023 return;
3024 }
3025 if (!test_device->open)
3026 {
3027 DBG (1, "sane_cancel: not open\n");
3028 return;
3029 }
3030 if (test_device->cancelled)
3031 {
3032 DBG (1, "sane_cancel: scan already cancelled\n");
3033 return;
3034 }
3035 if (!test_device->scanning)
3036 {
3037 DBG (2, "sane_cancel: scan is already finished\n");
3038 return;
3039 }
3040 finish_pass (test_device);
3041 test_device->cancelled = SANE_TRUE;
3042 test_device->scanning = SANE_FALSE;
3043 test_device->eof = SANE_FALSE;
3044 test_device->pass = 0;
3045 return;
3046 }
3047
3048 SANE_Status
sane_set_io_mode(SANE_Handle handle, SANE_Bool non_blocking)3049 sane_set_io_mode (SANE_Handle handle, SANE_Bool non_blocking)
3050 {
3051 Test_Device *test_device = handle;
3052
3053 DBG (2, "sane_set_io_mode: handle = %p, non_blocking = %d\n", handle,
3054 non_blocking);
3055 if (!inited)
3056 {
3057 DBG (1, "sane_set_io_mode: not inited, call sane_init() first\n");
3058 return SANE_STATUS_INVAL;
3059 }
3060 if (!check_handle (handle))
3061 {
3062 DBG (1, "sane_set_io_mode: handle %p unknown\n", handle);
3063 return SANE_STATUS_INVAL;
3064 }
3065 if (!test_device->open)
3066 {
3067 DBG (1, "sane_set_io_mode: not open\n");
3068 return SANE_STATUS_INVAL;
3069 }
3070 if (!test_device->scanning)
3071 {
3072 DBG (1, "sane_set_io_mode: not scanning\n");
3073 return SANE_STATUS_INVAL;
3074 }
3075 if (test_device->val[opt_non_blocking].w == SANE_TRUE)
3076 {
3077 if (fcntl (test_device->pipe,
3078 F_SETFL, non_blocking ? O_NONBLOCK : 0) < 0)
3079 {
3080 DBG (1, "sane_set_io_mode: can't set io mode");
3081 return SANE_STATUS_INVAL;
3082 }
3083 }
3084 else
3085 {
3086 DBG (1, "sane_set_io_mode: unsupported\n");
3087 if (non_blocking)
3088 return SANE_STATUS_UNSUPPORTED;
3089 }
3090 return SANE_STATUS_GOOD;
3091 }
3092
3093 SANE_Status
sane_get_select_fd(SANE_Handle handle, SANE_Int * fd)3094 sane_get_select_fd (SANE_Handle handle, SANE_Int * fd)
3095 {
3096 Test_Device *test_device = handle;
3097
3098 DBG (2, "sane_get_select_fd: handle = %p, fd %s 0\n", handle,
3099 fd ? "!=" : "=");
3100 if (!inited)
3101 {
3102 DBG (1, "sane_get_select_fd: not inited, call sane_init() first\n");
3103 return SANE_STATUS_INVAL;
3104 }
3105 if (!check_handle (handle))
3106 {
3107 DBG (1, "sane_get_select_fd: handle %p unknown\n", handle);
3108 return SANE_STATUS_INVAL;
3109 }
3110 if (!test_device->open)
3111 {
3112 DBG (1, "sane_get_select_fd: not open\n");
3113 return SANE_STATUS_INVAL;
3114 }
3115 if (!test_device->scanning)
3116 {
3117 DBG (1, "sane_get_select_fd: not scanning\n");
3118 return SANE_STATUS_INVAL;
3119 }
3120 if (test_device->val[opt_select_fd].w == SANE_TRUE)
3121 {
3122 *fd = test_device->pipe;
3123 return SANE_STATUS_GOOD;
3124 }
3125 DBG(1,"sane_get_select_fd: unsupported\n");
3126 return SANE_STATUS_UNSUPPORTED;
3127 }
3128