• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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