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_values()1258 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
1436 static SANE_Status
read_option_str_list(SANE_String line,SANE_String option_string,parameter_type p_type,void * value,SANE_String_Const * string_list)1437 read_option_str_list (SANE_String line, SANE_String option_string,
1438 parameter_type p_type, void *value,
1439 SANE_String_Const *string_list)
1440 {
1441 SANE_String new_value = NULL;
1442
1443 SANE_Status ret = read_option (line, option_string, p_type, &new_value);
1444 if (ret != SANE_STATUS_GOOD)
1445 {
1446 if (new_value)
1447 {
1448 free(new_value);
1449 }
1450 return ret;
1451 }
1452
1453 for (SANE_String_Const *option = string_list; *option; option++)
1454 {
1455 if (strcmp (*option, new_value) == 0)
1456 {
1457
1458 if (*(SANE_String*) value)
1459 {
1460 free (*(SANE_String*) value);
1461 }
1462 *(SANE_String*) value = new_value;
1463
1464 return SANE_STATUS_GOOD;
1465 }
1466 }
1467
1468 return SANE_STATUS_INVAL;
1469 }
1470
1471
1472 static SANE_Status
reader_process(Test_Device * test_device,SANE_Int fd)1473 reader_process (Test_Device * test_device, SANE_Int fd)
1474 {
1475 SANE_Status status;
1476 size_t byte_count = 0;
1477 size_t bytes_total;
1478 SANE_Byte *buffer = 0;
1479 ssize_t bytes_written = 0;
1480 size_t buffer_size = 0, write_count = 0;
1481
1482 DBG (2, "(child) reader_process: test_device=%p, fd=%d\n",
1483 (void *) test_device, fd);
1484
1485 bytes_total = (size_t) test_device->lines * (size_t) test_device->bytes_per_line;
1486 status = init_picture_buffer (test_device, &buffer, &buffer_size);
1487 if (status != SANE_STATUS_GOOD)
1488 return status;
1489
1490 DBG (2, "(child) reader_process: buffer=%p, buffersize=%lu\n",
1491 (void *) buffer, (u_long) buffer_size);
1492
1493 while (byte_count < bytes_total)
1494 {
1495 if (write_count == 0)
1496 {
1497 write_count = buffer_size;
1498 if (byte_count + (size_t) write_count > bytes_total)
1499 write_count = (size_t) bytes_total - (size_t) byte_count;
1500
1501 if (test_device->val[opt_read_delay].w == SANE_TRUE)
1502 usleep ((useconds_t) test_device->val[opt_read_delay_duration].w);
1503 }
1504 bytes_written = write (fd, buffer, write_count);
1505 if (bytes_written < 0)
1506 {
1507 DBG (1, "(child) reader_process: write returned %s\n",
1508 strerror (errno));
1509 return SANE_STATUS_IO_ERROR;
1510 }
1511 byte_count += (size_t) bytes_written;
1512 DBG (4, "(child) reader_process: wrote %ld bytes of %lu (%zu total)\n",
1513 bytes_written, write_count, byte_count);
1514 write_count -= (size_t) bytes_written;
1515 }
1516
1517 free (buffer);
1518
1519 if (sanei_thread_is_forked ())
1520 {
1521 DBG (4, "(child) reader_process: finished, wrote %zu bytes, expected %zu "
1522 "bytes, now waiting\n", byte_count, bytes_total);
1523 while (SANE_TRUE)
1524 sleep (10);
1525 DBG (4, "(child) reader_process: this should have never happened...");
1526 close (fd);
1527 }
1528 else
1529 {
1530 DBG (4, "(child) reader_process: finished, wrote %zu bytes, expected %zu "
1531 "bytes\n", byte_count, bytes_total);
1532 }
1533 return SANE_STATUS_GOOD;
1534 }
1535
1536 /*
1537 * this code either runs in child or thread context...
1538 */
1539 static int
reader_task(void * data)1540 reader_task (void *data)
1541 {
1542 SANE_Status status;
1543 struct SIGACTION act;
1544 struct Test_Device *test_device = (struct Test_Device *) data;
1545
1546 DBG (2, "reader_task started\n");
1547 if (sanei_thread_is_forked ())
1548 {
1549 DBG (3, "reader_task started (forked)\n");
1550 close (test_device->pipe);
1551 test_device->pipe = -1;
1552
1553 }
1554 else
1555 {
1556 DBG (3, "reader_task started (as thread)\n");
1557 }
1558
1559 memset (&act, 0, sizeof (act));
1560 sigaction (SIGTERM, &act, 0);
1561
1562 status = reader_process (test_device, test_device->reader_fds);
1563 DBG (2, "(child) reader_task: reader_process finished (%s)\n",
1564 sane_strstatus (status));
1565 return (int) status;
1566 }
1567
1568 static SANE_Status
finish_pass(Test_Device * test_device)1569 finish_pass (Test_Device * test_device)
1570 {
1571 SANE_Status return_status = SANE_STATUS_GOOD;
1572
1573 DBG (2, "finish_pass: test_device=%p\n", (void *) test_device);
1574 test_device->scanning = SANE_FALSE;
1575 if (test_device->pipe >= 0)
1576 {
1577 DBG (2, "finish_pass: closing pipe\n");
1578 close (test_device->pipe);
1579 DBG (2, "finish_pass: pipe closed\n");
1580 test_device->pipe = -1;
1581 }
1582 if (sanei_thread_is_valid (test_device->reader_pid))
1583 {
1584 int status;
1585 SANE_Pid pid;
1586
1587 DBG (2, "finish_pass: terminating reader process %ld\n",
1588 (long) test_device->reader_pid);
1589 sanei_thread_kill (test_device->reader_pid);
1590 pid = sanei_thread_waitpid (test_device->reader_pid, &status);
1591 if (!sanei_thread_is_valid (pid))
1592 {
1593 DBG (1,
1594 "finish_pass: sanei_thread_waitpid failed, already terminated? (%s)\n",
1595 strerror (errno));
1596 }
1597 else
1598 {
1599 DBG (2, "finish_pass: reader process terminated with status: %s\n",
1600 sane_strstatus (status));
1601 }
1602 sanei_thread_invalidate (test_device->reader_pid);
1603 }
1604 /* this happens when running in thread context... */
1605 if (test_device->reader_fds >= 0)
1606 {
1607 DBG (2, "finish_pass: closing reader pipe\n");
1608 close (test_device->reader_fds);
1609 DBG (2, "finish_pass: reader pipe closed\n");
1610 test_device->reader_fds = -1;
1611 }
1612 return return_status;
1613 }
1614
1615 static void
print_options(Test_Device * test_device)1616 print_options (Test_Device * test_device)
1617 {
1618 SANE_Option_Descriptor *od;
1619 SANE_Word option_number;
1620 SANE_Char caps[1024];
1621
1622 for (option_number = 0; option_number < num_options; option_number++)
1623 {
1624 od = &test_device->opt[option_number];
1625 DBG (0, "-----> number: %d\n", option_number);
1626 DBG (0, " name: `%s'\n", od->name);
1627 DBG (0, " title: `%s'\n", od->title);
1628 DBG (0, " description: `%s'\n", od->desc);
1629 DBG (0, " type: %s\n",
1630 od->type == SANE_TYPE_BOOL ? "SANE_TYPE_BOOL" :
1631 od->type == SANE_TYPE_INT ? "SANE_TYPE_INT" :
1632 od->type == SANE_TYPE_FIXED ? "SANE_TYPE_FIXED" :
1633 od->type == SANE_TYPE_STRING ? "SANE_TYPE_STRING" :
1634 od->type == SANE_TYPE_BUTTON ? "SANE_TYPE_BUTTON" :
1635 od->type == SANE_TYPE_GROUP ? "SANE_TYPE_GROUP" : "unknown");
1636 DBG (0, " unit: %s\n",
1637 od->unit == SANE_UNIT_NONE ? "SANE_UNIT_NONE" :
1638 od->unit == SANE_UNIT_PIXEL ? "SANE_UNIT_PIXEL" :
1639 od->unit == SANE_UNIT_BIT ? "SANE_UNIT_BIT" :
1640 od->unit == SANE_UNIT_MM ? "SANE_UNIT_MM" :
1641 od->unit == SANE_UNIT_DPI ? "SANE_UNIT_DPI" :
1642 od->unit == SANE_UNIT_PERCENT ? "SANE_UNIT_PERCENT" :
1643 od->unit == SANE_UNIT_MICROSECOND ? "SANE_UNIT_MICROSECOND" :
1644 "unknown");
1645 DBG (0, " size: %d\n", od->size);
1646 caps[0] = '\0';
1647 if (od->cap & SANE_CAP_SOFT_SELECT)
1648 strcat (caps, "SANE_CAP_SOFT_SELECT ");
1649 if (od->cap & SANE_CAP_HARD_SELECT)
1650 strcat (caps, "SANE_CAP_HARD_SELECT ");
1651 if (od->cap & SANE_CAP_SOFT_DETECT)
1652 strcat (caps, "SANE_CAP_SOFT_DETECT ");
1653 if (od->cap & SANE_CAP_EMULATED)
1654 strcat (caps, "SANE_CAP_EMULATED ");
1655 if (od->cap & SANE_CAP_AUTOMATIC)
1656 strcat (caps, "SANE_CAP_AUTOMATIC ");
1657 if (od->cap & SANE_CAP_INACTIVE)
1658 strcat (caps, "SANE_CAP_INACTIVE ");
1659 if (od->cap & SANE_CAP_ADVANCED)
1660 strcat (caps, "SANE_CAP_ADVANCED ");
1661 DBG (0, " capabilities: %s\n", caps);
1662 DBG (0, "constraint type: %s\n",
1663 od->constraint_type == SANE_CONSTRAINT_NONE ?
1664 "SANE_CONSTRAINT_NONE" :
1665 od->constraint_type == SANE_CONSTRAINT_RANGE ?
1666 "SANE_CONSTRAINT_RANGE" :
1667 od->constraint_type == SANE_CONSTRAINT_WORD_LIST ?
1668 "SANE_CONSTRAINT_WORD_LIST" :
1669 od->constraint_type == SANE_CONSTRAINT_STRING_LIST ?
1670 "SANE_CONSTRAINT_STRING_LIST" : "unknown");
1671 }
1672 }
1673
1674 /***************************** SANE API ****************************/
1675
1676 SANE_Status
sane_init(SANE_Int * __sane_unused__ version_code,SANE_Auth_Callback __sane_unused__ authorize)1677 sane_init (SANE_Int * __sane_unused__ version_code, SANE_Auth_Callback __sane_unused__ authorize)
1678 {
1679 FILE *fp;
1680 SANE_Int linenumber;
1681 SANE_Char line[PATH_MAX], *word = NULL;
1682 SANE_String_Const cp;
1683 SANE_Device *sane_device;
1684 Test_Device *test_device, *previous_device;
1685 SANE_Int num;
1686
1687 DBG_INIT ();
1688 sanei_thread_init ();
1689
1690 test_device = 0;
1691 previous_device = 0;
1692
1693 DBG (1, "sane_init: SANE test backend version %d.%d.%d from %s\n", SANE_CURRENT_MAJOR,
1694 SANE_CURRENT_MINOR, BUILD, PACKAGE_STRING);
1695
1696 if (version_code)
1697 *version_code = SANE_VERSION_CODE (SANE_CURRENT_MAJOR, SANE_CURRENT_MINOR, BUILD);
1698
1699 if (inited)
1700 DBG (3, "sane_init: warning: already inited\n");
1701
1702 // Setup initial values of string options. Call free initially in case we've
1703 // already called sane_init and these values are already non-null.
1704 free (init_mode);
1705 init_mode = strdup (SANE_VALUE_SCAN_MODE_GRAY);
1706 if (!init_mode)
1707 goto fail;
1708
1709 free (init_three_pass_order);
1710 init_three_pass_order = strdup ("RGB");
1711 if (!init_three_pass_order)
1712 goto fail;
1713
1714 free (init_scan_source);
1715 init_scan_source = strdup ("Flatbed");
1716 if (!init_scan_source)
1717 goto fail;
1718
1719 free (init_test_picture);
1720 init_test_picture = strdup ("Solid black");
1721 if (!init_test_picture)
1722 goto fail;
1723
1724 free (init_read_status_code);
1725 init_read_status_code = strdup ("Default");
1726 if (!init_read_status_code)
1727 goto fail;
1728
1729 free (init_string);
1730 init_string = strdup ("This is the contents of the string option. "
1731 "Fill some more words to see how the frontend behaves.");
1732 if (!init_string)
1733 goto fail;
1734
1735 free (init_string_constraint_string_list);
1736 init_string_constraint_string_list = strdup ("First entry");
1737 if (!init_string_constraint_string_list)
1738 goto fail;
1739
1740 free (init_string_constraint_long_string_list);
1741 init_string_constraint_long_string_list = strdup ("First entry");
1742 if (!init_string_constraint_long_string_list)
1743 goto fail;
1744
1745 fp = sanei_config_open (TEST_CONFIG_FILE);
1746 if (fp)
1747 {
1748 linenumber = 0;
1749 DBG (4, "sane_init: reading config file `%s'\n", TEST_CONFIG_FILE);
1750 while (sanei_config_read (line, sizeof (line), fp))
1751 {
1752 if (word)
1753 free (word);
1754 word = NULL;
1755 linenumber++;
1756
1757 cp = sanei_config_get_string (line, &word);
1758 if (!word || cp == line)
1759 {
1760 DBG (5,
1761 "sane_init: config file line %3d: ignoring empty line\n",
1762 linenumber);
1763 continue;
1764 }
1765 if (word[0] == '#')
1766 {
1767 DBG (5,
1768 "sane_init: config file line %3d: ignoring comment line\n",
1769 linenumber);
1770 continue;
1771 }
1772
1773 DBG (5, "sane_init: config file line %3d: `%s'\n",
1774 linenumber, line);
1775
1776 if (read_option (line, "number_of_devices", param_int,
1777 &init_number_of_devices) == SANE_STATUS_GOOD)
1778 continue;
1779
1780 if (read_option_str_list (line, "mode", param_string,
1781 &init_mode, mode_list) == SANE_STATUS_GOOD)
1782 continue;
1783
1784 if (read_option (line, "hand-scanner", param_bool,
1785 &init_hand_scanner) == SANE_STATUS_GOOD)
1786 continue;
1787 if (read_option (line, "three-pass", param_bool,
1788 &init_three_pass) == SANE_STATUS_GOOD)
1789 continue;
1790 if (read_option_str_list (line, "three-pass-order", param_string,
1791 &init_three_pass_order, order_list) == SANE_STATUS_GOOD)
1792 continue;
1793 if (read_option (line, "resolution_min", param_fixed,
1794 &resolution_range.min) == SANE_STATUS_GOOD)
1795 continue;
1796 if (read_option (line, "resolution_max", param_fixed,
1797 &resolution_range.max) == SANE_STATUS_GOOD)
1798 continue;
1799 if (read_option (line, "resolution_quant", param_fixed,
1800 &resolution_range.quant) == SANE_STATUS_GOOD)
1801 continue;
1802 if (read_option (line, "resolution", param_fixed,
1803 &init_resolution) == SANE_STATUS_GOOD)
1804 continue;
1805 if (read_option (line, "depth", param_int,
1806 &init_depth) == SANE_STATUS_GOOD)
1807 continue;
1808 if (read_option_str_list (line, "scan-source", param_string,
1809 &init_scan_source, source_list) == SANE_STATUS_GOOD)
1810 continue;
1811 if (read_option_str_list (line, "test-picture", param_string,
1812 &init_test_picture, test_picture_list) == SANE_STATUS_GOOD)
1813 continue;
1814 if (read_option (line, "invert-endianess", param_bool,
1815 &init_invert_endianess) == SANE_STATUS_GOOD)
1816 continue;
1817 if (read_option (line, "read-limit", param_bool,
1818 &init_read_limit) == SANE_STATUS_GOOD)
1819 continue;
1820 if (read_option (line, "read-limit-size", param_int,
1821 &init_read_limit_size) == SANE_STATUS_GOOD)
1822 continue;
1823 if (read_option (line, "read-delay", param_bool,
1824 &init_read_delay) == SANE_STATUS_GOOD)
1825 continue;
1826 if (read_option (line, "read-delay-duration", param_int,
1827 &init_read_delay_duration) == SANE_STATUS_GOOD)
1828 continue;
1829 if (read_option_str_list (line, "read-status-code", param_string,
1830 &init_read_status_code, read_status_code_list) == SANE_STATUS_GOOD)
1831 continue;
1832 if (read_option (line, "ppl-loss", param_int,
1833 &init_ppl_loss) == SANE_STATUS_GOOD)
1834 continue;
1835 if (read_option (line, "fuzzy-parameters", param_bool,
1836 &init_fuzzy_parameters) == SANE_STATUS_GOOD)
1837 continue;
1838 if (read_option (line, "non-blocking", param_bool,
1839 &init_non_blocking) == SANE_STATUS_GOOD)
1840 continue;
1841 if (read_option (line, "select-fd", param_bool,
1842 &init_select_fd) == SANE_STATUS_GOOD)
1843 continue;
1844 if (read_option (line, "enable-test-options", param_bool,
1845 &init_enable_test_options) == SANE_STATUS_GOOD)
1846 continue;
1847 if (read_option (line, "geometry_min", param_fixed,
1848 &geometry_range.min) == SANE_STATUS_GOOD)
1849 continue;
1850 if (read_option (line, "geometry_max", param_fixed,
1851 &geometry_range.max) == SANE_STATUS_GOOD)
1852 continue;
1853 if (read_option (line, "geometry_quant", param_fixed,
1854 &geometry_range.quant) == SANE_STATUS_GOOD)
1855 continue;
1856 if (read_option (line, "tl_x", param_fixed,
1857 &init_tl_x) == SANE_STATUS_GOOD)
1858 continue;
1859 if (read_option (line, "tl_y", param_fixed,
1860 &init_tl_y) == SANE_STATUS_GOOD)
1861 continue;
1862 if (read_option (line, "br_x", param_fixed,
1863 &init_br_x) == SANE_STATUS_GOOD)
1864 continue;
1865 if (read_option (line, "br_y", param_fixed,
1866 &init_br_y) == SANE_STATUS_GOOD)
1867 continue;
1868
1869 DBG (3, "sane-init: I don't know how to handle option `%s'\n",
1870 word);
1871 } /* while */
1872 if (word)
1873 free (word);
1874 fclose (fp);
1875 } /* if */
1876 else
1877 {
1878 DBG (3, "sane_init: couldn't find config file (%s), using default "
1879 "settings\n", TEST_CONFIG_FILE);
1880 }
1881
1882 /* create devices */
1883 sane_device_list =
1884 malloc ((size_t) (init_number_of_devices + 1) * sizeof (sane_device));
1885 if (!sane_device_list)
1886 goto fail;
1887 for (num = 0; num < init_number_of_devices; num++)
1888 {
1889 SANE_Char number_string[PATH_MAX];
1890
1891 test_device = calloc (sizeof (*test_device), 1);
1892 if (!test_device)
1893 goto fail_device;
1894 test_device->sane.vendor = "Noname";
1895 test_device->sane.type = "virtual device";
1896 test_device->sane.model = "frontend-tester";
1897 snprintf (number_string, sizeof (number_string), "%d", num);
1898 number_string[sizeof (number_string) - 1] = '\0';
1899 test_device->name = strdup (number_string);
1900 if (!test_device->name)
1901 goto fail_name;
1902 test_device->sane.name = test_device->name;
1903 if (previous_device)
1904 previous_device->next = test_device;
1905 previous_device = test_device;
1906 if (num == 0)
1907 first_test_device = test_device;
1908 sane_device_list[num] = &test_device->sane;
1909 test_device->open = SANE_FALSE;
1910 test_device->eof = SANE_FALSE;
1911 test_device->scanning = SANE_FALSE;
1912 test_device->cancelled = SANE_FALSE;
1913 test_device->options_initialized = SANE_FALSE;
1914 sanei_thread_initialize (test_device->reader_pid);
1915 test_device->pipe = -1;
1916 DBG (4, "sane_init: new device: `%s' is a %s %s %s\n",
1917 test_device->sane.name, test_device->sane.vendor,
1918 test_device->sane.model, test_device->sane.type);
1919 }
1920 test_device->next = 0;
1921 sane_device_list[num] = 0;
1922 srand ((unsigned int) time (NULL));
1923 random_factor = ((double) rand ()) / RAND_MAX + 0.5;
1924 inited = SANE_TRUE;
1925 return SANE_STATUS_GOOD;
1926
1927 fail_name:
1928 // test_device refers to the last device we were creating, which has not
1929 // yet been added to the linked list of devices.
1930 free (test_device);
1931 fail_device:
1932 // Now, iterate through the linked list of devices to clean up any successful
1933 // devices.
1934 test_device = first_test_device;
1935 while (test_device)
1936 {
1937 previous_device = test_device;
1938 test_device = test_device->next;
1939 cleanup_test_device (previous_device);
1940 }
1941 free (sane_device_list);
1942 fail:
1943 cleanup_initial_string_values ();
1944 return SANE_STATUS_NO_MEM;
1945 }
1946
1947 void
sane_exit(void)1948 sane_exit (void)
1949 {
1950 Test_Device *test_device, *previous_device;
1951
1952 DBG (2, "sane_exit\n");
1953 if (!inited)
1954 {
1955 DBG (1, "sane_exit: not inited, call sane_init() first\n");
1956 return;
1957 }
1958
1959 test_device = first_test_device;
1960 while (test_device)
1961 {
1962 DBG (4, "sane_exit: freeing device %s\n", test_device->name);
1963 previous_device = test_device;
1964 test_device = test_device->next;
1965 cleanup_test_device (previous_device);
1966 }
1967 DBG (4, "sane_exit: freeing device list\n");
1968 if (sane_device_list)
1969 free (sane_device_list);
1970 sane_device_list = NULL;
1971 first_test_device = NULL;
1972
1973 cleanup_initial_string_values ();
1974 inited = SANE_FALSE;
1975 return;
1976 }
1977
1978
1979 SANE_Status
sane_get_devices(const SANE_Device *** device_list,SANE_Bool local_only)1980 sane_get_devices (const SANE_Device *** device_list, SANE_Bool local_only)
1981 {
1982
1983 DBG (2, "sane_get_devices: device_list=%p, local_only=%d\n",
1984 (void *) device_list, local_only);
1985 if (!inited)
1986 {
1987 DBG (1, "sane_get_devices: not inited, call sane_init() first\n");
1988 return SANE_STATUS_INVAL;
1989 }
1990
1991 if (!device_list)
1992 {
1993 DBG (1, "sane_get_devices: device_list == 0\n");
1994 return SANE_STATUS_INVAL;
1995 }
1996 *device_list = (const SANE_Device **) sane_device_list;
1997 return SANE_STATUS_GOOD;
1998 }
1999
2000 SANE_Status
sane_open(SANE_String_Const devicename,SANE_Handle * handle)2001 sane_open (SANE_String_Const devicename, SANE_Handle * handle)
2002 {
2003 Test_Device *test_device = first_test_device;
2004 SANE_Status status;
2005
2006 DBG (2, "sane_open: devicename = \"%s\", handle=%p\n",
2007 devicename, (void *) handle);
2008 if (!inited)
2009 {
2010 DBG (1, "sane_open: not inited, call sane_init() first\n");
2011 return SANE_STATUS_INVAL;
2012 }
2013
2014 if (!handle)
2015 {
2016 DBG (1, "sane_open: handle == 0\n");
2017 return SANE_STATUS_INVAL;
2018 }
2019
2020 if (!devicename || strlen (devicename) == 0)
2021 {
2022 DBG (2, "sane_open: device name NULL or empty\n");
2023 }
2024 else
2025 {
2026 for (test_device = first_test_device; test_device;
2027 test_device = test_device->next)
2028 {
2029 if (strcmp (devicename, test_device->name) == 0)
2030 break;
2031 }
2032 }
2033 if (!test_device)
2034 {
2035 DBG (1, "sane_open: device `%s' not found\n", devicename);
2036 return SANE_STATUS_INVAL;
2037 }
2038 if (test_device->open)
2039 {
2040 DBG (1, "sane_open: device `%s' already open\n", devicename);
2041 return SANE_STATUS_DEVICE_BUSY;
2042 }
2043 DBG (2, "sane_open: opening device `%s', handle = %p\n", test_device->name,
2044 (void *) test_device);
2045 test_device->open = SANE_TRUE;
2046 *handle = test_device;
2047
2048 if (!test_device->options_initialized) {
2049 status = init_options (test_device);
2050 if (status != SANE_STATUS_GOOD)
2051 return status;
2052 test_device->options_initialized = SANE_TRUE;
2053 }
2054
2055 test_device->open = SANE_TRUE;
2056 test_device->scanning = SANE_FALSE;
2057 test_device->cancelled = SANE_FALSE;
2058 test_device->eof = SANE_FALSE;
2059 test_device->bytes_total = 0;
2060 test_device->pass = 0;
2061 test_device->number_of_scans = 0;
2062
2063 return SANE_STATUS_GOOD;
2064 }
2065
2066 void
sane_close(SANE_Handle handle)2067 sane_close (SANE_Handle handle)
2068 {
2069 Test_Device *test_device = handle;
2070
2071 DBG (2, "sane_close: handle=%p\n", (void *) handle);
2072 if (!inited)
2073 {
2074 DBG (1, "sane_close: not inited, call sane_init() first\n");
2075 return;
2076 }
2077
2078 if (!check_handle (handle))
2079 {
2080 DBG (1, "sane_close: handle %p unknown\n", (void *) handle);
2081 return;
2082 }
2083 if (!test_device->open)
2084 {
2085 DBG (1, "sane_close: handle %p not open\n", (void *) handle);
2086 return;
2087 }
2088 test_device->open = SANE_FALSE;
2089 return;
2090 }
2091
2092 const SANE_Option_Descriptor *
sane_get_option_descriptor(SANE_Handle handle,SANE_Int option)2093 sane_get_option_descriptor (SANE_Handle handle, SANE_Int option)
2094 {
2095 Test_Device *test_device = handle;
2096
2097 DBG (4, "sane_get_option_descriptor: handle=%p, option = %d\n",
2098 (void *) handle, option);
2099 if (!inited)
2100 {
2101 DBG (1, "sane_get_option_descriptor: not inited, call sane_init() "
2102 "first\n");
2103 return 0;
2104 }
2105
2106 if (!check_handle (handle))
2107 {
2108 DBG (1, "sane_get_option_descriptor: handle %p unknown\n",
2109 (void *) handle);
2110 return 0;
2111 }
2112 if (!test_device->open)
2113 {
2114 DBG (1, "sane_get_option_descriptor: not open\n");
2115 return 0;
2116 }
2117 if (option < 0 || option >= num_options)
2118 {
2119 DBG (3, "sane_get_option_descriptor: option < 0 || "
2120 "option > num_options\n");
2121 return 0;
2122 }
2123
2124 test_device->loaded[option] = 1;
2125
2126 return &test_device->opt[option];
2127 }
2128
2129 SANE_Status
sane_control_option(SANE_Handle handle,SANE_Int option,SANE_Action action,void * value,SANE_Int * info)2130 sane_control_option (SANE_Handle handle, SANE_Int option, SANE_Action action,
2131 void *value, SANE_Int * info)
2132 {
2133 Test_Device *test_device = handle;
2134 SANE_Int myinfo = 0;
2135 SANE_Status status;
2136
2137 DBG (4, "sane_control_option: handle=%p, opt=%d, act=%d, val=%p, info=%p\n",
2138 (void *) handle, option, action, (void *) value, (void *) info);
2139 if (!inited)
2140 {
2141 DBG (1, "sane_control_option: not inited, call sane_init() first\n");
2142 return SANE_STATUS_INVAL;
2143 }
2144
2145 if (!check_handle (handle))
2146 {
2147 DBG (1, "sane_control_option: handle %p unknown\n", (void *) handle);
2148 return SANE_STATUS_INVAL;
2149 }
2150 if (!test_device->open)
2151 {
2152 DBG (1, "sane_control_option: not open\n");
2153 return SANE_STATUS_INVAL;
2154 }
2155 if (test_device->scanning)
2156 {
2157 DBG (1, "sane_control_option: is scanning\n");
2158 return SANE_STATUS_INVAL;
2159 }
2160 if (option < 0 || option >= num_options)
2161 {
2162 DBG (1, "sane_control_option: option < 0 || option > num_options\n");
2163 return SANE_STATUS_INVAL;
2164 }
2165
2166 if (!test_device->loaded[option])
2167 {
2168 DBG (1, "sane_control_option: option not loaded\n");
2169 return SANE_STATUS_INVAL;
2170 }
2171
2172 if (!SANE_OPTION_IS_ACTIVE (test_device->opt[option].cap))
2173 {
2174 DBG (1, "sane_control_option: option is inactive\n");
2175 return SANE_STATUS_INVAL;
2176 }
2177
2178 if (test_device->opt[option].type == SANE_TYPE_GROUP)
2179 {
2180 DBG (1, "sane_control_option: option is a group\n");
2181 return SANE_STATUS_INVAL;
2182 }
2183
2184 switch (action)
2185 {
2186 case SANE_ACTION_SET_AUTO:
2187 if (!SANE_OPTION_IS_SETTABLE (test_device->opt[option].cap))
2188 {
2189 DBG (1, "sane_control_option: option is not setable\n");
2190 return SANE_STATUS_INVAL;
2191 }
2192 if (!(test_device->opt[option].cap & SANE_CAP_AUTOMATIC))
2193 {
2194 DBG (1, "sane_control_option: option is not automatically "
2195 "setable\n");
2196 return SANE_STATUS_INVAL;
2197 }
2198 switch (option)
2199 {
2200 case opt_bool_soft_select_soft_detect_auto:
2201 test_device->val[option].w = SANE_TRUE;
2202 DBG (4, "sane_control_option: set option %d (%s) automatically "
2203 "to %s\n", option, test_device->opt[option].name,
2204 test_device->val[option].w == SANE_TRUE ? "true" : "false");
2205 break;
2206
2207 default:
2208 DBG (1, "sane_control_option: trying to automatically set "
2209 "unexpected option\n");
2210 return SANE_STATUS_INVAL;
2211 }
2212 break;
2213
2214 case SANE_ACTION_SET_VALUE:
2215 if (!SANE_OPTION_IS_SETTABLE (test_device->opt[option].cap))
2216 {
2217 DBG (1, "sane_control_option: option is not setable\n");
2218 return SANE_STATUS_INVAL;
2219 }
2220 status = sanei_constrain_value (&test_device->opt[option],
2221 value, &myinfo);
2222 if (status != SANE_STATUS_GOOD)
2223 {
2224 DBG (3, "sane_control_option: sanei_constrain_value returned %s\n",
2225 sane_strstatus (status));
2226 return status;
2227 }
2228 switch (option)
2229 {
2230 case opt_tl_x: /* Fixed with parameter reloading */
2231 case opt_tl_y:
2232 case opt_br_x:
2233 case opt_br_y:
2234 case opt_resolution:
2235 if (test_device->val[option].w == *(SANE_Fixed *) value)
2236 {
2237 DBG (4, "sane_control_option: option %d (%s) not changed\n",
2238 option, test_device->opt[option].name);
2239 break;
2240 }
2241 test_device->val[option].w = *(SANE_Fixed *) value;
2242 myinfo |= SANE_INFO_RELOAD_PARAMS;
2243 DBG (4, "sane_control_option: set option %d (%s) to %.0f %s\n",
2244 option, test_device->opt[option].name,
2245 SANE_UNFIX (*(SANE_Fixed *) value),
2246 test_device->opt[option].unit == SANE_UNIT_MM ? "mm" : "dpi");
2247 break;
2248 case opt_fixed: /* Fixed */
2249 case opt_fixed_constraint_range:
2250 if (test_device->val[option].w == *(SANE_Fixed *) value)
2251 {
2252 DBG (4, "sane_control_option: option %d (%s) not changed\n",
2253 option, test_device->opt[option].name);
2254 break;
2255 }
2256 test_device->val[option].w = *(SANE_Fixed *) value;
2257 DBG (4, "sane_control_option: set option %d (%s) to %.0f\n",
2258 option, test_device->opt[option].name,
2259 SANE_UNFIX (*(SANE_Fixed *) value));
2260 break;
2261 case opt_read_limit_size: /* Int */
2262 case opt_ppl_loss:
2263 case opt_read_delay_duration:
2264 case opt_int:
2265 case opt_int_constraint_range:
2266 if (test_device->val[option].w == *(SANE_Int *) value)
2267 {
2268 DBG (4, "sane_control_option: option %d (%s) not changed\n",
2269 option, test_device->opt[option].name);
2270 break;
2271 }
2272 test_device->val[option].w = *(SANE_Int *) value;
2273 DBG (4, "sane_control_option: set option %d (%s) to %d\n",
2274 option, test_device->opt[option].name, *(SANE_Int *) value);
2275 break;
2276 case opt_int_inexact:
2277 if (test_device->val[option].w == *(SANE_Int *) value)
2278 {
2279 DBG (4, "sane_control_option: option %d (%s) not changed\n",
2280 option, test_device->opt[option].name);
2281 break;
2282 }
2283 *(SANE_Int *) value += 1;
2284 test_device->val[option].w = *(SANE_Int *) value;
2285 myinfo |= SANE_INFO_INEXACT;
2286 DBG (4, "sane_control_option: set option %d (%s) to %d\n",
2287 option, test_device->opt[option].name, *(SANE_Int *) value);
2288 break;
2289 case opt_fuzzy_parameters: /* Bool with parameter reloading */
2290 if (test_device->val[option].w == *(SANE_Bool *) value)
2291 {
2292 DBG (4, "sane_control_option: option %d (%s) not changed\n",
2293 option, test_device->opt[option].name);
2294 break;
2295 }
2296 test_device->val[option].w = *(SANE_Bool *) value;
2297 myinfo |= SANE_INFO_RELOAD_PARAMS;
2298 DBG (4, "sane_control_option: set option %d (%s) to %s\n",
2299 option, test_device->opt[option].name,
2300 *(SANE_Bool *) value == SANE_TRUE ? "true" : "false");
2301 break;
2302 case opt_invert_endianess: /* Bool */
2303 case opt_non_blocking:
2304 case opt_select_fd:
2305 case opt_bool_soft_select_soft_detect:
2306 case opt_bool_soft_select_soft_detect_auto:
2307 case opt_bool_soft_select_soft_detect_emulated:
2308 if (test_device->val[option].w == *(SANE_Bool *) value)
2309 {
2310 DBG (4, "sane_control_option: option %d (%s) not changed\n",
2311 option, test_device->opt[option].name);
2312 break;
2313 }
2314 test_device->val[option].w = *(SANE_Bool *) value;
2315 DBG (4, "sane_control_option: set option %d (%s) to %s\n",
2316 option, test_device->opt[option].name,
2317 *(SANE_Bool *) value == SANE_TRUE ? "true" : "false");
2318 break;
2319 case opt_depth: /* Word list with parameter and options reloading */
2320 if (test_device->val[option].w == *(SANE_Int *) value)
2321 {
2322 DBG (4, "sane_control_option: option %d (%s) not changed\n",
2323 option, test_device->opt[option].name);
2324 break;
2325 }
2326 test_device->val[option].w = *(SANE_Int *) value;
2327 if (test_device->val[option].w == 16)
2328 test_device->opt[opt_invert_endianess].cap &= ~SANE_CAP_INACTIVE;
2329 else
2330 test_device->opt[opt_invert_endianess].cap |= SANE_CAP_INACTIVE;
2331
2332 myinfo |= SANE_INFO_RELOAD_PARAMS;
2333 myinfo |= SANE_INFO_RELOAD_OPTIONS;
2334 DBG (4, "sane_control_option: set option %d (%s) to %d\n",
2335 option, test_device->opt[option].name, *(SANE_Int *) value);
2336 break;
2337 case opt_three_pass_order: /* String list with parameter reload */
2338 if (strcmp (test_device->val[option].s, value) == 0)
2339 {
2340 DBG (4, "sane_control_option: option %d (%s) not changed\n",
2341 option, test_device->opt[option].name);
2342 break;
2343 }
2344 strcpy (test_device->val[option].s, (SANE_String) value);
2345 myinfo |= SANE_INFO_RELOAD_PARAMS;
2346 DBG (4, "sane_control_option: set option %d (%s) to %s\n",
2347 option, test_device->opt[option].name, (SANE_String) value);
2348 break;
2349 case opt_int_constraint_word_list: /* Word list */
2350 case opt_fixed_constraint_word_list:
2351 if (test_device->val[option].w == *(SANE_Int *) value)
2352 {
2353 DBG (4, "sane_control_option: option %d (%s) not changed\n",
2354 option, test_device->opt[option].name);
2355 break;
2356 }
2357 test_device->val[option].w = *(SANE_Int *) value;
2358 DBG (4, "sane_control_option: set option %d (%s) to %d\n",
2359 option, test_device->opt[option].name, *(SANE_Int *) value);
2360 break;
2361 case opt_read_status_code: /* String (list) */
2362 case opt_test_picture:
2363 case opt_string:
2364 case opt_string_constraint_string_list:
2365 case opt_string_constraint_long_string_list:
2366 case opt_scan_source:
2367 if (strcmp (test_device->val[option].s, value) == 0)
2368 {
2369 DBG (4, "sane_control_option: option %d (%s) not changed\n",
2370 option, test_device->opt[option].name);
2371 break;
2372 }
2373 strcpy (test_device->val[option].s, (SANE_String) value);
2374 DBG (4, "sane_control_option: set option %d (%s) to `%s'\n",
2375 option, test_device->opt[option].name, (SANE_String) value);
2376 break;
2377 case opt_int_array: /* Word array */
2378 case opt_int_array_constraint_range:
2379 case opt_gamma_red:
2380 case opt_gamma_green:
2381 case opt_gamma_blue:
2382 case opt_gamma_all:
2383 case opt_int_array_constraint_word_list:
2384 memcpy (test_device->val[option].wa, value,
2385 (size_t) test_device->opt[option].size);
2386 DBG (4, "sane_control_option: set option %d (%s) to %p\n",
2387 option, test_device->opt[option].name, (void *) value);
2388 if (option == opt_gamma_all) {
2389 print_gamma_table(gamma_all, GAMMA_ALL_SIZE);
2390 }
2391 if (option == opt_gamma_red) {
2392 print_gamma_table(gamma_red, GAMMA_RED_SIZE);
2393 }
2394 break;
2395 /* options with side-effects */
2396 case opt_print_options:
2397 DBG (4, "sane_control_option: set option %d (%s)\n",
2398 option, test_device->opt[option].name);
2399 print_options (test_device);
2400 break;
2401 case opt_button:
2402 DBG (0, "Yes! You pressed me!\n");
2403 DBG (4, "sane_control_option: set option %d (%s)\n",
2404 option, test_device->opt[option].name);
2405 break;
2406 case opt_mode:
2407 if (strcmp (test_device->val[option].s, value) == 0)
2408 {
2409 DBG (4, "sane_control_option: option %d (%s) not changed\n",
2410 option, test_device->opt[option].name);
2411 break;
2412 }
2413 strcpy (test_device->val[option].s, (SANE_String) value);
2414 myinfo |= SANE_INFO_RELOAD_PARAMS;
2415 myinfo |= SANE_INFO_RELOAD_OPTIONS;
2416 if (strcmp (test_device->val[option].s, SANE_VALUE_SCAN_MODE_COLOR) == 0)
2417 {
2418 test_device->opt[opt_three_pass].cap &= ~SANE_CAP_INACTIVE;
2419 if (test_device->val[opt_three_pass].w == SANE_TRUE)
2420 test_device->opt[opt_three_pass_order].cap
2421 &= ~SANE_CAP_INACTIVE;
2422 }
2423 else
2424 {
2425 test_device->opt[opt_three_pass].cap |= SANE_CAP_INACTIVE;
2426 test_device->opt[opt_three_pass_order].cap |= SANE_CAP_INACTIVE;
2427 }
2428 DBG (4, "sane_control_option: set option %d (%s) to %s\n",
2429 option, test_device->opt[option].name, (SANE_String) value);
2430 break;
2431 case opt_three_pass:
2432 if (test_device->val[option].w == *(SANE_Bool *) value)
2433 {
2434 DBG (4, "sane_control_option: option %d (%s) not changed\n",
2435 option, test_device->opt[option].name);
2436 break;
2437 }
2438 test_device->val[option].w = *(SANE_Bool *) value;
2439 myinfo |= SANE_INFO_RELOAD_PARAMS;
2440 myinfo |= SANE_INFO_RELOAD_OPTIONS;
2441 if (test_device->val[option].w == SANE_TRUE)
2442 test_device->opt[opt_three_pass_order].cap &= ~SANE_CAP_INACTIVE;
2443 else
2444 test_device->opt[opt_three_pass_order].cap |= SANE_CAP_INACTIVE;
2445 DBG (4, "sane_control_option: set option %d (%s) to %s\n",
2446 option, test_device->opt[option].name,
2447 *(SANE_Bool *) value == SANE_TRUE ? "true" : "false");
2448 break;
2449 case opt_hand_scanner:
2450 if (test_device->val[option].w == *(SANE_Bool *) value)
2451 {
2452 DBG (4, "sane_control_option: option %d (%s) not changed\n",
2453 option, test_device->opt[option].name);
2454 break;
2455 }
2456 test_device->val[option].w = *(SANE_Bool *) value;
2457 myinfo |= SANE_INFO_RELOAD_PARAMS;
2458 myinfo |= SANE_INFO_RELOAD_OPTIONS;
2459 if (test_device->val[option].w == SANE_TRUE)
2460 {
2461 test_device->opt[opt_tl_x].cap |= SANE_CAP_INACTIVE;
2462 test_device->opt[opt_tl_y].cap |= SANE_CAP_INACTIVE;
2463 test_device->opt[opt_br_x].cap |= SANE_CAP_INACTIVE;
2464 test_device->opt[opt_br_y].cap |= SANE_CAP_INACTIVE;
2465 }
2466 else
2467 {
2468 test_device->opt[opt_tl_x].cap &= ~SANE_CAP_INACTIVE;
2469 test_device->opt[opt_tl_y].cap &= ~SANE_CAP_INACTIVE;
2470 test_device->opt[opt_br_x].cap &= ~SANE_CAP_INACTIVE;
2471 test_device->opt[opt_br_y].cap &= ~SANE_CAP_INACTIVE;
2472 }
2473 DBG (4, "sane_control_option: set option %d (%s) to %s\n",
2474 option, test_device->opt[option].name,
2475 *(SANE_Bool *) value == SANE_TRUE ? "true" : "false");
2476 break;
2477 case opt_read_limit:
2478 if (test_device->val[option].w == *(SANE_Bool *) value)
2479 {
2480 DBG (4, "sane_control_option: option %d (%s) not changed\n",
2481 option, test_device->opt[option].name);
2482 break;
2483 }
2484 test_device->val[option].w = *(SANE_Bool *) value;
2485 myinfo |= SANE_INFO_RELOAD_OPTIONS;
2486 if (test_device->val[option].w == SANE_TRUE)
2487 test_device->opt[opt_read_limit_size].cap &= ~SANE_CAP_INACTIVE;
2488 else
2489 test_device->opt[opt_read_limit_size].cap |= SANE_CAP_INACTIVE;
2490 DBG (4, "sane_control_option: set option %d (%s) to %s\n",
2491 option, test_device->opt[option].name,
2492 *(SANE_Bool *) value == SANE_TRUE ? "true" : "false");
2493 break;
2494 case opt_read_delay:
2495 if (test_device->val[option].w == *(SANE_Bool *) value)
2496 {
2497 DBG (4, "sane_control_option: option %d (%s) not changed\n",
2498 option, test_device->opt[option].name);
2499 break;
2500 }
2501 test_device->val[option].w = *(SANE_Bool *) value;
2502 myinfo |= SANE_INFO_RELOAD_OPTIONS;
2503 if (test_device->val[option].w == SANE_TRUE)
2504 test_device->opt[opt_read_delay_duration].cap
2505 &= ~SANE_CAP_INACTIVE;
2506 else
2507 test_device->opt[opt_read_delay_duration].cap |=
2508 SANE_CAP_INACTIVE;
2509 DBG (4, "sane_control_option: set option %d (%s) to %s\n", option,
2510 test_device->opt[option].name,
2511 *(SANE_Bool *) value == SANE_TRUE ? "true" : "false");
2512 break;
2513 case opt_enable_test_options:
2514 {
2515 int option_number;
2516 if (test_device->val[option].w == *(SANE_Bool *) value)
2517 {
2518 DBG (4, "sane_control_option: option %d (%s) not changed\n",
2519 option, test_device->opt[option].name);
2520 break;
2521 }
2522 test_device->val[option].w = *(SANE_Bool *) value;
2523 myinfo |= SANE_INFO_RELOAD_OPTIONS;
2524 for (option_number = opt_bool_soft_select_soft_detect;
2525 option_number < num_options; option_number++)
2526 {
2527 if (test_device->opt[option_number].type == SANE_TYPE_GROUP)
2528 continue;
2529 if (test_device->val[option].w == SANE_TRUE)
2530 test_device->opt[option_number].cap &= ~SANE_CAP_INACTIVE;
2531 else
2532 test_device->opt[option_number].cap |= SANE_CAP_INACTIVE;
2533 }
2534 DBG (4, "sane_control_option: set option %d (%s) to %s\n",
2535 option, test_device->opt[option].name,
2536 *(SANE_Bool *) value == SANE_TRUE ? "true" : "false");
2537 break;
2538 }
2539 default:
2540 DBG (1, "sane_control_option: trying to set unexpected option\n");
2541 return SANE_STATUS_INVAL;
2542 }
2543 break;
2544
2545 case SANE_ACTION_GET_VALUE:
2546 switch (option)
2547 {
2548 case opt_num_opts:
2549 *(SANE_Word *) value = num_options;
2550 DBG (4, "sane_control_option: get option 0, value = %d\n",
2551 num_options);
2552 break;
2553 case opt_tl_x: /* Fixed options */
2554 case opt_tl_y:
2555 case opt_br_x:
2556 case opt_br_y:
2557 case opt_resolution:
2558 case opt_fixed:
2559 case opt_fixed_constraint_range:
2560 case opt_fixed_constraint_word_list:
2561 {
2562 *(SANE_Fixed *) value = test_device->val[option].w;
2563 DBG (4,
2564 "sane_control_option: get option %d (%s), value=%.1f %s\n",
2565 option, test_device->opt[option].name,
2566 SANE_UNFIX (*(SANE_Fixed *) value),
2567 test_device->opt[option].unit ==
2568 SANE_UNIT_MM ? "mm" : SANE_UNIT_DPI ? "dpi" : "");
2569 break;
2570 }
2571 case opt_hand_scanner: /* Bool options */
2572 case opt_three_pass:
2573 case opt_invert_endianess:
2574 case opt_read_limit:
2575 case opt_read_delay:
2576 case opt_fuzzy_parameters:
2577 case opt_non_blocking:
2578 case opt_select_fd:
2579 case opt_bool_soft_select_soft_detect:
2580 case opt_bool_hard_select_soft_detect:
2581 case opt_bool_soft_detect:
2582 case opt_enable_test_options:
2583 case opt_bool_soft_select_soft_detect_emulated:
2584 case opt_bool_soft_select_soft_detect_auto:
2585 *(SANE_Bool *) value = test_device->val[option].w;
2586 DBG (4,
2587 "sane_control_option: get option %d (%s), value=%s\n",
2588 option, test_device->opt[option].name,
2589 *(SANE_Bool *) value == SANE_TRUE ? "true" : "false");
2590 break;
2591 case opt_mode: /* String (list) options */
2592 case opt_three_pass_order:
2593 case opt_read_status_code:
2594 case opt_test_picture:
2595 case opt_string:
2596 case opt_string_constraint_string_list:
2597 case opt_string_constraint_long_string_list:
2598 case opt_scan_source:
2599 strcpy (value, test_device->val[option].s);
2600 DBG (4, "sane_control_option: get option %d (%s), value=`%s'\n",
2601 option, test_device->opt[option].name, (SANE_String) value);
2602 break;
2603 case opt_depth: /* Int + word list options */
2604 case opt_read_limit_size:
2605 case opt_ppl_loss:
2606 case opt_read_delay_duration:
2607 case opt_int:
2608 case opt_int_inexact:
2609 case opt_int_constraint_range:
2610 case opt_int_constraint_word_list:
2611 *(SANE_Int *) value = test_device->val[option].w;
2612 DBG (4, "sane_control_option: get option %d (%s), value=%d\n",
2613 option, test_device->opt[option].name, *(SANE_Int *) value);
2614 break;
2615 case opt_int_array: /* Int array */
2616 case opt_int_array_constraint_range:
2617 case opt_gamma_red:
2618 case opt_gamma_green:
2619 case opt_gamma_blue:
2620 case opt_gamma_all:
2621 case opt_int_array_constraint_word_list:
2622 memcpy (value, test_device->val[option].wa,
2623 (size_t) test_device->opt[option].size);
2624 DBG (4, "sane_control_option: get option %d (%s), value=%p\n",
2625 option, test_device->opt[option].name, (void *) value);
2626 break;
2627 default:
2628 DBG (1, "sane_control_option: trying to get unexpected option\n");
2629 return SANE_STATUS_INVAL;
2630 }
2631 break;
2632 default:
2633 DBG (1, "sane_control_option: trying unexpected action %d\n", action);
2634 return SANE_STATUS_INVAL;
2635 }
2636
2637 if (info)
2638 *info = myinfo;
2639
2640 if(myinfo & SANE_INFO_RELOAD_OPTIONS){
2641 SANE_Int i = 0;
2642 for(i=1;i<num_options;i++){
2643 test_device->loaded[i] = 0;
2644 }
2645 }
2646
2647 DBG (4, "sane_control_option: finished, info=%s %s %s \n",
2648 myinfo & SANE_INFO_INEXACT ? "inexact" : "",
2649 myinfo & SANE_INFO_RELOAD_PARAMS ? "reload_parameters" : "",
2650 myinfo & SANE_INFO_RELOAD_OPTIONS ? "reload_options" : "");
2651
2652 return SANE_STATUS_GOOD;
2653 }
2654
2655
2656 SANE_Status
sane_get_parameters(SANE_Handle handle,SANE_Parameters * params)2657 sane_get_parameters (SANE_Handle handle, SANE_Parameters * params)
2658 {
2659 Test_Device *test_device = handle;
2660 SANE_Parameters *p;
2661 double res, tl_x = 0, tl_y = 0, br_x = 0, br_y = 0;
2662 SANE_String text_format, mode;
2663 SANE_Int channels = 1;
2664
2665 DBG (2, "sane_get_parameters: handle=%p, params=%p\n",
2666 (void *) handle, (void *) params);
2667 if (!inited)
2668 {
2669 DBG (1, "sane_get_parameters: not inited, call sane_init() first\n");
2670 return SANE_STATUS_INVAL;
2671 }
2672 if (!check_handle (handle))
2673 {
2674 DBG (1, "sane_get_parameters: handle %p unknown\n", (void *) handle);
2675 return SANE_STATUS_INVAL;
2676 }
2677 if (!test_device->open)
2678 {
2679 DBG (1, "sane_get_parameters: handle %p not open\n", (void *) handle);
2680 return SANE_STATUS_INVAL;
2681 }
2682
2683 res = SANE_UNFIX (test_device->val[opt_resolution].w);
2684 mode = test_device->val[opt_mode].s;
2685 p = &test_device->params;
2686 p->depth = test_device->val[opt_depth].w;
2687
2688 if (test_device->val[opt_hand_scanner].w == SANE_TRUE)
2689 {
2690 tl_x = 0.0;
2691 br_x = 110.0;
2692 tl_y = 0.0;
2693 br_y = 170.0;
2694 p->lines = -1;
2695 test_device->lines = (SANE_Word) (res * (br_y - tl_y) / MM_PER_INCH);
2696 }
2697 else
2698 {
2699 tl_x = SANE_UNFIX (test_device->val[opt_tl_x].w);
2700 tl_y = SANE_UNFIX (test_device->val[opt_tl_y].w);
2701 br_x = SANE_UNFIX (test_device->val[opt_br_x].w);
2702 br_y = SANE_UNFIX (test_device->val[opt_br_y].w);
2703 if (tl_x > br_x)
2704 swap_double (&tl_x, &br_x);
2705 if (tl_y > br_y)
2706 swap_double (&tl_y, &br_y);
2707 test_device->lines = (SANE_Word) (res * (br_y - tl_y) / MM_PER_INCH);
2708 if (test_device->lines < 1)
2709 test_device->lines = 1;
2710 p->lines = test_device->lines;
2711 if (test_device->val[opt_fuzzy_parameters].w == SANE_TRUE
2712 && test_device->scanning == SANE_FALSE)
2713 p->lines *= (SANE_Int) random_factor;
2714 }
2715
2716 if (strcmp (mode, SANE_VALUE_SCAN_MODE_GRAY) == 0)
2717 {
2718 p->format = SANE_FRAME_GRAY;
2719 p->last_frame = SANE_TRUE;
2720 }
2721 else /* Color */
2722 {
2723 if (test_device->val[opt_three_pass].w == SANE_TRUE)
2724 {
2725 if (test_device->val[opt_three_pass_order].s[test_device->pass]
2726 == 'R')
2727 p->format = SANE_FRAME_RED;
2728 else if (test_device->val[opt_three_pass_order].s[test_device->pass]
2729 == 'G')
2730 p->format = SANE_FRAME_GREEN;
2731 else
2732 p->format = SANE_FRAME_BLUE;
2733 if (test_device->pass > 1)
2734 p->last_frame = SANE_TRUE;
2735 else
2736 p->last_frame = SANE_FALSE;
2737 }
2738 else
2739 {
2740 p->format = SANE_FRAME_RGB;
2741 p->last_frame = SANE_TRUE;
2742 }
2743 }
2744
2745 p->pixels_per_line = (SANE_Int) (res * (br_x - tl_x) / MM_PER_INCH);
2746 if (test_device->val[opt_fuzzy_parameters].w == SANE_TRUE
2747 && test_device->scanning == SANE_FALSE)
2748 p->pixels_per_line *= (SANE_Int) random_factor;
2749 if (p->pixels_per_line < 1)
2750 p->pixels_per_line = 1;
2751
2752 if (p->format == SANE_FRAME_RGB)
2753 channels = 3;
2754
2755 if (p->depth == 1)
2756 p->bytes_per_line = channels * (int) ((p->pixels_per_line + 7) / 8);
2757 else /* depth == 8 || depth == 16 */
2758 p->bytes_per_line = channels * p->pixels_per_line * ((p->depth + 7) / 8);
2759
2760 test_device->bytes_per_line = p->bytes_per_line;
2761
2762 p->pixels_per_line -= test_device->val[opt_ppl_loss].w;
2763 if (p->pixels_per_line < 1)
2764 p->pixels_per_line = 1;
2765 test_device->pixels_per_line = p->pixels_per_line;
2766
2767 switch (p->format)
2768 {
2769 case SANE_FRAME_GRAY:
2770 text_format = "gray";
2771 break;
2772 case SANE_FRAME_RGB:
2773 text_format = "rgb";
2774 break;
2775 case SANE_FRAME_RED:
2776 text_format = "red";
2777 break;
2778 case SANE_FRAME_GREEN:
2779 text_format = "green";
2780 break;
2781 case SANE_FRAME_BLUE:
2782 text_format = "blue";
2783 break;
2784 default:
2785 text_format = "unknown";
2786 break;
2787 }
2788
2789 DBG (3, "sane_get_parameters: format=%s\n", text_format);
2790 DBG (3, "sane_get_parameters: last_frame=%s\n",
2791 p->last_frame ? "true" : "false");
2792 DBG (3, "sane_get_parameters: lines=%d\n", p->lines);
2793 DBG (3, "sane_get_parameters: depth=%d\n", p->depth);
2794 DBG (3, "sane_get_parameters: pixels_per_line=%d\n", p->pixels_per_line);
2795 DBG (3, "sane_get_parameters: bytes_per_line=%d\n", p->bytes_per_line);
2796
2797 if (params)
2798 *params = *p;
2799
2800 return SANE_STATUS_GOOD;
2801 }
2802
2803 SANE_Status
sane_start(SANE_Handle handle)2804 sane_start (SANE_Handle handle)
2805 {
2806 Test_Device *test_device = handle;
2807 int pipe_descriptor[2];
2808
2809 DBG (2, "sane_start: handle=%p\n", handle);
2810 if (!inited)
2811 {
2812 DBG (1, "sane_start: not inited, call sane_init() first\n");
2813 return SANE_STATUS_INVAL;
2814 }
2815 if (!check_handle (handle))
2816 {
2817 DBG (1, "sane_start: handle %p unknown\n", handle);
2818 return SANE_STATUS_INVAL;
2819 }
2820 if (!test_device->open)
2821 {
2822 DBG (1, "sane_start: not open\n");
2823 return SANE_STATUS_INVAL;
2824 }
2825 if (test_device->scanning
2826 && (test_device->val[opt_three_pass].w == SANE_FALSE
2827 && strcmp (test_device->val[opt_mode].s, SANE_VALUE_SCAN_MODE_COLOR) == 0))
2828 {
2829 DBG (1, "sane_start: already scanning\n");
2830 return SANE_STATUS_INVAL;
2831 }
2832 if (strcmp (test_device->val[opt_mode].s, SANE_VALUE_SCAN_MODE_COLOR) == 0
2833 && test_device->val[opt_three_pass].w == SANE_TRUE
2834 && test_device->pass > 2)
2835 {
2836 DBG (1, "sane_start: already in last pass of three\n");
2837 return SANE_STATUS_INVAL;
2838 }
2839
2840 if (test_device->pass == 0)
2841 {
2842 test_device->number_of_scans++;
2843 DBG (3, "sane_start: scanning page %d\n", test_device->number_of_scans);
2844
2845 if ((strcmp (test_device->val[opt_scan_source].s, "Automatic Document Feeder") == 0) &&
2846 (((test_device->number_of_scans) % 11) == 0))
2847 {
2848 DBG (1, "sane_start: Document feeder is out of documents!\n");
2849 return SANE_STATUS_NO_DOCS;
2850 }
2851 }
2852
2853 test_device->scanning = SANE_TRUE;
2854 test_device->cancelled = SANE_FALSE;
2855 test_device->eof = SANE_FALSE;
2856 test_device->bytes_total = 0;
2857
2858 sane_get_parameters (handle, 0);
2859
2860 if (test_device->params.lines == 0)
2861 {
2862 DBG (1, "sane_start: lines == 0\n");
2863 test_device->scanning = SANE_FALSE;
2864 return SANE_STATUS_INVAL;
2865 }
2866 if (test_device->params.pixels_per_line == 0)
2867 {
2868 DBG (1, "sane_start: pixels_per_line == 0\n");
2869 test_device->scanning = SANE_FALSE;
2870 return SANE_STATUS_INVAL;
2871 }
2872 if (test_device->params.bytes_per_line == 0)
2873 {
2874 DBG (1, "sane_start: bytes_per_line == 0\n");
2875 test_device->scanning = SANE_FALSE;
2876 return SANE_STATUS_INVAL;
2877 }
2878
2879 if (pipe (pipe_descriptor) < 0)
2880 {
2881 DBG (1, "sane_start: pipe failed (%s)\n", strerror (errno));
2882 return SANE_STATUS_IO_ERROR;
2883 }
2884
2885 /* create reader routine as new process or thread */
2886 test_device->pipe = pipe_descriptor[0];
2887 test_device->reader_fds = pipe_descriptor[1];
2888 test_device->reader_pid =
2889 sanei_thread_begin (reader_task, (void *) test_device);
2890
2891 if (!sanei_thread_is_valid (test_device->reader_pid))
2892 {
2893 DBG (1, "sane_start: sanei_thread_begin failed (%s)\n",
2894 strerror (errno));
2895 return SANE_STATUS_NO_MEM;
2896 }
2897
2898 if (sanei_thread_is_forked ())
2899 {
2900 close (test_device->reader_fds);
2901 test_device->reader_fds = -1;
2902 }
2903
2904 return SANE_STATUS_GOOD;
2905 }
2906
2907
2908 SANE_Status
sane_read(SANE_Handle handle,SANE_Byte * data,SANE_Int max_length,SANE_Int * length)2909 sane_read (SANE_Handle handle, SANE_Byte * data,
2910 SANE_Int max_length, SANE_Int * length)
2911 {
2912 Test_Device *test_device = handle;
2913 SANE_Int max_scan_length;
2914 ssize_t bytes_read;
2915 size_t read_count;
2916 size_t bytes_total = (size_t) test_device->lines * (size_t) test_device->bytes_per_line;
2917
2918
2919 DBG (4, "sane_read: handle=%p, data=%p, max_length = %d, length=%p\n",
2920 handle, (void *) data, max_length, (void *) length);
2921 if (!inited)
2922 {
2923 DBG (1, "sane_read: not inited, call sane_init() first\n");
2924 return SANE_STATUS_INVAL;
2925 }
2926 if (!check_handle (handle))
2927 {
2928 DBG (1, "sane_read: handle %p unknown\n", handle);
2929 return SANE_STATUS_INVAL;
2930 }
2931 if (!length)
2932 {
2933 DBG (1, "sane_read: length == NULL\n");
2934 return SANE_STATUS_INVAL;
2935 }
2936
2937 if (strcmp (test_device->val[opt_read_status_code].s, "Default") != 0)
2938 {
2939 SANE_String_Const sc = test_device->val[opt_read_status_code].s;
2940 DBG (3, "sane_read: setting return status to %s\n", sc);
2941 if (strcmp (sc, "SANE_STATUS_UNSUPPORTED") == 0)
2942 return SANE_STATUS_UNSUPPORTED;
2943 if (strcmp (sc, "SANE_STATUS_CANCELLED") == 0)
2944 return SANE_STATUS_CANCELLED;
2945 if (strcmp (sc, "SANE_STATUS_DEVICE_BUSY") == 0)
2946 return SANE_STATUS_DEVICE_BUSY;
2947 if (strcmp (sc, "SANE_STATUS_INVAL") == 0)
2948 return SANE_STATUS_INVAL;
2949 if (strcmp (sc, "SANE_STATUS_EOF") == 0)
2950 return SANE_STATUS_EOF;
2951 if (strcmp (sc, "SANE_STATUS_JAMMED") == 0)
2952 return SANE_STATUS_JAMMED;
2953 if (strcmp (sc, "SANE_STATUS_NO_DOCS") == 0)
2954 return SANE_STATUS_NO_DOCS;
2955 if (strcmp (sc, "SANE_STATUS_COVER_OPEN") == 0)
2956 return SANE_STATUS_COVER_OPEN;
2957 if (strcmp (sc, "SANE_STATUS_IO_ERROR") == 0)
2958 return SANE_STATUS_IO_ERROR;
2959 if (strcmp (sc, "SANE_STATUS_NO_MEM") == 0)
2960 return SANE_STATUS_NO_MEM;
2961 if (strcmp (sc, "SANE_STATUS_ACCESS_DENIED") == 0)
2962 return SANE_STATUS_ACCESS_DENIED;
2963 }
2964
2965 max_scan_length = max_length;
2966 if (test_device->val[opt_read_limit].w == SANE_TRUE
2967 && test_device->val[opt_read_limit_size].w < max_scan_length)
2968 {
2969 max_scan_length = test_device->val[opt_read_limit_size].w;
2970 DBG (3, "sane_read: limiting max_scan_length to %d bytes\n",
2971 max_scan_length);
2972 }
2973
2974 *length = 0;
2975
2976 if (!data)
2977 {
2978 DBG (1, "sane_read: data == NULL\n");
2979 return SANE_STATUS_INVAL;
2980 }
2981 if (!test_device->open)
2982 {
2983 DBG (1, "sane_read: not open\n");
2984 return SANE_STATUS_INVAL;
2985 }
2986 if (test_device->cancelled)
2987 {
2988 DBG (1, "sane_read: scan was cancelled\n");
2989 return SANE_STATUS_CANCELLED;
2990 }
2991 if (test_device->eof)
2992 {
2993 DBG (2, "sane_read: No more data available, sending EOF\n");
2994 return SANE_STATUS_EOF;
2995 }
2996 if (!test_device->scanning)
2997 {
2998 DBG (1, "sane_read: not scanning (call sane_start first)\n");
2999 return SANE_STATUS_INVAL;
3000 }
3001 read_count = (size_t) max_scan_length;
3002
3003 bytes_read = read (test_device->pipe, data, read_count);
3004 if (bytes_read == 0
3005 || ((size_t) bytes_read + (size_t) test_device->bytes_total >= bytes_total))
3006 {
3007 SANE_Status status;
3008 DBG (2, "sane_read: EOF reached\n");
3009 status = finish_pass (test_device);
3010 if (status != SANE_STATUS_GOOD)
3011 {
3012 DBG (1, "sane_read: finish_pass returned `%s'\n",
3013 sane_strstatus (status));
3014 return status;
3015 }
3016 test_device->eof = SANE_TRUE;
3017 if (strcmp (test_device->val[opt_mode].s, SANE_VALUE_SCAN_MODE_COLOR) == 0
3018 && test_device->val[opt_three_pass].w == SANE_TRUE)
3019 {
3020 test_device->pass++;
3021 if (test_device->pass > 2)
3022 test_device->pass = 0;
3023 }
3024 if (bytes_read == 0)
3025 return SANE_STATUS_EOF;
3026 }
3027 else if (bytes_read < 0)
3028 {
3029 if (errno == EAGAIN)
3030 {
3031 DBG (2, "sane_read: no data available, try again\n");
3032 return SANE_STATUS_GOOD;
3033 }
3034 else
3035 {
3036 DBG (1, "sane_read: read returned error: %s\n", strerror (errno));
3037 return SANE_STATUS_IO_ERROR;
3038 }
3039 }
3040 *length = (SANE_Int) bytes_read;
3041 test_device->bytes_total += (size_t) bytes_read;
3042
3043 DBG (2, "sane_read: read %zu bytes of %zu, total %zu\n", (size_t) bytes_read,
3044 (size_t) max_scan_length, (size_t) test_device->bytes_total);
3045 return SANE_STATUS_GOOD;
3046 }
3047
3048 void
sane_cancel(SANE_Handle handle)3049 sane_cancel (SANE_Handle handle)
3050 {
3051 Test_Device *test_device = handle;
3052
3053 DBG (2, "sane_cancel: handle = %p\n", handle);
3054 if (!inited)
3055 {
3056 DBG (1, "sane_cancel: not inited, call sane_init() first\n");
3057 return;
3058 }
3059 if (!check_handle (handle))
3060 {
3061 DBG (1, "sane_cancel: handle %p unknown\n", handle);
3062 return;
3063 }
3064 if (!test_device->open)
3065 {
3066 DBG (1, "sane_cancel: not open\n");
3067 return;
3068 }
3069 if (test_device->cancelled)
3070 {
3071 DBG (1, "sane_cancel: scan already cancelled\n");
3072 return;
3073 }
3074 if (!test_device->scanning)
3075 {
3076 DBG (2, "sane_cancel: scan is already finished\n");
3077 return;
3078 }
3079 finish_pass (test_device);
3080 test_device->cancelled = SANE_TRUE;
3081 test_device->scanning = SANE_FALSE;
3082 test_device->eof = SANE_FALSE;
3083 test_device->pass = 0;
3084 return;
3085 }
3086
3087 SANE_Status
sane_set_io_mode(SANE_Handle handle,SANE_Bool non_blocking)3088 sane_set_io_mode (SANE_Handle handle, SANE_Bool non_blocking)
3089 {
3090 Test_Device *test_device = handle;
3091
3092 DBG (2, "sane_set_io_mode: handle = %p, non_blocking = %d\n", handle,
3093 non_blocking);
3094 if (!inited)
3095 {
3096 DBG (1, "sane_set_io_mode: not inited, call sane_init() first\n");
3097 return SANE_STATUS_INVAL;
3098 }
3099 if (!check_handle (handle))
3100 {
3101 DBG (1, "sane_set_io_mode: handle %p unknown\n", handle);
3102 return SANE_STATUS_INVAL;
3103 }
3104 if (!test_device->open)
3105 {
3106 DBG (1, "sane_set_io_mode: not open\n");
3107 return SANE_STATUS_INVAL;
3108 }
3109 if (!test_device->scanning)
3110 {
3111 DBG (1, "sane_set_io_mode: not scanning\n");
3112 return SANE_STATUS_INVAL;
3113 }
3114 if (test_device->val[opt_non_blocking].w == SANE_TRUE)
3115 {
3116 if (fcntl (test_device->pipe,
3117 F_SETFL, non_blocking ? O_NONBLOCK : 0) < 0)
3118 {
3119 DBG (1, "sane_set_io_mode: can't set io mode");
3120 return SANE_STATUS_INVAL;
3121 }
3122 }
3123 else
3124 {
3125 DBG (1, "sane_set_io_mode: unsupported\n");
3126 if (non_blocking)
3127 return SANE_STATUS_UNSUPPORTED;
3128 }
3129 return SANE_STATUS_GOOD;
3130 }
3131
3132 SANE_Status
sane_get_select_fd(SANE_Handle handle,SANE_Int * fd)3133 sane_get_select_fd (SANE_Handle handle, SANE_Int * fd)
3134 {
3135 Test_Device *test_device = handle;
3136
3137 DBG (2, "sane_get_select_fd: handle = %p, fd %s 0\n", handle,
3138 fd ? "!=" : "=");
3139 if (!inited)
3140 {
3141 DBG (1, "sane_get_select_fd: not inited, call sane_init() first\n");
3142 return SANE_STATUS_INVAL;
3143 }
3144 if (!check_handle (handle))
3145 {
3146 DBG (1, "sane_get_select_fd: handle %p unknown\n", handle);
3147 return SANE_STATUS_INVAL;
3148 }
3149 if (!test_device->open)
3150 {
3151 DBG (1, "sane_get_select_fd: not open\n");
3152 return SANE_STATUS_INVAL;
3153 }
3154 if (!test_device->scanning)
3155 {
3156 DBG (1, "sane_get_select_fd: not scanning\n");
3157 return SANE_STATUS_INVAL;
3158 }
3159 if (test_device->val[opt_select_fd].w == SANE_TRUE)
3160 {
3161 *fd = test_device->pipe;
3162 return SANE_STATUS_GOOD;
3163 }
3164 DBG(1,"sane_get_select_fd: unsupported\n");
3165 return SANE_STATUS_UNSUPPORTED;
3166 }
3167