1141cc406Sopenharmony_ci/* sane - Scanner Access Now Easy. 2141cc406Sopenharmony_ci 3141cc406Sopenharmony_ci Copyright (C) 2002-2006 Henning Meier-Geinitz <henning@meier-geinitz.de> 4141cc406Sopenharmony_ci Changes according to the sanei_thread usage by 5141cc406Sopenharmony_ci Gerhard Jaeger <gerhard@gjaeger.de> 6141cc406Sopenharmony_ci 7141cc406Sopenharmony_ci This file is part of the SANE package. 8141cc406Sopenharmony_ci 9141cc406Sopenharmony_ci This program is free software; you can redistribute it and/or 10141cc406Sopenharmony_ci modify it under the terms of the GNU General Public License as 11141cc406Sopenharmony_ci published by the Free Software Foundation; either version 2 of the 12141cc406Sopenharmony_ci License, or (at your option) any later version. 13141cc406Sopenharmony_ci 14141cc406Sopenharmony_ci This program is distributed in the hope that it will be useful, but 15141cc406Sopenharmony_ci WITHOUT ANY WARRANTY; without even the implied warranty of 16141cc406Sopenharmony_ci MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 17141cc406Sopenharmony_ci General Public License for more details. 18141cc406Sopenharmony_ci 19141cc406Sopenharmony_ci You should have received a copy of the GNU General Public License 20141cc406Sopenharmony_ci along with this program. If not, see <https://www.gnu.org/licenses/>. 21141cc406Sopenharmony_ci 22141cc406Sopenharmony_ci As a special exception, the authors of SANE give permission for 23141cc406Sopenharmony_ci additional uses of the libraries contained in this release of SANE. 24141cc406Sopenharmony_ci 25141cc406Sopenharmony_ci The exception is that, if you link a SANE library with other files 26141cc406Sopenharmony_ci to produce an executable, this does not by itself cause the 27141cc406Sopenharmony_ci resulting executable to be covered by the GNU General Public 28141cc406Sopenharmony_ci License. Your use of that executable is in no way restricted on 29141cc406Sopenharmony_ci account of linking the SANE library code into it. 30141cc406Sopenharmony_ci 31141cc406Sopenharmony_ci This exception does not, however, invalidate any other reasons why 32141cc406Sopenharmony_ci the executable file might be covered by the GNU General Public 33141cc406Sopenharmony_ci License. 34141cc406Sopenharmony_ci 35141cc406Sopenharmony_ci If you submit changes to SANE to the maintainers to be included in 36141cc406Sopenharmony_ci a subsequent release, you agree by submitting the changes that 37141cc406Sopenharmony_ci those changes may be distributed with this exception intact. 38141cc406Sopenharmony_ci 39141cc406Sopenharmony_ci If you write modifications of your own for SANE, it is your choice 40141cc406Sopenharmony_ci whether to permit this exception to apply to your modifications. 41141cc406Sopenharmony_ci If you do not wish that, delete this exception notice. 42141cc406Sopenharmony_ci 43141cc406Sopenharmony_ci This backend is for testing frontends. 44141cc406Sopenharmony_ci*/ 45141cc406Sopenharmony_ci 46141cc406Sopenharmony_ci#define BUILD 28 47141cc406Sopenharmony_ci 48141cc406Sopenharmony_ci#include "../include/sane/config.h" 49141cc406Sopenharmony_ci 50141cc406Sopenharmony_ci#include <errno.h> 51141cc406Sopenharmony_ci#include <signal.h> 52141cc406Sopenharmony_ci#include <stdio.h> 53141cc406Sopenharmony_ci#include <stdlib.h> 54141cc406Sopenharmony_ci#include <string.h> 55141cc406Sopenharmony_ci#include <sys/types.h> 56141cc406Sopenharmony_ci#include <time.h> 57141cc406Sopenharmony_ci#include <unistd.h> 58141cc406Sopenharmony_ci#include <fcntl.h> 59141cc406Sopenharmony_ci 60141cc406Sopenharmony_ci#include "../include/_stdint.h" 61141cc406Sopenharmony_ci 62141cc406Sopenharmony_ci#include "../include/sane/sane.h" 63141cc406Sopenharmony_ci#include "../include/sane/sanei.h" 64141cc406Sopenharmony_ci#include "../include/sane/saneopts.h" 65141cc406Sopenharmony_ci#include "../include/sane/sanei_config.h" 66141cc406Sopenharmony_ci#include "../include/sane/sanei_thread.h" 67141cc406Sopenharmony_ci 68141cc406Sopenharmony_ci#define BACKEND_NAME test 69141cc406Sopenharmony_ci#include "../include/sane/sanei_backend.h" 70141cc406Sopenharmony_ci 71141cc406Sopenharmony_ci#include "test.h" 72141cc406Sopenharmony_ci 73141cc406Sopenharmony_ci#include "test-picture.c" 74141cc406Sopenharmony_ci 75141cc406Sopenharmony_ci#define TEST_CONFIG_FILE "test.conf" 76141cc406Sopenharmony_ci 77141cc406Sopenharmony_cistatic SANE_Bool inited = SANE_FALSE; 78141cc406Sopenharmony_cistatic SANE_Device **sane_device_list = 0; 79141cc406Sopenharmony_cistatic Test_Device *first_test_device = 0; 80141cc406Sopenharmony_ci 81141cc406Sopenharmony_cistatic SANE_Range geometry_range = { 82141cc406Sopenharmony_ci SANE_FIX (0.0), 83141cc406Sopenharmony_ci SANE_FIX (200.0), 84141cc406Sopenharmony_ci SANE_FIX (1.0) 85141cc406Sopenharmony_ci}; 86141cc406Sopenharmony_ci 87141cc406Sopenharmony_cistatic SANE_Range resolution_range = { 88141cc406Sopenharmony_ci SANE_FIX (1.0), 89141cc406Sopenharmony_ci SANE_FIX (1200.0), 90141cc406Sopenharmony_ci SANE_FIX (1.0) 91141cc406Sopenharmony_ci}; 92141cc406Sopenharmony_ci 93141cc406Sopenharmony_cistatic SANE_Range ppl_loss_range = { 94141cc406Sopenharmony_ci 0, 95141cc406Sopenharmony_ci 128, 96141cc406Sopenharmony_ci 1 97141cc406Sopenharmony_ci}; 98141cc406Sopenharmony_ci 99141cc406Sopenharmony_cistatic SANE_Range read_limit_size_range = { 100141cc406Sopenharmony_ci 1, 101141cc406Sopenharmony_ci 64 * 1024, /* 64 KB ought to be enough for everyone :-) */ 102141cc406Sopenharmony_ci 1 103141cc406Sopenharmony_ci}; 104141cc406Sopenharmony_ci 105141cc406Sopenharmony_cistatic SANE_Range read_delay_duration_range = { 106141cc406Sopenharmony_ci 1000, 107141cc406Sopenharmony_ci 200 * 1000, /* 200 msec */ 108141cc406Sopenharmony_ci 1000 109141cc406Sopenharmony_ci}; 110141cc406Sopenharmony_ci 111141cc406Sopenharmony_cistatic SANE_Range int_constraint_range = { 112141cc406Sopenharmony_ci 4, 113141cc406Sopenharmony_ci 192, 114141cc406Sopenharmony_ci 2 115141cc406Sopenharmony_ci}; 116141cc406Sopenharmony_ci 117141cc406Sopenharmony_cistatic SANE_Range gamma_range = { 118141cc406Sopenharmony_ci 0, 119141cc406Sopenharmony_ci 255, 120141cc406Sopenharmony_ci 1 121141cc406Sopenharmony_ci}; 122141cc406Sopenharmony_ci 123141cc406Sopenharmony_cistatic SANE_Range fixed_constraint_range = { 124141cc406Sopenharmony_ci SANE_FIX (-42.17), 125141cc406Sopenharmony_ci SANE_FIX (32767.9999), 126141cc406Sopenharmony_ci SANE_FIX (2.0) 127141cc406Sopenharmony_ci}; 128141cc406Sopenharmony_ci 129141cc406Sopenharmony_cistatic SANE_String_Const mode_list[] = { 130141cc406Sopenharmony_ci SANE_VALUE_SCAN_MODE_GRAY, 131141cc406Sopenharmony_ci SANE_VALUE_SCAN_MODE_COLOR, 132141cc406Sopenharmony_ci 0 133141cc406Sopenharmony_ci}; 134141cc406Sopenharmony_ci 135141cc406Sopenharmony_cistatic SANE_String_Const order_list[] = { 136141cc406Sopenharmony_ci "RGB", "RBG", "GBR", "GRB", "BRG", "BGR", 137141cc406Sopenharmony_ci 0 138141cc406Sopenharmony_ci}; 139141cc406Sopenharmony_ci 140141cc406Sopenharmony_cistatic SANE_String_Const test_picture_list[] = { 141141cc406Sopenharmony_ci SANE_I18N ("Solid black"), SANE_I18N ("Solid white"), 142141cc406Sopenharmony_ci SANE_I18N ("Color pattern"), SANE_I18N ("Grid"), 143141cc406Sopenharmony_ci 0 144141cc406Sopenharmony_ci}; 145141cc406Sopenharmony_ci 146141cc406Sopenharmony_cistatic SANE_String_Const read_status_code_list[] = { 147141cc406Sopenharmony_ci SANE_I18N ("Default"), "SANE_STATUS_UNSUPPORTED", "SANE_STATUS_CANCELLED", 148141cc406Sopenharmony_ci "SANE_STATUS_DEVICE_BUSY", "SANE_STATUS_INVAL", "SANE_STATUS_EOF", 149141cc406Sopenharmony_ci "SANE_STATUS_JAMMED", "SANE_STATUS_NO_DOCS", "SANE_STATUS_COVER_OPEN", 150141cc406Sopenharmony_ci "SANE_STATUS_IO_ERROR", "SANE_STATUS_NO_MEM", "SANE_STATUS_ACCESS_DENIED", 151141cc406Sopenharmony_ci 0 152141cc406Sopenharmony_ci}; 153141cc406Sopenharmony_ci 154141cc406Sopenharmony_cistatic SANE_Int depth_list[] = { 155141cc406Sopenharmony_ci 3, 1, 8, 16 156141cc406Sopenharmony_ci}; 157141cc406Sopenharmony_ci 158141cc406Sopenharmony_cistatic SANE_Int int_constraint_word_list[] = { 159141cc406Sopenharmony_ci 9, -42, -8, 0, 17, 42, 256, 65536, 256 * 256 * 256, 256 * 256 * 256 * 64 160141cc406Sopenharmony_ci}; 161141cc406Sopenharmony_ci 162141cc406Sopenharmony_cistatic SANE_Int fixed_constraint_word_list[] = { 163141cc406Sopenharmony_ci 4, SANE_FIX (-32.7), SANE_FIX (12.1), SANE_FIX (42.0), SANE_FIX (129.5) 164141cc406Sopenharmony_ci}; 165141cc406Sopenharmony_ci 166141cc406Sopenharmony_cistatic SANE_String_Const string_constraint_string_list[] = { 167141cc406Sopenharmony_ci SANE_I18N ("First entry"), SANE_I18N ("Second entry"), 168141cc406Sopenharmony_ci SANE_I18N 169141cc406Sopenharmony_ci ("This is the very long third entry. Maybe the frontend has an idea how to " 170141cc406Sopenharmony_ci "display it"), 171141cc406Sopenharmony_ci 0 172141cc406Sopenharmony_ci}; 173141cc406Sopenharmony_ci 174141cc406Sopenharmony_cistatic SANE_String_Const string_constraint_long_string_list[] = { 175141cc406Sopenharmony_ci SANE_I18N ("First entry"), SANE_I18N ("Second entry"), "3", "4", "5", "6", 176141cc406Sopenharmony_ci "7", "8", "9", "10", 177141cc406Sopenharmony_ci "11", "12", "13", "14", "15", "16", "17", "18", "19", "20", "21", "22", 178141cc406Sopenharmony_ci "23", "24", "25", "26", "27", "28", "29", "30", "31", "32", "33", "34", 179141cc406Sopenharmony_ci "35", "36", "37", "38", "39", "40", "41", "42", "43", "44", "45", "46", 180141cc406Sopenharmony_ci 0 181141cc406Sopenharmony_ci}; 182141cc406Sopenharmony_ci 183141cc406Sopenharmony_cistatic SANE_Int int_array[] = { 184141cc406Sopenharmony_ci -17, 0, -5, 42, 91, 256 * 256 * 256 * 64 185141cc406Sopenharmony_ci}; 186141cc406Sopenharmony_ci 187141cc406Sopenharmony_cistatic SANE_Int int_array_constraint_range[] = { 188141cc406Sopenharmony_ci 48, 6, 4, 92, 190, 16 189141cc406Sopenharmony_ci}; 190141cc406Sopenharmony_ci 191141cc406Sopenharmony_ci#define GAMMA_RED_SIZE 256 192141cc406Sopenharmony_ci#define GAMMA_GREEN_SIZE 256 193141cc406Sopenharmony_ci#define GAMMA_BLUE_SIZE 256 194141cc406Sopenharmony_ci#define GAMMA_ALL_SIZE 4096 195141cc406Sopenharmony_cistatic SANE_Int gamma_red[GAMMA_RED_SIZE]; // initialized in init_options() 196141cc406Sopenharmony_cistatic SANE_Int gamma_green[GAMMA_GREEN_SIZE]; 197141cc406Sopenharmony_cistatic SANE_Int gamma_blue[GAMMA_BLUE_SIZE]; 198141cc406Sopenharmony_cistatic SANE_Int gamma_all[GAMMA_ALL_SIZE]; 199141cc406Sopenharmony_ci 200141cc406Sopenharmony_cistatic void 201141cc406Sopenharmony_ciinit_gamma_table(SANE_Int *tablePtr, SANE_Int count, SANE_Int max) 202141cc406Sopenharmony_ci{ 203141cc406Sopenharmony_ci for (int i=0; i<count; ++i) { 204141cc406Sopenharmony_ci tablePtr[i] = (SANE_Int)(((double)i * max)/(double)count); 205141cc406Sopenharmony_ci } 206141cc406Sopenharmony_ci} 207141cc406Sopenharmony_ci 208141cc406Sopenharmony_cistatic void 209141cc406Sopenharmony_ciprint_gamma_table(SANE_Int *tablePtr, SANE_Int count) 210141cc406Sopenharmony_ci{ 211141cc406Sopenharmony_ci char str[200]; 212141cc406Sopenharmony_ci str[0] = '\0'; 213141cc406Sopenharmony_ci DBG (5, "Gamma Table Size: %d\n", count); 214141cc406Sopenharmony_ci for (int i=0; i<count; ++i) { 215141cc406Sopenharmony_ci if (i%16 == 0 && strlen(str) > 0) { 216141cc406Sopenharmony_ci DBG (5, "%s\n", str); 217141cc406Sopenharmony_ci str[0] = '\0'; 218141cc406Sopenharmony_ci } 219141cc406Sopenharmony_ci sprintf (str + strlen(str), " %04X", tablePtr[i]); 220141cc406Sopenharmony_ci } 221141cc406Sopenharmony_ci if (strlen(str) > 0) { 222141cc406Sopenharmony_ci DBG (5, "%s\n", str); 223141cc406Sopenharmony_ci } 224141cc406Sopenharmony_ci} 225141cc406Sopenharmony_ci 226141cc406Sopenharmony_ci 227141cc406Sopenharmony_cistatic SANE_Int int_array_constraint_word_list[] = { 228141cc406Sopenharmony_ci -42, 0, -8, 17, 42, 42 229141cc406Sopenharmony_ci}; 230141cc406Sopenharmony_ci 231141cc406Sopenharmony_cistatic SANE_String_Const source_list[] = { 232141cc406Sopenharmony_ci SANE_I18N ("Flatbed"), SANE_I18N ("Automatic Document Feeder"), 233141cc406Sopenharmony_ci 0 234141cc406Sopenharmony_ci}; 235141cc406Sopenharmony_ci 236141cc406Sopenharmony_cistatic double random_factor; /* use for fuzzyness of parameters */ 237141cc406Sopenharmony_ci 238141cc406Sopenharmony_ci/* initial values. Initial string values are set in sane_init() */ 239141cc406Sopenharmony_cistatic SANE_Word init_number_of_devices = 2; 240141cc406Sopenharmony_cistatic SANE_Fixed init_tl_x = SANE_FIX (0.0); 241141cc406Sopenharmony_cistatic SANE_Fixed init_tl_y = SANE_FIX (0.0); 242141cc406Sopenharmony_cistatic SANE_Fixed init_br_x = SANE_FIX (80.0); 243141cc406Sopenharmony_cistatic SANE_Fixed init_br_y = SANE_FIX (100.0); 244141cc406Sopenharmony_cistatic SANE_Word init_resolution = 50; 245141cc406Sopenharmony_cistatic SANE_String init_mode = NULL; 246141cc406Sopenharmony_cistatic SANE_Word init_depth = 8; 247141cc406Sopenharmony_cistatic SANE_Bool init_hand_scanner = SANE_FALSE; 248141cc406Sopenharmony_cistatic SANE_Bool init_three_pass = SANE_FALSE; 249141cc406Sopenharmony_cistatic SANE_String init_three_pass_order = NULL; 250141cc406Sopenharmony_cistatic SANE_String init_scan_source = NULL; 251141cc406Sopenharmony_cistatic SANE_String init_test_picture = NULL; 252141cc406Sopenharmony_cistatic SANE_Bool init_invert_endianess = SANE_FALSE; 253141cc406Sopenharmony_cistatic SANE_Bool init_read_limit = SANE_FALSE; 254141cc406Sopenharmony_cistatic SANE_Word init_read_limit_size = 1; 255141cc406Sopenharmony_cistatic SANE_Bool init_read_delay = SANE_FALSE; 256141cc406Sopenharmony_cistatic SANE_Word init_read_delay_duration = 1000; 257141cc406Sopenharmony_cistatic SANE_String init_read_status_code = NULL; 258141cc406Sopenharmony_cistatic SANE_Bool init_fuzzy_parameters = SANE_FALSE; 259141cc406Sopenharmony_cistatic SANE_Word init_ppl_loss = 0; 260141cc406Sopenharmony_cistatic SANE_Bool init_non_blocking = SANE_FALSE; 261141cc406Sopenharmony_cistatic SANE_Bool init_select_fd = SANE_FALSE; 262141cc406Sopenharmony_cistatic SANE_Bool init_enable_test_options = SANE_FALSE; 263141cc406Sopenharmony_cistatic SANE_String init_string = NULL; 264141cc406Sopenharmony_cistatic SANE_String init_string_constraint_string_list = NULL; 265141cc406Sopenharmony_cistatic SANE_String init_string_constraint_long_string_list = NULL; 266141cc406Sopenharmony_ci 267141cc406Sopenharmony_ci/* Test if this machine is little endian (from coolscan.c) */ 268141cc406Sopenharmony_cistatic SANE_Bool 269141cc406Sopenharmony_cilittle_endian (void) 270141cc406Sopenharmony_ci{ 271141cc406Sopenharmony_ci SANE_Int testvalue = 255; 272141cc406Sopenharmony_ci uint8_t *firstbyte = (uint8_t *) & testvalue; 273141cc406Sopenharmony_ci 274141cc406Sopenharmony_ci if (*firstbyte == 255) 275141cc406Sopenharmony_ci return SANE_TRUE; 276141cc406Sopenharmony_ci return SANE_FALSE; 277141cc406Sopenharmony_ci} 278141cc406Sopenharmony_ci 279141cc406Sopenharmony_cistatic void 280141cc406Sopenharmony_ciswap_double (double *a, double *b) 281141cc406Sopenharmony_ci{ 282141cc406Sopenharmony_ci double c; 283141cc406Sopenharmony_ci 284141cc406Sopenharmony_ci c = *a; 285141cc406Sopenharmony_ci *a = *b; 286141cc406Sopenharmony_ci *b = c; 287141cc406Sopenharmony_ci 288141cc406Sopenharmony_ci return; 289141cc406Sopenharmony_ci} 290141cc406Sopenharmony_ci 291141cc406Sopenharmony_cistatic size_t 292141cc406Sopenharmony_cimax_string_size (const SANE_String_Const strings[]) 293141cc406Sopenharmony_ci{ 294141cc406Sopenharmony_ci size_t size, max_size = 0; 295141cc406Sopenharmony_ci SANE_Int i; 296141cc406Sopenharmony_ci 297141cc406Sopenharmony_ci for (i = 0; strings[i]; ++i) 298141cc406Sopenharmony_ci { 299141cc406Sopenharmony_ci size = strlen (strings[i]) + 1; 300141cc406Sopenharmony_ci if (size > max_size) 301141cc406Sopenharmony_ci max_size = size; 302141cc406Sopenharmony_ci } 303141cc406Sopenharmony_ci return max_size; 304141cc406Sopenharmony_ci} 305141cc406Sopenharmony_ci 306141cc406Sopenharmony_cistatic SANE_Bool 307141cc406Sopenharmony_cicheck_handle (SANE_Handle handle) 308141cc406Sopenharmony_ci{ 309141cc406Sopenharmony_ci Test_Device *test_device = first_test_device; 310141cc406Sopenharmony_ci 311141cc406Sopenharmony_ci while (test_device) 312141cc406Sopenharmony_ci { 313141cc406Sopenharmony_ci if (test_device == (Test_Device *) handle) 314141cc406Sopenharmony_ci return SANE_TRUE; 315141cc406Sopenharmony_ci test_device = test_device->next; 316141cc406Sopenharmony_ci } 317141cc406Sopenharmony_ci return SANE_FALSE; 318141cc406Sopenharmony_ci} 319141cc406Sopenharmony_ci 320141cc406Sopenharmony_cistatic void 321141cc406Sopenharmony_cicleanup_options (Test_Device * test_device) 322141cc406Sopenharmony_ci{ 323141cc406Sopenharmony_ci DBG (2, "cleanup_options: test_device=%p\n", (void *) test_device); 324141cc406Sopenharmony_ci 325141cc406Sopenharmony_ci free(test_device->val[opt_mode].s); 326141cc406Sopenharmony_ci test_device->val[opt_mode].s = NULL; 327141cc406Sopenharmony_ci 328141cc406Sopenharmony_ci free(test_device->val[opt_three_pass_order].s); 329141cc406Sopenharmony_ci test_device->val[opt_three_pass_order].s = NULL; 330141cc406Sopenharmony_ci 331141cc406Sopenharmony_ci free(test_device->val[opt_scan_source].s); 332141cc406Sopenharmony_ci test_device->val[opt_scan_source].s = NULL; 333141cc406Sopenharmony_ci 334141cc406Sopenharmony_ci free(test_device->val[opt_test_picture].s); 335141cc406Sopenharmony_ci test_device->val[opt_test_picture].s = NULL; 336141cc406Sopenharmony_ci 337141cc406Sopenharmony_ci free(test_device->val[opt_read_status_code].s); 338141cc406Sopenharmony_ci test_device->val[opt_read_status_code].s = NULL; 339141cc406Sopenharmony_ci 340141cc406Sopenharmony_ci free(test_device->val[opt_string].s); 341141cc406Sopenharmony_ci test_device->val[opt_string].s = NULL; 342141cc406Sopenharmony_ci 343141cc406Sopenharmony_ci free(test_device->val[opt_string_constraint_string_list].s); 344141cc406Sopenharmony_ci test_device->val[opt_string_constraint_string_list].s = NULL; 345141cc406Sopenharmony_ci 346141cc406Sopenharmony_ci free(test_device->val[opt_string_constraint_long_string_list].s); 347141cc406Sopenharmony_ci test_device->val[opt_string_constraint_long_string_list].s = NULL; 348141cc406Sopenharmony_ci 349141cc406Sopenharmony_ci test_device->options_initialized = SANE_FALSE; 350141cc406Sopenharmony_ci} 351141cc406Sopenharmony_ci 352141cc406Sopenharmony_cistatic SANE_Status 353141cc406Sopenharmony_ciinit_options (Test_Device * test_device) 354141cc406Sopenharmony_ci{ 355141cc406Sopenharmony_ci SANE_Option_Descriptor *od; 356141cc406Sopenharmony_ci 357141cc406Sopenharmony_ci DBG (2, "init_options: test_device=%p\n", (void *) test_device); 358141cc406Sopenharmony_ci 359141cc406Sopenharmony_ci /* opt_num_opts */ 360141cc406Sopenharmony_ci od = &test_device->opt[opt_num_opts]; 361141cc406Sopenharmony_ci od->name = ""; 362141cc406Sopenharmony_ci od->title = SANE_TITLE_NUM_OPTIONS; 363141cc406Sopenharmony_ci od->desc = SANE_DESC_NUM_OPTIONS; 364141cc406Sopenharmony_ci od->type = SANE_TYPE_INT; 365141cc406Sopenharmony_ci od->unit = SANE_UNIT_NONE; 366141cc406Sopenharmony_ci od->size = sizeof (SANE_Word); 367141cc406Sopenharmony_ci od->cap = SANE_CAP_SOFT_DETECT; 368141cc406Sopenharmony_ci od->constraint_type = SANE_CONSTRAINT_NONE; 369141cc406Sopenharmony_ci od->constraint.range = 0; 370141cc406Sopenharmony_ci test_device->val[opt_num_opts].w = num_options; 371141cc406Sopenharmony_ci 372141cc406Sopenharmony_ci test_device->loaded[opt_num_opts] = 1; 373141cc406Sopenharmony_ci 374141cc406Sopenharmony_ci /* opt_mode_group */ 375141cc406Sopenharmony_ci od = &test_device->opt[opt_mode_group]; 376141cc406Sopenharmony_ci od->name = ""; 377141cc406Sopenharmony_ci od->title = SANE_I18N ("Scan Mode"); 378141cc406Sopenharmony_ci od->desc = ""; 379141cc406Sopenharmony_ci od->type = SANE_TYPE_GROUP; 380141cc406Sopenharmony_ci od->unit = SANE_UNIT_NONE; 381141cc406Sopenharmony_ci od->size = 0; 382141cc406Sopenharmony_ci od->cap = 0; 383141cc406Sopenharmony_ci od->constraint_type = SANE_CONSTRAINT_NONE; 384141cc406Sopenharmony_ci od->constraint.range = 0; 385141cc406Sopenharmony_ci test_device->val[opt_mode_group].w = 0; 386141cc406Sopenharmony_ci 387141cc406Sopenharmony_ci /* opt_mode */ 388141cc406Sopenharmony_ci od = &test_device->opt[opt_mode]; 389141cc406Sopenharmony_ci od->name = SANE_NAME_SCAN_MODE; 390141cc406Sopenharmony_ci od->title = SANE_TITLE_SCAN_MODE; 391141cc406Sopenharmony_ci od->desc = SANE_DESC_SCAN_MODE; 392141cc406Sopenharmony_ci od->type = SANE_TYPE_STRING; 393141cc406Sopenharmony_ci od->unit = SANE_UNIT_NONE; 394141cc406Sopenharmony_ci od->size = (SANE_Int) max_string_size (mode_list); 395141cc406Sopenharmony_ci od->cap = SANE_CAP_SOFT_DETECT | SANE_CAP_SOFT_SELECT; 396141cc406Sopenharmony_ci od->constraint_type = SANE_CONSTRAINT_STRING_LIST; 397141cc406Sopenharmony_ci od->constraint.string_list = mode_list; 398141cc406Sopenharmony_ci test_device->val[opt_mode].s = malloc ((size_t) od->size); 399141cc406Sopenharmony_ci if (!test_device->val[opt_mode].s) 400141cc406Sopenharmony_ci goto fail; 401141cc406Sopenharmony_ci strcpy (test_device->val[opt_mode].s, init_mode); 402141cc406Sopenharmony_ci 403141cc406Sopenharmony_ci /* opt_depth */ 404141cc406Sopenharmony_ci od = &test_device->opt[opt_depth]; 405141cc406Sopenharmony_ci od->name = SANE_NAME_BIT_DEPTH; 406141cc406Sopenharmony_ci od->title = SANE_TITLE_BIT_DEPTH; 407141cc406Sopenharmony_ci od->desc = SANE_DESC_BIT_DEPTH; 408141cc406Sopenharmony_ci od->type = SANE_TYPE_INT; 409141cc406Sopenharmony_ci od->unit = SANE_UNIT_NONE; 410141cc406Sopenharmony_ci od->size = sizeof (SANE_Word); 411141cc406Sopenharmony_ci od->cap = SANE_CAP_SOFT_DETECT | SANE_CAP_SOFT_SELECT; 412141cc406Sopenharmony_ci od->constraint_type = SANE_CONSTRAINT_WORD_LIST; 413141cc406Sopenharmony_ci od->constraint.word_list = depth_list; 414141cc406Sopenharmony_ci test_device->val[opt_depth].w = init_depth; 415141cc406Sopenharmony_ci 416141cc406Sopenharmony_ci /* opt_hand_scanner */ 417141cc406Sopenharmony_ci od = &test_device->opt[opt_hand_scanner]; 418141cc406Sopenharmony_ci od->name = "hand-scanner"; 419141cc406Sopenharmony_ci od->title = SANE_I18N ("Hand-scanner simulation"); 420141cc406Sopenharmony_ci od->desc = SANE_I18N ("Simulate a hand-scanner. Hand-scanners do not " 421141cc406Sopenharmony_ci "know the image height a priori. Instead, they " 422141cc406Sopenharmony_ci "return a height of -1. Setting this option allows one " 423141cc406Sopenharmony_ci "to test whether a frontend can handle this " 424141cc406Sopenharmony_ci "correctly. This option also enables a fixed width " 425141cc406Sopenharmony_ci "of 11 cm."); 426141cc406Sopenharmony_ci od->type = SANE_TYPE_BOOL; 427141cc406Sopenharmony_ci od->unit = SANE_UNIT_NONE; 428141cc406Sopenharmony_ci od->size = sizeof (SANE_Word); 429141cc406Sopenharmony_ci od->cap = SANE_CAP_SOFT_DETECT | SANE_CAP_SOFT_SELECT; 430141cc406Sopenharmony_ci od->constraint_type = SANE_CONSTRAINT_NONE; 431141cc406Sopenharmony_ci od->constraint.range = 0; 432141cc406Sopenharmony_ci test_device->val[opt_hand_scanner].w = init_hand_scanner; 433141cc406Sopenharmony_ci 434141cc406Sopenharmony_ci /* opt_three_pass */ 435141cc406Sopenharmony_ci od = &test_device->opt[opt_three_pass]; 436141cc406Sopenharmony_ci od->name = "three-pass"; 437141cc406Sopenharmony_ci od->title = SANE_I18N ("Three-pass simulation"); 438141cc406Sopenharmony_ci od->desc = SANE_I18N ("Simulate a three-pass scanner. In color mode, three " 439141cc406Sopenharmony_ci "frames are transmitted."); 440141cc406Sopenharmony_ci od->type = SANE_TYPE_BOOL; 441141cc406Sopenharmony_ci od->unit = SANE_UNIT_NONE; 442141cc406Sopenharmony_ci od->size = sizeof (SANE_Word); 443141cc406Sopenharmony_ci od->cap = SANE_CAP_SOFT_DETECT | SANE_CAP_SOFT_SELECT; 444141cc406Sopenharmony_ci if (strcmp (init_mode, SANE_VALUE_SCAN_MODE_COLOR) != 0) 445141cc406Sopenharmony_ci od->cap |= SANE_CAP_INACTIVE; 446141cc406Sopenharmony_ci od->constraint_type = SANE_CONSTRAINT_NONE; 447141cc406Sopenharmony_ci od->constraint.range = 0; 448141cc406Sopenharmony_ci test_device->val[opt_three_pass].w = init_three_pass; 449141cc406Sopenharmony_ci 450141cc406Sopenharmony_ci /* opt_three_pass_order */ 451141cc406Sopenharmony_ci od = &test_device->opt[opt_three_pass_order]; 452141cc406Sopenharmony_ci od->name = "three-pass-order"; 453141cc406Sopenharmony_ci od->title = SANE_I18N ("Set the order of frames"); 454141cc406Sopenharmony_ci od->desc = SANE_I18N ("Set the order of frames in three-pass color mode."); 455141cc406Sopenharmony_ci od->type = SANE_TYPE_STRING; 456141cc406Sopenharmony_ci od->unit = SANE_UNIT_NONE; 457141cc406Sopenharmony_ci od->size = (SANE_Int) max_string_size (order_list); 458141cc406Sopenharmony_ci od->cap = SANE_CAP_SOFT_DETECT | SANE_CAP_SOFT_SELECT; 459141cc406Sopenharmony_ci if (strcmp (init_mode, SANE_VALUE_SCAN_MODE_COLOR) != 0) 460141cc406Sopenharmony_ci od->cap |= SANE_CAP_INACTIVE; 461141cc406Sopenharmony_ci if (!init_three_pass) 462141cc406Sopenharmony_ci od->cap |= SANE_CAP_INACTIVE; 463141cc406Sopenharmony_ci od->constraint_type = SANE_CONSTRAINT_STRING_LIST; 464141cc406Sopenharmony_ci od->constraint.string_list = order_list; 465141cc406Sopenharmony_ci test_device->val[opt_three_pass_order].s = malloc ((size_t) od->size); 466141cc406Sopenharmony_ci if (!test_device->val[opt_three_pass_order].s) 467141cc406Sopenharmony_ci goto fail; 468141cc406Sopenharmony_ci strcpy (test_device->val[opt_three_pass_order].s, init_three_pass_order); 469141cc406Sopenharmony_ci 470141cc406Sopenharmony_ci /* opt_resolution */ 471141cc406Sopenharmony_ci od = &test_device->opt[opt_resolution]; 472141cc406Sopenharmony_ci od->name = SANE_NAME_SCAN_RESOLUTION; 473141cc406Sopenharmony_ci od->title = SANE_TITLE_SCAN_RESOLUTION; 474141cc406Sopenharmony_ci od->desc = SANE_DESC_SCAN_RESOLUTION; 475141cc406Sopenharmony_ci od->type = SANE_TYPE_FIXED; 476141cc406Sopenharmony_ci od->unit = SANE_UNIT_DPI; 477141cc406Sopenharmony_ci od->size = sizeof (SANE_Word); 478141cc406Sopenharmony_ci od->cap = SANE_CAP_SOFT_DETECT | SANE_CAP_SOFT_SELECT; 479141cc406Sopenharmony_ci od->constraint_type = SANE_CONSTRAINT_RANGE; 480141cc406Sopenharmony_ci od->constraint.range = &resolution_range; 481141cc406Sopenharmony_ci test_device->val[opt_resolution].w = init_resolution; 482141cc406Sopenharmony_ci 483141cc406Sopenharmony_ci /* opt_scan_source */ 484141cc406Sopenharmony_ci od = &test_device->opt[opt_scan_source]; 485141cc406Sopenharmony_ci od->name = SANE_NAME_SCAN_SOURCE; 486141cc406Sopenharmony_ci od->title = SANE_TITLE_SCAN_SOURCE; 487141cc406Sopenharmony_ci od->desc = SANE_I18N("If Automatic Document Feeder is selected, the feeder will be 'empty' after 10 scans."); 488141cc406Sopenharmony_ci od->type = SANE_TYPE_STRING; 489141cc406Sopenharmony_ci od->unit = SANE_UNIT_NONE; 490141cc406Sopenharmony_ci od->size = (SANE_Int) max_string_size (source_list); 491141cc406Sopenharmony_ci od->cap = SANE_CAP_SOFT_DETECT | SANE_CAP_SOFT_SELECT; 492141cc406Sopenharmony_ci od->constraint_type = SANE_CONSTRAINT_STRING_LIST; 493141cc406Sopenharmony_ci od->constraint.string_list = source_list; 494141cc406Sopenharmony_ci test_device->val[opt_scan_source].s = malloc ((size_t) od->size); 495141cc406Sopenharmony_ci if (!test_device->val[opt_scan_source].s) 496141cc406Sopenharmony_ci goto fail; 497141cc406Sopenharmony_ci strcpy (test_device->val[opt_scan_source].s, init_scan_source); 498141cc406Sopenharmony_ci 499141cc406Sopenharmony_ci /* opt_special_group */ 500141cc406Sopenharmony_ci od = &test_device->opt[opt_special_group]; 501141cc406Sopenharmony_ci od->name = ""; 502141cc406Sopenharmony_ci od->title = SANE_I18N ("Special Options"); 503141cc406Sopenharmony_ci od->desc = ""; 504141cc406Sopenharmony_ci od->type = SANE_TYPE_GROUP; 505141cc406Sopenharmony_ci od->unit = SANE_UNIT_NONE; 506141cc406Sopenharmony_ci od->size = 0; 507141cc406Sopenharmony_ci od->cap = 0; 508141cc406Sopenharmony_ci od->constraint_type = SANE_CONSTRAINT_NONE; 509141cc406Sopenharmony_ci od->constraint.range = 0; 510141cc406Sopenharmony_ci test_device->val[opt_special_group].w = 0; 511141cc406Sopenharmony_ci 512141cc406Sopenharmony_ci /* opt_test_picture */ 513141cc406Sopenharmony_ci od = &test_device->opt[opt_test_picture]; 514141cc406Sopenharmony_ci od->name = "test-picture"; 515141cc406Sopenharmony_ci od->title = SANE_I18N ("Select the test picture"); 516141cc406Sopenharmony_ci od->desc = 517141cc406Sopenharmony_ci SANE_I18N ("Select the kind of test picture. Available options:\n" 518141cc406Sopenharmony_ci "Solid black: fills the whole scan with black.\n" 519141cc406Sopenharmony_ci "Solid white: fills the whole scan with white.\n" 520141cc406Sopenharmony_ci "Color pattern: draws various color test patterns " 521141cc406Sopenharmony_ci "depending on the mode.\n" 522141cc406Sopenharmony_ci "Grid: draws a black/white grid with a width and " 523141cc406Sopenharmony_ci "height of 10 mm per square."); 524141cc406Sopenharmony_ci od->type = SANE_TYPE_STRING; 525141cc406Sopenharmony_ci od->unit = SANE_UNIT_NONE; 526141cc406Sopenharmony_ci od->size = (SANE_Int) max_string_size (test_picture_list); 527141cc406Sopenharmony_ci od->cap = SANE_CAP_SOFT_DETECT | SANE_CAP_SOFT_SELECT; 528141cc406Sopenharmony_ci od->constraint_type = SANE_CONSTRAINT_STRING_LIST; 529141cc406Sopenharmony_ci od->constraint.string_list = test_picture_list; 530141cc406Sopenharmony_ci test_device->val[opt_test_picture].s = malloc ((size_t) od->size); 531141cc406Sopenharmony_ci if (!test_device->val[opt_test_picture].s) 532141cc406Sopenharmony_ci goto fail; 533141cc406Sopenharmony_ci strcpy (test_device->val[opt_test_picture].s, init_test_picture); 534141cc406Sopenharmony_ci 535141cc406Sopenharmony_ci /* opt_invert_endianness */ 536141cc406Sopenharmony_ci od = &test_device->opt[opt_invert_endianess]; 537141cc406Sopenharmony_ci od->name = "invert-endianess"; 538141cc406Sopenharmony_ci od->title = SANE_I18N ("Invert endianness"); 539141cc406Sopenharmony_ci od->desc = SANE_I18N ("Exchange upper and lower byte of image data in 16 " 540141cc406Sopenharmony_ci "bit modes. This option can be used to test the 16 " 541141cc406Sopenharmony_ci "bit modes of frontends, e.g. if the frontend uses " 542141cc406Sopenharmony_ci "the correct endianness."); 543141cc406Sopenharmony_ci od->type = SANE_TYPE_BOOL; 544141cc406Sopenharmony_ci od->unit = SANE_UNIT_NONE; 545141cc406Sopenharmony_ci od->size = sizeof (SANE_Word); 546141cc406Sopenharmony_ci od->cap = SANE_CAP_SOFT_DETECT | SANE_CAP_SOFT_SELECT; 547141cc406Sopenharmony_ci od->cap |= SANE_CAP_INACTIVE; 548141cc406Sopenharmony_ci od->constraint_type = SANE_CONSTRAINT_NONE; 549141cc406Sopenharmony_ci od->constraint.range = 0; 550141cc406Sopenharmony_ci test_device->val[opt_invert_endianess].w = init_invert_endianess; 551141cc406Sopenharmony_ci 552141cc406Sopenharmony_ci /* opt_read_limit */ 553141cc406Sopenharmony_ci od = &test_device->opt[opt_read_limit]; 554141cc406Sopenharmony_ci od->name = "read-limit"; 555141cc406Sopenharmony_ci od->title = SANE_I18N ("Read limit"); 556141cc406Sopenharmony_ci od->desc = SANE_I18N ("Limit the amount of data transferred with each " 557141cc406Sopenharmony_ci "call to sane_read()."); 558141cc406Sopenharmony_ci od->type = SANE_TYPE_BOOL; 559141cc406Sopenharmony_ci od->unit = SANE_UNIT_NONE; 560141cc406Sopenharmony_ci od->size = sizeof (SANE_Word); 561141cc406Sopenharmony_ci od->cap = SANE_CAP_SOFT_DETECT | SANE_CAP_SOFT_SELECT; 562141cc406Sopenharmony_ci od->constraint_type = SANE_CONSTRAINT_NONE; 563141cc406Sopenharmony_ci od->constraint.range = 0; 564141cc406Sopenharmony_ci test_device->val[opt_read_limit].w = init_read_limit; 565141cc406Sopenharmony_ci 566141cc406Sopenharmony_ci /* opt_read_limit_size */ 567141cc406Sopenharmony_ci od = &test_device->opt[opt_read_limit_size]; 568141cc406Sopenharmony_ci od->name = "read-limit-size"; 569141cc406Sopenharmony_ci od->title = SANE_I18N ("Size of read-limit"); 570141cc406Sopenharmony_ci od->desc = SANE_I18N ("The (maximum) amount of data transferred with each " 571141cc406Sopenharmony_ci "call to sane_read()."); 572141cc406Sopenharmony_ci od->type = SANE_TYPE_INT; 573141cc406Sopenharmony_ci od->unit = SANE_UNIT_NONE; 574141cc406Sopenharmony_ci od->size = sizeof (SANE_Word); 575141cc406Sopenharmony_ci od->cap = SANE_CAP_SOFT_DETECT | SANE_CAP_SOFT_SELECT; 576141cc406Sopenharmony_ci if (!init_read_limit) 577141cc406Sopenharmony_ci od->cap |= SANE_CAP_INACTIVE; 578141cc406Sopenharmony_ci od->constraint_type = SANE_CONSTRAINT_RANGE; 579141cc406Sopenharmony_ci od->constraint.range = &read_limit_size_range; 580141cc406Sopenharmony_ci test_device->val[opt_read_limit_size].w = init_read_limit_size; 581141cc406Sopenharmony_ci 582141cc406Sopenharmony_ci /* opt_read_delay */ 583141cc406Sopenharmony_ci od = &test_device->opt[opt_read_delay]; 584141cc406Sopenharmony_ci od->name = "read-delay"; 585141cc406Sopenharmony_ci od->title = SANE_I18N ("Read delay"); 586141cc406Sopenharmony_ci od->desc = SANE_I18N ("Delay the transfer of data to the pipe."); 587141cc406Sopenharmony_ci od->type = SANE_TYPE_BOOL; 588141cc406Sopenharmony_ci od->unit = SANE_UNIT_NONE; 589141cc406Sopenharmony_ci od->size = sizeof (SANE_Word); 590141cc406Sopenharmony_ci od->cap = SANE_CAP_SOFT_DETECT | SANE_CAP_SOFT_SELECT; 591141cc406Sopenharmony_ci od->constraint_type = SANE_CONSTRAINT_NONE; 592141cc406Sopenharmony_ci od->constraint.range = 0; 593141cc406Sopenharmony_ci test_device->val[opt_read_delay].w = init_read_delay; 594141cc406Sopenharmony_ci 595141cc406Sopenharmony_ci /* opt_read_delay_duration */ 596141cc406Sopenharmony_ci od = &test_device->opt[opt_read_delay_duration]; 597141cc406Sopenharmony_ci od->name = "read-delay-duration"; 598141cc406Sopenharmony_ci od->title = SANE_I18N ("Duration of read-delay"); 599141cc406Sopenharmony_ci od->desc = SANE_I18N ("How long to wait after transferring each buffer of " 600141cc406Sopenharmony_ci "data through the pipe."); 601141cc406Sopenharmony_ci od->type = SANE_TYPE_INT; 602141cc406Sopenharmony_ci od->unit = SANE_UNIT_MICROSECOND; 603141cc406Sopenharmony_ci od->size = sizeof (SANE_Word); 604141cc406Sopenharmony_ci od->cap = SANE_CAP_SOFT_DETECT | SANE_CAP_SOFT_SELECT; 605141cc406Sopenharmony_ci if (!init_read_delay) 606141cc406Sopenharmony_ci od->cap |= SANE_CAP_INACTIVE; 607141cc406Sopenharmony_ci od->constraint_type = SANE_CONSTRAINT_RANGE; 608141cc406Sopenharmony_ci od->constraint.range = &read_delay_duration_range; 609141cc406Sopenharmony_ci test_device->val[opt_read_delay_duration].w = init_read_delay_duration; 610141cc406Sopenharmony_ci 611141cc406Sopenharmony_ci /* opt_read_status_code */ 612141cc406Sopenharmony_ci od = &test_device->opt[opt_read_status_code]; 613141cc406Sopenharmony_ci od->name = "read-return-value"; 614141cc406Sopenharmony_ci od->title = SANE_I18N ("Return-value of sane_read"); 615141cc406Sopenharmony_ci od->desc = 616141cc406Sopenharmony_ci SANE_I18N ("Select the return-value of sane_read(). \"Default\" " 617141cc406Sopenharmony_ci "is the normal handling for scanning. All other status " 618141cc406Sopenharmony_ci "codes are for testing how the frontend handles them."); 619141cc406Sopenharmony_ci od->type = SANE_TYPE_STRING; 620141cc406Sopenharmony_ci od->unit = SANE_UNIT_NONE; 621141cc406Sopenharmony_ci od->size = (SANE_Int) max_string_size (read_status_code_list); 622141cc406Sopenharmony_ci od->cap = SANE_CAP_SOFT_DETECT | SANE_CAP_SOFT_SELECT; 623141cc406Sopenharmony_ci od->constraint_type = SANE_CONSTRAINT_STRING_LIST; 624141cc406Sopenharmony_ci od->constraint.string_list = read_status_code_list; 625141cc406Sopenharmony_ci test_device->val[opt_read_status_code].s = malloc ((size_t) od->size); 626141cc406Sopenharmony_ci if (!test_device->val[opt_read_status_code].s) 627141cc406Sopenharmony_ci goto fail; 628141cc406Sopenharmony_ci strcpy (test_device->val[opt_read_status_code].s, init_read_status_code); 629141cc406Sopenharmony_ci 630141cc406Sopenharmony_ci /* opt_ppl_loss */ 631141cc406Sopenharmony_ci od = &test_device->opt[opt_ppl_loss]; 632141cc406Sopenharmony_ci od->name = "ppl-loss"; 633141cc406Sopenharmony_ci od->title = SANE_I18N ("Loss of pixels per line"); 634141cc406Sopenharmony_ci od->desc = 635141cc406Sopenharmony_ci SANE_I18N ("The number of pixels that are wasted at the end of each " 636141cc406Sopenharmony_ci "line."); 637141cc406Sopenharmony_ci od->type = SANE_TYPE_INT; 638141cc406Sopenharmony_ci od->unit = SANE_UNIT_PIXEL; 639141cc406Sopenharmony_ci od->size = sizeof (SANE_Word); 640141cc406Sopenharmony_ci od->cap = SANE_CAP_SOFT_DETECT | SANE_CAP_SOFT_SELECT; 641141cc406Sopenharmony_ci od->constraint_type = SANE_CONSTRAINT_RANGE; 642141cc406Sopenharmony_ci od->constraint.range = &ppl_loss_range; 643141cc406Sopenharmony_ci test_device->val[opt_ppl_loss].w = init_ppl_loss; 644141cc406Sopenharmony_ci 645141cc406Sopenharmony_ci /* opt_fuzzy_parameters */ 646141cc406Sopenharmony_ci od = &test_device->opt[opt_fuzzy_parameters]; 647141cc406Sopenharmony_ci od->name = "fuzzy-parameters"; 648141cc406Sopenharmony_ci od->title = SANE_I18N ("Fuzzy parameters"); 649141cc406Sopenharmony_ci od->desc = SANE_I18N ("Return fuzzy lines and bytes per line when " 650141cc406Sopenharmony_ci "sane_parameters() is called before sane_start()."); 651141cc406Sopenharmony_ci od->type = SANE_TYPE_BOOL; 652141cc406Sopenharmony_ci od->unit = SANE_UNIT_NONE; 653141cc406Sopenharmony_ci od->size = sizeof (SANE_Word); 654141cc406Sopenharmony_ci od->cap = SANE_CAP_SOFT_DETECT | SANE_CAP_SOFT_SELECT; 655141cc406Sopenharmony_ci od->constraint_type = SANE_CONSTRAINT_NONE; 656141cc406Sopenharmony_ci od->constraint.range = 0; 657141cc406Sopenharmony_ci test_device->val[opt_fuzzy_parameters].w = init_fuzzy_parameters; 658141cc406Sopenharmony_ci 659141cc406Sopenharmony_ci /* opt_non_blocking */ 660141cc406Sopenharmony_ci od = &test_device->opt[opt_non_blocking]; 661141cc406Sopenharmony_ci od->name = "non-blocking"; 662141cc406Sopenharmony_ci od->title = SANE_I18N ("Use non-blocking IO"); 663141cc406Sopenharmony_ci od->desc = SANE_I18N ("Use non-blocking IO for sane_read() if supported " 664141cc406Sopenharmony_ci "by the frontend."); 665141cc406Sopenharmony_ci od->type = SANE_TYPE_BOOL; 666141cc406Sopenharmony_ci od->unit = SANE_UNIT_NONE; 667141cc406Sopenharmony_ci od->size = sizeof (SANE_Word); 668141cc406Sopenharmony_ci od->cap = SANE_CAP_SOFT_DETECT | SANE_CAP_SOFT_SELECT; 669141cc406Sopenharmony_ci od->constraint_type = SANE_CONSTRAINT_NONE; 670141cc406Sopenharmony_ci od->constraint.range = 0; 671141cc406Sopenharmony_ci test_device->val[opt_non_blocking].w = init_non_blocking; 672141cc406Sopenharmony_ci 673141cc406Sopenharmony_ci /* opt_select_fd */ 674141cc406Sopenharmony_ci od = &test_device->opt[opt_select_fd]; 675141cc406Sopenharmony_ci od->name = "select-fd"; 676141cc406Sopenharmony_ci od->title = SANE_I18N ("Offer select file descriptor"); 677141cc406Sopenharmony_ci od->desc = SANE_I18N ("Offer a select filedescriptor for detecting if " 678141cc406Sopenharmony_ci "sane_read() will return data."); 679141cc406Sopenharmony_ci od->type = SANE_TYPE_BOOL; 680141cc406Sopenharmony_ci od->unit = SANE_UNIT_NONE; 681141cc406Sopenharmony_ci od->size = sizeof (SANE_Word); 682141cc406Sopenharmony_ci od->cap = SANE_CAP_SOFT_DETECT | SANE_CAP_SOFT_SELECT; 683141cc406Sopenharmony_ci od->constraint_type = SANE_CONSTRAINT_NONE; 684141cc406Sopenharmony_ci od->constraint.range = 0; 685141cc406Sopenharmony_ci test_device->val[opt_select_fd].w = init_select_fd; 686141cc406Sopenharmony_ci 687141cc406Sopenharmony_ci /* opt_enable_test_options */ 688141cc406Sopenharmony_ci od = &test_device->opt[opt_enable_test_options]; 689141cc406Sopenharmony_ci od->name = "enable-test-options"; 690141cc406Sopenharmony_ci od->title = SANE_I18N ("Enable test options"); 691141cc406Sopenharmony_ci od->desc = SANE_I18N ("Enable various test options. This is for testing " 692141cc406Sopenharmony_ci "the ability of frontends to view and modify all the " 693141cc406Sopenharmony_ci "different SANE option types."); 694141cc406Sopenharmony_ci od->type = SANE_TYPE_BOOL; 695141cc406Sopenharmony_ci od->unit = SANE_UNIT_NONE; 696141cc406Sopenharmony_ci od->size = sizeof (SANE_Word); 697141cc406Sopenharmony_ci od->cap = SANE_CAP_SOFT_DETECT | SANE_CAP_SOFT_SELECT; 698141cc406Sopenharmony_ci od->constraint_type = SANE_CONSTRAINT_NONE; 699141cc406Sopenharmony_ci od->constraint.range = 0; 700141cc406Sopenharmony_ci test_device->val[opt_enable_test_options].w = init_enable_test_options; 701141cc406Sopenharmony_ci 702141cc406Sopenharmony_ci /* opt_print_options */ 703141cc406Sopenharmony_ci od = &test_device->opt[opt_print_options]; 704141cc406Sopenharmony_ci od->name = "print-options"; 705141cc406Sopenharmony_ci od->title = SANE_I18N ("Print options"); 706141cc406Sopenharmony_ci od->desc = SANE_I18N ("Print a list of all options."); 707141cc406Sopenharmony_ci od->type = SANE_TYPE_BUTTON; 708141cc406Sopenharmony_ci od->unit = SANE_UNIT_NONE; 709141cc406Sopenharmony_ci od->size = 0; 710141cc406Sopenharmony_ci od->cap = SANE_CAP_SOFT_DETECT | SANE_CAP_SOFT_SELECT; 711141cc406Sopenharmony_ci od->constraint_type = SANE_CONSTRAINT_NONE; 712141cc406Sopenharmony_ci od->constraint.string_list = 0; 713141cc406Sopenharmony_ci test_device->val[opt_print_options].w = 0; 714141cc406Sopenharmony_ci 715141cc406Sopenharmony_ci /* opt_geometry_group */ 716141cc406Sopenharmony_ci od = &test_device->opt[opt_geometry_group]; 717141cc406Sopenharmony_ci od->name = ""; 718141cc406Sopenharmony_ci od->title = SANE_I18N ("Geometry"); 719141cc406Sopenharmony_ci od->desc = ""; 720141cc406Sopenharmony_ci od->type = SANE_TYPE_GROUP; 721141cc406Sopenharmony_ci od->unit = SANE_UNIT_NONE; 722141cc406Sopenharmony_ci od->size = 0; 723141cc406Sopenharmony_ci od->cap = 0; 724141cc406Sopenharmony_ci od->constraint_type = SANE_CONSTRAINT_NONE; 725141cc406Sopenharmony_ci od->constraint.range = 0; 726141cc406Sopenharmony_ci test_device->val[opt_geometry_group].w = 0; 727141cc406Sopenharmony_ci 728141cc406Sopenharmony_ci /* opt_tl_x */ 729141cc406Sopenharmony_ci od = &test_device->opt[opt_tl_x]; 730141cc406Sopenharmony_ci od->name = SANE_NAME_SCAN_TL_X; 731141cc406Sopenharmony_ci od->title = SANE_TITLE_SCAN_TL_X; 732141cc406Sopenharmony_ci od->desc = SANE_DESC_SCAN_TL_X; 733141cc406Sopenharmony_ci od->type = SANE_TYPE_FIXED; 734141cc406Sopenharmony_ci od->unit = SANE_UNIT_MM; 735141cc406Sopenharmony_ci od->size = sizeof (SANE_Word); 736141cc406Sopenharmony_ci od->cap = SANE_CAP_SOFT_DETECT | SANE_CAP_SOFT_SELECT; 737141cc406Sopenharmony_ci od->constraint_type = SANE_CONSTRAINT_RANGE; 738141cc406Sopenharmony_ci od->constraint.range = &geometry_range; 739141cc406Sopenharmony_ci test_device->val[opt_tl_x].w = init_tl_x; 740141cc406Sopenharmony_ci 741141cc406Sopenharmony_ci /* opt_tl_y */ 742141cc406Sopenharmony_ci od = &test_device->opt[opt_tl_y]; 743141cc406Sopenharmony_ci od->name = SANE_NAME_SCAN_TL_Y; 744141cc406Sopenharmony_ci od->title = SANE_TITLE_SCAN_TL_Y; 745141cc406Sopenharmony_ci od->desc = SANE_DESC_SCAN_TL_Y; 746141cc406Sopenharmony_ci od->type = SANE_TYPE_FIXED; 747141cc406Sopenharmony_ci od->unit = SANE_UNIT_MM; 748141cc406Sopenharmony_ci od->size = sizeof (SANE_Word); 749141cc406Sopenharmony_ci od->cap = SANE_CAP_SOFT_DETECT | SANE_CAP_SOFT_SELECT; 750141cc406Sopenharmony_ci od->constraint_type = SANE_CONSTRAINT_RANGE; 751141cc406Sopenharmony_ci od->constraint.range = &geometry_range; 752141cc406Sopenharmony_ci test_device->val[opt_tl_y].w = init_tl_y; 753141cc406Sopenharmony_ci 754141cc406Sopenharmony_ci /* opt_br_x */ 755141cc406Sopenharmony_ci od = &test_device->opt[opt_br_x]; 756141cc406Sopenharmony_ci od->name = SANE_NAME_SCAN_BR_X; 757141cc406Sopenharmony_ci od->title = SANE_TITLE_SCAN_BR_X; 758141cc406Sopenharmony_ci od->desc = SANE_DESC_SCAN_BR_X; 759141cc406Sopenharmony_ci od->type = SANE_TYPE_FIXED; 760141cc406Sopenharmony_ci od->unit = SANE_UNIT_MM; 761141cc406Sopenharmony_ci od->size = sizeof (SANE_Word); 762141cc406Sopenharmony_ci od->cap = SANE_CAP_SOFT_DETECT | SANE_CAP_SOFT_SELECT; 763141cc406Sopenharmony_ci od->constraint_type = SANE_CONSTRAINT_RANGE; 764141cc406Sopenharmony_ci od->constraint.range = &geometry_range; 765141cc406Sopenharmony_ci test_device->val[opt_br_x].w = init_br_x; 766141cc406Sopenharmony_ci 767141cc406Sopenharmony_ci /* opt_br_y */ 768141cc406Sopenharmony_ci od = &test_device->opt[opt_br_y]; 769141cc406Sopenharmony_ci od->name = SANE_NAME_SCAN_BR_Y; 770141cc406Sopenharmony_ci od->title = SANE_TITLE_SCAN_BR_Y; 771141cc406Sopenharmony_ci od->desc = SANE_DESC_SCAN_BR_Y; 772141cc406Sopenharmony_ci od->type = SANE_TYPE_FIXED; 773141cc406Sopenharmony_ci od->unit = SANE_UNIT_MM; 774141cc406Sopenharmony_ci od->size = sizeof (SANE_Word); 775141cc406Sopenharmony_ci od->cap = SANE_CAP_SOFT_DETECT | SANE_CAP_SOFT_SELECT; 776141cc406Sopenharmony_ci od->constraint_type = SANE_CONSTRAINT_RANGE; 777141cc406Sopenharmony_ci od->constraint.range = &geometry_range; 778141cc406Sopenharmony_ci test_device->val[opt_br_y].w = init_br_y; 779141cc406Sopenharmony_ci 780141cc406Sopenharmony_ci /* opt_bool_group */ 781141cc406Sopenharmony_ci od = &test_device->opt[opt_bool_group]; 782141cc406Sopenharmony_ci od->name = ""; 783141cc406Sopenharmony_ci od->title = SANE_I18N ("Bool test options"); 784141cc406Sopenharmony_ci od->desc = ""; 785141cc406Sopenharmony_ci od->type = SANE_TYPE_GROUP; 786141cc406Sopenharmony_ci od->unit = SANE_UNIT_NONE; 787141cc406Sopenharmony_ci od->size = 0; 788141cc406Sopenharmony_ci od->cap = SANE_CAP_ADVANCED; 789141cc406Sopenharmony_ci od->constraint_type = SANE_CONSTRAINT_NONE; 790141cc406Sopenharmony_ci od->constraint.range = 0; 791141cc406Sopenharmony_ci test_device->val[opt_bool_group].w = 0; 792141cc406Sopenharmony_ci 793141cc406Sopenharmony_ci /* opt_bool_soft_select_soft_detect */ 794141cc406Sopenharmony_ci od = &test_device->opt[opt_bool_soft_select_soft_detect]; 795141cc406Sopenharmony_ci od->name = "bool-soft-select-soft-detect"; 796141cc406Sopenharmony_ci od->title = SANE_I18N ("(1/6) Bool soft select soft detect"); 797141cc406Sopenharmony_ci od->desc = 798141cc406Sopenharmony_ci SANE_I18N ("(1/6) Bool test option that has soft select and soft " 799141cc406Sopenharmony_ci "detect (and advanced) capabilities. That's just a " 800141cc406Sopenharmony_ci "normal bool option."); 801141cc406Sopenharmony_ci od->type = SANE_TYPE_BOOL; 802141cc406Sopenharmony_ci od->unit = SANE_UNIT_NONE; 803141cc406Sopenharmony_ci od->size = sizeof (SANE_Word); 804141cc406Sopenharmony_ci od->cap = SANE_CAP_SOFT_DETECT | SANE_CAP_SOFT_SELECT | SANE_CAP_ADVANCED; 805141cc406Sopenharmony_ci if (init_enable_test_options == SANE_FALSE) 806141cc406Sopenharmony_ci od->cap |= SANE_CAP_INACTIVE; 807141cc406Sopenharmony_ci od->constraint_type = SANE_CONSTRAINT_NONE; 808141cc406Sopenharmony_ci od->constraint.range = 0; 809141cc406Sopenharmony_ci test_device->val[opt_bool_soft_select_soft_detect].w = SANE_FALSE; 810141cc406Sopenharmony_ci 811141cc406Sopenharmony_ci /* opt_bool_hard_select_soft_detect */ 812141cc406Sopenharmony_ci od = &test_device->opt[opt_bool_hard_select_soft_detect]; 813141cc406Sopenharmony_ci od->name = "bool-hard-select-soft-detect"; 814141cc406Sopenharmony_ci od->title = SANE_I18N ("(2/6) Bool hard select soft detect"); 815141cc406Sopenharmony_ci od->desc = 816141cc406Sopenharmony_ci SANE_I18N ("(2/6) Bool test option that has hard select and soft " 817141cc406Sopenharmony_ci "detect (and advanced) capabilities. That means the " 818141cc406Sopenharmony_ci "option can't be set by the frontend but by the user " 819141cc406Sopenharmony_ci "(e.g. by pressing a button at the device)."); 820141cc406Sopenharmony_ci od->type = SANE_TYPE_BOOL; 821141cc406Sopenharmony_ci od->unit = SANE_UNIT_NONE; 822141cc406Sopenharmony_ci od->size = sizeof (SANE_Word); 823141cc406Sopenharmony_ci od->cap = SANE_CAP_SOFT_DETECT | SANE_CAP_HARD_SELECT | SANE_CAP_ADVANCED; 824141cc406Sopenharmony_ci if (init_enable_test_options == SANE_FALSE) 825141cc406Sopenharmony_ci od->cap |= SANE_CAP_INACTIVE; 826141cc406Sopenharmony_ci od->constraint_type = SANE_CONSTRAINT_NONE; 827141cc406Sopenharmony_ci od->constraint.range = 0; 828141cc406Sopenharmony_ci test_device->val[opt_bool_hard_select_soft_detect].w = SANE_FALSE; 829141cc406Sopenharmony_ci 830141cc406Sopenharmony_ci /* opt_bool_hard_select */ 831141cc406Sopenharmony_ci od = &test_device->opt[opt_bool_hard_select]; 832141cc406Sopenharmony_ci od->name = "bool-hard-select"; 833141cc406Sopenharmony_ci od->title = SANE_I18N ("(3/6) Bool hard select"); 834141cc406Sopenharmony_ci od->desc = SANE_I18N ("(3/6) Bool test option that has hard select " 835141cc406Sopenharmony_ci "(and advanced) capabilities. That means the option " 836141cc406Sopenharmony_ci "can't be set by the frontend but by the user " 837141cc406Sopenharmony_ci "(e.g. by pressing a button at the device) and can't " 838141cc406Sopenharmony_ci "be read by the frontend."); 839141cc406Sopenharmony_ci od->type = SANE_TYPE_BOOL; 840141cc406Sopenharmony_ci od->unit = SANE_UNIT_NONE; 841141cc406Sopenharmony_ci od->size = sizeof (SANE_Word); 842141cc406Sopenharmony_ci od->cap = SANE_CAP_HARD_SELECT | SANE_CAP_ADVANCED; 843141cc406Sopenharmony_ci if (init_enable_test_options == SANE_FALSE) 844141cc406Sopenharmony_ci od->cap |= SANE_CAP_INACTIVE; 845141cc406Sopenharmony_ci od->constraint_type = SANE_CONSTRAINT_NONE; 846141cc406Sopenharmony_ci od->constraint.range = 0; 847141cc406Sopenharmony_ci test_device->val[opt_bool_hard_select].w = SANE_FALSE; 848141cc406Sopenharmony_ci 849141cc406Sopenharmony_ci /* opt_bool_soft_detect */ 850141cc406Sopenharmony_ci od = &test_device->opt[opt_bool_soft_detect]; 851141cc406Sopenharmony_ci od->name = "bool-soft-detect"; 852141cc406Sopenharmony_ci od->title = SANE_I18N ("(4/6) Bool soft detect"); 853141cc406Sopenharmony_ci od->desc = SANE_I18N ("(4/6) Bool test option that has soft detect " 854141cc406Sopenharmony_ci "(and advanced) capabilities. That means the option " 855141cc406Sopenharmony_ci "is read-only."); 856141cc406Sopenharmony_ci od->type = SANE_TYPE_BOOL; 857141cc406Sopenharmony_ci od->unit = SANE_UNIT_NONE; 858141cc406Sopenharmony_ci od->size = sizeof (SANE_Word); 859141cc406Sopenharmony_ci od->cap = SANE_CAP_SOFT_DETECT | SANE_CAP_ADVANCED; 860141cc406Sopenharmony_ci if (init_enable_test_options == SANE_FALSE) 861141cc406Sopenharmony_ci od->cap |= SANE_CAP_INACTIVE; 862141cc406Sopenharmony_ci od->constraint_type = SANE_CONSTRAINT_NONE; 863141cc406Sopenharmony_ci od->constraint.range = 0; 864141cc406Sopenharmony_ci test_device->val[opt_bool_soft_detect].w = SANE_FALSE; 865141cc406Sopenharmony_ci 866141cc406Sopenharmony_ci /* opt_bool_soft_select_soft_detect_emulated */ 867141cc406Sopenharmony_ci od = &test_device->opt[opt_bool_soft_select_soft_detect_emulated]; 868141cc406Sopenharmony_ci od->name = "bool-soft-select-soft-detect-emulated"; 869141cc406Sopenharmony_ci od->title = SANE_I18N ("(5/6) Bool soft select soft detect emulated"); 870141cc406Sopenharmony_ci od->desc = SANE_I18N ("(5/6) Bool test option that has soft select, soft " 871141cc406Sopenharmony_ci "detect, and emulated (and advanced) capabilities."); 872141cc406Sopenharmony_ci od->type = SANE_TYPE_BOOL; 873141cc406Sopenharmony_ci od->unit = SANE_UNIT_NONE; 874141cc406Sopenharmony_ci od->size = sizeof (SANE_Word); 875141cc406Sopenharmony_ci od->cap = SANE_CAP_SOFT_DETECT | SANE_CAP_SOFT_SELECT | SANE_CAP_ADVANCED 876141cc406Sopenharmony_ci | SANE_CAP_EMULATED; 877141cc406Sopenharmony_ci if (init_enable_test_options == SANE_FALSE) 878141cc406Sopenharmony_ci od->cap |= SANE_CAP_INACTIVE; 879141cc406Sopenharmony_ci od->constraint_type = SANE_CONSTRAINT_NONE; 880141cc406Sopenharmony_ci od->constraint.range = 0; 881141cc406Sopenharmony_ci test_device->val[opt_bool_soft_select_soft_detect_emulated].w = SANE_FALSE; 882141cc406Sopenharmony_ci 883141cc406Sopenharmony_ci /* opt_bool_soft_select_soft_detect_auto */ 884141cc406Sopenharmony_ci od = &test_device->opt[opt_bool_soft_select_soft_detect_auto]; 885141cc406Sopenharmony_ci od->name = "bool-soft-select-soft-detect-auto"; 886141cc406Sopenharmony_ci od->title = SANE_I18N ("(6/6) Bool soft select soft detect auto"); 887141cc406Sopenharmony_ci od->desc = SANE_I18N ("(6/6) Bool test option that has soft select, soft " 888141cc406Sopenharmony_ci "detect, and automatic (and advanced) capabilities. " 889141cc406Sopenharmony_ci "This option can be automatically set by the backend."); 890141cc406Sopenharmony_ci od->type = SANE_TYPE_BOOL; 891141cc406Sopenharmony_ci od->unit = SANE_UNIT_NONE; 892141cc406Sopenharmony_ci od->size = sizeof (SANE_Word); 893141cc406Sopenharmony_ci od->cap = SANE_CAP_SOFT_DETECT | SANE_CAP_SOFT_SELECT | SANE_CAP_ADVANCED 894141cc406Sopenharmony_ci | SANE_CAP_AUTOMATIC; 895141cc406Sopenharmony_ci if (init_enable_test_options == SANE_FALSE) 896141cc406Sopenharmony_ci od->cap |= SANE_CAP_INACTIVE; 897141cc406Sopenharmony_ci od->constraint_type = SANE_CONSTRAINT_NONE; 898141cc406Sopenharmony_ci od->constraint.range = 0; 899141cc406Sopenharmony_ci test_device->val[opt_bool_soft_select_soft_detect_auto].w = SANE_FALSE; 900141cc406Sopenharmony_ci 901141cc406Sopenharmony_ci /* opt_int_group */ 902141cc406Sopenharmony_ci od = &test_device->opt[opt_int_group]; 903141cc406Sopenharmony_ci od->name = ""; 904141cc406Sopenharmony_ci od->title = SANE_I18N ("Int test options"); 905141cc406Sopenharmony_ci od->desc = ""; 906141cc406Sopenharmony_ci od->type = SANE_TYPE_GROUP; 907141cc406Sopenharmony_ci od->unit = SANE_UNIT_NONE; 908141cc406Sopenharmony_ci od->size = 0; 909141cc406Sopenharmony_ci od->cap = SANE_CAP_ADVANCED; 910141cc406Sopenharmony_ci od->constraint_type = SANE_CONSTRAINT_NONE; 911141cc406Sopenharmony_ci od->constraint.range = 0; 912141cc406Sopenharmony_ci test_device->val[opt_int_group].w = 0; 913141cc406Sopenharmony_ci 914141cc406Sopenharmony_ci /* opt_int */ 915141cc406Sopenharmony_ci od = &test_device->opt[opt_int]; 916141cc406Sopenharmony_ci od->name = "int"; 917141cc406Sopenharmony_ci od->title = SANE_I18N ("(1/7) Int"); 918141cc406Sopenharmony_ci od->desc = SANE_I18N ("(1/7) Int test option with no unit and no " 919141cc406Sopenharmony_ci "constraint set."); 920141cc406Sopenharmony_ci od->type = SANE_TYPE_INT; 921141cc406Sopenharmony_ci od->unit = SANE_UNIT_NONE; 922141cc406Sopenharmony_ci od->size = sizeof (SANE_Word); 923141cc406Sopenharmony_ci od->cap = SANE_CAP_SOFT_DETECT | SANE_CAP_SOFT_SELECT | SANE_CAP_ADVANCED; 924141cc406Sopenharmony_ci if (init_enable_test_options == SANE_FALSE) 925141cc406Sopenharmony_ci od->cap |= SANE_CAP_INACTIVE; 926141cc406Sopenharmony_ci od->constraint_type = SANE_CONSTRAINT_NONE; 927141cc406Sopenharmony_ci od->constraint.range = 0; 928141cc406Sopenharmony_ci test_device->val[opt_int].w = 42; 929141cc406Sopenharmony_ci 930141cc406Sopenharmony_ci /* opt_int_constraint_range */ 931141cc406Sopenharmony_ci od = &test_device->opt[opt_int_constraint_range]; 932141cc406Sopenharmony_ci od->name = "int-constraint-range"; 933141cc406Sopenharmony_ci od->title = SANE_I18N ("(2/7) Int constraint range"); 934141cc406Sopenharmony_ci od->desc = SANE_I18N ("(2/7) Int test option with unit pixel and " 935141cc406Sopenharmony_ci "constraint range set. Minimum is 4, maximum 192, and " 936141cc406Sopenharmony_ci "quant is 2."); 937141cc406Sopenharmony_ci od->type = SANE_TYPE_INT; 938141cc406Sopenharmony_ci od->unit = SANE_UNIT_PIXEL; 939141cc406Sopenharmony_ci od->size = sizeof (SANE_Word); 940141cc406Sopenharmony_ci od->cap = SANE_CAP_SOFT_DETECT | SANE_CAP_SOFT_SELECT | SANE_CAP_ADVANCED; 941141cc406Sopenharmony_ci if (init_enable_test_options == SANE_FALSE) 942141cc406Sopenharmony_ci od->cap |= SANE_CAP_INACTIVE; 943141cc406Sopenharmony_ci od->constraint_type = SANE_CONSTRAINT_RANGE; 944141cc406Sopenharmony_ci od->constraint.range = &int_constraint_range; 945141cc406Sopenharmony_ci test_device->val[opt_int_constraint_range].w = 26; 946141cc406Sopenharmony_ci 947141cc406Sopenharmony_ci /* opt_int_constraint_word_list */ 948141cc406Sopenharmony_ci od = &test_device->opt[opt_int_constraint_word_list]; 949141cc406Sopenharmony_ci od->name = "int-constraint-word-list"; 950141cc406Sopenharmony_ci od->title = SANE_I18N ("(3/7) Int constraint word list"); 951141cc406Sopenharmony_ci od->desc = SANE_I18N ("(3/7) Int test option with unit bits and " 952141cc406Sopenharmony_ci "constraint word list set."); 953141cc406Sopenharmony_ci od->type = SANE_TYPE_INT; 954141cc406Sopenharmony_ci od->unit = SANE_UNIT_BIT; 955141cc406Sopenharmony_ci od->size = sizeof (SANE_Word); 956141cc406Sopenharmony_ci od->cap = SANE_CAP_SOFT_DETECT | SANE_CAP_SOFT_SELECT | SANE_CAP_ADVANCED; 957141cc406Sopenharmony_ci if (init_enable_test_options == SANE_FALSE) 958141cc406Sopenharmony_ci od->cap |= SANE_CAP_INACTIVE; 959141cc406Sopenharmony_ci od->constraint_type = SANE_CONSTRAINT_WORD_LIST; 960141cc406Sopenharmony_ci od->constraint.word_list = int_constraint_word_list; 961141cc406Sopenharmony_ci test_device->val[opt_int_constraint_word_list].w = 42; 962141cc406Sopenharmony_ci 963141cc406Sopenharmony_ci /* opt_int_array */ 964141cc406Sopenharmony_ci od = &test_device->opt[opt_int_array]; 965141cc406Sopenharmony_ci od->name = "int-constraint-array"; 966141cc406Sopenharmony_ci od->title = SANE_I18N ("(4/7) Int array"); 967141cc406Sopenharmony_ci od->desc = SANE_I18N ("(4/7) Int test option with unit mm and using " 968141cc406Sopenharmony_ci "an array without constraints."); 969141cc406Sopenharmony_ci od->type = SANE_TYPE_INT; 970141cc406Sopenharmony_ci od->unit = SANE_UNIT_MM; 971141cc406Sopenharmony_ci od->size = 6 * sizeof (SANE_Word); 972141cc406Sopenharmony_ci od->cap = SANE_CAP_SOFT_DETECT | SANE_CAP_SOFT_SELECT | SANE_CAP_ADVANCED; 973141cc406Sopenharmony_ci if (init_enable_test_options == SANE_FALSE) 974141cc406Sopenharmony_ci od->cap |= SANE_CAP_INACTIVE; 975141cc406Sopenharmony_ci od->constraint_type = SANE_CONSTRAINT_NONE; 976141cc406Sopenharmony_ci od->constraint.range = 0; 977141cc406Sopenharmony_ci test_device->val[opt_int_array].wa = &int_array[0]; 978141cc406Sopenharmony_ci 979141cc406Sopenharmony_ci /* opt_int_array_constraint_range */ 980141cc406Sopenharmony_ci od = &test_device->opt[opt_int_array_constraint_range]; 981141cc406Sopenharmony_ci od->name = "int-constraint-array-constraint-range"; 982141cc406Sopenharmony_ci od->title = SANE_I18N ("(5/7) Int array constraint range"); 983141cc406Sopenharmony_ci od->desc = SANE_I18N ("(5/7) Int test option with unit dpi and using " 984141cc406Sopenharmony_ci "an array with a range constraint. Minimum is 4, " 985141cc406Sopenharmony_ci "maximum 192, and quant is 2."); 986141cc406Sopenharmony_ci od->type = SANE_TYPE_INT; 987141cc406Sopenharmony_ci od->unit = SANE_UNIT_DPI; 988141cc406Sopenharmony_ci od->size = 6 * sizeof (SANE_Word); 989141cc406Sopenharmony_ci od->cap = SANE_CAP_SOFT_DETECT | SANE_CAP_SOFT_SELECT | SANE_CAP_ADVANCED; 990141cc406Sopenharmony_ci if (init_enable_test_options == SANE_FALSE) 991141cc406Sopenharmony_ci od->cap |= SANE_CAP_INACTIVE; 992141cc406Sopenharmony_ci od->constraint_type = SANE_CONSTRAINT_RANGE; 993141cc406Sopenharmony_ci od->constraint.range = &int_constraint_range; 994141cc406Sopenharmony_ci test_device->val[opt_int_array_constraint_range].wa = 995141cc406Sopenharmony_ci &int_array_constraint_range[0]; 996141cc406Sopenharmony_ci 997141cc406Sopenharmony_ci /* opt_int_array_constraint_word_list */ 998141cc406Sopenharmony_ci od = &test_device->opt[opt_int_array_constraint_word_list]; 999141cc406Sopenharmony_ci od->name = "int-constraint-array-constraint-word-list"; 1000141cc406Sopenharmony_ci od->title = SANE_I18N ("(6/7) Int array constraint word list"); 1001141cc406Sopenharmony_ci od->desc = SANE_I18N ("(6/7) Int test option with unit percent and using " 1002141cc406Sopenharmony_ci "an array with a word list constraint."); 1003141cc406Sopenharmony_ci od->type = SANE_TYPE_INT; 1004141cc406Sopenharmony_ci od->unit = SANE_UNIT_PERCENT; 1005141cc406Sopenharmony_ci od->size = 6 * sizeof (SANE_Word); 1006141cc406Sopenharmony_ci od->cap = SANE_CAP_SOFT_DETECT | SANE_CAP_SOFT_SELECT | SANE_CAP_ADVANCED; 1007141cc406Sopenharmony_ci if (init_enable_test_options == SANE_FALSE) 1008141cc406Sopenharmony_ci od->cap |= SANE_CAP_INACTIVE; 1009141cc406Sopenharmony_ci od->constraint_type = SANE_CONSTRAINT_WORD_LIST; 1010141cc406Sopenharmony_ci od->constraint.word_list = int_constraint_word_list; 1011141cc406Sopenharmony_ci test_device->val[opt_int_array_constraint_word_list].wa = 1012141cc406Sopenharmony_ci &int_array_constraint_word_list[0]; 1013141cc406Sopenharmony_ci 1014141cc406Sopenharmony_ci /* opt_int_inexact */ 1015141cc406Sopenharmony_ci od = &test_device->opt[opt_int_inexact]; 1016141cc406Sopenharmony_ci od->name = "int-inexact"; 1017141cc406Sopenharmony_ci od->title = SANE_I18N ("(7/7) Int inexact"); 1018141cc406Sopenharmony_ci od->desc = SANE_I18N ("(7/7) Int test option that modifies the value " 1019141cc406Sopenharmony_ci "and returns SANE_INFO_INEXACT."); 1020141cc406Sopenharmony_ci od->type = SANE_TYPE_INT; 1021141cc406Sopenharmony_ci od->unit = SANE_UNIT_NONE; 1022141cc406Sopenharmony_ci od->size = sizeof (SANE_Word); 1023141cc406Sopenharmony_ci od->cap = SANE_CAP_SOFT_DETECT | SANE_CAP_SOFT_SELECT | SANE_CAP_ADVANCED; 1024141cc406Sopenharmony_ci if (init_enable_test_options == SANE_FALSE) 1025141cc406Sopenharmony_ci od->cap |= SANE_CAP_INACTIVE; 1026141cc406Sopenharmony_ci od->constraint_type = SANE_CONSTRAINT_NONE; 1027141cc406Sopenharmony_ci od->constraint.range = 0; 1028141cc406Sopenharmony_ci test_device->val[opt_int_inexact].w = 67; 1029141cc406Sopenharmony_ci 1030141cc406Sopenharmony_ci 1031141cc406Sopenharmony_ci /* opt_gamma_red */ 1032141cc406Sopenharmony_ci init_gamma_table(gamma_red, GAMMA_RED_SIZE, gamma_range.max); 1033141cc406Sopenharmony_ci od = &test_device->opt[opt_gamma_red]; 1034141cc406Sopenharmony_ci od->name = SANE_NAME_GAMMA_VECTOR_R; 1035141cc406Sopenharmony_ci od->title = SANE_TITLE_GAMMA_VECTOR_R; 1036141cc406Sopenharmony_ci od->desc = SANE_DESC_GAMMA_VECTOR_R; 1037141cc406Sopenharmony_ci od->type = SANE_TYPE_INT; 1038141cc406Sopenharmony_ci od->unit = SANE_UNIT_NONE; 1039141cc406Sopenharmony_ci od->size = 256 * sizeof (SANE_Word); 1040141cc406Sopenharmony_ci od->cap = SANE_CAP_SOFT_DETECT | SANE_CAP_SOFT_SELECT | SANE_CAP_ADVANCED; 1041141cc406Sopenharmony_ci od->constraint_type = SANE_CONSTRAINT_RANGE; 1042141cc406Sopenharmony_ci od->constraint.range = &gamma_range; 1043141cc406Sopenharmony_ci test_device->val[opt_gamma_red].wa = &gamma_red[0]; 1044141cc406Sopenharmony_ci 1045141cc406Sopenharmony_ci /* opt_gamma_green */ 1046141cc406Sopenharmony_ci init_gamma_table(gamma_green, GAMMA_GREEN_SIZE, gamma_range.max); 1047141cc406Sopenharmony_ci od = &test_device->opt[opt_gamma_green]; 1048141cc406Sopenharmony_ci od->name = SANE_NAME_GAMMA_VECTOR_G; 1049141cc406Sopenharmony_ci od->title = SANE_TITLE_GAMMA_VECTOR_G; 1050141cc406Sopenharmony_ci od->desc = SANE_DESC_GAMMA_VECTOR_G; 1051141cc406Sopenharmony_ci od->type = SANE_TYPE_INT; 1052141cc406Sopenharmony_ci od->unit = SANE_UNIT_NONE; 1053141cc406Sopenharmony_ci od->size = 256 * sizeof (SANE_Word); 1054141cc406Sopenharmony_ci od->cap = SANE_CAP_SOFT_DETECT | SANE_CAP_SOFT_SELECT | SANE_CAP_ADVANCED; 1055141cc406Sopenharmony_ci od->constraint_type = SANE_CONSTRAINT_RANGE; 1056141cc406Sopenharmony_ci od->constraint.range = &gamma_range; 1057141cc406Sopenharmony_ci test_device->val[opt_gamma_green].wa = &gamma_green[0]; 1058141cc406Sopenharmony_ci 1059141cc406Sopenharmony_ci /* opt_gamma_blue */ 1060141cc406Sopenharmony_ci init_gamma_table(gamma_blue, GAMMA_BLUE_SIZE, gamma_range.max); 1061141cc406Sopenharmony_ci od = &test_device->opt[opt_gamma_blue]; 1062141cc406Sopenharmony_ci od->name = SANE_NAME_GAMMA_VECTOR_B; 1063141cc406Sopenharmony_ci od->title = SANE_TITLE_GAMMA_VECTOR_B; 1064141cc406Sopenharmony_ci od->desc = SANE_DESC_GAMMA_VECTOR_B; 1065141cc406Sopenharmony_ci od->type = SANE_TYPE_INT; 1066141cc406Sopenharmony_ci od->unit = SANE_UNIT_NONE; 1067141cc406Sopenharmony_ci od->size = 256 * sizeof (SANE_Word); 1068141cc406Sopenharmony_ci od->cap = SANE_CAP_SOFT_DETECT | SANE_CAP_SOFT_SELECT | SANE_CAP_ADVANCED; 1069141cc406Sopenharmony_ci od->constraint_type = SANE_CONSTRAINT_RANGE; 1070141cc406Sopenharmony_ci od->constraint.range = &gamma_range; 1071141cc406Sopenharmony_ci test_device->val[opt_gamma_blue].wa = &gamma_blue[0]; 1072141cc406Sopenharmony_ci 1073141cc406Sopenharmony_ci /* opt_gamma_all */ 1074141cc406Sopenharmony_ci init_gamma_table(gamma_all, GAMMA_ALL_SIZE, gamma_range.max); 1075141cc406Sopenharmony_ci print_gamma_table(gamma_all, GAMMA_ALL_SIZE); 1076141cc406Sopenharmony_ci od = &test_device->opt[opt_gamma_all]; 1077141cc406Sopenharmony_ci od->name = SANE_NAME_GAMMA_VECTOR; 1078141cc406Sopenharmony_ci od->title = SANE_TITLE_GAMMA_VECTOR; 1079141cc406Sopenharmony_ci od->desc = SANE_DESC_GAMMA_VECTOR; 1080141cc406Sopenharmony_ci od->type = SANE_TYPE_INT; 1081141cc406Sopenharmony_ci od->unit = SANE_UNIT_NONE; 1082141cc406Sopenharmony_ci od->size = GAMMA_ALL_SIZE * sizeof (SANE_Word); 1083141cc406Sopenharmony_ci od->cap = SANE_CAP_SOFT_DETECT | SANE_CAP_SOFT_SELECT | SANE_CAP_ADVANCED; 1084141cc406Sopenharmony_ci od->constraint_type = SANE_CONSTRAINT_RANGE; 1085141cc406Sopenharmony_ci od->constraint.range = &gamma_range; 1086141cc406Sopenharmony_ci test_device->val[opt_gamma_all].wa = &gamma_all[0]; 1087141cc406Sopenharmony_ci 1088141cc406Sopenharmony_ci /* opt_fixed_group */ 1089141cc406Sopenharmony_ci od = &test_device->opt[opt_fixed_group]; 1090141cc406Sopenharmony_ci od->name = ""; 1091141cc406Sopenharmony_ci od->title = SANE_I18N ("Fixed test options"); 1092141cc406Sopenharmony_ci od->desc = ""; 1093141cc406Sopenharmony_ci od->type = SANE_TYPE_GROUP; 1094141cc406Sopenharmony_ci od->unit = SANE_UNIT_NONE; 1095141cc406Sopenharmony_ci od->size = 0; 1096141cc406Sopenharmony_ci od->cap = SANE_CAP_ADVANCED; 1097141cc406Sopenharmony_ci od->constraint_type = SANE_CONSTRAINT_NONE; 1098141cc406Sopenharmony_ci od->constraint.range = 0; 1099141cc406Sopenharmony_ci test_device->val[opt_fixed_group].w = 0; 1100141cc406Sopenharmony_ci 1101141cc406Sopenharmony_ci /* opt_fixed */ 1102141cc406Sopenharmony_ci od = &test_device->opt[opt_fixed]; 1103141cc406Sopenharmony_ci od->name = "fixed"; 1104141cc406Sopenharmony_ci od->title = SANE_I18N ("(1/3) Fixed"); 1105141cc406Sopenharmony_ci od->desc = SANE_I18N ("(1/3) Fixed test option with no unit and no " 1106141cc406Sopenharmony_ci "constraint set."); 1107141cc406Sopenharmony_ci od->type = SANE_TYPE_FIXED; 1108141cc406Sopenharmony_ci od->unit = SANE_UNIT_NONE; 1109141cc406Sopenharmony_ci od->size = sizeof (SANE_Word); 1110141cc406Sopenharmony_ci od->cap = SANE_CAP_SOFT_DETECT | SANE_CAP_SOFT_SELECT | SANE_CAP_ADVANCED; 1111141cc406Sopenharmony_ci if (init_enable_test_options == SANE_FALSE) 1112141cc406Sopenharmony_ci od->cap |= SANE_CAP_INACTIVE; 1113141cc406Sopenharmony_ci od->constraint_type = SANE_CONSTRAINT_NONE; 1114141cc406Sopenharmony_ci od->constraint.range = 0; 1115141cc406Sopenharmony_ci test_device->val[opt_fixed].w = SANE_FIX (42.0); 1116141cc406Sopenharmony_ci 1117141cc406Sopenharmony_ci /* opt_fixed_constraint_range */ 1118141cc406Sopenharmony_ci od = &test_device->opt[opt_fixed_constraint_range]; 1119141cc406Sopenharmony_ci od->name = "fixed-constraint-range"; 1120141cc406Sopenharmony_ci od->title = SANE_I18N ("(2/3) Fixed constraint range"); 1121141cc406Sopenharmony_ci od->desc = SANE_I18N ("(2/3) Fixed test option with unit microsecond and " 1122141cc406Sopenharmony_ci "constraint range set. Minimum is -42.17, maximum " 1123141cc406Sopenharmony_ci "32767.9999, and quant is 2.0."); 1124141cc406Sopenharmony_ci od->type = SANE_TYPE_FIXED; 1125141cc406Sopenharmony_ci od->unit = SANE_UNIT_MICROSECOND; 1126141cc406Sopenharmony_ci od->size = sizeof (SANE_Word); 1127141cc406Sopenharmony_ci od->cap = SANE_CAP_SOFT_DETECT | SANE_CAP_SOFT_SELECT | SANE_CAP_ADVANCED; 1128141cc406Sopenharmony_ci if (init_enable_test_options == SANE_FALSE) 1129141cc406Sopenharmony_ci od->cap |= SANE_CAP_INACTIVE; 1130141cc406Sopenharmony_ci od->constraint_type = SANE_CONSTRAINT_RANGE; 1131141cc406Sopenharmony_ci od->constraint.range = &fixed_constraint_range; 1132141cc406Sopenharmony_ci test_device->val[opt_fixed_constraint_range].w = SANE_FIX (41.83); 1133141cc406Sopenharmony_ci 1134141cc406Sopenharmony_ci /* opt_fixed_constraint_word_list */ 1135141cc406Sopenharmony_ci od = &test_device->opt[opt_fixed_constraint_word_list]; 1136141cc406Sopenharmony_ci od->name = "fixed-constraint-word-list"; 1137141cc406Sopenharmony_ci od->title = SANE_I18N ("(3/3) Fixed constraint word list"); 1138141cc406Sopenharmony_ci od->desc = SANE_I18N ("(3/3) Fixed test option with no unit and " 1139141cc406Sopenharmony_ci "constraint word list set."); 1140141cc406Sopenharmony_ci od->type = SANE_TYPE_FIXED; 1141141cc406Sopenharmony_ci od->unit = SANE_UNIT_NONE; 1142141cc406Sopenharmony_ci od->size = sizeof (SANE_Word); 1143141cc406Sopenharmony_ci od->cap = SANE_CAP_SOFT_DETECT | SANE_CAP_SOFT_SELECT | SANE_CAP_ADVANCED; 1144141cc406Sopenharmony_ci if (init_enable_test_options == SANE_FALSE) 1145141cc406Sopenharmony_ci od->cap |= SANE_CAP_INACTIVE; 1146141cc406Sopenharmony_ci od->constraint_type = SANE_CONSTRAINT_WORD_LIST; 1147141cc406Sopenharmony_ci od->constraint.word_list = fixed_constraint_word_list; 1148141cc406Sopenharmony_ci test_device->val[opt_fixed_constraint_word_list].w = SANE_FIX (42.0); 1149141cc406Sopenharmony_ci 1150141cc406Sopenharmony_ci /* opt_string_group */ 1151141cc406Sopenharmony_ci od = &test_device->opt[opt_string_group]; 1152141cc406Sopenharmony_ci od->name = ""; 1153141cc406Sopenharmony_ci od->title = SANE_I18N ("String test options"); 1154141cc406Sopenharmony_ci od->desc = ""; 1155141cc406Sopenharmony_ci od->type = SANE_TYPE_GROUP; 1156141cc406Sopenharmony_ci od->unit = SANE_UNIT_NONE; 1157141cc406Sopenharmony_ci od->size = 0; 1158141cc406Sopenharmony_ci od->cap = 0; 1159141cc406Sopenharmony_ci od->constraint_type = SANE_CONSTRAINT_NONE; 1160141cc406Sopenharmony_ci od->constraint.range = 0; 1161141cc406Sopenharmony_ci test_device->val[opt_string_group].w = 0; 1162141cc406Sopenharmony_ci 1163141cc406Sopenharmony_ci /* opt_string */ 1164141cc406Sopenharmony_ci od = &test_device->opt[opt_string]; 1165141cc406Sopenharmony_ci od->name = "string"; 1166141cc406Sopenharmony_ci od->title = SANE_I18N ("(1/3) String"); 1167141cc406Sopenharmony_ci od->desc = SANE_I18N ("(1/3) String test option without constraint."); 1168141cc406Sopenharmony_ci od->type = SANE_TYPE_STRING; 1169141cc406Sopenharmony_ci od->unit = SANE_UNIT_NONE; 1170141cc406Sopenharmony_ci od->size = (SANE_Int) strlen (init_string) + 1; 1171141cc406Sopenharmony_ci od->cap = SANE_CAP_SOFT_DETECT | SANE_CAP_SOFT_SELECT; 1172141cc406Sopenharmony_ci if (init_enable_test_options == SANE_FALSE) 1173141cc406Sopenharmony_ci od->cap |= SANE_CAP_INACTIVE; 1174141cc406Sopenharmony_ci od->constraint_type = SANE_CONSTRAINT_NONE; 1175141cc406Sopenharmony_ci od->constraint.string_list = 0; 1176141cc406Sopenharmony_ci test_device->val[opt_string].s = malloc ((size_t) od->size); 1177141cc406Sopenharmony_ci if (!test_device->val[opt_string].s) 1178141cc406Sopenharmony_ci goto fail; 1179141cc406Sopenharmony_ci strcpy (test_device->val[opt_string].s, init_string); 1180141cc406Sopenharmony_ci 1181141cc406Sopenharmony_ci /* opt_string_constraint_string_list */ 1182141cc406Sopenharmony_ci od = &test_device->opt[opt_string_constraint_string_list]; 1183141cc406Sopenharmony_ci od->name = "string-constraint-string-list"; 1184141cc406Sopenharmony_ci od->title = SANE_I18N ("(2/3) String constraint string list"); 1185141cc406Sopenharmony_ci od->desc = SANE_I18N ("(2/3) String test option with string list " 1186141cc406Sopenharmony_ci "constraint."); 1187141cc406Sopenharmony_ci od->type = SANE_TYPE_STRING; 1188141cc406Sopenharmony_ci od->unit = SANE_UNIT_NONE; 1189141cc406Sopenharmony_ci od->size = (SANE_Int) max_string_size (string_constraint_string_list); 1190141cc406Sopenharmony_ci od->cap = SANE_CAP_SOFT_DETECT | SANE_CAP_SOFT_SELECT; 1191141cc406Sopenharmony_ci if (init_enable_test_options == SANE_FALSE) 1192141cc406Sopenharmony_ci od->cap |= SANE_CAP_INACTIVE; 1193141cc406Sopenharmony_ci od->constraint_type = SANE_CONSTRAINT_STRING_LIST; 1194141cc406Sopenharmony_ci od->constraint.string_list = string_constraint_string_list; 1195141cc406Sopenharmony_ci test_device->val[opt_string_constraint_string_list].s = malloc ((size_t) od->size); 1196141cc406Sopenharmony_ci if (!test_device->val[opt_string_constraint_string_list].s) 1197141cc406Sopenharmony_ci goto fail; 1198141cc406Sopenharmony_ci strcpy (test_device->val[opt_string_constraint_string_list].s, 1199141cc406Sopenharmony_ci init_string_constraint_string_list); 1200141cc406Sopenharmony_ci 1201141cc406Sopenharmony_ci /* opt_string_constraint_long_string_list */ 1202141cc406Sopenharmony_ci od = &test_device->opt[opt_string_constraint_long_string_list]; 1203141cc406Sopenharmony_ci od->name = "string-constraint-long-string-list"; 1204141cc406Sopenharmony_ci od->title = SANE_I18N ("(3/3) String constraint long string list"); 1205141cc406Sopenharmony_ci od->desc = SANE_I18N ("(3/3) String test option with string list " 1206141cc406Sopenharmony_ci "constraint. Contains some more entries..."); 1207141cc406Sopenharmony_ci od->type = SANE_TYPE_STRING; 1208141cc406Sopenharmony_ci od->unit = SANE_UNIT_NONE; 1209141cc406Sopenharmony_ci od->size = (SANE_Int) max_string_size (string_constraint_long_string_list); 1210141cc406Sopenharmony_ci od->cap = SANE_CAP_SOFT_DETECT | SANE_CAP_SOFT_SELECT; 1211141cc406Sopenharmony_ci if (init_enable_test_options == SANE_FALSE) 1212141cc406Sopenharmony_ci od->cap |= SANE_CAP_INACTIVE; 1213141cc406Sopenharmony_ci od->constraint_type = SANE_CONSTRAINT_STRING_LIST; 1214141cc406Sopenharmony_ci od->constraint.string_list = string_constraint_long_string_list; 1215141cc406Sopenharmony_ci test_device->val[opt_string_constraint_long_string_list].s = 1216141cc406Sopenharmony_ci malloc ((size_t) od->size); 1217141cc406Sopenharmony_ci if (!test_device->val[opt_string_constraint_long_string_list].s) 1218141cc406Sopenharmony_ci goto fail; 1219141cc406Sopenharmony_ci strcpy (test_device->val[opt_string_constraint_long_string_list].s, 1220141cc406Sopenharmony_ci init_string_constraint_long_string_list); 1221141cc406Sopenharmony_ci 1222141cc406Sopenharmony_ci /* opt_button_group */ 1223141cc406Sopenharmony_ci od = &test_device->opt[opt_button_group]; 1224141cc406Sopenharmony_ci od->name = ""; 1225141cc406Sopenharmony_ci od->title = SANE_I18N ("Button test options"); 1226141cc406Sopenharmony_ci od->desc = ""; 1227141cc406Sopenharmony_ci od->type = SANE_TYPE_GROUP; 1228141cc406Sopenharmony_ci od->unit = SANE_UNIT_NONE; 1229141cc406Sopenharmony_ci od->size = 0; 1230141cc406Sopenharmony_ci od->cap = 0; 1231141cc406Sopenharmony_ci od->constraint_type = SANE_CONSTRAINT_NONE; 1232141cc406Sopenharmony_ci od->constraint.range = 0; 1233141cc406Sopenharmony_ci test_device->val[opt_button_group].w = 0; 1234141cc406Sopenharmony_ci 1235141cc406Sopenharmony_ci /* opt_button */ 1236141cc406Sopenharmony_ci od = &test_device->opt[opt_button]; 1237141cc406Sopenharmony_ci od->name = "button"; 1238141cc406Sopenharmony_ci od->title = SANE_I18N ("(1/1) Button"); 1239141cc406Sopenharmony_ci od->desc = SANE_I18N ("(1/1) Button test option. Prints some text..."); 1240141cc406Sopenharmony_ci od->type = SANE_TYPE_BUTTON; 1241141cc406Sopenharmony_ci od->unit = SANE_UNIT_NONE; 1242141cc406Sopenharmony_ci od->size = 0; 1243141cc406Sopenharmony_ci od->cap = SANE_CAP_SOFT_DETECT | SANE_CAP_SOFT_SELECT; 1244141cc406Sopenharmony_ci if (init_enable_test_options == SANE_FALSE) 1245141cc406Sopenharmony_ci od->cap |= SANE_CAP_INACTIVE; 1246141cc406Sopenharmony_ci od->constraint_type = SANE_CONSTRAINT_NONE; 1247141cc406Sopenharmony_ci od->constraint.string_list = 0; 1248141cc406Sopenharmony_ci test_device->val[opt_button].w = 0; 1249141cc406Sopenharmony_ci 1250141cc406Sopenharmony_ci return SANE_STATUS_GOOD; 1251141cc406Sopenharmony_ci 1252141cc406Sopenharmony_cifail: 1253141cc406Sopenharmony_ci cleanup_options (test_device); 1254141cc406Sopenharmony_ci return SANE_STATUS_NO_MEM; 1255141cc406Sopenharmony_ci} 1256141cc406Sopenharmony_ci 1257141cc406Sopenharmony_cistatic void 1258141cc406Sopenharmony_cicleanup_initial_string_values () 1259141cc406Sopenharmony_ci{ 1260141cc406Sopenharmony_ci // Cleanup backing memory for initial values of string options. 1261141cc406Sopenharmony_ci free (init_mode); 1262141cc406Sopenharmony_ci init_mode = NULL; 1263141cc406Sopenharmony_ci free (init_three_pass_order); 1264141cc406Sopenharmony_ci init_three_pass_order = NULL; 1265141cc406Sopenharmony_ci free (init_scan_source); 1266141cc406Sopenharmony_ci init_scan_source = NULL; 1267141cc406Sopenharmony_ci free (init_test_picture); 1268141cc406Sopenharmony_ci init_test_picture = NULL; 1269141cc406Sopenharmony_ci free (init_read_status_code); 1270141cc406Sopenharmony_ci init_read_status_code = NULL; 1271141cc406Sopenharmony_ci free (init_string); 1272141cc406Sopenharmony_ci init_string = NULL; 1273141cc406Sopenharmony_ci free (init_string_constraint_string_list); 1274141cc406Sopenharmony_ci init_string_constraint_string_list = NULL; 1275141cc406Sopenharmony_ci free (init_string_constraint_long_string_list); 1276141cc406Sopenharmony_ci init_string_constraint_long_string_list = NULL; 1277141cc406Sopenharmony_ci} 1278141cc406Sopenharmony_ci 1279141cc406Sopenharmony_cistatic void 1280141cc406Sopenharmony_cicleanup_test_device (Test_Device * test_device) 1281141cc406Sopenharmony_ci{ 1282141cc406Sopenharmony_ci DBG (2, "cleanup_test_device: test_device=%p\n", (void *) test_device); 1283141cc406Sopenharmony_ci if (test_device->options_initialized) 1284141cc406Sopenharmony_ci cleanup_options (test_device); 1285141cc406Sopenharmony_ci if (test_device->name) 1286141cc406Sopenharmony_ci free (test_device->name); 1287141cc406Sopenharmony_ci free (test_device); 1288141cc406Sopenharmony_ci} 1289141cc406Sopenharmony_ci 1290141cc406Sopenharmony_cistatic SANE_Status 1291141cc406Sopenharmony_ciread_option (SANE_String line, SANE_String option_string, 1292141cc406Sopenharmony_ci parameter_type p_type, void *value) 1293141cc406Sopenharmony_ci{ 1294141cc406Sopenharmony_ci SANE_String_Const cp; 1295141cc406Sopenharmony_ci SANE_Char *word, *end; 1296141cc406Sopenharmony_ci 1297141cc406Sopenharmony_ci word = 0; 1298141cc406Sopenharmony_ci 1299141cc406Sopenharmony_ci cp = sanei_config_get_string (line, &word); 1300141cc406Sopenharmony_ci 1301141cc406Sopenharmony_ci if (!word) 1302141cc406Sopenharmony_ci return SANE_STATUS_INVAL; 1303141cc406Sopenharmony_ci 1304141cc406Sopenharmony_ci if (strcmp (word, option_string) != 0) 1305141cc406Sopenharmony_ci { 1306141cc406Sopenharmony_ci free(word); 1307141cc406Sopenharmony_ci return SANE_STATUS_INVAL; 1308141cc406Sopenharmony_ci } 1309141cc406Sopenharmony_ci 1310141cc406Sopenharmony_ci free (word); 1311141cc406Sopenharmony_ci word = 0; 1312141cc406Sopenharmony_ci 1313141cc406Sopenharmony_ci switch (p_type) 1314141cc406Sopenharmony_ci { 1315141cc406Sopenharmony_ci case param_none: 1316141cc406Sopenharmony_ci return SANE_STATUS_GOOD; 1317141cc406Sopenharmony_ci case param_bool: 1318141cc406Sopenharmony_ci { 1319141cc406Sopenharmony_ci cp = sanei_config_get_string (cp, &word); 1320141cc406Sopenharmony_ci if (!word) 1321141cc406Sopenharmony_ci return SANE_STATUS_INVAL; 1322141cc406Sopenharmony_ci if (strlen (word) == 0) 1323141cc406Sopenharmony_ci { 1324141cc406Sopenharmony_ci DBG (3, "read_option: option `%s' requires parameter\n", 1325141cc406Sopenharmony_ci option_string); 1326141cc406Sopenharmony_ci return SANE_STATUS_INVAL; 1327141cc406Sopenharmony_ci } 1328141cc406Sopenharmony_ci if (strcmp (word, "true") != 0 && strcmp (word, "false") != 0) 1329141cc406Sopenharmony_ci { 1330141cc406Sopenharmony_ci DBG (3, "read_option: option `%s' requires parameter " 1331141cc406Sopenharmony_ci "`true' or `false'\n", option_string); 1332141cc406Sopenharmony_ci return SANE_STATUS_INVAL; 1333141cc406Sopenharmony_ci } 1334141cc406Sopenharmony_ci else if (strcmp (word, "true") == 0) 1335141cc406Sopenharmony_ci *(SANE_Bool *) value = SANE_TRUE; 1336141cc406Sopenharmony_ci else 1337141cc406Sopenharmony_ci *(SANE_Bool *) value = SANE_FALSE; 1338141cc406Sopenharmony_ci DBG (3, "read_option: set option `%s' to %s\n", option_string, 1339141cc406Sopenharmony_ci *(SANE_Bool *) value == SANE_TRUE ? "true" : "false"); 1340141cc406Sopenharmony_ci break; 1341141cc406Sopenharmony_ci } 1342141cc406Sopenharmony_ci case param_int: 1343141cc406Sopenharmony_ci { 1344141cc406Sopenharmony_ci SANE_Int int_value; 1345141cc406Sopenharmony_ci 1346141cc406Sopenharmony_ci cp = sanei_config_get_string (cp, &word); 1347141cc406Sopenharmony_ci if (!word) 1348141cc406Sopenharmony_ci return SANE_STATUS_INVAL; 1349141cc406Sopenharmony_ci errno = 0; 1350141cc406Sopenharmony_ci int_value = (SANE_Int) strtol (word, &end, 0); 1351141cc406Sopenharmony_ci if (end == word) 1352141cc406Sopenharmony_ci { 1353141cc406Sopenharmony_ci DBG (3, "read_option: option `%s' requires parameter\n", 1354141cc406Sopenharmony_ci option_string); 1355141cc406Sopenharmony_ci return SANE_STATUS_INVAL; 1356141cc406Sopenharmony_ci } 1357141cc406Sopenharmony_ci else if (errno) 1358141cc406Sopenharmony_ci { 1359141cc406Sopenharmony_ci DBG (3, "read_option: option `%s': can't parse parameter `%s' " 1360141cc406Sopenharmony_ci "(%s)\n", option_string, word, strerror (errno)); 1361141cc406Sopenharmony_ci return SANE_STATUS_INVAL; 1362141cc406Sopenharmony_ci } 1363141cc406Sopenharmony_ci else 1364141cc406Sopenharmony_ci { 1365141cc406Sopenharmony_ci DBG (3, "read_option: set option `%s' to %d\n", option_string, 1366141cc406Sopenharmony_ci int_value); 1367141cc406Sopenharmony_ci *(SANE_Int *) value = int_value; 1368141cc406Sopenharmony_ci } 1369141cc406Sopenharmony_ci break; 1370141cc406Sopenharmony_ci } 1371141cc406Sopenharmony_ci case param_fixed: 1372141cc406Sopenharmony_ci { 1373141cc406Sopenharmony_ci double double_value; 1374141cc406Sopenharmony_ci SANE_Fixed fixed_value; 1375141cc406Sopenharmony_ci 1376141cc406Sopenharmony_ci cp = sanei_config_get_string (cp, &word); 1377141cc406Sopenharmony_ci if (!word) 1378141cc406Sopenharmony_ci return SANE_STATUS_INVAL; 1379141cc406Sopenharmony_ci errno = 0; 1380141cc406Sopenharmony_ci double_value = strtod (word, &end); 1381141cc406Sopenharmony_ci if (end == word) 1382141cc406Sopenharmony_ci { 1383141cc406Sopenharmony_ci DBG (3, "read_option: option `%s' requires parameter\n", 1384141cc406Sopenharmony_ci option_string); 1385141cc406Sopenharmony_ci return SANE_STATUS_INVAL; 1386141cc406Sopenharmony_ci } 1387141cc406Sopenharmony_ci else if (errno) 1388141cc406Sopenharmony_ci { 1389141cc406Sopenharmony_ci DBG (3, "read_option: option `%s': can't parse parameter `%s' " 1390141cc406Sopenharmony_ci "(%s)\n", option_string, word, strerror (errno)); 1391141cc406Sopenharmony_ci return SANE_STATUS_INVAL; 1392141cc406Sopenharmony_ci } 1393141cc406Sopenharmony_ci else 1394141cc406Sopenharmony_ci { 1395141cc406Sopenharmony_ci DBG (3, "read_option: set option `%s' to %.0f\n", option_string, 1396141cc406Sopenharmony_ci double_value); 1397141cc406Sopenharmony_ci fixed_value = SANE_FIX (double_value); 1398141cc406Sopenharmony_ci *(SANE_Fixed *) value = fixed_value; 1399141cc406Sopenharmony_ci } 1400141cc406Sopenharmony_ci break; 1401141cc406Sopenharmony_ci } 1402141cc406Sopenharmony_ci case param_string: 1403141cc406Sopenharmony_ci { 1404141cc406Sopenharmony_ci cp = sanei_config_get_string (cp, &word); 1405141cc406Sopenharmony_ci if (!word) 1406141cc406Sopenharmony_ci return SANE_STATUS_INVAL; 1407141cc406Sopenharmony_ci if (strlen (word) == 0) 1408141cc406Sopenharmony_ci { 1409141cc406Sopenharmony_ci DBG (3, "read_option: option `%s' requires parameter\n", 1410141cc406Sopenharmony_ci option_string); 1411141cc406Sopenharmony_ci return SANE_STATUS_INVAL; 1412141cc406Sopenharmony_ci } 1413141cc406Sopenharmony_ci else 1414141cc406Sopenharmony_ci { 1415141cc406Sopenharmony_ci DBG (3, "read_option: set option `%s' to `%s'\n", option_string, 1416141cc406Sopenharmony_ci word); 1417141cc406Sopenharmony_ci if (*(SANE_String *) value) 1418141cc406Sopenharmony_ci free (*(SANE_String *) value); 1419141cc406Sopenharmony_ci *(SANE_String *) value = strdup (word); 1420141cc406Sopenharmony_ci if (!*(SANE_String *) value) 1421141cc406Sopenharmony_ci return SANE_STATUS_NO_MEM; 1422141cc406Sopenharmony_ci } 1423141cc406Sopenharmony_ci break; 1424141cc406Sopenharmony_ci } 1425141cc406Sopenharmony_ci default: 1426141cc406Sopenharmony_ci DBG (1, "read_option: unknown param_type %d\n", p_type); 1427141cc406Sopenharmony_ci return SANE_STATUS_INVAL; 1428141cc406Sopenharmony_ci } /* switch */ 1429141cc406Sopenharmony_ci 1430141cc406Sopenharmony_ci if (word) 1431141cc406Sopenharmony_ci free (word); 1432141cc406Sopenharmony_ci return SANE_STATUS_GOOD; 1433141cc406Sopenharmony_ci} 1434141cc406Sopenharmony_ci 1435141cc406Sopenharmony_cistatic SANE_Status 1436141cc406Sopenharmony_cireader_process (Test_Device * test_device, SANE_Int fd) 1437141cc406Sopenharmony_ci{ 1438141cc406Sopenharmony_ci SANE_Status status; 1439141cc406Sopenharmony_ci size_t byte_count = 0; 1440141cc406Sopenharmony_ci size_t bytes_total; 1441141cc406Sopenharmony_ci SANE_Byte *buffer = 0; 1442141cc406Sopenharmony_ci ssize_t bytes_written = 0; 1443141cc406Sopenharmony_ci size_t buffer_size = 0, write_count = 0; 1444141cc406Sopenharmony_ci 1445141cc406Sopenharmony_ci DBG (2, "(child) reader_process: test_device=%p, fd=%d\n", 1446141cc406Sopenharmony_ci (void *) test_device, fd); 1447141cc406Sopenharmony_ci 1448141cc406Sopenharmony_ci bytes_total = (size_t) test_device->lines * (size_t) test_device->bytes_per_line; 1449141cc406Sopenharmony_ci status = init_picture_buffer (test_device, &buffer, &buffer_size); 1450141cc406Sopenharmony_ci if (status != SANE_STATUS_GOOD) 1451141cc406Sopenharmony_ci return status; 1452141cc406Sopenharmony_ci 1453141cc406Sopenharmony_ci DBG (2, "(child) reader_process: buffer=%p, buffersize=%lu\n", 1454141cc406Sopenharmony_ci (void *) buffer, (u_long) buffer_size); 1455141cc406Sopenharmony_ci 1456141cc406Sopenharmony_ci while (byte_count < bytes_total) 1457141cc406Sopenharmony_ci { 1458141cc406Sopenharmony_ci if (write_count == 0) 1459141cc406Sopenharmony_ci { 1460141cc406Sopenharmony_ci write_count = buffer_size; 1461141cc406Sopenharmony_ci if (byte_count + (size_t) write_count > bytes_total) 1462141cc406Sopenharmony_ci write_count = (size_t) bytes_total - (size_t) byte_count; 1463141cc406Sopenharmony_ci 1464141cc406Sopenharmony_ci if (test_device->val[opt_read_delay].w == SANE_TRUE) 1465141cc406Sopenharmony_ci usleep ((useconds_t) test_device->val[opt_read_delay_duration].w); 1466141cc406Sopenharmony_ci } 1467141cc406Sopenharmony_ci bytes_written = write (fd, buffer, write_count); 1468141cc406Sopenharmony_ci if (bytes_written < 0) 1469141cc406Sopenharmony_ci { 1470141cc406Sopenharmony_ci DBG (1, "(child) reader_process: write returned %s\n", 1471141cc406Sopenharmony_ci strerror (errno)); 1472141cc406Sopenharmony_ci return SANE_STATUS_IO_ERROR; 1473141cc406Sopenharmony_ci } 1474141cc406Sopenharmony_ci byte_count += (size_t) bytes_written; 1475141cc406Sopenharmony_ci DBG (4, "(child) reader_process: wrote %ld bytes of %lu (%zu total)\n", 1476141cc406Sopenharmony_ci bytes_written, write_count, byte_count); 1477141cc406Sopenharmony_ci write_count -= (size_t) bytes_written; 1478141cc406Sopenharmony_ci } 1479141cc406Sopenharmony_ci 1480141cc406Sopenharmony_ci free (buffer); 1481141cc406Sopenharmony_ci 1482141cc406Sopenharmony_ci if (sanei_thread_is_forked ()) 1483141cc406Sopenharmony_ci { 1484141cc406Sopenharmony_ci DBG (4, "(child) reader_process: finished, wrote %zu bytes, expected %zu " 1485141cc406Sopenharmony_ci "bytes, now waiting\n", byte_count, bytes_total); 1486141cc406Sopenharmony_ci while (SANE_TRUE) 1487141cc406Sopenharmony_ci sleep (10); 1488141cc406Sopenharmony_ci DBG (4, "(child) reader_process: this should have never happened..."); 1489141cc406Sopenharmony_ci close (fd); 1490141cc406Sopenharmony_ci } 1491141cc406Sopenharmony_ci else 1492141cc406Sopenharmony_ci { 1493141cc406Sopenharmony_ci DBG (4, "(child) reader_process: finished, wrote %zu bytes, expected %zu " 1494141cc406Sopenharmony_ci "bytes\n", byte_count, bytes_total); 1495141cc406Sopenharmony_ci } 1496141cc406Sopenharmony_ci return SANE_STATUS_GOOD; 1497141cc406Sopenharmony_ci} 1498141cc406Sopenharmony_ci 1499141cc406Sopenharmony_ci/* 1500141cc406Sopenharmony_ci * this code either runs in child or thread context... 1501141cc406Sopenharmony_ci */ 1502141cc406Sopenharmony_cistatic int 1503141cc406Sopenharmony_cireader_task (void *data) 1504141cc406Sopenharmony_ci{ 1505141cc406Sopenharmony_ci SANE_Status status; 1506141cc406Sopenharmony_ci struct SIGACTION act; 1507141cc406Sopenharmony_ci struct Test_Device *test_device = (struct Test_Device *) data; 1508141cc406Sopenharmony_ci 1509141cc406Sopenharmony_ci DBG (2, "reader_task started\n"); 1510141cc406Sopenharmony_ci if (sanei_thread_is_forked ()) 1511141cc406Sopenharmony_ci { 1512141cc406Sopenharmony_ci DBG (3, "reader_task started (forked)\n"); 1513141cc406Sopenharmony_ci close (test_device->pipe); 1514141cc406Sopenharmony_ci test_device->pipe = -1; 1515141cc406Sopenharmony_ci 1516141cc406Sopenharmony_ci } 1517141cc406Sopenharmony_ci else 1518141cc406Sopenharmony_ci { 1519141cc406Sopenharmony_ci DBG (3, "reader_task started (as thread)\n"); 1520141cc406Sopenharmony_ci } 1521141cc406Sopenharmony_ci 1522141cc406Sopenharmony_ci memset (&act, 0, sizeof (act)); 1523141cc406Sopenharmony_ci sigaction (SIGTERM, &act, 0); 1524141cc406Sopenharmony_ci 1525141cc406Sopenharmony_ci status = reader_process (test_device, test_device->reader_fds); 1526141cc406Sopenharmony_ci DBG (2, "(child) reader_task: reader_process finished (%s)\n", 1527141cc406Sopenharmony_ci sane_strstatus (status)); 1528141cc406Sopenharmony_ci return (int) status; 1529141cc406Sopenharmony_ci} 1530141cc406Sopenharmony_ci 1531141cc406Sopenharmony_cistatic SANE_Status 1532141cc406Sopenharmony_cifinish_pass (Test_Device * test_device) 1533141cc406Sopenharmony_ci{ 1534141cc406Sopenharmony_ci SANE_Status return_status = SANE_STATUS_GOOD; 1535141cc406Sopenharmony_ci 1536141cc406Sopenharmony_ci DBG (2, "finish_pass: test_device=%p\n", (void *) test_device); 1537141cc406Sopenharmony_ci test_device->scanning = SANE_FALSE; 1538141cc406Sopenharmony_ci if (test_device->pipe >= 0) 1539141cc406Sopenharmony_ci { 1540141cc406Sopenharmony_ci DBG (2, "finish_pass: closing pipe\n"); 1541141cc406Sopenharmony_ci close (test_device->pipe); 1542141cc406Sopenharmony_ci DBG (2, "finish_pass: pipe closed\n"); 1543141cc406Sopenharmony_ci test_device->pipe = -1; 1544141cc406Sopenharmony_ci } 1545141cc406Sopenharmony_ci if (sanei_thread_is_valid (test_device->reader_pid)) 1546141cc406Sopenharmony_ci { 1547141cc406Sopenharmony_ci int status; 1548141cc406Sopenharmony_ci SANE_Pid pid; 1549141cc406Sopenharmony_ci 1550141cc406Sopenharmony_ci DBG (2, "finish_pass: terminating reader process %ld\n", 1551141cc406Sopenharmony_ci (long) test_device->reader_pid); 1552141cc406Sopenharmony_ci sanei_thread_kill (test_device->reader_pid); 1553141cc406Sopenharmony_ci pid = sanei_thread_waitpid (test_device->reader_pid, &status); 1554141cc406Sopenharmony_ci if (!sanei_thread_is_valid (pid)) 1555141cc406Sopenharmony_ci { 1556141cc406Sopenharmony_ci DBG (1, 1557141cc406Sopenharmony_ci "finish_pass: sanei_thread_waitpid failed, already terminated? (%s)\n", 1558141cc406Sopenharmony_ci strerror (errno)); 1559141cc406Sopenharmony_ci } 1560141cc406Sopenharmony_ci else 1561141cc406Sopenharmony_ci { 1562141cc406Sopenharmony_ci DBG (2, "finish_pass: reader process terminated with status: %s\n", 1563141cc406Sopenharmony_ci sane_strstatus (status)); 1564141cc406Sopenharmony_ci } 1565141cc406Sopenharmony_ci sanei_thread_invalidate (test_device->reader_pid); 1566141cc406Sopenharmony_ci } 1567141cc406Sopenharmony_ci /* this happens when running in thread context... */ 1568141cc406Sopenharmony_ci if (test_device->reader_fds >= 0) 1569141cc406Sopenharmony_ci { 1570141cc406Sopenharmony_ci DBG (2, "finish_pass: closing reader pipe\n"); 1571141cc406Sopenharmony_ci close (test_device->reader_fds); 1572141cc406Sopenharmony_ci DBG (2, "finish_pass: reader pipe closed\n"); 1573141cc406Sopenharmony_ci test_device->reader_fds = -1; 1574141cc406Sopenharmony_ci } 1575141cc406Sopenharmony_ci return return_status; 1576141cc406Sopenharmony_ci} 1577141cc406Sopenharmony_ci 1578141cc406Sopenharmony_cistatic void 1579141cc406Sopenharmony_ciprint_options (Test_Device * test_device) 1580141cc406Sopenharmony_ci{ 1581141cc406Sopenharmony_ci SANE_Option_Descriptor *od; 1582141cc406Sopenharmony_ci SANE_Word option_number; 1583141cc406Sopenharmony_ci SANE_Char caps[1024]; 1584141cc406Sopenharmony_ci 1585141cc406Sopenharmony_ci for (option_number = 0; option_number < num_options; option_number++) 1586141cc406Sopenharmony_ci { 1587141cc406Sopenharmony_ci od = &test_device->opt[option_number]; 1588141cc406Sopenharmony_ci DBG (0, "-----> number: %d\n", option_number); 1589141cc406Sopenharmony_ci DBG (0, " name: `%s'\n", od->name); 1590141cc406Sopenharmony_ci DBG (0, " title: `%s'\n", od->title); 1591141cc406Sopenharmony_ci DBG (0, " description: `%s'\n", od->desc); 1592141cc406Sopenharmony_ci DBG (0, " type: %s\n", 1593141cc406Sopenharmony_ci od->type == SANE_TYPE_BOOL ? "SANE_TYPE_BOOL" : 1594141cc406Sopenharmony_ci od->type == SANE_TYPE_INT ? "SANE_TYPE_INT" : 1595141cc406Sopenharmony_ci od->type == SANE_TYPE_FIXED ? "SANE_TYPE_FIXED" : 1596141cc406Sopenharmony_ci od->type == SANE_TYPE_STRING ? "SANE_TYPE_STRING" : 1597141cc406Sopenharmony_ci od->type == SANE_TYPE_BUTTON ? "SANE_TYPE_BUTTON" : 1598141cc406Sopenharmony_ci od->type == SANE_TYPE_GROUP ? "SANE_TYPE_GROUP" : "unknown"); 1599141cc406Sopenharmony_ci DBG (0, " unit: %s\n", 1600141cc406Sopenharmony_ci od->unit == SANE_UNIT_NONE ? "SANE_UNIT_NONE" : 1601141cc406Sopenharmony_ci od->unit == SANE_UNIT_PIXEL ? "SANE_UNIT_PIXEL" : 1602141cc406Sopenharmony_ci od->unit == SANE_UNIT_BIT ? "SANE_UNIT_BIT" : 1603141cc406Sopenharmony_ci od->unit == SANE_UNIT_MM ? "SANE_UNIT_MM" : 1604141cc406Sopenharmony_ci od->unit == SANE_UNIT_DPI ? "SANE_UNIT_DPI" : 1605141cc406Sopenharmony_ci od->unit == SANE_UNIT_PERCENT ? "SANE_UNIT_PERCENT" : 1606141cc406Sopenharmony_ci od->unit == SANE_UNIT_MICROSECOND ? "SANE_UNIT_MICROSECOND" : 1607141cc406Sopenharmony_ci "unknown"); 1608141cc406Sopenharmony_ci DBG (0, " size: %d\n", od->size); 1609141cc406Sopenharmony_ci caps[0] = '\0'; 1610141cc406Sopenharmony_ci if (od->cap & SANE_CAP_SOFT_SELECT) 1611141cc406Sopenharmony_ci strcat (caps, "SANE_CAP_SOFT_SELECT "); 1612141cc406Sopenharmony_ci if (od->cap & SANE_CAP_HARD_SELECT) 1613141cc406Sopenharmony_ci strcat (caps, "SANE_CAP_HARD_SELECT "); 1614141cc406Sopenharmony_ci if (od->cap & SANE_CAP_SOFT_DETECT) 1615141cc406Sopenharmony_ci strcat (caps, "SANE_CAP_SOFT_DETECT "); 1616141cc406Sopenharmony_ci if (od->cap & SANE_CAP_EMULATED) 1617141cc406Sopenharmony_ci strcat (caps, "SANE_CAP_EMULATED "); 1618141cc406Sopenharmony_ci if (od->cap & SANE_CAP_AUTOMATIC) 1619141cc406Sopenharmony_ci strcat (caps, "SANE_CAP_AUTOMATIC "); 1620141cc406Sopenharmony_ci if (od->cap & SANE_CAP_INACTIVE) 1621141cc406Sopenharmony_ci strcat (caps, "SANE_CAP_INACTIVE "); 1622141cc406Sopenharmony_ci if (od->cap & SANE_CAP_ADVANCED) 1623141cc406Sopenharmony_ci strcat (caps, "SANE_CAP_ADVANCED "); 1624141cc406Sopenharmony_ci DBG (0, " capabilities: %s\n", caps); 1625141cc406Sopenharmony_ci DBG (0, "constraint type: %s\n", 1626141cc406Sopenharmony_ci od->constraint_type == SANE_CONSTRAINT_NONE ? 1627141cc406Sopenharmony_ci "SANE_CONSTRAINT_NONE" : 1628141cc406Sopenharmony_ci od->constraint_type == SANE_CONSTRAINT_RANGE ? 1629141cc406Sopenharmony_ci "SANE_CONSTRAINT_RANGE" : 1630141cc406Sopenharmony_ci od->constraint_type == SANE_CONSTRAINT_WORD_LIST ? 1631141cc406Sopenharmony_ci "SANE_CONSTRAINT_WORD_LIST" : 1632141cc406Sopenharmony_ci od->constraint_type == SANE_CONSTRAINT_STRING_LIST ? 1633141cc406Sopenharmony_ci "SANE_CONSTRAINT_STRING_LIST" : "unknown"); 1634141cc406Sopenharmony_ci } 1635141cc406Sopenharmony_ci} 1636141cc406Sopenharmony_ci 1637141cc406Sopenharmony_ci/***************************** SANE API ****************************/ 1638141cc406Sopenharmony_ci 1639141cc406Sopenharmony_ci 1640141cc406Sopenharmony_ciSANE_Status 1641141cc406Sopenharmony_cisane_init (SANE_Int * __sane_unused__ version_code, SANE_Auth_Callback __sane_unused__ authorize) 1642141cc406Sopenharmony_ci{ 1643141cc406Sopenharmony_ci FILE *fp; 1644141cc406Sopenharmony_ci SANE_Int linenumber; 1645141cc406Sopenharmony_ci SANE_Char line[PATH_MAX], *word = NULL; 1646141cc406Sopenharmony_ci SANE_String_Const cp; 1647141cc406Sopenharmony_ci SANE_Device *sane_device; 1648141cc406Sopenharmony_ci Test_Device *test_device, *previous_device; 1649141cc406Sopenharmony_ci SANE_Int num; 1650141cc406Sopenharmony_ci 1651141cc406Sopenharmony_ci DBG_INIT (); 1652141cc406Sopenharmony_ci sanei_thread_init (); 1653141cc406Sopenharmony_ci 1654141cc406Sopenharmony_ci test_device = 0; 1655141cc406Sopenharmony_ci previous_device = 0; 1656141cc406Sopenharmony_ci 1657141cc406Sopenharmony_ci DBG (1, "sane_init: SANE test backend version %d.%d.%d from %s\n", SANE_CURRENT_MAJOR, 1658141cc406Sopenharmony_ci SANE_CURRENT_MINOR, BUILD, PACKAGE_STRING); 1659141cc406Sopenharmony_ci 1660141cc406Sopenharmony_ci if (version_code) 1661141cc406Sopenharmony_ci *version_code = SANE_VERSION_CODE (SANE_CURRENT_MAJOR, SANE_CURRENT_MINOR, BUILD); 1662141cc406Sopenharmony_ci 1663141cc406Sopenharmony_ci if (inited) 1664141cc406Sopenharmony_ci DBG (3, "sane_init: warning: already inited\n"); 1665141cc406Sopenharmony_ci 1666141cc406Sopenharmony_ci // Setup initial values of string options. Call free initially in case we've 1667141cc406Sopenharmony_ci // already called sane_init and these values are already non-null. 1668141cc406Sopenharmony_ci free (init_mode); 1669141cc406Sopenharmony_ci init_mode = strdup (SANE_VALUE_SCAN_MODE_GRAY); 1670141cc406Sopenharmony_ci if (!init_mode) 1671141cc406Sopenharmony_ci goto fail; 1672141cc406Sopenharmony_ci 1673141cc406Sopenharmony_ci free (init_three_pass_order); 1674141cc406Sopenharmony_ci init_three_pass_order = strdup ("RGB"); 1675141cc406Sopenharmony_ci if (!init_three_pass_order) 1676141cc406Sopenharmony_ci goto fail; 1677141cc406Sopenharmony_ci 1678141cc406Sopenharmony_ci free (init_scan_source); 1679141cc406Sopenharmony_ci init_scan_source = strdup ("Flatbed"); 1680141cc406Sopenharmony_ci if (!init_scan_source) 1681141cc406Sopenharmony_ci goto fail; 1682141cc406Sopenharmony_ci 1683141cc406Sopenharmony_ci free (init_test_picture); 1684141cc406Sopenharmony_ci init_test_picture = strdup ("Solid black"); 1685141cc406Sopenharmony_ci if (!init_test_picture) 1686141cc406Sopenharmony_ci goto fail; 1687141cc406Sopenharmony_ci 1688141cc406Sopenharmony_ci free (init_read_status_code); 1689141cc406Sopenharmony_ci init_read_status_code = strdup ("Default"); 1690141cc406Sopenharmony_ci if (!init_read_status_code) 1691141cc406Sopenharmony_ci goto fail; 1692141cc406Sopenharmony_ci 1693141cc406Sopenharmony_ci free (init_string); 1694141cc406Sopenharmony_ci init_string = strdup ("This is the contents of the string option. " 1695141cc406Sopenharmony_ci "Fill some more words to see how the frontend behaves."); 1696141cc406Sopenharmony_ci if (!init_string) 1697141cc406Sopenharmony_ci goto fail; 1698141cc406Sopenharmony_ci 1699141cc406Sopenharmony_ci free (init_string_constraint_string_list); 1700141cc406Sopenharmony_ci init_string_constraint_string_list = strdup ("First entry"); 1701141cc406Sopenharmony_ci if (!init_string_constraint_string_list) 1702141cc406Sopenharmony_ci goto fail; 1703141cc406Sopenharmony_ci 1704141cc406Sopenharmony_ci free (init_string_constraint_long_string_list); 1705141cc406Sopenharmony_ci init_string_constraint_long_string_list = strdup ("First entry"); 1706141cc406Sopenharmony_ci if (!init_string_constraint_long_string_list) 1707141cc406Sopenharmony_ci goto fail; 1708141cc406Sopenharmony_ci 1709141cc406Sopenharmony_ci fp = sanei_config_open (TEST_CONFIG_FILE); 1710141cc406Sopenharmony_ci if (fp) 1711141cc406Sopenharmony_ci { 1712141cc406Sopenharmony_ci linenumber = 0; 1713141cc406Sopenharmony_ci DBG (4, "sane_init: reading config file `%s'\n", TEST_CONFIG_FILE); 1714141cc406Sopenharmony_ci while (sanei_config_read (line, sizeof (line), fp)) 1715141cc406Sopenharmony_ci { 1716141cc406Sopenharmony_ci if (word) 1717141cc406Sopenharmony_ci free (word); 1718141cc406Sopenharmony_ci word = NULL; 1719141cc406Sopenharmony_ci linenumber++; 1720141cc406Sopenharmony_ci 1721141cc406Sopenharmony_ci cp = sanei_config_get_string (line, &word); 1722141cc406Sopenharmony_ci if (!word || cp == line) 1723141cc406Sopenharmony_ci { 1724141cc406Sopenharmony_ci DBG (5, 1725141cc406Sopenharmony_ci "sane_init: config file line %3d: ignoring empty line\n", 1726141cc406Sopenharmony_ci linenumber); 1727141cc406Sopenharmony_ci continue; 1728141cc406Sopenharmony_ci } 1729141cc406Sopenharmony_ci if (word[0] == '#') 1730141cc406Sopenharmony_ci { 1731141cc406Sopenharmony_ci DBG (5, 1732141cc406Sopenharmony_ci "sane_init: config file line %3d: ignoring comment line\n", 1733141cc406Sopenharmony_ci linenumber); 1734141cc406Sopenharmony_ci continue; 1735141cc406Sopenharmony_ci } 1736141cc406Sopenharmony_ci 1737141cc406Sopenharmony_ci DBG (5, "sane_init: config file line %3d: `%s'\n", 1738141cc406Sopenharmony_ci linenumber, line); 1739141cc406Sopenharmony_ci if (read_option (line, "number_of_devices", param_int, 1740141cc406Sopenharmony_ci &init_number_of_devices) == SANE_STATUS_GOOD) 1741141cc406Sopenharmony_ci continue; 1742141cc406Sopenharmony_ci if (read_option (line, "mode", param_string, 1743141cc406Sopenharmony_ci &init_mode) == SANE_STATUS_GOOD) 1744141cc406Sopenharmony_ci continue; 1745141cc406Sopenharmony_ci if (read_option (line, "hand-scanner", param_bool, 1746141cc406Sopenharmony_ci &init_hand_scanner) == SANE_STATUS_GOOD) 1747141cc406Sopenharmony_ci continue; 1748141cc406Sopenharmony_ci if (read_option (line, "three-pass", param_bool, 1749141cc406Sopenharmony_ci &init_three_pass) == SANE_STATUS_GOOD) 1750141cc406Sopenharmony_ci continue; 1751141cc406Sopenharmony_ci if (read_option (line, "three-pass-order", param_string, 1752141cc406Sopenharmony_ci &init_three_pass_order) == SANE_STATUS_GOOD) 1753141cc406Sopenharmony_ci continue; 1754141cc406Sopenharmony_ci if (read_option (line, "resolution_min", param_fixed, 1755141cc406Sopenharmony_ci &resolution_range.min) == SANE_STATUS_GOOD) 1756141cc406Sopenharmony_ci continue; 1757141cc406Sopenharmony_ci if (read_option (line, "resolution_max", param_fixed, 1758141cc406Sopenharmony_ci &resolution_range.max) == SANE_STATUS_GOOD) 1759141cc406Sopenharmony_ci continue; 1760141cc406Sopenharmony_ci if (read_option (line, "resolution_quant", param_fixed, 1761141cc406Sopenharmony_ci &resolution_range.quant) == SANE_STATUS_GOOD) 1762141cc406Sopenharmony_ci continue; 1763141cc406Sopenharmony_ci if (read_option (line, "resolution", param_fixed, 1764141cc406Sopenharmony_ci &init_resolution) == SANE_STATUS_GOOD) 1765141cc406Sopenharmony_ci continue; 1766141cc406Sopenharmony_ci if (read_option (line, "depth", param_int, 1767141cc406Sopenharmony_ci &init_depth) == SANE_STATUS_GOOD) 1768141cc406Sopenharmony_ci continue; 1769141cc406Sopenharmony_ci if (read_option (line, "scan-source", param_string, 1770141cc406Sopenharmony_ci &init_scan_source) == SANE_STATUS_GOOD) 1771141cc406Sopenharmony_ci continue; 1772141cc406Sopenharmony_ci if (read_option (line, "test-picture", param_string, 1773141cc406Sopenharmony_ci &init_test_picture) == SANE_STATUS_GOOD) 1774141cc406Sopenharmony_ci continue; 1775141cc406Sopenharmony_ci if (read_option (line, "invert-endianess", param_bool, 1776141cc406Sopenharmony_ci &init_invert_endianess) == SANE_STATUS_GOOD) 1777141cc406Sopenharmony_ci continue; 1778141cc406Sopenharmony_ci if (read_option (line, "read-limit", param_bool, 1779141cc406Sopenharmony_ci &init_read_limit) == SANE_STATUS_GOOD) 1780141cc406Sopenharmony_ci continue; 1781141cc406Sopenharmony_ci if (read_option (line, "read-limit-size", param_int, 1782141cc406Sopenharmony_ci &init_read_limit_size) == SANE_STATUS_GOOD) 1783141cc406Sopenharmony_ci continue; 1784141cc406Sopenharmony_ci if (read_option (line, "read-delay", param_bool, 1785141cc406Sopenharmony_ci &init_read_delay) == SANE_STATUS_GOOD) 1786141cc406Sopenharmony_ci continue; 1787141cc406Sopenharmony_ci if (read_option (line, "read-delay-duration", param_int, 1788141cc406Sopenharmony_ci &init_read_delay_duration) == SANE_STATUS_GOOD) 1789141cc406Sopenharmony_ci continue; 1790141cc406Sopenharmony_ci if (read_option (line, "read-status-code", param_string, 1791141cc406Sopenharmony_ci &init_read_status_code) == SANE_STATUS_GOOD) 1792141cc406Sopenharmony_ci continue; 1793141cc406Sopenharmony_ci if (read_option (line, "ppl-loss", param_int, 1794141cc406Sopenharmony_ci &init_ppl_loss) == SANE_STATUS_GOOD) 1795141cc406Sopenharmony_ci continue; 1796141cc406Sopenharmony_ci if (read_option (line, "fuzzy-parameters", param_bool, 1797141cc406Sopenharmony_ci &init_fuzzy_parameters) == SANE_STATUS_GOOD) 1798141cc406Sopenharmony_ci continue; 1799141cc406Sopenharmony_ci if (read_option (line, "non-blocking", param_bool, 1800141cc406Sopenharmony_ci &init_non_blocking) == SANE_STATUS_GOOD) 1801141cc406Sopenharmony_ci continue; 1802141cc406Sopenharmony_ci if (read_option (line, "select-fd", param_bool, 1803141cc406Sopenharmony_ci &init_select_fd) == SANE_STATUS_GOOD) 1804141cc406Sopenharmony_ci continue; 1805141cc406Sopenharmony_ci if (read_option (line, "enable-test-options", param_bool, 1806141cc406Sopenharmony_ci &init_enable_test_options) == SANE_STATUS_GOOD) 1807141cc406Sopenharmony_ci continue; 1808141cc406Sopenharmony_ci if (read_option (line, "geometry_min", param_fixed, 1809141cc406Sopenharmony_ci &geometry_range.min) == SANE_STATUS_GOOD) 1810141cc406Sopenharmony_ci continue; 1811141cc406Sopenharmony_ci if (read_option (line, "geometry_max", param_fixed, 1812141cc406Sopenharmony_ci &geometry_range.max) == SANE_STATUS_GOOD) 1813141cc406Sopenharmony_ci continue; 1814141cc406Sopenharmony_ci if (read_option (line, "geometry_quant", param_fixed, 1815141cc406Sopenharmony_ci &geometry_range.quant) == SANE_STATUS_GOOD) 1816141cc406Sopenharmony_ci continue; 1817141cc406Sopenharmony_ci if (read_option (line, "tl_x", param_fixed, 1818141cc406Sopenharmony_ci &init_tl_x) == SANE_STATUS_GOOD) 1819141cc406Sopenharmony_ci continue; 1820141cc406Sopenharmony_ci if (read_option (line, "tl_y", param_fixed, 1821141cc406Sopenharmony_ci &init_tl_y) == SANE_STATUS_GOOD) 1822141cc406Sopenharmony_ci continue; 1823141cc406Sopenharmony_ci if (read_option (line, "br_x", param_fixed, 1824141cc406Sopenharmony_ci &init_br_x) == SANE_STATUS_GOOD) 1825141cc406Sopenharmony_ci continue; 1826141cc406Sopenharmony_ci if (read_option (line, "br_y", param_fixed, 1827141cc406Sopenharmony_ci &init_br_y) == SANE_STATUS_GOOD) 1828141cc406Sopenharmony_ci continue; 1829141cc406Sopenharmony_ci 1830141cc406Sopenharmony_ci DBG (3, "sane-init: I don't know how to handle option `%s'\n", 1831141cc406Sopenharmony_ci word); 1832141cc406Sopenharmony_ci } /* while */ 1833141cc406Sopenharmony_ci if (word) 1834141cc406Sopenharmony_ci free (word); 1835141cc406Sopenharmony_ci fclose (fp); 1836141cc406Sopenharmony_ci } /* if */ 1837141cc406Sopenharmony_ci else 1838141cc406Sopenharmony_ci { 1839141cc406Sopenharmony_ci DBG (3, "sane_init: couldn't find config file (%s), using default " 1840141cc406Sopenharmony_ci "settings\n", TEST_CONFIG_FILE); 1841141cc406Sopenharmony_ci } 1842141cc406Sopenharmony_ci 1843141cc406Sopenharmony_ci /* create devices */ 1844141cc406Sopenharmony_ci sane_device_list = 1845141cc406Sopenharmony_ci malloc ((size_t) (init_number_of_devices + 1) * sizeof (sane_device)); 1846141cc406Sopenharmony_ci if (!sane_device_list) 1847141cc406Sopenharmony_ci goto fail; 1848141cc406Sopenharmony_ci for (num = 0; num < init_number_of_devices; num++) 1849141cc406Sopenharmony_ci { 1850141cc406Sopenharmony_ci SANE_Char number_string[PATH_MAX]; 1851141cc406Sopenharmony_ci 1852141cc406Sopenharmony_ci test_device = calloc (sizeof (*test_device), 1); 1853141cc406Sopenharmony_ci if (!test_device) 1854141cc406Sopenharmony_ci goto fail_device; 1855141cc406Sopenharmony_ci test_device->sane.vendor = "Noname"; 1856141cc406Sopenharmony_ci test_device->sane.type = "virtual device"; 1857141cc406Sopenharmony_ci test_device->sane.model = "frontend-tester"; 1858141cc406Sopenharmony_ci snprintf (number_string, sizeof (number_string), "%d", num); 1859141cc406Sopenharmony_ci number_string[sizeof (number_string) - 1] = '\0'; 1860141cc406Sopenharmony_ci test_device->name = strdup (number_string); 1861141cc406Sopenharmony_ci if (!test_device->name) 1862141cc406Sopenharmony_ci goto fail_name; 1863141cc406Sopenharmony_ci test_device->sane.name = test_device->name; 1864141cc406Sopenharmony_ci if (previous_device) 1865141cc406Sopenharmony_ci previous_device->next = test_device; 1866141cc406Sopenharmony_ci previous_device = test_device; 1867141cc406Sopenharmony_ci if (num == 0) 1868141cc406Sopenharmony_ci first_test_device = test_device; 1869141cc406Sopenharmony_ci sane_device_list[num] = &test_device->sane; 1870141cc406Sopenharmony_ci test_device->open = SANE_FALSE; 1871141cc406Sopenharmony_ci test_device->eof = SANE_FALSE; 1872141cc406Sopenharmony_ci test_device->scanning = SANE_FALSE; 1873141cc406Sopenharmony_ci test_device->cancelled = SANE_FALSE; 1874141cc406Sopenharmony_ci test_device->options_initialized = SANE_FALSE; 1875141cc406Sopenharmony_ci sanei_thread_initialize (test_device->reader_pid); 1876141cc406Sopenharmony_ci test_device->pipe = -1; 1877141cc406Sopenharmony_ci DBG (4, "sane_init: new device: `%s' is a %s %s %s\n", 1878141cc406Sopenharmony_ci test_device->sane.name, test_device->sane.vendor, 1879141cc406Sopenharmony_ci test_device->sane.model, test_device->sane.type); 1880141cc406Sopenharmony_ci } 1881141cc406Sopenharmony_ci test_device->next = 0; 1882141cc406Sopenharmony_ci sane_device_list[num] = 0; 1883141cc406Sopenharmony_ci srand ((unsigned int) time (NULL)); 1884141cc406Sopenharmony_ci random_factor = ((double) rand ()) / RAND_MAX + 0.5; 1885141cc406Sopenharmony_ci inited = SANE_TRUE; 1886141cc406Sopenharmony_ci return SANE_STATUS_GOOD; 1887141cc406Sopenharmony_ci 1888141cc406Sopenharmony_cifail_name: 1889141cc406Sopenharmony_ci // test_device refers to the last device we were creating, which has not 1890141cc406Sopenharmony_ci // yet been added to the linked list of devices. 1891141cc406Sopenharmony_ci free (test_device); 1892141cc406Sopenharmony_cifail_device: 1893141cc406Sopenharmony_ci // Now, iterate through the linked list of devices to clean up any successful 1894141cc406Sopenharmony_ci // devices. 1895141cc406Sopenharmony_ci test_device = first_test_device; 1896141cc406Sopenharmony_ci while (test_device) 1897141cc406Sopenharmony_ci { 1898141cc406Sopenharmony_ci previous_device = test_device; 1899141cc406Sopenharmony_ci test_device = test_device->next; 1900141cc406Sopenharmony_ci cleanup_test_device (previous_device); 1901141cc406Sopenharmony_ci } 1902141cc406Sopenharmony_ci free (sane_device_list); 1903141cc406Sopenharmony_cifail: 1904141cc406Sopenharmony_ci cleanup_initial_string_values (); 1905141cc406Sopenharmony_ci return SANE_STATUS_NO_MEM; 1906141cc406Sopenharmony_ci} 1907141cc406Sopenharmony_ci 1908141cc406Sopenharmony_civoid 1909141cc406Sopenharmony_cisane_exit (void) 1910141cc406Sopenharmony_ci{ 1911141cc406Sopenharmony_ci Test_Device *test_device, *previous_device; 1912141cc406Sopenharmony_ci 1913141cc406Sopenharmony_ci DBG (2, "sane_exit\n"); 1914141cc406Sopenharmony_ci if (!inited) 1915141cc406Sopenharmony_ci { 1916141cc406Sopenharmony_ci DBG (1, "sane_exit: not inited, call sane_init() first\n"); 1917141cc406Sopenharmony_ci return; 1918141cc406Sopenharmony_ci } 1919141cc406Sopenharmony_ci 1920141cc406Sopenharmony_ci test_device = first_test_device; 1921141cc406Sopenharmony_ci while (test_device) 1922141cc406Sopenharmony_ci { 1923141cc406Sopenharmony_ci DBG (4, "sane_exit: freeing device %s\n", test_device->name); 1924141cc406Sopenharmony_ci previous_device = test_device; 1925141cc406Sopenharmony_ci test_device = test_device->next; 1926141cc406Sopenharmony_ci cleanup_test_device (previous_device); 1927141cc406Sopenharmony_ci } 1928141cc406Sopenharmony_ci DBG (4, "sane_exit: freeing device list\n"); 1929141cc406Sopenharmony_ci if (sane_device_list) 1930141cc406Sopenharmony_ci free (sane_device_list); 1931141cc406Sopenharmony_ci sane_device_list = NULL; 1932141cc406Sopenharmony_ci first_test_device = NULL; 1933141cc406Sopenharmony_ci 1934141cc406Sopenharmony_ci cleanup_initial_string_values (); 1935141cc406Sopenharmony_ci inited = SANE_FALSE; 1936141cc406Sopenharmony_ci return; 1937141cc406Sopenharmony_ci} 1938141cc406Sopenharmony_ci 1939141cc406Sopenharmony_ci 1940141cc406Sopenharmony_ciSANE_Status 1941141cc406Sopenharmony_cisane_get_devices (const SANE_Device *** device_list, SANE_Bool local_only) 1942141cc406Sopenharmony_ci{ 1943141cc406Sopenharmony_ci 1944141cc406Sopenharmony_ci DBG (2, "sane_get_devices: device_list=%p, local_only=%d\n", 1945141cc406Sopenharmony_ci (void *) device_list, local_only); 1946141cc406Sopenharmony_ci if (!inited) 1947141cc406Sopenharmony_ci { 1948141cc406Sopenharmony_ci DBG (1, "sane_get_devices: not inited, call sane_init() first\n"); 1949141cc406Sopenharmony_ci return SANE_STATUS_INVAL; 1950141cc406Sopenharmony_ci } 1951141cc406Sopenharmony_ci 1952141cc406Sopenharmony_ci if (!device_list) 1953141cc406Sopenharmony_ci { 1954141cc406Sopenharmony_ci DBG (1, "sane_get_devices: device_list == 0\n"); 1955141cc406Sopenharmony_ci return SANE_STATUS_INVAL; 1956141cc406Sopenharmony_ci } 1957141cc406Sopenharmony_ci *device_list = (const SANE_Device **) sane_device_list; 1958141cc406Sopenharmony_ci return SANE_STATUS_GOOD; 1959141cc406Sopenharmony_ci} 1960141cc406Sopenharmony_ci 1961141cc406Sopenharmony_ciSANE_Status 1962141cc406Sopenharmony_cisane_open (SANE_String_Const devicename, SANE_Handle * handle) 1963141cc406Sopenharmony_ci{ 1964141cc406Sopenharmony_ci Test_Device *test_device = first_test_device; 1965141cc406Sopenharmony_ci SANE_Status status; 1966141cc406Sopenharmony_ci 1967141cc406Sopenharmony_ci DBG (2, "sane_open: devicename = \"%s\", handle=%p\n", 1968141cc406Sopenharmony_ci devicename, (void *) handle); 1969141cc406Sopenharmony_ci if (!inited) 1970141cc406Sopenharmony_ci { 1971141cc406Sopenharmony_ci DBG (1, "sane_open: not inited, call sane_init() first\n"); 1972141cc406Sopenharmony_ci return SANE_STATUS_INVAL; 1973141cc406Sopenharmony_ci } 1974141cc406Sopenharmony_ci 1975141cc406Sopenharmony_ci if (!handle) 1976141cc406Sopenharmony_ci { 1977141cc406Sopenharmony_ci DBG (1, "sane_open: handle == 0\n"); 1978141cc406Sopenharmony_ci return SANE_STATUS_INVAL; 1979141cc406Sopenharmony_ci } 1980141cc406Sopenharmony_ci 1981141cc406Sopenharmony_ci if (!devicename || strlen (devicename) == 0) 1982141cc406Sopenharmony_ci { 1983141cc406Sopenharmony_ci DBG (2, "sane_open: device name NULL or empty\n"); 1984141cc406Sopenharmony_ci } 1985141cc406Sopenharmony_ci else 1986141cc406Sopenharmony_ci { 1987141cc406Sopenharmony_ci for (test_device = first_test_device; test_device; 1988141cc406Sopenharmony_ci test_device = test_device->next) 1989141cc406Sopenharmony_ci { 1990141cc406Sopenharmony_ci if (strcmp (devicename, test_device->name) == 0) 1991141cc406Sopenharmony_ci break; 1992141cc406Sopenharmony_ci } 1993141cc406Sopenharmony_ci } 1994141cc406Sopenharmony_ci if (!test_device) 1995141cc406Sopenharmony_ci { 1996141cc406Sopenharmony_ci DBG (1, "sane_open: device `%s' not found\n", devicename); 1997141cc406Sopenharmony_ci return SANE_STATUS_INVAL; 1998141cc406Sopenharmony_ci } 1999141cc406Sopenharmony_ci if (test_device->open) 2000141cc406Sopenharmony_ci { 2001141cc406Sopenharmony_ci DBG (1, "sane_open: device `%s' already open\n", devicename); 2002141cc406Sopenharmony_ci return SANE_STATUS_DEVICE_BUSY; 2003141cc406Sopenharmony_ci } 2004141cc406Sopenharmony_ci DBG (2, "sane_open: opening device `%s', handle = %p\n", test_device->name, 2005141cc406Sopenharmony_ci (void *) test_device); 2006141cc406Sopenharmony_ci test_device->open = SANE_TRUE; 2007141cc406Sopenharmony_ci *handle = test_device; 2008141cc406Sopenharmony_ci 2009141cc406Sopenharmony_ci if (!test_device->options_initialized) { 2010141cc406Sopenharmony_ci status = init_options (test_device); 2011141cc406Sopenharmony_ci if (status != SANE_STATUS_GOOD) 2012141cc406Sopenharmony_ci return status; 2013141cc406Sopenharmony_ci test_device->options_initialized = SANE_TRUE; 2014141cc406Sopenharmony_ci } 2015141cc406Sopenharmony_ci 2016141cc406Sopenharmony_ci test_device->open = SANE_TRUE; 2017141cc406Sopenharmony_ci test_device->scanning = SANE_FALSE; 2018141cc406Sopenharmony_ci test_device->cancelled = SANE_FALSE; 2019141cc406Sopenharmony_ci test_device->eof = SANE_FALSE; 2020141cc406Sopenharmony_ci test_device->bytes_total = 0; 2021141cc406Sopenharmony_ci test_device->pass = 0; 2022141cc406Sopenharmony_ci test_device->number_of_scans = 0; 2023141cc406Sopenharmony_ci 2024141cc406Sopenharmony_ci return SANE_STATUS_GOOD; 2025141cc406Sopenharmony_ci} 2026141cc406Sopenharmony_ci 2027141cc406Sopenharmony_civoid 2028141cc406Sopenharmony_cisane_close (SANE_Handle handle) 2029141cc406Sopenharmony_ci{ 2030141cc406Sopenharmony_ci Test_Device *test_device = handle; 2031141cc406Sopenharmony_ci 2032141cc406Sopenharmony_ci DBG (2, "sane_close: handle=%p\n", (void *) handle); 2033141cc406Sopenharmony_ci if (!inited) 2034141cc406Sopenharmony_ci { 2035141cc406Sopenharmony_ci DBG (1, "sane_close: not inited, call sane_init() first\n"); 2036141cc406Sopenharmony_ci return; 2037141cc406Sopenharmony_ci } 2038141cc406Sopenharmony_ci 2039141cc406Sopenharmony_ci if (!check_handle (handle)) 2040141cc406Sopenharmony_ci { 2041141cc406Sopenharmony_ci DBG (1, "sane_close: handle %p unknown\n", (void *) handle); 2042141cc406Sopenharmony_ci return; 2043141cc406Sopenharmony_ci } 2044141cc406Sopenharmony_ci if (!test_device->open) 2045141cc406Sopenharmony_ci { 2046141cc406Sopenharmony_ci DBG (1, "sane_close: handle %p not open\n", (void *) handle); 2047141cc406Sopenharmony_ci return; 2048141cc406Sopenharmony_ci } 2049141cc406Sopenharmony_ci test_device->open = SANE_FALSE; 2050141cc406Sopenharmony_ci return; 2051141cc406Sopenharmony_ci} 2052141cc406Sopenharmony_ci 2053141cc406Sopenharmony_ciconst SANE_Option_Descriptor * 2054141cc406Sopenharmony_cisane_get_option_descriptor (SANE_Handle handle, SANE_Int option) 2055141cc406Sopenharmony_ci{ 2056141cc406Sopenharmony_ci Test_Device *test_device = handle; 2057141cc406Sopenharmony_ci 2058141cc406Sopenharmony_ci DBG (4, "sane_get_option_descriptor: handle=%p, option = %d\n", 2059141cc406Sopenharmony_ci (void *) handle, option); 2060141cc406Sopenharmony_ci if (!inited) 2061141cc406Sopenharmony_ci { 2062141cc406Sopenharmony_ci DBG (1, "sane_get_option_descriptor: not inited, call sane_init() " 2063141cc406Sopenharmony_ci "first\n"); 2064141cc406Sopenharmony_ci return 0; 2065141cc406Sopenharmony_ci } 2066141cc406Sopenharmony_ci 2067141cc406Sopenharmony_ci if (!check_handle (handle)) 2068141cc406Sopenharmony_ci { 2069141cc406Sopenharmony_ci DBG (1, "sane_get_option_descriptor: handle %p unknown\n", 2070141cc406Sopenharmony_ci (void *) handle); 2071141cc406Sopenharmony_ci return 0; 2072141cc406Sopenharmony_ci } 2073141cc406Sopenharmony_ci if (!test_device->open) 2074141cc406Sopenharmony_ci { 2075141cc406Sopenharmony_ci DBG (1, "sane_get_option_descriptor: not open\n"); 2076141cc406Sopenharmony_ci return 0; 2077141cc406Sopenharmony_ci } 2078141cc406Sopenharmony_ci if (option < 0 || option >= num_options) 2079141cc406Sopenharmony_ci { 2080141cc406Sopenharmony_ci DBG (3, "sane_get_option_descriptor: option < 0 || " 2081141cc406Sopenharmony_ci "option > num_options\n"); 2082141cc406Sopenharmony_ci return 0; 2083141cc406Sopenharmony_ci } 2084141cc406Sopenharmony_ci 2085141cc406Sopenharmony_ci test_device->loaded[option] = 1; 2086141cc406Sopenharmony_ci 2087141cc406Sopenharmony_ci return &test_device->opt[option]; 2088141cc406Sopenharmony_ci} 2089141cc406Sopenharmony_ci 2090141cc406Sopenharmony_ciSANE_Status 2091141cc406Sopenharmony_cisane_control_option (SANE_Handle handle, SANE_Int option, SANE_Action action, 2092141cc406Sopenharmony_ci void *value, SANE_Int * info) 2093141cc406Sopenharmony_ci{ 2094141cc406Sopenharmony_ci Test_Device *test_device = handle; 2095141cc406Sopenharmony_ci SANE_Int myinfo = 0; 2096141cc406Sopenharmony_ci SANE_Status status; 2097141cc406Sopenharmony_ci 2098141cc406Sopenharmony_ci DBG (4, "sane_control_option: handle=%p, opt=%d, act=%d, val=%p, info=%p\n", 2099141cc406Sopenharmony_ci (void *) handle, option, action, (void *) value, (void *) info); 2100141cc406Sopenharmony_ci if (!inited) 2101141cc406Sopenharmony_ci { 2102141cc406Sopenharmony_ci DBG (1, "sane_control_option: not inited, call sane_init() first\n"); 2103141cc406Sopenharmony_ci return SANE_STATUS_INVAL; 2104141cc406Sopenharmony_ci } 2105141cc406Sopenharmony_ci 2106141cc406Sopenharmony_ci if (!check_handle (handle)) 2107141cc406Sopenharmony_ci { 2108141cc406Sopenharmony_ci DBG (1, "sane_control_option: handle %p unknown\n", (void *) handle); 2109141cc406Sopenharmony_ci return SANE_STATUS_INVAL; 2110141cc406Sopenharmony_ci } 2111141cc406Sopenharmony_ci if (!test_device->open) 2112141cc406Sopenharmony_ci { 2113141cc406Sopenharmony_ci DBG (1, "sane_control_option: not open\n"); 2114141cc406Sopenharmony_ci return SANE_STATUS_INVAL; 2115141cc406Sopenharmony_ci } 2116141cc406Sopenharmony_ci if (test_device->scanning) 2117141cc406Sopenharmony_ci { 2118141cc406Sopenharmony_ci DBG (1, "sane_control_option: is scanning\n"); 2119141cc406Sopenharmony_ci return SANE_STATUS_INVAL; 2120141cc406Sopenharmony_ci } 2121141cc406Sopenharmony_ci if (option < 0 || option >= num_options) 2122141cc406Sopenharmony_ci { 2123141cc406Sopenharmony_ci DBG (1, "sane_control_option: option < 0 || option > num_options\n"); 2124141cc406Sopenharmony_ci return SANE_STATUS_INVAL; 2125141cc406Sopenharmony_ci } 2126141cc406Sopenharmony_ci 2127141cc406Sopenharmony_ci if (!test_device->loaded[option]) 2128141cc406Sopenharmony_ci { 2129141cc406Sopenharmony_ci DBG (1, "sane_control_option: option not loaded\n"); 2130141cc406Sopenharmony_ci return SANE_STATUS_INVAL; 2131141cc406Sopenharmony_ci } 2132141cc406Sopenharmony_ci 2133141cc406Sopenharmony_ci if (!SANE_OPTION_IS_ACTIVE (test_device->opt[option].cap)) 2134141cc406Sopenharmony_ci { 2135141cc406Sopenharmony_ci DBG (1, "sane_control_option: option is inactive\n"); 2136141cc406Sopenharmony_ci return SANE_STATUS_INVAL; 2137141cc406Sopenharmony_ci } 2138141cc406Sopenharmony_ci 2139141cc406Sopenharmony_ci if (test_device->opt[option].type == SANE_TYPE_GROUP) 2140141cc406Sopenharmony_ci { 2141141cc406Sopenharmony_ci DBG (1, "sane_control_option: option is a group\n"); 2142141cc406Sopenharmony_ci return SANE_STATUS_INVAL; 2143141cc406Sopenharmony_ci } 2144141cc406Sopenharmony_ci 2145141cc406Sopenharmony_ci switch (action) 2146141cc406Sopenharmony_ci { 2147141cc406Sopenharmony_ci case SANE_ACTION_SET_AUTO: 2148141cc406Sopenharmony_ci if (!SANE_OPTION_IS_SETTABLE (test_device->opt[option].cap)) 2149141cc406Sopenharmony_ci { 2150141cc406Sopenharmony_ci DBG (1, "sane_control_option: option is not setable\n"); 2151141cc406Sopenharmony_ci return SANE_STATUS_INVAL; 2152141cc406Sopenharmony_ci } 2153141cc406Sopenharmony_ci if (!(test_device->opt[option].cap & SANE_CAP_AUTOMATIC)) 2154141cc406Sopenharmony_ci { 2155141cc406Sopenharmony_ci DBG (1, "sane_control_option: option is not automatically " 2156141cc406Sopenharmony_ci "setable\n"); 2157141cc406Sopenharmony_ci return SANE_STATUS_INVAL; 2158141cc406Sopenharmony_ci } 2159141cc406Sopenharmony_ci switch (option) 2160141cc406Sopenharmony_ci { 2161141cc406Sopenharmony_ci case opt_bool_soft_select_soft_detect_auto: 2162141cc406Sopenharmony_ci test_device->val[option].w = SANE_TRUE; 2163141cc406Sopenharmony_ci DBG (4, "sane_control_option: set option %d (%s) automatically " 2164141cc406Sopenharmony_ci "to %s\n", option, test_device->opt[option].name, 2165141cc406Sopenharmony_ci test_device->val[option].w == SANE_TRUE ? "true" : "false"); 2166141cc406Sopenharmony_ci break; 2167141cc406Sopenharmony_ci 2168141cc406Sopenharmony_ci default: 2169141cc406Sopenharmony_ci DBG (1, "sane_control_option: trying to automatically set " 2170141cc406Sopenharmony_ci "unexpected option\n"); 2171141cc406Sopenharmony_ci return SANE_STATUS_INVAL; 2172141cc406Sopenharmony_ci } 2173141cc406Sopenharmony_ci break; 2174141cc406Sopenharmony_ci 2175141cc406Sopenharmony_ci case SANE_ACTION_SET_VALUE: 2176141cc406Sopenharmony_ci if (!SANE_OPTION_IS_SETTABLE (test_device->opt[option].cap)) 2177141cc406Sopenharmony_ci { 2178141cc406Sopenharmony_ci DBG (1, "sane_control_option: option is not setable\n"); 2179141cc406Sopenharmony_ci return SANE_STATUS_INVAL; 2180141cc406Sopenharmony_ci } 2181141cc406Sopenharmony_ci status = sanei_constrain_value (&test_device->opt[option], 2182141cc406Sopenharmony_ci value, &myinfo); 2183141cc406Sopenharmony_ci if (status != SANE_STATUS_GOOD) 2184141cc406Sopenharmony_ci { 2185141cc406Sopenharmony_ci DBG (3, "sane_control_option: sanei_constrain_value returned %s\n", 2186141cc406Sopenharmony_ci sane_strstatus (status)); 2187141cc406Sopenharmony_ci return status; 2188141cc406Sopenharmony_ci } 2189141cc406Sopenharmony_ci switch (option) 2190141cc406Sopenharmony_ci { 2191141cc406Sopenharmony_ci case opt_tl_x: /* Fixed with parameter reloading */ 2192141cc406Sopenharmony_ci case opt_tl_y: 2193141cc406Sopenharmony_ci case opt_br_x: 2194141cc406Sopenharmony_ci case opt_br_y: 2195141cc406Sopenharmony_ci case opt_resolution: 2196141cc406Sopenharmony_ci if (test_device->val[option].w == *(SANE_Fixed *) value) 2197141cc406Sopenharmony_ci { 2198141cc406Sopenharmony_ci DBG (4, "sane_control_option: option %d (%s) not changed\n", 2199141cc406Sopenharmony_ci option, test_device->opt[option].name); 2200141cc406Sopenharmony_ci break; 2201141cc406Sopenharmony_ci } 2202141cc406Sopenharmony_ci test_device->val[option].w = *(SANE_Fixed *) value; 2203141cc406Sopenharmony_ci myinfo |= SANE_INFO_RELOAD_PARAMS; 2204141cc406Sopenharmony_ci DBG (4, "sane_control_option: set option %d (%s) to %.0f %s\n", 2205141cc406Sopenharmony_ci option, test_device->opt[option].name, 2206141cc406Sopenharmony_ci SANE_UNFIX (*(SANE_Fixed *) value), 2207141cc406Sopenharmony_ci test_device->opt[option].unit == SANE_UNIT_MM ? "mm" : "dpi"); 2208141cc406Sopenharmony_ci break; 2209141cc406Sopenharmony_ci case opt_fixed: /* Fixed */ 2210141cc406Sopenharmony_ci case opt_fixed_constraint_range: 2211141cc406Sopenharmony_ci if (test_device->val[option].w == *(SANE_Fixed *) value) 2212141cc406Sopenharmony_ci { 2213141cc406Sopenharmony_ci DBG (4, "sane_control_option: option %d (%s) not changed\n", 2214141cc406Sopenharmony_ci option, test_device->opt[option].name); 2215141cc406Sopenharmony_ci break; 2216141cc406Sopenharmony_ci } 2217141cc406Sopenharmony_ci test_device->val[option].w = *(SANE_Fixed *) value; 2218141cc406Sopenharmony_ci DBG (4, "sane_control_option: set option %d (%s) to %.0f\n", 2219141cc406Sopenharmony_ci option, test_device->opt[option].name, 2220141cc406Sopenharmony_ci SANE_UNFIX (*(SANE_Fixed *) value)); 2221141cc406Sopenharmony_ci break; 2222141cc406Sopenharmony_ci case opt_read_limit_size: /* Int */ 2223141cc406Sopenharmony_ci case opt_ppl_loss: 2224141cc406Sopenharmony_ci case opt_read_delay_duration: 2225141cc406Sopenharmony_ci case opt_int: 2226141cc406Sopenharmony_ci case opt_int_constraint_range: 2227141cc406Sopenharmony_ci if (test_device->val[option].w == *(SANE_Int *) value) 2228141cc406Sopenharmony_ci { 2229141cc406Sopenharmony_ci DBG (4, "sane_control_option: option %d (%s) not changed\n", 2230141cc406Sopenharmony_ci option, test_device->opt[option].name); 2231141cc406Sopenharmony_ci break; 2232141cc406Sopenharmony_ci } 2233141cc406Sopenharmony_ci test_device->val[option].w = *(SANE_Int *) value; 2234141cc406Sopenharmony_ci DBG (4, "sane_control_option: set option %d (%s) to %d\n", 2235141cc406Sopenharmony_ci option, test_device->opt[option].name, *(SANE_Int *) value); 2236141cc406Sopenharmony_ci break; 2237141cc406Sopenharmony_ci case opt_int_inexact: 2238141cc406Sopenharmony_ci if (test_device->val[option].w == *(SANE_Int *) value) 2239141cc406Sopenharmony_ci { 2240141cc406Sopenharmony_ci DBG (4, "sane_control_option: option %d (%s) not changed\n", 2241141cc406Sopenharmony_ci option, test_device->opt[option].name); 2242141cc406Sopenharmony_ci break; 2243141cc406Sopenharmony_ci } 2244141cc406Sopenharmony_ci *(SANE_Int *) value += 1; 2245141cc406Sopenharmony_ci test_device->val[option].w = *(SANE_Int *) value; 2246141cc406Sopenharmony_ci myinfo |= SANE_INFO_INEXACT; 2247141cc406Sopenharmony_ci DBG (4, "sane_control_option: set option %d (%s) to %d\n", 2248141cc406Sopenharmony_ci option, test_device->opt[option].name, *(SANE_Int *) value); 2249141cc406Sopenharmony_ci break; 2250141cc406Sopenharmony_ci case opt_fuzzy_parameters: /* Bool with parameter reloading */ 2251141cc406Sopenharmony_ci if (test_device->val[option].w == *(SANE_Bool *) value) 2252141cc406Sopenharmony_ci { 2253141cc406Sopenharmony_ci DBG (4, "sane_control_option: option %d (%s) not changed\n", 2254141cc406Sopenharmony_ci option, test_device->opt[option].name); 2255141cc406Sopenharmony_ci break; 2256141cc406Sopenharmony_ci } 2257141cc406Sopenharmony_ci test_device->val[option].w = *(SANE_Bool *) value; 2258141cc406Sopenharmony_ci myinfo |= SANE_INFO_RELOAD_PARAMS; 2259141cc406Sopenharmony_ci DBG (4, "sane_control_option: set option %d (%s) to %s\n", 2260141cc406Sopenharmony_ci option, test_device->opt[option].name, 2261141cc406Sopenharmony_ci *(SANE_Bool *) value == SANE_TRUE ? "true" : "false"); 2262141cc406Sopenharmony_ci break; 2263141cc406Sopenharmony_ci case opt_invert_endianess: /* Bool */ 2264141cc406Sopenharmony_ci case opt_non_blocking: 2265141cc406Sopenharmony_ci case opt_select_fd: 2266141cc406Sopenharmony_ci case opt_bool_soft_select_soft_detect: 2267141cc406Sopenharmony_ci case opt_bool_soft_select_soft_detect_auto: 2268141cc406Sopenharmony_ci case opt_bool_soft_select_soft_detect_emulated: 2269141cc406Sopenharmony_ci if (test_device->val[option].w == *(SANE_Bool *) value) 2270141cc406Sopenharmony_ci { 2271141cc406Sopenharmony_ci DBG (4, "sane_control_option: option %d (%s) not changed\n", 2272141cc406Sopenharmony_ci option, test_device->opt[option].name); 2273141cc406Sopenharmony_ci break; 2274141cc406Sopenharmony_ci } 2275141cc406Sopenharmony_ci test_device->val[option].w = *(SANE_Bool *) value; 2276141cc406Sopenharmony_ci DBG (4, "sane_control_option: set option %d (%s) to %s\n", 2277141cc406Sopenharmony_ci option, test_device->opt[option].name, 2278141cc406Sopenharmony_ci *(SANE_Bool *) value == SANE_TRUE ? "true" : "false"); 2279141cc406Sopenharmony_ci break; 2280141cc406Sopenharmony_ci case opt_depth: /* Word list with parameter and options reloading */ 2281141cc406Sopenharmony_ci if (test_device->val[option].w == *(SANE_Int *) value) 2282141cc406Sopenharmony_ci { 2283141cc406Sopenharmony_ci DBG (4, "sane_control_option: option %d (%s) not changed\n", 2284141cc406Sopenharmony_ci option, test_device->opt[option].name); 2285141cc406Sopenharmony_ci break; 2286141cc406Sopenharmony_ci } 2287141cc406Sopenharmony_ci test_device->val[option].w = *(SANE_Int *) value; 2288141cc406Sopenharmony_ci if (test_device->val[option].w == 16) 2289141cc406Sopenharmony_ci test_device->opt[opt_invert_endianess].cap &= ~SANE_CAP_INACTIVE; 2290141cc406Sopenharmony_ci else 2291141cc406Sopenharmony_ci test_device->opt[opt_invert_endianess].cap |= SANE_CAP_INACTIVE; 2292141cc406Sopenharmony_ci 2293141cc406Sopenharmony_ci myinfo |= SANE_INFO_RELOAD_PARAMS; 2294141cc406Sopenharmony_ci myinfo |= SANE_INFO_RELOAD_OPTIONS; 2295141cc406Sopenharmony_ci DBG (4, "sane_control_option: set option %d (%s) to %d\n", 2296141cc406Sopenharmony_ci option, test_device->opt[option].name, *(SANE_Int *) value); 2297141cc406Sopenharmony_ci break; 2298141cc406Sopenharmony_ci case opt_three_pass_order: /* String list with parameter reload */ 2299141cc406Sopenharmony_ci if (strcmp (test_device->val[option].s, value) == 0) 2300141cc406Sopenharmony_ci { 2301141cc406Sopenharmony_ci DBG (4, "sane_control_option: option %d (%s) not changed\n", 2302141cc406Sopenharmony_ci option, test_device->opt[option].name); 2303141cc406Sopenharmony_ci break; 2304141cc406Sopenharmony_ci } 2305141cc406Sopenharmony_ci strcpy (test_device->val[option].s, (SANE_String) value); 2306141cc406Sopenharmony_ci myinfo |= SANE_INFO_RELOAD_PARAMS; 2307141cc406Sopenharmony_ci DBG (4, "sane_control_option: set option %d (%s) to %s\n", 2308141cc406Sopenharmony_ci option, test_device->opt[option].name, (SANE_String) value); 2309141cc406Sopenharmony_ci break; 2310141cc406Sopenharmony_ci case opt_int_constraint_word_list: /* Word list */ 2311141cc406Sopenharmony_ci case opt_fixed_constraint_word_list: 2312141cc406Sopenharmony_ci if (test_device->val[option].w == *(SANE_Int *) value) 2313141cc406Sopenharmony_ci { 2314141cc406Sopenharmony_ci DBG (4, "sane_control_option: option %d (%s) not changed\n", 2315141cc406Sopenharmony_ci option, test_device->opt[option].name); 2316141cc406Sopenharmony_ci break; 2317141cc406Sopenharmony_ci } 2318141cc406Sopenharmony_ci test_device->val[option].w = *(SANE_Int *) value; 2319141cc406Sopenharmony_ci DBG (4, "sane_control_option: set option %d (%s) to %d\n", 2320141cc406Sopenharmony_ci option, test_device->opt[option].name, *(SANE_Int *) value); 2321141cc406Sopenharmony_ci break; 2322141cc406Sopenharmony_ci case opt_read_status_code: /* String (list) */ 2323141cc406Sopenharmony_ci case opt_test_picture: 2324141cc406Sopenharmony_ci case opt_string: 2325141cc406Sopenharmony_ci case opt_string_constraint_string_list: 2326141cc406Sopenharmony_ci case opt_string_constraint_long_string_list: 2327141cc406Sopenharmony_ci case opt_scan_source: 2328141cc406Sopenharmony_ci if (strcmp (test_device->val[option].s, value) == 0) 2329141cc406Sopenharmony_ci { 2330141cc406Sopenharmony_ci DBG (4, "sane_control_option: option %d (%s) not changed\n", 2331141cc406Sopenharmony_ci option, test_device->opt[option].name); 2332141cc406Sopenharmony_ci break; 2333141cc406Sopenharmony_ci } 2334141cc406Sopenharmony_ci strcpy (test_device->val[option].s, (SANE_String) value); 2335141cc406Sopenharmony_ci DBG (4, "sane_control_option: set option %d (%s) to `%s'\n", 2336141cc406Sopenharmony_ci option, test_device->opt[option].name, (SANE_String) value); 2337141cc406Sopenharmony_ci break; 2338141cc406Sopenharmony_ci case opt_int_array: /* Word array */ 2339141cc406Sopenharmony_ci case opt_int_array_constraint_range: 2340141cc406Sopenharmony_ci case opt_gamma_red: 2341141cc406Sopenharmony_ci case opt_gamma_green: 2342141cc406Sopenharmony_ci case opt_gamma_blue: 2343141cc406Sopenharmony_ci case opt_gamma_all: 2344141cc406Sopenharmony_ci case opt_int_array_constraint_word_list: 2345141cc406Sopenharmony_ci memcpy (test_device->val[option].wa, value, 2346141cc406Sopenharmony_ci (size_t) test_device->opt[option].size); 2347141cc406Sopenharmony_ci DBG (4, "sane_control_option: set option %d (%s) to %p\n", 2348141cc406Sopenharmony_ci option, test_device->opt[option].name, (void *) value); 2349141cc406Sopenharmony_ci if (option == opt_gamma_all) { 2350141cc406Sopenharmony_ci print_gamma_table(gamma_all, GAMMA_ALL_SIZE); 2351141cc406Sopenharmony_ci } 2352141cc406Sopenharmony_ci if (option == opt_gamma_red) { 2353141cc406Sopenharmony_ci print_gamma_table(gamma_red, GAMMA_RED_SIZE); 2354141cc406Sopenharmony_ci } 2355141cc406Sopenharmony_ci break; 2356141cc406Sopenharmony_ci /* options with side-effects */ 2357141cc406Sopenharmony_ci case opt_print_options: 2358141cc406Sopenharmony_ci DBG (4, "sane_control_option: set option %d (%s)\n", 2359141cc406Sopenharmony_ci option, test_device->opt[option].name); 2360141cc406Sopenharmony_ci print_options (test_device); 2361141cc406Sopenharmony_ci break; 2362141cc406Sopenharmony_ci case opt_button: 2363141cc406Sopenharmony_ci DBG (0, "Yes! You pressed me!\n"); 2364141cc406Sopenharmony_ci DBG (4, "sane_control_option: set option %d (%s)\n", 2365141cc406Sopenharmony_ci option, test_device->opt[option].name); 2366141cc406Sopenharmony_ci break; 2367141cc406Sopenharmony_ci case opt_mode: 2368141cc406Sopenharmony_ci if (strcmp (test_device->val[option].s, value) == 0) 2369141cc406Sopenharmony_ci { 2370141cc406Sopenharmony_ci DBG (4, "sane_control_option: option %d (%s) not changed\n", 2371141cc406Sopenharmony_ci option, test_device->opt[option].name); 2372141cc406Sopenharmony_ci break; 2373141cc406Sopenharmony_ci } 2374141cc406Sopenharmony_ci strcpy (test_device->val[option].s, (SANE_String) value); 2375141cc406Sopenharmony_ci myinfo |= SANE_INFO_RELOAD_PARAMS; 2376141cc406Sopenharmony_ci myinfo |= SANE_INFO_RELOAD_OPTIONS; 2377141cc406Sopenharmony_ci if (strcmp (test_device->val[option].s, SANE_VALUE_SCAN_MODE_COLOR) == 0) 2378141cc406Sopenharmony_ci { 2379141cc406Sopenharmony_ci test_device->opt[opt_three_pass].cap &= ~SANE_CAP_INACTIVE; 2380141cc406Sopenharmony_ci if (test_device->val[opt_three_pass].w == SANE_TRUE) 2381141cc406Sopenharmony_ci test_device->opt[opt_three_pass_order].cap 2382141cc406Sopenharmony_ci &= ~SANE_CAP_INACTIVE; 2383141cc406Sopenharmony_ci } 2384141cc406Sopenharmony_ci else 2385141cc406Sopenharmony_ci { 2386141cc406Sopenharmony_ci test_device->opt[opt_three_pass].cap |= SANE_CAP_INACTIVE; 2387141cc406Sopenharmony_ci test_device->opt[opt_three_pass_order].cap |= SANE_CAP_INACTIVE; 2388141cc406Sopenharmony_ci } 2389141cc406Sopenharmony_ci DBG (4, "sane_control_option: set option %d (%s) to %s\n", 2390141cc406Sopenharmony_ci option, test_device->opt[option].name, (SANE_String) value); 2391141cc406Sopenharmony_ci break; 2392141cc406Sopenharmony_ci case opt_three_pass: 2393141cc406Sopenharmony_ci if (test_device->val[option].w == *(SANE_Bool *) value) 2394141cc406Sopenharmony_ci { 2395141cc406Sopenharmony_ci DBG (4, "sane_control_option: option %d (%s) not changed\n", 2396141cc406Sopenharmony_ci option, test_device->opt[option].name); 2397141cc406Sopenharmony_ci break; 2398141cc406Sopenharmony_ci } 2399141cc406Sopenharmony_ci test_device->val[option].w = *(SANE_Bool *) value; 2400141cc406Sopenharmony_ci myinfo |= SANE_INFO_RELOAD_PARAMS; 2401141cc406Sopenharmony_ci myinfo |= SANE_INFO_RELOAD_OPTIONS; 2402141cc406Sopenharmony_ci if (test_device->val[option].w == SANE_TRUE) 2403141cc406Sopenharmony_ci test_device->opt[opt_three_pass_order].cap &= ~SANE_CAP_INACTIVE; 2404141cc406Sopenharmony_ci else 2405141cc406Sopenharmony_ci test_device->opt[opt_three_pass_order].cap |= SANE_CAP_INACTIVE; 2406141cc406Sopenharmony_ci DBG (4, "sane_control_option: set option %d (%s) to %s\n", 2407141cc406Sopenharmony_ci option, test_device->opt[option].name, 2408141cc406Sopenharmony_ci *(SANE_Bool *) value == SANE_TRUE ? "true" : "false"); 2409141cc406Sopenharmony_ci break; 2410141cc406Sopenharmony_ci case opt_hand_scanner: 2411141cc406Sopenharmony_ci if (test_device->val[option].w == *(SANE_Bool *) value) 2412141cc406Sopenharmony_ci { 2413141cc406Sopenharmony_ci DBG (4, "sane_control_option: option %d (%s) not changed\n", 2414141cc406Sopenharmony_ci option, test_device->opt[option].name); 2415141cc406Sopenharmony_ci break; 2416141cc406Sopenharmony_ci } 2417141cc406Sopenharmony_ci test_device->val[option].w = *(SANE_Bool *) value; 2418141cc406Sopenharmony_ci myinfo |= SANE_INFO_RELOAD_PARAMS; 2419141cc406Sopenharmony_ci myinfo |= SANE_INFO_RELOAD_OPTIONS; 2420141cc406Sopenharmony_ci if (test_device->val[option].w == SANE_TRUE) 2421141cc406Sopenharmony_ci { 2422141cc406Sopenharmony_ci test_device->opt[opt_tl_x].cap |= SANE_CAP_INACTIVE; 2423141cc406Sopenharmony_ci test_device->opt[opt_tl_y].cap |= SANE_CAP_INACTIVE; 2424141cc406Sopenharmony_ci test_device->opt[opt_br_x].cap |= SANE_CAP_INACTIVE; 2425141cc406Sopenharmony_ci test_device->opt[opt_br_y].cap |= SANE_CAP_INACTIVE; 2426141cc406Sopenharmony_ci } 2427141cc406Sopenharmony_ci else 2428141cc406Sopenharmony_ci { 2429141cc406Sopenharmony_ci test_device->opt[opt_tl_x].cap &= ~SANE_CAP_INACTIVE; 2430141cc406Sopenharmony_ci test_device->opt[opt_tl_y].cap &= ~SANE_CAP_INACTIVE; 2431141cc406Sopenharmony_ci test_device->opt[opt_br_x].cap &= ~SANE_CAP_INACTIVE; 2432141cc406Sopenharmony_ci test_device->opt[opt_br_y].cap &= ~SANE_CAP_INACTIVE; 2433141cc406Sopenharmony_ci } 2434141cc406Sopenharmony_ci DBG (4, "sane_control_option: set option %d (%s) to %s\n", 2435141cc406Sopenharmony_ci option, test_device->opt[option].name, 2436141cc406Sopenharmony_ci *(SANE_Bool *) value == SANE_TRUE ? "true" : "false"); 2437141cc406Sopenharmony_ci break; 2438141cc406Sopenharmony_ci case opt_read_limit: 2439141cc406Sopenharmony_ci if (test_device->val[option].w == *(SANE_Bool *) value) 2440141cc406Sopenharmony_ci { 2441141cc406Sopenharmony_ci DBG (4, "sane_control_option: option %d (%s) not changed\n", 2442141cc406Sopenharmony_ci option, test_device->opt[option].name); 2443141cc406Sopenharmony_ci break; 2444141cc406Sopenharmony_ci } 2445141cc406Sopenharmony_ci test_device->val[option].w = *(SANE_Bool *) value; 2446141cc406Sopenharmony_ci myinfo |= SANE_INFO_RELOAD_OPTIONS; 2447141cc406Sopenharmony_ci if (test_device->val[option].w == SANE_TRUE) 2448141cc406Sopenharmony_ci test_device->opt[opt_read_limit_size].cap &= ~SANE_CAP_INACTIVE; 2449141cc406Sopenharmony_ci else 2450141cc406Sopenharmony_ci test_device->opt[opt_read_limit_size].cap |= SANE_CAP_INACTIVE; 2451141cc406Sopenharmony_ci DBG (4, "sane_control_option: set option %d (%s) to %s\n", 2452141cc406Sopenharmony_ci option, test_device->opt[option].name, 2453141cc406Sopenharmony_ci *(SANE_Bool *) value == SANE_TRUE ? "true" : "false"); 2454141cc406Sopenharmony_ci break; 2455141cc406Sopenharmony_ci case opt_read_delay: 2456141cc406Sopenharmony_ci if (test_device->val[option].w == *(SANE_Bool *) value) 2457141cc406Sopenharmony_ci { 2458141cc406Sopenharmony_ci DBG (4, "sane_control_option: option %d (%s) not changed\n", 2459141cc406Sopenharmony_ci option, test_device->opt[option].name); 2460141cc406Sopenharmony_ci break; 2461141cc406Sopenharmony_ci } 2462141cc406Sopenharmony_ci test_device->val[option].w = *(SANE_Bool *) value; 2463141cc406Sopenharmony_ci myinfo |= SANE_INFO_RELOAD_OPTIONS; 2464141cc406Sopenharmony_ci if (test_device->val[option].w == SANE_TRUE) 2465141cc406Sopenharmony_ci test_device->opt[opt_read_delay_duration].cap 2466141cc406Sopenharmony_ci &= ~SANE_CAP_INACTIVE; 2467141cc406Sopenharmony_ci else 2468141cc406Sopenharmony_ci test_device->opt[opt_read_delay_duration].cap |= 2469141cc406Sopenharmony_ci SANE_CAP_INACTIVE; 2470141cc406Sopenharmony_ci DBG (4, "sane_control_option: set option %d (%s) to %s\n", option, 2471141cc406Sopenharmony_ci test_device->opt[option].name, 2472141cc406Sopenharmony_ci *(SANE_Bool *) value == SANE_TRUE ? "true" : "false"); 2473141cc406Sopenharmony_ci break; 2474141cc406Sopenharmony_ci case opt_enable_test_options: 2475141cc406Sopenharmony_ci { 2476141cc406Sopenharmony_ci int option_number; 2477141cc406Sopenharmony_ci if (test_device->val[option].w == *(SANE_Bool *) value) 2478141cc406Sopenharmony_ci { 2479141cc406Sopenharmony_ci DBG (4, "sane_control_option: option %d (%s) not changed\n", 2480141cc406Sopenharmony_ci option, test_device->opt[option].name); 2481141cc406Sopenharmony_ci break; 2482141cc406Sopenharmony_ci } 2483141cc406Sopenharmony_ci test_device->val[option].w = *(SANE_Bool *) value; 2484141cc406Sopenharmony_ci myinfo |= SANE_INFO_RELOAD_OPTIONS; 2485141cc406Sopenharmony_ci for (option_number = opt_bool_soft_select_soft_detect; 2486141cc406Sopenharmony_ci option_number < num_options; option_number++) 2487141cc406Sopenharmony_ci { 2488141cc406Sopenharmony_ci if (test_device->opt[option_number].type == SANE_TYPE_GROUP) 2489141cc406Sopenharmony_ci continue; 2490141cc406Sopenharmony_ci if (test_device->val[option].w == SANE_TRUE) 2491141cc406Sopenharmony_ci test_device->opt[option_number].cap &= ~SANE_CAP_INACTIVE; 2492141cc406Sopenharmony_ci else 2493141cc406Sopenharmony_ci test_device->opt[option_number].cap |= SANE_CAP_INACTIVE; 2494141cc406Sopenharmony_ci } 2495141cc406Sopenharmony_ci DBG (4, "sane_control_option: set option %d (%s) to %s\n", 2496141cc406Sopenharmony_ci option, test_device->opt[option].name, 2497141cc406Sopenharmony_ci *(SANE_Bool *) value == SANE_TRUE ? "true" : "false"); 2498141cc406Sopenharmony_ci break; 2499141cc406Sopenharmony_ci } 2500141cc406Sopenharmony_ci default: 2501141cc406Sopenharmony_ci DBG (1, "sane_control_option: trying to set unexpected option\n"); 2502141cc406Sopenharmony_ci return SANE_STATUS_INVAL; 2503141cc406Sopenharmony_ci } 2504141cc406Sopenharmony_ci break; 2505141cc406Sopenharmony_ci 2506141cc406Sopenharmony_ci case SANE_ACTION_GET_VALUE: 2507141cc406Sopenharmony_ci switch (option) 2508141cc406Sopenharmony_ci { 2509141cc406Sopenharmony_ci case opt_num_opts: 2510141cc406Sopenharmony_ci *(SANE_Word *) value = num_options; 2511141cc406Sopenharmony_ci DBG (4, "sane_control_option: get option 0, value = %d\n", 2512141cc406Sopenharmony_ci num_options); 2513141cc406Sopenharmony_ci break; 2514141cc406Sopenharmony_ci case opt_tl_x: /* Fixed options */ 2515141cc406Sopenharmony_ci case opt_tl_y: 2516141cc406Sopenharmony_ci case opt_br_x: 2517141cc406Sopenharmony_ci case opt_br_y: 2518141cc406Sopenharmony_ci case opt_resolution: 2519141cc406Sopenharmony_ci case opt_fixed: 2520141cc406Sopenharmony_ci case opt_fixed_constraint_range: 2521141cc406Sopenharmony_ci case opt_fixed_constraint_word_list: 2522141cc406Sopenharmony_ci { 2523141cc406Sopenharmony_ci *(SANE_Fixed *) value = test_device->val[option].w; 2524141cc406Sopenharmony_ci DBG (4, 2525141cc406Sopenharmony_ci "sane_control_option: get option %d (%s), value=%.1f %s\n", 2526141cc406Sopenharmony_ci option, test_device->opt[option].name, 2527141cc406Sopenharmony_ci SANE_UNFIX (*(SANE_Fixed *) value), 2528141cc406Sopenharmony_ci test_device->opt[option].unit == 2529141cc406Sopenharmony_ci SANE_UNIT_MM ? "mm" : SANE_UNIT_DPI ? "dpi" : ""); 2530141cc406Sopenharmony_ci break; 2531141cc406Sopenharmony_ci } 2532141cc406Sopenharmony_ci case opt_hand_scanner: /* Bool options */ 2533141cc406Sopenharmony_ci case opt_three_pass: 2534141cc406Sopenharmony_ci case opt_invert_endianess: 2535141cc406Sopenharmony_ci case opt_read_limit: 2536141cc406Sopenharmony_ci case opt_read_delay: 2537141cc406Sopenharmony_ci case opt_fuzzy_parameters: 2538141cc406Sopenharmony_ci case opt_non_blocking: 2539141cc406Sopenharmony_ci case opt_select_fd: 2540141cc406Sopenharmony_ci case opt_bool_soft_select_soft_detect: 2541141cc406Sopenharmony_ci case opt_bool_hard_select_soft_detect: 2542141cc406Sopenharmony_ci case opt_bool_soft_detect: 2543141cc406Sopenharmony_ci case opt_enable_test_options: 2544141cc406Sopenharmony_ci case opt_bool_soft_select_soft_detect_emulated: 2545141cc406Sopenharmony_ci case opt_bool_soft_select_soft_detect_auto: 2546141cc406Sopenharmony_ci *(SANE_Bool *) value = test_device->val[option].w; 2547141cc406Sopenharmony_ci DBG (4, 2548141cc406Sopenharmony_ci "sane_control_option: get option %d (%s), value=%s\n", 2549141cc406Sopenharmony_ci option, test_device->opt[option].name, 2550141cc406Sopenharmony_ci *(SANE_Bool *) value == SANE_TRUE ? "true" : "false"); 2551141cc406Sopenharmony_ci break; 2552141cc406Sopenharmony_ci case opt_mode: /* String (list) options */ 2553141cc406Sopenharmony_ci case opt_three_pass_order: 2554141cc406Sopenharmony_ci case opt_read_status_code: 2555141cc406Sopenharmony_ci case opt_test_picture: 2556141cc406Sopenharmony_ci case opt_string: 2557141cc406Sopenharmony_ci case opt_string_constraint_string_list: 2558141cc406Sopenharmony_ci case opt_string_constraint_long_string_list: 2559141cc406Sopenharmony_ci case opt_scan_source: 2560141cc406Sopenharmony_ci strcpy (value, test_device->val[option].s); 2561141cc406Sopenharmony_ci DBG (4, "sane_control_option: get option %d (%s), value=`%s'\n", 2562141cc406Sopenharmony_ci option, test_device->opt[option].name, (SANE_String) value); 2563141cc406Sopenharmony_ci break; 2564141cc406Sopenharmony_ci case opt_depth: /* Int + word list options */ 2565141cc406Sopenharmony_ci case opt_read_limit_size: 2566141cc406Sopenharmony_ci case opt_ppl_loss: 2567141cc406Sopenharmony_ci case opt_read_delay_duration: 2568141cc406Sopenharmony_ci case opt_int: 2569141cc406Sopenharmony_ci case opt_int_inexact: 2570141cc406Sopenharmony_ci case opt_int_constraint_range: 2571141cc406Sopenharmony_ci case opt_int_constraint_word_list: 2572141cc406Sopenharmony_ci *(SANE_Int *) value = test_device->val[option].w; 2573141cc406Sopenharmony_ci DBG (4, "sane_control_option: get option %d (%s), value=%d\n", 2574141cc406Sopenharmony_ci option, test_device->opt[option].name, *(SANE_Int *) value); 2575141cc406Sopenharmony_ci break; 2576141cc406Sopenharmony_ci case opt_int_array: /* Int array */ 2577141cc406Sopenharmony_ci case opt_int_array_constraint_range: 2578141cc406Sopenharmony_ci case opt_gamma_red: 2579141cc406Sopenharmony_ci case opt_gamma_green: 2580141cc406Sopenharmony_ci case opt_gamma_blue: 2581141cc406Sopenharmony_ci case opt_gamma_all: 2582141cc406Sopenharmony_ci case opt_int_array_constraint_word_list: 2583141cc406Sopenharmony_ci memcpy (value, test_device->val[option].wa, 2584141cc406Sopenharmony_ci (size_t) test_device->opt[option].size); 2585141cc406Sopenharmony_ci DBG (4, "sane_control_option: get option %d (%s), value=%p\n", 2586141cc406Sopenharmony_ci option, test_device->opt[option].name, (void *) value); 2587141cc406Sopenharmony_ci break; 2588141cc406Sopenharmony_ci default: 2589141cc406Sopenharmony_ci DBG (1, "sane_control_option: trying to get unexpected option\n"); 2590141cc406Sopenharmony_ci return SANE_STATUS_INVAL; 2591141cc406Sopenharmony_ci } 2592141cc406Sopenharmony_ci break; 2593141cc406Sopenharmony_ci default: 2594141cc406Sopenharmony_ci DBG (1, "sane_control_option: trying unexpected action %d\n", action); 2595141cc406Sopenharmony_ci return SANE_STATUS_INVAL; 2596141cc406Sopenharmony_ci } 2597141cc406Sopenharmony_ci 2598141cc406Sopenharmony_ci if (info) 2599141cc406Sopenharmony_ci *info = myinfo; 2600141cc406Sopenharmony_ci 2601141cc406Sopenharmony_ci if(myinfo & SANE_INFO_RELOAD_OPTIONS){ 2602141cc406Sopenharmony_ci SANE_Int i = 0; 2603141cc406Sopenharmony_ci for(i=1;i<num_options;i++){ 2604141cc406Sopenharmony_ci test_device->loaded[i] = 0; 2605141cc406Sopenharmony_ci } 2606141cc406Sopenharmony_ci } 2607141cc406Sopenharmony_ci 2608141cc406Sopenharmony_ci DBG (4, "sane_control_option: finished, info=%s %s %s \n", 2609141cc406Sopenharmony_ci myinfo & SANE_INFO_INEXACT ? "inexact" : "", 2610141cc406Sopenharmony_ci myinfo & SANE_INFO_RELOAD_PARAMS ? "reload_parameters" : "", 2611141cc406Sopenharmony_ci myinfo & SANE_INFO_RELOAD_OPTIONS ? "reload_options" : ""); 2612141cc406Sopenharmony_ci 2613141cc406Sopenharmony_ci return SANE_STATUS_GOOD; 2614141cc406Sopenharmony_ci} 2615141cc406Sopenharmony_ci 2616141cc406Sopenharmony_ci 2617141cc406Sopenharmony_ciSANE_Status 2618141cc406Sopenharmony_cisane_get_parameters (SANE_Handle handle, SANE_Parameters * params) 2619141cc406Sopenharmony_ci{ 2620141cc406Sopenharmony_ci Test_Device *test_device = handle; 2621141cc406Sopenharmony_ci SANE_Parameters *p; 2622141cc406Sopenharmony_ci double res, tl_x = 0, tl_y = 0, br_x = 0, br_y = 0; 2623141cc406Sopenharmony_ci SANE_String text_format, mode; 2624141cc406Sopenharmony_ci SANE_Int channels = 1; 2625141cc406Sopenharmony_ci 2626141cc406Sopenharmony_ci DBG (2, "sane_get_parameters: handle=%p, params=%p\n", 2627141cc406Sopenharmony_ci (void *) handle, (void *) params); 2628141cc406Sopenharmony_ci if (!inited) 2629141cc406Sopenharmony_ci { 2630141cc406Sopenharmony_ci DBG (1, "sane_get_parameters: not inited, call sane_init() first\n"); 2631141cc406Sopenharmony_ci return SANE_STATUS_INVAL; 2632141cc406Sopenharmony_ci } 2633141cc406Sopenharmony_ci if (!check_handle (handle)) 2634141cc406Sopenharmony_ci { 2635141cc406Sopenharmony_ci DBG (1, "sane_get_parameters: handle %p unknown\n", (void *) handle); 2636141cc406Sopenharmony_ci return SANE_STATUS_INVAL; 2637141cc406Sopenharmony_ci } 2638141cc406Sopenharmony_ci if (!test_device->open) 2639141cc406Sopenharmony_ci { 2640141cc406Sopenharmony_ci DBG (1, "sane_get_parameters: handle %p not open\n", (void *) handle); 2641141cc406Sopenharmony_ci return SANE_STATUS_INVAL; 2642141cc406Sopenharmony_ci } 2643141cc406Sopenharmony_ci 2644141cc406Sopenharmony_ci res = SANE_UNFIX (test_device->val[opt_resolution].w); 2645141cc406Sopenharmony_ci mode = test_device->val[opt_mode].s; 2646141cc406Sopenharmony_ci p = &test_device->params; 2647141cc406Sopenharmony_ci p->depth = test_device->val[opt_depth].w; 2648141cc406Sopenharmony_ci 2649141cc406Sopenharmony_ci if (test_device->val[opt_hand_scanner].w == SANE_TRUE) 2650141cc406Sopenharmony_ci { 2651141cc406Sopenharmony_ci tl_x = 0.0; 2652141cc406Sopenharmony_ci br_x = 110.0; 2653141cc406Sopenharmony_ci tl_y = 0.0; 2654141cc406Sopenharmony_ci br_y = 170.0; 2655141cc406Sopenharmony_ci p->lines = -1; 2656141cc406Sopenharmony_ci test_device->lines = (SANE_Word) (res * (br_y - tl_y) / MM_PER_INCH); 2657141cc406Sopenharmony_ci } 2658141cc406Sopenharmony_ci else 2659141cc406Sopenharmony_ci { 2660141cc406Sopenharmony_ci tl_x = SANE_UNFIX (test_device->val[opt_tl_x].w); 2661141cc406Sopenharmony_ci tl_y = SANE_UNFIX (test_device->val[opt_tl_y].w); 2662141cc406Sopenharmony_ci br_x = SANE_UNFIX (test_device->val[opt_br_x].w); 2663141cc406Sopenharmony_ci br_y = SANE_UNFIX (test_device->val[opt_br_y].w); 2664141cc406Sopenharmony_ci if (tl_x > br_x) 2665141cc406Sopenharmony_ci swap_double (&tl_x, &br_x); 2666141cc406Sopenharmony_ci if (tl_y > br_y) 2667141cc406Sopenharmony_ci swap_double (&tl_y, &br_y); 2668141cc406Sopenharmony_ci test_device->lines = (SANE_Word) (res * (br_y - tl_y) / MM_PER_INCH); 2669141cc406Sopenharmony_ci if (test_device->lines < 1) 2670141cc406Sopenharmony_ci test_device->lines = 1; 2671141cc406Sopenharmony_ci p->lines = test_device->lines; 2672141cc406Sopenharmony_ci if (test_device->val[opt_fuzzy_parameters].w == SANE_TRUE 2673141cc406Sopenharmony_ci && test_device->scanning == SANE_FALSE) 2674141cc406Sopenharmony_ci p->lines *= (SANE_Int) random_factor; 2675141cc406Sopenharmony_ci } 2676141cc406Sopenharmony_ci 2677141cc406Sopenharmony_ci if (strcmp (mode, SANE_VALUE_SCAN_MODE_GRAY) == 0) 2678141cc406Sopenharmony_ci { 2679141cc406Sopenharmony_ci p->format = SANE_FRAME_GRAY; 2680141cc406Sopenharmony_ci p->last_frame = SANE_TRUE; 2681141cc406Sopenharmony_ci } 2682141cc406Sopenharmony_ci else /* Color */ 2683141cc406Sopenharmony_ci { 2684141cc406Sopenharmony_ci if (test_device->val[opt_three_pass].w == SANE_TRUE) 2685141cc406Sopenharmony_ci { 2686141cc406Sopenharmony_ci if (test_device->val[opt_three_pass_order].s[test_device->pass] 2687141cc406Sopenharmony_ci == 'R') 2688141cc406Sopenharmony_ci p->format = SANE_FRAME_RED; 2689141cc406Sopenharmony_ci else if (test_device->val[opt_three_pass_order].s[test_device->pass] 2690141cc406Sopenharmony_ci == 'G') 2691141cc406Sopenharmony_ci p->format = SANE_FRAME_GREEN; 2692141cc406Sopenharmony_ci else 2693141cc406Sopenharmony_ci p->format = SANE_FRAME_BLUE; 2694141cc406Sopenharmony_ci if (test_device->pass > 1) 2695141cc406Sopenharmony_ci p->last_frame = SANE_TRUE; 2696141cc406Sopenharmony_ci else 2697141cc406Sopenharmony_ci p->last_frame = SANE_FALSE; 2698141cc406Sopenharmony_ci } 2699141cc406Sopenharmony_ci else 2700141cc406Sopenharmony_ci { 2701141cc406Sopenharmony_ci p->format = SANE_FRAME_RGB; 2702141cc406Sopenharmony_ci p->last_frame = SANE_TRUE; 2703141cc406Sopenharmony_ci } 2704141cc406Sopenharmony_ci } 2705141cc406Sopenharmony_ci 2706141cc406Sopenharmony_ci p->pixels_per_line = (SANE_Int) (res * (br_x - tl_x) / MM_PER_INCH); 2707141cc406Sopenharmony_ci if (test_device->val[opt_fuzzy_parameters].w == SANE_TRUE 2708141cc406Sopenharmony_ci && test_device->scanning == SANE_FALSE) 2709141cc406Sopenharmony_ci p->pixels_per_line *= (SANE_Int) random_factor; 2710141cc406Sopenharmony_ci if (p->pixels_per_line < 1) 2711141cc406Sopenharmony_ci p->pixels_per_line = 1; 2712141cc406Sopenharmony_ci 2713141cc406Sopenharmony_ci if (p->format == SANE_FRAME_RGB) 2714141cc406Sopenharmony_ci channels = 3; 2715141cc406Sopenharmony_ci 2716141cc406Sopenharmony_ci if (p->depth == 1) 2717141cc406Sopenharmony_ci p->bytes_per_line = channels * (int) ((p->pixels_per_line + 7) / 8); 2718141cc406Sopenharmony_ci else /* depth == 8 || depth == 16 */ 2719141cc406Sopenharmony_ci p->bytes_per_line = channels * p->pixels_per_line * ((p->depth + 7) / 8); 2720141cc406Sopenharmony_ci 2721141cc406Sopenharmony_ci test_device->bytes_per_line = p->bytes_per_line; 2722141cc406Sopenharmony_ci 2723141cc406Sopenharmony_ci p->pixels_per_line -= test_device->val[opt_ppl_loss].w; 2724141cc406Sopenharmony_ci if (p->pixels_per_line < 1) 2725141cc406Sopenharmony_ci p->pixels_per_line = 1; 2726141cc406Sopenharmony_ci test_device->pixels_per_line = p->pixels_per_line; 2727141cc406Sopenharmony_ci 2728141cc406Sopenharmony_ci switch (p->format) 2729141cc406Sopenharmony_ci { 2730141cc406Sopenharmony_ci case SANE_FRAME_GRAY: 2731141cc406Sopenharmony_ci text_format = "gray"; 2732141cc406Sopenharmony_ci break; 2733141cc406Sopenharmony_ci case SANE_FRAME_RGB: 2734141cc406Sopenharmony_ci text_format = "rgb"; 2735141cc406Sopenharmony_ci break; 2736141cc406Sopenharmony_ci case SANE_FRAME_RED: 2737141cc406Sopenharmony_ci text_format = "red"; 2738141cc406Sopenharmony_ci break; 2739141cc406Sopenharmony_ci case SANE_FRAME_GREEN: 2740141cc406Sopenharmony_ci text_format = "green"; 2741141cc406Sopenharmony_ci break; 2742141cc406Sopenharmony_ci case SANE_FRAME_BLUE: 2743141cc406Sopenharmony_ci text_format = "blue"; 2744141cc406Sopenharmony_ci break; 2745141cc406Sopenharmony_ci default: 2746141cc406Sopenharmony_ci text_format = "unknown"; 2747141cc406Sopenharmony_ci break; 2748141cc406Sopenharmony_ci } 2749141cc406Sopenharmony_ci 2750141cc406Sopenharmony_ci DBG (3, "sane_get_parameters: format=%s\n", text_format); 2751141cc406Sopenharmony_ci DBG (3, "sane_get_parameters: last_frame=%s\n", 2752141cc406Sopenharmony_ci p->last_frame ? "true" : "false"); 2753141cc406Sopenharmony_ci DBG (3, "sane_get_parameters: lines=%d\n", p->lines); 2754141cc406Sopenharmony_ci DBG (3, "sane_get_parameters: depth=%d\n", p->depth); 2755141cc406Sopenharmony_ci DBG (3, "sane_get_parameters: pixels_per_line=%d\n", p->pixels_per_line); 2756141cc406Sopenharmony_ci DBG (3, "sane_get_parameters: bytes_per_line=%d\n", p->bytes_per_line); 2757141cc406Sopenharmony_ci 2758141cc406Sopenharmony_ci if (params) 2759141cc406Sopenharmony_ci *params = *p; 2760141cc406Sopenharmony_ci 2761141cc406Sopenharmony_ci return SANE_STATUS_GOOD; 2762141cc406Sopenharmony_ci} 2763141cc406Sopenharmony_ci 2764141cc406Sopenharmony_ciSANE_Status 2765141cc406Sopenharmony_cisane_start (SANE_Handle handle) 2766141cc406Sopenharmony_ci{ 2767141cc406Sopenharmony_ci Test_Device *test_device = handle; 2768141cc406Sopenharmony_ci int pipe_descriptor[2]; 2769141cc406Sopenharmony_ci 2770141cc406Sopenharmony_ci DBG (2, "sane_start: handle=%p\n", handle); 2771141cc406Sopenharmony_ci if (!inited) 2772141cc406Sopenharmony_ci { 2773141cc406Sopenharmony_ci DBG (1, "sane_start: not inited, call sane_init() first\n"); 2774141cc406Sopenharmony_ci return SANE_STATUS_INVAL; 2775141cc406Sopenharmony_ci } 2776141cc406Sopenharmony_ci if (!check_handle (handle)) 2777141cc406Sopenharmony_ci { 2778141cc406Sopenharmony_ci DBG (1, "sane_start: handle %p unknown\n", handle); 2779141cc406Sopenharmony_ci return SANE_STATUS_INVAL; 2780141cc406Sopenharmony_ci } 2781141cc406Sopenharmony_ci if (!test_device->open) 2782141cc406Sopenharmony_ci { 2783141cc406Sopenharmony_ci DBG (1, "sane_start: not open\n"); 2784141cc406Sopenharmony_ci return SANE_STATUS_INVAL; 2785141cc406Sopenharmony_ci } 2786141cc406Sopenharmony_ci if (test_device->scanning 2787141cc406Sopenharmony_ci && (test_device->val[opt_three_pass].w == SANE_FALSE 2788141cc406Sopenharmony_ci && strcmp (test_device->val[opt_mode].s, SANE_VALUE_SCAN_MODE_COLOR) == 0)) 2789141cc406Sopenharmony_ci { 2790141cc406Sopenharmony_ci DBG (1, "sane_start: already scanning\n"); 2791141cc406Sopenharmony_ci return SANE_STATUS_INVAL; 2792141cc406Sopenharmony_ci } 2793141cc406Sopenharmony_ci if (strcmp (test_device->val[opt_mode].s, SANE_VALUE_SCAN_MODE_COLOR) == 0 2794141cc406Sopenharmony_ci && test_device->val[opt_three_pass].w == SANE_TRUE 2795141cc406Sopenharmony_ci && test_device->pass > 2) 2796141cc406Sopenharmony_ci { 2797141cc406Sopenharmony_ci DBG (1, "sane_start: already in last pass of three\n"); 2798141cc406Sopenharmony_ci return SANE_STATUS_INVAL; 2799141cc406Sopenharmony_ci } 2800141cc406Sopenharmony_ci 2801141cc406Sopenharmony_ci if (test_device->pass == 0) 2802141cc406Sopenharmony_ci { 2803141cc406Sopenharmony_ci test_device->number_of_scans++; 2804141cc406Sopenharmony_ci DBG (3, "sane_start: scanning page %d\n", test_device->number_of_scans); 2805141cc406Sopenharmony_ci 2806141cc406Sopenharmony_ci if ((strcmp (test_device->val[opt_scan_source].s, "Automatic Document Feeder") == 0) && 2807141cc406Sopenharmony_ci (((test_device->number_of_scans) % 11) == 0)) 2808141cc406Sopenharmony_ci { 2809141cc406Sopenharmony_ci DBG (1, "sane_start: Document feeder is out of documents!\n"); 2810141cc406Sopenharmony_ci return SANE_STATUS_NO_DOCS; 2811141cc406Sopenharmony_ci } 2812141cc406Sopenharmony_ci } 2813141cc406Sopenharmony_ci 2814141cc406Sopenharmony_ci test_device->scanning = SANE_TRUE; 2815141cc406Sopenharmony_ci test_device->cancelled = SANE_FALSE; 2816141cc406Sopenharmony_ci test_device->eof = SANE_FALSE; 2817141cc406Sopenharmony_ci test_device->bytes_total = 0; 2818141cc406Sopenharmony_ci 2819141cc406Sopenharmony_ci sane_get_parameters (handle, 0); 2820141cc406Sopenharmony_ci 2821141cc406Sopenharmony_ci if (test_device->params.lines == 0) 2822141cc406Sopenharmony_ci { 2823141cc406Sopenharmony_ci DBG (1, "sane_start: lines == 0\n"); 2824141cc406Sopenharmony_ci test_device->scanning = SANE_FALSE; 2825141cc406Sopenharmony_ci return SANE_STATUS_INVAL; 2826141cc406Sopenharmony_ci } 2827141cc406Sopenharmony_ci if (test_device->params.pixels_per_line == 0) 2828141cc406Sopenharmony_ci { 2829141cc406Sopenharmony_ci DBG (1, "sane_start: pixels_per_line == 0\n"); 2830141cc406Sopenharmony_ci test_device->scanning = SANE_FALSE; 2831141cc406Sopenharmony_ci return SANE_STATUS_INVAL; 2832141cc406Sopenharmony_ci } 2833141cc406Sopenharmony_ci if (test_device->params.bytes_per_line == 0) 2834141cc406Sopenharmony_ci { 2835141cc406Sopenharmony_ci DBG (1, "sane_start: bytes_per_line == 0\n"); 2836141cc406Sopenharmony_ci test_device->scanning = SANE_FALSE; 2837141cc406Sopenharmony_ci return SANE_STATUS_INVAL; 2838141cc406Sopenharmony_ci } 2839141cc406Sopenharmony_ci 2840141cc406Sopenharmony_ci if (pipe (pipe_descriptor) < 0) 2841141cc406Sopenharmony_ci { 2842141cc406Sopenharmony_ci DBG (1, "sane_start: pipe failed (%s)\n", strerror (errno)); 2843141cc406Sopenharmony_ci return SANE_STATUS_IO_ERROR; 2844141cc406Sopenharmony_ci } 2845141cc406Sopenharmony_ci 2846141cc406Sopenharmony_ci /* create reader routine as new process or thread */ 2847141cc406Sopenharmony_ci test_device->pipe = pipe_descriptor[0]; 2848141cc406Sopenharmony_ci test_device->reader_fds = pipe_descriptor[1]; 2849141cc406Sopenharmony_ci test_device->reader_pid = 2850141cc406Sopenharmony_ci sanei_thread_begin (reader_task, (void *) test_device); 2851141cc406Sopenharmony_ci 2852141cc406Sopenharmony_ci if (!sanei_thread_is_valid (test_device->reader_pid)) 2853141cc406Sopenharmony_ci { 2854141cc406Sopenharmony_ci DBG (1, "sane_start: sanei_thread_begin failed (%s)\n", 2855141cc406Sopenharmony_ci strerror (errno)); 2856141cc406Sopenharmony_ci return SANE_STATUS_NO_MEM; 2857141cc406Sopenharmony_ci } 2858141cc406Sopenharmony_ci 2859141cc406Sopenharmony_ci if (sanei_thread_is_forked ()) 2860141cc406Sopenharmony_ci { 2861141cc406Sopenharmony_ci close (test_device->reader_fds); 2862141cc406Sopenharmony_ci test_device->reader_fds = -1; 2863141cc406Sopenharmony_ci } 2864141cc406Sopenharmony_ci 2865141cc406Sopenharmony_ci return SANE_STATUS_GOOD; 2866141cc406Sopenharmony_ci} 2867141cc406Sopenharmony_ci 2868141cc406Sopenharmony_ci 2869141cc406Sopenharmony_ciSANE_Status 2870141cc406Sopenharmony_cisane_read (SANE_Handle handle, SANE_Byte * data, 2871141cc406Sopenharmony_ci SANE_Int max_length, SANE_Int * length) 2872141cc406Sopenharmony_ci{ 2873141cc406Sopenharmony_ci Test_Device *test_device = handle; 2874141cc406Sopenharmony_ci SANE_Int max_scan_length; 2875141cc406Sopenharmony_ci ssize_t bytes_read; 2876141cc406Sopenharmony_ci size_t read_count; 2877141cc406Sopenharmony_ci size_t bytes_total = (size_t) test_device->lines * (size_t) test_device->bytes_per_line; 2878141cc406Sopenharmony_ci 2879141cc406Sopenharmony_ci 2880141cc406Sopenharmony_ci DBG (4, "sane_read: handle=%p, data=%p, max_length = %d, length=%p\n", 2881141cc406Sopenharmony_ci handle, (void *) data, max_length, (void *) length); 2882141cc406Sopenharmony_ci if (!inited) 2883141cc406Sopenharmony_ci { 2884141cc406Sopenharmony_ci DBG (1, "sane_read: not inited, call sane_init() first\n"); 2885141cc406Sopenharmony_ci return SANE_STATUS_INVAL; 2886141cc406Sopenharmony_ci } 2887141cc406Sopenharmony_ci if (!check_handle (handle)) 2888141cc406Sopenharmony_ci { 2889141cc406Sopenharmony_ci DBG (1, "sane_read: handle %p unknown\n", handle); 2890141cc406Sopenharmony_ci return SANE_STATUS_INVAL; 2891141cc406Sopenharmony_ci } 2892141cc406Sopenharmony_ci if (!length) 2893141cc406Sopenharmony_ci { 2894141cc406Sopenharmony_ci DBG (1, "sane_read: length == NULL\n"); 2895141cc406Sopenharmony_ci return SANE_STATUS_INVAL; 2896141cc406Sopenharmony_ci } 2897141cc406Sopenharmony_ci 2898141cc406Sopenharmony_ci if (strcmp (test_device->val[opt_read_status_code].s, "Default") != 0) 2899141cc406Sopenharmony_ci { 2900141cc406Sopenharmony_ci SANE_String_Const sc = test_device->val[opt_read_status_code].s; 2901141cc406Sopenharmony_ci DBG (3, "sane_read: setting return status to %s\n", sc); 2902141cc406Sopenharmony_ci if (strcmp (sc, "SANE_STATUS_UNSUPPORTED") == 0) 2903141cc406Sopenharmony_ci return SANE_STATUS_UNSUPPORTED; 2904141cc406Sopenharmony_ci if (strcmp (sc, "SANE_STATUS_CANCELLED") == 0) 2905141cc406Sopenharmony_ci return SANE_STATUS_CANCELLED; 2906141cc406Sopenharmony_ci if (strcmp (sc, "SANE_STATUS_DEVICE_BUSY") == 0) 2907141cc406Sopenharmony_ci return SANE_STATUS_DEVICE_BUSY; 2908141cc406Sopenharmony_ci if (strcmp (sc, "SANE_STATUS_INVAL") == 0) 2909141cc406Sopenharmony_ci return SANE_STATUS_INVAL; 2910141cc406Sopenharmony_ci if (strcmp (sc, "SANE_STATUS_EOF") == 0) 2911141cc406Sopenharmony_ci return SANE_STATUS_EOF; 2912141cc406Sopenharmony_ci if (strcmp (sc, "SANE_STATUS_JAMMED") == 0) 2913141cc406Sopenharmony_ci return SANE_STATUS_JAMMED; 2914141cc406Sopenharmony_ci if (strcmp (sc, "SANE_STATUS_NO_DOCS") == 0) 2915141cc406Sopenharmony_ci return SANE_STATUS_NO_DOCS; 2916141cc406Sopenharmony_ci if (strcmp (sc, "SANE_STATUS_COVER_OPEN") == 0) 2917141cc406Sopenharmony_ci return SANE_STATUS_COVER_OPEN; 2918141cc406Sopenharmony_ci if (strcmp (sc, "SANE_STATUS_IO_ERROR") == 0) 2919141cc406Sopenharmony_ci return SANE_STATUS_IO_ERROR; 2920141cc406Sopenharmony_ci if (strcmp (sc, "SANE_STATUS_NO_MEM") == 0) 2921141cc406Sopenharmony_ci return SANE_STATUS_NO_MEM; 2922141cc406Sopenharmony_ci if (strcmp (sc, "SANE_STATUS_ACCESS_DENIED") == 0) 2923141cc406Sopenharmony_ci return SANE_STATUS_ACCESS_DENIED; 2924141cc406Sopenharmony_ci } 2925141cc406Sopenharmony_ci 2926141cc406Sopenharmony_ci max_scan_length = max_length; 2927141cc406Sopenharmony_ci if (test_device->val[opt_read_limit].w == SANE_TRUE 2928141cc406Sopenharmony_ci && test_device->val[opt_read_limit_size].w < max_scan_length) 2929141cc406Sopenharmony_ci { 2930141cc406Sopenharmony_ci max_scan_length = test_device->val[opt_read_limit_size].w; 2931141cc406Sopenharmony_ci DBG (3, "sane_read: limiting max_scan_length to %d bytes\n", 2932141cc406Sopenharmony_ci max_scan_length); 2933141cc406Sopenharmony_ci } 2934141cc406Sopenharmony_ci 2935141cc406Sopenharmony_ci *length = 0; 2936141cc406Sopenharmony_ci 2937141cc406Sopenharmony_ci if (!data) 2938141cc406Sopenharmony_ci { 2939141cc406Sopenharmony_ci DBG (1, "sane_read: data == NULL\n"); 2940141cc406Sopenharmony_ci return SANE_STATUS_INVAL; 2941141cc406Sopenharmony_ci } 2942141cc406Sopenharmony_ci if (!test_device->open) 2943141cc406Sopenharmony_ci { 2944141cc406Sopenharmony_ci DBG (1, "sane_read: not open\n"); 2945141cc406Sopenharmony_ci return SANE_STATUS_INVAL; 2946141cc406Sopenharmony_ci } 2947141cc406Sopenharmony_ci if (test_device->cancelled) 2948141cc406Sopenharmony_ci { 2949141cc406Sopenharmony_ci DBG (1, "sane_read: scan was cancelled\n"); 2950141cc406Sopenharmony_ci return SANE_STATUS_CANCELLED; 2951141cc406Sopenharmony_ci } 2952141cc406Sopenharmony_ci if (test_device->eof) 2953141cc406Sopenharmony_ci { 2954141cc406Sopenharmony_ci DBG (2, "sane_read: No more data available, sending EOF\n"); 2955141cc406Sopenharmony_ci return SANE_STATUS_EOF; 2956141cc406Sopenharmony_ci } 2957141cc406Sopenharmony_ci if (!test_device->scanning) 2958141cc406Sopenharmony_ci { 2959141cc406Sopenharmony_ci DBG (1, "sane_read: not scanning (call sane_start first)\n"); 2960141cc406Sopenharmony_ci return SANE_STATUS_INVAL; 2961141cc406Sopenharmony_ci } 2962141cc406Sopenharmony_ci read_count = (size_t) max_scan_length; 2963141cc406Sopenharmony_ci 2964141cc406Sopenharmony_ci bytes_read = read (test_device->pipe, data, read_count); 2965141cc406Sopenharmony_ci if (bytes_read == 0 2966141cc406Sopenharmony_ci || ((size_t) bytes_read + (size_t) test_device->bytes_total >= bytes_total)) 2967141cc406Sopenharmony_ci { 2968141cc406Sopenharmony_ci SANE_Status status; 2969141cc406Sopenharmony_ci DBG (2, "sane_read: EOF reached\n"); 2970141cc406Sopenharmony_ci status = finish_pass (test_device); 2971141cc406Sopenharmony_ci if (status != SANE_STATUS_GOOD) 2972141cc406Sopenharmony_ci { 2973141cc406Sopenharmony_ci DBG (1, "sane_read: finish_pass returned `%s'\n", 2974141cc406Sopenharmony_ci sane_strstatus (status)); 2975141cc406Sopenharmony_ci return status; 2976141cc406Sopenharmony_ci } 2977141cc406Sopenharmony_ci test_device->eof = SANE_TRUE; 2978141cc406Sopenharmony_ci if (strcmp (test_device->val[opt_mode].s, SANE_VALUE_SCAN_MODE_COLOR) == 0 2979141cc406Sopenharmony_ci && test_device->val[opt_three_pass].w == SANE_TRUE) 2980141cc406Sopenharmony_ci { 2981141cc406Sopenharmony_ci test_device->pass++; 2982141cc406Sopenharmony_ci if (test_device->pass > 2) 2983141cc406Sopenharmony_ci test_device->pass = 0; 2984141cc406Sopenharmony_ci } 2985141cc406Sopenharmony_ci if (bytes_read == 0) 2986141cc406Sopenharmony_ci return SANE_STATUS_EOF; 2987141cc406Sopenharmony_ci } 2988141cc406Sopenharmony_ci else if (bytes_read < 0) 2989141cc406Sopenharmony_ci { 2990141cc406Sopenharmony_ci if (errno == EAGAIN) 2991141cc406Sopenharmony_ci { 2992141cc406Sopenharmony_ci DBG (2, "sane_read: no data available, try again\n"); 2993141cc406Sopenharmony_ci return SANE_STATUS_GOOD; 2994141cc406Sopenharmony_ci } 2995141cc406Sopenharmony_ci else 2996141cc406Sopenharmony_ci { 2997141cc406Sopenharmony_ci DBG (1, "sane_read: read returned error: %s\n", strerror (errno)); 2998141cc406Sopenharmony_ci return SANE_STATUS_IO_ERROR; 2999141cc406Sopenharmony_ci } 3000141cc406Sopenharmony_ci } 3001141cc406Sopenharmony_ci *length = (SANE_Int) bytes_read; 3002141cc406Sopenharmony_ci test_device->bytes_total += (size_t) bytes_read; 3003141cc406Sopenharmony_ci 3004141cc406Sopenharmony_ci DBG (2, "sane_read: read %zu bytes of %zu, total %zu\n", (size_t) bytes_read, 3005141cc406Sopenharmony_ci (size_t) max_scan_length, (size_t) test_device->bytes_total); 3006141cc406Sopenharmony_ci return SANE_STATUS_GOOD; 3007141cc406Sopenharmony_ci} 3008141cc406Sopenharmony_ci 3009141cc406Sopenharmony_civoid 3010141cc406Sopenharmony_cisane_cancel (SANE_Handle handle) 3011141cc406Sopenharmony_ci{ 3012141cc406Sopenharmony_ci Test_Device *test_device = handle; 3013141cc406Sopenharmony_ci 3014141cc406Sopenharmony_ci DBG (2, "sane_cancel: handle = %p\n", handle); 3015141cc406Sopenharmony_ci if (!inited) 3016141cc406Sopenharmony_ci { 3017141cc406Sopenharmony_ci DBG (1, "sane_cancel: not inited, call sane_init() first\n"); 3018141cc406Sopenharmony_ci return; 3019141cc406Sopenharmony_ci } 3020141cc406Sopenharmony_ci if (!check_handle (handle)) 3021141cc406Sopenharmony_ci { 3022141cc406Sopenharmony_ci DBG (1, "sane_cancel: handle %p unknown\n", handle); 3023141cc406Sopenharmony_ci return; 3024141cc406Sopenharmony_ci } 3025141cc406Sopenharmony_ci if (!test_device->open) 3026141cc406Sopenharmony_ci { 3027141cc406Sopenharmony_ci DBG (1, "sane_cancel: not open\n"); 3028141cc406Sopenharmony_ci return; 3029141cc406Sopenharmony_ci } 3030141cc406Sopenharmony_ci if (test_device->cancelled) 3031141cc406Sopenharmony_ci { 3032141cc406Sopenharmony_ci DBG (1, "sane_cancel: scan already cancelled\n"); 3033141cc406Sopenharmony_ci return; 3034141cc406Sopenharmony_ci } 3035141cc406Sopenharmony_ci if (!test_device->scanning) 3036141cc406Sopenharmony_ci { 3037141cc406Sopenharmony_ci DBG (2, "sane_cancel: scan is already finished\n"); 3038141cc406Sopenharmony_ci return; 3039141cc406Sopenharmony_ci } 3040141cc406Sopenharmony_ci finish_pass (test_device); 3041141cc406Sopenharmony_ci test_device->cancelled = SANE_TRUE; 3042141cc406Sopenharmony_ci test_device->scanning = SANE_FALSE; 3043141cc406Sopenharmony_ci test_device->eof = SANE_FALSE; 3044141cc406Sopenharmony_ci test_device->pass = 0; 3045141cc406Sopenharmony_ci return; 3046141cc406Sopenharmony_ci} 3047141cc406Sopenharmony_ci 3048141cc406Sopenharmony_ciSANE_Status 3049141cc406Sopenharmony_cisane_set_io_mode (SANE_Handle handle, SANE_Bool non_blocking) 3050141cc406Sopenharmony_ci{ 3051141cc406Sopenharmony_ci Test_Device *test_device = handle; 3052141cc406Sopenharmony_ci 3053141cc406Sopenharmony_ci DBG (2, "sane_set_io_mode: handle = %p, non_blocking = %d\n", handle, 3054141cc406Sopenharmony_ci non_blocking); 3055141cc406Sopenharmony_ci if (!inited) 3056141cc406Sopenharmony_ci { 3057141cc406Sopenharmony_ci DBG (1, "sane_set_io_mode: not inited, call sane_init() first\n"); 3058141cc406Sopenharmony_ci return SANE_STATUS_INVAL; 3059141cc406Sopenharmony_ci } 3060141cc406Sopenharmony_ci if (!check_handle (handle)) 3061141cc406Sopenharmony_ci { 3062141cc406Sopenharmony_ci DBG (1, "sane_set_io_mode: handle %p unknown\n", handle); 3063141cc406Sopenharmony_ci return SANE_STATUS_INVAL; 3064141cc406Sopenharmony_ci } 3065141cc406Sopenharmony_ci if (!test_device->open) 3066141cc406Sopenharmony_ci { 3067141cc406Sopenharmony_ci DBG (1, "sane_set_io_mode: not open\n"); 3068141cc406Sopenharmony_ci return SANE_STATUS_INVAL; 3069141cc406Sopenharmony_ci } 3070141cc406Sopenharmony_ci if (!test_device->scanning) 3071141cc406Sopenharmony_ci { 3072141cc406Sopenharmony_ci DBG (1, "sane_set_io_mode: not scanning\n"); 3073141cc406Sopenharmony_ci return SANE_STATUS_INVAL; 3074141cc406Sopenharmony_ci } 3075141cc406Sopenharmony_ci if (test_device->val[opt_non_blocking].w == SANE_TRUE) 3076141cc406Sopenharmony_ci { 3077141cc406Sopenharmony_ci if (fcntl (test_device->pipe, 3078141cc406Sopenharmony_ci F_SETFL, non_blocking ? O_NONBLOCK : 0) < 0) 3079141cc406Sopenharmony_ci { 3080141cc406Sopenharmony_ci DBG (1, "sane_set_io_mode: can't set io mode"); 3081141cc406Sopenharmony_ci return SANE_STATUS_INVAL; 3082141cc406Sopenharmony_ci } 3083141cc406Sopenharmony_ci } 3084141cc406Sopenharmony_ci else 3085141cc406Sopenharmony_ci { 3086141cc406Sopenharmony_ci DBG (1, "sane_set_io_mode: unsupported\n"); 3087141cc406Sopenharmony_ci if (non_blocking) 3088141cc406Sopenharmony_ci return SANE_STATUS_UNSUPPORTED; 3089141cc406Sopenharmony_ci } 3090141cc406Sopenharmony_ci return SANE_STATUS_GOOD; 3091141cc406Sopenharmony_ci} 3092141cc406Sopenharmony_ci 3093141cc406Sopenharmony_ciSANE_Status 3094141cc406Sopenharmony_cisane_get_select_fd (SANE_Handle handle, SANE_Int * fd) 3095141cc406Sopenharmony_ci{ 3096141cc406Sopenharmony_ci Test_Device *test_device = handle; 3097141cc406Sopenharmony_ci 3098141cc406Sopenharmony_ci DBG (2, "sane_get_select_fd: handle = %p, fd %s 0\n", handle, 3099141cc406Sopenharmony_ci fd ? "!=" : "="); 3100141cc406Sopenharmony_ci if (!inited) 3101141cc406Sopenharmony_ci { 3102141cc406Sopenharmony_ci DBG (1, "sane_get_select_fd: not inited, call sane_init() first\n"); 3103141cc406Sopenharmony_ci return SANE_STATUS_INVAL; 3104141cc406Sopenharmony_ci } 3105141cc406Sopenharmony_ci if (!check_handle (handle)) 3106141cc406Sopenharmony_ci { 3107141cc406Sopenharmony_ci DBG (1, "sane_get_select_fd: handle %p unknown\n", handle); 3108141cc406Sopenharmony_ci return SANE_STATUS_INVAL; 3109141cc406Sopenharmony_ci } 3110141cc406Sopenharmony_ci if (!test_device->open) 3111141cc406Sopenharmony_ci { 3112141cc406Sopenharmony_ci DBG (1, "sane_get_select_fd: not open\n"); 3113141cc406Sopenharmony_ci return SANE_STATUS_INVAL; 3114141cc406Sopenharmony_ci } 3115141cc406Sopenharmony_ci if (!test_device->scanning) 3116141cc406Sopenharmony_ci { 3117141cc406Sopenharmony_ci DBG (1, "sane_get_select_fd: not scanning\n"); 3118141cc406Sopenharmony_ci return SANE_STATUS_INVAL; 3119141cc406Sopenharmony_ci } 3120141cc406Sopenharmony_ci if (test_device->val[opt_select_fd].w == SANE_TRUE) 3121141cc406Sopenharmony_ci { 3122141cc406Sopenharmony_ci *fd = test_device->pipe; 3123141cc406Sopenharmony_ci return SANE_STATUS_GOOD; 3124141cc406Sopenharmony_ci } 3125141cc406Sopenharmony_ci DBG(1,"sane_get_select_fd: unsupported\n"); 3126141cc406Sopenharmony_ci return SANE_STATUS_UNSUPPORTED; 3127141cc406Sopenharmony_ci} 3128