1141cc406Sopenharmony_ci/* sane - Scanner Access Now Easy. 2141cc406Sopenharmony_ci 3141cc406Sopenharmony_ci Copyright (C) 2000-2001 Kazuya Fukuda, based on sharp.c, which is 4141cc406Sopenharmony_ci based on canon.c. 5141cc406Sopenharmony_ci 6141cc406Sopenharmony_ci This file is part of the SANE package. 7141cc406Sopenharmony_ci 8141cc406Sopenharmony_ci This program is free software; you can redistribute it and/or 9141cc406Sopenharmony_ci modify it under the terms of the GNU General Public License as 10141cc406Sopenharmony_ci published by the Free Software Foundation; either version 2 of the 11141cc406Sopenharmony_ci License, or (at your option) any later version. 12141cc406Sopenharmony_ci 13141cc406Sopenharmony_ci This program is distributed in the hope that it will be useful, but 14141cc406Sopenharmony_ci WITHOUT ANY WARRANTY; without even the implied warranty of 15141cc406Sopenharmony_ci MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16141cc406Sopenharmony_ci General Public License for more details. 17141cc406Sopenharmony_ci 18141cc406Sopenharmony_ci You should have received a copy of the GNU General Public License 19141cc406Sopenharmony_ci along with this program. If not, see <https://www.gnu.org/licenses/>. 20141cc406Sopenharmony_ci 21141cc406Sopenharmony_ci As a special exception, the authors of SANE give permission for 22141cc406Sopenharmony_ci additional uses of the libraries contained in this release of SANE. 23141cc406Sopenharmony_ci 24141cc406Sopenharmony_ci The exception is that, if you link a SANE library with other files 25141cc406Sopenharmony_ci to produce an executable, this does not by itself cause the 26141cc406Sopenharmony_ci resulting executable to be covered by the GNU General Public 27141cc406Sopenharmony_ci License. Your use of that executable is in no way restricted on 28141cc406Sopenharmony_ci account of linking the SANE library code into it. 29141cc406Sopenharmony_ci 30141cc406Sopenharmony_ci This exception does not, however, invalidate any other reasons why 31141cc406Sopenharmony_ci the executable file might be covered by the GNU General Public 32141cc406Sopenharmony_ci License. 33141cc406Sopenharmony_ci 34141cc406Sopenharmony_ci If you submit changes to SANE to the maintainers to be included in 35141cc406Sopenharmony_ci a subsequent release, you agree by submitting the changes that 36141cc406Sopenharmony_ci those changes may be distributed with this exception intact. 37141cc406Sopenharmony_ci 38141cc406Sopenharmony_ci If you write modifications of your own for SANE, it is your choice 39141cc406Sopenharmony_ci whether to permit this exception to apply to your modifications. 40141cc406Sopenharmony_ci If you do not wish that, delete this exception notice. 41141cc406Sopenharmony_ci 42141cc406Sopenharmony_ci This file implements a SANE backend for NEC flatbed scanners. */ 43141cc406Sopenharmony_ci 44141cc406Sopenharmony_ci/* 45141cc406Sopenharmony_ci Version 0.12 46141cc406Sopenharmony_ci - Remove references to sharp backend (grep for "JX"). 47141cc406Sopenharmony_ci - Check for HAVE_SYS_SHM_H before including sys/shm.h and 48141cc406Sopenharmony_ci disable shared memory support if necessary. 49141cc406Sopenharmony_ci - free devlist allocated in sane_get_devices() in sane_exit() 50141cc406Sopenharmony_ci - resolution setting bug fixed(PC-IN500/4C 10dpi step) 51141cc406Sopenharmony_ci - remove resolution list 52141cc406Sopenharmony_ci Version 0.11 53141cc406Sopenharmony_ci - get_data_buffer_status is not called in sane_get_parameter and 54141cc406Sopenharmony_ci sane_read_direct, sane_read_shuffled. 55141cc406Sopenharmony_ci - change some #include <> to "" 56141cc406Sopenharmony_ci Version 0.10 57141cc406Sopenharmony_ci - First release! 58141cc406Sopenharmony_ci - supported scanner 59141cc406Sopenharmony_ci PC-IN500/4C available 60141cc406Sopenharmony_ci MultiReder 300U/300S series not available 61141cc406Sopenharmony_ci MultiReder 600U/600S series not available 62141cc406Sopenharmony_ci MultiReader PetiScan series not available 63141cc406Sopenharmony_ci*/ 64141cc406Sopenharmony_ci#include "../include/sane/config.h" 65141cc406Sopenharmony_ci 66141cc406Sopenharmony_ci#include <limits.h> 67141cc406Sopenharmony_ci#include <stdlib.h> 68141cc406Sopenharmony_ci#include <stdarg.h> 69141cc406Sopenharmony_ci#include <string.h> 70141cc406Sopenharmony_ci#include <unistd.h> 71141cc406Sopenharmony_ci#include <errno.h> 72141cc406Sopenharmony_ci#include <math.h> 73141cc406Sopenharmony_ci 74141cc406Sopenharmony_ci#include "../include/sane/sane.h" 75141cc406Sopenharmony_ci#include "../include/sane/saneopts.h" 76141cc406Sopenharmony_ci#include "../include/sane/sanei_scsi.h" 77141cc406Sopenharmony_ci 78141cc406Sopenharmony_ci/* QUEUEDEBUG should be undefined unless you want to play 79141cc406Sopenharmony_ci with the sanei_scsi.c under Linux and/or with the Linux's SG driver, 80141cc406Sopenharmony_ci or your suspect problems with command queueing 81141cc406Sopenharmony_ci*/ 82141cc406Sopenharmony_ci#define QUEUEDEBUG 83141cc406Sopenharmony_ci/*#define DEBUG*/ 84141cc406Sopenharmony_ci#ifdef DEBUG 85141cc406Sopenharmony_ci#include <unistd.h> 86141cc406Sopenharmony_ci#include <sys/time.h> 87141cc406Sopenharmony_ci#endif 88141cc406Sopenharmony_ci 89141cc406Sopenharmony_ci/* USE_FORK: fork a special reader process 90141cc406Sopenharmony_ci disable shared memory support. 91141cc406Sopenharmony_ci*/ 92141cc406Sopenharmony_ci#if 0 93141cc406Sopenharmony_ci#ifdef HAVE_SYS_SHM_H 94141cc406Sopenharmony_ci#define USE_FORK 95141cc406Sopenharmony_ci#endif 96141cc406Sopenharmony_ci#endif 97141cc406Sopenharmony_ci 98141cc406Sopenharmony_ci#ifdef USE_FORK 99141cc406Sopenharmony_ci#include <signal.h> 100141cc406Sopenharmony_ci#include <fcntl.h> 101141cc406Sopenharmony_ci#include <sys/types.h> 102141cc406Sopenharmony_ci#include <sys/wait.h> 103141cc406Sopenharmony_ci 104141cc406Sopenharmony_ci#include <sys/ipc.h> 105141cc406Sopenharmony_ci#include <sys/shm.h> 106141cc406Sopenharmony_ci 107141cc406Sopenharmony_ci#endif /* USE_FORK */ 108141cc406Sopenharmony_ci 109141cc406Sopenharmony_ci#ifndef USE_CUSTOM_GAMMA 110141cc406Sopenharmony_ci#define USE_CUSTOM_GAMMA 111141cc406Sopenharmony_ci#endif 112141cc406Sopenharmony_ci#ifndef USE_COLOR_THRESHOLD 113141cc406Sopenharmony_ci#define USE_COLOR_THRESHOLD 114141cc406Sopenharmony_ci#endif 115141cc406Sopenharmony_ci/* enable a short list of some standard resolutions. XSane provides 116141cc406Sopenharmony_ci its own resolution list; therefore its is generally not reasonable 117141cc406Sopenharmony_ci to enable this list, if you mainly using XSane. But it might be handy 118141cc406Sopenharmony_ci if you are working with xscanimage 119141cc406Sopenharmony_ci*/ 120141cc406Sopenharmony_ci/* #define USE_RESOLUTION_LIST */ 121141cc406Sopenharmony_ci 122141cc406Sopenharmony_ci#define BACKEND_NAME nec 123141cc406Sopenharmony_ci#include "../include/sane/sanei_backend.h" 124141cc406Sopenharmony_ci 125141cc406Sopenharmony_ci#ifndef PATH_MAX 126141cc406Sopenharmony_ci#define PATH_MAX 1024 127141cc406Sopenharmony_ci#endif 128141cc406Sopenharmony_ci 129141cc406Sopenharmony_ci#define DEFAULT_MUD_1200 1200 130141cc406Sopenharmony_ci 131141cc406Sopenharmony_ci#define PIX_TO_MM(x, mud) ((x) * 25.4 / mud) 132141cc406Sopenharmony_ci#define MM_TO_PIX(x, mud) ((x) * mud / 25.4) 133141cc406Sopenharmony_ci 134141cc406Sopenharmony_ci#include "../include/sane/sanei_config.h" 135141cc406Sopenharmony_ci#define NEC_CONFIG_FILE "nec.conf" 136141cc406Sopenharmony_ci 137141cc406Sopenharmony_ci#include "nec.h" 138141cc406Sopenharmony_ci 139141cc406Sopenharmony_cistatic int num_devices = 0; 140141cc406Sopenharmony_cistatic NEC_Device *first_dev = NULL; 141141cc406Sopenharmony_cistatic NEC_Scanner *first_handle = NULL; 142141cc406Sopenharmony_cistatic const SANE_Device **devlist = 0; 143141cc406Sopenharmony_ci 144141cc406Sopenharmony_citypedef enum 145141cc406Sopenharmony_ci { 146141cc406Sopenharmony_ci MODES_LINEART = 0, 147141cc406Sopenharmony_ci MODES_GRAY, 148141cc406Sopenharmony_ci MODES_COLOR, 149141cc406Sopenharmony_ci MODES_LINEART_COLOR 150141cc406Sopenharmony_ci } 151141cc406Sopenharmony_ciModes; 152141cc406Sopenharmony_ci 153141cc406Sopenharmony_ci#define M_LINEART SANE_VALUE_SCAN_MODE_LINEART 154141cc406Sopenharmony_ci#define M_GRAY SANE_VALUE_SCAN_MODE_GRAY 155141cc406Sopenharmony_ci#define M_LINEART_COLOR "Lineart Color" 156141cc406Sopenharmony_ci#define M_COLOR SANE_VALUE_SCAN_MODE_COLOR 157141cc406Sopenharmony_cistatic const SANE_String_Const mode_list[] = 158141cc406Sopenharmony_ci{ 159141cc406Sopenharmony_ci#if 0 160141cc406Sopenharmony_ci M_LINEART, M_GRAY, M_LINEART_COLOR, M_COLOR, 161141cc406Sopenharmony_ci#endif 162141cc406Sopenharmony_ci M_LINEART, M_GRAY, M_COLOR, 163141cc406Sopenharmony_ci 0 164141cc406Sopenharmony_ci}; 165141cc406Sopenharmony_ci 166141cc406Sopenharmony_ci#define M_BILEVEL "none" 167141cc406Sopenharmony_ci#define M_BAYER "Dither Bayer" 168141cc406Sopenharmony_ci#define M_SPIRAL "Dither Spiral" 169141cc406Sopenharmony_ci#define M_DISPERSED "Dither Dispersed" 170141cc406Sopenharmony_ci#define M_ERRDIFFUSION "Error Diffusion" 171141cc406Sopenharmony_ci 172141cc406Sopenharmony_ci#define M_DITHER1 "Dither 1" 173141cc406Sopenharmony_ci#define M_DITHER2 "Dither 2" 174141cc406Sopenharmony_ci#define M_DITHER3 "Dither 3" 175141cc406Sopenharmony_ci#define M_DITHERUSER "User defined" 176141cc406Sopenharmony_ci 177141cc406Sopenharmony_cistatic const SANE_String_Const halftone_list[] = 178141cc406Sopenharmony_ci{ 179141cc406Sopenharmony_ci M_BILEVEL, M_DITHER1, M_DITHER2, M_DITHER3, 180141cc406Sopenharmony_ci 0 181141cc406Sopenharmony_ci}; 182141cc406Sopenharmony_ci 183141cc406Sopenharmony_ci#define LIGHT_GREEN "green" 184141cc406Sopenharmony_ci#define LIGHT_RED "red" 185141cc406Sopenharmony_ci#define LIGHT_BLUE "blue" 186141cc406Sopenharmony_ci#define LIGHT_NONE "none" 187141cc406Sopenharmony_ci#define LIGHT_WHITE "white" 188141cc406Sopenharmony_ci 189141cc406Sopenharmony_cistatic const SANE_String_Const light_color_list[] = 190141cc406Sopenharmony_ci{ 191141cc406Sopenharmony_ci LIGHT_GREEN, LIGHT_RED, LIGHT_BLUE, LIGHT_NONE, 192141cc406Sopenharmony_ci 0 193141cc406Sopenharmony_ci}; 194141cc406Sopenharmony_ci 195141cc406Sopenharmony_ci/* possible values for ADF/FSU selection */ 196141cc406Sopenharmony_cistatic SANE_String use_adf = "Automatic Document Feeder"; 197141cc406Sopenharmony_cistatic SANE_String use_fsu = "Transparency Adapter"; 198141cc406Sopenharmony_cistatic SANE_String use_simple = "Flatbed"; 199141cc406Sopenharmony_ci 200141cc406Sopenharmony_ci#define HAVE_FSU 1 201141cc406Sopenharmony_ci#define HAVE_ADF 2 202141cc406Sopenharmony_ci 203141cc406Sopenharmony_ci/* The follow #defines are used in NEC_Scanner.adf_fsu_mode 204141cc406Sopenharmony_ci and as indexes for the arrays x_ranges, y_ranges in NEC_Device 205141cc406Sopenharmony_ci*/ 206141cc406Sopenharmony_ci#define SCAN_SIMPLE 0 207141cc406Sopenharmony_ci#define SCAN_WITH_FSU 1 208141cc406Sopenharmony_ci#define SCAN_WITH_ADF 2 209141cc406Sopenharmony_ci 210141cc406Sopenharmony_ci#define LOAD_PAPER 1 211141cc406Sopenharmony_ci#define UNLOAD_PAPER 0 212141cc406Sopenharmony_ci 213141cc406Sopenharmony_ci#define PAPER_MAX 10 214141cc406Sopenharmony_ci#define W_LETTER "11\"x17\"" 215141cc406Sopenharmony_ci#define INVOICE "8.5\"x5.5\"" 216141cc406Sopenharmony_cistatic const SANE_String_Const paper_list_pcinxxx[] = 217141cc406Sopenharmony_ci{ 218141cc406Sopenharmony_ci "A3", "A4", "A5", "A6", "B4", "B5", 219141cc406Sopenharmony_ci W_LETTER, "Legal", "Letter", INVOICE, 220141cc406Sopenharmony_ci 0 221141cc406Sopenharmony_ci}; 222141cc406Sopenharmony_ci 223141cc406Sopenharmony_cistatic const SANE_String_Const paper_list_pcin500[] = 224141cc406Sopenharmony_ci{ 225141cc406Sopenharmony_ci "A4", "A5", "A6", "B5", 226141cc406Sopenharmony_ci 0 227141cc406Sopenharmony_ci}; 228141cc406Sopenharmony_ci 229141cc406Sopenharmony_ci 230141cc406Sopenharmony_ci#define CRT1 "CRT1" 231141cc406Sopenharmony_ci#define CRT2 "CRT2" 232141cc406Sopenharmony_ci#define PRINTER1 "PRINTER1" 233141cc406Sopenharmony_ci#define PRINTER2 "PRINTER2" 234141cc406Sopenharmony_ci#define NONE "NONE" 235141cc406Sopenharmony_ci/* #define CUSTOM "CUSTOM" */ 236141cc406Sopenharmony_cistatic const SANE_String_Const gamma_list[] = 237141cc406Sopenharmony_ci{ 238141cc406Sopenharmony_ci CRT1, CRT2, PRINTER1, PRINTER2, NONE, 239141cc406Sopenharmony_ci 0 240141cc406Sopenharmony_ci}; 241141cc406Sopenharmony_ci 242141cc406Sopenharmony_ci#if 0 243141cc406Sopenharmony_ci#define SPEED_NORMAL "Normal" 244141cc406Sopenharmony_ci#define SPEED_FAST "Fast" 245141cc406Sopenharmony_cistatic const SANE_String_Const speed_list[] = 246141cc406Sopenharmony_ci{ 247141cc406Sopenharmony_ci SPEED_NORMAL, SPEED_FAST, 248141cc406Sopenharmony_ci 0 249141cc406Sopenharmony_ci}; 250141cc406Sopenharmony_ci#endif 251141cc406Sopenharmony_ci 252141cc406Sopenharmony_ci#ifdef USE_RESOLUTION_LIST 253141cc406Sopenharmony_ci#define RESOLUTION_MAX_PCINXXX 8 254141cc406Sopenharmony_cistatic const SANE_String_Const resolution_list_pcinxxx[] = 255141cc406Sopenharmony_ci{ 256141cc406Sopenharmony_ci "50", "75", "100", "150", "200", "300", "400", "600", "Select", 257141cc406Sopenharmony_ci 0 258141cc406Sopenharmony_ci}; 259141cc406Sopenharmony_ci 260141cc406Sopenharmony_ci#define RESOLUTION_MAX_PCIN500 8 261141cc406Sopenharmony_cistatic const SANE_String_Const resolution_list_pcin500[] = 262141cc406Sopenharmony_ci{ 263141cc406Sopenharmony_ci "50", "75", "100", "150", "200", "300", "400", "480", "Select", 264141cc406Sopenharmony_ci 0 265141cc406Sopenharmony_ci}; 266141cc406Sopenharmony_ci#endif 267141cc406Sopenharmony_ci 268141cc406Sopenharmony_ci#define EDGE_NONE "None" 269141cc406Sopenharmony_ci#define EDGE_MIDDLE "Middle" 270141cc406Sopenharmony_ci#define EDGE_STRONG "Strong" 271141cc406Sopenharmony_ci#define EDGE_BLUR "Blur" 272141cc406Sopenharmony_cistatic const SANE_String_Const edge_emphasis_list[] = 273141cc406Sopenharmony_ci{ 274141cc406Sopenharmony_ci EDGE_NONE, EDGE_MIDDLE, EDGE_STRONG, EDGE_BLUR, 275141cc406Sopenharmony_ci 0 276141cc406Sopenharmony_ci}; 277141cc406Sopenharmony_ci 278141cc406Sopenharmony_ci#ifdef USE_CUSTOM_GAMMA 279141cc406Sopenharmony_cistatic const SANE_Range u8_range = 280141cc406Sopenharmony_ci { 281141cc406Sopenharmony_ci 0, /* minimum */ 282141cc406Sopenharmony_ci 255, /* maximum */ 283141cc406Sopenharmony_ci 0 /* quantization */ 284141cc406Sopenharmony_ci }; 285141cc406Sopenharmony_ci#endif 286141cc406Sopenharmony_ci 287141cc406Sopenharmony_cistatic SANE_Status 288141cc406Sopenharmony_cisense_handler(int fd, u_char *sense_buffer, void *ss) 289141cc406Sopenharmony_ci{ 290141cc406Sopenharmony_ci int sense_key; 291141cc406Sopenharmony_ci NEC_Sense_Data *sdat = (NEC_Sense_Data *) ss; 292141cc406Sopenharmony_ci 293141cc406Sopenharmony_ci (void) fd; /* silence compilation warnings */ 294141cc406Sopenharmony_ci 295141cc406Sopenharmony_ci #define add_sense_code sense_buffer[12] 296141cc406Sopenharmony_ci #define add_sense_qual sense_buffer[13] 297141cc406Sopenharmony_ci 298141cc406Sopenharmony_ci memcpy(sdat->sb, sense_buffer, 16); 299141cc406Sopenharmony_ci 300141cc406Sopenharmony_ci DBG(10, "sense code: %02x %02x %02x %02x %02x %02x %02x %02x " 301141cc406Sopenharmony_ci "%02x %02x %02x %02x %02x %02x %02x %02x\n", 302141cc406Sopenharmony_ci sense_buffer[0], sense_buffer[1], sense_buffer[2], sense_buffer[3], 303141cc406Sopenharmony_ci sense_buffer[4], sense_buffer[5], sense_buffer[6], sense_buffer[7], 304141cc406Sopenharmony_ci sense_buffer[8], sense_buffer[9], sense_buffer[10], sense_buffer[11], 305141cc406Sopenharmony_ci sense_buffer[12], sense_buffer[13], sense_buffer[14], sense_buffer[15]); 306141cc406Sopenharmony_ci 307141cc406Sopenharmony_ci sense_key = sense_buffer[1] & 0x0F; 308141cc406Sopenharmony_ci /* do we have additional information ? */ 309141cc406Sopenharmony_ci if (sense_buffer[7] >= 5) 310141cc406Sopenharmony_ci { 311141cc406Sopenharmony_ci if (sdat->model == PCIN500) 312141cc406Sopenharmony_ci { 313141cc406Sopenharmony_ci switch (sense_key) 314141cc406Sopenharmony_ci { 315141cc406Sopenharmony_ci case 0x02: /* not ready */ 316141cc406Sopenharmony_ci switch (add_sense_code) 317141cc406Sopenharmony_ci { 318141cc406Sopenharmony_ci case 0x80: 319141cc406Sopenharmony_ci switch (add_sense_qual & 0xf0) 320141cc406Sopenharmony_ci { 321141cc406Sopenharmony_ci case 0x10: 322141cc406Sopenharmony_ci DBG(1, "Scanner not ready: memory error\n"); 323141cc406Sopenharmony_ci return SANE_STATUS_IO_ERROR; 324141cc406Sopenharmony_ci case 0x20: 325141cc406Sopenharmony_ci DBG(1, "Scanner not ready: hardware error\n"); 326141cc406Sopenharmony_ci return SANE_STATUS_IO_ERROR; 327141cc406Sopenharmony_ci case 0x30: 328141cc406Sopenharmony_ci DBG(1, "Scanner not ready: optical error\n"); 329141cc406Sopenharmony_ci return SANE_STATUS_IO_ERROR; 330141cc406Sopenharmony_ci case 0x40: 331141cc406Sopenharmony_ci DBG(1, "Scanner not ready: optical error\n"); 332141cc406Sopenharmony_ci return SANE_STATUS_IO_ERROR; 333141cc406Sopenharmony_ci case 0x50: 334141cc406Sopenharmony_ci DBG(1, "Scanner not ready: marker error\n"); 335141cc406Sopenharmony_ci return SANE_STATUS_IO_ERROR; 336141cc406Sopenharmony_ci case 0x60: 337141cc406Sopenharmony_ci DBG(1, "Scanner not ready: mechanical error\n"); 338141cc406Sopenharmony_ci return SANE_STATUS_IO_ERROR; 339141cc406Sopenharmony_ci case 0x70: 340141cc406Sopenharmony_ci DBG(1, "Scanner not ready: hardware error\n"); 341141cc406Sopenharmony_ci return SANE_STATUS_IO_ERROR; 342141cc406Sopenharmony_ci case 0x80: 343141cc406Sopenharmony_ci DBG(1, "Scanner not ready: hardware error\n"); 344141cc406Sopenharmony_ci return SANE_STATUS_IO_ERROR; 345141cc406Sopenharmony_ci case 0x90: 346141cc406Sopenharmony_ci default: 347141cc406Sopenharmony_ci DBG(5, "Scanner not ready: undocumented reason\n"); 348141cc406Sopenharmony_ci return SANE_STATUS_IO_ERROR; 349141cc406Sopenharmony_ci } 350141cc406Sopenharmony_ci default: 351141cc406Sopenharmony_ci DBG(5, "Scanner not ready: unknown sense code\n"); 352141cc406Sopenharmony_ci return SANE_STATUS_IO_ERROR; 353141cc406Sopenharmony_ci } 354141cc406Sopenharmony_ci case 0x03: /* medium error */ 355141cc406Sopenharmony_ci DBG(5, "medium error: undocumented reason\n"); 356141cc406Sopenharmony_ci return SANE_STATUS_IO_ERROR; 357141cc406Sopenharmony_ci case 0x04: /* hardware error */ 358141cc406Sopenharmony_ci DBG(1, "general hardware error\n"); 359141cc406Sopenharmony_ci return SANE_STATUS_IO_ERROR; 360141cc406Sopenharmony_ci case 0x05: /* illegal request */ 361141cc406Sopenharmony_ci DBG(10, "error: illegal request\n"); 362141cc406Sopenharmony_ci return SANE_STATUS_IO_ERROR; 363141cc406Sopenharmony_ci case 0x06: /* unit attention */ 364141cc406Sopenharmony_ci DBG(5, "unit attention: exact reason not documented\n"); 365141cc406Sopenharmony_ci return SANE_STATUS_IO_ERROR; 366141cc406Sopenharmony_ci case 0x0B: /* data remains */ 367141cc406Sopenharmony_ci DBG(5, "error: aborted command\n"); 368141cc406Sopenharmony_ci return SANE_STATUS_IO_ERROR; 369141cc406Sopenharmony_ci default: 370141cc406Sopenharmony_ci DBG(5, "error: sense code not documented\n"); 371141cc406Sopenharmony_ci return SANE_STATUS_IO_ERROR; 372141cc406Sopenharmony_ci } 373141cc406Sopenharmony_ci } 374141cc406Sopenharmony_ci } 375141cc406Sopenharmony_ci return SANE_STATUS_IO_ERROR; 376141cc406Sopenharmony_ci} 377141cc406Sopenharmony_ci 378141cc406Sopenharmony_cistatic SANE_Status 379141cc406Sopenharmony_citest_unit_ready (int fd) 380141cc406Sopenharmony_ci{ 381141cc406Sopenharmony_ci static u_char cmd[] = {TEST_UNIT_READY, 0, 0, 0, 0, 0}; 382141cc406Sopenharmony_ci SANE_Status status; 383141cc406Sopenharmony_ci DBG (11, "<< test_unit_ready "); 384141cc406Sopenharmony_ci 385141cc406Sopenharmony_ci status = sanei_scsi_cmd (fd, cmd, sizeof (cmd), 0, 0); 386141cc406Sopenharmony_ci 387141cc406Sopenharmony_ci DBG (11, ">>\n"); 388141cc406Sopenharmony_ci return (status); 389141cc406Sopenharmony_ci} 390141cc406Sopenharmony_ci 391141cc406Sopenharmony_ci#if 0 392141cc406Sopenharmony_cistatic SANE_Status 393141cc406Sopenharmony_cirequest_sense (int fd, void *sense_buf, size_t *sense_size) 394141cc406Sopenharmony_ci{ 395141cc406Sopenharmony_ci static u_char cmd[] = {REQUEST_SENSE, 0, 0, 0, SENSE_LEN, 0}; 396141cc406Sopenharmony_ci SANE_Status status; 397141cc406Sopenharmony_ci DBG (11, "<< request_sense "); 398141cc406Sopenharmony_ci 399141cc406Sopenharmony_ci status = sanei_scsi_cmd (fd, cmd, sizeof (cmd), sense_buf, sense_size); 400141cc406Sopenharmony_ci 401141cc406Sopenharmony_ci DBG (11, ">>\n"); 402141cc406Sopenharmony_ci return (status); 403141cc406Sopenharmony_ci} 404141cc406Sopenharmony_ci#endif 405141cc406Sopenharmony_ci 406141cc406Sopenharmony_cistatic SANE_Status 407141cc406Sopenharmony_ciinquiry (int fd, void *inq_buf, size_t *inq_size) 408141cc406Sopenharmony_ci{ 409141cc406Sopenharmony_ci static u_char cmd[] = {INQUIRY, 0, 0, 0, INQUIRY_LEN, 0}; 410141cc406Sopenharmony_ci SANE_Status status; 411141cc406Sopenharmony_ci DBG (11, "<< inquiry "); 412141cc406Sopenharmony_ci 413141cc406Sopenharmony_ci status = sanei_scsi_cmd (fd, cmd, sizeof (cmd), inq_buf, inq_size); 414141cc406Sopenharmony_ci 415141cc406Sopenharmony_ci DBG (11, ">>\n"); 416141cc406Sopenharmony_ci return (status); 417141cc406Sopenharmony_ci} 418141cc406Sopenharmony_ci 419141cc406Sopenharmony_cistatic SANE_Status 420141cc406Sopenharmony_cimode_select_mud (int fd, int mud) 421141cc406Sopenharmony_ci{ 422141cc406Sopenharmony_ci static u_char cmd[6 + MODEPARAM_LEN] = 423141cc406Sopenharmony_ci {MODE_SELECT6, 0x10, 0, 0, MODEPARAM_LEN, 0}; 424141cc406Sopenharmony_ci mode_select_param *mp; 425141cc406Sopenharmony_ci SANE_Status status; 426141cc406Sopenharmony_ci DBG (11, "<< mode_select_mud "); 427141cc406Sopenharmony_ci 428141cc406Sopenharmony_ci mp = (mode_select_param *)(cmd + 6); 429141cc406Sopenharmony_ci memset (mp, 0, MODEPARAM_LEN); 430141cc406Sopenharmony_ci mp->mode_param_header1 = 11; 431141cc406Sopenharmony_ci mp->page_code = 3; 432141cc406Sopenharmony_ci mp->page_length = 6; 433141cc406Sopenharmony_ci mp->mud[0] = mud >> 8; 434141cc406Sopenharmony_ci mp->mud[1] = mud & 0xFF; 435141cc406Sopenharmony_ci 436141cc406Sopenharmony_ci status = sanei_scsi_cmd (fd, cmd, sizeof (cmd), 0, 0); 437141cc406Sopenharmony_ci 438141cc406Sopenharmony_ci DBG (11, ">>\n"); 439141cc406Sopenharmony_ci return (status); 440141cc406Sopenharmony_ci} 441141cc406Sopenharmony_ci 442141cc406Sopenharmony_ci#if 0 443141cc406Sopenharmony_cistatic SANE_Status 444141cc406Sopenharmony_cimode_select_adf_fsu (int fd, int mode) 445141cc406Sopenharmony_ci{ 446141cc406Sopenharmony_ci static u_char cmd[6 + MODE_SUBDEV_LEN] = 447141cc406Sopenharmony_ci {MODE_SELECT6, 0x10, 0, 0, MODE_SUBDEV_LEN, 0}; 448141cc406Sopenharmony_ci mode_select_subdevice *mp; 449141cc406Sopenharmony_ci SANE_Status status; 450141cc406Sopenharmony_ci DBG (11, "<< mode_select_adf_fsu "); 451141cc406Sopenharmony_ci 452141cc406Sopenharmony_ci mp = (mode_select_subdevice *)(cmd + 6); 453141cc406Sopenharmony_ci memset (mp, 0, MODE_SUBDEV_LEN); 454141cc406Sopenharmony_ci mp->page_code = 0x20; 455141cc406Sopenharmony_ci mp->page_length = 26; 456141cc406Sopenharmony_ci switch (mode) 457141cc406Sopenharmony_ci { 458141cc406Sopenharmony_ci case SCAN_SIMPLE: 459141cc406Sopenharmony_ci mp->a_mode = 0x40; 460141cc406Sopenharmony_ci mp->f_mode = 0x40; 461141cc406Sopenharmony_ci break; 462141cc406Sopenharmony_ci case SCAN_WITH_FSU: 463141cc406Sopenharmony_ci mp->a_mode = 0; 464141cc406Sopenharmony_ci mp->f_mode = 0x40; 465141cc406Sopenharmony_ci break; 466141cc406Sopenharmony_ci case SCAN_WITH_ADF: 467141cc406Sopenharmony_ci mp->a_mode = 0x40; 468141cc406Sopenharmony_ci mp->f_mode = 0; 469141cc406Sopenharmony_ci break; 470141cc406Sopenharmony_ci } 471141cc406Sopenharmony_ci 472141cc406Sopenharmony_ci status = sanei_scsi_cmd (fd, cmd, sizeof (cmd), 0, 0); 473141cc406Sopenharmony_ci 474141cc406Sopenharmony_ci DBG (11, ">>\n"); 475141cc406Sopenharmony_ci return (status); 476141cc406Sopenharmony_ci} 477141cc406Sopenharmony_ci#endif 478141cc406Sopenharmony_ci 479141cc406Sopenharmony_cistatic SANE_Status wait_ready(int fd); 480141cc406Sopenharmony_ci 481141cc406Sopenharmony_cistatic SANE_Status 482141cc406Sopenharmony_cimode_sense (int fd, void *modeparam_buf, size_t * modeparam_size, 483141cc406Sopenharmony_ci int page) 484141cc406Sopenharmony_ci{ 485141cc406Sopenharmony_ci static u_char cmd[6] = {MODE_SENSE6, 0, 0, 0, 0, 0}; 486141cc406Sopenharmony_ci SANE_Status status; 487141cc406Sopenharmony_ci DBG (11, "<< mode_sense "); 488141cc406Sopenharmony_ci cmd[0] = 0x1a; 489141cc406Sopenharmony_ci cmd[2] = page; 490141cc406Sopenharmony_ci cmd[4] = *modeparam_size; 491141cc406Sopenharmony_ci status = sanei_scsi_cmd (fd, cmd, sizeof (cmd), modeparam_buf, 492141cc406Sopenharmony_ci modeparam_size); 493141cc406Sopenharmony_ci 494141cc406Sopenharmony_ci DBG (11, ">>\n"); 495141cc406Sopenharmony_ci return (status); 496141cc406Sopenharmony_ci} 497141cc406Sopenharmony_ci 498141cc406Sopenharmony_cistatic SANE_Status 499141cc406Sopenharmony_ciscan (int fd) 500141cc406Sopenharmony_ci{ 501141cc406Sopenharmony_ci static u_char cmd[] = {SCAN, 0, 0, 0, 0, 0}; 502141cc406Sopenharmony_ci SANE_Status status; 503141cc406Sopenharmony_ci DBG (11, "<< scan "); 504141cc406Sopenharmony_ci 505141cc406Sopenharmony_ci status = sanei_scsi_cmd (fd, cmd, sizeof (cmd), 0, 0); 506141cc406Sopenharmony_ci 507141cc406Sopenharmony_ci DBG (11, ">>\n"); 508141cc406Sopenharmony_ci return (status); 509141cc406Sopenharmony_ci} 510141cc406Sopenharmony_ci 511141cc406Sopenharmony_ci#if 0 512141cc406Sopenharmony_cistatic SANE_Status 513141cc406Sopenharmony_cisend_diagnostics (int fd) 514141cc406Sopenharmony_ci{ 515141cc406Sopenharmony_ci static u_char cmd[] = {SEND_DIAGNOSTIC, 0x04, 0, 0, 0, 0}; 516141cc406Sopenharmony_ci SANE_Status status; 517141cc406Sopenharmony_ci DBG (11, "<< send_diagnostics "); 518141cc406Sopenharmony_ci 519141cc406Sopenharmony_ci status = sanei_scsi_cmd (fd, cmd, sizeof (cmd), 0, 0); 520141cc406Sopenharmony_ci 521141cc406Sopenharmony_ci DBG (11, ">>\n"); 522141cc406Sopenharmony_ci return (status); 523141cc406Sopenharmony_ci} 524141cc406Sopenharmony_ci#endif 525141cc406Sopenharmony_ci 526141cc406Sopenharmony_cistatic SANE_Status 527141cc406Sopenharmony_ciset_window (int fd, window_param *wp, int len) 528141cc406Sopenharmony_ci{ 529141cc406Sopenharmony_ci static u_char cmd[10 + WINDOW_LEN] = 530141cc406Sopenharmony_ci {SET_WINDOW, 0, 0, 0, 0, 0, 0, 0, 0, 0}; 531141cc406Sopenharmony_ci window_param *winp; 532141cc406Sopenharmony_ci SANE_Status status; 533141cc406Sopenharmony_ci DBG (11, "<< set_window "); 534141cc406Sopenharmony_ci 535141cc406Sopenharmony_ci cmd[8] = len; 536141cc406Sopenharmony_ci winp = (window_param *)(cmd + 10); 537141cc406Sopenharmony_ci memset (winp, 0, WINDOW_LEN); 538141cc406Sopenharmony_ci memcpy (winp, wp, len); 539141cc406Sopenharmony_ci status = sanei_scsi_cmd (fd, cmd, sizeof (cmd), 0, 0); 540141cc406Sopenharmony_ci 541141cc406Sopenharmony_ci DBG (11, ">>\n"); 542141cc406Sopenharmony_ci return (status); 543141cc406Sopenharmony_ci 544141cc406Sopenharmony_ci} 545141cc406Sopenharmony_ci 546141cc406Sopenharmony_cistatic SANE_Status 547141cc406Sopenharmony_ciget_window (int fd, void *buf, size_t * buf_size) 548141cc406Sopenharmony_ci{ 549141cc406Sopenharmony_ci static u_char cmd[10] = {GET_WINDOW, 0, 0, 0, 0, 0, 0, 0, WINDOW_LEN, 0}; 550141cc406Sopenharmony_ci SANE_Status status; 551141cc406Sopenharmony_ci DBG (11, "<< get_window "); 552141cc406Sopenharmony_ci 553141cc406Sopenharmony_ci cmd[8] = *buf_size; 554141cc406Sopenharmony_ci status = sanei_scsi_cmd (fd, cmd, sizeof (cmd), buf, buf_size); 555141cc406Sopenharmony_ci 556141cc406Sopenharmony_ci DBG (11, ">>\n"); 557141cc406Sopenharmony_ci return (status); 558141cc406Sopenharmony_ci} 559141cc406Sopenharmony_ci 560141cc406Sopenharmony_ci#if 0 561141cc406Sopenharmony_cistatic SANE_Status 562141cc406Sopenharmony_ciget_data_buffer_status (int fd, void *buf, size_t *buf_size) 563141cc406Sopenharmony_ci{ 564141cc406Sopenharmony_ci static u_char cmd[10] = 565141cc406Sopenharmony_ci {GET_DATA_BUFFER_STATUS, 0, 0, 0, 0, 0, 0, 0, 0, 0}; 566141cc406Sopenharmony_ci SANE_Status status; 567141cc406Sopenharmony_ci DBG (11, "<< get_data_buffer_status "); 568141cc406Sopenharmony_ci 569141cc406Sopenharmony_ci cmd[8] = *buf_size; 570141cc406Sopenharmony_ci status = sanei_scsi_cmd (fd, cmd, sizeof (cmd), buf, buf_size); 571141cc406Sopenharmony_ci 572141cc406Sopenharmony_ci DBG (11, ">>\n"); 573141cc406Sopenharmony_ci return (status); 574141cc406Sopenharmony_ci} 575141cc406Sopenharmony_ci#endif 576141cc406Sopenharmony_ci 577141cc406Sopenharmony_ci#ifdef USE_FORK 578141cc406Sopenharmony_ci 579141cc406Sopenharmony_ci/* the following four functions serve simply the purpose 580141cc406Sopenharmony_ci to avoid "over-optimised" code when reader_process and 581141cc406Sopenharmony_ci read_data wait for the buffer to become ready. The simple 582141cc406Sopenharmony_ci while-loops in these functions which check the buffer 583141cc406Sopenharmony_ci status may be optimised so that the machine code only 584141cc406Sopenharmony_ci operates with registers instead of using the variable 585141cc406Sopenharmony_ci values stored in memory. (This is only a workaround - 586141cc406Sopenharmony_ci it would be better to set a compiler pragma, which ensures 587141cc406Sopenharmony_ci that the program looks into the RAM in these while loops -- 588141cc406Sopenharmony_ci but unfortunately I could not find appropriate information 589141cc406Sopenharmony_ci about this at least for gcc, not to speak about other 590141cc406Sopenharmony_ci compilers... 591141cc406Sopenharmony_ci Abel) 592141cc406Sopenharmony_ci*/ 593141cc406Sopenharmony_ci 594141cc406Sopenharmony_cistatic int 595141cc406Sopenharmony_cicancel_requested(NEC_Scanner *s) 596141cc406Sopenharmony_ci{ 597141cc406Sopenharmony_ci return s->rdr_ctl->cancel; 598141cc406Sopenharmony_ci} 599141cc406Sopenharmony_ci 600141cc406Sopenharmony_cistatic SANE_Status 601141cc406Sopenharmony_cirdr_status(NEC_Scanner *s) 602141cc406Sopenharmony_ci{ 603141cc406Sopenharmony_ci return s->rdr_ctl->status; 604141cc406Sopenharmony_ci} 605141cc406Sopenharmony_ci 606141cc406Sopenharmony_cistatic int 607141cc406Sopenharmony_cibuf_status(NEC_shmem_ctl *s) 608141cc406Sopenharmony_ci{ 609141cc406Sopenharmony_ci return s->shm_status; 610141cc406Sopenharmony_ci} 611141cc406Sopenharmony_ci 612141cc406Sopenharmony_cistatic int 613141cc406Sopenharmony_cireader_running(NEC_Scanner *s) 614141cc406Sopenharmony_ci{ 615141cc406Sopenharmony_ci return s->rdr_ctl->running; 616141cc406Sopenharmony_ci} 617141cc406Sopenharmony_ci 618141cc406Sopenharmony_cistatic int 619141cc406Sopenharmony_cireader_process(NEC_Scanner *s) 620141cc406Sopenharmony_ci{ 621141cc406Sopenharmony_ci SANE_Status status; 622141cc406Sopenharmony_ci sigset_t sigterm_set; 623141cc406Sopenharmony_ci static u_char cmd[] = {READ, 0, 0, 0, 0, 0, 0, 0, 0, 0}; 624141cc406Sopenharmony_ci int full_count = 0, counted; 625141cc406Sopenharmony_ci size_t waitindex, cmdindex; 626141cc406Sopenharmony_ci size_t bytes_to_queue; 627141cc406Sopenharmony_ci size_t nread; 628141cc406Sopenharmony_ci size_t max_bytes_per_read; 629141cc406Sopenharmony_ci int max_queue; 630141cc406Sopenharmony_ci int i; 631141cc406Sopenharmony_ci NEC_shmem_ctl *bc; 632141cc406Sopenharmony_ci 633141cc406Sopenharmony_ci s->rdr_ctl->running = 1; 634141cc406Sopenharmony_ci DBG(11, "<< reader_process\n"); 635141cc406Sopenharmony_ci 636141cc406Sopenharmony_ci sigemptyset (&sigterm_set); 637141cc406Sopenharmony_ci 638141cc406Sopenharmony_ci bytes_to_queue = s->bytes_to_read; 639141cc406Sopenharmony_ci 640141cc406Sopenharmony_ci max_bytes_per_read = s->dev->info.bufsize / s->params.bytes_per_line; 641141cc406Sopenharmony_ci if (max_bytes_per_read) 642141cc406Sopenharmony_ci max_bytes_per_read *= s->params.bytes_per_line; 643141cc406Sopenharmony_ci else 644141cc406Sopenharmony_ci /* this is a really tiny buffer..*/ 645141cc406Sopenharmony_ci max_bytes_per_read = s->dev->info.bufsize; 646141cc406Sopenharmony_ci 647141cc406Sopenharmony_ci /* wait_ready(s->fd); */ 648141cc406Sopenharmony_ci 649141cc406Sopenharmony_ci if (s->dev->info.queued_reads <= s->dev->info.buffers) 650141cc406Sopenharmony_ci max_queue = s->dev->info.queued_reads; 651141cc406Sopenharmony_ci else 652141cc406Sopenharmony_ci max_queue = s->dev->info.buffers; 653141cc406Sopenharmony_ci for (i = 0; i < max_queue; i++) 654141cc406Sopenharmony_ci { 655141cc406Sopenharmony_ci bc = &s->rdr_ctl->buf_ctl[i]; 656141cc406Sopenharmony_ci if (bytes_to_queue) 657141cc406Sopenharmony_ci { 658141cc406Sopenharmony_ci nread = bytes_to_queue; 659141cc406Sopenharmony_ci if (nread > max_bytes_per_read) 660141cc406Sopenharmony_ci nread = max_bytes_per_read; 661141cc406Sopenharmony_ci bc->used = nread; 662141cc406Sopenharmony_ci cmd[6] = nread >> 16; 663141cc406Sopenharmony_ci cmd[7] = nread >> 8; 664141cc406Sopenharmony_ci cmd[8] = nread; 665141cc406Sopenharmony_ci#ifdef QUEUEDEBUG 666141cc406Sopenharmony_ci DBG(2, "reader: req_enter...\n"); 667141cc406Sopenharmony_ci#endif 668141cc406Sopenharmony_ci status = sanei_scsi_req_enter (s->fd, cmd, sizeof (cmd), 669141cc406Sopenharmony_ci bc->buffer, 670141cc406Sopenharmony_ci &bc->used, 671141cc406Sopenharmony_ci &bc->qid); 672141cc406Sopenharmony_ci#ifdef QUEUEDEBUG 673141cc406Sopenharmony_ci DBG(2, "reader: req_enter ok\n"); 674141cc406Sopenharmony_ci#endif 675141cc406Sopenharmony_ci if (status != SANE_STATUS_GOOD) 676141cc406Sopenharmony_ci { 677141cc406Sopenharmony_ci DBG(1, "reader_process: read command failed: %s", 678141cc406Sopenharmony_ci sane_strstatus(status)); 679141cc406Sopenharmony_ci#ifdef HAVE_SANEI_SCSI_OPEN_EXTENDED 680141cc406Sopenharmony_ci sanei_scsi_req_flush_all_extended(s->fd); 681141cc406Sopenharmony_ci#else 682141cc406Sopenharmony_ci sanei_scsi_req_flush_all(); 683141cc406Sopenharmony_ci#endif 684141cc406Sopenharmony_ci s->rdr_ctl->status = status; 685141cc406Sopenharmony_ci s->rdr_ctl->running = 0; 686141cc406Sopenharmony_ci return 2; 687141cc406Sopenharmony_ci } 688141cc406Sopenharmony_ci bc->shm_status = SHM_BUSY; 689141cc406Sopenharmony_ci bc->nreq = bc->used; 690141cc406Sopenharmony_ci bytes_to_queue -= bc->nreq; 691141cc406Sopenharmony_ci } 692141cc406Sopenharmony_ci else 693141cc406Sopenharmony_ci { 694141cc406Sopenharmony_ci bc->used = 0; 695141cc406Sopenharmony_ci bc->shm_status = SHM_EMPTY; 696141cc406Sopenharmony_ci } 697141cc406Sopenharmony_ci } 698141cc406Sopenharmony_ci waitindex = 0; 699141cc406Sopenharmony_ci cmdindex = i % s->dev->info.buffers; 700141cc406Sopenharmony_ci 701141cc406Sopenharmony_ci while(s->bytes_to_read > 0) 702141cc406Sopenharmony_ci { 703141cc406Sopenharmony_ci if (cancel_requested(s)) 704141cc406Sopenharmony_ci { 705141cc406Sopenharmony_ci#ifdef QUEUEDEBUG 706141cc406Sopenharmony_ci DBG(2, "reader: flushing requests...\n"); 707141cc406Sopenharmony_ci#endif 708141cc406Sopenharmony_ci#ifdef HAVE_SANEI_SCSI_OPEN_EXTENDED 709141cc406Sopenharmony_ci sanei_scsi_req_flush_all_extended(s->fd); 710141cc406Sopenharmony_ci#else 711141cc406Sopenharmony_ci sanei_scsi_req_flush_all(); 712141cc406Sopenharmony_ci#endif 713141cc406Sopenharmony_ci#ifdef QUEUEDEBUG 714141cc406Sopenharmony_ci DBG(2, "reader: flushing requests ok\n"); 715141cc406Sopenharmony_ci#endif 716141cc406Sopenharmony_ci s->rdr_ctl->cancel = 0; 717141cc406Sopenharmony_ci s->rdr_ctl->status = SANE_STATUS_CANCELLED; 718141cc406Sopenharmony_ci s->rdr_ctl->running = 0; 719141cc406Sopenharmony_ci DBG(11, " reader_process (cancelled) >>\n"); 720141cc406Sopenharmony_ci return 1; 721141cc406Sopenharmony_ci } 722141cc406Sopenharmony_ci 723141cc406Sopenharmony_ci bc = &s->rdr_ctl->buf_ctl[waitindex]; 724141cc406Sopenharmony_ci if (bc->shm_status == SHM_BUSY) 725141cc406Sopenharmony_ci { 726141cc406Sopenharmony_ci#ifdef DEBUG 727141cc406Sopenharmony_ci { 728141cc406Sopenharmony_ci struct timeval t; 729141cc406Sopenharmony_ci gettimeofday(&t, 0); 730141cc406Sopenharmony_ci DBG(2, "rd: waiting for data %li.%06li\n", t.tv_sec, t.tv_usec); 731141cc406Sopenharmony_ci } 732141cc406Sopenharmony_ci#endif 733141cc406Sopenharmony_ci#ifdef QUEUEDEBUG 734141cc406Sopenharmony_ci DBG(2, "reader: req_wait...\n"); 735141cc406Sopenharmony_ci#endif 736141cc406Sopenharmony_ci status = sanei_scsi_req_wait(bc->qid); 737141cc406Sopenharmony_ci#ifdef QUEUEDEBUG 738141cc406Sopenharmony_ci DBG(2, "reader: req_wait ok\n"); 739141cc406Sopenharmony_ci#endif 740141cc406Sopenharmony_ci#ifdef DEBUG 741141cc406Sopenharmony_ci { 742141cc406Sopenharmony_ci struct timeval t; 743141cc406Sopenharmony_ci gettimeofday(&t, 0); 744141cc406Sopenharmony_ci DBG(2, "rd: data received %li.%06li\n", t.tv_sec, t.tv_usec); 745141cc406Sopenharmony_ci } 746141cc406Sopenharmony_ci#endif 747141cc406Sopenharmony_ci if (status != SANE_STATUS_GOOD) 748141cc406Sopenharmony_ci { 749141cc406Sopenharmony_ci DBG(1, "reader_process: read command failed: %s", 750141cc406Sopenharmony_ci sane_strstatus(status)); 751141cc406Sopenharmony_ci#ifdef HAVE_SANEI_SCSI_OPEN_EXTENDED 752141cc406Sopenharmony_ci sanei_scsi_req_flush_all_extended(s->fd); 753141cc406Sopenharmony_ci#else 754141cc406Sopenharmony_ci sanei_scsi_req_flush_all(); 755141cc406Sopenharmony_ci#endif 756141cc406Sopenharmony_ci s->rdr_ctl->status = status; 757141cc406Sopenharmony_ci s->rdr_ctl->running = 0; 758141cc406Sopenharmony_ci return 2; 759141cc406Sopenharmony_ci } 760141cc406Sopenharmony_ci s->bytes_to_read -= bc->used; 761141cc406Sopenharmony_ci bytes_to_queue += bc->nreq - bc->used; 762141cc406Sopenharmony_ci bc->start = 0; 763141cc406Sopenharmony_ci bc->shm_status = SHM_FULL; 764141cc406Sopenharmony_ci 765141cc406Sopenharmony_ci waitindex++; 766141cc406Sopenharmony_ci if (waitindex == s->dev->info.buffers) 767141cc406Sopenharmony_ci waitindex = 0; 768141cc406Sopenharmony_ci 769141cc406Sopenharmony_ci } 770141cc406Sopenharmony_ci 771141cc406Sopenharmony_ci if (bytes_to_queue) 772141cc406Sopenharmony_ci { 773141cc406Sopenharmony_ci /* wait until the next buffer is completely read via read_data */ 774141cc406Sopenharmony_ci bc = &s->rdr_ctl->buf_ctl[cmdindex]; 775141cc406Sopenharmony_ci counted = 0; 776141cc406Sopenharmony_ci while (buf_status(bc) != SHM_EMPTY) 777141cc406Sopenharmony_ci { 778141cc406Sopenharmony_ci if (!counted) 779141cc406Sopenharmony_ci { 780141cc406Sopenharmony_ci counted = 1; 781141cc406Sopenharmony_ci full_count++; 782141cc406Sopenharmony_ci } 783141cc406Sopenharmony_ci if (cancel_requested(s)) 784141cc406Sopenharmony_ci { 785141cc406Sopenharmony_ci#ifdef HAVE_SANEI_SCSI_OPEN_EXTENDED 786141cc406Sopenharmony_ci sanei_scsi_req_flush_all_extended(s->fd); 787141cc406Sopenharmony_ci#else 788141cc406Sopenharmony_ci sanei_scsi_req_flush_all(); 789141cc406Sopenharmony_ci#endif 790141cc406Sopenharmony_ci s->rdr_ctl->cancel = 0; 791141cc406Sopenharmony_ci s->rdr_ctl->status = SANE_STATUS_CANCELLED; 792141cc406Sopenharmony_ci s->rdr_ctl->running = 0; 793141cc406Sopenharmony_ci DBG(11, " reader_process (cancelled) >>\n"); 794141cc406Sopenharmony_ci return 1; 795141cc406Sopenharmony_ci } 796141cc406Sopenharmony_ci } 797141cc406Sopenharmony_ci 798141cc406Sopenharmony_ci nread = bytes_to_queue; 799141cc406Sopenharmony_ci if (nread > max_bytes_per_read) 800141cc406Sopenharmony_ci nread = max_bytes_per_read; 801141cc406Sopenharmony_ci bc->used = nread; 802141cc406Sopenharmony_ci cmd[6] = nread >> 16; 803141cc406Sopenharmony_ci cmd[7] = nread >> 8; 804141cc406Sopenharmony_ci cmd[8] = nread; 805141cc406Sopenharmony_ci status = sanei_scsi_req_enter (s->fd, cmd, sizeof (cmd), 806141cc406Sopenharmony_ci bc->buffer, &bc->used, &bc->qid); 807141cc406Sopenharmony_ci if (status != SANE_STATUS_GOOD) 808141cc406Sopenharmony_ci { 809141cc406Sopenharmony_ci DBG(1, "reader_process: read command failed: %s", 810141cc406Sopenharmony_ci sane_strstatus(status)); 811141cc406Sopenharmony_ci#ifdef HAVE_SANEI_SCSI_OPEN_EXTENDED 812141cc406Sopenharmony_ci sanei_scsi_req_flush_all_extended(s->fd); 813141cc406Sopenharmony_ci#else 814141cc406Sopenharmony_ci sanei_scsi_req_flush_all(); 815141cc406Sopenharmony_ci#endif 816141cc406Sopenharmony_ci s->rdr_ctl->status = status; 817141cc406Sopenharmony_ci s->rdr_ctl->running = 0; 818141cc406Sopenharmony_ci return 2; 819141cc406Sopenharmony_ci } 820141cc406Sopenharmony_ci bc->shm_status = SHM_BUSY; 821141cc406Sopenharmony_ci bc->nreq = nread; 822141cc406Sopenharmony_ci bytes_to_queue -= nread; 823141cc406Sopenharmony_ci 824141cc406Sopenharmony_ci cmdindex++; 825141cc406Sopenharmony_ci if (cmdindex == s->dev->info.buffers) 826141cc406Sopenharmony_ci cmdindex = 0; 827141cc406Sopenharmony_ci } 828141cc406Sopenharmony_ci 829141cc406Sopenharmony_ci if (cancel_requested(s)) 830141cc406Sopenharmony_ci { 831141cc406Sopenharmony_ci#ifdef HAVE_SANEI_SCSI_OPEN_EXTENDED 832141cc406Sopenharmony_ci sanei_scsi_req_flush_all_extended(s->fd); 833141cc406Sopenharmony_ci#else 834141cc406Sopenharmony_ci sanei_scsi_req_flush_all(); 835141cc406Sopenharmony_ci#endif 836141cc406Sopenharmony_ci s->rdr_ctl->cancel = 0; 837141cc406Sopenharmony_ci s->rdr_ctl->status = SANE_STATUS_CANCELLED; 838141cc406Sopenharmony_ci s->rdr_ctl->running = 0; 839141cc406Sopenharmony_ci DBG(11, " reader_process (cancelled) >>\n"); 840141cc406Sopenharmony_ci return 1; 841141cc406Sopenharmony_ci } 842141cc406Sopenharmony_ci } 843141cc406Sopenharmony_ci 844141cc406Sopenharmony_ci DBG(1, "buffer full conditions: %i\n", full_count); 845141cc406Sopenharmony_ci DBG(11, " reader_process>>\n"); 846141cc406Sopenharmony_ci 847141cc406Sopenharmony_ci s->rdr_ctl->running = 0; 848141cc406Sopenharmony_ci return 0; 849141cc406Sopenharmony_ci} 850141cc406Sopenharmony_ci 851141cc406Sopenharmony_cistatic SANE_Status 852141cc406Sopenharmony_ciread_data (NEC_Scanner *s, SANE_Byte *buf, size_t * buf_size) 853141cc406Sopenharmony_ci{ 854141cc406Sopenharmony_ci size_t copysize, copied = 0; 855141cc406Sopenharmony_ci NEC_shmem_ctl *bc; 856141cc406Sopenharmony_ci 857141cc406Sopenharmony_ci DBG(11, "<< read_data "); 858141cc406Sopenharmony_ci 859141cc406Sopenharmony_ci bc = &s->rdr_ctl->buf_ctl[s->read_buff]; 860141cc406Sopenharmony_ci 861141cc406Sopenharmony_ci while (copied < *buf_size) 862141cc406Sopenharmony_ci { 863141cc406Sopenharmony_ci /* wait until the reader process delivers data or a scanner error occurs: */ 864141cc406Sopenharmony_ci while ( buf_status(bc) != SHM_FULL 865141cc406Sopenharmony_ci && rdr_status(s) == SANE_STATUS_GOOD) 866141cc406Sopenharmony_ci { 867141cc406Sopenharmony_ci usleep(10); /* could perhaps be longer. make this user configurable?? */ 868141cc406Sopenharmony_ci } 869141cc406Sopenharmony_ci 870141cc406Sopenharmony_ci if (rdr_status(s) != SANE_STATUS_GOOD) 871141cc406Sopenharmony_ci { 872141cc406Sopenharmony_ci return rdr_status(s); 873141cc406Sopenharmony_ci DBG(11, ">>\n"); 874141cc406Sopenharmony_ci } 875141cc406Sopenharmony_ci 876141cc406Sopenharmony_ci copysize = bc->used - bc->start; 877141cc406Sopenharmony_ci 878141cc406Sopenharmony_ci if (copysize > *buf_size - copied ) 879141cc406Sopenharmony_ci copysize = *buf_size - copied; 880141cc406Sopenharmony_ci 881141cc406Sopenharmony_ci memcpy(buf, &(bc->buffer[bc->start]), copysize); 882141cc406Sopenharmony_ci 883141cc406Sopenharmony_ci copied += copysize; 884141cc406Sopenharmony_ci buf = &buf[copysize]; 885141cc406Sopenharmony_ci 886141cc406Sopenharmony_ci bc->start += copysize; 887141cc406Sopenharmony_ci if (bc->start >= bc->used) 888141cc406Sopenharmony_ci { 889141cc406Sopenharmony_ci bc->start = 0; 890141cc406Sopenharmony_ci bc->shm_status = SHM_EMPTY; 891141cc406Sopenharmony_ci s->read_buff++; 892141cc406Sopenharmony_ci if (s->read_buff == s->dev->info.buffers) 893141cc406Sopenharmony_ci s->read_buff = 0; 894141cc406Sopenharmony_ci bc = &s->rdr_ctl->buf_ctl[s->read_buff]; 895141cc406Sopenharmony_ci } 896141cc406Sopenharmony_ci } 897141cc406Sopenharmony_ci 898141cc406Sopenharmony_ci DBG(11, ">>\n"); 899141cc406Sopenharmony_ci return SANE_STATUS_GOOD; 900141cc406Sopenharmony_ci} 901141cc406Sopenharmony_ci 902141cc406Sopenharmony_ci#else /* don't USE_FORK: */ 903141cc406Sopenharmony_ci 904141cc406Sopenharmony_cistatic SANE_Status 905141cc406Sopenharmony_ciread_data (NEC_Scanner *s, SANE_Byte *buf, size_t * buf_size) 906141cc406Sopenharmony_ci{ 907141cc406Sopenharmony_ci static u_char cmd[] = {READ, 0, 0, 0, 0, 0, 0, 0, 0, 0}; 908141cc406Sopenharmony_ci SANE_Status status = SANE_STATUS_GOOD; 909141cc406Sopenharmony_ci size_t remain = *buf_size; 910141cc406Sopenharmony_ci size_t nread; 911141cc406Sopenharmony_ci DBG (11, "<< read_data "); 912141cc406Sopenharmony_ci 913141cc406Sopenharmony_ci /* sane_read_shuffled requires that read_data returns 914141cc406Sopenharmony_ci exactly *buf_size bytes, so it must be guaranteed here. 915141cc406Sopenharmony_ci Further make sure that not more bytes are read in than 916141cc406Sopenharmony_ci sanei_scsi_max_request_size allows, to avoid a failure 917141cc406Sopenharmony_ci of the read command 918141cc406Sopenharmony_ci */ 919141cc406Sopenharmony_ci while (remain > 0) 920141cc406Sopenharmony_ci { 921141cc406Sopenharmony_ci nread = remain; 922141cc406Sopenharmony_ci if (nread > s->dev->info.bufsize) 923141cc406Sopenharmony_ci nread = s->dev->info.bufsize; 924141cc406Sopenharmony_ci cmd[6] = nread >> 16; 925141cc406Sopenharmony_ci cmd[7] = nread >> 8; 926141cc406Sopenharmony_ci cmd[8] = nread; 927141cc406Sopenharmony_ci status = sanei_scsi_cmd (s->fd, cmd, sizeof (cmd), 928141cc406Sopenharmony_ci &buf[*buf_size - remain], &nread); 929141cc406Sopenharmony_ci if (status != SANE_STATUS_GOOD) 930141cc406Sopenharmony_ci { 931141cc406Sopenharmony_ci DBG(11, ">>\n"); 932141cc406Sopenharmony_ci return(status); 933141cc406Sopenharmony_ci } 934141cc406Sopenharmony_ci remain -= nread; 935141cc406Sopenharmony_ci } 936141cc406Sopenharmony_ci DBG (11, ">>\n"); 937141cc406Sopenharmony_ci return (status); 938141cc406Sopenharmony_ci} 939141cc406Sopenharmony_ci#endif 940141cc406Sopenharmony_ci 941141cc406Sopenharmony_cistatic size_t 942141cc406Sopenharmony_cimax_string_size (const SANE_String_Const strings[]) 943141cc406Sopenharmony_ci{ 944141cc406Sopenharmony_ci size_t size, max_size = 0; 945141cc406Sopenharmony_ci int i; 946141cc406Sopenharmony_ci DBG (10, "<< max_string_size "); 947141cc406Sopenharmony_ci 948141cc406Sopenharmony_ci for (i = 0; strings[i]; ++i) 949141cc406Sopenharmony_ci { 950141cc406Sopenharmony_ci size = strlen (strings[i]) + 1; 951141cc406Sopenharmony_ci if (size > max_size) 952141cc406Sopenharmony_ci max_size = size; 953141cc406Sopenharmony_ci } 954141cc406Sopenharmony_ci 955141cc406Sopenharmony_ci DBG (10, ">>\n"); 956141cc406Sopenharmony_ci return max_size; 957141cc406Sopenharmony_ci} 958141cc406Sopenharmony_ci 959141cc406Sopenharmony_cistatic SANE_Status 960141cc406Sopenharmony_ciwait_ready(int fd) 961141cc406Sopenharmony_ci{ 962141cc406Sopenharmony_ci SANE_Status status; 963141cc406Sopenharmony_ci int retry = 0; 964141cc406Sopenharmony_ci 965141cc406Sopenharmony_ci while ((status = test_unit_ready (fd)) != SANE_STATUS_GOOD) 966141cc406Sopenharmony_ci { 967141cc406Sopenharmony_ci DBG (5, "wait_ready failed (%d)\n", retry); 968141cc406Sopenharmony_ci DBG (5, "wait_ready status = (%d)\n", status); 969141cc406Sopenharmony_ci if (retry++ > 15){ 970141cc406Sopenharmony_ci return SANE_STATUS_IO_ERROR; 971141cc406Sopenharmony_ci } 972141cc406Sopenharmony_ci sleep(3); 973141cc406Sopenharmony_ci } 974141cc406Sopenharmony_ci return (status); 975141cc406Sopenharmony_ci 976141cc406Sopenharmony_ci} 977141cc406Sopenharmony_ci 978141cc406Sopenharmony_cistatic SANE_Status 979141cc406Sopenharmony_ciattach (const char *devnam, NEC_Device ** devp) 980141cc406Sopenharmony_ci{ 981141cc406Sopenharmony_ci SANE_Status status; 982141cc406Sopenharmony_ci NEC_Device *dev; 983141cc406Sopenharmony_ci NEC_Sense_Data sensedat; 984141cc406Sopenharmony_ci 985141cc406Sopenharmony_ci int fd; 986141cc406Sopenharmony_ci unsigned char inquiry_data[INQUIRY_LEN]; 987141cc406Sopenharmony_ci const unsigned char *model_name; 988141cc406Sopenharmony_ci mode_sense_param msp; 989141cc406Sopenharmony_ci size_t buf_size; 990141cc406Sopenharmony_ci DBG (10, "<< attach "); 991141cc406Sopenharmony_ci 992141cc406Sopenharmony_ci for (dev = first_dev; dev; dev = dev->next) 993141cc406Sopenharmony_ci { 994141cc406Sopenharmony_ci if (strcmp (dev->sane.name, devnam) == 0) 995141cc406Sopenharmony_ci { 996141cc406Sopenharmony_ci if (devp) 997141cc406Sopenharmony_ci *devp = dev; 998141cc406Sopenharmony_ci return (SANE_STATUS_GOOD); 999141cc406Sopenharmony_ci } 1000141cc406Sopenharmony_ci } 1001141cc406Sopenharmony_ci 1002141cc406Sopenharmony_ci sensedat.model = unknown; 1003141cc406Sopenharmony_ci sensedat.complain_on_adf_error = 0; 1004141cc406Sopenharmony_ci DBG (3, "attach: opening %s\n", devnam); 1005141cc406Sopenharmony_ci#ifdef HAVE_SANEI_SCSI_OPEN_EXTENDED 1006141cc406Sopenharmony_ci { 1007141cc406Sopenharmony_ci int bufsize = 4096; 1008141cc406Sopenharmony_ci status = sanei_scsi_open_extended (devnam, &fd, &sense_handler, &sensedat, &bufsize); 1009141cc406Sopenharmony_ci if (status != SANE_STATUS_GOOD) 1010141cc406Sopenharmony_ci { 1011141cc406Sopenharmony_ci DBG (1, "attach: open failed: %s\n", sane_strstatus (status)); 1012141cc406Sopenharmony_ci return (status); 1013141cc406Sopenharmony_ci } 1014141cc406Sopenharmony_ci if (bufsize < 4096) 1015141cc406Sopenharmony_ci { 1016141cc406Sopenharmony_ci DBG(1, "attach: open failed. no memory\n"); 1017141cc406Sopenharmony_ci sanei_scsi_close(fd); 1018141cc406Sopenharmony_ci return SANE_STATUS_NO_MEM; 1019141cc406Sopenharmony_ci } 1020141cc406Sopenharmony_ci } 1021141cc406Sopenharmony_ci#else 1022141cc406Sopenharmony_ci status = sanei_scsi_open (devnam, &fd, &sense_handler, &sensedat); 1023141cc406Sopenharmony_ci if (status != SANE_STATUS_GOOD) 1024141cc406Sopenharmony_ci { 1025141cc406Sopenharmony_ci DBG (1, "attach: open failed: %s\n", sane_strstatus (status)); 1026141cc406Sopenharmony_ci return (status); 1027141cc406Sopenharmony_ci } 1028141cc406Sopenharmony_ci#endif 1029141cc406Sopenharmony_ci 1030141cc406Sopenharmony_ci DBG (3, "attach: sending INQUIRY\n"); 1031141cc406Sopenharmony_ci memset (inquiry_data, 0, sizeof (inquiry_data)); 1032141cc406Sopenharmony_ci buf_size = sizeof (inquiry_data); 1033141cc406Sopenharmony_ci status = inquiry (fd, inquiry_data, &buf_size); 1034141cc406Sopenharmony_ci if (status != SANE_STATUS_GOOD) 1035141cc406Sopenharmony_ci { 1036141cc406Sopenharmony_ci DBG (1, "attach: inquiry failed: %s\n", sane_strstatus (status)); 1037141cc406Sopenharmony_ci sanei_scsi_close (fd); 1038141cc406Sopenharmony_ci return (status); 1039141cc406Sopenharmony_ci } 1040141cc406Sopenharmony_ci 1041141cc406Sopenharmony_ci if (inquiry_data[0] == 6 && strncmp ((char *)inquiry_data + 8, "NEC", 3) == 0) 1042141cc406Sopenharmony_ci { 1043141cc406Sopenharmony_ci if (strncmp ((char *)inquiry_data + 16, "PC-IN500/4C", 11) == 0) 1044141cc406Sopenharmony_ci sensedat.model = PCIN500; 1045141cc406Sopenharmony_ci else 1046141cc406Sopenharmony_ci sensedat.model = unknown; 1047141cc406Sopenharmony_ci } 1048141cc406Sopenharmony_ci 1049141cc406Sopenharmony_ci if (sensedat.model == unknown) 1050141cc406Sopenharmony_ci { 1051141cc406Sopenharmony_ci DBG (1, "attach: device doesn't look like a NEC scanner\n"); 1052141cc406Sopenharmony_ci DBG (1, " : Only PC-IN500/4C is supported.\n"); 1053141cc406Sopenharmony_ci sanei_scsi_close (fd); 1054141cc406Sopenharmony_ci return (SANE_STATUS_INVAL); 1055141cc406Sopenharmony_ci } 1056141cc406Sopenharmony_ci 1057141cc406Sopenharmony_ci DBG (3, "attach: sending TEST_UNIT_READY\n"); 1058141cc406Sopenharmony_ci status = test_unit_ready (fd); 1059141cc406Sopenharmony_ci if (status != SANE_STATUS_GOOD) 1060141cc406Sopenharmony_ci { 1061141cc406Sopenharmony_ci DBG (1, "attach: test unit ready failed (%s)\n", 1062141cc406Sopenharmony_ci sane_strstatus (status)); 1063141cc406Sopenharmony_ci sanei_scsi_close (fd); 1064141cc406Sopenharmony_ci return (status); 1065141cc406Sopenharmony_ci } 1066141cc406Sopenharmony_ci DBG (3, "attach: sending MODE SELECT\n"); 1067141cc406Sopenharmony_ci 1068141cc406Sopenharmony_ci if (sensedat.model == PCIN500) 1069141cc406Sopenharmony_ci status = mode_select_mud (fd, DEFAULT_MUD_1200); 1070141cc406Sopenharmony_ci 1071141cc406Sopenharmony_ci if (status != SANE_STATUS_GOOD) 1072141cc406Sopenharmony_ci { 1073141cc406Sopenharmony_ci DBG (1, "attach: MODE_SELECT_MUD failed\n"); 1074141cc406Sopenharmony_ci sanei_scsi_close (fd); 1075141cc406Sopenharmony_ci return (SANE_STATUS_INVAL); 1076141cc406Sopenharmony_ci } 1077141cc406Sopenharmony_ci 1078141cc406Sopenharmony_ci DBG (3, "attach: sending MODE SENSE/MUP page\n"); 1079141cc406Sopenharmony_ci memset (&msp, 0, sizeof (msp)); 1080141cc406Sopenharmony_ci buf_size = sizeof (msp); 1081141cc406Sopenharmony_ci status = mode_sense (fd, &msp, &buf_size, 3); 1082141cc406Sopenharmony_ci if (status != SANE_STATUS_GOOD) 1083141cc406Sopenharmony_ci { 1084141cc406Sopenharmony_ci DBG (1, "attach: MODE_SENSE/MUP page failed\n"); 1085141cc406Sopenharmony_ci sanei_scsi_close (fd); 1086141cc406Sopenharmony_ci return (SANE_STATUS_INVAL); 1087141cc406Sopenharmony_ci } 1088141cc406Sopenharmony_ci#ifdef DEBUG_NEC 1089141cc406Sopenharmony_ci DBG (3,"attach: MODE SENSE parameter\n"); 1090141cc406Sopenharmony_ci DBG(11, "%02x %02x %02x %02x " 1091141cc406Sopenharmony_ci "%02x %02x %02x %02x %02x %02x %02x %02x\n", 1092141cc406Sopenharmony_ci msp.mode_data_length, 1093141cc406Sopenharmony_ci msp.mode_param_header2, 1094141cc406Sopenharmony_ci msp.mode_param_header3, 1095141cc406Sopenharmony_ci msp.mode_desciptor_length, 1096141cc406Sopenharmony_ci msp.page_code, 1097141cc406Sopenharmony_ci msp.page_length, 1098141cc406Sopenharmony_ci msp.bmu, 1099141cc406Sopenharmony_ci msp.res2, 1100141cc406Sopenharmony_ci msp.mud[0], 1101141cc406Sopenharmony_ci msp.mud[1], 1102141cc406Sopenharmony_ci msp.res3, 1103141cc406Sopenharmony_ci msp.res4); 1104141cc406Sopenharmony_ci#endif 1105141cc406Sopenharmony_ci dev = malloc (sizeof (*dev)); 1106141cc406Sopenharmony_ci if (!dev) 1107141cc406Sopenharmony_ci return (SANE_STATUS_NO_MEM); 1108141cc406Sopenharmony_ci memset (dev, 0, sizeof (*dev)); 1109141cc406Sopenharmony_ci 1110141cc406Sopenharmony_ci dev->sane.name = (SANE_String) strdup (devnam); 1111141cc406Sopenharmony_ci dev->sane.vendor = "NEC"; 1112141cc406Sopenharmony_ci model_name = inquiry_data + 16; 1113141cc406Sopenharmony_ci dev->sane.model = strndup ((const char *)model_name, 10); 1114141cc406Sopenharmony_ci dev->sane.type = "flatbed scanner"; 1115141cc406Sopenharmony_ci 1116141cc406Sopenharmony_ci dev->sensedat.model = sensedat.model; 1117141cc406Sopenharmony_ci 1118141cc406Sopenharmony_ci DBG (5, "dev->sane.name = %s\n", dev->sane.name); 1119141cc406Sopenharmony_ci DBG (5, "dev->sane.vendor = %s\n", dev->sane.vendor); 1120141cc406Sopenharmony_ci DBG (5, "dev->sane.model = %s\n", dev->sane.model); 1121141cc406Sopenharmony_ci DBG (5, "dev->sane.type = %s\n", dev->sane.type); 1122141cc406Sopenharmony_ci 1123141cc406Sopenharmony_ci if (sensedat.model == PCIN500) 1124141cc406Sopenharmony_ci dev->info.res_range.quant = 10; 1125141cc406Sopenharmony_ci else 1126141cc406Sopenharmony_ci dev->info.res_range.quant = 0; 1127141cc406Sopenharmony_ci 1128141cc406Sopenharmony_ci dev->info.tl_x_ranges[SCAN_SIMPLE].min = SANE_FIX(0); 1129141cc406Sopenharmony_ci dev->info.br_x_ranges[SCAN_SIMPLE].min = SANE_FIX(1); 1130141cc406Sopenharmony_ci dev->info.tl_y_ranges[SCAN_SIMPLE].min = SANE_FIX(0); 1131141cc406Sopenharmony_ci dev->info.br_y_ranges[SCAN_SIMPLE].min = SANE_FIX(1); 1132141cc406Sopenharmony_ci dev->info.tl_x_ranges[SCAN_SIMPLE].quant = SANE_FIX(0); 1133141cc406Sopenharmony_ci dev->info.br_x_ranges[SCAN_SIMPLE].quant = SANE_FIX(0); 1134141cc406Sopenharmony_ci dev->info.tl_y_ranges[SCAN_SIMPLE].quant = SANE_FIX(0); 1135141cc406Sopenharmony_ci dev->info.br_y_ranges[SCAN_SIMPLE].quant = SANE_FIX(0); 1136141cc406Sopenharmony_ci 1137141cc406Sopenharmony_ci if (sensedat.model == PCIN500) 1138141cc406Sopenharmony_ci dev->info.res_default = 15; 1139141cc406Sopenharmony_ci else 1140141cc406Sopenharmony_ci dev->info.res_default = 150; 1141141cc406Sopenharmony_ci dev->info.tl_x_ranges[SCAN_SIMPLE].max = SANE_FIX(209); 1142141cc406Sopenharmony_ci dev->info.br_x_ranges[SCAN_SIMPLE].max = SANE_FIX(210); 1143141cc406Sopenharmony_ci dev->info.tl_y_ranges[SCAN_SIMPLE].max = SANE_FIX(296); 1144141cc406Sopenharmony_ci dev->info.br_y_ranges[SCAN_SIMPLE].max = SANE_FIX(297); 1145141cc406Sopenharmony_ci 1146141cc406Sopenharmony_ci dev->info.bmu = msp.bmu; 1147141cc406Sopenharmony_ci dev->info.mud = (msp.mud[0] << 8) + msp.mud[1]; 1148141cc406Sopenharmony_ci 1149141cc406Sopenharmony_ci dev->info.adf_fsu_installed = 0; 1150141cc406Sopenharmony_ci if (dev->sensedat.model == PCIN500) 1151141cc406Sopenharmony_ci { 1152141cc406Sopenharmony_ci dev->info.res_range.max = 48; 1153141cc406Sopenharmony_ci dev->info.res_range.min = 5; 1154141cc406Sopenharmony_ci 1155141cc406Sopenharmony_ci dev->info.x_default = SANE_FIX(210); 1156141cc406Sopenharmony_ci dev->info.tl_x_ranges[SCAN_SIMPLE].max = SANE_FIX(210); /* 304.8mm is the real max */ 1157141cc406Sopenharmony_ci dev->info.br_x_ranges[SCAN_SIMPLE].max = SANE_FIX(210); /* 304.8mm is the real max */ 1158141cc406Sopenharmony_ci 1159141cc406Sopenharmony_ci dev->info.y_default = SANE_FIX(297); 1160141cc406Sopenharmony_ci dev->info.tl_y_ranges[SCAN_SIMPLE].max = SANE_FIX(297); /* 431.8 is the real max */ 1161141cc406Sopenharmony_ci dev->info.br_y_ranges[SCAN_SIMPLE].max = SANE_FIX(297); /* 431.8 is the real max */ 1162141cc406Sopenharmony_ci } 1163141cc406Sopenharmony_ci else 1164141cc406Sopenharmony_ci { 1165141cc406Sopenharmony_ci dev->info.res_range.max = 400; 1166141cc406Sopenharmony_ci dev->info.res_range.min = 50; 1167141cc406Sopenharmony_ci 1168141cc406Sopenharmony_ci dev->info.x_default = SANE_FIX(210); 1169141cc406Sopenharmony_ci dev->info.tl_x_ranges[SCAN_SIMPLE].max = SANE_FIX(210); /* 304.8mm is the real max */ 1170141cc406Sopenharmony_ci dev->info.br_x_ranges[SCAN_SIMPLE].max = SANE_FIX(210); /* 304.8mm is the real max */ 1171141cc406Sopenharmony_ci 1172141cc406Sopenharmony_ci dev->info.y_default = SANE_FIX(297); 1173141cc406Sopenharmony_ci dev->info.tl_y_ranges[SCAN_SIMPLE].max = SANE_FIX(297); /* 431.8 is the real max */ 1174141cc406Sopenharmony_ci dev->info.br_y_ranges[SCAN_SIMPLE].max = SANE_FIX(297); /* 431.8 is the real max */ 1175141cc406Sopenharmony_ci } 1176141cc406Sopenharmony_ci sanei_scsi_close (fd); 1177141cc406Sopenharmony_ci 1178141cc406Sopenharmony_ci dev->info.threshold_range.min = 1; 1179141cc406Sopenharmony_ci dev->info.threshold_range.max = 255; 1180141cc406Sopenharmony_ci dev->info.threshold_range.quant = 0; 1181141cc406Sopenharmony_ci 1182141cc406Sopenharmony_ci dev->info.tint_range.min = 1; 1183141cc406Sopenharmony_ci dev->info.tint_range.max = 255; 1184141cc406Sopenharmony_ci dev->info.tint_range.quant = 0; 1185141cc406Sopenharmony_ci 1186141cc406Sopenharmony_ci dev->info.color_range.min = 1; 1187141cc406Sopenharmony_ci dev->info.color_range.max = 255; 1188141cc406Sopenharmony_ci dev->info.color_range.quant = 0; 1189141cc406Sopenharmony_ci 1190141cc406Sopenharmony_ci DBG (5, "res_default=%d\n", dev->info.res_default); 1191141cc406Sopenharmony_ci DBG (5, "res_range.max=%d\n", dev->info.res_range.max); 1192141cc406Sopenharmony_ci DBG (5, "res_range.min=%d\n", dev->info.res_range.min); 1193141cc406Sopenharmony_ci DBG (5, "res_range.quant=%d\n", dev->info.res_range.quant); 1194141cc406Sopenharmony_ci 1195141cc406Sopenharmony_ci DBG (5, "x_default=%f\n", SANE_UNFIX(dev->info.x_default)); 1196141cc406Sopenharmony_ci DBG (5, "tl_x_range[0].max=%f\n", SANE_UNFIX(dev->info.tl_x_ranges[SCAN_SIMPLE].max)); 1197141cc406Sopenharmony_ci DBG (5, "tl_x_range[0].min=%f\n", SANE_UNFIX(dev->info.tl_x_ranges[SCAN_SIMPLE].min)); 1198141cc406Sopenharmony_ci DBG (5, "tl_x_range[0].quant=%d\n", dev->info.tl_x_ranges[SCAN_SIMPLE].quant); 1199141cc406Sopenharmony_ci DBG (5, "br_x_range[0].max=%f\n", SANE_UNFIX(dev->info.br_x_ranges[SCAN_SIMPLE].max)); 1200141cc406Sopenharmony_ci DBG (5, "br_x_range[0].min=%f\n", SANE_UNFIX(dev->info.br_x_ranges[SCAN_SIMPLE].min)); 1201141cc406Sopenharmony_ci DBG (5, "br_x_range[0].quant=%d\n", dev->info.br_x_ranges[SCAN_SIMPLE].quant); 1202141cc406Sopenharmony_ci DBG (5, "y_default=%f\n", SANE_UNFIX(dev->info.y_default)); 1203141cc406Sopenharmony_ci DBG (5, "tl_y_range[0].max=%f\n", SANE_UNFIX(dev->info.tl_y_ranges[SCAN_SIMPLE].max)); 1204141cc406Sopenharmony_ci DBG (5, "tl_y_range[0].min=%f\n", SANE_UNFIX(dev->info.tl_y_ranges[SCAN_SIMPLE].min)); 1205141cc406Sopenharmony_ci DBG (5, "tl_y_range[0].quant=%d\n", dev->info.tl_y_ranges[SCAN_SIMPLE].quant); 1206141cc406Sopenharmony_ci DBG (5, "br_y_range[0].max=%f\n", SANE_UNFIX(dev->info.br_y_ranges[SCAN_SIMPLE].max)); 1207141cc406Sopenharmony_ci DBG (5, "br_y_range[0].min=%f\n", SANE_UNFIX(dev->info.br_y_ranges[SCAN_SIMPLE].min)); 1208141cc406Sopenharmony_ci DBG (5, "br_y_range[0].quant=%d\n", dev->info.br_y_ranges[SCAN_SIMPLE].quant); 1209141cc406Sopenharmony_ci 1210141cc406Sopenharmony_ci if (dev->info.adf_fsu_installed & HAVE_FSU) 1211141cc406Sopenharmony_ci { 1212141cc406Sopenharmony_ci DBG (5, "tl_x_range[1].max=%f\n", SANE_UNFIX(dev->info.tl_x_ranges[SCAN_WITH_FSU].max)); 1213141cc406Sopenharmony_ci DBG (5, "tl_x_range[1].min=%f\n", SANE_UNFIX(dev->info.tl_x_ranges[SCAN_WITH_FSU].min)); 1214141cc406Sopenharmony_ci DBG (5, "tl_x_range[1].quant=%d\n", dev->info.tl_x_ranges[SCAN_WITH_FSU].quant); 1215141cc406Sopenharmony_ci DBG (5, "br_x_range[1].max=%f\n", SANE_UNFIX(dev->info.br_x_ranges[SCAN_WITH_FSU].max)); 1216141cc406Sopenharmony_ci DBG (5, "br_x_range[1].min=%f\n", SANE_UNFIX(dev->info.br_x_ranges[SCAN_WITH_FSU].min)); 1217141cc406Sopenharmony_ci DBG (5, "br_x_range[1].quant=%d\n", dev->info.br_x_ranges[SCAN_WITH_FSU].quant); 1218141cc406Sopenharmony_ci DBG (5, "tl_y_range[1].max=%f\n", SANE_UNFIX(dev->info.tl_y_ranges[SCAN_WITH_FSU].max)); 1219141cc406Sopenharmony_ci DBG (5, "tl_y_range[1].min=%f\n", SANE_UNFIX(dev->info.tl_y_ranges[SCAN_WITH_FSU].min)); 1220141cc406Sopenharmony_ci DBG (5, "tl_y_range[1].quant=%d\n", dev->info.tl_y_ranges[SCAN_WITH_FSU].quant); 1221141cc406Sopenharmony_ci DBG (5, "br_y_range[1].max=%f\n", SANE_UNFIX(dev->info.br_y_ranges[SCAN_WITH_FSU].max)); 1222141cc406Sopenharmony_ci DBG (5, "br_y_range[1].min=%f\n", SANE_UNFIX(dev->info.br_y_ranges[SCAN_WITH_FSU].min)); 1223141cc406Sopenharmony_ci DBG (5, "br_y_range[1].quant=%d\n", dev->info.br_y_ranges[SCAN_WITH_FSU].quant); 1224141cc406Sopenharmony_ci } 1225141cc406Sopenharmony_ci 1226141cc406Sopenharmony_ci if (dev->info.adf_fsu_installed & HAVE_ADF) 1227141cc406Sopenharmony_ci { 1228141cc406Sopenharmony_ci DBG (5, "tl_x_range[2].max=%f\n", SANE_UNFIX(dev->info.tl_x_ranges[SCAN_WITH_ADF].max)); 1229141cc406Sopenharmony_ci DBG (5, "tl_x_range[2].min=%f\n", SANE_UNFIX(dev->info.tl_x_ranges[SCAN_WITH_ADF].min)); 1230141cc406Sopenharmony_ci DBG (5, "tl_x_range[2].quant=%d\n", dev->info.tl_x_ranges[SCAN_WITH_ADF].quant); 1231141cc406Sopenharmony_ci DBG (5, "br_x_range[2].max=%f\n", SANE_UNFIX(dev->info.br_x_ranges[SCAN_WITH_ADF].max)); 1232141cc406Sopenharmony_ci DBG (5, "br_x_range[2].min=%f\n", SANE_UNFIX(dev->info.br_x_ranges[SCAN_WITH_ADF].min)); 1233141cc406Sopenharmony_ci DBG (5, "br_x_range[2].quant=%d\n", dev->info.br_x_ranges[SCAN_WITH_ADF].quant); 1234141cc406Sopenharmony_ci DBG (5, "tl_y_range[2].max=%f\n", SANE_UNFIX(dev->info.tl_y_ranges[SCAN_WITH_ADF].max)); 1235141cc406Sopenharmony_ci DBG (5, "tl_y_range[2].min=%f\n", SANE_UNFIX(dev->info.tl_y_ranges[SCAN_WITH_ADF].min)); 1236141cc406Sopenharmony_ci DBG (5, "tl_y_range[2].quant=%d\n", dev->info.tl_y_ranges[SCAN_WITH_ADF].quant); 1237141cc406Sopenharmony_ci DBG (5, "br_y_range[2].max=%f\n", SANE_UNFIX(dev->info.br_y_ranges[SCAN_WITH_ADF].max)); 1238141cc406Sopenharmony_ci DBG (5, "br_y_range[2].min=%f\n", SANE_UNFIX(dev->info.br_y_ranges[SCAN_WITH_ADF].min)); 1239141cc406Sopenharmony_ci DBG (5, "br_y_range[2].quant=%d\n", dev->info.br_y_ranges[SCAN_WITH_ADF].quant); 1240141cc406Sopenharmony_ci } 1241141cc406Sopenharmony_ci 1242141cc406Sopenharmony_ci DBG (5, "bmu=%d\n", dev->info.bmu); 1243141cc406Sopenharmony_ci DBG (5, "mud=%d\n", dev->info.mud); 1244141cc406Sopenharmony_ci 1245141cc406Sopenharmony_ci ++num_devices; 1246141cc406Sopenharmony_ci dev->next = first_dev; 1247141cc406Sopenharmony_ci first_dev = dev; 1248141cc406Sopenharmony_ci 1249141cc406Sopenharmony_ci if (devp) 1250141cc406Sopenharmony_ci *devp = dev; 1251141cc406Sopenharmony_ci 1252141cc406Sopenharmony_ci DBG (10, ">>\n"); 1253141cc406Sopenharmony_ci return (SANE_STATUS_GOOD); 1254141cc406Sopenharmony_ci} 1255141cc406Sopenharmony_ci 1256141cc406Sopenharmony_ci/* Enabling / disabling of gamma options. 1257141cc406Sopenharmony_ci Depends on many user settable options, so lets put it into 1258141cc406Sopenharmony_ci one function to be called by init_options and by sane_control_option 1259141cc406Sopenharmony_ci 1260141cc406Sopenharmony_ci*/ 1261141cc406Sopenharmony_ci#ifdef USE_CUSTOM_GAMMA 1262141cc406Sopenharmony_cistatic void 1263141cc406Sopenharmony_ciset_gamma_caps(NEC_Scanner *s) 1264141cc406Sopenharmony_ci{ 1265141cc406Sopenharmony_ci /* neither fixed nor custom gamma for line art modes */ 1266141cc406Sopenharmony_ci if ( strcmp(s->val[OPT_MODE].s, M_LINEART) == 0 1267141cc406Sopenharmony_ci || strcmp(s->val[OPT_MODE].s, M_LINEART_COLOR) == 0) 1268141cc406Sopenharmony_ci { 1269141cc406Sopenharmony_ci s->opt[OPT_GAMMA].cap |= SANE_CAP_INACTIVE; 1270141cc406Sopenharmony_ci s->opt[OPT_CUSTOM_GAMMA].cap |= SANE_CAP_INACTIVE; 1271141cc406Sopenharmony_ci s->opt[OPT_GAMMA_VECTOR].cap |= SANE_CAP_INACTIVE; 1272141cc406Sopenharmony_ci s->opt[OPT_GAMMA_VECTOR_R].cap |= SANE_CAP_INACTIVE; 1273141cc406Sopenharmony_ci s->opt[OPT_GAMMA_VECTOR_G].cap |= SANE_CAP_INACTIVE; 1274141cc406Sopenharmony_ci s->opt[OPT_GAMMA_VECTOR_B].cap |= SANE_CAP_INACTIVE; 1275141cc406Sopenharmony_ci } 1276141cc406Sopenharmony_ci else if (strcmp(s->val[OPT_MODE].s, M_GRAY) == 0) 1277141cc406Sopenharmony_ci { 1278141cc406Sopenharmony_ci s->opt[OPT_CUSTOM_GAMMA].cap &= ~SANE_CAP_INACTIVE; 1279141cc406Sopenharmony_ci if (s->val[OPT_CUSTOM_GAMMA].w == SANE_FALSE) 1280141cc406Sopenharmony_ci { 1281141cc406Sopenharmony_ci s->opt[OPT_GAMMA].cap &= ~SANE_CAP_INACTIVE; 1282141cc406Sopenharmony_ci s->opt[OPT_GAMMA_VECTOR].cap |= SANE_CAP_INACTIVE; 1283141cc406Sopenharmony_ci } 1284141cc406Sopenharmony_ci else 1285141cc406Sopenharmony_ci { 1286141cc406Sopenharmony_ci s->opt[OPT_GAMMA].cap |= SANE_CAP_INACTIVE; 1287141cc406Sopenharmony_ci s->opt[OPT_GAMMA_VECTOR].cap &= ~SANE_CAP_INACTIVE; 1288141cc406Sopenharmony_ci } 1289141cc406Sopenharmony_ci s->opt[OPT_GAMMA_VECTOR_R].cap |= SANE_CAP_INACTIVE; 1290141cc406Sopenharmony_ci s->opt[OPT_GAMMA_VECTOR_G].cap |= SANE_CAP_INACTIVE; 1291141cc406Sopenharmony_ci s->opt[OPT_GAMMA_VECTOR_B].cap |= SANE_CAP_INACTIVE; 1292141cc406Sopenharmony_ci } 1293141cc406Sopenharmony_ci else 1294141cc406Sopenharmony_ci { 1295141cc406Sopenharmony_ci /* color mode */ 1296141cc406Sopenharmony_ci s->opt[OPT_CUSTOM_GAMMA].cap &= ~SANE_CAP_INACTIVE; 1297141cc406Sopenharmony_ci if (s->val[OPT_CUSTOM_GAMMA].w == SANE_FALSE) 1298141cc406Sopenharmony_ci { 1299141cc406Sopenharmony_ci s->opt[OPT_GAMMA].cap &= ~SANE_CAP_INACTIVE; 1300141cc406Sopenharmony_ci s->opt[OPT_GAMMA_VECTOR_R].cap |= SANE_CAP_INACTIVE; 1301141cc406Sopenharmony_ci s->opt[OPT_GAMMA_VECTOR_G].cap |= SANE_CAP_INACTIVE; 1302141cc406Sopenharmony_ci s->opt[OPT_GAMMA_VECTOR_B].cap |= SANE_CAP_INACTIVE; 1303141cc406Sopenharmony_ci } 1304141cc406Sopenharmony_ci else 1305141cc406Sopenharmony_ci { 1306141cc406Sopenharmony_ci s->opt[OPT_GAMMA].cap |= SANE_CAP_INACTIVE; 1307141cc406Sopenharmony_ci s->opt[OPT_GAMMA_VECTOR_R].cap &= ~SANE_CAP_INACTIVE; 1308141cc406Sopenharmony_ci s->opt[OPT_GAMMA_VECTOR_G].cap &= ~SANE_CAP_INACTIVE; 1309141cc406Sopenharmony_ci s->opt[OPT_GAMMA_VECTOR_B].cap &= ~SANE_CAP_INACTIVE; 1310141cc406Sopenharmony_ci } 1311141cc406Sopenharmony_ci s->opt[OPT_GAMMA_VECTOR].cap |= SANE_CAP_INACTIVE; 1312141cc406Sopenharmony_ci } 1313141cc406Sopenharmony_ci} 1314141cc406Sopenharmony_ci#endif /* USE_CUSTOM_GAMMA */ 1315141cc406Sopenharmony_ci 1316141cc406Sopenharmony_ci/* The next function is a slightly modified version of sanei_constrain_value 1317141cc406Sopenharmony_ci Instead of returning status information like STATUS_INVAL, it adjusts 1318141cc406Sopenharmony_ci an invalid value to the nearest allowed one. 1319141cc406Sopenharmony_ci*/ 1320141cc406Sopenharmony_cistatic void 1321141cc406Sopenharmony_ciclip_value (const SANE_Option_Descriptor * opt, void * value) 1322141cc406Sopenharmony_ci{ 1323141cc406Sopenharmony_ci const SANE_String_Const * string_list; 1324141cc406Sopenharmony_ci const SANE_Word * word_list; 1325141cc406Sopenharmony_ci int i, num_matches, match; 1326141cc406Sopenharmony_ci const SANE_Range * range; 1327141cc406Sopenharmony_ci SANE_Word w, v; 1328141cc406Sopenharmony_ci size_t len; 1329141cc406Sopenharmony_ci 1330141cc406Sopenharmony_ci switch (opt->constraint_type) 1331141cc406Sopenharmony_ci { 1332141cc406Sopenharmony_ci case SANE_CONSTRAINT_RANGE: 1333141cc406Sopenharmony_ci w = *(SANE_Word *) value; 1334141cc406Sopenharmony_ci range = opt->constraint.range; 1335141cc406Sopenharmony_ci 1336141cc406Sopenharmony_ci if (w < range->min) 1337141cc406Sopenharmony_ci w = range->min; 1338141cc406Sopenharmony_ci else if (w > range->max) 1339141cc406Sopenharmony_ci w = range->max; 1340141cc406Sopenharmony_ci 1341141cc406Sopenharmony_ci if (range->quant) 1342141cc406Sopenharmony_ci { 1343141cc406Sopenharmony_ci v = (w - range->min + range->quant/2) / range->quant; 1344141cc406Sopenharmony_ci w = v * range->quant + range->min; 1345141cc406Sopenharmony_ci *(SANE_Word*) value = w; 1346141cc406Sopenharmony_ci } 1347141cc406Sopenharmony_ci break; 1348141cc406Sopenharmony_ci 1349141cc406Sopenharmony_ci case SANE_CONSTRAINT_WORD_LIST: 1350141cc406Sopenharmony_ci w = *(SANE_Word *) value; 1351141cc406Sopenharmony_ci word_list = opt->constraint.word_list; 1352141cc406Sopenharmony_ci for (i = 1; w != word_list[i]; ++i) 1353141cc406Sopenharmony_ci if (i >= word_list[0]) 1354141cc406Sopenharmony_ci /* somewhat arbitrary... Would be better to have a default value 1355141cc406Sopenharmony_ci explicitly defined. 1356141cc406Sopenharmony_ci */ 1357141cc406Sopenharmony_ci *(SANE_Word*) value = word_list[1]; 1358141cc406Sopenharmony_ci break; 1359141cc406Sopenharmony_ci 1360141cc406Sopenharmony_ci case SANE_CONSTRAINT_STRING_LIST: 1361141cc406Sopenharmony_ci /* Matching algorithm: take the longest unique match ignoring 1362141cc406Sopenharmony_ci case. If there is an exact match, it is admissible even if 1363141cc406Sopenharmony_ci the same string is a prefix of a longer option name. */ 1364141cc406Sopenharmony_ci string_list = opt->constraint.string_list; 1365141cc406Sopenharmony_ci len = strlen (value); 1366141cc406Sopenharmony_ci 1367141cc406Sopenharmony_ci /* count how many matches of length LEN characters we have: */ 1368141cc406Sopenharmony_ci num_matches = 0; 1369141cc406Sopenharmony_ci match = -1; 1370141cc406Sopenharmony_ci for (i = 0; string_list[i]; ++i) 1371141cc406Sopenharmony_ci if (strncasecmp (value, string_list[i], len) == 0 1372141cc406Sopenharmony_ci && len <= strlen (string_list[i])) 1373141cc406Sopenharmony_ci { 1374141cc406Sopenharmony_ci match = i; 1375141cc406Sopenharmony_ci if (len == strlen (string_list[i])) 1376141cc406Sopenharmony_ci { 1377141cc406Sopenharmony_ci /* exact match... */ 1378141cc406Sopenharmony_ci if (strcmp (value, string_list[i]) != 0) 1379141cc406Sopenharmony_ci /* ...but case differs */ 1380141cc406Sopenharmony_ci strcpy (value, string_list[match]); 1381141cc406Sopenharmony_ci } 1382141cc406Sopenharmony_ci ++num_matches; 1383141cc406Sopenharmony_ci } 1384141cc406Sopenharmony_ci 1385141cc406Sopenharmony_ci if (num_matches > 1) 1386141cc406Sopenharmony_ci /* xxx quite arbitrary... We could also choose the first match 1387141cc406Sopenharmony_ci */ 1388141cc406Sopenharmony_ci strcpy(value, string_list[match]); 1389141cc406Sopenharmony_ci else if (num_matches == 1) 1390141cc406Sopenharmony_ci strcpy (value, string_list[match]); 1391141cc406Sopenharmony_ci else 1392141cc406Sopenharmony_ci strcpy (value, string_list[0]); 1393141cc406Sopenharmony_ci 1394141cc406Sopenharmony_ci default: 1395141cc406Sopenharmony_ci break; 1396141cc406Sopenharmony_ci } 1397141cc406Sopenharmony_ci} 1398141cc406Sopenharmony_ci 1399141cc406Sopenharmony_ci/* make sure that enough memory is allocated for each string, 1400141cc406Sopenharmony_ci so that the strcpy in sane_control_option / set value cannot 1401141cc406Sopenharmony_ci write behind the end of the allocated memory. 1402141cc406Sopenharmony_ci*/ 1403141cc406Sopenharmony_cistatic SANE_Status 1404141cc406Sopenharmony_ciinit_string_option(NEC_Scanner *s, SANE_String_Const name, 1405141cc406Sopenharmony_ci SANE_String_Const title, SANE_String_Const desc, 1406141cc406Sopenharmony_ci const SANE_String_Const *string_list, int option, int default_index) 1407141cc406Sopenharmony_ci{ 1408141cc406Sopenharmony_ci int i; 1409141cc406Sopenharmony_ci 1410141cc406Sopenharmony_ci s->opt[option].name = name; 1411141cc406Sopenharmony_ci s->opt[option].title = title; 1412141cc406Sopenharmony_ci s->opt[option].desc = desc; 1413141cc406Sopenharmony_ci s->opt[option].type = SANE_TYPE_STRING; 1414141cc406Sopenharmony_ci s->opt[option].size = max_string_size (string_list); 1415141cc406Sopenharmony_ci s->opt[option].constraint_type = SANE_CONSTRAINT_STRING_LIST; 1416141cc406Sopenharmony_ci s->opt[option].constraint.string_list = string_list; 1417141cc406Sopenharmony_ci s->val[option].s = malloc(s->opt[option].size); 1418141cc406Sopenharmony_ci if (s->val[option].s == 0) 1419141cc406Sopenharmony_ci { 1420141cc406Sopenharmony_ci for (i = 1; i < NUM_OPTIONS; i++) 1421141cc406Sopenharmony_ci { 1422141cc406Sopenharmony_ci if (s->val[i].s && s->opt[i].type == SANE_TYPE_STRING) 1423141cc406Sopenharmony_ci free(s->val[i].s); 1424141cc406Sopenharmony_ci } 1425141cc406Sopenharmony_ci return SANE_STATUS_NO_MEM; 1426141cc406Sopenharmony_ci } 1427141cc406Sopenharmony_ci strcpy(s->val[option].s, string_list[default_index]); 1428141cc406Sopenharmony_ci return SANE_STATUS_GOOD; 1429141cc406Sopenharmony_ci} 1430141cc406Sopenharmony_ci 1431141cc406Sopenharmony_cistatic SANE_Status 1432141cc406Sopenharmony_ciinit_options (NEC_Scanner * s) 1433141cc406Sopenharmony_ci{ 1434141cc406Sopenharmony_ci int i, default_source; 1435141cc406Sopenharmony_ci SANE_Word scalar; 1436141cc406Sopenharmony_ci DBG (10, "<< init_options "); 1437141cc406Sopenharmony_ci 1438141cc406Sopenharmony_ci memset (s->opt, 0, sizeof (s->opt)); 1439141cc406Sopenharmony_ci memset (s->val, 0, sizeof (s->val)); 1440141cc406Sopenharmony_ci 1441141cc406Sopenharmony_ci for (i = 0; i < NUM_OPTIONS; ++i) 1442141cc406Sopenharmony_ci { 1443141cc406Sopenharmony_ci s->opt[i].size = sizeof (SANE_Word); 1444141cc406Sopenharmony_ci s->opt[i].cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT; 1445141cc406Sopenharmony_ci s->val[i].s = 0; 1446141cc406Sopenharmony_ci } 1447141cc406Sopenharmony_ci 1448141cc406Sopenharmony_ci s->opt[OPT_NUM_OPTS].title = SANE_TITLE_NUM_OPTIONS; 1449141cc406Sopenharmony_ci s->opt[OPT_NUM_OPTS].desc = SANE_DESC_NUM_OPTIONS; 1450141cc406Sopenharmony_ci s->opt[OPT_NUM_OPTS].type = SANE_TYPE_INT; 1451141cc406Sopenharmony_ci s->opt[OPT_NUM_OPTS].cap = SANE_CAP_SOFT_DETECT; 1452141cc406Sopenharmony_ci s->val[OPT_NUM_OPTS].w = NUM_OPTIONS; 1453141cc406Sopenharmony_ci 1454141cc406Sopenharmony_ci /* Mode group: */ 1455141cc406Sopenharmony_ci s->opt[OPT_MODE_GROUP].title = "Scan Mode"; 1456141cc406Sopenharmony_ci s->opt[OPT_MODE_GROUP].desc = ""; 1457141cc406Sopenharmony_ci s->opt[OPT_MODE_GROUP].type = SANE_TYPE_GROUP; 1458141cc406Sopenharmony_ci s->opt[OPT_MODE_GROUP].cap = 0; 1459141cc406Sopenharmony_ci s->opt[OPT_MODE_GROUP].constraint_type = SANE_CONSTRAINT_NONE; 1460141cc406Sopenharmony_ci 1461141cc406Sopenharmony_ci /* scan mode */ 1462141cc406Sopenharmony_ci init_string_option(s, SANE_NAME_SCAN_MODE, SANE_TITLE_SCAN_MODE, 1463141cc406Sopenharmony_ci SANE_DESC_SCAN_MODE, mode_list, OPT_MODE, MODES_COLOR); 1464141cc406Sopenharmony_ci 1465141cc406Sopenharmony_ci /* half tone */ 1466141cc406Sopenharmony_ci init_string_option(s, SANE_NAME_HALFTONE_PATTERN, SANE_TITLE_HALFTONE_PATTERN, 1467141cc406Sopenharmony_ci SANE_DESC_HALFTONE " (not support)", halftone_list, OPT_HALFTONE, 0); 1468141cc406Sopenharmony_ci 1469141cc406Sopenharmony_ci if (s->dev->sensedat.model == PCIN500) 1470141cc406Sopenharmony_ci s->opt[OPT_HALFTONE].cap |= SANE_CAP_INACTIVE; 1471141cc406Sopenharmony_ci 1472141cc406Sopenharmony_ci i = 0; 1473141cc406Sopenharmony_ci default_source = -1; 1474141cc406Sopenharmony_ci 1475141cc406Sopenharmony_ci if (s->dev->info.adf_fsu_installed & HAVE_ADF) 1476141cc406Sopenharmony_ci { 1477141cc406Sopenharmony_ci s->dev->info.scansources[i++] = use_adf; 1478141cc406Sopenharmony_ci default_source = SCAN_WITH_ADF; 1479141cc406Sopenharmony_ci } 1480141cc406Sopenharmony_ci if (s->dev->info.adf_fsu_installed & HAVE_FSU) 1481141cc406Sopenharmony_ci { 1482141cc406Sopenharmony_ci s->dev->info.scansources[i++] = use_fsu; 1483141cc406Sopenharmony_ci if (default_source < 0) 1484141cc406Sopenharmony_ci default_source = SCAN_WITH_FSU; 1485141cc406Sopenharmony_ci } 1486141cc406Sopenharmony_ci s->dev->info.scansources[i++] = use_simple; 1487141cc406Sopenharmony_ci if (default_source < 0) 1488141cc406Sopenharmony_ci default_source = SCAN_SIMPLE; 1489141cc406Sopenharmony_ci s->dev->info.scansources[i] = 0; 1490141cc406Sopenharmony_ci 1491141cc406Sopenharmony_ci init_string_option(s, SANE_NAME_SCAN_SOURCE, SANE_TITLE_SCAN_SOURCE, 1492141cc406Sopenharmony_ci SANE_DESC_SCAN_SOURCE, (SANE_String_Const*)s->dev->info.scansources, 1493141cc406Sopenharmony_ci OPT_SCANSOURCE, 0); 1494141cc406Sopenharmony_ci 1495141cc406Sopenharmony_ci if (i < 2) 1496141cc406Sopenharmony_ci s->opt[OPT_SCANSOURCE].cap |= SANE_CAP_INACTIVE; 1497141cc406Sopenharmony_ci 1498141cc406Sopenharmony_ci if (s->dev->sensedat.model == PCIN500) 1499141cc406Sopenharmony_ci init_string_option(s, "Paper size", "Paper size", 1500141cc406Sopenharmony_ci "Paper size", paper_list_pcin500, OPT_PAPER, 0); 1501141cc406Sopenharmony_ci else 1502141cc406Sopenharmony_ci init_string_option(s, "Paper size", "Paper size", 1503141cc406Sopenharmony_ci "Paper size", paper_list_pcinxxx, OPT_PAPER, 1); 1504141cc406Sopenharmony_ci 1505141cc406Sopenharmony_ci /* gamma */ 1506141cc406Sopenharmony_ci init_string_option(s, "Gamma", "Gamma", "Gamma", gamma_list, OPT_GAMMA, 0); 1507141cc406Sopenharmony_ci 1508141cc406Sopenharmony_ci /* Resolution Group */ 1509141cc406Sopenharmony_ci s->opt[OPT_RESOLUTION_GROUP].title = "Resolution"; 1510141cc406Sopenharmony_ci s->opt[OPT_RESOLUTION_GROUP].desc = ""; 1511141cc406Sopenharmony_ci s->opt[OPT_RESOLUTION_GROUP].type = SANE_TYPE_GROUP; 1512141cc406Sopenharmony_ci s->opt[OPT_RESOLUTION_GROUP].cap = 0; 1513141cc406Sopenharmony_ci s->opt[OPT_RESOLUTION_GROUP].constraint_type = SANE_CONSTRAINT_NONE; 1514141cc406Sopenharmony_ci 1515141cc406Sopenharmony_ci#ifdef USE_RESOLUTION_LIST 1516141cc406Sopenharmony_ci /* select resolution */ 1517141cc406Sopenharmony_ci if (s->dev->sensedat.model == PCIN500) 1518141cc406Sopenharmony_ci init_string_option(s, "Resolution", "Resolution", "Resolution", 1519141cc406Sopenharmony_ci resolution_list_pcin500, OPT_RESOLUTION_LIST, RESOLUTION_MAX_PCIN500); 1520141cc406Sopenharmony_ci else 1521141cc406Sopenharmony_ci init_string_option(s, "Resolution", "Resolution", "Resolution", 1522141cc406Sopenharmony_ci resolution_list_pcinxxx, OPT_RESOLUTION_LIST, RESOLUTION_MAX_PCINXXX); 1523141cc406Sopenharmony_ci#endif 1524141cc406Sopenharmony_ci 1525141cc406Sopenharmony_ci /* x & y resolution */ 1526141cc406Sopenharmony_ci s->opt[OPT_RESOLUTION].name = SANE_NAME_SCAN_RESOLUTION; 1527141cc406Sopenharmony_ci if (s->dev->sensedat.model == PCIN500) 1528141cc406Sopenharmony_ci s->opt[OPT_RESOLUTION].title = SANE_TITLE_SCAN_RESOLUTION"(x 10)"; 1529141cc406Sopenharmony_ci else 1530141cc406Sopenharmony_ci s->opt[OPT_RESOLUTION].title = SANE_TITLE_SCAN_RESOLUTION; 1531141cc406Sopenharmony_ci s->opt[OPT_RESOLUTION].desc = SANE_DESC_SCAN_RESOLUTION; 1532141cc406Sopenharmony_ci s->opt[OPT_RESOLUTION].type = SANE_TYPE_INT; 1533141cc406Sopenharmony_ci s->opt[OPT_RESOLUTION].unit = SANE_UNIT_DPI; 1534141cc406Sopenharmony_ci s->opt[OPT_RESOLUTION].constraint_type = SANE_CONSTRAINT_RANGE; 1535141cc406Sopenharmony_ci s->opt[OPT_RESOLUTION].constraint.range = &s->dev->info.res_range; 1536141cc406Sopenharmony_ci s->val[OPT_RESOLUTION].w = s->dev->info.res_default; 1537141cc406Sopenharmony_ci 1538141cc406Sopenharmony_ci /* "Geometry" group: */ 1539141cc406Sopenharmony_ci s->opt[OPT_GEOMETRY_GROUP].title = "Geometry"; 1540141cc406Sopenharmony_ci s->opt[OPT_GEOMETRY_GROUP].desc = ""; 1541141cc406Sopenharmony_ci s->opt[OPT_GEOMETRY_GROUP].type = SANE_TYPE_GROUP; 1542141cc406Sopenharmony_ci s->opt[OPT_GEOMETRY_GROUP].cap = SANE_CAP_ADVANCED; 1543141cc406Sopenharmony_ci s->opt[OPT_GEOMETRY_GROUP].constraint_type = SANE_CONSTRAINT_NONE; 1544141cc406Sopenharmony_ci 1545141cc406Sopenharmony_ci /* top-left x */ 1546141cc406Sopenharmony_ci s->opt[OPT_TL_X].name = SANE_NAME_SCAN_TL_X; 1547141cc406Sopenharmony_ci s->opt[OPT_TL_X].title = SANE_TITLE_SCAN_TL_X; 1548141cc406Sopenharmony_ci s->opt[OPT_TL_X].desc = SANE_DESC_SCAN_TL_X; 1549141cc406Sopenharmony_ci s->opt[OPT_TL_X].type = SANE_TYPE_FIXED; 1550141cc406Sopenharmony_ci s->opt[OPT_TL_X].unit = SANE_UNIT_MM; 1551141cc406Sopenharmony_ci s->opt[OPT_TL_X].constraint_type = SANE_CONSTRAINT_RANGE; 1552141cc406Sopenharmony_ci s->opt[OPT_TL_X].constraint.range = &s->dev->info.tl_x_ranges[default_source]; 1553141cc406Sopenharmony_ci s->val[OPT_TL_X].w = s->dev->info.tl_x_ranges[default_source].min; 1554141cc406Sopenharmony_ci 1555141cc406Sopenharmony_ci /* top-left y */ 1556141cc406Sopenharmony_ci s->opt[OPT_TL_Y].name = SANE_NAME_SCAN_TL_Y; 1557141cc406Sopenharmony_ci s->opt[OPT_TL_Y].title = SANE_TITLE_SCAN_TL_Y; 1558141cc406Sopenharmony_ci s->opt[OPT_TL_Y].desc = SANE_DESC_SCAN_TL_Y; 1559141cc406Sopenharmony_ci s->opt[OPT_TL_Y].type = SANE_TYPE_FIXED; 1560141cc406Sopenharmony_ci s->opt[OPT_TL_Y].unit = SANE_UNIT_MM; 1561141cc406Sopenharmony_ci s->opt[OPT_TL_Y].constraint_type = SANE_CONSTRAINT_RANGE; 1562141cc406Sopenharmony_ci s->opt[OPT_TL_Y].constraint.range = &s->dev->info.tl_y_ranges[default_source]; 1563141cc406Sopenharmony_ci s->val[OPT_TL_Y].w = s->dev->info.tl_y_ranges[default_source].min; 1564141cc406Sopenharmony_ci 1565141cc406Sopenharmony_ci /* bottom-right x */ 1566141cc406Sopenharmony_ci s->opt[OPT_BR_X].name = SANE_NAME_SCAN_BR_X; 1567141cc406Sopenharmony_ci s->opt[OPT_BR_X].title = SANE_TITLE_SCAN_BR_X; 1568141cc406Sopenharmony_ci s->opt[OPT_BR_X].desc = SANE_DESC_SCAN_BR_X; 1569141cc406Sopenharmony_ci s->opt[OPT_BR_X].type = SANE_TYPE_FIXED; 1570141cc406Sopenharmony_ci s->opt[OPT_BR_X].unit = SANE_UNIT_MM; 1571141cc406Sopenharmony_ci s->opt[OPT_BR_X].constraint_type = SANE_CONSTRAINT_RANGE; 1572141cc406Sopenharmony_ci s->opt[OPT_BR_X].constraint.range = &s->dev->info.br_x_ranges[default_source]; 1573141cc406Sopenharmony_ci scalar = s->dev->info.x_default; 1574141cc406Sopenharmony_ci clip_value (&s->opt[OPT_BR_X], &scalar); 1575141cc406Sopenharmony_ci s->val[OPT_BR_X].w = scalar; 1576141cc406Sopenharmony_ci 1577141cc406Sopenharmony_ci /* bottom-right y */ 1578141cc406Sopenharmony_ci s->opt[OPT_BR_Y].name = SANE_NAME_SCAN_BR_Y; 1579141cc406Sopenharmony_ci s->opt[OPT_BR_Y].title = SANE_TITLE_SCAN_BR_Y; 1580141cc406Sopenharmony_ci s->opt[OPT_BR_Y].desc = SANE_DESC_SCAN_BR_Y; 1581141cc406Sopenharmony_ci s->opt[OPT_BR_Y].type = SANE_TYPE_FIXED; 1582141cc406Sopenharmony_ci s->opt[OPT_BR_Y].unit = SANE_UNIT_MM; 1583141cc406Sopenharmony_ci s->opt[OPT_BR_Y].constraint_type = SANE_CONSTRAINT_RANGE; 1584141cc406Sopenharmony_ci s->opt[OPT_BR_Y].constraint.range = &s->dev->info.br_y_ranges[default_source]; 1585141cc406Sopenharmony_ci scalar = s->dev->info.y_default; 1586141cc406Sopenharmony_ci clip_value (&s->opt[OPT_BR_X], &scalar); 1587141cc406Sopenharmony_ci s->val[OPT_BR_Y].w = scalar; 1588141cc406Sopenharmony_ci 1589141cc406Sopenharmony_ci /* "Enhancement" group: */ 1590141cc406Sopenharmony_ci s->opt[OPT_ENHANCEMENT_GROUP].title = "Enhancement"; 1591141cc406Sopenharmony_ci s->opt[OPT_ENHANCEMENT_GROUP].desc = ""; 1592141cc406Sopenharmony_ci s->opt[OPT_ENHANCEMENT_GROUP].type = SANE_TYPE_GROUP; 1593141cc406Sopenharmony_ci s->opt[OPT_ENHANCEMENT_GROUP].cap = 0; 1594141cc406Sopenharmony_ci s->opt[OPT_ENHANCEMENT_GROUP].constraint_type = SANE_CONSTRAINT_NONE; 1595141cc406Sopenharmony_ci 1596141cc406Sopenharmony_ci /* edge emphasis */ 1597141cc406Sopenharmony_ci init_string_option(s, "Edge emphasis", "Edge emphasis", 1598141cc406Sopenharmony_ci "Edge emphasis", edge_emphasis_list, 1599141cc406Sopenharmony_ci OPT_EDGE_EMPHASIS, 0); 1600141cc406Sopenharmony_ci 1601141cc406Sopenharmony_ci if (s->dev->sensedat.model == PCIN500) 1602141cc406Sopenharmony_ci s->opt[OPT_EDGE_EMPHASIS].cap |= SANE_CAP_INACTIVE; 1603141cc406Sopenharmony_ci 1604141cc406Sopenharmony_ci /* OR */ 1605141cc406Sopenharmony_ci s->opt[OPT_OR].name = "OR"; 1606141cc406Sopenharmony_ci s->opt[OPT_OR].title = "OR"; 1607141cc406Sopenharmony_ci s->opt[OPT_OR].desc = "Select OR emphancement"; 1608141cc406Sopenharmony_ci s->opt[OPT_OR].type = SANE_TYPE_BOOL; 1609141cc406Sopenharmony_ci s->val[OPT_OR].w = SANE_FALSE; 1610141cc406Sopenharmony_ci 1611141cc406Sopenharmony_ci /* EDGE */ 1612141cc406Sopenharmony_ci s->opt[OPT_EDGE].name = "edge"; 1613141cc406Sopenharmony_ci s->opt[OPT_EDGE].title = "Edge"; 1614141cc406Sopenharmony_ci s->opt[OPT_EDGE].desc = "Select Edge emphancement"; 1615141cc406Sopenharmony_ci s->opt[OPT_EDGE].type = SANE_TYPE_BOOL; 1616141cc406Sopenharmony_ci s->val[OPT_EDGE].w = SANE_FALSE; 1617141cc406Sopenharmony_ci 1618141cc406Sopenharmony_ci /* NR */ 1619141cc406Sopenharmony_ci s->opt[OPT_NR].name = "NR"; 1620141cc406Sopenharmony_ci s->opt[OPT_NR].title = "NR"; 1621141cc406Sopenharmony_ci s->opt[OPT_NR].desc = "Select noise reduction"; 1622141cc406Sopenharmony_ci s->opt[OPT_NR].type = SANE_TYPE_BOOL; 1623141cc406Sopenharmony_ci s->val[OPT_NR].w = SANE_FALSE; 1624141cc406Sopenharmony_ci 1625141cc406Sopenharmony_ci if (s->dev->sensedat.model != PCIN500) 1626141cc406Sopenharmony_ci { 1627141cc406Sopenharmony_ci s->opt[OPT_EDGE].cap |= SANE_CAP_INACTIVE; 1628141cc406Sopenharmony_ci s->opt[OPT_NR].cap |= SANE_CAP_INACTIVE; 1629141cc406Sopenharmony_ci s->opt[OPT_OR].cap |= SANE_CAP_INACTIVE; 1630141cc406Sopenharmony_ci } 1631141cc406Sopenharmony_ci /* tint */ 1632141cc406Sopenharmony_ci s->opt[OPT_TINT].name = "tint"; 1633141cc406Sopenharmony_ci s->opt[OPT_TINT].title = "Tint"; 1634141cc406Sopenharmony_ci s->opt[OPT_TINT].desc = "Select tint"; 1635141cc406Sopenharmony_ci s->opt[OPT_TINT].type = SANE_TYPE_INT; 1636141cc406Sopenharmony_ci s->opt[OPT_TINT].unit = SANE_UNIT_NONE; 1637141cc406Sopenharmony_ci s->opt[OPT_TINT].constraint_type = SANE_CONSTRAINT_RANGE; 1638141cc406Sopenharmony_ci s->opt[OPT_TINT].constraint.range = &s->dev->info.tint_range; 1639141cc406Sopenharmony_ci s->val[OPT_TINT].w = 128; 1640141cc406Sopenharmony_ci if (s->dev->sensedat.model != PCIN500) 1641141cc406Sopenharmony_ci s->opt[OPT_TINT].cap |= SANE_CAP_INACTIVE; 1642141cc406Sopenharmony_ci 1643141cc406Sopenharmony_ci /* color */ 1644141cc406Sopenharmony_ci s->opt[OPT_COLOR].name = "color"; 1645141cc406Sopenharmony_ci s->opt[OPT_COLOR].title = "Color"; 1646141cc406Sopenharmony_ci s->opt[OPT_COLOR].desc = "Select color"; 1647141cc406Sopenharmony_ci s->opt[OPT_COLOR].type = SANE_TYPE_INT; 1648141cc406Sopenharmony_ci s->opt[OPT_COLOR].unit = SANE_UNIT_NONE; 1649141cc406Sopenharmony_ci s->opt[OPT_COLOR].constraint_type = SANE_CONSTRAINT_RANGE; 1650141cc406Sopenharmony_ci s->opt[OPT_COLOR].constraint.range = &s->dev->info.color_range; 1651141cc406Sopenharmony_ci s->val[OPT_COLOR].w = 128; 1652141cc406Sopenharmony_ci if (s->dev->sensedat.model != PCIN500) 1653141cc406Sopenharmony_ci s->opt[OPT_COLOR].cap |= SANE_CAP_INACTIVE; 1654141cc406Sopenharmony_ci 1655141cc406Sopenharmony_ci /* threshold */ 1656141cc406Sopenharmony_ci s->opt[OPT_THRESHOLD].name = SANE_NAME_THRESHOLD; 1657141cc406Sopenharmony_ci s->opt[OPT_THRESHOLD].title = SANE_TITLE_THRESHOLD; 1658141cc406Sopenharmony_ci s->opt[OPT_THRESHOLD].desc = SANE_DESC_THRESHOLD; 1659141cc406Sopenharmony_ci s->opt[OPT_THRESHOLD].type = SANE_TYPE_INT; 1660141cc406Sopenharmony_ci s->opt[OPT_THRESHOLD].unit = SANE_UNIT_NONE; 1661141cc406Sopenharmony_ci s->opt[OPT_THRESHOLD].constraint_type = SANE_CONSTRAINT_RANGE; 1662141cc406Sopenharmony_ci s->opt[OPT_THRESHOLD].constraint.range = &s->dev->info.threshold_range; 1663141cc406Sopenharmony_ci s->val[OPT_THRESHOLD].w = 128; 1664141cc406Sopenharmony_ci s->opt[OPT_THRESHOLD].cap |= SANE_CAP_INACTIVE; 1665141cc406Sopenharmony_ci 1666141cc406Sopenharmony_ci#ifdef USE_COLOR_THRESHOLD 1667141cc406Sopenharmony_ci s->opt[OPT_THRESHOLD_R].name = SANE_NAME_THRESHOLD "-red"; 1668141cc406Sopenharmony_ci /* xxx the titles and descriptions are confusing: 1669141cc406Sopenharmony_ci "set white point (red)" 1670141cc406Sopenharmony_ci Any idea? maybe "threshold to get the red component on" 1671141cc406Sopenharmony_ci */ 1672141cc406Sopenharmony_ci s->opt[OPT_THRESHOLD_R].title = SANE_TITLE_THRESHOLD " (red)"; 1673141cc406Sopenharmony_ci s->opt[OPT_THRESHOLD_R].desc = SANE_DESC_THRESHOLD " (red)"; 1674141cc406Sopenharmony_ci s->opt[OPT_THRESHOLD_R].type = SANE_TYPE_INT; 1675141cc406Sopenharmony_ci s->opt[OPT_THRESHOLD_R].unit = SANE_UNIT_NONE; 1676141cc406Sopenharmony_ci s->opt[OPT_THRESHOLD_R].constraint_type = SANE_CONSTRAINT_RANGE; 1677141cc406Sopenharmony_ci s->opt[OPT_THRESHOLD_R].constraint.range = &s->dev->info.threshold_range; 1678141cc406Sopenharmony_ci s->val[OPT_THRESHOLD_R].w = 128; 1679141cc406Sopenharmony_ci s->opt[OPT_THRESHOLD_R].cap |= SANE_CAP_INACTIVE; 1680141cc406Sopenharmony_ci 1681141cc406Sopenharmony_ci s->opt[OPT_THRESHOLD_G].name = SANE_NAME_THRESHOLD "-green"; 1682141cc406Sopenharmony_ci s->opt[OPT_THRESHOLD_G].title = SANE_TITLE_THRESHOLD " (green)"; 1683141cc406Sopenharmony_ci s->opt[OPT_THRESHOLD_G].desc = SANE_DESC_THRESHOLD " (green)"; 1684141cc406Sopenharmony_ci s->opt[OPT_THRESHOLD_G].type = SANE_TYPE_INT; 1685141cc406Sopenharmony_ci s->opt[OPT_THRESHOLD_G].unit = SANE_UNIT_NONE; 1686141cc406Sopenharmony_ci s->opt[OPT_THRESHOLD_G].constraint_type = SANE_CONSTRAINT_RANGE; 1687141cc406Sopenharmony_ci s->opt[OPT_THRESHOLD_G].constraint.range = &s->dev->info.threshold_range; 1688141cc406Sopenharmony_ci s->val[OPT_THRESHOLD_G].w = 128; 1689141cc406Sopenharmony_ci s->opt[OPT_THRESHOLD_G].cap |= SANE_CAP_INACTIVE; 1690141cc406Sopenharmony_ci 1691141cc406Sopenharmony_ci s->opt[OPT_THRESHOLD_B].name = SANE_NAME_THRESHOLD "-blue"; 1692141cc406Sopenharmony_ci s->opt[OPT_THRESHOLD_B].title = SANE_TITLE_THRESHOLD " (blue)"; 1693141cc406Sopenharmony_ci s->opt[OPT_THRESHOLD_B].desc = SANE_DESC_THRESHOLD " (blue)"; 1694141cc406Sopenharmony_ci s->opt[OPT_THRESHOLD_B].type = SANE_TYPE_INT; 1695141cc406Sopenharmony_ci s->opt[OPT_THRESHOLD_B].unit = SANE_UNIT_NONE; 1696141cc406Sopenharmony_ci s->opt[OPT_THRESHOLD_B].constraint_type = SANE_CONSTRAINT_RANGE; 1697141cc406Sopenharmony_ci s->opt[OPT_THRESHOLD_B].constraint.range = &s->dev->info.threshold_range; 1698141cc406Sopenharmony_ci s->val[OPT_THRESHOLD_B].w = 128; 1699141cc406Sopenharmony_ci s->opt[OPT_THRESHOLD_B].cap |= SANE_CAP_INACTIVE; 1700141cc406Sopenharmony_ci 1701141cc406Sopenharmony_ci#endif 1702141cc406Sopenharmony_ci 1703141cc406Sopenharmony_ci /* light color (for gray scale and line art scans) */ 1704141cc406Sopenharmony_ci init_string_option(s, "LightColor", "LightColor", "LightColor", 1705141cc406Sopenharmony_ci light_color_list, OPT_LIGHTCOLOR, 3); 1706141cc406Sopenharmony_ci s->opt[OPT_LIGHTCOLOR].cap |= SANE_CAP_INACTIVE; 1707141cc406Sopenharmony_ci 1708141cc406Sopenharmony_ci s->opt[OPT_PREVIEW].name = SANE_NAME_PREVIEW; 1709141cc406Sopenharmony_ci s->opt[OPT_PREVIEW].title = SANE_TITLE_PREVIEW; 1710141cc406Sopenharmony_ci s->opt[OPT_PREVIEW].desc = SANE_DESC_PREVIEW; 1711141cc406Sopenharmony_ci s->opt[OPT_PREVIEW].type = SANE_TYPE_BOOL; 1712141cc406Sopenharmony_ci s->opt[OPT_PREVIEW].cap = SANE_CAP_SOFT_DETECT | SANE_CAP_SOFT_SELECT; 1713141cc406Sopenharmony_ci s->val[OPT_PREVIEW].w = SANE_FALSE; 1714141cc406Sopenharmony_ci 1715141cc406Sopenharmony_ci 1716141cc406Sopenharmony_ci#ifdef USE_CUSTOM_GAMMA 1717141cc406Sopenharmony_ci /* custom-gamma table */ 1718141cc406Sopenharmony_ci s->opt[OPT_CUSTOM_GAMMA].name = SANE_NAME_CUSTOM_GAMMA; 1719141cc406Sopenharmony_ci s->opt[OPT_CUSTOM_GAMMA].title = SANE_TITLE_CUSTOM_GAMMA; 1720141cc406Sopenharmony_ci s->opt[OPT_CUSTOM_GAMMA].desc = SANE_DESC_CUSTOM_GAMMA; 1721141cc406Sopenharmony_ci s->opt[OPT_CUSTOM_GAMMA].type = SANE_TYPE_BOOL; 1722141cc406Sopenharmony_ci s->val[OPT_CUSTOM_GAMMA].w = SANE_FALSE; 1723141cc406Sopenharmony_ci 1724141cc406Sopenharmony_ci /* grayscale gamma vector */ 1725141cc406Sopenharmony_ci s->opt[OPT_GAMMA_VECTOR].name = SANE_NAME_GAMMA_VECTOR; 1726141cc406Sopenharmony_ci s->opt[OPT_GAMMA_VECTOR].title = SANE_TITLE_GAMMA_VECTOR; 1727141cc406Sopenharmony_ci s->opt[OPT_GAMMA_VECTOR].desc = SANE_DESC_GAMMA_VECTOR; 1728141cc406Sopenharmony_ci s->opt[OPT_GAMMA_VECTOR].type = SANE_TYPE_INT; 1729141cc406Sopenharmony_ci#if 0 1730141cc406Sopenharmony_ci s->opt[OPT_GAMMA_VECTOR].cap |= SANE_CAP_INACTIVE; 1731141cc406Sopenharmony_ci#endif 1732141cc406Sopenharmony_ci s->opt[OPT_GAMMA_VECTOR].unit = SANE_UNIT_NONE; 1733141cc406Sopenharmony_ci s->opt[OPT_GAMMA_VECTOR].size = 256 * sizeof (SANE_Word); 1734141cc406Sopenharmony_ci s->opt[OPT_GAMMA_VECTOR].constraint_type = SANE_CONSTRAINT_RANGE; 1735141cc406Sopenharmony_ci s->opt[OPT_GAMMA_VECTOR].constraint.range = &u8_range; 1736141cc406Sopenharmony_ci s->val[OPT_GAMMA_VECTOR].wa = &s->gamma_table[0][0]; 1737141cc406Sopenharmony_ci 1738141cc406Sopenharmony_ci /* red gamma vector */ 1739141cc406Sopenharmony_ci s->opt[OPT_GAMMA_VECTOR_R].name = SANE_NAME_GAMMA_VECTOR_R; 1740141cc406Sopenharmony_ci s->opt[OPT_GAMMA_VECTOR_R].title = SANE_TITLE_GAMMA_VECTOR_R; 1741141cc406Sopenharmony_ci s->opt[OPT_GAMMA_VECTOR_R].desc = SANE_DESC_GAMMA_VECTOR_R; 1742141cc406Sopenharmony_ci s->opt[OPT_GAMMA_VECTOR_R].type = SANE_TYPE_INT; 1743141cc406Sopenharmony_ci#if 0 1744141cc406Sopenharmony_ci s->opt[OPT_GAMMA_VECTOR_R].cap |= SANE_CAP_INACTIVE; 1745141cc406Sopenharmony_ci#endif 1746141cc406Sopenharmony_ci s->opt[OPT_GAMMA_VECTOR_R].unit = SANE_UNIT_NONE; 1747141cc406Sopenharmony_ci s->opt[OPT_GAMMA_VECTOR_R].size = 256 * sizeof (SANE_Word); 1748141cc406Sopenharmony_ci s->opt[OPT_GAMMA_VECTOR_R].constraint_type = SANE_CONSTRAINT_RANGE; 1749141cc406Sopenharmony_ci s->opt[OPT_GAMMA_VECTOR_R].constraint.range = &u8_range; 1750141cc406Sopenharmony_ci s->val[OPT_GAMMA_VECTOR_R].wa = &s->gamma_table[1][0]; 1751141cc406Sopenharmony_ci 1752141cc406Sopenharmony_ci /* green gamma vector */ 1753141cc406Sopenharmony_ci s->opt[OPT_GAMMA_VECTOR_G].name = SANE_NAME_GAMMA_VECTOR_G; 1754141cc406Sopenharmony_ci s->opt[OPT_GAMMA_VECTOR_G].title = SANE_TITLE_GAMMA_VECTOR_G; 1755141cc406Sopenharmony_ci s->opt[OPT_GAMMA_VECTOR_G].desc = SANE_DESC_GAMMA_VECTOR_G; 1756141cc406Sopenharmony_ci s->opt[OPT_GAMMA_VECTOR_G].type = SANE_TYPE_INT; 1757141cc406Sopenharmony_ci#if 0 1758141cc406Sopenharmony_ci s->opt[OPT_GAMMA_VECTOR_G].cap |= SANE_CAP_INACTIVE; 1759141cc406Sopenharmony_ci#endif 1760141cc406Sopenharmony_ci s->opt[OPT_GAMMA_VECTOR_G].unit = SANE_UNIT_NONE; 1761141cc406Sopenharmony_ci s->opt[OPT_GAMMA_VECTOR_G].size = 256 * sizeof (SANE_Word); 1762141cc406Sopenharmony_ci s->opt[OPT_GAMMA_VECTOR_G].constraint_type = SANE_CONSTRAINT_RANGE; 1763141cc406Sopenharmony_ci s->opt[OPT_GAMMA_VECTOR_G].constraint.range = &u8_range; 1764141cc406Sopenharmony_ci s->val[OPT_GAMMA_VECTOR_G].wa = &s->gamma_table[2][0]; 1765141cc406Sopenharmony_ci 1766141cc406Sopenharmony_ci /* blue gamma vector */ 1767141cc406Sopenharmony_ci s->opt[OPT_GAMMA_VECTOR_B].name = SANE_NAME_GAMMA_VECTOR_B; 1768141cc406Sopenharmony_ci s->opt[OPT_GAMMA_VECTOR_B].title = SANE_TITLE_GAMMA_VECTOR_B; 1769141cc406Sopenharmony_ci s->opt[OPT_GAMMA_VECTOR_B].desc = SANE_DESC_GAMMA_VECTOR_B; 1770141cc406Sopenharmony_ci s->opt[OPT_GAMMA_VECTOR_B].type = SANE_TYPE_INT; 1771141cc406Sopenharmony_ci#if 0 1772141cc406Sopenharmony_ci s->opt[OPT_GAMMA_VECTOR_B].cap |= SANE_CAP_INACTIVE; 1773141cc406Sopenharmony_ci#endif 1774141cc406Sopenharmony_ci s->opt[OPT_GAMMA_VECTOR_B].unit = SANE_UNIT_NONE; 1775141cc406Sopenharmony_ci s->opt[OPT_GAMMA_VECTOR_B].size = 256 * sizeof (SANE_Word); 1776141cc406Sopenharmony_ci s->opt[OPT_GAMMA_VECTOR_B].constraint_type = SANE_CONSTRAINT_RANGE; 1777141cc406Sopenharmony_ci s->opt[OPT_GAMMA_VECTOR_B].constraint.range = &u8_range; 1778141cc406Sopenharmony_ci s->val[OPT_GAMMA_VECTOR_B].wa = &s->gamma_table[3][0]; 1779141cc406Sopenharmony_ci set_gamma_caps(s); 1780141cc406Sopenharmony_ci#endif 1781141cc406Sopenharmony_ci 1782141cc406Sopenharmony_ci DBG (10, ">>\n"); 1783141cc406Sopenharmony_ci return SANE_STATUS_GOOD; 1784141cc406Sopenharmony_ci} 1785141cc406Sopenharmony_ci 1786141cc406Sopenharmony_cistatic SANE_Status 1787141cc406Sopenharmony_cido_cancel (NEC_Scanner * s) 1788141cc406Sopenharmony_ci{ 1789141cc406Sopenharmony_ci DBG (10, "<< do_cancel "); 1790141cc406Sopenharmony_ci 1791141cc406Sopenharmony_ci#ifdef USE_FORK 1792141cc406Sopenharmony_ci if (s->reader_pid > 0) 1793141cc406Sopenharmony_ci { 1794141cc406Sopenharmony_ci int exit_status; 1795141cc406Sopenharmony_ci int count = 0; 1796141cc406Sopenharmony_ci /* ensure child knows it's time to stop: */ 1797141cc406Sopenharmony_ci 1798141cc406Sopenharmony_ci DBG(11, "stopping reader process\n"); 1799141cc406Sopenharmony_ci s->rdr_ctl->cancel = 1; 1800141cc406Sopenharmony_ci while(reader_running(s) && count < 100) 1801141cc406Sopenharmony_ci { 1802141cc406Sopenharmony_ci usleep(100000); 1803141cc406Sopenharmony_ci count++; 1804141cc406Sopenharmony_ci }; 1805141cc406Sopenharmony_ci if (reader_running(s)) 1806141cc406Sopenharmony_ci { 1807141cc406Sopenharmony_ci kill(s->reader_pid, SIGKILL); 1808141cc406Sopenharmony_ci } 1809141cc406Sopenharmony_ci wait(&exit_status); 1810141cc406Sopenharmony_ci DBG(11, "reader process stopped\n"); 1811141cc406Sopenharmony_ci 1812141cc406Sopenharmony_ci s->reader_pid = 0; 1813141cc406Sopenharmony_ci } 1814141cc406Sopenharmony_ci 1815141cc406Sopenharmony_ci#endif 1816141cc406Sopenharmony_ci s->scanning = SANE_FALSE; 1817141cc406Sopenharmony_ci 1818141cc406Sopenharmony_ci if (s->fd >= 0) 1819141cc406Sopenharmony_ci { 1820141cc406Sopenharmony_ci sanei_scsi_close (s->fd); 1821141cc406Sopenharmony_ci s->fd = -1; 1822141cc406Sopenharmony_ci } 1823141cc406Sopenharmony_ci#ifdef USE_FORK 1824141cc406Sopenharmony_ci { 1825141cc406Sopenharmony_ci struct shmid_ds ds; 1826141cc406Sopenharmony_ci if (s->shmid != -1) 1827141cc406Sopenharmony_ci shmctl(s->shmid, IPC_RMID, &ds); 1828141cc406Sopenharmony_ci s->shmid = -1; 1829141cc406Sopenharmony_ci } 1830141cc406Sopenharmony_ci#endif 1831141cc406Sopenharmony_ci if (s->buffer) 1832141cc406Sopenharmony_ci free(s->buffer); 1833141cc406Sopenharmony_ci s->buffer = 0; 1834141cc406Sopenharmony_ci 1835141cc406Sopenharmony_ci DBG (10, ">>\n"); 1836141cc406Sopenharmony_ci return (SANE_STATUS_CANCELLED); 1837141cc406Sopenharmony_ci} 1838141cc406Sopenharmony_ci 1839141cc406Sopenharmony_cistatic NEC_New_Device *new_devs = 0; 1840141cc406Sopenharmony_cistatic NEC_New_Device *new_dev_pool = 0; 1841141cc406Sopenharmony_ci 1842141cc406Sopenharmony_cistatic SANE_Status 1843141cc406Sopenharmony_ciattach_and_list(const char *devnam) 1844141cc406Sopenharmony_ci{ 1845141cc406Sopenharmony_ci SANE_Status res; 1846141cc406Sopenharmony_ci NEC_Device *devp; 1847141cc406Sopenharmony_ci NEC_New_Device *np; 1848141cc406Sopenharmony_ci 1849141cc406Sopenharmony_ci res = attach(devnam, &devp); 1850141cc406Sopenharmony_ci if (res == SANE_STATUS_GOOD) 1851141cc406Sopenharmony_ci { 1852141cc406Sopenharmony_ci if (new_dev_pool) 1853141cc406Sopenharmony_ci { 1854141cc406Sopenharmony_ci np = new_dev_pool; 1855141cc406Sopenharmony_ci new_dev_pool = np->next; 1856141cc406Sopenharmony_ci } 1857141cc406Sopenharmony_ci else 1858141cc406Sopenharmony_ci { 1859141cc406Sopenharmony_ci np = malloc(sizeof(NEC_New_Device)); 1860141cc406Sopenharmony_ci if (np == 0) 1861141cc406Sopenharmony_ci return SANE_STATUS_NO_MEM; 1862141cc406Sopenharmony_ci } 1863141cc406Sopenharmony_ci np->next =new_devs; 1864141cc406Sopenharmony_ci np->dev = devp; 1865141cc406Sopenharmony_ci new_devs = np; 1866141cc406Sopenharmony_ci } 1867141cc406Sopenharmony_ci return res; 1868141cc406Sopenharmony_ci} 1869141cc406Sopenharmony_ci 1870141cc406Sopenharmony_ciSANE_Status 1871141cc406Sopenharmony_cisane_init (SANE_Int * version_code, SANE_Auth_Callback authorize) 1872141cc406Sopenharmony_ci{ 1873141cc406Sopenharmony_ci char devnam[PATH_MAX] = "/dev/scanner"; 1874141cc406Sopenharmony_ci char line[PATH_MAX]; 1875141cc406Sopenharmony_ci const char *lp; 1876141cc406Sopenharmony_ci char *word; 1877141cc406Sopenharmony_ci char *end; 1878141cc406Sopenharmony_ci FILE *fp; 1879141cc406Sopenharmony_ci int opt_index = 0; 1880141cc406Sopenharmony_ci int buffers[2] = {DEFAULT_BUFFERS, DEFAULT_BUFFERS}; 1881141cc406Sopenharmony_ci int bufsize[2] = {DEFAULT_BUFSIZE, DEFAULT_BUFSIZE}; 1882141cc406Sopenharmony_ci int queued_reads[2] = {DEFAULT_QUEUED_READS, DEFAULT_QUEUED_READS}; 1883141cc406Sopenharmony_ci int linecount = 0; 1884141cc406Sopenharmony_ci#if 1 1885141cc406Sopenharmony_ci NEC_Device nd; 1886141cc406Sopenharmony_ci NEC_Device *dp = &nd; 1887141cc406Sopenharmony_ci#else 1888141cc406Sopenharmony_ci NEC_Device *dp; 1889141cc406Sopenharmony_ci#endif 1890141cc406Sopenharmony_ci NEC_New_Device *np; 1891141cc406Sopenharmony_ci int i; 1892141cc406Sopenharmony_ci 1893141cc406Sopenharmony_ci (void) authorize; /* silence compilation warnings */ 1894141cc406Sopenharmony_ci 1895141cc406Sopenharmony_ci DBG_INIT (); 1896141cc406Sopenharmony_ci DBG (10, "<< sane_init "); 1897141cc406Sopenharmony_ci 1898141cc406Sopenharmony_ci DBG (1, "sane_init: NEC (Ver %d.%d)\n", NEC_MAJOR, NEC_MINOR); 1899141cc406Sopenharmony_ci 1900141cc406Sopenharmony_ci if (version_code) 1901141cc406Sopenharmony_ci *version_code = SANE_VERSION_CODE (SANE_CURRENT_MAJOR, SANE_CURRENT_MINOR, 0); 1902141cc406Sopenharmony_ci 1903141cc406Sopenharmony_ci fp = sanei_config_open (NEC_CONFIG_FILE); 1904141cc406Sopenharmony_ci if (!fp) 1905141cc406Sopenharmony_ci { 1906141cc406Sopenharmony_ci /* use "/dev/scanner" as the default device name if no 1907141cc406Sopenharmony_ci config file is available 1908141cc406Sopenharmony_ci */ 1909141cc406Sopenharmony_ci attach (devnam, &dp); 1910141cc406Sopenharmony_ci /* make sure that there are at least two buffers */ 1911141cc406Sopenharmony_ci if (DEFAULT_BUFFERS < 2) 1912141cc406Sopenharmony_ci dp->info.buffers = DEFAULT_BUFFERS; 1913141cc406Sopenharmony_ci else 1914141cc406Sopenharmony_ci dp->info.buffers = 2; 1915141cc406Sopenharmony_ci dp->info.wanted_bufsize = DEFAULT_BUFSIZE; 1916141cc406Sopenharmony_ci dp->info.queued_reads = DEFAULT_QUEUED_READS; 1917141cc406Sopenharmony_ci return SANE_STATUS_GOOD; 1918141cc406Sopenharmony_ci } 1919141cc406Sopenharmony_ci 1920141cc406Sopenharmony_ci while (fgets(line, PATH_MAX, fp)) 1921141cc406Sopenharmony_ci { 1922141cc406Sopenharmony_ci linecount++; 1923141cc406Sopenharmony_ci word = 0; 1924141cc406Sopenharmony_ci lp = sanei_config_get_string(line, &word); 1925141cc406Sopenharmony_ci if (word) 1926141cc406Sopenharmony_ci { 1927141cc406Sopenharmony_ci if (word[0] != '#') 1928141cc406Sopenharmony_ci { 1929141cc406Sopenharmony_ci if (strcmp(word, "option") == 0) 1930141cc406Sopenharmony_ci { 1931141cc406Sopenharmony_ci free(word); 1932141cc406Sopenharmony_ci word = 0; 1933141cc406Sopenharmony_ci lp = sanei_config_get_string(lp, &word); 1934141cc406Sopenharmony_ci if (strcmp(word, "buffers") == 0) 1935141cc406Sopenharmony_ci { 1936141cc406Sopenharmony_ci free(word); 1937141cc406Sopenharmony_ci word = 0; 1938141cc406Sopenharmony_ci sanei_config_get_string(lp, &word); 1939141cc406Sopenharmony_ci i = strtol(word, &end, 0); 1940141cc406Sopenharmony_ci if (end == word) 1941141cc406Sopenharmony_ci { 1942141cc406Sopenharmony_ci DBG(1, "error in config file, line %i: number expected:\n", 1943141cc406Sopenharmony_ci linecount); 1944141cc406Sopenharmony_ci DBG(1, "%s\n", line); 1945141cc406Sopenharmony_ci } 1946141cc406Sopenharmony_ci else 1947141cc406Sopenharmony_ci if (i > 2) 1948141cc406Sopenharmony_ci buffers[opt_index] = i; 1949141cc406Sopenharmony_ci else 1950141cc406Sopenharmony_ci buffers[opt_index] = 2; 1951141cc406Sopenharmony_ci } 1952141cc406Sopenharmony_ci else if (strcmp(word, "buffersize") == 0) 1953141cc406Sopenharmony_ci { 1954141cc406Sopenharmony_ci free(word); 1955141cc406Sopenharmony_ci word = 0; 1956141cc406Sopenharmony_ci sanei_config_get_string(lp, &word); 1957141cc406Sopenharmony_ci i = strtol(word, &end, 0); 1958141cc406Sopenharmony_ci if (word == end) 1959141cc406Sopenharmony_ci { 1960141cc406Sopenharmony_ci DBG(1, "error in config file, line %i: number expected:\n", 1961141cc406Sopenharmony_ci linecount); 1962141cc406Sopenharmony_ci DBG(1, "%s\n", line); 1963141cc406Sopenharmony_ci } 1964141cc406Sopenharmony_ci else 1965141cc406Sopenharmony_ci bufsize[opt_index] = i; 1966141cc406Sopenharmony_ci } 1967141cc406Sopenharmony_ci else if (strcmp(word, "readqueue") == 0) 1968141cc406Sopenharmony_ci { 1969141cc406Sopenharmony_ci free(word); 1970141cc406Sopenharmony_ci word = 0; 1971141cc406Sopenharmony_ci sanei_config_get_string(lp, &word); 1972141cc406Sopenharmony_ci i = strtol(word, &end, 0); 1973141cc406Sopenharmony_ci if (word == end) 1974141cc406Sopenharmony_ci { 1975141cc406Sopenharmony_ci DBG(1, "error in config file, line %i: number expected:\n", 1976141cc406Sopenharmony_ci linecount); 1977141cc406Sopenharmony_ci DBG(1, "%s\n", line); 1978141cc406Sopenharmony_ci } 1979141cc406Sopenharmony_ci else 1980141cc406Sopenharmony_ci queued_reads[opt_index] = i; 1981141cc406Sopenharmony_ci } 1982141cc406Sopenharmony_ci else 1983141cc406Sopenharmony_ci { 1984141cc406Sopenharmony_ci DBG(1, "error in config file, line %i: unknown option\n", 1985141cc406Sopenharmony_ci linecount); 1986141cc406Sopenharmony_ci DBG(1, "%s\n", line); 1987141cc406Sopenharmony_ci } 1988141cc406Sopenharmony_ci } 1989141cc406Sopenharmony_ci else 1990141cc406Sopenharmony_ci { 1991141cc406Sopenharmony_ci while (new_devs) 1992141cc406Sopenharmony_ci { 1993141cc406Sopenharmony_ci if (buffers[1] >= 2) 1994141cc406Sopenharmony_ci new_devs->dev->info.buffers = buffers[1]; 1995141cc406Sopenharmony_ci else 1996141cc406Sopenharmony_ci new_devs->dev->info.buffers = 2; 1997141cc406Sopenharmony_ci if (bufsize[1] > 0) 1998141cc406Sopenharmony_ci new_devs->dev->info.wanted_bufsize = bufsize[1]; 1999141cc406Sopenharmony_ci else 2000141cc406Sopenharmony_ci new_devs->dev->info.wanted_bufsize = DEFAULT_BUFSIZE; 2001141cc406Sopenharmony_ci if (queued_reads[1] >= 0) 2002141cc406Sopenharmony_ci new_devs->dev->info.queued_reads = queued_reads[1]; 2003141cc406Sopenharmony_ci else 2004141cc406Sopenharmony_ci new_devs->dev->info.queued_reads = 0; 2005141cc406Sopenharmony_ci np = new_devs->next; 2006141cc406Sopenharmony_ci new_devs->next = new_dev_pool; 2007141cc406Sopenharmony_ci new_dev_pool = new_devs; 2008141cc406Sopenharmony_ci new_devs = np; 2009141cc406Sopenharmony_ci } 2010141cc406Sopenharmony_ci if (line[strlen(line)-1] == '\n') 2011141cc406Sopenharmony_ci line[strlen(line)-1] = 0; 2012141cc406Sopenharmony_ci sanei_config_attach_matching_devices(line, &attach_and_list); 2013141cc406Sopenharmony_ci buffers[1] = buffers[0]; 2014141cc406Sopenharmony_ci bufsize[1] = bufsize[0]; 2015141cc406Sopenharmony_ci queued_reads[1] = queued_reads[0]; 2016141cc406Sopenharmony_ci opt_index = 1; 2017141cc406Sopenharmony_ci } 2018141cc406Sopenharmony_ci } 2019141cc406Sopenharmony_ci if (word) free(word); 2020141cc406Sopenharmony_ci } 2021141cc406Sopenharmony_ci } 2022141cc406Sopenharmony_ci 2023141cc406Sopenharmony_ci while (new_devs) 2024141cc406Sopenharmony_ci { 2025141cc406Sopenharmony_ci if (buffers[1] >= 2) 2026141cc406Sopenharmony_ci new_devs->dev->info.buffers = buffers[1]; 2027141cc406Sopenharmony_ci else 2028141cc406Sopenharmony_ci new_devs->dev->info.buffers = 2; 2029141cc406Sopenharmony_ci if (bufsize[1] > 0) 2030141cc406Sopenharmony_ci new_devs->dev->info.wanted_bufsize = bufsize[1]; 2031141cc406Sopenharmony_ci else 2032141cc406Sopenharmony_ci new_devs->dev->info.wanted_bufsize = DEFAULT_BUFSIZE; 2033141cc406Sopenharmony_ci if (queued_reads[1] >= 0) 2034141cc406Sopenharmony_ci new_devs->dev->info.queued_reads = queued_reads[1]; 2035141cc406Sopenharmony_ci else 2036141cc406Sopenharmony_ci new_devs->dev->info.queued_reads = 0; 2037141cc406Sopenharmony_ci if (line[strlen(line)-1] == '\n') 2038141cc406Sopenharmony_ci line[strlen(line)-1] = 0; 2039141cc406Sopenharmony_ci np = new_devs->next; 2040141cc406Sopenharmony_ci free(new_devs); 2041141cc406Sopenharmony_ci new_devs = np; 2042141cc406Sopenharmony_ci } 2043141cc406Sopenharmony_ci while (new_dev_pool) 2044141cc406Sopenharmony_ci { 2045141cc406Sopenharmony_ci np = new_dev_pool->next; 2046141cc406Sopenharmony_ci free(new_dev_pool); 2047141cc406Sopenharmony_ci new_dev_pool = np; 2048141cc406Sopenharmony_ci } 2049141cc406Sopenharmony_ci fclose(fp); 2050141cc406Sopenharmony_ci DBG (10, ">>\n"); 2051141cc406Sopenharmony_ci return (SANE_STATUS_GOOD); 2052141cc406Sopenharmony_ci} 2053141cc406Sopenharmony_ci 2054141cc406Sopenharmony_civoid 2055141cc406Sopenharmony_cisane_exit (void) 2056141cc406Sopenharmony_ci{ 2057141cc406Sopenharmony_ci NEC_Device *dev, *next; 2058141cc406Sopenharmony_ci DBG (10, "<< sane_exit "); 2059141cc406Sopenharmony_ci 2060141cc406Sopenharmony_ci for (dev = first_dev; dev; dev = next) 2061141cc406Sopenharmony_ci { 2062141cc406Sopenharmony_ci next = dev->next; 2063141cc406Sopenharmony_ci free ((void *) dev->sane.name); 2064141cc406Sopenharmony_ci free ((void *) dev->sane.model); 2065141cc406Sopenharmony_ci free (dev); 2066141cc406Sopenharmony_ci } 2067141cc406Sopenharmony_ci first_dev = 0; 2068141cc406Sopenharmony_ci 2069141cc406Sopenharmony_ci if (devlist) 2070141cc406Sopenharmony_ci free(devlist); 2071141cc406Sopenharmony_ci 2072141cc406Sopenharmony_ci DBG (10, ">>\n"); 2073141cc406Sopenharmony_ci} 2074141cc406Sopenharmony_ci 2075141cc406Sopenharmony_ciSANE_Status 2076141cc406Sopenharmony_cisane_get_devices (const SANE_Device *** device_list, SANE_Bool local_only) 2077141cc406Sopenharmony_ci{ 2078141cc406Sopenharmony_ci NEC_Device *dev; 2079141cc406Sopenharmony_ci int i; 2080141cc406Sopenharmony_ci DBG (10, "<< sane_get_devices "); 2081141cc406Sopenharmony_ci 2082141cc406Sopenharmony_ci (void) local_only; /* silence compilation warnings */ 2083141cc406Sopenharmony_ci 2084141cc406Sopenharmony_ci if (devlist) 2085141cc406Sopenharmony_ci free (devlist); 2086141cc406Sopenharmony_ci devlist = malloc ((num_devices + 1) * sizeof (devlist[0])); 2087141cc406Sopenharmony_ci if (!devlist) 2088141cc406Sopenharmony_ci return (SANE_STATUS_NO_MEM); 2089141cc406Sopenharmony_ci 2090141cc406Sopenharmony_ci i = 0; 2091141cc406Sopenharmony_ci for (dev = first_dev; dev; dev = dev->next) 2092141cc406Sopenharmony_ci devlist[i++] = &dev->sane; 2093141cc406Sopenharmony_ci devlist[i++] = 0; 2094141cc406Sopenharmony_ci 2095141cc406Sopenharmony_ci *device_list = devlist; 2096141cc406Sopenharmony_ci 2097141cc406Sopenharmony_ci DBG (10, ">>\n"); 2098141cc406Sopenharmony_ci return SANE_STATUS_GOOD; 2099141cc406Sopenharmony_ci} 2100141cc406Sopenharmony_ci 2101141cc406Sopenharmony_ciSANE_Status 2102141cc406Sopenharmony_cisane_open (SANE_String_Const devnam, SANE_Handle * handle) 2103141cc406Sopenharmony_ci{ 2104141cc406Sopenharmony_ci SANE_Status status; 2105141cc406Sopenharmony_ci NEC_Device *dev; 2106141cc406Sopenharmony_ci NEC_Scanner *s; 2107141cc406Sopenharmony_ci#ifdef USE_CUSTOM_GAMMA 2108141cc406Sopenharmony_ci int i, j; 2109141cc406Sopenharmony_ci#endif 2110141cc406Sopenharmony_ci 2111141cc406Sopenharmony_ci DBG (10, "<< sane_open "); 2112141cc406Sopenharmony_ci 2113141cc406Sopenharmony_ci if (devnam[0]) 2114141cc406Sopenharmony_ci { 2115141cc406Sopenharmony_ci for (dev = first_dev; dev; dev = dev->next) 2116141cc406Sopenharmony_ci { 2117141cc406Sopenharmony_ci if (strcmp (dev->sane.name, devnam) == 0) 2118141cc406Sopenharmony_ci break; 2119141cc406Sopenharmony_ci } 2120141cc406Sopenharmony_ci 2121141cc406Sopenharmony_ci if (!dev) 2122141cc406Sopenharmony_ci { 2123141cc406Sopenharmony_ci status = attach (devnam, &dev); 2124141cc406Sopenharmony_ci if (status != SANE_STATUS_GOOD) 2125141cc406Sopenharmony_ci return (status); 2126141cc406Sopenharmony_ci } 2127141cc406Sopenharmony_ci } 2128141cc406Sopenharmony_ci else 2129141cc406Sopenharmony_ci { 2130141cc406Sopenharmony_ci dev = first_dev; 2131141cc406Sopenharmony_ci } 2132141cc406Sopenharmony_ci 2133141cc406Sopenharmony_ci if (!dev) 2134141cc406Sopenharmony_ci return (SANE_STATUS_INVAL); 2135141cc406Sopenharmony_ci 2136141cc406Sopenharmony_ci s = malloc (sizeof (*s)); 2137141cc406Sopenharmony_ci if (!s) 2138141cc406Sopenharmony_ci return SANE_STATUS_NO_MEM; 2139141cc406Sopenharmony_ci memset (s, 0, sizeof (*s)); 2140141cc406Sopenharmony_ci 2141141cc406Sopenharmony_ci s->fd = -1; 2142141cc406Sopenharmony_ci s->dev = dev; 2143141cc406Sopenharmony_ci 2144141cc406Sopenharmony_ci s->buffer = 0; 2145141cc406Sopenharmony_ci#ifdef USE_CUSTOM_GAMMA 2146141cc406Sopenharmony_ci for (i = 0; i < 4; ++i) 2147141cc406Sopenharmony_ci for (j = 0; j < 256; ++j) 2148141cc406Sopenharmony_ci s->gamma_table[i][j] = j; 2149141cc406Sopenharmony_ci#endif 2150141cc406Sopenharmony_ci status = init_options (s); 2151141cc406Sopenharmony_ci if (status != SANE_STATUS_GOOD) 2152141cc406Sopenharmony_ci { 2153141cc406Sopenharmony_ci /* xxx clean up mallocs */ 2154141cc406Sopenharmony_ci return status; 2155141cc406Sopenharmony_ci } 2156141cc406Sopenharmony_ci 2157141cc406Sopenharmony_ci s->next = first_handle; 2158141cc406Sopenharmony_ci first_handle = s; 2159141cc406Sopenharmony_ci 2160141cc406Sopenharmony_ci *handle = s; 2161141cc406Sopenharmony_ci 2162141cc406Sopenharmony_ci DBG (10, ">>\n"); 2163141cc406Sopenharmony_ci return SANE_STATUS_GOOD; 2164141cc406Sopenharmony_ci} 2165141cc406Sopenharmony_ci 2166141cc406Sopenharmony_civoid 2167141cc406Sopenharmony_cisane_close (SANE_Handle handle) 2168141cc406Sopenharmony_ci{ 2169141cc406Sopenharmony_ci NEC_Scanner *s = (NEC_Scanner *) handle; 2170141cc406Sopenharmony_ci DBG (10, "<< sane_close "); 2171141cc406Sopenharmony_ci 2172141cc406Sopenharmony_ci if (s->fd != -1) 2173141cc406Sopenharmony_ci sanei_scsi_close (s->fd); 2174141cc406Sopenharmony_ci#ifdef USE_FORK 2175141cc406Sopenharmony_ci { 2176141cc406Sopenharmony_ci struct shmid_ds ds; 2177141cc406Sopenharmony_ci if (s->shmid != -1) 2178141cc406Sopenharmony_ci shmctl(s->shmid, IPC_RMID, &ds); 2179141cc406Sopenharmony_ci } 2180141cc406Sopenharmony_ci#endif 2181141cc406Sopenharmony_ci if (s->buffer) 2182141cc406Sopenharmony_ci free(s->buffer); 2183141cc406Sopenharmony_ci free (s); 2184141cc406Sopenharmony_ci 2185141cc406Sopenharmony_ci DBG (10, ">>\n"); 2186141cc406Sopenharmony_ci} 2187141cc406Sopenharmony_ci 2188141cc406Sopenharmony_ciconst SANE_Option_Descriptor * 2189141cc406Sopenharmony_cisane_get_option_descriptor (SANE_Handle handle, SANE_Int option) 2190141cc406Sopenharmony_ci{ 2191141cc406Sopenharmony_ci NEC_Scanner *s = handle; 2192141cc406Sopenharmony_ci DBG (10, "<< sane_get_option_descriptor "); 2193141cc406Sopenharmony_ci 2194141cc406Sopenharmony_ci if ((unsigned) option >= NUM_OPTIONS) 2195141cc406Sopenharmony_ci return (0); 2196141cc406Sopenharmony_ci 2197141cc406Sopenharmony_ci DBG (10, ">>\n"); 2198141cc406Sopenharmony_ci return (s->opt + option); 2199141cc406Sopenharmony_ci} 2200141cc406Sopenharmony_ci 2201141cc406Sopenharmony_ciSANE_Status 2202141cc406Sopenharmony_cisane_control_option (SANE_Handle handle, SANE_Int option, 2203141cc406Sopenharmony_ci SANE_Action action, void *val, SANE_Int * info) 2204141cc406Sopenharmony_ci{ 2205141cc406Sopenharmony_ci NEC_Scanner *s = handle; 2206141cc406Sopenharmony_ci SANE_Status status; 2207141cc406Sopenharmony_ci#ifdef USE_CUSTOM_GAMMA 2208141cc406Sopenharmony_ci SANE_Word w, cap; 2209141cc406Sopenharmony_ci#else 2210141cc406Sopenharmony_ci SANE_Word cap; 2211141cc406Sopenharmony_ci#endif 2212141cc406Sopenharmony_ci int range_index; 2213141cc406Sopenharmony_ci DBG (10, "<< sane_control_option %i", option); 2214141cc406Sopenharmony_ci 2215141cc406Sopenharmony_ci if (info) 2216141cc406Sopenharmony_ci *info = 0; 2217141cc406Sopenharmony_ci 2218141cc406Sopenharmony_ci if (s->scanning) 2219141cc406Sopenharmony_ci return (SANE_STATUS_DEVICE_BUSY); 2220141cc406Sopenharmony_ci if (option >= NUM_OPTIONS) 2221141cc406Sopenharmony_ci return (SANE_STATUS_INVAL); 2222141cc406Sopenharmony_ci 2223141cc406Sopenharmony_ci cap = s->opt[option].cap; 2224141cc406Sopenharmony_ci if (!SANE_OPTION_IS_ACTIVE (cap)) 2225141cc406Sopenharmony_ci return (SANE_STATUS_INVAL); 2226141cc406Sopenharmony_ci 2227141cc406Sopenharmony_ci if (action == SANE_ACTION_GET_VALUE) 2228141cc406Sopenharmony_ci { 2229141cc406Sopenharmony_ci switch (option) 2230141cc406Sopenharmony_ci { 2231141cc406Sopenharmony_ci /* word options: */ 2232141cc406Sopenharmony_ci case OPT_RESOLUTION: 2233141cc406Sopenharmony_ci case OPT_TL_X: 2234141cc406Sopenharmony_ci case OPT_TL_Y: 2235141cc406Sopenharmony_ci case OPT_BR_X: 2236141cc406Sopenharmony_ci case OPT_BR_Y: 2237141cc406Sopenharmony_ci case OPT_NUM_OPTS: 2238141cc406Sopenharmony_ci case OPT_THRESHOLD: 2239141cc406Sopenharmony_ci case OPT_TINT: 2240141cc406Sopenharmony_ci case OPT_COLOR: 2241141cc406Sopenharmony_ci#ifdef USE_COLOR_THRESHOLD 2242141cc406Sopenharmony_ci case OPT_THRESHOLD_R: 2243141cc406Sopenharmony_ci case OPT_THRESHOLD_G: 2244141cc406Sopenharmony_ci case OPT_THRESHOLD_B: 2245141cc406Sopenharmony_ci#endif 2246141cc406Sopenharmony_ci case OPT_OR: 2247141cc406Sopenharmony_ci case OPT_NR: 2248141cc406Sopenharmony_ci case OPT_EDGE: 2249141cc406Sopenharmony_ci case OPT_PREVIEW: 2250141cc406Sopenharmony_ci#ifdef USE_CUSTOM_GAMMA 2251141cc406Sopenharmony_ci case OPT_CUSTOM_GAMMA: 2252141cc406Sopenharmony_ci#endif 2253141cc406Sopenharmony_ci *(SANE_Word *) val = s->val[option].w; 2254141cc406Sopenharmony_ci#if 0 /* here, values are read; reload should not be necessary */ 2255141cc406Sopenharmony_ci if (info) 2256141cc406Sopenharmony_ci *info |= SANE_INFO_RELOAD_PARAMS; 2257141cc406Sopenharmony_ci#endif 2258141cc406Sopenharmony_ci return (SANE_STATUS_GOOD); 2259141cc406Sopenharmony_ci 2260141cc406Sopenharmony_ci#ifdef USE_CUSTOM_GAMMA 2261141cc406Sopenharmony_ci /* word-array options: */ 2262141cc406Sopenharmony_ci case OPT_GAMMA_VECTOR: 2263141cc406Sopenharmony_ci case OPT_GAMMA_VECTOR_R: 2264141cc406Sopenharmony_ci case OPT_GAMMA_VECTOR_G: 2265141cc406Sopenharmony_ci case OPT_GAMMA_VECTOR_B: 2266141cc406Sopenharmony_ci memcpy (val, s->val[option].wa, s->opt[option].size); 2267141cc406Sopenharmony_ci return SANE_STATUS_GOOD; 2268141cc406Sopenharmony_ci#endif 2269141cc406Sopenharmony_ci 2270141cc406Sopenharmony_ci /* string options: */ 2271141cc406Sopenharmony_ci case OPT_MODE: 2272141cc406Sopenharmony_ci case OPT_HALFTONE: 2273141cc406Sopenharmony_ci case OPT_PAPER: 2274141cc406Sopenharmony_ci case OPT_GAMMA: 2275141cc406Sopenharmony_ci#ifdef USE_RESOLUTION_LIST 2276141cc406Sopenharmony_ci case OPT_RESOLUTION_LIST: 2277141cc406Sopenharmony_ci#endif 2278141cc406Sopenharmony_ci case OPT_EDGE_EMPHASIS: 2279141cc406Sopenharmony_ci case OPT_LIGHTCOLOR: 2280141cc406Sopenharmony_ci case OPT_SCANSOURCE: 2281141cc406Sopenharmony_ci strcpy (val, s->val[option].s); 2282141cc406Sopenharmony_ci#if 0 2283141cc406Sopenharmony_ci if (info) 2284141cc406Sopenharmony_ci *info |= SANE_INFO_RELOAD_PARAMS; 2285141cc406Sopenharmony_ci#endif 2286141cc406Sopenharmony_ci 2287141cc406Sopenharmony_ci return (SANE_STATUS_GOOD); 2288141cc406Sopenharmony_ci 2289141cc406Sopenharmony_ci } 2290141cc406Sopenharmony_ci } 2291141cc406Sopenharmony_ci else if (action == SANE_ACTION_SET_VALUE) 2292141cc406Sopenharmony_ci { 2293141cc406Sopenharmony_ci if (!SANE_OPTION_IS_SETTABLE (cap)) 2294141cc406Sopenharmony_ci return (SANE_STATUS_INVAL); 2295141cc406Sopenharmony_ci 2296141cc406Sopenharmony_ci status = sanei_constrain_value (s->opt + option, val, info); 2297141cc406Sopenharmony_ci if (status != SANE_STATUS_GOOD) 2298141cc406Sopenharmony_ci return status; 2299141cc406Sopenharmony_ci 2300141cc406Sopenharmony_ci switch (option) 2301141cc406Sopenharmony_ci { 2302141cc406Sopenharmony_ci /* (mostly) side-effect-free word options: */ 2303141cc406Sopenharmony_ci case OPT_RESOLUTION: 2304141cc406Sopenharmony_ci case OPT_TL_X: 2305141cc406Sopenharmony_ci case OPT_TL_Y: 2306141cc406Sopenharmony_ci case OPT_BR_X: 2307141cc406Sopenharmony_ci case OPT_BR_Y: 2308141cc406Sopenharmony_ci if (info && s->val[option].w != *(SANE_Word *) val) 2309141cc406Sopenharmony_ci *info |= SANE_INFO_RELOAD_PARAMS; 2310141cc406Sopenharmony_ci // fall through 2311141cc406Sopenharmony_ci case OPT_NUM_OPTS: 2312141cc406Sopenharmony_ci case OPT_THRESHOLD: 2313141cc406Sopenharmony_ci /* xxx theoretically, we could use OPT_THRESHOLD in 2314141cc406Sopenharmony_ci bi-level color mode to adjust all three other 2315141cc406Sopenharmony_ci threshold together. But this would require to set 2316141cc406Sopenharmony_ci the bit SANE_INFO_RELOAD_OPTIONS in *info, and that 2317141cc406Sopenharmony_ci would unfortunately cause a crash in both xscanimage 2318141cc406Sopenharmony_ci and xsane... Therefore, OPT_THRESHOLD is disabled 2319141cc406Sopenharmony_ci for bi-level color scan right now. 2320141cc406Sopenharmony_ci */ 2321141cc406Sopenharmony_ci case OPT_TINT: 2322141cc406Sopenharmony_ci case OPT_COLOR: 2323141cc406Sopenharmony_ci#ifdef USE_COLOR_THRESHOLD 2324141cc406Sopenharmony_ci case OPT_THRESHOLD_R: 2325141cc406Sopenharmony_ci case OPT_THRESHOLD_G: 2326141cc406Sopenharmony_ci case OPT_THRESHOLD_B: 2327141cc406Sopenharmony_ci#endif 2328141cc406Sopenharmony_ci case OPT_OR: 2329141cc406Sopenharmony_ci case OPT_NR: 2330141cc406Sopenharmony_ci case OPT_EDGE: 2331141cc406Sopenharmony_ci case OPT_PREVIEW: 2332141cc406Sopenharmony_ci s->val[option].w = *(SANE_Word *) val; 2333141cc406Sopenharmony_ci return (SANE_STATUS_GOOD); 2334141cc406Sopenharmony_ci 2335141cc406Sopenharmony_ci case OPT_MODE: 2336141cc406Sopenharmony_ci if (strcmp (val, M_LINEART) == 0) 2337141cc406Sopenharmony_ci { 2338141cc406Sopenharmony_ci s->opt[OPT_LIGHTCOLOR].cap &= ~SANE_CAP_INACTIVE; 2339141cc406Sopenharmony_ci s->opt[OPT_THRESHOLD].cap &= ~SANE_CAP_INACTIVE; 2340141cc406Sopenharmony_ci s->opt[OPT_TINT].cap |= SANE_CAP_INACTIVE; 2341141cc406Sopenharmony_ci s->opt[OPT_COLOR].cap |= SANE_CAP_INACTIVE; 2342141cc406Sopenharmony_ci#ifdef USE_COLOR_THRESHOLD 2343141cc406Sopenharmony_ci s->opt[OPT_THRESHOLD_R].cap |= SANE_CAP_INACTIVE; 2344141cc406Sopenharmony_ci s->opt[OPT_THRESHOLD_G].cap |= SANE_CAP_INACTIVE; 2345141cc406Sopenharmony_ci s->opt[OPT_THRESHOLD_B].cap |= SANE_CAP_INACTIVE; 2346141cc406Sopenharmony_ci#endif 2347141cc406Sopenharmony_ci if (s->dev->sensedat.model == PCIN500) 2348141cc406Sopenharmony_ci s->opt[OPT_HALFTONE].cap &= ~SANE_CAP_INACTIVE; 2349141cc406Sopenharmony_ci } 2350141cc406Sopenharmony_ci else if (strcmp (val, M_LINEART_COLOR) == 0) 2351141cc406Sopenharmony_ci { 2352141cc406Sopenharmony_ci s->opt[OPT_LIGHTCOLOR].cap |= SANE_CAP_INACTIVE; 2353141cc406Sopenharmony_ci s->opt[OPT_THRESHOLD].cap |= SANE_CAP_INACTIVE; 2354141cc406Sopenharmony_ci s->opt[OPT_TINT].cap |= SANE_CAP_INACTIVE; 2355141cc406Sopenharmony_ci s->opt[OPT_COLOR].cap |= SANE_CAP_INACTIVE; 2356141cc406Sopenharmony_ci#ifdef USE_COLOR_THRESHOLD 2357141cc406Sopenharmony_ci s->opt[OPT_THRESHOLD_R].cap &= ~SANE_CAP_INACTIVE; 2358141cc406Sopenharmony_ci s->opt[OPT_THRESHOLD_G].cap &= ~SANE_CAP_INACTIVE; 2359141cc406Sopenharmony_ci s->opt[OPT_THRESHOLD_B].cap &= ~SANE_CAP_INACTIVE; 2360141cc406Sopenharmony_ci#endif 2361141cc406Sopenharmony_ci if (s->dev->sensedat.model == PCIN500) 2362141cc406Sopenharmony_ci s->opt[OPT_HALFTONE].cap &= ~SANE_CAP_INACTIVE; 2363141cc406Sopenharmony_ci } 2364141cc406Sopenharmony_ci else if (strcmp (val, M_GRAY) == 0) 2365141cc406Sopenharmony_ci { 2366141cc406Sopenharmony_ci s->opt[OPT_LIGHTCOLOR].cap &= ~SANE_CAP_INACTIVE; 2367141cc406Sopenharmony_ci s->opt[OPT_THRESHOLD].cap |= SANE_CAP_INACTIVE; 2368141cc406Sopenharmony_ci s->opt[OPT_TINT].cap |= SANE_CAP_INACTIVE; 2369141cc406Sopenharmony_ci s->opt[OPT_COLOR].cap |= SANE_CAP_INACTIVE; 2370141cc406Sopenharmony_ci#ifdef USE_COLOR_THRESHOLD 2371141cc406Sopenharmony_ci s->opt[OPT_THRESHOLD_R].cap |= SANE_CAP_INACTIVE; 2372141cc406Sopenharmony_ci s->opt[OPT_THRESHOLD_G].cap |= SANE_CAP_INACTIVE; 2373141cc406Sopenharmony_ci s->opt[OPT_THRESHOLD_B].cap |= SANE_CAP_INACTIVE; 2374141cc406Sopenharmony_ci#endif 2375141cc406Sopenharmony_ci s->opt[OPT_HALFTONE].cap |= SANE_CAP_INACTIVE; 2376141cc406Sopenharmony_ci } 2377141cc406Sopenharmony_ci else 2378141cc406Sopenharmony_ci { 2379141cc406Sopenharmony_ci s->opt[OPT_LIGHTCOLOR].cap |= SANE_CAP_INACTIVE; 2380141cc406Sopenharmony_ci s->opt[OPT_THRESHOLD].cap |= SANE_CAP_INACTIVE; 2381141cc406Sopenharmony_ci s->opt[OPT_TINT].cap &= ~SANE_CAP_INACTIVE; 2382141cc406Sopenharmony_ci s->opt[OPT_COLOR].cap &= ~SANE_CAP_INACTIVE; 2383141cc406Sopenharmony_ci#ifdef USE_COLOR_THRESHOLD 2384141cc406Sopenharmony_ci s->opt[OPT_THRESHOLD_R].cap |= SANE_CAP_INACTIVE; 2385141cc406Sopenharmony_ci s->opt[OPT_THRESHOLD_G].cap |= SANE_CAP_INACTIVE; 2386141cc406Sopenharmony_ci s->opt[OPT_THRESHOLD_B].cap |= SANE_CAP_INACTIVE; 2387141cc406Sopenharmony_ci#endif 2388141cc406Sopenharmony_ci s->opt[OPT_HALFTONE].cap |= SANE_CAP_INACTIVE; 2389141cc406Sopenharmony_ci } 2390141cc406Sopenharmony_ci#if 0 2391141cc406Sopenharmony_ci if ( strcmp (val, M_LINEART) == 0 2392141cc406Sopenharmony_ci || strcmp (val, M_GRAY) == 0) 2393141cc406Sopenharmony_ci { 2394141cc406Sopenharmony_ci s->opt[OPT_LIGHTCOLOR].cap &= ~SANE_CAP_INACTIVE; 2395141cc406Sopenharmony_ci } 2396141cc406Sopenharmony_ci else 2397141cc406Sopenharmony_ci { 2398141cc406Sopenharmony_ci s->opt[OPT_LIGHTCOLOR].cap |= SANE_CAP_INACTIVE; 2399141cc406Sopenharmony_ci } 2400141cc406Sopenharmony_ci#endif 2401141cc406Sopenharmony_ci strcpy(s->val[option].s, val); 2402141cc406Sopenharmony_ci#ifdef USE_CUSTOM_GAMMA 2403141cc406Sopenharmony_ci set_gamma_caps(s); 2404141cc406Sopenharmony_ci#endif 2405141cc406Sopenharmony_ci if (info) 2406141cc406Sopenharmony_ci *info |= SANE_INFO_RELOAD_OPTIONS | SANE_INFO_RELOAD_PARAMS; 2407141cc406Sopenharmony_ci return (SANE_STATUS_GOOD); 2408141cc406Sopenharmony_ci 2409141cc406Sopenharmony_ci case OPT_GAMMA: 2410141cc406Sopenharmony_ci case OPT_HALFTONE: 2411141cc406Sopenharmony_ci case OPT_EDGE_EMPHASIS: 2412141cc406Sopenharmony_ci case OPT_LIGHTCOLOR: 2413141cc406Sopenharmony_ci#if 0 2414141cc406Sopenharmony_ci if (s->val[option].s) 2415141cc406Sopenharmony_ci free (s->val[option].s); 2416141cc406Sopenharmony_ci s->val[option].s = strdup (val); 2417141cc406Sopenharmony_ci#endif 2418141cc406Sopenharmony_ci strcpy(s->val[option].s, val); 2419141cc406Sopenharmony_ci return (SANE_STATUS_GOOD); 2420141cc406Sopenharmony_ci 2421141cc406Sopenharmony_ci case OPT_SCANSOURCE: 2422141cc406Sopenharmony_ci if (info && strcmp (s->val[option].s, (SANE_String) val)) 2423141cc406Sopenharmony_ci *info |= SANE_INFO_RELOAD_OPTIONS | SANE_INFO_RELOAD_PARAMS; 2424141cc406Sopenharmony_ci#if 0 2425141cc406Sopenharmony_ci if (s->val[option].s) 2426141cc406Sopenharmony_ci free (s->val[option].s); 2427141cc406Sopenharmony_ci s->val[option].s = strdup (val); 2428141cc406Sopenharmony_ci#endif 2429141cc406Sopenharmony_ci strcpy(s->val[option].s, val); 2430141cc406Sopenharmony_ci if (strcmp(val, use_fsu) == 0) 2431141cc406Sopenharmony_ci range_index = SCAN_WITH_FSU; 2432141cc406Sopenharmony_ci else if (strcmp(val, use_adf) == 0) 2433141cc406Sopenharmony_ci range_index = SCAN_WITH_ADF; 2434141cc406Sopenharmony_ci else 2435141cc406Sopenharmony_ci range_index = SCAN_SIMPLE; 2436141cc406Sopenharmony_ci 2437141cc406Sopenharmony_ci s->opt[OPT_TL_X].constraint.range 2438141cc406Sopenharmony_ci = &s->dev->info.tl_x_ranges[range_index]; 2439141cc406Sopenharmony_ci clip_value (&s->opt[OPT_TL_X], &s->val[OPT_TL_X].w); 2440141cc406Sopenharmony_ci 2441141cc406Sopenharmony_ci s->opt[OPT_TL_Y].constraint.range 2442141cc406Sopenharmony_ci = &s->dev->info.tl_y_ranges[range_index]; 2443141cc406Sopenharmony_ci clip_value (&s->opt[OPT_TL_Y], &s->val[OPT_TL_Y].w); 2444141cc406Sopenharmony_ci 2445141cc406Sopenharmony_ci s->opt[OPT_BR_X].constraint.range 2446141cc406Sopenharmony_ci = &s->dev->info.br_x_ranges[range_index]; 2447141cc406Sopenharmony_ci clip_value (&s->opt[OPT_BR_X], &s->val[OPT_BR_X].w); 2448141cc406Sopenharmony_ci 2449141cc406Sopenharmony_ci s->opt[OPT_BR_Y].constraint.range 2450141cc406Sopenharmony_ci = &s->dev->info.br_y_ranges[range_index]; 2451141cc406Sopenharmony_ci clip_value (&s->opt[OPT_BR_Y], &s->val[OPT_BR_Y].w); 2452141cc406Sopenharmony_ci 2453141cc406Sopenharmony_ci return (SANE_STATUS_GOOD); 2454141cc406Sopenharmony_ci 2455141cc406Sopenharmony_ci case OPT_PAPER: 2456141cc406Sopenharmony_ci if (info) 2457141cc406Sopenharmony_ci *info |= SANE_INFO_RELOAD_OPTIONS | SANE_INFO_RELOAD_PARAMS; 2458141cc406Sopenharmony_ci#if 0 2459141cc406Sopenharmony_ci if (s->val[option].s) 2460141cc406Sopenharmony_ci free (s->val[option].s); 2461141cc406Sopenharmony_ci s->val[option].s = strdup (val); 2462141cc406Sopenharmony_ci#endif 2463141cc406Sopenharmony_ci strcpy(s->val[option].s, val); 2464141cc406Sopenharmony_ci s->val[OPT_TL_X].w = SANE_FIX(0); 2465141cc406Sopenharmony_ci s->val[OPT_TL_Y].w = SANE_FIX(0); 2466141cc406Sopenharmony_ci if (strcmp (s->val[option].s, "A3") == 0){ 2467141cc406Sopenharmony_ci s->val[OPT_BR_X].w = SANE_FIX(297); 2468141cc406Sopenharmony_ci s->val[OPT_BR_Y].w = SANE_FIX(420); 2469141cc406Sopenharmony_ci }else if (strcmp (s->val[option].s, "A4") == 0){ 2470141cc406Sopenharmony_ci s->val[OPT_BR_X].w = SANE_FIX(210); 2471141cc406Sopenharmony_ci s->val[OPT_BR_Y].w = SANE_FIX(297); 2472141cc406Sopenharmony_ci }else if (strcmp (s->val[option].s, "A5") == 0){ 2473141cc406Sopenharmony_ci s->val[OPT_BR_X].w = SANE_FIX(148.5); 2474141cc406Sopenharmony_ci s->val[OPT_BR_Y].w = SANE_FIX(210); 2475141cc406Sopenharmony_ci }else if (strcmp (s->val[option].s, "A6") == 0){ 2476141cc406Sopenharmony_ci s->val[OPT_BR_X].w = SANE_FIX(105); 2477141cc406Sopenharmony_ci s->val[OPT_BR_Y].w = SANE_FIX(148.5); 2478141cc406Sopenharmony_ci }else if (strcmp (s->val[option].s, "B4") == 0){ 2479141cc406Sopenharmony_ci s->val[OPT_BR_X].w = SANE_FIX(250); 2480141cc406Sopenharmony_ci s->val[OPT_BR_Y].w = SANE_FIX(353); 2481141cc406Sopenharmony_ci }else if (strcmp (s->val[option].s, "B5") == 0){ 2482141cc406Sopenharmony_ci s->val[OPT_BR_X].w = SANE_FIX(182); 2483141cc406Sopenharmony_ci s->val[OPT_BR_Y].w = SANE_FIX(257); 2484141cc406Sopenharmony_ci }else if (strcmp (s->val[option].s, W_LETTER) == 0){ 2485141cc406Sopenharmony_ci s->val[OPT_BR_X].w = SANE_FIX(279.4); 2486141cc406Sopenharmony_ci s->val[OPT_BR_Y].w = SANE_FIX(431.8); 2487141cc406Sopenharmony_ci }else if (strcmp (s->val[option].s, "Legal") == 0){ 2488141cc406Sopenharmony_ci s->val[OPT_BR_X].w = SANE_FIX(215.9); 2489141cc406Sopenharmony_ci s->val[OPT_BR_Y].w = SANE_FIX(355.6); 2490141cc406Sopenharmony_ci }else if (strcmp (s->val[option].s, "Letter") == 0){ 2491141cc406Sopenharmony_ci s->val[OPT_BR_X].w = SANE_FIX(215.9); 2492141cc406Sopenharmony_ci s->val[OPT_BR_Y].w = SANE_FIX(279.4); 2493141cc406Sopenharmony_ci }else if (strcmp (s->val[option].s, INVOICE) == 0){ 2494141cc406Sopenharmony_ci s->val[OPT_BR_X].w = SANE_FIX(215.9); 2495141cc406Sopenharmony_ci s->val[OPT_BR_Y].w = SANE_FIX(139.7); 2496141cc406Sopenharmony_ci }else{ 2497141cc406Sopenharmony_ci } 2498141cc406Sopenharmony_ci return (SANE_STATUS_GOOD); 2499141cc406Sopenharmony_ci 2500141cc406Sopenharmony_ci#ifdef USE_RESOLUTION_LIST 2501141cc406Sopenharmony_ci case OPT_RESOLUTION_LIST: 2502141cc406Sopenharmony_ci if (info) 2503141cc406Sopenharmony_ci *info |= SANE_INFO_RELOAD_OPTIONS | SANE_INFO_RELOAD_PARAMS; 2504141cc406Sopenharmony_ci#if 0 2505141cc406Sopenharmony_ci if (s->val[option].s) 2506141cc406Sopenharmony_ci free (s->val[option].s); 2507141cc406Sopenharmony_ci s->val[option].s = strdup (val); 2508141cc406Sopenharmony_ci#endif 2509141cc406Sopenharmony_ci for (i = 0; s->opt[OPT_RESOLUTION_LIST].constraint.string_list[i]; i++) { 2510141cc406Sopenharmony_ci if (strcmp (val, 2511141cc406Sopenharmony_ci s->opt[OPT_RESOLUTION_LIST].constraint.string_list[i]) == 0){ 2512141cc406Sopenharmony_ci s->val[OPT_RESOLUTION].w 2513141cc406Sopenharmony_ci = atoi(s->opt[OPT_RESOLUTION_LIST].constraint.string_list[i]); 2514141cc406Sopenharmony_ci if (info) 2515141cc406Sopenharmony_ci *info |= SANE_INFO_RELOAD_PARAMS; 2516141cc406Sopenharmony_ci break; 2517141cc406Sopenharmony_ci } 2518141cc406Sopenharmony_ci } 2519141cc406Sopenharmony_ci return (SANE_STATUS_GOOD); 2520141cc406Sopenharmony_ci#endif 2521141cc406Sopenharmony_ci 2522141cc406Sopenharmony_ci#ifdef USE_CUSTOM_GAMMA 2523141cc406Sopenharmony_ci /* side-effect-free word-array options: */ 2524141cc406Sopenharmony_ci case OPT_GAMMA_VECTOR: 2525141cc406Sopenharmony_ci case OPT_GAMMA_VECTOR_R: 2526141cc406Sopenharmony_ci case OPT_GAMMA_VECTOR_G: 2527141cc406Sopenharmony_ci case OPT_GAMMA_VECTOR_B: 2528141cc406Sopenharmony_ci memcpy (s->val[option].wa, val, s->opt[option].size); 2529141cc406Sopenharmony_ci return SANE_STATUS_GOOD; 2530141cc406Sopenharmony_ci 2531141cc406Sopenharmony_ci case OPT_CUSTOM_GAMMA: 2532141cc406Sopenharmony_ci w = *(SANE_Word *) val; 2533141cc406Sopenharmony_ci 2534141cc406Sopenharmony_ci if (w == s->val[OPT_CUSTOM_GAMMA].w) 2535141cc406Sopenharmony_ci return SANE_STATUS_GOOD; /* no change */ 2536141cc406Sopenharmony_ci 2537141cc406Sopenharmony_ci if (info) 2538141cc406Sopenharmony_ci *info |= SANE_INFO_RELOAD_OPTIONS; 2539141cc406Sopenharmony_ci s->val[OPT_CUSTOM_GAMMA].w = w; 2540141cc406Sopenharmony_ci set_gamma_caps(s); 2541141cc406Sopenharmony_ci return SANE_STATUS_GOOD; 2542141cc406Sopenharmony_ci#endif 2543141cc406Sopenharmony_ci } 2544141cc406Sopenharmony_ci } 2545141cc406Sopenharmony_ci 2546141cc406Sopenharmony_ci DBG (10, ">>\n"); 2547141cc406Sopenharmony_ci return (SANE_STATUS_INVAL); 2548141cc406Sopenharmony_ci} 2549141cc406Sopenharmony_ci 2550141cc406Sopenharmony_ciSANE_Status 2551141cc406Sopenharmony_cisane_get_parameters (SANE_Handle handle, SANE_Parameters * params) 2552141cc406Sopenharmony_ci{ 2553141cc406Sopenharmony_ci int width, length, res; 2554141cc406Sopenharmony_ci const char *mode; 2555141cc406Sopenharmony_ci NEC_Scanner *s = handle; 2556141cc406Sopenharmony_ci DBG (10, "<< sane_get_parameters "); 2557141cc406Sopenharmony_ci 2558141cc406Sopenharmony_ci res = s->val[OPT_RESOLUTION].w * s->dev->info.res_range.quant; 2559141cc406Sopenharmony_ci if (!s->scanning) 2560141cc406Sopenharmony_ci { 2561141cc406Sopenharmony_ci /* make best-effort guess at what parameters will look like once 2562141cc406Sopenharmony_ci scanning starts. */ 2563141cc406Sopenharmony_ci memset (&s->params, 0, sizeof (s->params)); 2564141cc406Sopenharmony_ci 2565141cc406Sopenharmony_ci width = MM_TO_PIX( SANE_UNFIX(s->val[OPT_BR_X].w) 2566141cc406Sopenharmony_ci - SANE_UNFIX(s->val[OPT_TL_X].w), 2567141cc406Sopenharmony_ci s->dev->info.mud); 2568141cc406Sopenharmony_ci length = MM_TO_PIX( SANE_UNFIX(s->val[OPT_BR_Y].w) 2569141cc406Sopenharmony_ci - SANE_UNFIX(s->val[OPT_TL_Y].w), 2570141cc406Sopenharmony_ci s->dev->info.mud); 2571141cc406Sopenharmony_ci 2572141cc406Sopenharmony_ci s->width = width; 2573141cc406Sopenharmony_ci s->length = length; 2574141cc406Sopenharmony_ci s->params.pixels_per_line = width * res / s->dev->info.mud; 2575141cc406Sopenharmony_ci s->params.lines = length * res / s->dev->info.mud; 2576141cc406Sopenharmony_ci 2577141cc406Sopenharmony_ci if (s->dev->sensedat.model == PCIN500) 2578141cc406Sopenharmony_ci { 2579141cc406Sopenharmony_ci s->params.pixels_per_line += 1; 2580141cc406Sopenharmony_ci s->params.lines += 1; 2581141cc406Sopenharmony_ci } 2582141cc406Sopenharmony_ci s->unscanned_lines = s->params.lines; 2583141cc406Sopenharmony_ci } 2584141cc406Sopenharmony_ci#if 0 2585141cc406Sopenharmony_ci else 2586141cc406Sopenharmony_ci { 2587141cc406Sopenharmony_ci buffer_status bs; 2588141cc406Sopenharmony_ci SANE_Status status; 2589141cc406Sopenharmony_ci size_t len = sizeof (buffer_status); 2590141cc406Sopenharmony_ci status = get_data_buffer_status (s->fd, &bs, &len); 2591141cc406Sopenharmony_ci DBG (11, "<< get_data_buffer_status "); 2592141cc406Sopenharmony_ci 2593141cc406Sopenharmony_ci if (status != SANE_STATUS_GOOD) 2594141cc406Sopenharmony_ci { 2595141cc406Sopenharmony_ci do_cancel(s); 2596141cc406Sopenharmony_ci return (status); 2597141cc406Sopenharmony_ci } 2598141cc406Sopenharmony_ci DBG (11, ">>\n "); 2599141cc406Sopenharmony_ci { 2600141cc406Sopenharmony_ci#ifdef DEBUG_NEC 2601141cc406Sopenharmony_ci int i; 2602141cc406Sopenharmony_ci u_char *buf = &bs; 2603141cc406Sopenharmony_ci DBG(11, "get data buffer status(debug):\n"); 2604141cc406Sopenharmony_ci for (i = 0; i < len; i += 16) 2605141cc406Sopenharmony_ci { 2606141cc406Sopenharmony_ci DBG(1, "%2x %2x %2x %2x %2x %2x %2x %2x - %2x %2x %2x %2x \n", 2607141cc406Sopenharmony_ci buf[i], buf[i+1], buf[i+2], buf[i+3], buf[i+4], buf[i+5], buf[i+6], buf[i+7], buf[i+8], 2608141cc406Sopenharmony_ci buf[i+9], buf[i+10], buf[i+11]); 2609141cc406Sopenharmony_ci } 2610141cc406Sopenharmony_ci#endif 2611141cc406Sopenharmony_ci } 2612141cc406Sopenharmony_ci } 2613141cc406Sopenharmony_ci#endif 2614141cc406Sopenharmony_ci res = s->val[OPT_RESOLUTION].w * s->dev->info.res_range.quant; 2615141cc406Sopenharmony_ci 2616141cc406Sopenharmony_ci mode = s->val[OPT_MODE].s; 2617141cc406Sopenharmony_ci 2618141cc406Sopenharmony_ci if (strcmp (mode, M_LINEART) == 0) 2619141cc406Sopenharmony_ci { 2620141cc406Sopenharmony_ci s->params.format = SANE_FRAME_GRAY; 2621141cc406Sopenharmony_ci s->params.bytes_per_line = (s->params.pixels_per_line + 7) / 8; 2622141cc406Sopenharmony_ci s->params.depth = 1; 2623141cc406Sopenharmony_ci s->modes = MODES_LINEART; 2624141cc406Sopenharmony_ci } 2625141cc406Sopenharmony_ci else if (strcmp (mode, M_GRAY) == 0) 2626141cc406Sopenharmony_ci { 2627141cc406Sopenharmony_ci s->params.format = SANE_FRAME_GRAY; 2628141cc406Sopenharmony_ci s->params.bytes_per_line = s->params.pixels_per_line; 2629141cc406Sopenharmony_ci s->params.depth = 8; 2630141cc406Sopenharmony_ci s->modes = MODES_GRAY; 2631141cc406Sopenharmony_ci } 2632141cc406Sopenharmony_ci else if (strcmp (mode, M_LINEART_COLOR) == 0) 2633141cc406Sopenharmony_ci { 2634141cc406Sopenharmony_ci s->params.format = SANE_FRAME_RGB; 2635141cc406Sopenharmony_ci s->params.bytes_per_line = 3 * (s->params.pixels_per_line + 7) / 8; 2636141cc406Sopenharmony_ci s->params.depth = 8; 2637141cc406Sopenharmony_ci s->modes = MODES_LINEART_COLOR; 2638141cc406Sopenharmony_ci } 2639141cc406Sopenharmony_ci else 2640141cc406Sopenharmony_ci { 2641141cc406Sopenharmony_ci s->params.format = SANE_FRAME_RGB; 2642141cc406Sopenharmony_ci s->params.bytes_per_line = 3 * s->params.pixels_per_line; 2643141cc406Sopenharmony_ci s->params.depth = 8; 2644141cc406Sopenharmony_ci s->modes = MODES_COLOR; 2645141cc406Sopenharmony_ci } 2646141cc406Sopenharmony_ci s->params.last_frame = SANE_TRUE; 2647141cc406Sopenharmony_ci 2648141cc406Sopenharmony_ci if (params) 2649141cc406Sopenharmony_ci *params = s->params; 2650141cc406Sopenharmony_ci 2651141cc406Sopenharmony_ci DBG (10, ">>\n"); 2652141cc406Sopenharmony_ci return (SANE_STATUS_GOOD); 2653141cc406Sopenharmony_ci} 2654141cc406Sopenharmony_ci 2655141cc406Sopenharmony_ci#ifdef USE_CUSTOM_GAMMA 2656141cc406Sopenharmony_ci 2657141cc406Sopenharmony_cistatic int 2658141cc406Sopenharmony_cisprint_gamma(Option_Value val, SANE_Byte *dst) 2659141cc406Sopenharmony_ci{ 2660141cc406Sopenharmony_ci int i; 2661141cc406Sopenharmony_ci SANE_Byte *p = dst; 2662141cc406Sopenharmony_ci 2663141cc406Sopenharmony_ci p += sprintf((char *) p, "%i", val.wa[0]); 2664141cc406Sopenharmony_ci for (i = 1; i < 256; i++) 2665141cc406Sopenharmony_ci p += sprintf((char *) p, ",%i", val.wa[i] > 255 ? 255 : val.wa[i]); 2666141cc406Sopenharmony_ci return p - dst; 2667141cc406Sopenharmony_ci} 2668141cc406Sopenharmony_ci 2669141cc406Sopenharmony_cistatic SANE_Status 2670141cc406Sopenharmony_cisend_ascii_gamma_tables (NEC_Scanner *s) 2671141cc406Sopenharmony_ci{ 2672141cc406Sopenharmony_ci SANE_Status status; 2673141cc406Sopenharmony_ci int i; 2674141cc406Sopenharmony_ci 2675141cc406Sopenharmony_ci DBG(11, "<< send_ascii_gamma_tables "); 2676141cc406Sopenharmony_ci 2677141cc406Sopenharmony_ci /* we need: 4 bytes for each gamma value (3 digits + delimiter) 2678141cc406Sopenharmony_ci + 10 bytes for the command header 2679141cc406Sopenharmony_ci i.e. 4 * 4 * 256 + 10 = 4106 bytes 2680141cc406Sopenharmony_ci */ 2681141cc406Sopenharmony_ci 2682141cc406Sopenharmony_ci if (s->dev->info.bufsize < 4106) 2683141cc406Sopenharmony_ci return SANE_STATUS_NO_MEM; 2684141cc406Sopenharmony_ci 2685141cc406Sopenharmony_ci memset(s->buffer, 0, 4106); 2686141cc406Sopenharmony_ci 2687141cc406Sopenharmony_ci i = sprint_gamma(s->val[OPT_GAMMA_VECTOR_R], &s->buffer[10]); 2688141cc406Sopenharmony_ci s->buffer[10+i++] = '/'; 2689141cc406Sopenharmony_ci i += sprint_gamma(s->val[OPT_GAMMA_VECTOR_G], &s->buffer[10+i]); 2690141cc406Sopenharmony_ci s->buffer[10+i++] = '/'; 2691141cc406Sopenharmony_ci i += sprint_gamma(s->val[OPT_GAMMA_VECTOR_B], &s->buffer[10+i]); 2692141cc406Sopenharmony_ci s->buffer[10+i++] = '/'; 2693141cc406Sopenharmony_ci i += sprint_gamma(s->val[OPT_GAMMA_VECTOR], &s->buffer[10+i]); 2694141cc406Sopenharmony_ci 2695141cc406Sopenharmony_ci DBG(12, "%s\n", &s->buffer[10]); 2696141cc406Sopenharmony_ci 2697141cc406Sopenharmony_ci s->buffer[0] = SEND; 2698141cc406Sopenharmony_ci s->buffer[2] = 0x03; 2699141cc406Sopenharmony_ci s->buffer[7] = i >> 8; 2700141cc406Sopenharmony_ci s->buffer[8] = i & 0xff; 2701141cc406Sopenharmony_ci 2702141cc406Sopenharmony_ci wait_ready(s->fd); 2703141cc406Sopenharmony_ci status = sanei_scsi_cmd (s->fd, s->buffer, i+10, 0, 0); 2704141cc406Sopenharmony_ci 2705141cc406Sopenharmony_ci DBG(11, ">>\n"); 2706141cc406Sopenharmony_ci 2707141cc406Sopenharmony_ci return status; 2708141cc406Sopenharmony_ci} 2709141cc406Sopenharmony_ci#endif 2710141cc406Sopenharmony_ci 2711141cc406Sopenharmony_cistatic SANE_Status 2712141cc406Sopenharmony_cisend_binary_g_table(NEC_Scanner *s, SANE_Word *a, int dtq) 2713141cc406Sopenharmony_ci{ 2714141cc406Sopenharmony_ci SANE_Status status; 2715141cc406Sopenharmony_ci unsigned int i, j; 2716141cc406Sopenharmony_ci 2717141cc406Sopenharmony_ci (void) dtq; /* silence compilation warnings */ 2718141cc406Sopenharmony_ci 2719141cc406Sopenharmony_ci DBG(11, "<< send_binary_g_table\n"); 2720141cc406Sopenharmony_ci 2721141cc406Sopenharmony_ci i = 256; 2722141cc406Sopenharmony_ci if (s->dev->info.bufsize < i) 2723141cc406Sopenharmony_ci return SANE_STATUS_NO_MEM; 2724141cc406Sopenharmony_ci memset(s->buffer, 0, i+10); 2725141cc406Sopenharmony_ci 2726141cc406Sopenharmony_ci s->buffer[0] = SEND; 2727141cc406Sopenharmony_ci s->buffer[2] = 0x03; 2728141cc406Sopenharmony_ci s->buffer[7] = i >> 8; 2729141cc406Sopenharmony_ci s->buffer[8] = i & 0xff; 2730141cc406Sopenharmony_ci 2731141cc406Sopenharmony_ci for (i = 0; i < 256; i++) 2732141cc406Sopenharmony_ci { 2733141cc406Sopenharmony_ci s->buffer[i+11] = a[i&0xff] & 0xff; 2734141cc406Sopenharmony_ci } 2735141cc406Sopenharmony_ci 2736141cc406Sopenharmony_ci for (j = 0; j < 256; j += 16) 2737141cc406Sopenharmony_ci { 2738141cc406Sopenharmony_ci DBG(11, "%02x %02x %02x %02x %02x %02x %02x %02x " 2739141cc406Sopenharmony_ci "%02x %02x %02x %02x %02x %02x %02x %02x\n", 2740141cc406Sopenharmony_ci a[j ], a[j+1], a[j+2], a[j+3], 2741141cc406Sopenharmony_ci a[j+4], a[j+5], a[j+6], a[j+7], 2742141cc406Sopenharmony_ci a[j+8], a[j+9], a[j+10], a[j+11], 2743141cc406Sopenharmony_ci a[j+12], a[j+13], a[j+14], a[j+15]); 2744141cc406Sopenharmony_ci } 2745141cc406Sopenharmony_ci DBG(12, "transfer length = %d\n", i); 2746141cc406Sopenharmony_ci DBG(12, "buffer[7] = %d\n", s->buffer[7]); 2747141cc406Sopenharmony_ci DBG(12, "buffer[8] = %d\n", s->buffer[8]); 2748141cc406Sopenharmony_ci 2749141cc406Sopenharmony_ci /* wait_ready(s->fd); */ 2750141cc406Sopenharmony_ci status = sanei_scsi_cmd (s->fd, s->buffer, i+10, 0, 0); 2751141cc406Sopenharmony_ci 2752141cc406Sopenharmony_ci DBG(11, ">>\n"); 2753141cc406Sopenharmony_ci 2754141cc406Sopenharmony_ci return status; 2755141cc406Sopenharmony_ci} 2756141cc406Sopenharmony_ci 2757141cc406Sopenharmony_ci#ifdef USE_CUSTOM_GAMMA 2758141cc406Sopenharmony_cistatic SANE_Status 2759141cc406Sopenharmony_cisend_binary_gamma_tables (NEC_Scanner *s) 2760141cc406Sopenharmony_ci{ 2761141cc406Sopenharmony_ci SANE_Status status; 2762141cc406Sopenharmony_ci 2763141cc406Sopenharmony_ci status = send_binary_g_table(s, s->val[OPT_GAMMA_VECTOR].wa, 0x10); 2764141cc406Sopenharmony_ci if (status != SANE_STATUS_GOOD) 2765141cc406Sopenharmony_ci return status; 2766141cc406Sopenharmony_ci DBG(11, "send_binary_gamma_tables\n"); 2767141cc406Sopenharmony_ci#if 0 2768141cc406Sopenharmony_ci status = send_binary_g_table(s, s->val[OPT_GAMMA_VECTOR_R].wa, 0x11); 2769141cc406Sopenharmony_ci if (status != SANE_STATUS_GOOD) 2770141cc406Sopenharmony_ci return status; 2771141cc406Sopenharmony_ci 2772141cc406Sopenharmony_ci status = send_binary_g_table(s, s->val[OPT_GAMMA_VECTOR_G].wa, 0x12); 2773141cc406Sopenharmony_ci if (status != SANE_STATUS_GOOD) 2774141cc406Sopenharmony_ci return status; 2775141cc406Sopenharmony_ci 2776141cc406Sopenharmony_ci status = send_binary_g_table(s, s->val[OPT_GAMMA_VECTOR_B].wa, 0x13); 2777141cc406Sopenharmony_ci#endif 2778141cc406Sopenharmony_ci return status; 2779141cc406Sopenharmony_ci} 2780141cc406Sopenharmony_ci 2781141cc406Sopenharmony_cistatic SANE_Status 2782141cc406Sopenharmony_cisend_gamma_tables (NEC_Scanner *s) 2783141cc406Sopenharmony_ci{ 2784141cc406Sopenharmony_ci if (s->dev->sensedat.model == PCIN500) 2785141cc406Sopenharmony_ci { 2786141cc406Sopenharmony_ci return send_binary_gamma_tables(s); 2787141cc406Sopenharmony_ci } 2788141cc406Sopenharmony_ci else 2789141cc406Sopenharmony_ci { 2790141cc406Sopenharmony_ci return send_ascii_gamma_tables(s); 2791141cc406Sopenharmony_ci } 2792141cc406Sopenharmony_ci 2793141cc406Sopenharmony_ci} 2794141cc406Sopenharmony_ci#endif 2795141cc406Sopenharmony_ci 2796141cc406Sopenharmony_ci#ifdef USE_COLOR_THRESHOLD 2797141cc406Sopenharmony_ci/* not used? */ 2798141cc406Sopenharmony_ci#if 0 2799141cc406Sopenharmony_cistatic SANE_Status 2800141cc406Sopenharmony_cisend_threshold_data(NEC_Scanner *s) 2801141cc406Sopenharmony_ci{ 2802141cc406Sopenharmony_ci SANE_Status status; 2803141cc406Sopenharmony_ci SANE_Byte cmd[26] = {SEND, 0, 0x82, 0, 0, 0, 0, 0, 0, 0}; 2804141cc406Sopenharmony_ci int len; 2805141cc406Sopenharmony_ci 2806141cc406Sopenharmony_ci memset(cmd, 0, sizeof(cmd)); 2807141cc406Sopenharmony_ci /* maximum string length: 3 bytes for each number (they are 2808141cc406Sopenharmony_ci restricted to the range 0..255), 3 '/' and the null-byte, 2809141cc406Sopenharmony_ci total: 16 bytes. 2810141cc406Sopenharmony_ci */ 2811141cc406Sopenharmony_ci len = sprintf((char *) &cmd[10], "%i/%i/%i/%i", 2812141cc406Sopenharmony_ci s->val[OPT_THRESHOLD_R].w, 2813141cc406Sopenharmony_ci s->val[OPT_THRESHOLD_G].w, 2814141cc406Sopenharmony_ci s->val[OPT_THRESHOLD_B].w, 2815141cc406Sopenharmony_ci s->val[OPT_THRESHOLD].w); 2816141cc406Sopenharmony_ci cmd[8] = len; 2817141cc406Sopenharmony_ci 2818141cc406Sopenharmony_ci wait_ready(s->fd); 2819141cc406Sopenharmony_ci status = sanei_scsi_cmd(s->fd, cmd, len + 10, 0, 0); 2820141cc406Sopenharmony_ci return status; 2821141cc406Sopenharmony_ci} 2822141cc406Sopenharmony_ci#endif 2823141cc406Sopenharmony_ci#endif 2824141cc406Sopenharmony_ci 2825141cc406Sopenharmony_ciSANE_Status 2826141cc406Sopenharmony_cisane_start (SANE_Handle handle) 2827141cc406Sopenharmony_ci{ 2828141cc406Sopenharmony_ci char *mode, *halftone, *gamma, *edge, *lightcolor, *adf_fsu; 2829141cc406Sopenharmony_ci NEC_Scanner *s = handle; 2830141cc406Sopenharmony_ci SANE_Status status; 2831141cc406Sopenharmony_ci size_t buf_size; 2832141cc406Sopenharmony_ci window_param wp; 2833141cc406Sopenharmony_ci 2834141cc406Sopenharmony_ci DBG (10, "<< sane_start "); 2835141cc406Sopenharmony_ci 2836141cc406Sopenharmony_ci /* First make sure we have a current parameter set. Some of the 2837141cc406Sopenharmony_ci parameters will be overwritten below, but that's OK. */ 2838141cc406Sopenharmony_ci status = sane_get_parameters (s, 0); 2839141cc406Sopenharmony_ci if (status != SANE_STATUS_GOOD) 2840141cc406Sopenharmony_ci return status; 2841141cc406Sopenharmony_ci 2842141cc406Sopenharmony_ci s->dev->sensedat.complain_on_adf_error = 1; 2843141cc406Sopenharmony_ci 2844141cc406Sopenharmony_ci#ifdef HAVE_SANEI_SCSI_OPEN_EXTENDED 2845141cc406Sopenharmony_ci s->dev->info.bufsize = s->dev->info.wanted_bufsize; 2846141cc406Sopenharmony_ci if (s->dev->info.bufsize < 32 * 1024) 2847141cc406Sopenharmony_ci s->dev->info.bufsize = 32 * 1024; 2848141cc406Sopenharmony_ci { 2849141cc406Sopenharmony_ci int bsize = s->dev->info.bufsize; 2850141cc406Sopenharmony_ci status = sanei_scsi_open_extended (s->dev->sane.name, &s->fd, 2851141cc406Sopenharmony_ci &sense_handler, &s->dev->sensedat, &bsize); 2852141cc406Sopenharmony_ci s->dev->info.bufsize = bsize; 2853141cc406Sopenharmony_ci } 2854141cc406Sopenharmony_ci 2855141cc406Sopenharmony_ci if (status != SANE_STATUS_GOOD) 2856141cc406Sopenharmony_ci { 2857141cc406Sopenharmony_ci DBG (1, "open of %s failed: %s\n", 2858141cc406Sopenharmony_ci s->dev->sane.name, sane_strstatus (status)); 2859141cc406Sopenharmony_ci return (status); 2860141cc406Sopenharmony_ci } 2861141cc406Sopenharmony_ci 2862141cc406Sopenharmony_ci /* make sure that we got at least 32 kB. Even then, the scan will be 2863141cc406Sopenharmony_ci awfully slow. 2864141cc406Sopenharmony_ci 2865141cc406Sopenharmony_ci */ 2866141cc406Sopenharmony_ci if (s->dev->info.bufsize < 32 * 1024) 2867141cc406Sopenharmony_ci { 2868141cc406Sopenharmony_ci sanei_scsi_close(s->fd); 2869141cc406Sopenharmony_ci s->fd = -1; 2870141cc406Sopenharmony_ci return SANE_STATUS_NO_MEM; 2871141cc406Sopenharmony_ci } 2872141cc406Sopenharmony_ci#else 2873141cc406Sopenharmony_ci status = sanei_scsi_open(s->dev->sane.name, &s->fd, &sense_handler, 2874141cc406Sopenharmony_ci &s->dev->sensedat); 2875141cc406Sopenharmony_ci if (s->dev->info.wanted_bufsize < sanei_scsi_max_request_size) 2876141cc406Sopenharmony_ci s->dev->info.bufsize = s->dev->info.wanted_bufsize; 2877141cc406Sopenharmony_ci else 2878141cc406Sopenharmony_ci s->dev->info.bufsize = sanei_scsi_max_request_size; 2879141cc406Sopenharmony_ci 2880141cc406Sopenharmony_ci if (status != SANE_STATUS_GOOD) 2881141cc406Sopenharmony_ci { 2882141cc406Sopenharmony_ci DBG (1, "open of %s failed: %s\n", 2883141cc406Sopenharmony_ci s->dev->sane.name, sane_strstatus (status)); 2884141cc406Sopenharmony_ci return (status); 2885141cc406Sopenharmony_ci } 2886141cc406Sopenharmony_ci#endif 2887141cc406Sopenharmony_ci 2888141cc406Sopenharmony_ci s->buffer = malloc(s->dev->info.bufsize); 2889141cc406Sopenharmony_ci if (!s->buffer) { 2890141cc406Sopenharmony_ci sanei_scsi_close(s->fd); 2891141cc406Sopenharmony_ci s->fd = -1; 2892141cc406Sopenharmony_ci free(s); 2893141cc406Sopenharmony_ci return SANE_STATUS_NO_MEM; 2894141cc406Sopenharmony_ci } 2895141cc406Sopenharmony_ci 2896141cc406Sopenharmony_ci#ifdef USE_FORK 2897141cc406Sopenharmony_ci { 2898141cc406Sopenharmony_ci struct shmid_ds ds; 2899141cc406Sopenharmony_ci size_t n; 2900141cc406Sopenharmony_ci 2901141cc406Sopenharmony_ci s->shmid = shmget(IPC_PRIVATE, 2902141cc406Sopenharmony_ci sizeof(NEC_rdr_ctl) 2903141cc406Sopenharmony_ci + s->dev->info.buffers * 2904141cc406Sopenharmony_ci (sizeof(NEC_shmem_ctl) + s->dev->info.bufsize), 2905141cc406Sopenharmony_ci IPC_CREAT | 0600); 2906141cc406Sopenharmony_ci if (s->shmid == -1) 2907141cc406Sopenharmony_ci { 2908141cc406Sopenharmony_ci free(s->buffer); 2909141cc406Sopenharmony_ci s->buffer = 0; 2910141cc406Sopenharmony_ci sanei_scsi_close(s->fd); 2911141cc406Sopenharmony_ci s->fd = -1; 2912141cc406Sopenharmony_ci return SANE_STATUS_NO_MEM; 2913141cc406Sopenharmony_ci } 2914141cc406Sopenharmony_ci s->rdr_ctl = (NEC_rdr_ctl*) shmat(s->shmid, 0, 0); 2915141cc406Sopenharmony_ci if ((int)s->rdr_ctl == -1) 2916141cc406Sopenharmony_ci { 2917141cc406Sopenharmony_ci shmctl(s->shmid, IPC_RMID, &ds); 2918141cc406Sopenharmony_ci free(s->buffer); 2919141cc406Sopenharmony_ci s->buffer = 0; 2920141cc406Sopenharmony_ci sanei_scsi_close(s->fd); 2921141cc406Sopenharmony_ci s->fd = -1; 2922141cc406Sopenharmony_ci return SANE_STATUS_NO_MEM; 2923141cc406Sopenharmony_ci } 2924141cc406Sopenharmony_ci 2925141cc406Sopenharmony_ci s->rdr_ctl->buf_ctl = (NEC_shmem_ctl*) &s->rdr_ctl[1]; 2926141cc406Sopenharmony_ci for (n = 0; n < s->dev->info.buffers; n++) 2927141cc406Sopenharmony_ci { 2928141cc406Sopenharmony_ci s->rdr_ctl->buf_ctl[n].buffer = 2929141cc406Sopenharmony_ci (SANE_Byte*) &s->rdr_ctl->buf_ctl[s->dev->info.buffers] 2930141cc406Sopenharmony_ci + n * s->dev->info.bufsize; 2931141cc406Sopenharmony_ci } 2932141cc406Sopenharmony_ci } 2933141cc406Sopenharmony_ci#endif /* USE_FORK */ 2934141cc406Sopenharmony_ci 2935141cc406Sopenharmony_ci DBG (5, "start: TEST_UNIT_READY\n"); 2936141cc406Sopenharmony_ci status = test_unit_ready (s->fd); 2937141cc406Sopenharmony_ci 2938141cc406Sopenharmony_ci if (status != SANE_STATUS_GOOD) 2939141cc406Sopenharmony_ci { 2940141cc406Sopenharmony_ci DBG (1, "TEST UNIT READY failed: %s\n", sane_strstatus (status)); 2941141cc406Sopenharmony_ci sanei_scsi_close (s->fd); 2942141cc406Sopenharmony_ci s->fd = -1; 2943141cc406Sopenharmony_ci return (status); 2944141cc406Sopenharmony_ci } 2945141cc406Sopenharmony_ci 2946141cc406Sopenharmony_ci DBG (3, "start: sending MODE SELECT\n"); 2947141cc406Sopenharmony_ci status = mode_select_mud (s->fd, s->dev->info.mud); 2948141cc406Sopenharmony_ci if (status != SANE_STATUS_GOOD) 2949141cc406Sopenharmony_ci { 2950141cc406Sopenharmony_ci DBG (1, "start: MODE_SELECT6 failed\n"); 2951141cc406Sopenharmony_ci sanei_scsi_close (s->fd); 2952141cc406Sopenharmony_ci s->fd = -1; 2953141cc406Sopenharmony_ci return (status); 2954141cc406Sopenharmony_ci } 2955141cc406Sopenharmony_ci 2956141cc406Sopenharmony_ci mode = s->val[OPT_MODE].s; 2957141cc406Sopenharmony_ci halftone = s->val[OPT_HALFTONE].s; 2958141cc406Sopenharmony_ci gamma = s->val[OPT_GAMMA].s; 2959141cc406Sopenharmony_ci edge = s->val[OPT_EDGE_EMPHASIS].s; 2960141cc406Sopenharmony_ci lightcolor = s->val[OPT_LIGHTCOLOR].s; 2961141cc406Sopenharmony_ci adf_fsu = s->val[OPT_SCANSOURCE].s; 2962141cc406Sopenharmony_ci 2963141cc406Sopenharmony_ci if (s->val[OPT_PREVIEW].w == SANE_FALSE) 2964141cc406Sopenharmony_ci { 2965141cc406Sopenharmony_ci s->res = s->val[OPT_RESOLUTION].w * s->dev->info.res_range.quant; 2966141cc406Sopenharmony_ci } 2967141cc406Sopenharmony_ci else 2968141cc406Sopenharmony_ci { 2969141cc406Sopenharmony_ci s->res = 75; 2970141cc406Sopenharmony_ci } 2971141cc406Sopenharmony_ci s->ulx = MM_TO_PIX(SANE_UNFIX(s->val[OPT_TL_X].w), s->dev->info.mud); 2972141cc406Sopenharmony_ci s->uly = MM_TO_PIX(SANE_UNFIX(s->val[OPT_TL_Y].w), s->dev->info.mud); 2973141cc406Sopenharmony_ci s->threshold = s->val[OPT_THRESHOLD].w; 2974141cc406Sopenharmony_ci 2975141cc406Sopenharmony_ci if (strcmp (mode, M_LINEART_COLOR) == 0) 2976141cc406Sopenharmony_ci s->bpp = 1; 2977141cc406Sopenharmony_ci else 2978141cc406Sopenharmony_ci s->bpp = s->params.depth; 2979141cc406Sopenharmony_ci 2980141cc406Sopenharmony_ci s->adf_fsu_mode = SCAN_SIMPLE; /* default: scan without ADF and FSU */ 2981141cc406Sopenharmony_ci 2982141cc406Sopenharmony_ci if (strcmp(adf_fsu, use_fsu) == 0) 2983141cc406Sopenharmony_ci s->adf_fsu_mode = SCAN_WITH_FSU; 2984141cc406Sopenharmony_ci else if (strcmp(adf_fsu, use_adf) == 0) 2985141cc406Sopenharmony_ci s->adf_fsu_mode = SCAN_WITH_ADF; 2986141cc406Sopenharmony_ci else if (strcmp(adf_fsu, use_adf) == 0) 2987141cc406Sopenharmony_ci s->adf_fsu_mode = SCAN_SIMPLE; 2988141cc406Sopenharmony_ci 2989141cc406Sopenharmony_ci /* halftone must not set to be zero PC-IN500 */ 2990141cc406Sopenharmony_ci s->halftone = 0x01; 2991141cc406Sopenharmony_ci if (strcmp (mode, M_LINEART) == 0) 2992141cc406Sopenharmony_ci { 2993141cc406Sopenharmony_ci s->reverse = 0; 2994141cc406Sopenharmony_ci s->image_composition = 1; 2995141cc406Sopenharmony_ci if (strcmp(halftone, M_BILEVEL) == 0) 2996141cc406Sopenharmony_ci { 2997141cc406Sopenharmony_ci s->image_composition = 0; 2998141cc406Sopenharmony_ci s->halftone = 0x01; 2999141cc406Sopenharmony_ci } 3000141cc406Sopenharmony_ci else if (strcmp(halftone, M_DITHER1) == 0) 3001141cc406Sopenharmony_ci s->halftone = 0x01; 3002141cc406Sopenharmony_ci else if (strcmp(halftone, M_DITHER2) == 0) 3003141cc406Sopenharmony_ci s->halftone = 0x10; 3004141cc406Sopenharmony_ci else if (strcmp(halftone, M_DITHER3) == 0) 3005141cc406Sopenharmony_ci s->halftone = 0x20; 3006141cc406Sopenharmony_ci } 3007141cc406Sopenharmony_ci else if (strcmp (mode, M_GRAY) == 0) 3008141cc406Sopenharmony_ci { 3009141cc406Sopenharmony_ci s->image_composition = 2; 3010141cc406Sopenharmony_ci s->reverse = 1; 3011141cc406Sopenharmony_ci } 3012141cc406Sopenharmony_ci else if (strcmp (mode, M_LINEART_COLOR) == 0) 3013141cc406Sopenharmony_ci { 3014141cc406Sopenharmony_ci s->reverse = 1; 3015141cc406Sopenharmony_ci s->image_composition = 4; 3016141cc406Sopenharmony_ci if (strcmp(halftone, M_BILEVEL) == 0) 3017141cc406Sopenharmony_ci { 3018141cc406Sopenharmony_ci s->image_composition = 3; 3019141cc406Sopenharmony_ci s->halftone = 0x01; 3020141cc406Sopenharmony_ci } 3021141cc406Sopenharmony_ci else if (strcmp(halftone, M_DITHER1) == 0) 3022141cc406Sopenharmony_ci s->halftone = 0x01; 3023141cc406Sopenharmony_ci else if (strcmp(halftone, M_DITHER2) == 0) 3024141cc406Sopenharmony_ci s->halftone = 0x10; 3025141cc406Sopenharmony_ci else if (strcmp(halftone, M_DITHER3) == 0) 3026141cc406Sopenharmony_ci s->halftone = 0x20; 3027141cc406Sopenharmony_ci } 3028141cc406Sopenharmony_ci else if (strcmp (mode, M_COLOR) == 0) 3029141cc406Sopenharmony_ci { 3030141cc406Sopenharmony_ci s->image_composition = 5; 3031141cc406Sopenharmony_ci s->reverse = 1; 3032141cc406Sopenharmony_ci } 3033141cc406Sopenharmony_ci 3034141cc406Sopenharmony_ci if (s->dev->sensedat.model == PCIN500) 3035141cc406Sopenharmony_ci { 3036141cc406Sopenharmony_ci s->or = s->val[OPT_OR].w; 3037141cc406Sopenharmony_ci s->nr = s->val[OPT_NR].w; 3038141cc406Sopenharmony_ci s->edge = s->val[OPT_EDGE].w; 3039141cc406Sopenharmony_ci } 3040141cc406Sopenharmony_ci else 3041141cc406Sopenharmony_ci { 3042141cc406Sopenharmony_ci if (strcmp (edge, EDGE_NONE) == 0) 3043141cc406Sopenharmony_ci s->edge = 0; 3044141cc406Sopenharmony_ci else if (strcmp (edge, EDGE_MIDDLE) == 0) 3045141cc406Sopenharmony_ci s->edge = 1; 3046141cc406Sopenharmony_ci else if (strcmp (edge, EDGE_STRONG) == 0) 3047141cc406Sopenharmony_ci s->edge = 2; 3048141cc406Sopenharmony_ci else if (strcmp (edge, EDGE_BLUR) == 0) 3049141cc406Sopenharmony_ci s->edge = 3; 3050141cc406Sopenharmony_ci } 3051141cc406Sopenharmony_ci 3052141cc406Sopenharmony_ci s->lightcolor = 3; 3053141cc406Sopenharmony_ci if (strcmp(lightcolor, LIGHT_GREEN) == 0) 3054141cc406Sopenharmony_ci s->lightcolor = 0; 3055141cc406Sopenharmony_ci else if (strcmp(lightcolor, LIGHT_RED) == 0) 3056141cc406Sopenharmony_ci s->lightcolor = 1; 3057141cc406Sopenharmony_ci else if (strcmp(lightcolor, LIGHT_BLUE) == 0) 3058141cc406Sopenharmony_ci s->lightcolor = 2; 3059141cc406Sopenharmony_ci else if (strcmp(lightcolor, LIGHT_NONE) == 0) 3060141cc406Sopenharmony_ci s->lightcolor = 3; 3061141cc406Sopenharmony_ci 3062141cc406Sopenharmony_ci s->adf_scan = 0; 3063141cc406Sopenharmony_ci 3064141cc406Sopenharmony_ci#ifdef USE_CUSTOM_GAMMA 3065141cc406Sopenharmony_ci if (s->val[OPT_CUSTOM_GAMMA].w == SANE_FALSE) 3066141cc406Sopenharmony_ci { 3067141cc406Sopenharmony_ci#endif 3068141cc406Sopenharmony_ci if (s->dev->sensedat.model == PCIN500) 3069141cc406Sopenharmony_ci { 3070141cc406Sopenharmony_ci if (strcmp (gamma, CRT1)) 3071141cc406Sopenharmony_ci s->gamma = 1; 3072141cc406Sopenharmony_ci else if (strcmp (gamma, CRT2)) 3073141cc406Sopenharmony_ci s->gamma = 2; 3074141cc406Sopenharmony_ci else if (strcmp (gamma, PRINTER1)) 3075141cc406Sopenharmony_ci s->gamma = 3; 3076141cc406Sopenharmony_ci else if (strcmp (gamma, PRINTER2)) 3077141cc406Sopenharmony_ci s->gamma = 4; 3078141cc406Sopenharmony_ci else if (strcmp (gamma, NONE)) 3079141cc406Sopenharmony_ci s->gamma = 5; 3080141cc406Sopenharmony_ci } 3081141cc406Sopenharmony_ci#if 0 3082141cc406Sopenharmony_ci if (s->dev->sensedat.model != PCIN500) 3083141cc406Sopenharmony_ci { 3084141cc406Sopenharmony_ci ss.dtc = 0x03; 3085141cc406Sopenharmony_ci if (strcmp (gamma, GAMMA10) == 0) 3086141cc406Sopenharmony_ci ss.dtq = 0x01; 3087141cc406Sopenharmony_ci else 3088141cc406Sopenharmony_ci ss.dtq = 0x02; 3089141cc406Sopenharmony_ci ss.length = 0; 3090141cc406Sopenharmony_ci DBG (5, "start: SEND\n"); 3091141cc406Sopenharmony_ci status = send (s->fd, &ss); 3092141cc406Sopenharmony_ci if (status != SANE_STATUS_GOOD) 3093141cc406Sopenharmony_ci { 3094141cc406Sopenharmony_ci DBG (1, "send failed: %s\n", sane_strstatus (status)); 3095141cc406Sopenharmony_ci sanei_scsi_close (s->fd); 3096141cc406Sopenharmony_ci s->fd = -1; 3097141cc406Sopenharmony_ci return (status); 3098141cc406Sopenharmony_ci } 3099141cc406Sopenharmony_ci } 3100141cc406Sopenharmony_ci else 3101141cc406Sopenharmony_ci#else 3102141cc406Sopenharmony_ci { 3103141cc406Sopenharmony_ci int i; 3104141cc406Sopenharmony_ci SANE_Word gtbl[256]; 3105141cc406Sopenharmony_ci#if 0 3106141cc406Sopenharmony_ci if (strcmp (gamma, GAMMA10) == 0) 3107141cc406Sopenharmony_ci for (i = 0; i < 256; i++) 3108141cc406Sopenharmony_ci gtbl[i] = i; 3109141cc406Sopenharmony_ci else 3110141cc406Sopenharmony_ci#endif 3111141cc406Sopenharmony_ci { 3112141cc406Sopenharmony_ci gtbl[0] = 0; 3113141cc406Sopenharmony_ci for (i = 1; i < 256; i++) 3114141cc406Sopenharmony_ci gtbl[i] = 255 * exp(0.45 * log(i/255.0)); 3115141cc406Sopenharmony_ci } 3116141cc406Sopenharmony_ci send_binary_g_table(s, gtbl, 0x10); 3117141cc406Sopenharmony_ci send_binary_g_table(s, gtbl, 0x11); 3118141cc406Sopenharmony_ci send_binary_g_table(s, gtbl, 0x12); 3119141cc406Sopenharmony_ci send_binary_g_table(s, gtbl, 0x13); 3120141cc406Sopenharmony_ci } 3121141cc406Sopenharmony_ci#endif /* DEBUG_NEC */ 3122141cc406Sopenharmony_ci#ifdef USE_CUSTOM_GAMMA 3123141cc406Sopenharmony_ci } 3124141cc406Sopenharmony_ci else 3125141cc406Sopenharmony_ci { 3126141cc406Sopenharmony_ci s->gamma = 9; 3127141cc406Sopenharmony_ci status = send_gamma_tables(s); 3128141cc406Sopenharmony_ci } 3129141cc406Sopenharmony_ci if (status != SANE_STATUS_GOOD) 3130141cc406Sopenharmony_ci { 3131141cc406Sopenharmony_ci sanei_scsi_close (s->fd); 3132141cc406Sopenharmony_ci s->fd = -1; 3133141cc406Sopenharmony_ci return (status); 3134141cc406Sopenharmony_ci } 3135141cc406Sopenharmony_ci#endif 3136141cc406Sopenharmony_ci 3137141cc406Sopenharmony_ci s->tint = s->val[OPT_TINT].w; 3138141cc406Sopenharmony_ci s->color = s->val[OPT_COLOR].w; 3139141cc406Sopenharmony_ci 3140141cc406Sopenharmony_ci memset (&wp, 0, sizeof (wp)); 3141141cc406Sopenharmony_ci /* every NEC scanner seems to have a different 3142141cc406Sopenharmony_ci window descriptor block... 3143141cc406Sopenharmony_ci */ 3144141cc406Sopenharmony_ci if (s->dev->sensedat.model == PCIN500) 3145141cc406Sopenharmony_ci buf_size = sizeof(WDB) + sizeof(WDBX500); 3146141cc406Sopenharmony_ci else 3147141cc406Sopenharmony_ci buf_size = sizeof(WDB); 3148141cc406Sopenharmony_ci 3149141cc406Sopenharmony_ci wp.wpdh.wdl[0] = buf_size >> 8; 3150141cc406Sopenharmony_ci wp.wpdh.wdl[1] = buf_size; 3151141cc406Sopenharmony_ci wp.wdb.x_res[0] = s->res >> 8; 3152141cc406Sopenharmony_ci wp.wdb.x_res[1] = s->res; 3153141cc406Sopenharmony_ci wp.wdb.y_res[0] = s->res >> 8; 3154141cc406Sopenharmony_ci wp.wdb.y_res[1] = s->res; 3155141cc406Sopenharmony_ci wp.wdb.x_ul[0] = s->ulx >> 24; 3156141cc406Sopenharmony_ci wp.wdb.x_ul[1] = s->ulx >> 16; 3157141cc406Sopenharmony_ci wp.wdb.x_ul[2] = s->ulx >> 8; 3158141cc406Sopenharmony_ci wp.wdb.x_ul[3] = s->ulx; 3159141cc406Sopenharmony_ci wp.wdb.y_ul[0] = s->uly >> 24; 3160141cc406Sopenharmony_ci wp.wdb.y_ul[1] = s->uly >> 16; 3161141cc406Sopenharmony_ci wp.wdb.y_ul[2] = s->uly >> 8; 3162141cc406Sopenharmony_ci wp.wdb.y_ul[3] = s->uly; 3163141cc406Sopenharmony_ci wp.wdb.width[0] = s->width >> 24; 3164141cc406Sopenharmony_ci wp.wdb.width[1] = s->width >> 16; 3165141cc406Sopenharmony_ci wp.wdb.width[2] = s->width >> 8; 3166141cc406Sopenharmony_ci wp.wdb.width[3] = s->width; 3167141cc406Sopenharmony_ci wp.wdb.length[0] = s->length >> 24; 3168141cc406Sopenharmony_ci wp.wdb.length[1] = s->length >> 16; 3169141cc406Sopenharmony_ci wp.wdb.length[2] = s->length >> 8; 3170141cc406Sopenharmony_ci wp.wdb.length[3] = s->length; 3171141cc406Sopenharmony_ci wp.wdb.brightness = 0; 3172141cc406Sopenharmony_ci wp.wdb.threshold = s->threshold; 3173141cc406Sopenharmony_ci wp.wdb.brightness = 128; 3174141cc406Sopenharmony_ci wp.wdb.contrast = 128; 3175141cc406Sopenharmony_ci wp.wdb.image_composition = s->image_composition; 3176141cc406Sopenharmony_ci if (s->image_composition <= 2 || s->image_composition >= 5) 3177141cc406Sopenharmony_ci wp.wdb.bpp = s->bpp; 3178141cc406Sopenharmony_ci else 3179141cc406Sopenharmony_ci wp.wdb.bpp = 1; 3180141cc406Sopenharmony_ci wp.wdb.ht_pattern[0] = 0; 3181141cc406Sopenharmony_ci wp.wdb.ht_pattern[1] = 0; 3182141cc406Sopenharmony_ci if (s->dev->sensedat.model == PCIN500) 3183141cc406Sopenharmony_ci wp.wdb.ht_pattern[1] = s->halftone; 3184141cc406Sopenharmony_ci wp.wdb.rif_padding = (s->reverse * 128) + 0; 3185141cc406Sopenharmony_ci 3186141cc406Sopenharmony_ci if (s->dev->sensedat.model == PCIN500) 3187141cc406Sopenharmony_ci { 3188141cc406Sopenharmony_ci wp.wdbx500.data_length = 0x07; 3189141cc406Sopenharmony_ci wp.wdbx500.control = 0 | (s->or << 7) | (s->edge << 6) | (s->nr << 5) | 3190141cc406Sopenharmony_ci (s->lightcolor << 2); 3191141cc406Sopenharmony_ci wp.wdbx500.format = 0; 3192141cc406Sopenharmony_ci wp.wdbx500.gamma = s->gamma; 3193141cc406Sopenharmony_ci wp.wdbx500.tint = s->tint; 3194141cc406Sopenharmony_ci wp.wdbx500.color = s->color; 3195141cc406Sopenharmony_ci wp.wdbx500.reserved1 = 0; 3196141cc406Sopenharmony_ci wp.wdbx500.reserved2 = 0; 3197141cc406Sopenharmony_ci } 3198141cc406Sopenharmony_ci 3199141cc406Sopenharmony_ci DBG (5, "wdl=%d\n", (wp.wpdh.wdl[0] << 8) + wp.wpdh.wdl[1]); 3200141cc406Sopenharmony_ci DBG (5, "xres=%d\n", (wp.wdb.x_res[0] << 8) + wp.wdb.x_res[1]); 3201141cc406Sopenharmony_ci DBG (5, "yres=%d\n", (wp.wdb.y_res[0] << 8) + wp.wdb.y_res[1]); 3202141cc406Sopenharmony_ci DBG (5, "ulx=%d\n", (wp.wdb.x_ul[0] << 24) + (wp.wdb.x_ul[1] << 16) + 3203141cc406Sopenharmony_ci (wp.wdb.x_ul[2] << 8) + wp.wdb.x_ul[3]); 3204141cc406Sopenharmony_ci DBG (5, "uly=%d\n", (wp.wdb.y_ul[0] << 24) + (wp.wdb.y_ul[1] << 16) + 3205141cc406Sopenharmony_ci (wp.wdb.y_ul[2] << 8) + wp.wdb.y_ul[3]); 3206141cc406Sopenharmony_ci DBG (5, "width=%d\n", (wp.wdb.width[0] << 8) + (wp.wdb.width[1] << 16) + 3207141cc406Sopenharmony_ci (wp.wdb.width[2] << 8) + wp.wdb.width[3]); 3208141cc406Sopenharmony_ci DBG (5, "length=%d\n", (wp.wdb.length[0] << 16) + (wp.wdb.length[1] << 16) + 3209141cc406Sopenharmony_ci (wp.wdb.length[2] << 8) + wp.wdb.length[3]); 3210141cc406Sopenharmony_ci 3211141cc406Sopenharmony_ci DBG (5, "threshold=%d\n", wp.wdb.threshold); 3212141cc406Sopenharmony_ci DBG (5, "image_composition=%d\n", wp.wdb.image_composition); 3213141cc406Sopenharmony_ci DBG (5, "bpp=%d\n", wp.wdb.bpp); 3214141cc406Sopenharmony_ci DBG (5, "rif_padding=%d\n", wp.wdb.rif_padding); 3215141cc406Sopenharmony_ci 3216141cc406Sopenharmony_ci#ifdef DEBUG_NEC 3217141cc406Sopenharmony_ci { 3218141cc406Sopenharmony_ci window_param foo; 3219141cc406Sopenharmony_ci size_t len = buf_size; 3220141cc406Sopenharmony_ci len += sizeof(WPDH); 3221141cc406Sopenharmony_ci DBG (5, "start: GET WINDOW\n"); 3222141cc406Sopenharmony_ci status = get_window (s->fd, &foo, &len); 3223141cc406Sopenharmony_ci if (status != SANE_STATUS_GOOD) 3224141cc406Sopenharmony_ci { 3225141cc406Sopenharmony_ci DBG (1, "GET WINDOW failed: %s\n", sane_strstatus (status)); 3226141cc406Sopenharmony_ci sanei_scsi_close (s->fd); 3227141cc406Sopenharmony_ci s->fd = -1; 3228141cc406Sopenharmony_ci return (status); 3229141cc406Sopenharmony_ci } 3230141cc406Sopenharmony_ci#if 1 3231141cc406Sopenharmony_ci { 3232141cc406Sopenharmony_ci unsigned char *p = (unsigned char*) &foo; 3233141cc406Sopenharmony_ci int i; 3234141cc406Sopenharmony_ci DBG(11, "get window(debug):\n"); 3235141cc406Sopenharmony_ci for (i = 0; i < len; i += 16) 3236141cc406Sopenharmony_ci { 3237141cc406Sopenharmony_ci DBG(1, "%2x %2x %2x %2x %2x %2x %2x %2x - %2x %2x %2x %2x %2x %2x %2x %2x\n", 3238141cc406Sopenharmony_ci p[i], p[i+1], p[i+2], p[i+3], p[i+4], p[i+5], p[i+6], p[i+7], p[i+8], 3239141cc406Sopenharmony_ci p[i+9], p[i+10], p[i+11], p[i+12], p[i+13], p[i+14], p[i+15]); 3240141cc406Sopenharmony_ci } 3241141cc406Sopenharmony_ci } 3242141cc406Sopenharmony_ci#endif 3243141cc406Sopenharmony_ci foo.wpdh.wpdh[1] = 0; 3244141cc406Sopenharmony_ci status = set_window (s->fd, &foo, len); 3245141cc406Sopenharmony_ci if (status != SANE_STATUS_GOOD) 3246141cc406Sopenharmony_ci { 3247141cc406Sopenharmony_ci DBG (1, "SET WINDOW failed: %s\n", sane_strstatus (status)); 3248141cc406Sopenharmony_ci sanei_scsi_close (s->fd); 3249141cc406Sopenharmony_ci s->fd = -1; 3250141cc406Sopenharmony_ci return (status); 3251141cc406Sopenharmony_ci } 3252141cc406Sopenharmony_ci#if 1 3253141cc406Sopenharmony_ci { 3254141cc406Sopenharmony_ci unsigned char *p = (unsigned char*) &foo; 3255141cc406Sopenharmony_ci int i; 3256141cc406Sopenharmony_ci DBG(11, "set window(debug):\n"); 3257141cc406Sopenharmony_ci for (i = 0; i < len; i += 16) 3258141cc406Sopenharmony_ci { 3259141cc406Sopenharmony_ci DBG(1, "%2x %2x %2x %2x %2x %2x %2x %2x - %2x %2x %2x %2x %2x %2x %2x %2x\n", 3260141cc406Sopenharmony_ci p[i], p[i+1], p[i+2], p[i+3], p[i+4], p[i+5], p[i+6], p[i+7], p[i+8], 3261141cc406Sopenharmony_ci p[i+9], p[i+10], p[i+11], p[i+12], p[i+13], p[i+14], p[i+15]); 3262141cc406Sopenharmony_ci } 3263141cc406Sopenharmony_ci } 3264141cc406Sopenharmony_ci#endif 3265141cc406Sopenharmony_ci } 3266141cc406Sopenharmony_ci#endif /* debug_nec */ 3267141cc406Sopenharmony_ci 3268141cc406Sopenharmony_ci#ifdef DEBUG_NEC 3269141cc406Sopenharmony_ci { 3270141cc406Sopenharmony_ci unsigned char *p = (unsigned char*) ℘ 3271141cc406Sopenharmony_ci int i; 3272141cc406Sopenharmony_ci DBG(11, "set window(debug):\n"); 3273141cc406Sopenharmony_ci for (i = 0; i < sizeof(wp.wdb) + sizeof(wp.wdbx500); i += 16) 3274141cc406Sopenharmony_ci { 3275141cc406Sopenharmony_ci DBG(1, "%2x %2x %2x %2x %2x %2x %2x %2x - %2x %2x %2x %2x %2x %2x %2x %2x\n", 3276141cc406Sopenharmony_ci p[i], p[i+1], p[i+2], p[i+3], p[i+4], p[i+5], p[i+6], p[i+7], p[i+8], 3277141cc406Sopenharmony_ci p[i+9], p[i+10], p[i+11], p[i+12], p[i+13], p[i+14], p[i+15]); 3278141cc406Sopenharmony_ci } 3279141cc406Sopenharmony_ci } 3280141cc406Sopenharmony_ci#endif /* debug_nec */ 3281141cc406Sopenharmony_ci 3282141cc406Sopenharmony_ci buf_size += sizeof(WPDH); 3283141cc406Sopenharmony_ci DBG (5, "start: SET WINDOW\n"); 3284141cc406Sopenharmony_ci status = set_window (s->fd, &wp, buf_size); 3285141cc406Sopenharmony_ci if (status != SANE_STATUS_GOOD) 3286141cc406Sopenharmony_ci { 3287141cc406Sopenharmony_ci DBG (1, "SET WINDOW failed: %s\n", sane_strstatus (status)); 3288141cc406Sopenharmony_ci sanei_scsi_close (s->fd); 3289141cc406Sopenharmony_ci s->fd = -1; 3290141cc406Sopenharmony_ci return (status); 3291141cc406Sopenharmony_ci } 3292141cc406Sopenharmony_ci 3293141cc406Sopenharmony_ci memset (&wp, 0, buf_size); 3294141cc406Sopenharmony_ci DBG (5, "start: GET WINDOW\n"); 3295141cc406Sopenharmony_ci status = get_window (s->fd, &wp, &buf_size); 3296141cc406Sopenharmony_ci if (status != SANE_STATUS_GOOD) 3297141cc406Sopenharmony_ci { 3298141cc406Sopenharmony_ci DBG (1, "GET WINDOW failed: %s\n", sane_strstatus (status)); 3299141cc406Sopenharmony_ci sanei_scsi_close (s->fd); 3300141cc406Sopenharmony_ci s->fd = -1; 3301141cc406Sopenharmony_ci return (status); 3302141cc406Sopenharmony_ci } 3303141cc406Sopenharmony_ci#ifdef DEBUG_NEC 3304141cc406Sopenharmony_ci { 3305141cc406Sopenharmony_ci unsigned char *p = (unsigned char*) ℘ 3306141cc406Sopenharmony_ci int i; 3307141cc406Sopenharmony_ci DBG(11, "get window(debug):\n"); 3308141cc406Sopenharmony_ci for (i = 0; i < buf_size; i += 16) 3309141cc406Sopenharmony_ci { 3310141cc406Sopenharmony_ci DBG(1, "%2x %2x %2x %2x %2x %2x %2x %2x - %2x %2x %2x %2x %2x %2x %2x %2x\n", 3311141cc406Sopenharmony_ci p[i], p[i+1], p[i+2], p[i+3], p[i+4], p[i+5], p[i+6], p[i+7], p[i+8], 3312141cc406Sopenharmony_ci p[i+9], p[i+10], p[i+11], p[i+12], p[i+13], p[i+14], p[i+15]); 3313141cc406Sopenharmony_ci } 3314141cc406Sopenharmony_ci } 3315141cc406Sopenharmony_ci#endif 3316141cc406Sopenharmony_ci DBG (5, "xres=%d\n", (wp.wdb.x_res[0] << 8) + wp.wdb.x_res[1]); 3317141cc406Sopenharmony_ci DBG (5, "yres=%d\n", (wp.wdb.y_res[0] << 8) + wp.wdb.y_res[1]); 3318141cc406Sopenharmony_ci DBG (5, "ulx=%d\n", (wp.wdb.x_ul[0] << 24) + (wp.wdb.x_ul[1] << 16) + 3319141cc406Sopenharmony_ci (wp.wdb.x_ul[2] << 8) + wp.wdb.x_ul[3]); 3320141cc406Sopenharmony_ci DBG (5, "uly=%d\n", (wp.wdb.y_ul[0] << 24) + (wp.wdb.y_ul[1] << 16) + 3321141cc406Sopenharmony_ci (wp.wdb.y_ul[2] << 8) + wp.wdb.y_ul[3]); 3322141cc406Sopenharmony_ci DBG (5, "width=%d\n", (wp.wdb.width[0] << 24) + (wp.wdb.width[1] << 16) + 3323141cc406Sopenharmony_ci (wp.wdb.width[2] << 8) + wp.wdb.width[3]); 3324141cc406Sopenharmony_ci DBG (5, "length=%d\n", (wp.wdb.length[0] << 24) + (wp.wdb.length[1] << 16) + 3325141cc406Sopenharmony_ci (wp.wdb.length[2] << 8) + wp.wdb.length[3]); 3326141cc406Sopenharmony_ci DBG (5, "start: SCAN\n"); 3327141cc406Sopenharmony_ci s->scanning = SANE_TRUE; 3328141cc406Sopenharmony_ci s->busy = SANE_TRUE; 3329141cc406Sopenharmony_ci s->cancel = SANE_FALSE; 3330141cc406Sopenharmony_ci s->get_params_called = 0; 3331141cc406Sopenharmony_ci 3332141cc406Sopenharmony_ci status = scan (s->fd); 3333141cc406Sopenharmony_ci#ifdef DEBUG 3334141cc406Sopenharmony_ci { 3335141cc406Sopenharmony_ci struct timeval t; 3336141cc406Sopenharmony_ci gettimeofday(&t, 0); 3337141cc406Sopenharmony_ci DBG(2, "rd: scan started %li.%06li\n", t.tv_sec, t.tv_usec); 3338141cc406Sopenharmony_ci } 3339141cc406Sopenharmony_ci#endif 3340141cc406Sopenharmony_ci if (status != SANE_STATUS_GOOD) 3341141cc406Sopenharmony_ci { 3342141cc406Sopenharmony_ci DBG (1, "start of scan failed: %s\n", sane_strstatus (status)); 3343141cc406Sopenharmony_ci sanei_scsi_close (s->fd); 3344141cc406Sopenharmony_ci s->fd = -1; 3345141cc406Sopenharmony_ci s->busy = SANE_FALSE; 3346141cc406Sopenharmony_ci s->cancel = SANE_FALSE; 3347141cc406Sopenharmony_ci return (status); 3348141cc406Sopenharmony_ci } 3349141cc406Sopenharmony_ci 3350141cc406Sopenharmony_ci /* ask the scanner for the scan size */ 3351141cc406Sopenharmony_ci /* wait_ready(s->fd); */ 3352141cc406Sopenharmony_ci#ifdef DEBUG 3353141cc406Sopenharmony_ci { 3354141cc406Sopenharmony_ci struct timeval t; 3355141cc406Sopenharmony_ci gettimeofday(&t, 0); 3356141cc406Sopenharmony_ci DBG(2, "rd: wait_ready ok %li.%06li\n", t.tv_sec, t.tv_usec); 3357141cc406Sopenharmony_ci } 3358141cc406Sopenharmony_ci#endif 3359141cc406Sopenharmony_ci sane_get_parameters(s, 0); 3360141cc406Sopenharmony_ci#ifdef DEBUG 3361141cc406Sopenharmony_ci { 3362141cc406Sopenharmony_ci struct timeval t; 3363141cc406Sopenharmony_ci gettimeofday(&t, 0); 3364141cc406Sopenharmony_ci DBG(2, "rd: get_params ok %li.%06li\n", t.tv_sec, t.tv_usec); 3365141cc406Sopenharmony_ci } 3366141cc406Sopenharmony_ci#endif 3367141cc406Sopenharmony_ci if (strcmp (mode, M_LINEART_COLOR) != 0) 3368141cc406Sopenharmony_ci s->bytes_to_read = s->params.bytes_per_line * s->params.lines; 3369141cc406Sopenharmony_ci else 3370141cc406Sopenharmony_ci { 3371141cc406Sopenharmony_ci s->bytes_to_read = s->params.bytes_per_line * s->params.lines; 3372141cc406Sopenharmony_ci } 3373141cc406Sopenharmony_ci 3374141cc406Sopenharmony_ci#ifdef USE_FORK 3375141cc406Sopenharmony_ci { 3376141cc406Sopenharmony_ci size_t i; 3377141cc406Sopenharmony_ci for (i = 0; i < s->dev->info.buffers; i++) 3378141cc406Sopenharmony_ci s->rdr_ctl->buf_ctl[i].shm_status = SHM_EMPTY; 3379141cc406Sopenharmony_ci s->read_buff = 0; 3380141cc406Sopenharmony_ci s->rdr_ctl->cancel = 0; 3381141cc406Sopenharmony_ci s->rdr_ctl->running = 0; 3382141cc406Sopenharmony_ci s->rdr_ctl->status = SANE_STATUS_GOOD; 3383141cc406Sopenharmony_ci } 3384141cc406Sopenharmony_ci s->reader_pid = fork(); 3385141cc406Sopenharmony_ci#ifdef DEBUG 3386141cc406Sopenharmony_ci { 3387141cc406Sopenharmony_ci struct timeval t; 3388141cc406Sopenharmony_ci gettimeofday(&t, 0); 3389141cc406Sopenharmony_ci DBG(2, "rd: forked %li.%06li %i\n", t.tv_sec, t.tv_usec, 3390141cc406Sopenharmony_ci s->reader_pid); 3391141cc406Sopenharmony_ci } 3392141cc406Sopenharmony_ci#endif 3393141cc406Sopenharmony_ci if (s->reader_pid == 0) 3394141cc406Sopenharmony_ci { 3395141cc406Sopenharmony_ci sigset_t ignore_set; 3396141cc406Sopenharmony_ci struct SIGACTION act; 3397141cc406Sopenharmony_ci 3398141cc406Sopenharmony_ci sigfillset (&ignore_set); 3399141cc406Sopenharmony_ci sigdelset (&ignore_set, SIGTERM); 3400141cc406Sopenharmony_ci sigprocmask (SIG_SETMASK, &ignore_set, 0); 3401141cc406Sopenharmony_ci 3402141cc406Sopenharmony_ci memset (&act, 0, sizeof (act)); 3403141cc406Sopenharmony_ci sigaction (SIGTERM, &act, 0); 3404141cc406Sopenharmony_ci 3405141cc406Sopenharmony_ci /* don't use exit() since that would run the atexit() handlers... */ 3406141cc406Sopenharmony_ci _exit (reader_process (s)); 3407141cc406Sopenharmony_ci } 3408141cc406Sopenharmony_ci else if (s->reader_pid == -1) 3409141cc406Sopenharmony_ci { 3410141cc406Sopenharmony_ci s->busy = SANE_FALSE; 3411141cc406Sopenharmony_ci do_cancel(s); 3412141cc406Sopenharmony_ci return SANE_STATUS_NO_MEM; 3413141cc406Sopenharmony_ci } 3414141cc406Sopenharmony_ci 3415141cc406Sopenharmony_ci#endif /* USE_FORK */ 3416141cc406Sopenharmony_ci 3417141cc406Sopenharmony_ci 3418141cc406Sopenharmony_ci DBG (1, "%d pixels per line, %d bytes, %d lines high, total %lu bytes, " 3419141cc406Sopenharmony_ci "dpi=%d\n", s->params.pixels_per_line, s->params.bytes_per_line, 3420141cc406Sopenharmony_ci s->params.lines, (u_long) s->bytes_to_read, s->val[OPT_RESOLUTION].w); 3421141cc406Sopenharmony_ci 3422141cc406Sopenharmony_ci s->busy = SANE_FALSE; 3423141cc406Sopenharmony_ci s->buf_used = 0; 3424141cc406Sopenharmony_ci s->buf_pos = 0; 3425141cc406Sopenharmony_ci 3426141cc406Sopenharmony_ci if (s->cancel == SANE_TRUE) 3427141cc406Sopenharmony_ci { 3428141cc406Sopenharmony_ci do_cancel(s); 3429141cc406Sopenharmony_ci DBG (10, ">>\n"); 3430141cc406Sopenharmony_ci return(SANE_STATUS_CANCELLED); 3431141cc406Sopenharmony_ci } 3432141cc406Sopenharmony_ci 3433141cc406Sopenharmony_ci DBG (10, ">>\n"); 3434141cc406Sopenharmony_ci return (SANE_STATUS_GOOD); 3435141cc406Sopenharmony_ci 3436141cc406Sopenharmony_ci} 3437141cc406Sopenharmony_ci 3438141cc406Sopenharmony_cistatic SANE_Status 3439141cc406Sopenharmony_cisane_read_direct (SANE_Handle handle, SANE_Byte *dst_buf, SANE_Int max_len, 3440141cc406Sopenharmony_ci SANE_Int * len) 3441141cc406Sopenharmony_ci{ 3442141cc406Sopenharmony_ci NEC_Scanner *s = handle; 3443141cc406Sopenharmony_ci SANE_Status status; 3444141cc406Sopenharmony_ci size_t nread; 3445141cc406Sopenharmony_ci DBG (10, "<< sane_read_direct "); 3446141cc406Sopenharmony_ci 3447141cc406Sopenharmony_ci#if 0 3448141cc406Sopenharmony_ci { 3449141cc406Sopenharmony_ci buffer_status bs; 3450141cc406Sopenharmony_ci size_t len = sizeof (buffer_status); 3451141cc406Sopenharmony_ci get_data_buffer_status (s->fd, &bs, &len); 3452141cc406Sopenharmony_ci DBG (20, "buffer_status: %i ", bs.fdb[0]*256*256 + bs.fdb[1]*256 + bs.fdb[2]); 3453141cc406Sopenharmony_ci } 3454141cc406Sopenharmony_ci#endif 3455141cc406Sopenharmony_ci DBG (20, "remaining: %lu ", (u_long) s->bytes_to_read); 3456141cc406Sopenharmony_ci *len = 0; 3457141cc406Sopenharmony_ci 3458141cc406Sopenharmony_ci if (s->bytes_to_read == 0) 3459141cc406Sopenharmony_ci { 3460141cc406Sopenharmony_ci do_cancel (s); 3461141cc406Sopenharmony_ci return (SANE_STATUS_EOF); 3462141cc406Sopenharmony_ci } 3463141cc406Sopenharmony_ci 3464141cc406Sopenharmony_ci if (!s->scanning) 3465141cc406Sopenharmony_ci return (do_cancel (s)); 3466141cc406Sopenharmony_ci nread = max_len; 3467141cc406Sopenharmony_ci if (nread > s->bytes_to_read) 3468141cc406Sopenharmony_ci nread = s->bytes_to_read; 3469141cc406Sopenharmony_ci if (nread > s->dev->info.bufsize) 3470141cc406Sopenharmony_ci nread = s->dev->info.bufsize; 3471141cc406Sopenharmony_ci 3472141cc406Sopenharmony_ci#ifdef USE_FORK 3473141cc406Sopenharmony_ci status = read_data(s, dst_buf, &nread); 3474141cc406Sopenharmony_ci#else 3475141cc406Sopenharmony_ci#ifdef NOTUSE_PCIN500 3476141cc406Sopenharmony_ci wait_ready(s->fd); 3477141cc406Sopenharmony_ci#endif 3478141cc406Sopenharmony_ci status = read_data (s, dst_buf, &nread); 3479141cc406Sopenharmony_ci#endif 3480141cc406Sopenharmony_ci if (status != SANE_STATUS_GOOD) 3481141cc406Sopenharmony_ci { 3482141cc406Sopenharmony_ci do_cancel (s); 3483141cc406Sopenharmony_ci return (SANE_STATUS_IO_ERROR); 3484141cc406Sopenharmony_ci } 3485141cc406Sopenharmony_ci *len = nread; 3486141cc406Sopenharmony_ci s->bytes_to_read -= nread; 3487141cc406Sopenharmony_ci DBG (20, "remaining: %lu ", (u_long) s->bytes_to_read); 3488141cc406Sopenharmony_ci 3489141cc406Sopenharmony_ci DBG (10, ">>\n"); 3490141cc406Sopenharmony_ci return (SANE_STATUS_GOOD); 3491141cc406Sopenharmony_ci} 3492141cc406Sopenharmony_ci 3493141cc406Sopenharmony_cistatic SANE_Status 3494141cc406Sopenharmony_cisane_read_shuffled (SANE_Handle handle, SANE_Byte *dst_buf, SANE_Int max_len, 3495141cc406Sopenharmony_ci SANE_Int * len, int eight_bit_data) 3496141cc406Sopenharmony_ci{ 3497141cc406Sopenharmony_ci NEC_Scanner *s = handle; 3498141cc406Sopenharmony_ci SANE_Status status; 3499141cc406Sopenharmony_ci SANE_Byte *dest, *red, *green, *blue, mask; 3500141cc406Sopenharmony_ci SANE_Int transfer; 3501141cc406Sopenharmony_ci size_t nread, ntest, pixel, max_pixel, line, max_line; 3502141cc406Sopenharmony_ci size_t start_input, bytes_per_line_in; 3503141cc406Sopenharmony_ci DBG (10, "<< sane_read_shuffled "); 3504141cc406Sopenharmony_ci 3505141cc406Sopenharmony_ci#if 0 3506141cc406Sopenharmony_ci { 3507141cc406Sopenharmony_ci buffer_status bs; 3508141cc406Sopenharmony_ci size_t len = sizeof (buffer_status); 3509141cc406Sopenharmony_ci get_data_buffer_status (s->fd, &bs, &len); 3510141cc406Sopenharmony_ci DBG (20, "buffer_status: %i ", bs.fdb[0]*256*256 + bs.fdb[1]*256 + bs.fdb[2]); 3511141cc406Sopenharmony_ci } 3512141cc406Sopenharmony_ci#endif 3513141cc406Sopenharmony_ci *len = 0; 3514141cc406Sopenharmony_ci if (s->bytes_to_read == 0 && s->buf_pos == s->buf_used) 3515141cc406Sopenharmony_ci { 3516141cc406Sopenharmony_ci do_cancel (s); 3517141cc406Sopenharmony_ci DBG (10, ">>\n"); 3518141cc406Sopenharmony_ci return (SANE_STATUS_EOF); 3519141cc406Sopenharmony_ci } 3520141cc406Sopenharmony_ci 3521141cc406Sopenharmony_ci if (!s->scanning) 3522141cc406Sopenharmony_ci { 3523141cc406Sopenharmony_ci DBG (10, ">>\n"); 3524141cc406Sopenharmony_ci return(do_cancel(s)); 3525141cc406Sopenharmony_ci } 3526141cc406Sopenharmony_ci 3527141cc406Sopenharmony_ci if (s->buf_pos < s->buf_used) 3528141cc406Sopenharmony_ci { 3529141cc406Sopenharmony_ci transfer = s->buf_used - s->buf_pos; 3530141cc406Sopenharmony_ci if (transfer > max_len) 3531141cc406Sopenharmony_ci transfer = max_len; 3532141cc406Sopenharmony_ci 3533141cc406Sopenharmony_ci memcpy(dst_buf, &(s->buffer[s->buf_pos]), transfer); 3534141cc406Sopenharmony_ci s->buf_pos += transfer; 3535141cc406Sopenharmony_ci max_len -= transfer; 3536141cc406Sopenharmony_ci *len = transfer; 3537141cc406Sopenharmony_ci } 3538141cc406Sopenharmony_ci 3539141cc406Sopenharmony_ci while (max_len > 0 && s->bytes_to_read > 0) 3540141cc406Sopenharmony_ci { 3541141cc406Sopenharmony_ci if (eight_bit_data) 3542141cc406Sopenharmony_ci { 3543141cc406Sopenharmony_ci nread = s->dev->info.bufsize / s->params.bytes_per_line - 1; 3544141cc406Sopenharmony_ci nread *= s->params.bytes_per_line; 3545141cc406Sopenharmony_ci if (nread > s->bytes_to_read) 3546141cc406Sopenharmony_ci nread = s->bytes_to_read; 3547141cc406Sopenharmony_ci max_line = nread / s->params.bytes_per_line; 3548141cc406Sopenharmony_ci start_input = s->params.bytes_per_line; 3549141cc406Sopenharmony_ci bytes_per_line_in = s->params.bytes_per_line; 3550141cc406Sopenharmony_ci } 3551141cc406Sopenharmony_ci else 3552141cc406Sopenharmony_ci { 3553141cc406Sopenharmony_ci bytes_per_line_in = (s->params.pixels_per_line + 7) / 8; 3554141cc406Sopenharmony_ci bytes_per_line_in *= 3; 3555141cc406Sopenharmony_ci max_line = s->params.bytes_per_line + bytes_per_line_in; 3556141cc406Sopenharmony_ci max_line = s->dev->info.bufsize / max_line; 3557141cc406Sopenharmony_ci nread = max_line * bytes_per_line_in; 3558141cc406Sopenharmony_ci if (nread > s->bytes_to_read) 3559141cc406Sopenharmony_ci { 3560141cc406Sopenharmony_ci nread = s->bytes_to_read; 3561141cc406Sopenharmony_ci max_line = nread / bytes_per_line_in; 3562141cc406Sopenharmony_ci } 3563141cc406Sopenharmony_ci start_input = s->dev->info.bufsize - nread; 3564141cc406Sopenharmony_ci } 3565141cc406Sopenharmony_ci ntest = nread; 3566141cc406Sopenharmony_ci 3567141cc406Sopenharmony_ci#ifdef USE_FORK 3568141cc406Sopenharmony_ci status = read_data (s, &(s->buffer[start_input]), &nread); 3569141cc406Sopenharmony_ci#else 3570141cc406Sopenharmony_ci status = read_data (s, &(s->buffer[start_input]), &nread); 3571141cc406Sopenharmony_ci#endif 3572141cc406Sopenharmony_ci if (status != SANE_STATUS_GOOD) 3573141cc406Sopenharmony_ci { 3574141cc406Sopenharmony_ci do_cancel (s); 3575141cc406Sopenharmony_ci DBG (10, ">>\n"); 3576141cc406Sopenharmony_ci return (SANE_STATUS_IO_ERROR); 3577141cc406Sopenharmony_ci } 3578141cc406Sopenharmony_ci 3579141cc406Sopenharmony_ci if (nread != ntest) 3580141cc406Sopenharmony_ci { 3581141cc406Sopenharmony_ci /* if this happens, something is wrong in the input buffer 3582141cc406Sopenharmony_ci management... 3583141cc406Sopenharmony_ci */ 3584141cc406Sopenharmony_ci DBG(1, "Warning: could not read an integral number of scan lines\n"); 3585141cc406Sopenharmony_ci DBG(1, " image will be scrambled\n"); 3586141cc406Sopenharmony_ci } 3587141cc406Sopenharmony_ci 3588141cc406Sopenharmony_ci 3589141cc406Sopenharmony_ci s->buf_used = max_line * s->params.bytes_per_line; 3590141cc406Sopenharmony_ci s->buf_pos = 0; 3591141cc406Sopenharmony_ci s->bytes_to_read -= nread; 3592141cc406Sopenharmony_ci dest = s->buffer; 3593141cc406Sopenharmony_ci max_pixel = s->params.pixels_per_line; 3594141cc406Sopenharmony_ci 3595141cc406Sopenharmony_ci if (eight_bit_data) 3596141cc406Sopenharmony_ci for (line = 1; line <= max_line; line++) 3597141cc406Sopenharmony_ci { 3598141cc406Sopenharmony_ci red = &(s->buffer[line * s->params.bytes_per_line]); 3599141cc406Sopenharmony_ci green = &(red[max_pixel]); 3600141cc406Sopenharmony_ci blue = &(green[max_pixel]); 3601141cc406Sopenharmony_ci for (pixel = 0; pixel < max_pixel; pixel++) 3602141cc406Sopenharmony_ci { 3603141cc406Sopenharmony_ci *dest++ = *red++; 3604141cc406Sopenharmony_ci *dest++ = *green++; 3605141cc406Sopenharmony_ci *dest++ = *blue++; 3606141cc406Sopenharmony_ci } 3607141cc406Sopenharmony_ci } 3608141cc406Sopenharmony_ci else 3609141cc406Sopenharmony_ci for (line = 0; line < max_line; line++) 3610141cc406Sopenharmony_ci { 3611141cc406Sopenharmony_ci red = &(s->buffer[start_input + line * bytes_per_line_in]); 3612141cc406Sopenharmony_ci green = &(red[(max_pixel+7)/8]); 3613141cc406Sopenharmony_ci blue = &(green[(max_pixel+7)/8]); 3614141cc406Sopenharmony_ci mask = 0x80; 3615141cc406Sopenharmony_ci for (pixel = 0; pixel < max_pixel; pixel++) 3616141cc406Sopenharmony_ci { 3617141cc406Sopenharmony_ci *dest++ = (*red & mask) ? 0xff : 0; 3618141cc406Sopenharmony_ci *dest++ = (*green & mask) ? 0xff : 0; 3619141cc406Sopenharmony_ci *dest++ = (*blue & mask) ? 0xff : 0; 3620141cc406Sopenharmony_ci mask = mask >> 1; 3621141cc406Sopenharmony_ci if (mask == 0) 3622141cc406Sopenharmony_ci { 3623141cc406Sopenharmony_ci mask = 0x80; 3624141cc406Sopenharmony_ci red++; 3625141cc406Sopenharmony_ci green++; 3626141cc406Sopenharmony_ci blue++; 3627141cc406Sopenharmony_ci } 3628141cc406Sopenharmony_ci } 3629141cc406Sopenharmony_ci } 3630141cc406Sopenharmony_ci 3631141cc406Sopenharmony_ci transfer = max_len; 3632141cc406Sopenharmony_ci if (transfer > s->buf_used) 3633141cc406Sopenharmony_ci transfer = s->buf_used; 3634141cc406Sopenharmony_ci memcpy(&(dst_buf[*len]), s->buffer, transfer); 3635141cc406Sopenharmony_ci 3636141cc406Sopenharmony_ci max_len -= transfer; 3637141cc406Sopenharmony_ci s->buf_pos += transfer; 3638141cc406Sopenharmony_ci *len += transfer; 3639141cc406Sopenharmony_ci } 3640141cc406Sopenharmony_ci 3641141cc406Sopenharmony_ci if (s->bytes_to_read == 0 && s->buf_pos == s->buf_used) 3642141cc406Sopenharmony_ci do_cancel (s); 3643141cc406Sopenharmony_ci DBG (10, ">>\n"); 3644141cc406Sopenharmony_ci return (SANE_STATUS_GOOD); 3645141cc406Sopenharmony_ci} 3646141cc406Sopenharmony_ci 3647141cc406Sopenharmony_ciSANE_Status 3648141cc406Sopenharmony_cisane_read (SANE_Handle handle, SANE_Byte *dst_buf, SANE_Int max_len, 3649141cc406Sopenharmony_ci SANE_Int * len) 3650141cc406Sopenharmony_ci{ 3651141cc406Sopenharmony_ci NEC_Scanner *s = handle; 3652141cc406Sopenharmony_ci SANE_Status status; 3653141cc406Sopenharmony_ci 3654141cc406Sopenharmony_ci DBG (10, "<< sane_read "); 3655141cc406Sopenharmony_ci s->busy = SANE_TRUE; 3656141cc406Sopenharmony_ci if (s->cancel == SANE_TRUE) 3657141cc406Sopenharmony_ci { 3658141cc406Sopenharmony_ci do_cancel(s); 3659141cc406Sopenharmony_ci *len = 0; 3660141cc406Sopenharmony_ci return (SANE_STATUS_CANCELLED); 3661141cc406Sopenharmony_ci } 3662141cc406Sopenharmony_ci 3663141cc406Sopenharmony_ci if (s->image_composition <= 2) 3664141cc406Sopenharmony_ci status = sane_read_direct(handle, dst_buf, max_len, len); 3665141cc406Sopenharmony_ci else if (s->image_composition <= 4) 3666141cc406Sopenharmony_ci status = sane_read_shuffled(handle, dst_buf, max_len, len, 0); 3667141cc406Sopenharmony_ci else if (s->dev->sensedat.model == PCIN500) 3668141cc406Sopenharmony_ci status = sane_read_direct(handle, dst_buf, max_len, len); 3669141cc406Sopenharmony_ci else 3670141cc406Sopenharmony_ci status = sane_read_shuffled(handle, dst_buf, max_len, len, 1); 3671141cc406Sopenharmony_ci 3672141cc406Sopenharmony_ci s->busy = SANE_FALSE; 3673141cc406Sopenharmony_ci if (s->cancel == SANE_TRUE) 3674141cc406Sopenharmony_ci { 3675141cc406Sopenharmony_ci do_cancel(s); 3676141cc406Sopenharmony_ci return (SANE_STATUS_CANCELLED); 3677141cc406Sopenharmony_ci } 3678141cc406Sopenharmony_ci 3679141cc406Sopenharmony_ci DBG (10, ">> \n"); 3680141cc406Sopenharmony_ci return (status); 3681141cc406Sopenharmony_ci} 3682141cc406Sopenharmony_ci 3683141cc406Sopenharmony_civoid 3684141cc406Sopenharmony_cisane_cancel (SANE_Handle handle) 3685141cc406Sopenharmony_ci{ 3686141cc406Sopenharmony_ci NEC_Scanner *s = handle; 3687141cc406Sopenharmony_ci DBG (10, "<< sane_cancel "); 3688141cc406Sopenharmony_ci 3689141cc406Sopenharmony_ci s->cancel = SANE_TRUE; 3690141cc406Sopenharmony_ci if (s->busy == SANE_FALSE) 3691141cc406Sopenharmony_ci do_cancel(s); 3692141cc406Sopenharmony_ci 3693141cc406Sopenharmony_ci DBG (10, ">>\n"); 3694141cc406Sopenharmony_ci} 3695141cc406Sopenharmony_ci 3696141cc406Sopenharmony_ciSANE_Status 3697141cc406Sopenharmony_cisane_set_io_mode (SANE_Handle handle, SANE_Bool non_blocking) 3698141cc406Sopenharmony_ci{ 3699141cc406Sopenharmony_ci (void) handle; 3700141cc406Sopenharmony_ci (void) non_blocking; /* silence compilation warnings */ 3701141cc406Sopenharmony_ci 3702141cc406Sopenharmony_ci DBG (10, "<< sane_set_io_mode"); 3703141cc406Sopenharmony_ci DBG (10, ">>\n"); 3704141cc406Sopenharmony_ci 3705141cc406Sopenharmony_ci return SANE_STATUS_UNSUPPORTED; 3706141cc406Sopenharmony_ci} 3707141cc406Sopenharmony_ci 3708141cc406Sopenharmony_ciSANE_Status 3709141cc406Sopenharmony_cisane_get_select_fd (SANE_Handle handle, SANE_Int * fd) 3710141cc406Sopenharmony_ci{ 3711141cc406Sopenharmony_ci (void) handle; 3712141cc406Sopenharmony_ci (void) fd; /* silence compilation warnings */ 3713141cc406Sopenharmony_ci 3714141cc406Sopenharmony_ci DBG (10, "<< sane_get_select_fd"); 3715141cc406Sopenharmony_ci DBG (10, ">>\n"); 3716141cc406Sopenharmony_ci 3717141cc406Sopenharmony_ci return SANE_STATUS_UNSUPPORTED; 3718141cc406Sopenharmony_ci} 3719