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 77static SANE_Bool inited = SANE_FALSE; 78static SANE_Device **sane_device_list = 0; 79static Test_Device *first_test_device = 0; 80 81static SANE_Range geometry_range = { 82 SANE_FIX (0.0), 83 SANE_FIX (200.0), 84 SANE_FIX (1.0) 85}; 86 87static SANE_Range resolution_range = { 88 SANE_FIX (1.0), 89 SANE_FIX (1200.0), 90 SANE_FIX (1.0) 91}; 92 93static SANE_Range ppl_loss_range = { 94 0, 95 128, 96 1 97}; 98 99static SANE_Range read_limit_size_range = { 100 1, 101 64 * 1024, /* 64 KB ought to be enough for everyone :-) */ 102 1 103}; 104 105static SANE_Range read_delay_duration_range = { 106 1000, 107 200 * 1000, /* 200 msec */ 108 1000 109}; 110 111static SANE_Range int_constraint_range = { 112 4, 113 192, 114 2 115}; 116 117static SANE_Range gamma_range = { 118 0, 119 255, 120 1 121}; 122 123static SANE_Range fixed_constraint_range = { 124 SANE_FIX (-42.17), 125 SANE_FIX (32767.9999), 126 SANE_FIX (2.0) 127}; 128 129static SANE_String_Const mode_list[] = { 130 SANE_VALUE_SCAN_MODE_GRAY, 131 SANE_VALUE_SCAN_MODE_COLOR, 132 0 133}; 134 135static SANE_String_Const order_list[] = { 136 "RGB", "RBG", "GBR", "GRB", "BRG", "BGR", 137 0 138}; 139 140static 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 146static 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 154static SANE_Int depth_list[] = { 155 3, 1, 8, 16 156}; 157 158static SANE_Int int_constraint_word_list[] = { 159 9, -42, -8, 0, 17, 42, 256, 65536, 256 * 256 * 256, 256 * 256 * 256 * 64 160}; 161 162static 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 166static 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 174static 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 183static SANE_Int int_array[] = { 184 -17, 0, -5, 42, 91, 256 * 256 * 256 * 64 185}; 186 187static 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 195static SANE_Int gamma_red[GAMMA_RED_SIZE]; // initialized in init_options() 196static SANE_Int gamma_green[GAMMA_GREEN_SIZE]; 197static SANE_Int gamma_blue[GAMMA_BLUE_SIZE]; 198static SANE_Int gamma_all[GAMMA_ALL_SIZE]; 199 200static void 201init_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 208static void 209print_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 227static SANE_Int int_array_constraint_word_list[] = { 228 -42, 0, -8, 17, 42, 42 229}; 230 231static SANE_String_Const source_list[] = { 232 SANE_I18N ("Flatbed"), SANE_I18N ("Automatic Document Feeder"), 233 0 234}; 235 236static double random_factor; /* use for fuzzyness of parameters */ 237 238/* initial values. Initial string values are set in sane_init() */ 239static SANE_Word init_number_of_devices = 2; 240static SANE_Fixed init_tl_x = SANE_FIX (0.0); 241static SANE_Fixed init_tl_y = SANE_FIX (0.0); 242static SANE_Fixed init_br_x = SANE_FIX (80.0); 243static SANE_Fixed init_br_y = SANE_FIX (100.0); 244static SANE_Word init_resolution = 50; 245static SANE_String init_mode = NULL; 246static SANE_Word init_depth = 8; 247static SANE_Bool init_hand_scanner = SANE_FALSE; 248static SANE_Bool init_three_pass = SANE_FALSE; 249static SANE_String init_three_pass_order = NULL; 250static SANE_String init_scan_source = NULL; 251static SANE_String init_test_picture = NULL; 252static SANE_Bool init_invert_endianess = SANE_FALSE; 253static SANE_Bool init_read_limit = SANE_FALSE; 254static SANE_Word init_read_limit_size = 1; 255static SANE_Bool init_read_delay = SANE_FALSE; 256static SANE_Word init_read_delay_duration = 1000; 257static SANE_String init_read_status_code = NULL; 258static SANE_Bool init_fuzzy_parameters = SANE_FALSE; 259static SANE_Word init_ppl_loss = 0; 260static SANE_Bool init_non_blocking = SANE_FALSE; 261static SANE_Bool init_select_fd = SANE_FALSE; 262static SANE_Bool init_enable_test_options = SANE_FALSE; 263static SANE_String init_string = NULL; 264static SANE_String init_string_constraint_string_list = NULL; 265static SANE_String init_string_constraint_long_string_list = NULL; 266 267/* Test if this machine is little endian (from coolscan.c) */ 268static SANE_Bool 269little_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 279static void 280swap_double (double *a, double *b) 281{ 282 double c; 283 284 c = *a; 285 *a = *b; 286 *b = c; 287 288 return; 289} 290 291static size_t 292max_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 306static SANE_Bool 307check_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 320static void 321cleanup_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 352static SANE_Status 353init_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 1252fail: 1253 cleanup_options (test_device); 1254 return SANE_STATUS_NO_MEM; 1255} 1256 1257static void 1258cleanup_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 1279static void 1280cleanup_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 1290static SANE_Status 1291read_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 1435static SANE_Status 1436reader_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 */ 1502static int 1503reader_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 1531static SANE_Status 1532finish_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 1578static void 1579print_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 1640SANE_Status 1641sane_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 1888fail_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); 1892fail_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); 1903fail: 1904 cleanup_initial_string_values (); 1905 return SANE_STATUS_NO_MEM; 1906} 1907 1908void 1909sane_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 1940SANE_Status 1941sane_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 1961SANE_Status 1962sane_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 2027void 2028sane_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 2053const SANE_Option_Descriptor * 2054sane_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 2090SANE_Status 2091sane_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 2617SANE_Status 2618sane_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 2764SANE_Status 2765sane_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 2869SANE_Status 2870sane_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 3009void 3010sane_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 3048SANE_Status 3049sane_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 3093SANE_Status 3094sane_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