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