1141cc406Sopenharmony_ci/* sane - Scanner Access Now Easy. 2141cc406Sopenharmony_ci 3141cc406Sopenharmony_ci Copyright (C) 1998 Milon Firikis based on David Mosberger-Tang previous 4141cc406Sopenharmony_ci Work on mustek.c file from the SANE package. 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 Apple flatbed scanners. */ 43141cc406Sopenharmony_ci 44141cc406Sopenharmony_ci#include "../include/sane/config.h" 45141cc406Sopenharmony_ci 46141cc406Sopenharmony_ci#include <ctype.h> 47141cc406Sopenharmony_ci#include <errno.h> 48141cc406Sopenharmony_ci#include <fcntl.h> 49141cc406Sopenharmony_ci#include <limits.h> 50141cc406Sopenharmony_ci#include <signal.h> 51141cc406Sopenharmony_ci#include <stdio.h> 52141cc406Sopenharmony_ci#include <stdlib.h> 53141cc406Sopenharmony_ci#include <string.h> 54141cc406Sopenharmony_ci#include <unistd.h> 55141cc406Sopenharmony_ci 56141cc406Sopenharmony_ci#include <sys/time.h> 57141cc406Sopenharmony_ci#include <sys/types.h> 58141cc406Sopenharmony_ci#include <sys/wait.h> 59141cc406Sopenharmony_ci 60141cc406Sopenharmony_ci#include "../include/_stdint.h" 61141cc406Sopenharmony_ci 62141cc406Sopenharmony_ci#include "../include/sane/sane.h" 63141cc406Sopenharmony_ci#include "../include/sane/sanei.h" 64141cc406Sopenharmony_ci#include "../include/sane/saneopts.h" 65141cc406Sopenharmony_ci#include "../include/sane/sanei_scsi.h" 66141cc406Sopenharmony_ci 67141cc406Sopenharmony_ci 68141cc406Sopenharmony_ci/* SCSI commands that the Apple scanners understand: */ 69141cc406Sopenharmony_ci#define APPLE_SCSI_TEST_UNIT_READY 0x00 70141cc406Sopenharmony_ci#define APPLE_SCSI_REQUEST_SENSE 0x03 71141cc406Sopenharmony_ci#define APPLE_SCSI_INQUIRY 0x12 72141cc406Sopenharmony_ci#define APPLE_SCSI_MODE_SELECT 0x15 73141cc406Sopenharmony_ci#define APPLE_SCSI_RESERVE 0x16 74141cc406Sopenharmony_ci#define APPLE_SCSI_RELEASE 0x17 75141cc406Sopenharmony_ci#define APPLE_SCSI_START 0x1b 76141cc406Sopenharmony_ci#define APPLE_SCSI_AREA_AND_WINDOWS 0x24 77141cc406Sopenharmony_ci#define APPLE_SCSI_READ_SCANNED_DATA 0x28 78141cc406Sopenharmony_ci#define APPLE_SCSI_GET_DATA_STATUS 0x34 79141cc406Sopenharmony_ci 80141cc406Sopenharmony_ci 81141cc406Sopenharmony_ci#define INQ_LEN 0x60 82141cc406Sopenharmony_ci 83141cc406Sopenharmony_ci#define ENABLE(OPTION) s->opt[OPTION].cap &= ~SANE_CAP_INACTIVE 84141cc406Sopenharmony_ci#define DISABLE(OPTION) s->opt[OPTION].cap |= SANE_CAP_INACTIVE 85141cc406Sopenharmony_ci#define IS_ACTIVE(OPTION) (((s->opt[OPTION].cap) & SANE_CAP_INACTIVE) == 0) 86141cc406Sopenharmony_ci 87141cc406Sopenharmony_ci#define XQSTEP(XRES,BPP) (SANE_Int) (((double) (8*1200)) / ((double) (XRES*BPP))) 88141cc406Sopenharmony_ci#define YQSTEP(YRES) (SANE_Int) (((double) (1200)) / ((double) (YRES))) 89141cc406Sopenharmony_ci 90141cc406Sopenharmony_ci 91141cc406Sopenharmony_ci/* Very low info, Apple Scanners only */ 92141cc406Sopenharmony_ci 93141cc406Sopenharmony_ci/* TODO: Ok I admit it. I am not so clever to do this operations with bitwised 94141cc406Sopenharmony_ci operators. Sorry. */ 95141cc406Sopenharmony_ci 96141cc406Sopenharmony_ci#define STORE8(p,v) \ 97141cc406Sopenharmony_ci { \ 98141cc406Sopenharmony_ci *(p)=(v); \ 99141cc406Sopenharmony_ci } 100141cc406Sopenharmony_ci 101141cc406Sopenharmony_ci#define STORE16(p,v) \ 102141cc406Sopenharmony_ci { \ 103141cc406Sopenharmony_ci *(p)=(v)/256; \ 104141cc406Sopenharmony_ci *(p+1)=(v-*(p)*256); \ 105141cc406Sopenharmony_ci } 106141cc406Sopenharmony_ci 107141cc406Sopenharmony_ci#define STORE24(p,v) \ 108141cc406Sopenharmony_ci { \ 109141cc406Sopenharmony_ci *(p)=(v)/65536; \ 110141cc406Sopenharmony_ci *(p+1)=(v-*(p)*65536)/256; \ 111141cc406Sopenharmony_ci *(p+2)=(v-*(p)*65536-*(p+1)*256); \ 112141cc406Sopenharmony_ci } 113141cc406Sopenharmony_ci 114141cc406Sopenharmony_ci 115141cc406Sopenharmony_ci#define STORE32(p,v) \ 116141cc406Sopenharmony_ci { \ 117141cc406Sopenharmony_ci *(p)=(v)/16777216; \ 118141cc406Sopenharmony_ci *(p+1)=(v-*(p)*16777216)/65536; \ 119141cc406Sopenharmony_ci *(p+2)=(v-*(p)*16777216-*(p+1)*65536)/256; \ 120141cc406Sopenharmony_ci *(p+3)=(v-*(p)*16777216-*(p+1)*65536-*(p+2)*256);\ 121141cc406Sopenharmony_ci } 122141cc406Sopenharmony_ci 123141cc406Sopenharmony_ci#define READ24(p) *(p)*65536 + *(p+1)*256 + *(p+2) 124141cc406Sopenharmony_ci 125141cc406Sopenharmony_ci#include "../include/sane/sanei_backend.h" 126141cc406Sopenharmony_ci 127141cc406Sopenharmony_ci#ifndef PATH_MAX 128141cc406Sopenharmony_ci# define PATH_MAX 1024 129141cc406Sopenharmony_ci#endif 130141cc406Sopenharmony_ci 131141cc406Sopenharmony_ci#include "../include/sane/sanei_config.h" 132141cc406Sopenharmony_ci#define APPLE_CONFIG_FILE "apple.conf" 133141cc406Sopenharmony_ci 134141cc406Sopenharmony_ci#include "apple.h" 135141cc406Sopenharmony_ci 136141cc406Sopenharmony_ci 137141cc406Sopenharmony_cistatic const SANE_Device **devlist = 0; 138141cc406Sopenharmony_cistatic int num_devices; 139141cc406Sopenharmony_cistatic Apple_Device *first_dev; 140141cc406Sopenharmony_cistatic Apple_Scanner *first_handle; 141141cc406Sopenharmony_ci 142141cc406Sopenharmony_ci 143141cc406Sopenharmony_cistatic SANE_String_Const mode_list[6]; 144141cc406Sopenharmony_ci 145141cc406Sopenharmony_cistatic SANE_String_Const SupportedModel[] = 146141cc406Sopenharmony_ci{ 147141cc406Sopenharmony_ci"3", 148141cc406Sopenharmony_ci"AppleScanner 4bit, 16 Shades of Gray", 149141cc406Sopenharmony_ci"OneScanner 8bit, 256 Shades of Gray", 150141cc406Sopenharmony_ci"ColorOneScanner, RGB color 8bit per band", 151141cc406Sopenharmony_ciNULL 152141cc406Sopenharmony_ci}; 153141cc406Sopenharmony_ci 154141cc406Sopenharmony_cistatic const SANE_String_Const graymap_list[] = 155141cc406Sopenharmony_ci{ 156141cc406Sopenharmony_ci "dark", "normal", "light", 157141cc406Sopenharmony_ci 0 158141cc406Sopenharmony_ci}; 159141cc406Sopenharmony_ci 160141cc406Sopenharmony_ci#if 0 161141cc406Sopenharmony_cistatic const SANE_Int resbit4_list[] = 162141cc406Sopenharmony_ci{ 163141cc406Sopenharmony_ci 5, 164141cc406Sopenharmony_ci 75, 100, 150, 200, 300 165141cc406Sopenharmony_ci}; 166141cc406Sopenharmony_ci 167141cc406Sopenharmony_cistatic const SANE_Int resbit1_list[] = 168141cc406Sopenharmony_ci{ 169141cc406Sopenharmony_ci 17, 170141cc406Sopenharmony_ci 75, 90, 100, 120, 135, 150, 165, 180, 195, 171141cc406Sopenharmony_ci 200, 210, 225, 240, 255, 270, 285, 300 172141cc406Sopenharmony_ci}; 173141cc406Sopenharmony_ci#endif 174141cc406Sopenharmony_ci 175141cc406Sopenharmony_cistatic const SANE_Int resbit_list[] = 176141cc406Sopenharmony_ci{ 177141cc406Sopenharmony_ci 5, 178141cc406Sopenharmony_ci 75, 100, 150, 200, 300 179141cc406Sopenharmony_ci}; 180141cc406Sopenharmony_ci 181141cc406Sopenharmony_cistatic const SANE_String_Const speed_list[] = 182141cc406Sopenharmony_ci{ 183141cc406Sopenharmony_ci "normal", "high", "high wo H/S", 184141cc406Sopenharmony_ci 0 185141cc406Sopenharmony_ci}; 186141cc406Sopenharmony_ci 187141cc406Sopenharmony_cistatic SANE_String_Const halftone_pattern_list[6]; 188141cc406Sopenharmony_ci 189141cc406Sopenharmony_cistatic const SANE_String_Const color_sensor_list[] = 190141cc406Sopenharmony_ci{ 191141cc406Sopenharmony_ci "All", "Red", "Green", "Blue", 192141cc406Sopenharmony_ci 0 193141cc406Sopenharmony_ci}; 194141cc406Sopenharmony_ci 195141cc406Sopenharmony_ci/* NOTE: This is used for Brightness, Contrast, Threshold, AutoBackAdj 196141cc406Sopenharmony_ci and 0 is the default value */ 197141cc406Sopenharmony_cistatic const SANE_Range byte_range = 198141cc406Sopenharmony_ci{ 199141cc406Sopenharmony_ci 1, 255, 1 200141cc406Sopenharmony_ci}; 201141cc406Sopenharmony_ci 202141cc406Sopenharmony_cistatic const SANE_Range u8_range = 203141cc406Sopenharmony_ci{ 204141cc406Sopenharmony_ci 0, /* minimum */ 205141cc406Sopenharmony_ci 255, /* maximum */ 206141cc406Sopenharmony_ci 0 /* quantization */ 207141cc406Sopenharmony_ci}; 208141cc406Sopenharmony_ci 209141cc406Sopenharmony_ci 210141cc406Sopenharmony_ci/* NOTE: However I can select from different lists during the hardware 211141cc406Sopenharmony_ci probing time. */ 212141cc406Sopenharmony_ci 213141cc406Sopenharmony_ci 214141cc406Sopenharmony_ci 215141cc406Sopenharmony_ci 216141cc406Sopenharmony_cistatic const uint8_t inquiry[] = 217141cc406Sopenharmony_ci{ 218141cc406Sopenharmony_ci APPLE_SCSI_INQUIRY, 0x00, 0x00, 0x00, INQ_LEN, 0x00 219141cc406Sopenharmony_ci}; 220141cc406Sopenharmony_ci 221141cc406Sopenharmony_cistatic const uint8_t test_unit_ready[] = 222141cc406Sopenharmony_ci{ 223141cc406Sopenharmony_ci APPLE_SCSI_TEST_UNIT_READY, 0x00, 0x00, 0x00, 0x00, 0x00 224141cc406Sopenharmony_ci}; 225141cc406Sopenharmony_ci 226141cc406Sopenharmony_ci 227141cc406Sopenharmony_ci#if 0 228141cc406Sopenharmony_ciSANE_Int 229141cc406Sopenharmony_cixqstep (unsigned int Xres, unsigned int bpp) 230141cc406Sopenharmony_ci{ 231141cc406Sopenharmony_ci return (SANE_Int) ((double) (8 * 1200)) / ((double) (Xres * bpp)); 232141cc406Sopenharmony_ci} 233141cc406Sopenharmony_ci 234141cc406Sopenharmony_ci 235141cc406Sopenharmony_ciSANE_Int 236141cc406Sopenharmony_ciyqstep (unsigned int Yres, unsigned int bpp) 237141cc406Sopenharmony_ci{ 238141cc406Sopenharmony_ci return (SANE_Int) ((double) (1200)) / ((double) (Yres)); 239141cc406Sopenharmony_ci} 240141cc406Sopenharmony_ci#endif 241141cc406Sopenharmony_ci 242141cc406Sopenharmony_ci 243141cc406Sopenharmony_ci 244141cc406Sopenharmony_ci/* The functions below return the quantized value of x,y in scanners dots 245141cc406Sopenharmony_ci aka 1/1200 of an inch */ 246141cc406Sopenharmony_ci 247141cc406Sopenharmony_cistatic SANE_Int 248141cc406Sopenharmony_cixquant (double x, unsigned int Xres, unsigned int bpp, int dir) 249141cc406Sopenharmony_ci{ 250141cc406Sopenharmony_ci double tmp; 251141cc406Sopenharmony_ci unsigned int t; 252141cc406Sopenharmony_ci 253141cc406Sopenharmony_ci tmp = (double) x *Xres * bpp / (double) 8; 254141cc406Sopenharmony_ci t = (unsigned int) tmp; 255141cc406Sopenharmony_ci 256141cc406Sopenharmony_ci if (tmp - ((double) t) >= 0.1) 257141cc406Sopenharmony_ci if (dir) 258141cc406Sopenharmony_ci t++;; 259141cc406Sopenharmony_ci 260141cc406Sopenharmony_ci return t * 8 * 1200 / (Xres * bpp); 261141cc406Sopenharmony_ci} 262141cc406Sopenharmony_ci 263141cc406Sopenharmony_ci 264141cc406Sopenharmony_ci 265141cc406Sopenharmony_cistatic SANE_Int 266141cc406Sopenharmony_ciyquant (double y, unsigned int Yres, int dir) 267141cc406Sopenharmony_ci{ 268141cc406Sopenharmony_ci double tmp; 269141cc406Sopenharmony_ci unsigned int t; 270141cc406Sopenharmony_ci 271141cc406Sopenharmony_ci tmp = (double) y *Yres; 272141cc406Sopenharmony_ci t = (unsigned int) tmp; 273141cc406Sopenharmony_ci 274141cc406Sopenharmony_ci if (tmp - ((double) t) >= 0.1) 275141cc406Sopenharmony_ci if (dir) 276141cc406Sopenharmony_ci t++;; 277141cc406Sopenharmony_ci 278141cc406Sopenharmony_ci return t * 1200 / Yres; 279141cc406Sopenharmony_ci} 280141cc406Sopenharmony_ci 281141cc406Sopenharmony_cistatic SANE_Status 282141cc406Sopenharmony_ciwait_ready (int fd) 283141cc406Sopenharmony_ci{ 284141cc406Sopenharmony_ci#define MAX_WAITING_TIME 60 /* one minute, at most */ 285141cc406Sopenharmony_ci struct timeval now, start; 286141cc406Sopenharmony_ci SANE_Status status; 287141cc406Sopenharmony_ci 288141cc406Sopenharmony_ci#ifdef NEUTRALIZE_BACKEND 289141cc406Sopenharmony_cireturn SANE_STATUS_GOOD; 290141cc406Sopenharmony_ci#else 291141cc406Sopenharmony_ci 292141cc406Sopenharmony_ci gettimeofday (&start, 0); 293141cc406Sopenharmony_ci 294141cc406Sopenharmony_ci while (1) 295141cc406Sopenharmony_ci { 296141cc406Sopenharmony_ci DBG (USER_MESSAGE, "wait_ready: sending TEST_UNIT_READY\n"); 297141cc406Sopenharmony_ci 298141cc406Sopenharmony_ci status = sanei_scsi_cmd (fd, test_unit_ready, sizeof (test_unit_ready), 299141cc406Sopenharmony_ci 0, 0); 300141cc406Sopenharmony_ci switch (status) 301141cc406Sopenharmony_ci { 302141cc406Sopenharmony_ci default: 303141cc406Sopenharmony_ci /* Ignore errors while waiting for scanner to become ready. 304141cc406Sopenharmony_ci Some SCSI drivers return EIO while the scanner is 305141cc406Sopenharmony_ci returning to the home position. */ 306141cc406Sopenharmony_ci DBG (ERROR_MESSAGE, "wait_ready: test unit ready failed (%s)\n", 307141cc406Sopenharmony_ci sane_strstatus (status)); 308141cc406Sopenharmony_ci /* fall through */ 309141cc406Sopenharmony_ci case SANE_STATUS_DEVICE_BUSY: 310141cc406Sopenharmony_ci gettimeofday (&now, 0); 311141cc406Sopenharmony_ci if (now.tv_sec - start.tv_sec >= MAX_WAITING_TIME) 312141cc406Sopenharmony_ci { 313141cc406Sopenharmony_ci DBG (ERROR_MESSAGE, "wait_ready: timed out after %lu seconds\n", 314141cc406Sopenharmony_ci (u_long) now.tv_sec - start.tv_sec); 315141cc406Sopenharmony_ci return SANE_STATUS_INVAL; 316141cc406Sopenharmony_ci } 317141cc406Sopenharmony_ci usleep (100000); /* retry after 100ms */ 318141cc406Sopenharmony_ci break; 319141cc406Sopenharmony_ci 320141cc406Sopenharmony_ci case SANE_STATUS_GOOD: 321141cc406Sopenharmony_ci return status; 322141cc406Sopenharmony_ci } 323141cc406Sopenharmony_ci } 324141cc406Sopenharmony_ci return SANE_STATUS_INVAL; 325141cc406Sopenharmony_ci#endif /* NEUTRALIZE_BACKEND */ 326141cc406Sopenharmony_ci} 327141cc406Sopenharmony_ci 328141cc406Sopenharmony_cistatic SANE_Status 329141cc406Sopenharmony_cisense_handler (int scsi_fd, u_char * result, void *arg) 330141cc406Sopenharmony_ci{ 331141cc406Sopenharmony_ci (void) scsi_fd; /* silence gcc */ 332141cc406Sopenharmony_ci (void) arg; /* silence gcc */ 333141cc406Sopenharmony_ci 334141cc406Sopenharmony_ci switch (result[2] & 0x0F) 335141cc406Sopenharmony_ci { 336141cc406Sopenharmony_ci case 0: 337141cc406Sopenharmony_ci DBG (USER_MESSAGE, "Sense: No sense Error\n"); 338141cc406Sopenharmony_ci return SANE_STATUS_GOOD; 339141cc406Sopenharmony_ci case 2: 340141cc406Sopenharmony_ci DBG (ERROR_MESSAGE, "Sense: Scanner not ready\n"); 341141cc406Sopenharmony_ci return SANE_STATUS_DEVICE_BUSY; 342141cc406Sopenharmony_ci case 4: 343141cc406Sopenharmony_ci DBG (ERROR_MESSAGE, "Sense: Hardware Error. Read more...\n"); 344141cc406Sopenharmony_ci return SANE_STATUS_IO_ERROR; 345141cc406Sopenharmony_ci case 5: 346141cc406Sopenharmony_ci DBG (ERROR_MESSAGE, "Sense: Illegall request\n"); 347141cc406Sopenharmony_ci return SANE_STATUS_UNSUPPORTED; 348141cc406Sopenharmony_ci case 6: 349141cc406Sopenharmony_ci DBG (ERROR_MESSAGE, "Sense: Unit Attention (Wait until scanner " 350141cc406Sopenharmony_ci "boots)\n"); 351141cc406Sopenharmony_ci return SANE_STATUS_DEVICE_BUSY; 352141cc406Sopenharmony_ci case 9: 353141cc406Sopenharmony_ci DBG (ERROR_MESSAGE, "Sense: Vendor Unique. Read more...\n"); 354141cc406Sopenharmony_ci return SANE_STATUS_IO_ERROR; 355141cc406Sopenharmony_ci default: 356141cc406Sopenharmony_ci DBG (ERROR_MESSAGE, "Sense: Unknown Sense Key. Read more...\n"); 357141cc406Sopenharmony_ci return SANE_STATUS_IO_ERROR; 358141cc406Sopenharmony_ci } 359141cc406Sopenharmony_ci 360141cc406Sopenharmony_ci return SANE_STATUS_GOOD; 361141cc406Sopenharmony_ci} 362141cc406Sopenharmony_ci 363141cc406Sopenharmony_ci 364141cc406Sopenharmony_cistatic SANE_Status 365141cc406Sopenharmony_cirequest_sense (Apple_Scanner * s) 366141cc406Sopenharmony_ci{ 367141cc406Sopenharmony_ci uint8_t cmd[6]; 368141cc406Sopenharmony_ci uint8_t result[22]; 369141cc406Sopenharmony_ci size_t size = sizeof (result); 370141cc406Sopenharmony_ci SANE_Status status; 371141cc406Sopenharmony_ci 372141cc406Sopenharmony_ci memset (cmd, 0, sizeof (cmd)); 373141cc406Sopenharmony_ci memset (result, 0, sizeof (result)); 374141cc406Sopenharmony_ci 375141cc406Sopenharmony_ci#ifdef NEUTRALIZE_BACKEND 376141cc406Sopenharmony_cireturn SANE_STATUS_GOOD; 377141cc406Sopenharmony_ci#else 378141cc406Sopenharmony_ci 379141cc406Sopenharmony_ci cmd[0] = APPLE_SCSI_REQUEST_SENSE; 380141cc406Sopenharmony_ci STORE8 (cmd + 4, sizeof (result)); 381141cc406Sopenharmony_ci sanei_scsi_cmd (s->fd, cmd, sizeof (cmd), result, &size); 382141cc406Sopenharmony_ci 383141cc406Sopenharmony_ci if (result[7] != 14) 384141cc406Sopenharmony_ci { 385141cc406Sopenharmony_ci DBG (ERROR_MESSAGE, "Additional Length %u\n", (unsigned int) result[7]); 386141cc406Sopenharmony_ci status = SANE_STATUS_IO_ERROR; 387141cc406Sopenharmony_ci } 388141cc406Sopenharmony_ci 389141cc406Sopenharmony_ci 390141cc406Sopenharmony_ci status = sense_handler (s->fd, result, NULL); 391141cc406Sopenharmony_ci if (status == SANE_STATUS_IO_ERROR) 392141cc406Sopenharmony_ci { 393141cc406Sopenharmony_ci 394141cc406Sopenharmony_ci/* Now we are checking for Hardware and Vendor Unique Errors for all models */ 395141cc406Sopenharmony_ci/* First check the common Error conditions */ 396141cc406Sopenharmony_ci 397141cc406Sopenharmony_ci if (result[18] & 0x80) 398141cc406Sopenharmony_ci DBG (ERROR_MESSAGE, "Sense: Dim Light (output of lamp below 70%%).\n"); 399141cc406Sopenharmony_ci 400141cc406Sopenharmony_ci if (result[18] & 0x40) 401141cc406Sopenharmony_ci DBG (ERROR_MESSAGE, "Sense: No Light at all.\n"); 402141cc406Sopenharmony_ci 403141cc406Sopenharmony_ci if (result[18] & 0x20) 404141cc406Sopenharmony_ci DBG (ERROR_MESSAGE, "Sense: No Home.\n"); 405141cc406Sopenharmony_ci 406141cc406Sopenharmony_ci if (result[18] & 0x10) 407141cc406Sopenharmony_ci DBG (ERROR_MESSAGE, "Sense: No Limit. Tried to scan out of range.\n"); 408141cc406Sopenharmony_ci 409141cc406Sopenharmony_ci 410141cc406Sopenharmony_ci switch (s->hw->ScannerModel) 411141cc406Sopenharmony_ci { 412141cc406Sopenharmony_ci case APPLESCANNER: 413141cc406Sopenharmony_ci if (result[18] & 0x08) 414141cc406Sopenharmony_ci DBG (ERROR_MESSAGE, "Sense: Shade Error. Failed Calibration.\n"); 415141cc406Sopenharmony_ci if (result[18] & 0x04) 416141cc406Sopenharmony_ci DBG (ERROR_MESSAGE, "Sense: ROM Error.\n"); 417141cc406Sopenharmony_ci if (result[18] & 0x02) 418141cc406Sopenharmony_ci DBG (ERROR_MESSAGE, "Sense: RAM Error.\n"); 419141cc406Sopenharmony_ci if (result[18] & 0x01) 420141cc406Sopenharmony_ci DBG (ERROR_MESSAGE, "Sense: CPU Error.\n"); 421141cc406Sopenharmony_ci if (result[19] & 0x80) 422141cc406Sopenharmony_ci DBG (ERROR_MESSAGE, "Sense: DIPP Error.\n"); 423141cc406Sopenharmony_ci if (result[19] & 0x40) 424141cc406Sopenharmony_ci DBG (ERROR_MESSAGE, "Sense: DMA Error.\n"); 425141cc406Sopenharmony_ci if (result[19] & 0x20) 426141cc406Sopenharmony_ci DBG (ERROR_MESSAGE, "Sense: GA1 Error.\n"); 427141cc406Sopenharmony_ci break; 428141cc406Sopenharmony_ci case ONESCANNER: 429141cc406Sopenharmony_ci if (result[18] & 0x08) 430141cc406Sopenharmony_ci DBG (ERROR_MESSAGE, "Sense: CCD clock generator failed.\n"); 431141cc406Sopenharmony_ci if (result[18] & 0x04) 432141cc406Sopenharmony_ci DBG (ERROR_MESSAGE, "Sense: LRAM (Line RAM) Error.\n"); 433141cc406Sopenharmony_ci if (result[18] & 0x02) 434141cc406Sopenharmony_ci DBG (ERROR_MESSAGE, "Sense: CRAM (Correction RAM) Error.\n"); 435141cc406Sopenharmony_ci if (result[18] & 0x01) 436141cc406Sopenharmony_ci DBG (ERROR_MESSAGE, "Sense: ROM Error.\n"); 437141cc406Sopenharmony_ci if (result[19] & 0x08) 438141cc406Sopenharmony_ci DBG (ERROR_MESSAGE, "Sense: SRAM Error.\n"); 439141cc406Sopenharmony_ci if (result[19] & 0x04) 440141cc406Sopenharmony_ci DBG (ERROR_MESSAGE, "Sense: CPU Error.\n"); 441141cc406Sopenharmony_ci break; 442141cc406Sopenharmony_ci case COLORONESCANNER: 443141cc406Sopenharmony_ci if (result[18] & 0x08) 444141cc406Sopenharmony_ci DBG (ERROR_MESSAGE, "Sense: Calibration cirquit cannot " 445141cc406Sopenharmony_ci "support normal shading.\n"); 446141cc406Sopenharmony_ci if (result[18] & 0x04) 447141cc406Sopenharmony_ci DBG (ERROR_MESSAGE, "Sense: PSRAM (Correction RAM) Error.\n"); 448141cc406Sopenharmony_ci if (result[18] & 0x02) 449141cc406Sopenharmony_ci DBG (ERROR_MESSAGE, "Sense: SRAM Error.\n"); 450141cc406Sopenharmony_ci if (result[18] & 0x01) 451141cc406Sopenharmony_ci DBG (ERROR_MESSAGE, "Sense: ROM Error.\n"); 452141cc406Sopenharmony_ci if (result[19] & 0x10) 453141cc406Sopenharmony_ci DBG (ERROR_MESSAGE, "Sense: ICP (CPU) Error.\n"); 454141cc406Sopenharmony_ci if (result[19] & 0x02) 455141cc406Sopenharmony_ci DBG (ERROR_MESSAGE, "Sense: Over light. (Too bright lamp ?).\n"); 456141cc406Sopenharmony_ci break; 457141cc406Sopenharmony_ci default: 458141cc406Sopenharmony_ci DBG (ERROR_MESSAGE, 459141cc406Sopenharmony_ci "Sense: Unselected Scanner model. Please report this.\n"); 460141cc406Sopenharmony_ci break; 461141cc406Sopenharmony_ci } 462141cc406Sopenharmony_ci } 463141cc406Sopenharmony_ci 464141cc406Sopenharmony_ci DBG (USER_MESSAGE, "Sense: Optical gain %u.\n", (unsigned int) result[20]); 465141cc406Sopenharmony_ci return status; 466141cc406Sopenharmony_ci#endif /* NEUTRALIZE_BACKEND */ 467141cc406Sopenharmony_ci} 468141cc406Sopenharmony_ci 469141cc406Sopenharmony_ci 470141cc406Sopenharmony_ci 471141cc406Sopenharmony_ci 472141cc406Sopenharmony_ci 473141cc406Sopenharmony_cistatic SANE_Status 474141cc406Sopenharmony_ciattach (const char *devname, Apple_Device ** devp, int may_wait) 475141cc406Sopenharmony_ci{ 476141cc406Sopenharmony_ci char result[INQ_LEN]; 477141cc406Sopenharmony_ci const char *model_name = result + 44; 478141cc406Sopenharmony_ci int fd, apple_scanner, fw_revision; 479141cc406Sopenharmony_ci Apple_Device *dev; 480141cc406Sopenharmony_ci SANE_Status status; 481141cc406Sopenharmony_ci size_t size; 482141cc406Sopenharmony_ci 483141cc406Sopenharmony_ci for (dev = first_dev; dev; dev = dev->next) 484141cc406Sopenharmony_ci if (strcmp (dev->sane.name, devname) == 0) 485141cc406Sopenharmony_ci { 486141cc406Sopenharmony_ci if (devp) 487141cc406Sopenharmony_ci *devp = dev; 488141cc406Sopenharmony_ci return SANE_STATUS_GOOD; 489141cc406Sopenharmony_ci } 490141cc406Sopenharmony_ci 491141cc406Sopenharmony_ci DBG (USER_MESSAGE, "attach: opening %s\n", devname); 492141cc406Sopenharmony_ci 493141cc406Sopenharmony_ci#ifdef NEUTRALIZE_BACKEND 494141cc406Sopenharmony_ciresult[0]=0x06; 495141cc406Sopenharmony_cistrcpy(result + 8, "APPLE "); 496141cc406Sopenharmony_ci 497141cc406Sopenharmony_ciif (APPLE_MODEL_SELECT==APPLESCANNER) 498141cc406Sopenharmony_ci strcpy(result + 16, "SCANNER A9M0337 "); 499141cc406Sopenharmony_ciif (APPLE_MODEL_SELECT==ONESCANNER) 500141cc406Sopenharmony_ci strcpy(result + 16, "SCANNER II "); 501141cc406Sopenharmony_ciif (APPLE_MODEL_SELECT==COLORONESCANNER) 502141cc406Sopenharmony_ci strcpy(result + 16, "SCANNER III "); 503141cc406Sopenharmony_ci 504141cc406Sopenharmony_ci#else 505141cc406Sopenharmony_ci status = sanei_scsi_open (devname, &fd, sense_handler, 0); 506141cc406Sopenharmony_ci if (status != SANE_STATUS_GOOD) 507141cc406Sopenharmony_ci { 508141cc406Sopenharmony_ci DBG (ERROR_MESSAGE, "attach: open failed (%s)\n", 509141cc406Sopenharmony_ci sane_strstatus (status)); 510141cc406Sopenharmony_ci return SANE_STATUS_INVAL; 511141cc406Sopenharmony_ci } 512141cc406Sopenharmony_ci 513141cc406Sopenharmony_ci if (may_wait) 514141cc406Sopenharmony_ci wait_ready (fd); 515141cc406Sopenharmony_ci 516141cc406Sopenharmony_ci DBG (USER_MESSAGE, "attach: sending INQUIRY\n"); 517141cc406Sopenharmony_ci size = sizeof (result); 518141cc406Sopenharmony_ci status = sanei_scsi_cmd (fd, inquiry, sizeof (inquiry), result, &size); 519141cc406Sopenharmony_ci if (status != SANE_STATUS_GOOD) 520141cc406Sopenharmony_ci { 521141cc406Sopenharmony_ci DBG (ERROR_MESSAGE, "attach: inquiry failed (%s)\n", 522141cc406Sopenharmony_ci sane_strstatus (status)); 523141cc406Sopenharmony_ci sanei_scsi_close (fd); 524141cc406Sopenharmony_ci return status; 525141cc406Sopenharmony_ci } 526141cc406Sopenharmony_ci 527141cc406Sopenharmony_ci status = wait_ready (fd); 528141cc406Sopenharmony_ci sanei_scsi_close (fd); 529141cc406Sopenharmony_ci if (status != SANE_STATUS_GOOD) 530141cc406Sopenharmony_ci return status; 531141cc406Sopenharmony_ci#endif /* NEUTRALIZE_BACKEND */ 532141cc406Sopenharmony_ci 533141cc406Sopenharmony_ci /* check for old format: */ 534141cc406Sopenharmony_ci apple_scanner = (strncmp (result + 8, "APPLE ", 8) == 0); 535141cc406Sopenharmony_ci model_name = result + 16; 536141cc406Sopenharmony_ci 537141cc406Sopenharmony_ci apple_scanner = apple_scanner && (result[0] == 0x06); 538141cc406Sopenharmony_ci 539141cc406Sopenharmony_ci if (!apple_scanner) 540141cc406Sopenharmony_ci { 541141cc406Sopenharmony_ci DBG (ERROR_MESSAGE, "attach: device doesn't look like an Apple scanner" 542141cc406Sopenharmony_ci "(result[0]=%#02x)\n", result[0]); 543141cc406Sopenharmony_ci return SANE_STATUS_INVAL; 544141cc406Sopenharmony_ci } 545141cc406Sopenharmony_ci 546141cc406Sopenharmony_ci /* get firmware revision as BCD number: */ 547141cc406Sopenharmony_ci fw_revision = 548141cc406Sopenharmony_ci (result[32] - '0') << 8 | (result[34] - '0') << 4 | (result[35] - '0'); 549141cc406Sopenharmony_ci DBG (USER_MESSAGE, "attach: firmware revision %d.%02x\n", 550141cc406Sopenharmony_ci fw_revision >> 8, fw_revision & 0xff); 551141cc406Sopenharmony_ci 552141cc406Sopenharmony_ci dev = malloc (sizeof (*dev)); 553141cc406Sopenharmony_ci if (!dev) 554141cc406Sopenharmony_ci return SANE_STATUS_NO_MEM; 555141cc406Sopenharmony_ci 556141cc406Sopenharmony_ci memset (dev, 0, sizeof (*dev)); 557141cc406Sopenharmony_ci 558141cc406Sopenharmony_ci dev->sane.name = strdup (devname); 559141cc406Sopenharmony_ci dev->sane.vendor = "Apple"; 560141cc406Sopenharmony_ci dev->sane.model = strndup (model_name, 16); 561141cc406Sopenharmony_ci dev->sane.type = "flatbed scanner"; 562141cc406Sopenharmony_ci 563141cc406Sopenharmony_ci dev->x_range.min = 0; 564141cc406Sopenharmony_ci dev->x_range.max = SANE_FIX (8.51 * MM_PER_INCH); 565141cc406Sopenharmony_ci dev->x_range.quant = 0; 566141cc406Sopenharmony_ci 567141cc406Sopenharmony_ci dev->y_range.min = 0; 568141cc406Sopenharmony_ci dev->y_range.max = SANE_FIX (14.0 * MM_PER_INCH); 569141cc406Sopenharmony_ci dev->y_range.quant = 0; 570141cc406Sopenharmony_ci 571141cc406Sopenharmony_ci dev->MaxHeight = 16800; 572141cc406Sopenharmony_ci 573141cc406Sopenharmony_ci if (strncmp (model_name, "SCANNER A9M0337 ", 16) == 0) 574141cc406Sopenharmony_ci { 575141cc406Sopenharmony_ci dev->ScannerModel = APPLESCANNER; 576141cc406Sopenharmony_ci dev->dpi_range.min = SANE_FIX (75); 577141cc406Sopenharmony_ci dev->dpi_range.max = SANE_FIX (300); 578141cc406Sopenharmony_ci dev->dpi_range.quant = SANE_FIX (1); 579141cc406Sopenharmony_ci dev->MaxWidth = 10208; 580141cc406Sopenharmony_ci } 581141cc406Sopenharmony_ci else if (strncmp (model_name, "SCANNER II ", 16) == 0) 582141cc406Sopenharmony_ci { 583141cc406Sopenharmony_ci dev->ScannerModel = ONESCANNER; 584141cc406Sopenharmony_ci dev->dpi_range.min = SANE_FIX (72); 585141cc406Sopenharmony_ci dev->dpi_range.max = SANE_FIX (300); 586141cc406Sopenharmony_ci dev->dpi_range.quant = SANE_FIX (1); 587141cc406Sopenharmony_ci dev->MaxWidth = 10200; 588141cc406Sopenharmony_ci } 589141cc406Sopenharmony_ci else if (strncmp (model_name, "SCANNER III ", 16) == 0) 590141cc406Sopenharmony_ci { 591141cc406Sopenharmony_ci dev->ScannerModel = COLORONESCANNER; 592141cc406Sopenharmony_ci dev->dpi_range.min = SANE_FIX (72); 593141cc406Sopenharmony_ci dev->dpi_range.max = SANE_FIX (300); 594141cc406Sopenharmony_ci dev->dpi_range.quant = SANE_FIX (1); 595141cc406Sopenharmony_ci dev->MaxWidth = 10200; 596141cc406Sopenharmony_ci } 597141cc406Sopenharmony_ci else 598141cc406Sopenharmony_ci { 599141cc406Sopenharmony_ci DBG (ERROR_MESSAGE, 600141cc406Sopenharmony_ci "attach: Cannot found Apple scanner in the neighborhood\n"); 601141cc406Sopenharmony_ci free (dev); 602141cc406Sopenharmony_ci return SANE_STATUS_INVAL; 603141cc406Sopenharmony_ci } 604141cc406Sopenharmony_ci 605141cc406Sopenharmony_ci DBG (USER_MESSAGE, "attach: found Apple scanner model %s (%s)\n", 606141cc406Sopenharmony_ci dev->sane.model, dev->sane.type); 607141cc406Sopenharmony_ci 608141cc406Sopenharmony_ci ++num_devices; 609141cc406Sopenharmony_ci dev->next = first_dev; 610141cc406Sopenharmony_ci first_dev = dev; 611141cc406Sopenharmony_ci 612141cc406Sopenharmony_ci if (devp) 613141cc406Sopenharmony_ci *devp = dev; 614141cc406Sopenharmony_ci return SANE_STATUS_GOOD; 615141cc406Sopenharmony_ci} 616141cc406Sopenharmony_ci 617141cc406Sopenharmony_cistatic size_t 618141cc406Sopenharmony_cimax_string_size (const SANE_String_Const strings[]) 619141cc406Sopenharmony_ci{ 620141cc406Sopenharmony_ci size_t size, max_size = 0; 621141cc406Sopenharmony_ci int i; 622141cc406Sopenharmony_ci 623141cc406Sopenharmony_ci for (i = 0; strings[i]; ++i) 624141cc406Sopenharmony_ci { 625141cc406Sopenharmony_ci size = strlen (strings[i]) + 1; 626141cc406Sopenharmony_ci if (size > max_size) 627141cc406Sopenharmony_ci max_size = size; 628141cc406Sopenharmony_ci } 629141cc406Sopenharmony_ci return max_size; 630141cc406Sopenharmony_ci} 631141cc406Sopenharmony_ci 632141cc406Sopenharmony_ci 633141cc406Sopenharmony_cistatic SANE_Status 634141cc406Sopenharmony_ciscan_area_and_windows (Apple_Scanner * s) 635141cc406Sopenharmony_ci{ 636141cc406Sopenharmony_ci uint8_t cmd[10 + 8 + 42]; 637141cc406Sopenharmony_ci#define CMD cmd + 0 638141cc406Sopenharmony_ci#define WH cmd + 10 639141cc406Sopenharmony_ci#define WP WH + 8 640141cc406Sopenharmony_ci 641141cc406Sopenharmony_ci#ifdef NEUTRALIZE_BACKEND 642141cc406Sopenharmony_cireturn SANE_STATUS_GOOD; 643141cc406Sopenharmony_ci#else 644141cc406Sopenharmony_ci 645141cc406Sopenharmony_ci /* setup SCSI command (except length): */ 646141cc406Sopenharmony_ci memset (cmd, 0, sizeof (cmd)); 647141cc406Sopenharmony_ci cmd[0] = APPLE_SCSI_AREA_AND_WINDOWS; 648141cc406Sopenharmony_ci 649141cc406Sopenharmony_ci 650141cc406Sopenharmony_ci if (s->hw->ScannerModel == COLORONESCANNER) 651141cc406Sopenharmony_ci { 652141cc406Sopenharmony_ci STORE24 (CMD + 6, 50); 653141cc406Sopenharmony_ci STORE16 (WH + 6, 42); 654141cc406Sopenharmony_ci } 655141cc406Sopenharmony_ci else 656141cc406Sopenharmony_ci { 657141cc406Sopenharmony_ci STORE24 (CMD + 6, 48); 658141cc406Sopenharmony_ci STORE16 (WH + 6, 40); 659141cc406Sopenharmony_ci } 660141cc406Sopenharmony_ci 661141cc406Sopenharmony_ci/* Store resolution. First X, the Y */ 662141cc406Sopenharmony_ci 663141cc406Sopenharmony_ci STORE16 (WP + 2, s->val[OPT_RESOLUTION].w); 664141cc406Sopenharmony_ci STORE16 (WP + 4, s->val[OPT_RESOLUTION].w); 665141cc406Sopenharmony_ci 666141cc406Sopenharmony_ci/* Now the Scanner Window in Scanner Parameters */ 667141cc406Sopenharmony_ci 668141cc406Sopenharmony_ci STORE32 (WP + 6, s->ULx); 669141cc406Sopenharmony_ci STORE32 (WP + 10, s->ULy); 670141cc406Sopenharmony_ci STORE32 (WP + 14, s->Width); 671141cc406Sopenharmony_ci STORE32 (WP + 18, s->Height); 672141cc406Sopenharmony_ci 673141cc406Sopenharmony_ci/* Now The Enhansment Group */ 674141cc406Sopenharmony_ci 675141cc406Sopenharmony_ci STORE8 (WP + 22, s->val[OPT_BRIGHTNESS].w); 676141cc406Sopenharmony_ci STORE8 (WP + 23, s->val[OPT_THRESHOLD].w); 677141cc406Sopenharmony_ci STORE8 (WP + 24, s->val[OPT_CONTRAST].w); 678141cc406Sopenharmony_ci 679141cc406Sopenharmony_ci/* The Mode */ 680141cc406Sopenharmony_ci 681141cc406Sopenharmony_ci if (!strcmp (s->val[OPT_MODE].s, SANE_VALUE_SCAN_MODE_LINEART)) 682141cc406Sopenharmony_ci STORE8 (WP + 25, 0) 683141cc406Sopenharmony_ci else if (!strcmp (s->val[OPT_MODE].s, SANE_VALUE_SCAN_MODE_HALFTONE)) 684141cc406Sopenharmony_ci STORE8 (WP + 25, 1) 685141cc406Sopenharmony_ci else if (!strcmp (s->val[OPT_MODE].s, SANE_VALUE_SCAN_MODE_GRAY) || 686141cc406Sopenharmony_ci !strcmp (s->val[OPT_MODE].s, "Gray16")) 687141cc406Sopenharmony_ci STORE8 (WP + 25, 2) 688141cc406Sopenharmony_ci else if (!strcmp (s->val[OPT_MODE].s, "BiColor")) 689141cc406Sopenharmony_ci STORE8 (WP + 25, 3) 690141cc406Sopenharmony_ci else if (!strcmp (s->val[OPT_MODE].s, SANE_VALUE_SCAN_MODE_COLOR)) 691141cc406Sopenharmony_ci STORE8 (WP + 25, 5) 692141cc406Sopenharmony_ci else 693141cc406Sopenharmony_ci { 694141cc406Sopenharmony_ci DBG (ERROR_MESSAGE, "Cannot much mode %s\n", s->val[OPT_MODE].s); 695141cc406Sopenharmony_ci return SANE_STATUS_INVAL; 696141cc406Sopenharmony_ci } 697141cc406Sopenharmony_ci 698141cc406Sopenharmony_ci STORE8 (WP + 26, s->bpp) 699141cc406Sopenharmony_ci 700141cc406Sopenharmony_ci/* HalfTone */ 701141cc406Sopenharmony_ciif (s->hw->ScannerModel != COLORONESCANNER) 702141cc406Sopenharmony_ci { 703141cc406Sopenharmony_ci if (!strcmp (s->val[OPT_HALFTONE_PATTERN].s, "spiral4x4")) 704141cc406Sopenharmony_ci STORE16 (WP + 27, 0) 705141cc406Sopenharmony_ci else if (!strcmp (s->val[OPT_HALFTONE_PATTERN].s, "bayer4x4")) 706141cc406Sopenharmony_ci STORE16 (WP + 27, 1) 707141cc406Sopenharmony_ci else if (!strcmp (s->val[OPT_HALFTONE_PATTERN].s, "download")) 708141cc406Sopenharmony_ci STORE16 (WP + 27, 1) 709141cc406Sopenharmony_ci else if (!strcmp (s->val[OPT_HALFTONE_PATTERN].s, "spiral8x8")) 710141cc406Sopenharmony_ci STORE16 (WP + 27, 3) 711141cc406Sopenharmony_ci else if (!strcmp (s->val[OPT_HALFTONE_PATTERN].s, "bayer8x8")) 712141cc406Sopenharmony_ci STORE16 (WP + 27, 4) 713141cc406Sopenharmony_ci else 714141cc406Sopenharmony_ci { 715141cc406Sopenharmony_ci DBG (ERROR_MESSAGE, "Cannot much haftone pattern %s\n", 716141cc406Sopenharmony_ci s->val[OPT_HALFTONE_PATTERN].s); 717141cc406Sopenharmony_ci return SANE_STATUS_INVAL; 718141cc406Sopenharmony_ci } 719141cc406Sopenharmony_ci } 720141cc406Sopenharmony_ci/* Padding Type */ 721141cc406Sopenharmony_ci STORE8 (WP + 29, 3); 722141cc406Sopenharmony_ci 723141cc406Sopenharmony_ci if (s->hw->ScannerModel == COLORONESCANNER) 724141cc406Sopenharmony_ci { 725141cc406Sopenharmony_ci if (s->val[OPT_VOLT_REF].w) 726141cc406Sopenharmony_ci { 727141cc406Sopenharmony_ci STORE8(WP+40,s->val[OPT_VOLT_REF_TOP].w); 728141cc406Sopenharmony_ci STORE8(WP+41,s->val[OPT_VOLT_REF_BOTTOM].w); 729141cc406Sopenharmony_ci } 730141cc406Sopenharmony_ci else 731141cc406Sopenharmony_ci { 732141cc406Sopenharmony_ci STORE8(WP+40,0); 733141cc406Sopenharmony_ci STORE8(WP+41,0); 734141cc406Sopenharmony_ci } 735141cc406Sopenharmony_ci return sanei_scsi_cmd (s->fd, cmd, sizeof (cmd), 0, 0); 736141cc406Sopenharmony_ci } 737141cc406Sopenharmony_ci else 738141cc406Sopenharmony_ci return sanei_scsi_cmd (s->fd, cmd, sizeof (cmd) - 2, 0, 0); 739141cc406Sopenharmony_ci 740141cc406Sopenharmony_ci#endif /* NEUTRALIZE_BACKEND */ 741141cc406Sopenharmony_ci} 742141cc406Sopenharmony_ci 743141cc406Sopenharmony_cistatic SANE_Status 744141cc406Sopenharmony_cimode_select (Apple_Scanner * s) 745141cc406Sopenharmony_ci{ 746141cc406Sopenharmony_ci uint8_t cmd[6 + 12]; 747141cc406Sopenharmony_ci#define CMD cmd + 0 748141cc406Sopenharmony_ci#define PP cmd + 6 749141cc406Sopenharmony_ci 750141cc406Sopenharmony_ci /* setup SCSI command (except length): */ 751141cc406Sopenharmony_ci memset (cmd, 0, sizeof (cmd)); 752141cc406Sopenharmony_ci cmd[0] = APPLE_SCSI_MODE_SELECT; 753141cc406Sopenharmony_ci 754141cc406Sopenharmony_ci/* Apple Hardware Magic */ 755141cc406Sopenharmony_ci STORE8 (CMD + 1, 0x10); 756141cc406Sopenharmony_ci 757141cc406Sopenharmony_ci/* Parameter list length */ 758141cc406Sopenharmony_ci STORE8 (CMD + 4, 12); 759141cc406Sopenharmony_ci 760141cc406Sopenharmony_ci STORE8 (PP + 5, 6); 761141cc406Sopenharmony_ci 762141cc406Sopenharmony_ci if (s->val[OPT_LAMP].w) *(PP+8) |= 1; 763141cc406Sopenharmony_ci 764141cc406Sopenharmony_ci switch (s->hw->ScannerModel) 765141cc406Sopenharmony_ci { 766141cc406Sopenharmony_ci case APPLESCANNER: 767141cc406Sopenharmony_ci if (!strcmp (s->val[OPT_GRAYMAP].s, "dark")) 768141cc406Sopenharmony_ci STORE8 (PP + 6, 0) 769141cc406Sopenharmony_ci else if (!strcmp (s->val[OPT_GRAYMAP].s, "normal")) 770141cc406Sopenharmony_ci STORE8 (PP + 6, 1) 771141cc406Sopenharmony_ci else if (!strcmp (s->val[OPT_GRAYMAP].s, "light")) 772141cc406Sopenharmony_ci STORE8 (PP + 6, 2) 773141cc406Sopenharmony_ci else 774141cc406Sopenharmony_ci { 775141cc406Sopenharmony_ci DBG (ERROR_MESSAGE, "Cannot mach GrayMap Function %s\n", 776141cc406Sopenharmony_ci s->val[OPT_GRAYMAP].s); 777141cc406Sopenharmony_ci return SANE_STATUS_INVAL; 778141cc406Sopenharmony_ci } 779141cc406Sopenharmony_ci /* And the auto background threshold */ 780141cc406Sopenharmony_ci STORE8 (PP + 7, s->val[OPT_AUTOBACKGROUND_THRESHOLD].w) 781141cc406Sopenharmony_ci break; 782141cc406Sopenharmony_ci case ONESCANNER: 783141cc406Sopenharmony_ci if (s->val[OPT_LED].w) *(PP+7) |= 4; 784141cc406Sopenharmony_ci if (s->val[OPT_CCD].w) *(PP+8) |= 2; 785141cc406Sopenharmony_ci if (!strcmp (s->val[OPT_SPEED].s, "high")) 786141cc406Sopenharmony_ci *(PP+8) |= 4; 787141cc406Sopenharmony_ci else if (!strcmp (s->val[OPT_SPEED].s, "high wo H/S")) 788141cc406Sopenharmony_ci *(PP+8) |= 8; 789141cc406Sopenharmony_ci else if (!strcmp (s->val[OPT_SPEED].s, "normal")) 790141cc406Sopenharmony_ci { /* Do nothing. Zeros are great */} 791141cc406Sopenharmony_ci else 792141cc406Sopenharmony_ci { 793141cc406Sopenharmony_ci DBG (ERROR_MESSAGE, "Cannot mach speed selection %s\n", 794141cc406Sopenharmony_ci s->val[OPT_SPEED].s); 795141cc406Sopenharmony_ci return SANE_STATUS_INVAL; 796141cc406Sopenharmony_ci } 797141cc406Sopenharmony_ci break; 798141cc406Sopenharmony_ci case COLORONESCANNER: 799141cc406Sopenharmony_ci if (s->val[OPT_LED].w) *(PP+7) |= 4; 800141cc406Sopenharmony_ci if (!s->val[OPT_CUSTOM_GAMMA].w) *(PP+7) |= 2; 801141cc406Sopenharmony_ci if (!s->val[OPT_CUSTOM_CCT].w) *(PP+7) |= 1; 802141cc406Sopenharmony_ci if (s->val[OPT_MTF_CIRCUIT].w) *(PP+8) |= 16; 803141cc406Sopenharmony_ci if (s->val[OPT_ICP].w) *(PP+8) |= 8; 804141cc406Sopenharmony_ci if (s->val[OPT_POLARITY].w) *(PP+8) |= 4; 805141cc406Sopenharmony_ci if (s->val[OPT_CCD].w) *(PP+8) |= 2; 806141cc406Sopenharmony_ci 807141cc406Sopenharmony_ci if (!strcmp (s->val[OPT_COLOR_SENSOR].s, "All")) 808141cc406Sopenharmony_ci STORE8 (PP + 9, 0) 809141cc406Sopenharmony_ci else if (!strcmp (s->val[OPT_COLOR_SENSOR].s, "Red")) 810141cc406Sopenharmony_ci STORE8 (PP + 9, 1) 811141cc406Sopenharmony_ci else if (!strcmp (s->val[OPT_COLOR_SENSOR].s, "Green")) 812141cc406Sopenharmony_ci STORE8 (PP + 9, 2) 813141cc406Sopenharmony_ci else if (!strcmp (s->val[OPT_COLOR_SENSOR].s, "Blue")) 814141cc406Sopenharmony_ci STORE8 (PP + 9, 3) 815141cc406Sopenharmony_ci else 816141cc406Sopenharmony_ci { 817141cc406Sopenharmony_ci DBG (ERROR_MESSAGE, "Cannot mach Color Sensor for gray scans %s\n", 818141cc406Sopenharmony_ci s->val[OPT_COLOR_SENSOR].s); 819141cc406Sopenharmony_ci return SANE_STATUS_INVAL; 820141cc406Sopenharmony_ci } 821141cc406Sopenharmony_ci 822141cc406Sopenharmony_ci break; 823141cc406Sopenharmony_ci default: 824141cc406Sopenharmony_ci DBG(ERROR_MESSAGE,"Bad Scanner.\n"); 825141cc406Sopenharmony_ci break; 826141cc406Sopenharmony_ci } 827141cc406Sopenharmony_ci 828141cc406Sopenharmony_ci#ifdef NEUTRALIZE_BACKEND 829141cc406Sopenharmony_ci return SANE_STATUS_GOOD; 830141cc406Sopenharmony_ci#else 831141cc406Sopenharmony_ci return sanei_scsi_cmd (s->fd, cmd, sizeof (cmd), 0, 0); 832141cc406Sopenharmony_ci#endif /* NEUTRALIZE_BACKEND */ 833141cc406Sopenharmony_ci 834141cc406Sopenharmony_ci} 835141cc406Sopenharmony_ci 836141cc406Sopenharmony_cistatic SANE_Status 837141cc406Sopenharmony_cistart_scan (Apple_Scanner * s) 838141cc406Sopenharmony_ci{ 839141cc406Sopenharmony_ci SANE_Status status; 840141cc406Sopenharmony_ci uint8_t start[7]; 841141cc406Sopenharmony_ci 842141cc406Sopenharmony_ci 843141cc406Sopenharmony_ci memset (start, 0, sizeof (start)); 844141cc406Sopenharmony_ci start[0] = APPLE_SCSI_START; 845141cc406Sopenharmony_ci start[4] = 1; 846141cc406Sopenharmony_ci 847141cc406Sopenharmony_ci switch (s->hw->ScannerModel) 848141cc406Sopenharmony_ci { 849141cc406Sopenharmony_ci case APPLESCANNER: 850141cc406Sopenharmony_ci if (s->val[OPT_WAIT].w) start[5]=0x80; 851141cc406Sopenharmony_ci /* NOT TODO NoHome */ 852141cc406Sopenharmony_ci break; 853141cc406Sopenharmony_ci case ONESCANNER: 854141cc406Sopenharmony_ci if (!s->val[OPT_CALIBRATE].w) start[5]=0x20; 855141cc406Sopenharmony_ci break; 856141cc406Sopenharmony_ci case COLORONESCANNER: 857141cc406Sopenharmony_ci break; 858141cc406Sopenharmony_ci default: 859141cc406Sopenharmony_ci DBG(ERROR_MESSAGE,"Bad Scanner.\n"); 860141cc406Sopenharmony_ci break; 861141cc406Sopenharmony_ci } 862141cc406Sopenharmony_ci 863141cc406Sopenharmony_ci 864141cc406Sopenharmony_ci#ifdef NEUTRALIZE_BACKEND 865141cc406Sopenharmony_ci return SANE_STATUS_GOOD; 866141cc406Sopenharmony_ci#else 867141cc406Sopenharmony_ci status = sanei_scsi_cmd (s->fd, start, sizeof (start), 0, 0); 868141cc406Sopenharmony_ci return status; 869141cc406Sopenharmony_ci#endif /* NEUTRALIZE_BACKEND */ 870141cc406Sopenharmony_ci} 871141cc406Sopenharmony_ci 872141cc406Sopenharmony_cistatic SANE_Status 873141cc406Sopenharmony_cicalc_parameters (Apple_Scanner * s) 874141cc406Sopenharmony_ci{ 875141cc406Sopenharmony_ci SANE_String val = s->val[OPT_MODE].s; 876141cc406Sopenharmony_ci SANE_Status status = SANE_STATUS_GOOD; 877141cc406Sopenharmony_ci SANE_Bool OutOfRangeX, OutOfRangeY, Protect = SANE_TRUE; 878141cc406Sopenharmony_ci SANE_Int xqstep, yqstep; 879141cc406Sopenharmony_ci 880141cc406Sopenharmony_ci DBG (FLOW_CONTROL, "Entering calc_parameters\n"); 881141cc406Sopenharmony_ci 882141cc406Sopenharmony_ci if (!strcmp (val, SANE_VALUE_SCAN_MODE_LINEART)) 883141cc406Sopenharmony_ci { 884141cc406Sopenharmony_ci s->params.last_frame = SANE_TRUE; 885141cc406Sopenharmony_ci s->params.format = SANE_FRAME_GRAY; 886141cc406Sopenharmony_ci s->params.depth = 1; 887141cc406Sopenharmony_ci s->bpp = 1; 888141cc406Sopenharmony_ci } 889141cc406Sopenharmony_ci else if (!strcmp (val, SANE_VALUE_SCAN_MODE_HALFTONE)) 890141cc406Sopenharmony_ci { 891141cc406Sopenharmony_ci s->params.last_frame = SANE_TRUE; 892141cc406Sopenharmony_ci s->params.format = SANE_FRAME_GRAY; 893141cc406Sopenharmony_ci s->params.depth = 1; 894141cc406Sopenharmony_ci s->bpp = 1; 895141cc406Sopenharmony_ci } 896141cc406Sopenharmony_ci else if (!strcmp (val, "Gray16")) 897141cc406Sopenharmony_ci { 898141cc406Sopenharmony_ci s->params.last_frame = SANE_TRUE; 899141cc406Sopenharmony_ci s->params.format = SANE_FRAME_GRAY; 900141cc406Sopenharmony_ci s->params.depth = 8; 901141cc406Sopenharmony_ci s->bpp = 4; 902141cc406Sopenharmony_ci } 903141cc406Sopenharmony_ci else if (!strcmp (val, SANE_VALUE_SCAN_MODE_GRAY)) 904141cc406Sopenharmony_ci { 905141cc406Sopenharmony_ci s->params.last_frame = SANE_TRUE; 906141cc406Sopenharmony_ci s->params.format = SANE_FRAME_GRAY; 907141cc406Sopenharmony_ci s->params.depth = 8; 908141cc406Sopenharmony_ci s->bpp = 8; 909141cc406Sopenharmony_ci } 910141cc406Sopenharmony_ci else if (!strcmp (val, "BiColor")) 911141cc406Sopenharmony_ci { 912141cc406Sopenharmony_ci s->params.last_frame = SANE_TRUE; 913141cc406Sopenharmony_ci s->params.format = SANE_FRAME_RGB; 914141cc406Sopenharmony_ci s->params.depth = 24; 915141cc406Sopenharmony_ci s->bpp = 3; 916141cc406Sopenharmony_ci } 917141cc406Sopenharmony_ci else if (!strcmp (val, SANE_VALUE_SCAN_MODE_COLOR)) 918141cc406Sopenharmony_ci { 919141cc406Sopenharmony_ci s->params.last_frame = SANE_FALSE; 920141cc406Sopenharmony_ci s->params.format = SANE_FRAME_RED; 921141cc406Sopenharmony_ci s->params.depth = 24; 922141cc406Sopenharmony_ci s->bpp = 24; 923141cc406Sopenharmony_ci } 924141cc406Sopenharmony_ci else 925141cc406Sopenharmony_ci { 926141cc406Sopenharmony_ci DBG (ERROR_MESSAGE, "calc_parameters: Invalid mode %s\n", (char *) val); 927141cc406Sopenharmony_ci status = SANE_STATUS_INVAL; 928141cc406Sopenharmony_ci } 929141cc406Sopenharmony_ci 930141cc406Sopenharmony_ci s->ulx = SANE_UNFIX (s->val[OPT_TL_X].w) / MM_PER_INCH; 931141cc406Sopenharmony_ci s->uly = SANE_UNFIX (s->val[OPT_TL_Y].w) / MM_PER_INCH; 932141cc406Sopenharmony_ci s->wx = SANE_UNFIX (s->val[OPT_BR_X].w) / MM_PER_INCH - s->ulx; 933141cc406Sopenharmony_ci s->wy = SANE_UNFIX (s->val[OPT_BR_Y].w) / MM_PER_INCH - s->uly; 934141cc406Sopenharmony_ci 935141cc406Sopenharmony_ci DBG (VARIABLE_CONTROL, "Desired [%g,%g] to +[%g,%g]\n", 936141cc406Sopenharmony_ci s->ulx, s->uly, s->wx, s->wy); 937141cc406Sopenharmony_ci 938141cc406Sopenharmony_ci xqstep = XQSTEP (s->val[OPT_RESOLUTION].w, s->bpp); 939141cc406Sopenharmony_ci yqstep = YQSTEP (s->val[OPT_RESOLUTION].w); 940141cc406Sopenharmony_ci 941141cc406Sopenharmony_ci DBG (VARIABLE_CONTROL, "Quantization steps of [%u,%u].\n", xqstep, yqstep); 942141cc406Sopenharmony_ci 943141cc406Sopenharmony_ci s->ULx = xquant (s->ulx, s->val[OPT_RESOLUTION].w, s->bpp, 0); 944141cc406Sopenharmony_ci s->Width = xquant (s->wx, s->val[OPT_RESOLUTION].w, s->bpp, 1); 945141cc406Sopenharmony_ci s->ULy = yquant (s->uly, s->val[OPT_RESOLUTION].w, 0); 946141cc406Sopenharmony_ci s->Height = yquant (s->wy, s->val[OPT_RESOLUTION].w, 1); 947141cc406Sopenharmony_ci 948141cc406Sopenharmony_ci DBG (VARIABLE_CONTROL, "Scanner [%u,%u] to +[%u,%u]\n", 949141cc406Sopenharmony_ci s->ULx, s->ULy, s->Width, s->Height); 950141cc406Sopenharmony_ci 951141cc406Sopenharmony_ci do 952141cc406Sopenharmony_ci { 953141cc406Sopenharmony_ci 954141cc406Sopenharmony_ci OutOfRangeX = SANE_FALSE; 955141cc406Sopenharmony_ci OutOfRangeY = SANE_FALSE; 956141cc406Sopenharmony_ci 957141cc406Sopenharmony_ci if (s->ULx + s->Width > s->hw->MaxWidth) 958141cc406Sopenharmony_ci { 959141cc406Sopenharmony_ci OutOfRangeX = SANE_TRUE; 960141cc406Sopenharmony_ci Protect = SANE_FALSE; 961141cc406Sopenharmony_ci s->Width -= xqstep; 962141cc406Sopenharmony_ci } 963141cc406Sopenharmony_ci 964141cc406Sopenharmony_ci if (s->ULy + s->Height > s->hw->MaxHeight) 965141cc406Sopenharmony_ci { 966141cc406Sopenharmony_ci OutOfRangeY = SANE_TRUE; 967141cc406Sopenharmony_ci Protect = SANE_FALSE; 968141cc406Sopenharmony_ci s->Height -= yqstep; 969141cc406Sopenharmony_ci } 970141cc406Sopenharmony_ci 971141cc406Sopenharmony_ci DBG (VARIABLE_CONTROL, "Adapting to [%u,%u] to +[%u,%u]\n", 972141cc406Sopenharmony_ci s->ULx, s->ULy, s->Width, s->Height); 973141cc406Sopenharmony_ci 974141cc406Sopenharmony_ci } 975141cc406Sopenharmony_ci while (OutOfRangeX || OutOfRangeY); 976141cc406Sopenharmony_ci 977141cc406Sopenharmony_ci s->ulx = (double) s->ULx / 1200; 978141cc406Sopenharmony_ci s->uly = (double) s->ULy / 1200; 979141cc406Sopenharmony_ci s->wx = (double) s->Width / 1200; 980141cc406Sopenharmony_ci s->wy = (double) s->Height / 1200; 981141cc406Sopenharmony_ci 982141cc406Sopenharmony_ci 983141cc406Sopenharmony_ci DBG (VARIABLE_CONTROL, "Real [%g,%g] to +[%g,%g]\n", 984141cc406Sopenharmony_ci s->ulx, s->uly, s->wx, s->wy); 985141cc406Sopenharmony_ci 986141cc406Sopenharmony_ci 987141cc406Sopenharmony_ci/* 988141cc406Sopenharmony_ci 989141cc406Sopenharmony_ci TODO: Remove this ugly hack (Protect). Read to learn why! 990141cc406Sopenharmony_ci 991141cc406Sopenharmony_ci NOTE: I hate the Fixed Sane type. This type gave me a terrible 992141cc406Sopenharmony_ci headache and a difficult bug to find out. The xscanimage frontend 993141cc406Sopenharmony_ci was looping and segfaulting all the time with random order. The 994141cc406Sopenharmony_ci problem was the following: 995141cc406Sopenharmony_ci 996141cc406Sopenharmony_ci * You select new let's say BR_X 997141cc406Sopenharmony_ci * sane_control_option returns info inexact (always for BR_X) but 998141cc406Sopenharmony_ci does not modify val because it fits under the constrained 999141cc406Sopenharmony_ci quantization. 1000141cc406Sopenharmony_ci 1001141cc406Sopenharmony_ci Hm... Well sane_control doesn't change the (double) value of val 1002141cc406Sopenharmony_ci but the Fixed interpatation may have been change (by 1 or something 1003141cc406Sopenharmony_ci small). 1004141cc406Sopenharmony_ci 1005141cc406Sopenharmony_ci So now we should protect the val if the change is smaller than the 1006141cc406Sopenharmony_ci quantization step or better under the SANE_[UN]FIX accuracy. 1007141cc406Sopenharmony_ci 1008141cc406Sopenharmony_ci Looks like for two distinct val (Fixed) values we get the same 1009141cc406Sopenharmony_ci double. How come ? 1010141cc406Sopenharmony_ci 1011141cc406Sopenharmony_ci This hack fixed the looping situation. Unfortunately SIGSEGV 1012141cc406Sopenharmony_ci remains when you touch the slice bars (thouhg not all the 1013141cc406Sopenharmony_ci time). But it's OK if you select scan_area from the preview window 1014141cc406Sopenharmony_ci (cool). 1015141cc406Sopenharmony_ci 1016141cc406Sopenharmony_ci */ 1017141cc406Sopenharmony_ci 1018141cc406Sopenharmony_ci if (!Protect) 1019141cc406Sopenharmony_ci { 1020141cc406Sopenharmony_ci s->val[OPT_TL_X].w = SANE_FIX (s->ulx * MM_PER_INCH); 1021141cc406Sopenharmony_ci s->val[OPT_TL_Y].w = SANE_FIX (s->uly * MM_PER_INCH); 1022141cc406Sopenharmony_ci s->val[OPT_BR_X].w = SANE_FIX ((s->ulx + s->wx) * MM_PER_INCH); 1023141cc406Sopenharmony_ci s->val[OPT_BR_Y].w = SANE_FIX ((s->uly + s->wy) * MM_PER_INCH); 1024141cc406Sopenharmony_ci } 1025141cc406Sopenharmony_ci else 1026141cc406Sopenharmony_ci DBG (VARIABLE_CONTROL, "Not adapted. Protecting\n"); 1027141cc406Sopenharmony_ci 1028141cc406Sopenharmony_ci 1029141cc406Sopenharmony_ci DBG (VARIABLE_CONTROL, "GUI [%g,%g] to [%g,%g]\n", 1030141cc406Sopenharmony_ci SANE_UNFIX (s->val[OPT_TL_X].w), 1031141cc406Sopenharmony_ci SANE_UNFIX (s->val[OPT_TL_Y].w), 1032141cc406Sopenharmony_ci SANE_UNFIX (s->val[OPT_BR_X].w), 1033141cc406Sopenharmony_ci SANE_UNFIX (s->val[OPT_BR_Y].w)); 1034141cc406Sopenharmony_ci 1035141cc406Sopenharmony_ci /* NOTE: remember that AppleScanners quantize the scan area to be a 1036141cc406Sopenharmony_ci byte multiple */ 1037141cc406Sopenharmony_ci 1038141cc406Sopenharmony_ci 1039141cc406Sopenharmony_ci s->params.pixels_per_line = s->Width * s->val[OPT_RESOLUTION].w / 1200; 1040141cc406Sopenharmony_ci s->params.lines = s->Height * s->val[OPT_RESOLUTION].w / 1200; 1041141cc406Sopenharmony_ci s->params.bytes_per_line = s->params.pixels_per_line * s->params.depth / 8; 1042141cc406Sopenharmony_ci 1043141cc406Sopenharmony_ci 1044141cc406Sopenharmony_ci DBG (VARIABLE_CONTROL, "format=%d\n", s->params.format); 1045141cc406Sopenharmony_ci DBG (VARIABLE_CONTROL, "last_frame=%d\n", s->params.last_frame); 1046141cc406Sopenharmony_ci DBG (VARIABLE_CONTROL, "lines=%d\n", s->params.lines); 1047141cc406Sopenharmony_ci DBG (VARIABLE_CONTROL, "depth=%d (%d)\n", s->params.depth, s->bpp); 1048141cc406Sopenharmony_ci DBG (VARIABLE_CONTROL, "pixels_per_line=%d\n", s->params.pixels_per_line); 1049141cc406Sopenharmony_ci DBG (VARIABLE_CONTROL, "bytes_per_line=%d\n", s->params.bytes_per_line); 1050141cc406Sopenharmony_ci DBG (VARIABLE_CONTROL, "Pixels %dx%dx%d\n", 1051141cc406Sopenharmony_ci s->params.pixels_per_line, s->params.lines, 1 << s->params.depth); 1052141cc406Sopenharmony_ci 1053141cc406Sopenharmony_ci DBG (FLOW_CONTROL, "Leaving calc_parameters\n"); 1054141cc406Sopenharmony_ci return status; 1055141cc406Sopenharmony_ci} 1056141cc406Sopenharmony_ci 1057141cc406Sopenharmony_ci 1058141cc406Sopenharmony_ci 1059141cc406Sopenharmony_cistatic SANE_Status 1060141cc406Sopenharmony_cigamma_update(SANE_Handle handle) 1061141cc406Sopenharmony_ci{ 1062141cc406Sopenharmony_ciApple_Scanner *s = handle; 1063141cc406Sopenharmony_ci 1064141cc406Sopenharmony_ci 1065141cc406Sopenharmony_ciif (s->hw->ScannerModel == COLORONESCANNER) 1066141cc406Sopenharmony_ci { 1067141cc406Sopenharmony_ci if ( !strcmp(s->val[OPT_MODE].s,SANE_VALUE_SCAN_MODE_GRAY) || 1068141cc406Sopenharmony_ci !strcmp(s->val[OPT_MODE].s,"Gray16") ) 1069141cc406Sopenharmony_ci { 1070141cc406Sopenharmony_ci ENABLE (OPT_CUSTOM_GAMMA); 1071141cc406Sopenharmony_ci if (s->val[OPT_CUSTOM_GAMMA].w) 1072141cc406Sopenharmony_ci { 1073141cc406Sopenharmony_ci ENABLE (OPT_DOWNLOAD_GAMMA); 1074141cc406Sopenharmony_ci if (! strcmp(s->val[OPT_COLOR_SENSOR].s,"All")) 1075141cc406Sopenharmony_ci { 1076141cc406Sopenharmony_ci ENABLE (OPT_GAMMA_VECTOR_R); 1077141cc406Sopenharmony_ci ENABLE (OPT_GAMMA_VECTOR_G); 1078141cc406Sopenharmony_ci ENABLE (OPT_GAMMA_VECTOR_B); 1079141cc406Sopenharmony_ci } 1080141cc406Sopenharmony_ci if (! strcmp(s->val[OPT_COLOR_SENSOR].s,"Red")) 1081141cc406Sopenharmony_ci { 1082141cc406Sopenharmony_ci ENABLE (OPT_GAMMA_VECTOR_R); 1083141cc406Sopenharmony_ci DISABLE(OPT_GAMMA_VECTOR_G); 1084141cc406Sopenharmony_ci DISABLE (OPT_GAMMA_VECTOR_B); 1085141cc406Sopenharmony_ci } 1086141cc406Sopenharmony_ci if (! strcmp(s->val[OPT_COLOR_SENSOR].s,"Green")) 1087141cc406Sopenharmony_ci { 1088141cc406Sopenharmony_ci DISABLE (OPT_GAMMA_VECTOR_R); 1089141cc406Sopenharmony_ci ENABLE (OPT_GAMMA_VECTOR_G); 1090141cc406Sopenharmony_ci DISABLE (OPT_GAMMA_VECTOR_B); 1091141cc406Sopenharmony_ci } 1092141cc406Sopenharmony_ci if (! strcmp(s->val[OPT_COLOR_SENSOR].s,"Blue")) 1093141cc406Sopenharmony_ci { 1094141cc406Sopenharmony_ci DISABLE (OPT_GAMMA_VECTOR_R); 1095141cc406Sopenharmony_ci DISABLE (OPT_GAMMA_VECTOR_G); 1096141cc406Sopenharmony_ci ENABLE (OPT_GAMMA_VECTOR_B); 1097141cc406Sopenharmony_ci } 1098141cc406Sopenharmony_ci } 1099141cc406Sopenharmony_ci else /* Not custom gamma */ 1100141cc406Sopenharmony_ci { 1101141cc406Sopenharmony_ci goto discustom; 1102141cc406Sopenharmony_ci } 1103141cc406Sopenharmony_ci } 1104141cc406Sopenharmony_ci else if (!strcmp(s->val[OPT_MODE].s,SANE_VALUE_SCAN_MODE_COLOR)) 1105141cc406Sopenharmony_ci { 1106141cc406Sopenharmony_ci ENABLE (OPT_CUSTOM_GAMMA); 1107141cc406Sopenharmony_ci if (s->val[OPT_CUSTOM_GAMMA].w) 1108141cc406Sopenharmony_ci { 1109141cc406Sopenharmony_ci ENABLE (OPT_DOWNLOAD_GAMMA); 1110141cc406Sopenharmony_ci ENABLE (OPT_GAMMA_VECTOR_R); 1111141cc406Sopenharmony_ci ENABLE (OPT_GAMMA_VECTOR_G); 1112141cc406Sopenharmony_ci ENABLE (OPT_GAMMA_VECTOR_B); 1113141cc406Sopenharmony_ci } 1114141cc406Sopenharmony_ci else /* Not custom gamma */ 1115141cc406Sopenharmony_ci { 1116141cc406Sopenharmony_ci goto discustom; 1117141cc406Sopenharmony_ci } 1118141cc406Sopenharmony_ci } 1119141cc406Sopenharmony_ci else /* Not Gamma capable mode */ 1120141cc406Sopenharmony_ci { 1121141cc406Sopenharmony_ci goto disall; 1122141cc406Sopenharmony_ci } 1123141cc406Sopenharmony_ci } /* Not Gamma capable Scanner */ 1124141cc406Sopenharmony_cielse 1125141cc406Sopenharmony_ci { 1126141cc406Sopenharmony_cidisall: 1127141cc406Sopenharmony_ci DISABLE (OPT_CUSTOM_GAMMA); 1128141cc406Sopenharmony_cidiscustom: 1129141cc406Sopenharmony_ci DISABLE (OPT_GAMMA_VECTOR_R); 1130141cc406Sopenharmony_ci DISABLE (OPT_GAMMA_VECTOR_G); 1131141cc406Sopenharmony_ci DISABLE (OPT_GAMMA_VECTOR_B); 1132141cc406Sopenharmony_ci DISABLE (OPT_DOWNLOAD_GAMMA); 1133141cc406Sopenharmony_ci } 1134141cc406Sopenharmony_ci 1135141cc406Sopenharmony_cireturn SANE_STATUS_GOOD; 1136141cc406Sopenharmony_ci} 1137141cc406Sopenharmony_ci 1138141cc406Sopenharmony_ci 1139141cc406Sopenharmony_cistatic SANE_Status 1140141cc406Sopenharmony_cimode_update (SANE_Handle handle, char *val) 1141141cc406Sopenharmony_ci{ 1142141cc406Sopenharmony_ci Apple_Scanner *s = handle; 1143141cc406Sopenharmony_ci SANE_Bool cct=SANE_FALSE; 1144141cc406Sopenharmony_ci SANE_Bool UseThreshold=SANE_FALSE; 1145141cc406Sopenharmony_ci 1146141cc406Sopenharmony_ci DISABLE(OPT_COLOR_SENSOR); 1147141cc406Sopenharmony_ci 1148141cc406Sopenharmony_ci if (!strcmp (val, SANE_VALUE_SCAN_MODE_LINEART)) 1149141cc406Sopenharmony_ci { 1150141cc406Sopenharmony_ci if (s->hw->ScannerModel == APPLESCANNER) 1151141cc406Sopenharmony_ci ENABLE (OPT_AUTOBACKGROUND); 1152141cc406Sopenharmony_ci else 1153141cc406Sopenharmony_ci DISABLE (OPT_AUTOBACKGROUND); 1154141cc406Sopenharmony_ci DISABLE (OPT_HALFTONE_PATTERN); 1155141cc406Sopenharmony_ci 1156141cc406Sopenharmony_ci UseThreshold=SANE_TRUE; 1157141cc406Sopenharmony_ci } 1158141cc406Sopenharmony_ci else if (!strcmp (val, SANE_VALUE_SCAN_MODE_HALFTONE)) 1159141cc406Sopenharmony_ci { 1160141cc406Sopenharmony_ci DISABLE (OPT_AUTOBACKGROUND); 1161141cc406Sopenharmony_ci ENABLE (OPT_HALFTONE_PATTERN); 1162141cc406Sopenharmony_ci } 1163141cc406Sopenharmony_ci else if (!strcmp (val, "Gray16") || !strcmp (val, SANE_VALUE_SCAN_MODE_GRAY)) 1164141cc406Sopenharmony_ci { 1165141cc406Sopenharmony_ci DISABLE (OPT_AUTOBACKGROUND); 1166141cc406Sopenharmony_ci DISABLE (OPT_HALFTONE_PATTERN); 1167141cc406Sopenharmony_ci if (s->hw->ScannerModel == COLORONESCANNER) 1168141cc406Sopenharmony_ci ENABLE(OPT_COLOR_SENSOR); 1169141cc406Sopenharmony_ci 1170141cc406Sopenharmony_ci } /* End of Gray */ 1171141cc406Sopenharmony_ci else if (!strcmp (val, "BiColor")) 1172141cc406Sopenharmony_ci { 1173141cc406Sopenharmony_ci DISABLE (OPT_AUTOBACKGROUND); 1174141cc406Sopenharmony_ci DISABLE (OPT_HALFTONE_PATTERN); 1175141cc406Sopenharmony_ci UseThreshold=SANE_TRUE; 1176141cc406Sopenharmony_ci } 1177141cc406Sopenharmony_ci else if (!strcmp (val, SANE_VALUE_SCAN_MODE_COLOR)) 1178141cc406Sopenharmony_ci { 1179141cc406Sopenharmony_ci DISABLE (OPT_AUTOBACKGROUND); 1180141cc406Sopenharmony_ci DISABLE (OPT_HALFTONE_PATTERN); 1181141cc406Sopenharmony_ci cct=SANE_TRUE; 1182141cc406Sopenharmony_ci } 1183141cc406Sopenharmony_ci else 1184141cc406Sopenharmony_ci { 1185141cc406Sopenharmony_ci DBG (ERROR_MESSAGE, "Invalid mode %s\n", (char *) val); 1186141cc406Sopenharmony_ci return SANE_STATUS_INVAL; 1187141cc406Sopenharmony_ci } 1188141cc406Sopenharmony_ci 1189141cc406Sopenharmony_ci/* Second hand dependencies of mode option */ 1190141cc406Sopenharmony_ci/* Looks like code doubling */ 1191141cc406Sopenharmony_ci 1192141cc406Sopenharmony_ci 1193141cc406Sopenharmony_ci if (UseThreshold) 1194141cc406Sopenharmony_ci { 1195141cc406Sopenharmony_ci DISABLE (OPT_BRIGHTNESS); 1196141cc406Sopenharmony_ci DISABLE (OPT_CONTRAST); 1197141cc406Sopenharmony_ci DISABLE (OPT_VOLT_REF); 1198141cc406Sopenharmony_ci DISABLE (OPT_VOLT_REF_TOP); 1199141cc406Sopenharmony_ci DISABLE (OPT_VOLT_REF_BOTTOM); 1200141cc406Sopenharmony_ci 1201141cc406Sopenharmony_ci if (IS_ACTIVE (OPT_AUTOBACKGROUND) && s->val[OPT_AUTOBACKGROUND].w) 1202141cc406Sopenharmony_ci { 1203141cc406Sopenharmony_ci DISABLE (OPT_THRESHOLD); 1204141cc406Sopenharmony_ci ENABLE (OPT_AUTOBACKGROUND_THRESHOLD); 1205141cc406Sopenharmony_ci } 1206141cc406Sopenharmony_ci else 1207141cc406Sopenharmony_ci { 1208141cc406Sopenharmony_ci ENABLE (OPT_THRESHOLD); 1209141cc406Sopenharmony_ci DISABLE (OPT_AUTOBACKGROUND_THRESHOLD); 1210141cc406Sopenharmony_ci } 1211141cc406Sopenharmony_ci } 1212141cc406Sopenharmony_ci else 1213141cc406Sopenharmony_ci { 1214141cc406Sopenharmony_ci DISABLE (OPT_THRESHOLD); 1215141cc406Sopenharmony_ci DISABLE (OPT_AUTOBACKGROUND_THRESHOLD); 1216141cc406Sopenharmony_ci 1217141cc406Sopenharmony_ci if (s->hw->ScannerModel == COLORONESCANNER) 1218141cc406Sopenharmony_ci { 1219141cc406Sopenharmony_ci ENABLE (OPT_VOLT_REF); 1220141cc406Sopenharmony_ci if (s->val[OPT_VOLT_REF].w) 1221141cc406Sopenharmony_ci { 1222141cc406Sopenharmony_ci ENABLE (OPT_VOLT_REF_TOP); 1223141cc406Sopenharmony_ci ENABLE (OPT_VOLT_REF_BOTTOM); 1224141cc406Sopenharmony_ci DISABLE (OPT_BRIGHTNESS); 1225141cc406Sopenharmony_ci DISABLE (OPT_CONTRAST); 1226141cc406Sopenharmony_ci } 1227141cc406Sopenharmony_ci else 1228141cc406Sopenharmony_ci { 1229141cc406Sopenharmony_ci DISABLE (OPT_VOLT_REF_TOP); 1230141cc406Sopenharmony_ci DISABLE (OPT_VOLT_REF_BOTTOM); 1231141cc406Sopenharmony_ci ENABLE (OPT_BRIGHTNESS); 1232141cc406Sopenharmony_ci ENABLE (OPT_CONTRAST); 1233141cc406Sopenharmony_ci } 1234141cc406Sopenharmony_ci } 1235141cc406Sopenharmony_ci else 1236141cc406Sopenharmony_ci { 1237141cc406Sopenharmony_ci ENABLE (OPT_BRIGHTNESS); 1238141cc406Sopenharmony_ci ENABLE (OPT_CONTRAST); 1239141cc406Sopenharmony_ci } 1240141cc406Sopenharmony_ci } 1241141cc406Sopenharmony_ci 1242141cc406Sopenharmony_ci 1243141cc406Sopenharmony_ci if (IS_ACTIVE (OPT_HALFTONE_PATTERN) && 1244141cc406Sopenharmony_ci !strcmp (s->val[OPT_HALFTONE_PATTERN].s, "download")) 1245141cc406Sopenharmony_ci ENABLE (OPT_HALFTONE_FILE); 1246141cc406Sopenharmony_ci else 1247141cc406Sopenharmony_ci DISABLE (OPT_HALFTONE_FILE); 1248141cc406Sopenharmony_ci 1249141cc406Sopenharmony_ci if (cct) 1250141cc406Sopenharmony_ci ENABLE (OPT_CUSTOM_CCT); 1251141cc406Sopenharmony_ci else 1252141cc406Sopenharmony_ci DISABLE (OPT_CUSTOM_CCT); 1253141cc406Sopenharmony_ci 1254141cc406Sopenharmony_ci if (cct && s->val[OPT_CUSTOM_CCT].w) 1255141cc406Sopenharmony_ci { 1256141cc406Sopenharmony_ci ENABLE(OPT_CCT); 1257141cc406Sopenharmony_ci ENABLE(OPT_DOWNLOAD_CCT); 1258141cc406Sopenharmony_ci } 1259141cc406Sopenharmony_ci else 1260141cc406Sopenharmony_ci { 1261141cc406Sopenharmony_ci DISABLE(OPT_CCT); 1262141cc406Sopenharmony_ci DISABLE(OPT_DOWNLOAD_CCT); 1263141cc406Sopenharmony_ci } 1264141cc406Sopenharmony_ci 1265141cc406Sopenharmony_ci 1266141cc406Sopenharmony_ci gamma_update (s); 1267141cc406Sopenharmony_ci calc_parameters (s); 1268141cc406Sopenharmony_ci 1269141cc406Sopenharmony_ci return SANE_STATUS_GOOD; 1270141cc406Sopenharmony_ci 1271141cc406Sopenharmony_ci} 1272141cc406Sopenharmony_ci 1273141cc406Sopenharmony_ci 1274141cc406Sopenharmony_ci 1275141cc406Sopenharmony_ci 1276141cc406Sopenharmony_cistatic SANE_Status 1277141cc406Sopenharmony_ciinit_options (Apple_Scanner * s) 1278141cc406Sopenharmony_ci{ 1279141cc406Sopenharmony_ci int i; 1280141cc406Sopenharmony_ci 1281141cc406Sopenharmony_ci memset (s->opt, 0, sizeof (s->opt)); 1282141cc406Sopenharmony_ci memset (s->val, 0, sizeof (s->val)); 1283141cc406Sopenharmony_ci 1284141cc406Sopenharmony_ci for (i = 0; i < NUM_OPTIONS; ++i) 1285141cc406Sopenharmony_ci { 1286141cc406Sopenharmony_ci s->opt[i].size = sizeof (SANE_Word); 1287141cc406Sopenharmony_ci s->opt[i].cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT; 1288141cc406Sopenharmony_ci } 1289141cc406Sopenharmony_ci 1290141cc406Sopenharmony_ci s->opt[OPT_NUM_OPTS].title = SANE_TITLE_NUM_OPTIONS; 1291141cc406Sopenharmony_ci s->opt[OPT_NUM_OPTS].desc = SANE_DESC_NUM_OPTIONS; 1292141cc406Sopenharmony_ci s->opt[OPT_NUM_OPTS].type = SANE_TYPE_INT; 1293141cc406Sopenharmony_ci s->opt[OPT_NUM_OPTS].cap = SANE_CAP_SOFT_DETECT; 1294141cc406Sopenharmony_ci s->val[OPT_NUM_OPTS].w = NUM_OPTIONS; 1295141cc406Sopenharmony_ci 1296141cc406Sopenharmony_ci /* Hardware detect Information group: */ 1297141cc406Sopenharmony_ci 1298141cc406Sopenharmony_ci s->opt[OPT_HWDETECT_GROUP].title = "Hardware"; 1299141cc406Sopenharmony_ci s->opt[OPT_HWDETECT_GROUP].desc = "Detected during hardware probing"; 1300141cc406Sopenharmony_ci s->opt[OPT_HWDETECT_GROUP].type = SANE_TYPE_GROUP; 1301141cc406Sopenharmony_ci s->opt[OPT_HWDETECT_GROUP].cap = 0; 1302141cc406Sopenharmony_ci s->opt[OPT_HWDETECT_GROUP].constraint_type = SANE_CONSTRAINT_NONE; 1303141cc406Sopenharmony_ci 1304141cc406Sopenharmony_ci s->opt[OPT_MODEL].name = "model"; 1305141cc406Sopenharmony_ci s->opt[OPT_MODEL].title = "Model"; 1306141cc406Sopenharmony_ci s->opt[OPT_MODEL].desc = "Model and capabilities"; 1307141cc406Sopenharmony_ci s->opt[OPT_MODEL].type = SANE_TYPE_STRING; 1308141cc406Sopenharmony_ci s->opt[OPT_MODEL].cap = SANE_CAP_SOFT_DETECT; 1309141cc406Sopenharmony_ci s->opt[OPT_MODEL].constraint_type = SANE_CONSTRAINT_NONE; 1310141cc406Sopenharmony_ci s->opt[OPT_MODEL].size = max_string_size (SupportedModel); 1311141cc406Sopenharmony_ci s->val[OPT_MODEL].s = strdup (SupportedModel[s->hw->ScannerModel]); 1312141cc406Sopenharmony_ci 1313141cc406Sopenharmony_ci 1314141cc406Sopenharmony_ci /* "Mode" group: */ 1315141cc406Sopenharmony_ci 1316141cc406Sopenharmony_ci s->opt[OPT_MODE_GROUP].title = "Scan Mode"; 1317141cc406Sopenharmony_ci s->opt[OPT_MODE_GROUP].desc = ""; 1318141cc406Sopenharmony_ci s->opt[OPT_MODE_GROUP].type = SANE_TYPE_GROUP; 1319141cc406Sopenharmony_ci s->opt[OPT_MODE_GROUP].cap = 0; 1320141cc406Sopenharmony_ci s->opt[OPT_MODE_GROUP].constraint_type = SANE_CONSTRAINT_NONE; 1321141cc406Sopenharmony_ci 1322141cc406Sopenharmony_ci halftone_pattern_list[0]="spiral4x4"; 1323141cc406Sopenharmony_ci halftone_pattern_list[1]="bayer4x4"; 1324141cc406Sopenharmony_ci halftone_pattern_list[2]="download"; 1325141cc406Sopenharmony_ci halftone_pattern_list[3]=NULL; 1326141cc406Sopenharmony_ci 1327141cc406Sopenharmony_ci 1328141cc406Sopenharmony_ci switch (s->hw->ScannerModel) 1329141cc406Sopenharmony_ci { 1330141cc406Sopenharmony_ci case APPLESCANNER: 1331141cc406Sopenharmony_ci mode_list[0]=SANE_VALUE_SCAN_MODE_LINEART; 1332141cc406Sopenharmony_ci mode_list[1]=SANE_VALUE_SCAN_MODE_HALFTONE; 1333141cc406Sopenharmony_ci mode_list[2]="Gray16"; 1334141cc406Sopenharmony_ci mode_list[3]=NULL; 1335141cc406Sopenharmony_ci break; 1336141cc406Sopenharmony_ci case ONESCANNER: 1337141cc406Sopenharmony_ci mode_list[0]=SANE_VALUE_SCAN_MODE_LINEART; 1338141cc406Sopenharmony_ci mode_list[1]=SANE_VALUE_SCAN_MODE_HALFTONE; 1339141cc406Sopenharmony_ci mode_list[2]="Gray16"; 1340141cc406Sopenharmony_ci mode_list[3]=SANE_VALUE_SCAN_MODE_GRAY; 1341141cc406Sopenharmony_ci mode_list[4]=NULL; 1342141cc406Sopenharmony_ci halftone_pattern_list[3]="spiral8x8"; 1343141cc406Sopenharmony_ci halftone_pattern_list[4]="bayer8x8"; 1344141cc406Sopenharmony_ci halftone_pattern_list[5]=NULL; 1345141cc406Sopenharmony_ci break; 1346141cc406Sopenharmony_ci case COLORONESCANNER: 1347141cc406Sopenharmony_ci mode_list[0]=SANE_VALUE_SCAN_MODE_LINEART; 1348141cc406Sopenharmony_ci mode_list[1]="Gray16"; 1349141cc406Sopenharmony_ci mode_list[2]=SANE_VALUE_SCAN_MODE_GRAY; 1350141cc406Sopenharmony_ci mode_list[3]="BiColor"; 1351141cc406Sopenharmony_ci mode_list[4]=SANE_VALUE_SCAN_MODE_COLOR; 1352141cc406Sopenharmony_ci mode_list[5]=NULL; 1353141cc406Sopenharmony_ci break; 1354141cc406Sopenharmony_ci default: 1355141cc406Sopenharmony_ci break; 1356141cc406Sopenharmony_ci } 1357141cc406Sopenharmony_ci 1358141cc406Sopenharmony_ci 1359141cc406Sopenharmony_ci /* scan mode */ 1360141cc406Sopenharmony_ci s->opt[OPT_MODE].name = SANE_NAME_SCAN_MODE; 1361141cc406Sopenharmony_ci s->opt[OPT_MODE].title = SANE_TITLE_SCAN_MODE; 1362141cc406Sopenharmony_ci s->opt[OPT_MODE].desc = SANE_DESC_SCAN_MODE; 1363141cc406Sopenharmony_ci s->opt[OPT_MODE].type = SANE_TYPE_STRING; 1364141cc406Sopenharmony_ci s->opt[OPT_MODE].constraint_type = SANE_CONSTRAINT_STRING_LIST; 1365141cc406Sopenharmony_ci s->opt[OPT_MODE].size = max_string_size (mode_list); 1366141cc406Sopenharmony_ci s->opt[OPT_MODE].constraint.string_list = mode_list; 1367141cc406Sopenharmony_ci s->val[OPT_MODE].s = strdup (mode_list[0]); 1368141cc406Sopenharmony_ci 1369141cc406Sopenharmony_ci 1370141cc406Sopenharmony_ci /* resolution */ 1371141cc406Sopenharmony_ci s->opt[OPT_RESOLUTION].name = SANE_NAME_SCAN_RESOLUTION; 1372141cc406Sopenharmony_ci s->opt[OPT_RESOLUTION].title = SANE_TITLE_SCAN_RESOLUTION; 1373141cc406Sopenharmony_ci s->opt[OPT_RESOLUTION].desc = SANE_DESC_SCAN_RESOLUTION; 1374141cc406Sopenharmony_ci s->opt[OPT_RESOLUTION].type = SANE_TYPE_INT; 1375141cc406Sopenharmony_ci s->opt[OPT_RESOLUTION].unit = SANE_UNIT_DPI; 1376141cc406Sopenharmony_ci/* TODO: Build the constraints on resolution in a smart way */ 1377141cc406Sopenharmony_ci s->opt[OPT_RESOLUTION].constraint_type = SANE_CONSTRAINT_WORD_LIST; 1378141cc406Sopenharmony_ci s->opt[OPT_RESOLUTION].constraint.word_list = resbit_list; 1379141cc406Sopenharmony_ci s->val[OPT_RESOLUTION].w = resbit_list[1]; 1380141cc406Sopenharmony_ci 1381141cc406Sopenharmony_ci /* preview */ 1382141cc406Sopenharmony_ci s->opt[OPT_PREVIEW].name = SANE_NAME_PREVIEW; 1383141cc406Sopenharmony_ci s->opt[OPT_PREVIEW].title = SANE_TITLE_PREVIEW; 1384141cc406Sopenharmony_ci s->opt[OPT_PREVIEW].desc = SANE_DESC_PREVIEW; 1385141cc406Sopenharmony_ci s->opt[OPT_PREVIEW].cap = SANE_CAP_SOFT_DETECT | SANE_CAP_SOFT_SELECT; 1386141cc406Sopenharmony_ci s->opt[OPT_PREVIEW].type = SANE_TYPE_BOOL; 1387141cc406Sopenharmony_ci s->val[OPT_PREVIEW].w = SANE_FALSE; 1388141cc406Sopenharmony_ci 1389141cc406Sopenharmony_ci /* "Geometry" group: */ 1390141cc406Sopenharmony_ci s->opt[OPT_GEOMETRY_GROUP].title = "Geometry"; 1391141cc406Sopenharmony_ci s->opt[OPT_GEOMETRY_GROUP].desc = ""; 1392141cc406Sopenharmony_ci s->opt[OPT_GEOMETRY_GROUP].type = SANE_TYPE_GROUP; 1393141cc406Sopenharmony_ci s->opt[OPT_GEOMETRY_GROUP].cap = SANE_CAP_ADVANCED; 1394141cc406Sopenharmony_ci s->opt[OPT_GEOMETRY_GROUP].constraint_type = SANE_CONSTRAINT_NONE; 1395141cc406Sopenharmony_ci 1396141cc406Sopenharmony_ci /* top-left x */ 1397141cc406Sopenharmony_ci s->opt[OPT_TL_X].name = SANE_NAME_SCAN_TL_X; 1398141cc406Sopenharmony_ci s->opt[OPT_TL_X].title = SANE_TITLE_SCAN_TL_X; 1399141cc406Sopenharmony_ci s->opt[OPT_TL_X].desc = SANE_DESC_SCAN_TL_X; 1400141cc406Sopenharmony_ci s->opt[OPT_TL_X].type = SANE_TYPE_FIXED; 1401141cc406Sopenharmony_ci s->opt[OPT_TL_X].unit = SANE_UNIT_MM; 1402141cc406Sopenharmony_ci s->opt[OPT_TL_X].constraint_type = SANE_CONSTRAINT_RANGE; 1403141cc406Sopenharmony_ci s->opt[OPT_TL_X].constraint.range = &s->hw->x_range; 1404141cc406Sopenharmony_ci s->val[OPT_TL_X].w = 0; 1405141cc406Sopenharmony_ci 1406141cc406Sopenharmony_ci /* top-left y */ 1407141cc406Sopenharmony_ci s->opt[OPT_TL_Y].name = SANE_NAME_SCAN_TL_Y; 1408141cc406Sopenharmony_ci s->opt[OPT_TL_Y].title = SANE_TITLE_SCAN_TL_Y; 1409141cc406Sopenharmony_ci s->opt[OPT_TL_Y].desc = SANE_DESC_SCAN_TL_Y; 1410141cc406Sopenharmony_ci s->opt[OPT_TL_Y].type = SANE_TYPE_FIXED; 1411141cc406Sopenharmony_ci s->opt[OPT_TL_Y].unit = SANE_UNIT_MM; 1412141cc406Sopenharmony_ci s->opt[OPT_TL_Y].constraint_type = SANE_CONSTRAINT_RANGE; 1413141cc406Sopenharmony_ci s->opt[OPT_TL_Y].constraint.range = &s->hw->y_range; 1414141cc406Sopenharmony_ci s->val[OPT_TL_Y].w = 0; 1415141cc406Sopenharmony_ci 1416141cc406Sopenharmony_ci /* bottom-right x */ 1417141cc406Sopenharmony_ci s->opt[OPT_BR_X].name = SANE_NAME_SCAN_BR_X; 1418141cc406Sopenharmony_ci s->opt[OPT_BR_X].title = SANE_TITLE_SCAN_BR_X; 1419141cc406Sopenharmony_ci s->opt[OPT_BR_X].desc = SANE_DESC_SCAN_BR_X; 1420141cc406Sopenharmony_ci s->opt[OPT_BR_X].type = SANE_TYPE_FIXED; 1421141cc406Sopenharmony_ci s->opt[OPT_BR_X].unit = SANE_UNIT_MM; 1422141cc406Sopenharmony_ci s->opt[OPT_BR_X].constraint_type = SANE_CONSTRAINT_RANGE; 1423141cc406Sopenharmony_ci s->opt[OPT_BR_X].constraint.range = &s->hw->x_range; 1424141cc406Sopenharmony_ci s->val[OPT_BR_X].w = s->hw->x_range.max; 1425141cc406Sopenharmony_ci 1426141cc406Sopenharmony_ci /* bottom-right y */ 1427141cc406Sopenharmony_ci s->opt[OPT_BR_Y].name = SANE_NAME_SCAN_BR_Y; 1428141cc406Sopenharmony_ci s->opt[OPT_BR_Y].title = SANE_TITLE_SCAN_BR_Y; 1429141cc406Sopenharmony_ci s->opt[OPT_BR_Y].desc = SANE_DESC_SCAN_BR_Y; 1430141cc406Sopenharmony_ci s->opt[OPT_BR_Y].type = SANE_TYPE_FIXED; 1431141cc406Sopenharmony_ci s->opt[OPT_BR_Y].unit = SANE_UNIT_MM; 1432141cc406Sopenharmony_ci s->opt[OPT_BR_Y].constraint_type = SANE_CONSTRAINT_RANGE; 1433141cc406Sopenharmony_ci s->opt[OPT_BR_Y].constraint.range = &s->hw->y_range; 1434141cc406Sopenharmony_ci s->val[OPT_BR_Y].w = s->hw->y_range.max; 1435141cc406Sopenharmony_ci 1436141cc406Sopenharmony_ci 1437141cc406Sopenharmony_ci /* "Enhancement" group: */ 1438141cc406Sopenharmony_ci 1439141cc406Sopenharmony_ci s->opt[OPT_ENHANCEMENT_GROUP].title = "Enhancement"; 1440141cc406Sopenharmony_ci s->opt[OPT_ENHANCEMENT_GROUP].desc = ""; 1441141cc406Sopenharmony_ci s->opt[OPT_ENHANCEMENT_GROUP].type = SANE_TYPE_GROUP; 1442141cc406Sopenharmony_ci s->opt[OPT_ENHANCEMENT_GROUP].cap = 0; 1443141cc406Sopenharmony_ci s->opt[OPT_ENHANCEMENT_GROUP].constraint_type = SANE_CONSTRAINT_NONE; 1444141cc406Sopenharmony_ci 1445141cc406Sopenharmony_ci /* brightness */ 1446141cc406Sopenharmony_ci s->opt[OPT_BRIGHTNESS].name = SANE_NAME_BRIGHTNESS; 1447141cc406Sopenharmony_ci s->opt[OPT_BRIGHTNESS].title = SANE_TITLE_BRIGHTNESS; 1448141cc406Sopenharmony_ci s->opt[OPT_BRIGHTNESS].desc = SANE_DESC_BRIGHTNESS; 1449141cc406Sopenharmony_ci s->opt[OPT_BRIGHTNESS].type = SANE_TYPE_INT; 1450141cc406Sopenharmony_ci s->opt[OPT_BRIGHTNESS].unit = SANE_UNIT_NONE; 1451141cc406Sopenharmony_ci s->opt[OPT_BRIGHTNESS].constraint_type = SANE_CONSTRAINT_RANGE; 1452141cc406Sopenharmony_ci s->opt[OPT_BRIGHTNESS].constraint.range = &byte_range; 1453141cc406Sopenharmony_ci s->val[OPT_BRIGHTNESS].w = 128; 1454141cc406Sopenharmony_ci 1455141cc406Sopenharmony_ci /* contrast */ 1456141cc406Sopenharmony_ci s->opt[OPT_CONTRAST].name = SANE_NAME_CONTRAST; 1457141cc406Sopenharmony_ci s->opt[OPT_CONTRAST].title = SANE_TITLE_CONTRAST; 1458141cc406Sopenharmony_ci s->opt[OPT_CONTRAST].desc = SANE_DESC_CONTRAST 1459141cc406Sopenharmony_ci " This option is active for halftone/Grayscale modes only."; 1460141cc406Sopenharmony_ci s->opt[OPT_CONTRAST].type = SANE_TYPE_INT; 1461141cc406Sopenharmony_ci s->opt[OPT_CONTRAST].unit = SANE_UNIT_NONE; 1462141cc406Sopenharmony_ci s->opt[OPT_CONTRAST].constraint_type = SANE_CONSTRAINT_RANGE; 1463141cc406Sopenharmony_ci s->opt[OPT_CONTRAST].constraint.range = &byte_range; 1464141cc406Sopenharmony_ci s->val[OPT_CONTRAST].w = 1; 1465141cc406Sopenharmony_ci 1466141cc406Sopenharmony_ci /* threshold */ 1467141cc406Sopenharmony_ci s->opt[OPT_THRESHOLD].name = SANE_NAME_THRESHOLD; 1468141cc406Sopenharmony_ci s->opt[OPT_THRESHOLD].title = SANE_TITLE_THRESHOLD; 1469141cc406Sopenharmony_ci s->opt[OPT_THRESHOLD].desc = SANE_DESC_THRESHOLD; 1470141cc406Sopenharmony_ci s->opt[OPT_THRESHOLD].type = SANE_TYPE_INT; 1471141cc406Sopenharmony_ci s->opt[OPT_THRESHOLD].unit = SANE_UNIT_NONE; 1472141cc406Sopenharmony_ci s->opt[OPT_THRESHOLD].constraint_type = SANE_CONSTRAINT_RANGE; 1473141cc406Sopenharmony_ci s->opt[OPT_THRESHOLD].constraint.range = &byte_range; 1474141cc406Sopenharmony_ci s->val[OPT_THRESHOLD].w = 128; 1475141cc406Sopenharmony_ci 1476141cc406Sopenharmony_ci /* AppleScanner Only options */ 1477141cc406Sopenharmony_ci 1478141cc406Sopenharmony_ci /* GrayMap Enhance */ 1479141cc406Sopenharmony_ci s->opt[OPT_GRAYMAP].name = "graymap"; 1480141cc406Sopenharmony_ci s->opt[OPT_GRAYMAP].title = "GrayMap"; 1481141cc406Sopenharmony_ci s->opt[OPT_GRAYMAP].desc = "Fixed Gamma Enhancing"; 1482141cc406Sopenharmony_ci s->opt[OPT_GRAYMAP].type = SANE_TYPE_STRING; 1483141cc406Sopenharmony_ci s->opt[OPT_GRAYMAP].constraint_type = SANE_CONSTRAINT_STRING_LIST; 1484141cc406Sopenharmony_ci if (s->hw->ScannerModel != APPLESCANNER) 1485141cc406Sopenharmony_ci s->opt[OPT_GRAYMAP].cap |= SANE_CAP_INACTIVE; 1486141cc406Sopenharmony_ci s->opt[OPT_GRAYMAP].constraint.string_list = graymap_list; 1487141cc406Sopenharmony_ci s->opt[OPT_GRAYMAP].size = max_string_size (graymap_list); 1488141cc406Sopenharmony_ci s->val[OPT_GRAYMAP].s = strdup (graymap_list[1]); 1489141cc406Sopenharmony_ci 1490141cc406Sopenharmony_ci /* Enable auto background adjustment */ 1491141cc406Sopenharmony_ci s->opt[OPT_AUTOBACKGROUND].name = "abj"; 1492141cc406Sopenharmony_ci s->opt[OPT_AUTOBACKGROUND].title = "Use Auto Background Adjustment"; 1493141cc406Sopenharmony_ci s->opt[OPT_AUTOBACKGROUND].desc = 1494141cc406Sopenharmony_ci "Enables/Disables the Auto Background Adjustment feature"; 1495141cc406Sopenharmony_ci if (strcmp (s->val[OPT_MODE].s, SANE_VALUE_SCAN_MODE_LINEART) 1496141cc406Sopenharmony_ci || (s->hw->ScannerModel != APPLESCANNER)) 1497141cc406Sopenharmony_ci DISABLE (OPT_AUTOBACKGROUND); 1498141cc406Sopenharmony_ci s->opt[OPT_AUTOBACKGROUND].type = SANE_TYPE_BOOL; 1499141cc406Sopenharmony_ci s->val[OPT_AUTOBACKGROUND].w = SANE_FALSE; 1500141cc406Sopenharmony_ci 1501141cc406Sopenharmony_ci /* auto background adjustment threshold */ 1502141cc406Sopenharmony_ci s->opt[OPT_AUTOBACKGROUND_THRESHOLD].name = "abjthreshold"; 1503141cc406Sopenharmony_ci s->opt[OPT_AUTOBACKGROUND_THRESHOLD].title = "Auto Background Adjustment Threshold"; 1504141cc406Sopenharmony_ci s->opt[OPT_AUTOBACKGROUND_THRESHOLD].desc = "Selects the automatically adjustable threshold"; 1505141cc406Sopenharmony_ci s->opt[OPT_AUTOBACKGROUND_THRESHOLD].type = SANE_TYPE_INT; 1506141cc406Sopenharmony_ci s->opt[OPT_AUTOBACKGROUND_THRESHOLD].unit = SANE_UNIT_NONE; 1507141cc406Sopenharmony_ci s->opt[OPT_AUTOBACKGROUND_THRESHOLD].constraint_type = SANE_CONSTRAINT_RANGE; 1508141cc406Sopenharmony_ci 1509141cc406Sopenharmony_ci if (!IS_ACTIVE (OPT_AUTOBACKGROUND) || 1510141cc406Sopenharmony_ci s->val[OPT_AUTOBACKGROUND].w == SANE_FALSE) 1511141cc406Sopenharmony_ci s->opt[OPT_AUTOBACKGROUND_THRESHOLD].cap |= SANE_CAP_INACTIVE; 1512141cc406Sopenharmony_ci 1513141cc406Sopenharmony_ci s->opt[OPT_AUTOBACKGROUND_THRESHOLD].constraint.range = &byte_range; 1514141cc406Sopenharmony_ci s->val[OPT_AUTOBACKGROUND_THRESHOLD].w = 64; 1515141cc406Sopenharmony_ci 1516141cc406Sopenharmony_ci 1517141cc406Sopenharmony_ci /* AppleScanner & OneScanner options */ 1518141cc406Sopenharmony_ci 1519141cc406Sopenharmony_ci /* Select HalfTone Pattern */ 1520141cc406Sopenharmony_ci s->opt[OPT_HALFTONE_PATTERN].name = SANE_NAME_HALFTONE_PATTERN; 1521141cc406Sopenharmony_ci s->opt[OPT_HALFTONE_PATTERN].title = SANE_TITLE_HALFTONE_PATTERN; 1522141cc406Sopenharmony_ci s->opt[OPT_HALFTONE_PATTERN].desc = SANE_DESC_HALFTONE_PATTERN; 1523141cc406Sopenharmony_ci s->opt[OPT_HALFTONE_PATTERN].size = max_string_size (halftone_pattern_list); 1524141cc406Sopenharmony_ci s->opt[OPT_HALFTONE_PATTERN].type = SANE_TYPE_STRING; 1525141cc406Sopenharmony_ci s->opt[OPT_HALFTONE_PATTERN].cap |= SANE_CAP_AUTOMATIC; 1526141cc406Sopenharmony_ci s->opt[OPT_HALFTONE_PATTERN].constraint_type = SANE_CONSTRAINT_STRING_LIST; 1527141cc406Sopenharmony_ci s->opt[OPT_HALFTONE_PATTERN].constraint.string_list = halftone_pattern_list; 1528141cc406Sopenharmony_ci s->val[OPT_HALFTONE_PATTERN].s = strdup (halftone_pattern_list[0]); 1529141cc406Sopenharmony_ci 1530141cc406Sopenharmony_ci if (s->hw->ScannerModel!=APPLESCANNER && s->hw->ScannerModel!=ONESCANNER) 1531141cc406Sopenharmony_ci s->opt[OPT_HALFTONE_PATTERN].cap |= SANE_CAP_INACTIVE; 1532141cc406Sopenharmony_ci 1533141cc406Sopenharmony_ci 1534141cc406Sopenharmony_ci /* halftone pattern file */ 1535141cc406Sopenharmony_ci s->opt[OPT_HALFTONE_FILE].name = "halftone-pattern-file"; 1536141cc406Sopenharmony_ci s->opt[OPT_HALFTONE_FILE].title = "Halftone Pattern File"; 1537141cc406Sopenharmony_ci s->opt[OPT_HALFTONE_FILE].desc = 1538141cc406Sopenharmony_ci "Download and use the specified file as halftone pattern"; 1539141cc406Sopenharmony_ci s->opt[OPT_HALFTONE_FILE].type = SANE_TYPE_STRING; 1540141cc406Sopenharmony_ci s->opt[OPT_HALFTONE_FILE].cap |= SANE_CAP_INACTIVE; 1541141cc406Sopenharmony_ci s->opt[OPT_HALFTONE_FILE].size = 256; 1542141cc406Sopenharmony_ci s->val[OPT_HALFTONE_FILE].s = "halftone.pgm"; 1543141cc406Sopenharmony_ci 1544141cc406Sopenharmony_ci /* Use volt_ref */ 1545141cc406Sopenharmony_ci s->opt[OPT_VOLT_REF].name = "volt-ref"; 1546141cc406Sopenharmony_ci s->opt[OPT_VOLT_REF].title = "Volt Reference"; 1547141cc406Sopenharmony_ci s->opt[OPT_VOLT_REF].desc ="It's brightness equivalent."; 1548141cc406Sopenharmony_ci s->opt[OPT_VOLT_REF].type = SANE_TYPE_BOOL; 1549141cc406Sopenharmony_ci if (s->hw->ScannerModel!=COLORONESCANNER) 1550141cc406Sopenharmony_ci s->opt[OPT_VOLT_REF].cap |= SANE_CAP_INACTIVE; 1551141cc406Sopenharmony_ci s->val[OPT_VOLT_REF].w = SANE_FALSE; 1552141cc406Sopenharmony_ci 1553141cc406Sopenharmony_ci s->opt[OPT_VOLT_REF_TOP].name = "volt-ref-top"; 1554141cc406Sopenharmony_ci s->opt[OPT_VOLT_REF_TOP].title = "Top Voltage Reference"; 1555141cc406Sopenharmony_ci s->opt[OPT_VOLT_REF_TOP].desc = "I really do not know."; 1556141cc406Sopenharmony_ci s->opt[OPT_VOLT_REF_TOP].type = SANE_TYPE_INT; 1557141cc406Sopenharmony_ci s->opt[OPT_VOLT_REF_TOP].unit = SANE_UNIT_NONE; 1558141cc406Sopenharmony_ci if (s->hw->ScannerModel!=COLORONESCANNER || s->val[OPT_VOLT_REF].w==SANE_FALSE) 1559141cc406Sopenharmony_ci s->opt[OPT_VOLT_REF_TOP].cap |= SANE_CAP_INACTIVE; 1560141cc406Sopenharmony_ci s->opt[OPT_VOLT_REF_TOP].constraint_type = SANE_CONSTRAINT_RANGE; 1561141cc406Sopenharmony_ci s->opt[OPT_VOLT_REF_TOP].constraint.range = &byte_range; 1562141cc406Sopenharmony_ci s->val[OPT_VOLT_REF_TOP].w = 255; 1563141cc406Sopenharmony_ci 1564141cc406Sopenharmony_ci s->opt[OPT_VOLT_REF_BOTTOM].name = "volt-ref-bottom"; 1565141cc406Sopenharmony_ci s->opt[OPT_VOLT_REF_BOTTOM].title = "Bottom Voltage Reference"; 1566141cc406Sopenharmony_ci s->opt[OPT_VOLT_REF_BOTTOM].desc = "I really do not know."; 1567141cc406Sopenharmony_ci s->opt[OPT_VOLT_REF_BOTTOM].type = SANE_TYPE_INT; 1568141cc406Sopenharmony_ci s->opt[OPT_VOLT_REF_BOTTOM].unit = SANE_UNIT_NONE; 1569141cc406Sopenharmony_ci if (s->hw->ScannerModel!=COLORONESCANNER || s->val[OPT_VOLT_REF].w==SANE_FALSE) 1570141cc406Sopenharmony_ci s->opt[OPT_VOLT_REF_BOTTOM].cap |= SANE_CAP_INACTIVE; 1571141cc406Sopenharmony_ci s->opt[OPT_VOLT_REF_BOTTOM].constraint_type = SANE_CONSTRAINT_RANGE; 1572141cc406Sopenharmony_ci s->opt[OPT_VOLT_REF_BOTTOM].constraint.range = &byte_range; 1573141cc406Sopenharmony_ci s->val[OPT_VOLT_REF_BOTTOM].w = 1; 1574141cc406Sopenharmony_ci 1575141cc406Sopenharmony_ci/* Misc Functions: Advanced */ 1576141cc406Sopenharmony_ci 1577141cc406Sopenharmony_ci s->opt[OPT_MISC_GROUP].title = "Miscallaneous"; 1578141cc406Sopenharmony_ci s->opt[OPT_MISC_GROUP].desc = ""; 1579141cc406Sopenharmony_ci s->opt[OPT_MISC_GROUP].type = SANE_TYPE_GROUP; 1580141cc406Sopenharmony_ci s->opt[OPT_MISC_GROUP].cap = SANE_CAP_ADVANCED; 1581141cc406Sopenharmony_ci s->opt[OPT_MISC_GROUP].constraint_type = SANE_CONSTRAINT_NONE; 1582141cc406Sopenharmony_ci 1583141cc406Sopenharmony_ci 1584141cc406Sopenharmony_ci /* Turn On lamp during scan: All scanners */ 1585141cc406Sopenharmony_ci s->opt[OPT_LAMP].name = "lamp"; 1586141cc406Sopenharmony_ci s->opt[OPT_LAMP].title = "Lamp"; 1587141cc406Sopenharmony_ci s->opt[OPT_LAMP].desc = "Hold the lamp on during scans."; 1588141cc406Sopenharmony_ci s->opt[OPT_LAMP].type = SANE_TYPE_BOOL; 1589141cc406Sopenharmony_ci s->val[OPT_LAMP].w = SANE_FALSE; 1590141cc406Sopenharmony_ci 1591141cc406Sopenharmony_ci /* AppleScanner Only options */ 1592141cc406Sopenharmony_ci 1593141cc406Sopenharmony_ci /* Wait for button to be pressed before scanning */ 1594141cc406Sopenharmony_ci s->opt[OPT_WAIT].name = "wait"; 1595141cc406Sopenharmony_ci s->opt[OPT_WAIT].title = "Wait"; 1596141cc406Sopenharmony_ci s->opt[OPT_WAIT].desc = "You may issue the scan command but the actual " 1597141cc406Sopenharmony_ci "scan will not start unless you press the button in the front of the " 1598141cc406Sopenharmony_ci "scanner. It is a useful feature when you want to make a network scan (?) " 1599141cc406Sopenharmony_ci "In the mean time you may halt your computer waiting for the SCSI bus " 1600141cc406Sopenharmony_ci "to be free. If this happens just press the scanner button."; 1601141cc406Sopenharmony_ci s->opt[OPT_WAIT].type = SANE_TYPE_BOOL; 1602141cc406Sopenharmony_ci if (s->hw->ScannerModel != APPLESCANNER) 1603141cc406Sopenharmony_ci s->opt[OPT_WAIT].cap |= SANE_CAP_INACTIVE; 1604141cc406Sopenharmony_ci s->val[OPT_WAIT].w = SANE_FALSE; 1605141cc406Sopenharmony_ci 1606141cc406Sopenharmony_ci 1607141cc406Sopenharmony_ci /* OneScanner Only options */ 1608141cc406Sopenharmony_ci 1609141cc406Sopenharmony_ci /* Calibrate before scanning ? */ 1610141cc406Sopenharmony_ci s->opt[OPT_CALIBRATE].name = "calibrate"; 1611141cc406Sopenharmony_ci s->opt[OPT_CALIBRATE].title = "Calibrate"; 1612141cc406Sopenharmony_ci s->opt[OPT_CALIBRATE].desc = "You may avoid the calibration before " 1613141cc406Sopenharmony_ci "scanning but this will lead you to lower image quality."; 1614141cc406Sopenharmony_ci s->opt[OPT_CALIBRATE].type = SANE_TYPE_BOOL; 1615141cc406Sopenharmony_ci if (s->hw->ScannerModel != ONESCANNER) 1616141cc406Sopenharmony_ci s->opt[OPT_CALIBRATE].cap |= SANE_CAP_INACTIVE; 1617141cc406Sopenharmony_ci s->val[OPT_CALIBRATE].w = SANE_TRUE; 1618141cc406Sopenharmony_ci 1619141cc406Sopenharmony_ci /* speed */ 1620141cc406Sopenharmony_ci s->opt[OPT_SPEED].name = SANE_NAME_SCAN_SPEED; 1621141cc406Sopenharmony_ci s->opt[OPT_SPEED].title = SANE_TITLE_SCAN_SPEED; 1622141cc406Sopenharmony_ci s->opt[OPT_SPEED].desc = SANE_DESC_SCAN_SPEED; 1623141cc406Sopenharmony_ci s->opt[OPT_SPEED].type = SANE_TYPE_STRING; 1624141cc406Sopenharmony_ci if (s->hw->ScannerModel != ONESCANNER) 1625141cc406Sopenharmony_ci s->opt[OPT_SPEED].cap |= SANE_CAP_INACTIVE; 1626141cc406Sopenharmony_ci s->opt[OPT_SPEED].size = max_string_size (speed_list); 1627141cc406Sopenharmony_ci s->opt[OPT_SPEED].constraint_type = SANE_CONSTRAINT_STRING_LIST; 1628141cc406Sopenharmony_ci s->opt[OPT_SPEED].constraint.string_list = speed_list; 1629141cc406Sopenharmony_ci s->val[OPT_SPEED].s = strdup (speed_list[0]); 1630141cc406Sopenharmony_ci 1631141cc406Sopenharmony_ci /* OneScanner & ColorOneScanner (LED && CCD) */ 1632141cc406Sopenharmony_ci 1633141cc406Sopenharmony_ci /* LED ? */ 1634141cc406Sopenharmony_ci s->opt[OPT_LED].name = "led"; 1635141cc406Sopenharmony_ci s->opt[OPT_LED].title = "LED"; 1636141cc406Sopenharmony_ci s->opt[OPT_LED].desc ="This option controls the setting of the ambler LED."; 1637141cc406Sopenharmony_ci s->opt[OPT_LED].type = SANE_TYPE_BOOL; 1638141cc406Sopenharmony_ci if (s->hw->ScannerModel!=ONESCANNER && s->hw->ScannerModel!=COLORONESCANNER) 1639141cc406Sopenharmony_ci s->opt[OPT_LED].cap |= SANE_CAP_INACTIVE; 1640141cc406Sopenharmony_ci s->val[OPT_LED].w = SANE_TRUE; 1641141cc406Sopenharmony_ci 1642141cc406Sopenharmony_ci /* CCD Power ? */ 1643141cc406Sopenharmony_ci s->opt[OPT_CCD].name = "ccd"; 1644141cc406Sopenharmony_ci s->opt[OPT_CCD].title = "CCD Power"; 1645141cc406Sopenharmony_ci s->opt[OPT_CCD].desc ="This option controls the power to the CCD array."; 1646141cc406Sopenharmony_ci s->opt[OPT_CCD].type = SANE_TYPE_BOOL; 1647141cc406Sopenharmony_ci if (s->hw->ScannerModel!=ONESCANNER && s->hw->ScannerModel!=COLORONESCANNER) 1648141cc406Sopenharmony_ci s->opt[OPT_CCD].cap |= SANE_CAP_INACTIVE; 1649141cc406Sopenharmony_ci s->val[OPT_CCD].w = SANE_TRUE; 1650141cc406Sopenharmony_ci 1651141cc406Sopenharmony_ci /* Use MTF Circuit */ 1652141cc406Sopenharmony_ci s->opt[OPT_MTF_CIRCUIT].name = "mtf"; 1653141cc406Sopenharmony_ci s->opt[OPT_MTF_CIRCUIT].title = "MTF Circuit"; 1654141cc406Sopenharmony_ci s->opt[OPT_MTF_CIRCUIT].desc ="Turns the MTF (Modulation Transfer Function) " 1655141cc406Sopenharmony_ci "peaking circuit on or off."; 1656141cc406Sopenharmony_ci s->opt[OPT_MTF_CIRCUIT].type = SANE_TYPE_BOOL; 1657141cc406Sopenharmony_ci if (s->hw->ScannerModel!=COLORONESCANNER) 1658141cc406Sopenharmony_ci s->opt[OPT_MTF_CIRCUIT].cap |= SANE_CAP_INACTIVE; 1659141cc406Sopenharmony_ci s->val[OPT_MTF_CIRCUIT].w = SANE_TRUE; 1660141cc406Sopenharmony_ci 1661141cc406Sopenharmony_ci 1662141cc406Sopenharmony_ci /* Use ICP */ 1663141cc406Sopenharmony_ci s->opt[OPT_ICP].name = "icp"; 1664141cc406Sopenharmony_ci s->opt[OPT_ICP].title = "ICP"; 1665141cc406Sopenharmony_ci s->opt[OPT_ICP].desc ="What is an ICP anyway?"; 1666141cc406Sopenharmony_ci s->opt[OPT_ICP].type = SANE_TYPE_BOOL; 1667141cc406Sopenharmony_ci if (s->hw->ScannerModel!=COLORONESCANNER) 1668141cc406Sopenharmony_ci s->opt[OPT_ICP].cap |= SANE_CAP_INACTIVE; 1669141cc406Sopenharmony_ci s->val[OPT_ICP].w = SANE_TRUE; 1670141cc406Sopenharmony_ci 1671141cc406Sopenharmony_ci 1672141cc406Sopenharmony_ci /* Data Polarity */ 1673141cc406Sopenharmony_ci s->opt[OPT_POLARITY].name = "polarity"; 1674141cc406Sopenharmony_ci s->opt[OPT_POLARITY].title = "Data Polarity"; 1675141cc406Sopenharmony_ci s->opt[OPT_POLARITY].desc = "Reverse black and white."; 1676141cc406Sopenharmony_ci s->opt[OPT_POLARITY].type = SANE_TYPE_BOOL; 1677141cc406Sopenharmony_ci if (s->hw->ScannerModel!=COLORONESCANNER) 1678141cc406Sopenharmony_ci s->opt[OPT_POLARITY].cap |= SANE_CAP_INACTIVE; 1679141cc406Sopenharmony_ci s->val[OPT_POLARITY].w = SANE_FALSE; 1680141cc406Sopenharmony_ci 1681141cc406Sopenharmony_ci 1682141cc406Sopenharmony_ci/* Color Functions: Advanced */ 1683141cc406Sopenharmony_ci 1684141cc406Sopenharmony_ci s->opt[OPT_COLOR_GROUP].title = SANE_VALUE_SCAN_MODE_COLOR; 1685141cc406Sopenharmony_ci s->opt[OPT_COLOR_GROUP].desc = ""; 1686141cc406Sopenharmony_ci s->opt[OPT_COLOR_GROUP].type = SANE_TYPE_GROUP; 1687141cc406Sopenharmony_ci s->opt[OPT_COLOR_GROUP].cap = SANE_CAP_ADVANCED; 1688141cc406Sopenharmony_ci s->opt[OPT_COLOR_GROUP].constraint_type = SANE_CONSTRAINT_NONE; 1689141cc406Sopenharmony_ci 1690141cc406Sopenharmony_ci#ifdef CALIBRATION_FUNCTIONALITY 1691141cc406Sopenharmony_ci /* OneScanner calibration vector */ 1692141cc406Sopenharmony_ci s->opt[OPT_CALIBRATION_VECTOR].name = "calibration-vector"; 1693141cc406Sopenharmony_ci s->opt[OPT_CALIBRATION_VECTOR].title = "Calibration Vector"; 1694141cc406Sopenharmony_ci s->opt[OPT_CALIBRATION_VECTOR].desc = "Calibration vector for the CCD array."; 1695141cc406Sopenharmony_ci s->opt[OPT_CALIBRATION_VECTOR].type = SANE_TYPE_INT; 1696141cc406Sopenharmony_ci if (s->hw->ScannerModel!=ONESCANNER) 1697141cc406Sopenharmony_ci s->opt[OPT_CALIBRATION_VECTOR].cap |= SANE_CAP_INACTIVE; 1698141cc406Sopenharmony_ci s->opt[OPT_CALIBRATION_VECTOR].unit = SANE_UNIT_NONE; 1699141cc406Sopenharmony_ci s->opt[OPT_CALIBRATION_VECTOR].size = 2550 * sizeof (SANE_Word); 1700141cc406Sopenharmony_ci s->opt[OPT_CALIBRATION_VECTOR].constraint_type = SANE_CONSTRAINT_RANGE; 1701141cc406Sopenharmony_ci s->opt[OPT_CALIBRATION_VECTOR].constraint.range = &u8_range; 1702141cc406Sopenharmony_ci s->val[OPT_CALIBRATION_VECTOR].wa = s->calibration_vector; 1703141cc406Sopenharmony_ci 1704141cc406Sopenharmony_ci /* ColorOneScanner calibration vector per band */ 1705141cc406Sopenharmony_ci s->opt[OPT_CALIBRATION_VECTOR_RED].name = "calibration-vector-red"; 1706141cc406Sopenharmony_ci s->opt[OPT_CALIBRATION_VECTOR_RED].title = "Calibration Vector for Red"; 1707141cc406Sopenharmony_ci s->opt[OPT_CALIBRATION_VECTOR_RED].desc = "Calibration vector for the CCD array."; 1708141cc406Sopenharmony_ci s->opt[OPT_CALIBRATION_VECTOR_RED].type = SANE_TYPE_INT; 1709141cc406Sopenharmony_ci if (s->hw->ScannerModel!=COLORONESCANNER) 1710141cc406Sopenharmony_ci s->opt[OPT_CALIBRATION_VECTOR_RED].cap |= SANE_CAP_INACTIVE; 1711141cc406Sopenharmony_ci s->opt[OPT_CALIBRATION_VECTOR_RED].unit = SANE_UNIT_NONE; 1712141cc406Sopenharmony_ci s->opt[OPT_CALIBRATION_VECTOR_RED].size = 2700 * sizeof (SANE_Word); 1713141cc406Sopenharmony_ci s->opt[OPT_CALIBRATION_VECTOR_RED].constraint_type = SANE_CONSTRAINT_RANGE; 1714141cc406Sopenharmony_ci s->opt[OPT_CALIBRATION_VECTOR_RED].constraint.range = &u8_range; 1715141cc406Sopenharmony_ci s->val[OPT_CALIBRATION_VECTOR_RED].wa = s->calibration_vector_red; 1716141cc406Sopenharmony_ci 1717141cc406Sopenharmony_ci /* ColorOneScanner calibration vector per band */ 1718141cc406Sopenharmony_ci s->opt[OPT_CALIBRATION_VECTOR_GREEN].name = "calibration-vector-green"; 1719141cc406Sopenharmony_ci s->opt[OPT_CALIBRATION_VECTOR_GREEN].title = "Calibration Vector for Green"; 1720141cc406Sopenharmony_ci s->opt[OPT_CALIBRATION_VECTOR_GREEN].desc = "Calibration vector for the CCD array."; 1721141cc406Sopenharmony_ci s->opt[OPT_CALIBRATION_VECTOR_GREEN].type = SANE_TYPE_INT; 1722141cc406Sopenharmony_ci if (s->hw->ScannerModel!=COLORONESCANNER) 1723141cc406Sopenharmony_ci s->opt[OPT_CALIBRATION_VECTOR].cap |= SANE_CAP_INACTIVE; 1724141cc406Sopenharmony_ci s->opt[OPT_CALIBRATION_VECTOR_GREEN].unit = SANE_UNIT_NONE; 1725141cc406Sopenharmony_ci s->opt[OPT_CALIBRATION_VECTOR_GREEN].size = 2700 * sizeof (SANE_Word); 1726141cc406Sopenharmony_ci s->opt[OPT_CALIBRATION_VECTOR_GREEN].constraint_type = SANE_CONSTRAINT_RANGE; 1727141cc406Sopenharmony_ci s->opt[OPT_CALIBRATION_VECTOR_GREEN].constraint.range = &u8_range; 1728141cc406Sopenharmony_ci s->val[OPT_CALIBRATION_VECTOR_GREEN].wa = s->calibration_vector_green; 1729141cc406Sopenharmony_ci 1730141cc406Sopenharmony_ci /* ColorOneScanner calibration vector per band */ 1731141cc406Sopenharmony_ci s->opt[OPT_CALIBRATION_VECTOR_BLUE].name = "calibration-vector-blue"; 1732141cc406Sopenharmony_ci s->opt[OPT_CALIBRATION_VECTOR_BLUE].title = "Calibration Vector for Blue"; 1733141cc406Sopenharmony_ci s->opt[OPT_CALIBRATION_VECTOR_BLUE].desc = "Calibration vector for the CCD array."; 1734141cc406Sopenharmony_ci s->opt[OPT_CALIBRATION_VECTOR_BLUE].type = SANE_TYPE_INT; 1735141cc406Sopenharmony_ci if (s->hw->ScannerModel!=COLORONESCANNER) 1736141cc406Sopenharmony_ci s->opt[OPT_CALIBRATION_VECTOR_BLUE].cap |= SANE_CAP_INACTIVE; 1737141cc406Sopenharmony_ci s->opt[OPT_CALIBRATION_VECTOR_BLUE].unit = SANE_UNIT_NONE; 1738141cc406Sopenharmony_ci s->opt[OPT_CALIBRATION_VECTOR_BLUE].size = 2700 * sizeof (SANE_Word); 1739141cc406Sopenharmony_ci s->opt[OPT_CALIBRATION_VECTOR_BLUE].constraint_type = SANE_CONSTRAINT_RANGE; 1740141cc406Sopenharmony_ci s->opt[OPT_CALIBRATION_VECTOR_BLUE].constraint.range = &u8_range; 1741141cc406Sopenharmony_ci s->val[OPT_CALIBRATION_VECTOR_BLUE].wa = s->calibration_vector_blue; 1742141cc406Sopenharmony_ci#endif /* CALIBRATION_FUNCTIONALITY */ 1743141cc406Sopenharmony_ci 1744141cc406Sopenharmony_ci /* Action: Download calibration vector */ 1745141cc406Sopenharmony_ci s->opt[OPT_DOWNLOAD_CALIBRATION_VECTOR].name = "download-calibration"; 1746141cc406Sopenharmony_ci s->opt[OPT_DOWNLOAD_CALIBRATION_VECTOR].title = "Download Calibration Vector"; 1747141cc406Sopenharmony_ci s->opt[OPT_DOWNLOAD_CALIBRATION_VECTOR].desc = "Download calibration vector to scanner"; 1748141cc406Sopenharmony_ci s->opt[OPT_DOWNLOAD_CALIBRATION_VECTOR].type = SANE_TYPE_BUTTON; 1749141cc406Sopenharmony_ci if (s->hw->ScannerModel!=ONESCANNER && s->hw->ScannerModel!=COLORONESCANNER) 1750141cc406Sopenharmony_ci s->opt[OPT_DOWNLOAD_CALIBRATION_VECTOR].cap |= SANE_CAP_INACTIVE; 1751141cc406Sopenharmony_ci 1752141cc406Sopenharmony_ci /* custom-cct table */ 1753141cc406Sopenharmony_ci s->opt[OPT_CUSTOM_CCT].name = "custom-cct"; 1754141cc406Sopenharmony_ci s->opt[OPT_CUSTOM_CCT].title = "Use Custom CCT"; 1755141cc406Sopenharmony_ci s->opt[OPT_CUSTOM_CCT].desc ="Determines whether a builtin " 1756141cc406Sopenharmony_ci "or a custom 3x3 Color Correction Table (CCT) should be used."; 1757141cc406Sopenharmony_ci s->opt[OPT_CUSTOM_CCT].type = SANE_TYPE_BOOL; 1758141cc406Sopenharmony_ci s->opt[OPT_CUSTOM_CCT].cap |= SANE_CAP_INACTIVE; 1759141cc406Sopenharmony_ci if (s->hw->ScannerModel!=COLORONESCANNER) 1760141cc406Sopenharmony_ci s->opt[OPT_CUSTOM_CCT].cap |= SANE_CAP_INACTIVE; 1761141cc406Sopenharmony_ci s->val[OPT_CUSTOM_CCT].w = SANE_FALSE; 1762141cc406Sopenharmony_ci 1763141cc406Sopenharmony_ci 1764141cc406Sopenharmony_ci /* CCT */ 1765141cc406Sopenharmony_ci s->opt[OPT_CCT].name = "cct"; 1766141cc406Sopenharmony_ci s->opt[OPT_CCT].title = "3x3 Color Correction Table"; 1767141cc406Sopenharmony_ci s->opt[OPT_CCT].desc = "TODO: Color Correction is currently unsupported"; 1768141cc406Sopenharmony_ci s->opt[OPT_CCT].type = SANE_TYPE_FIXED; 1769141cc406Sopenharmony_ci s->opt[OPT_CCT].cap |= SANE_CAP_INACTIVE; 1770141cc406Sopenharmony_ci s->opt[OPT_CCT].unit = SANE_UNIT_NONE; 1771141cc406Sopenharmony_ci s->opt[OPT_CCT].size = 9 * sizeof (SANE_Word); 1772141cc406Sopenharmony_ci s->opt[OPT_CCT].constraint_type = SANE_CONSTRAINT_RANGE; 1773141cc406Sopenharmony_ci s->opt[OPT_CCT].constraint.range = &u8_range; 1774141cc406Sopenharmony_ci s->val[OPT_CCT].wa = s->cct3x3; 1775141cc406Sopenharmony_ci 1776141cc406Sopenharmony_ci 1777141cc406Sopenharmony_ci /* Action: custom 3x3 color correction table */ 1778141cc406Sopenharmony_ci s->opt[OPT_DOWNLOAD_CCT].name = "download-3x3"; 1779141cc406Sopenharmony_ci s->opt[OPT_DOWNLOAD_CCT].title = "Download 3x3 CCT"; 1780141cc406Sopenharmony_ci s->opt[OPT_DOWNLOAD_CCT].desc = "Download 3x3 color correction table"; 1781141cc406Sopenharmony_ci s->opt[OPT_DOWNLOAD_CCT].type = SANE_TYPE_BUTTON; 1782141cc406Sopenharmony_ci if (s->hw->ScannerModel!=COLORONESCANNER) 1783141cc406Sopenharmony_ci s->opt[OPT_DOWNLOAD_CCT].cap |= SANE_CAP_INACTIVE; 1784141cc406Sopenharmony_ci 1785141cc406Sopenharmony_ci 1786141cc406Sopenharmony_ci /* custom-gamma table */ 1787141cc406Sopenharmony_ci s->opt[OPT_CUSTOM_GAMMA].name = SANE_NAME_CUSTOM_GAMMA; 1788141cc406Sopenharmony_ci s->opt[OPT_CUSTOM_GAMMA].title = SANE_TITLE_CUSTOM_GAMMA; 1789141cc406Sopenharmony_ci s->opt[OPT_CUSTOM_GAMMA].desc = SANE_DESC_CUSTOM_GAMMA; 1790141cc406Sopenharmony_ci s->opt[OPT_CUSTOM_GAMMA].type = SANE_TYPE_BOOL; 1791141cc406Sopenharmony_ci s->opt[OPT_CUSTOM_GAMMA].cap |= SANE_CAP_INACTIVE; 1792141cc406Sopenharmony_ci s->val[OPT_CUSTOM_GAMMA].w = SANE_FALSE; 1793141cc406Sopenharmony_ci 1794141cc406Sopenharmony_ci /* red gamma vector */ 1795141cc406Sopenharmony_ci s->opt[OPT_GAMMA_VECTOR_R].name = SANE_NAME_GAMMA_VECTOR_R; 1796141cc406Sopenharmony_ci s->opt[OPT_GAMMA_VECTOR_R].title = SANE_TITLE_GAMMA_VECTOR_R; 1797141cc406Sopenharmony_ci s->opt[OPT_GAMMA_VECTOR_R].desc = SANE_DESC_GAMMA_VECTOR_R; 1798141cc406Sopenharmony_ci s->opt[OPT_GAMMA_VECTOR_R].type = SANE_TYPE_INT; 1799141cc406Sopenharmony_ci s->opt[OPT_GAMMA_VECTOR_R].cap |= SANE_CAP_INACTIVE; 1800141cc406Sopenharmony_ci s->opt[OPT_GAMMA_VECTOR_R].unit = SANE_UNIT_NONE; 1801141cc406Sopenharmony_ci s->opt[OPT_GAMMA_VECTOR_R].size = 256 * sizeof (SANE_Word); 1802141cc406Sopenharmony_ci s->opt[OPT_GAMMA_VECTOR_R].constraint_type = SANE_CONSTRAINT_RANGE; 1803141cc406Sopenharmony_ci s->opt[OPT_GAMMA_VECTOR_R].constraint.range = &u8_range; 1804141cc406Sopenharmony_ci s->val[OPT_GAMMA_VECTOR_R].wa = &s->gamma_table[0][0]; 1805141cc406Sopenharmony_ci 1806141cc406Sopenharmony_ci /* green gamma vector */ 1807141cc406Sopenharmony_ci s->opt[OPT_GAMMA_VECTOR_G].name = SANE_NAME_GAMMA_VECTOR_G; 1808141cc406Sopenharmony_ci s->opt[OPT_GAMMA_VECTOR_G].title = SANE_TITLE_GAMMA_VECTOR_G; 1809141cc406Sopenharmony_ci s->opt[OPT_GAMMA_VECTOR_G].desc = SANE_DESC_GAMMA_VECTOR_G; 1810141cc406Sopenharmony_ci s->opt[OPT_GAMMA_VECTOR_G].type = SANE_TYPE_INT; 1811141cc406Sopenharmony_ci s->opt[OPT_GAMMA_VECTOR_G].cap |= SANE_CAP_INACTIVE; 1812141cc406Sopenharmony_ci s->opt[OPT_GAMMA_VECTOR_G].unit = SANE_UNIT_NONE; 1813141cc406Sopenharmony_ci s->opt[OPT_GAMMA_VECTOR_G].size = 256 * sizeof (SANE_Word); 1814141cc406Sopenharmony_ci s->opt[OPT_GAMMA_VECTOR_G].constraint_type = SANE_CONSTRAINT_RANGE; 1815141cc406Sopenharmony_ci s->opt[OPT_GAMMA_VECTOR_G].constraint.range = &u8_range; 1816141cc406Sopenharmony_ci s->val[OPT_GAMMA_VECTOR_G].wa = &s->gamma_table[1][0]; 1817141cc406Sopenharmony_ci 1818141cc406Sopenharmony_ci /* blue gamma vector */ 1819141cc406Sopenharmony_ci s->opt[OPT_GAMMA_VECTOR_B].name = SANE_NAME_GAMMA_VECTOR_B; 1820141cc406Sopenharmony_ci s->opt[OPT_GAMMA_VECTOR_B].title = SANE_TITLE_GAMMA_VECTOR_B; 1821141cc406Sopenharmony_ci s->opt[OPT_GAMMA_VECTOR_B].desc = SANE_DESC_GAMMA_VECTOR_B; 1822141cc406Sopenharmony_ci s->opt[OPT_GAMMA_VECTOR_B].type = SANE_TYPE_INT; 1823141cc406Sopenharmony_ci s->opt[OPT_GAMMA_VECTOR_B].cap |= SANE_CAP_INACTIVE; 1824141cc406Sopenharmony_ci s->opt[OPT_GAMMA_VECTOR_B].unit = SANE_UNIT_NONE; 1825141cc406Sopenharmony_ci s->opt[OPT_GAMMA_VECTOR_B].size = 256 * sizeof (SANE_Word); 1826141cc406Sopenharmony_ci s->opt[OPT_GAMMA_VECTOR_B].constraint_type = SANE_CONSTRAINT_RANGE; 1827141cc406Sopenharmony_ci s->opt[OPT_GAMMA_VECTOR_B].constraint.range = &u8_range; 1828141cc406Sopenharmony_ci s->val[OPT_GAMMA_VECTOR_B].wa = &s->gamma_table[2][0]; 1829141cc406Sopenharmony_ci 1830141cc406Sopenharmony_ci /* Action: download gamma vectors table */ 1831141cc406Sopenharmony_ci s->opt[OPT_DOWNLOAD_GAMMA].name = "download-gamma"; 1832141cc406Sopenharmony_ci s->opt[OPT_DOWNLOAD_GAMMA].title = "Download Gamma Vector(s)"; 1833141cc406Sopenharmony_ci s->opt[OPT_DOWNLOAD_GAMMA].desc = "Download Gamma Vector(s)."; 1834141cc406Sopenharmony_ci s->opt[OPT_DOWNLOAD_GAMMA].type = SANE_TYPE_BUTTON; 1835141cc406Sopenharmony_ci s->opt[OPT_DOWNLOAD_GAMMA].cap |= SANE_CAP_INACTIVE; 1836141cc406Sopenharmony_ci 1837141cc406Sopenharmony_ci s->opt[OPT_COLOR_SENSOR].name = "color-sensor"; 1838141cc406Sopenharmony_ci s->opt[OPT_COLOR_SENSOR].title = "Gray scan with"; 1839141cc406Sopenharmony_ci s->opt[OPT_COLOR_SENSOR].desc = "Select the color sensor to scan in gray mode."; 1840141cc406Sopenharmony_ci s->opt[OPT_COLOR_SENSOR].type = SANE_TYPE_STRING; 1841141cc406Sopenharmony_ci s->opt[OPT_COLOR_SENSOR].unit = SANE_UNIT_NONE; 1842141cc406Sopenharmony_ci s->opt[OPT_COLOR_SENSOR].size = max_string_size (color_sensor_list); 1843141cc406Sopenharmony_ci if (s->hw->ScannerModel!=COLORONESCANNER) 1844141cc406Sopenharmony_ci s->opt[OPT_COLOR_SENSOR].cap |= SANE_CAP_INACTIVE; 1845141cc406Sopenharmony_ci s->opt[OPT_COLOR_SENSOR].constraint_type = SANE_CONSTRAINT_STRING_LIST; 1846141cc406Sopenharmony_ci s->opt[OPT_COLOR_SENSOR].constraint.string_list = color_sensor_list; 1847141cc406Sopenharmony_ci s->val[OPT_COLOR_SENSOR].s = strdup(color_sensor_list[2]); 1848141cc406Sopenharmony_ci 1849141cc406Sopenharmony_ci 1850141cc406Sopenharmony_ci mode_update (s, s->val[OPT_MODE].s); 1851141cc406Sopenharmony_ci 1852141cc406Sopenharmony_ci return SANE_STATUS_GOOD; 1853141cc406Sopenharmony_ci} 1854141cc406Sopenharmony_ci 1855141cc406Sopenharmony_cistatic SANE_Status 1856141cc406Sopenharmony_ciattach_one (const char *dev) 1857141cc406Sopenharmony_ci{ 1858141cc406Sopenharmony_ci attach (dev, 0, SANE_FALSE); 1859141cc406Sopenharmony_ci return SANE_STATUS_GOOD; 1860141cc406Sopenharmony_ci} 1861141cc406Sopenharmony_ci 1862141cc406Sopenharmony_ciSANE_Status 1863141cc406Sopenharmony_cisane_init (SANE_Int * version_code, SANE_Auth_Callback authorize) 1864141cc406Sopenharmony_ci{ 1865141cc406Sopenharmony_ci char dev_name[PATH_MAX]; 1866141cc406Sopenharmony_ci size_t len; 1867141cc406Sopenharmony_ci FILE *fp; 1868141cc406Sopenharmony_ci 1869141cc406Sopenharmony_ci (void) authorize; /* silence gcc */ 1870141cc406Sopenharmony_ci 1871141cc406Sopenharmony_ci DBG_INIT (); 1872141cc406Sopenharmony_ci 1873141cc406Sopenharmony_ci if (version_code) 1874141cc406Sopenharmony_ci *version_code = SANE_VERSION_CODE (SANE_CURRENT_MAJOR, SANE_CURRENT_MINOR, 0); 1875141cc406Sopenharmony_ci 1876141cc406Sopenharmony_ci fp = sanei_config_open (APPLE_CONFIG_FILE); 1877141cc406Sopenharmony_ci if (!fp) 1878141cc406Sopenharmony_ci { 1879141cc406Sopenharmony_ci /* default to /dev/scanner instead of insisting on config file */ 1880141cc406Sopenharmony_ci attach ("/dev/scanner", 0, SANE_FALSE); 1881141cc406Sopenharmony_ci return SANE_STATUS_GOOD; 1882141cc406Sopenharmony_ci } 1883141cc406Sopenharmony_ci 1884141cc406Sopenharmony_ci while (sanei_config_read (dev_name, sizeof (dev_name), fp)) 1885141cc406Sopenharmony_ci { 1886141cc406Sopenharmony_ci if (dev_name[0] == '#') /* ignore line comments */ 1887141cc406Sopenharmony_ci continue; 1888141cc406Sopenharmony_ci 1889141cc406Sopenharmony_ci len = strlen (dev_name); 1890141cc406Sopenharmony_ci 1891141cc406Sopenharmony_ci if (!len) 1892141cc406Sopenharmony_ci continue; /* ignore empty lines */ 1893141cc406Sopenharmony_ci 1894141cc406Sopenharmony_ci if (strncmp (dev_name, "option", 6) == 0 1895141cc406Sopenharmony_ci && isspace (dev_name[6])) 1896141cc406Sopenharmony_ci { 1897141cc406Sopenharmony_ci const char *str = dev_name + 7; 1898141cc406Sopenharmony_ci 1899141cc406Sopenharmony_ci while (isspace (*str)) 1900141cc406Sopenharmony_ci ++str; 1901141cc406Sopenharmony_ci 1902141cc406Sopenharmony_ci continue; 1903141cc406Sopenharmony_ci } 1904141cc406Sopenharmony_ci 1905141cc406Sopenharmony_ci sanei_config_attach_matching_devices (dev_name, attach_one); 1906141cc406Sopenharmony_ci } 1907141cc406Sopenharmony_ci fclose (fp); 1908141cc406Sopenharmony_ci return SANE_STATUS_GOOD; 1909141cc406Sopenharmony_ci} 1910141cc406Sopenharmony_ci 1911141cc406Sopenharmony_civoid 1912141cc406Sopenharmony_cisane_exit (void) 1913141cc406Sopenharmony_ci{ 1914141cc406Sopenharmony_ci Apple_Device *dev, *next; 1915141cc406Sopenharmony_ci 1916141cc406Sopenharmony_ci for (dev = first_dev; dev; dev = next) 1917141cc406Sopenharmony_ci { 1918141cc406Sopenharmony_ci next = dev->next; 1919141cc406Sopenharmony_ci free ((void *) dev->sane.name); 1920141cc406Sopenharmony_ci free ((void *) dev->sane.model); 1921141cc406Sopenharmony_ci free (dev); 1922141cc406Sopenharmony_ci } 1923141cc406Sopenharmony_ci if (devlist) 1924141cc406Sopenharmony_ci free (devlist); 1925141cc406Sopenharmony_ci} 1926141cc406Sopenharmony_ci 1927141cc406Sopenharmony_ciSANE_Status 1928141cc406Sopenharmony_cisane_get_devices (const SANE_Device *** device_list, SANE_Bool local_only) 1929141cc406Sopenharmony_ci{ 1930141cc406Sopenharmony_ci Apple_Device *dev; 1931141cc406Sopenharmony_ci int i; 1932141cc406Sopenharmony_ci 1933141cc406Sopenharmony_ci (void) local_only; /* silence gcc */ 1934141cc406Sopenharmony_ci 1935141cc406Sopenharmony_ci if (devlist) 1936141cc406Sopenharmony_ci free (devlist); 1937141cc406Sopenharmony_ci 1938141cc406Sopenharmony_ci devlist = malloc ((num_devices + 1) * sizeof (devlist[0])); 1939141cc406Sopenharmony_ci if (!devlist) 1940141cc406Sopenharmony_ci return SANE_STATUS_NO_MEM; 1941141cc406Sopenharmony_ci 1942141cc406Sopenharmony_ci i = 0; 1943141cc406Sopenharmony_ci for (dev = first_dev; i < num_devices; dev = dev->next) 1944141cc406Sopenharmony_ci devlist[i++] = &dev->sane; 1945141cc406Sopenharmony_ci devlist[i++] = 0; 1946141cc406Sopenharmony_ci 1947141cc406Sopenharmony_ci *device_list = devlist; 1948141cc406Sopenharmony_ci return SANE_STATUS_GOOD; 1949141cc406Sopenharmony_ci} 1950141cc406Sopenharmony_ci 1951141cc406Sopenharmony_ciSANE_Status 1952141cc406Sopenharmony_cisane_open (SANE_String_Const devicename, SANE_Handle * handle) 1953141cc406Sopenharmony_ci{ 1954141cc406Sopenharmony_ci Apple_Device *dev; 1955141cc406Sopenharmony_ci SANE_Status status; 1956141cc406Sopenharmony_ci Apple_Scanner *s; 1957141cc406Sopenharmony_ci int i, j; 1958141cc406Sopenharmony_ci 1959141cc406Sopenharmony_ci if (devicename[0]) 1960141cc406Sopenharmony_ci { 1961141cc406Sopenharmony_ci for (dev = first_dev; dev; dev = dev->next) 1962141cc406Sopenharmony_ci if (strcmp (dev->sane.name, devicename) == 0) 1963141cc406Sopenharmony_ci break; 1964141cc406Sopenharmony_ci 1965141cc406Sopenharmony_ci if (!dev) 1966141cc406Sopenharmony_ci { 1967141cc406Sopenharmony_ci status = attach (devicename, &dev, SANE_TRUE); 1968141cc406Sopenharmony_ci if (status != SANE_STATUS_GOOD) 1969141cc406Sopenharmony_ci return status; 1970141cc406Sopenharmony_ci } 1971141cc406Sopenharmony_ci } 1972141cc406Sopenharmony_ci else 1973141cc406Sopenharmony_ci /* empty devicname -> use first device */ 1974141cc406Sopenharmony_ci dev = first_dev; 1975141cc406Sopenharmony_ci 1976141cc406Sopenharmony_ci if (!dev) 1977141cc406Sopenharmony_ci return SANE_STATUS_INVAL; 1978141cc406Sopenharmony_ci 1979141cc406Sopenharmony_ci s = malloc (sizeof (*s)); 1980141cc406Sopenharmony_ci if (!s) 1981141cc406Sopenharmony_ci return SANE_STATUS_NO_MEM; 1982141cc406Sopenharmony_ci memset (s, 0, sizeof (*s)); 1983141cc406Sopenharmony_ci s->fd = -1; 1984141cc406Sopenharmony_ci s->hw = dev; 1985141cc406Sopenharmony_ci for (i = 0; i < 3; ++i) 1986141cc406Sopenharmony_ci for (j = 0; j < 256; ++j) 1987141cc406Sopenharmony_ci s->gamma_table[i][j] = j; 1988141cc406Sopenharmony_ci 1989141cc406Sopenharmony_ci init_options (s); 1990141cc406Sopenharmony_ci 1991141cc406Sopenharmony_ci /* insert newly opened handle into list of open handles: */ 1992141cc406Sopenharmony_ci s->next = first_handle; 1993141cc406Sopenharmony_ci first_handle = s; 1994141cc406Sopenharmony_ci 1995141cc406Sopenharmony_ci *handle = s; 1996141cc406Sopenharmony_ci return SANE_STATUS_GOOD; 1997141cc406Sopenharmony_ci} 1998141cc406Sopenharmony_ci 1999141cc406Sopenharmony_civoid 2000141cc406Sopenharmony_cisane_close (SANE_Handle handle) 2001141cc406Sopenharmony_ci{ 2002141cc406Sopenharmony_ci Apple_Scanner *prev, *s; 2003141cc406Sopenharmony_ci 2004141cc406Sopenharmony_ci /* remove handle from list of open handles: */ 2005141cc406Sopenharmony_ci prev = 0; 2006141cc406Sopenharmony_ci for (s = first_handle; s; s = s->next) 2007141cc406Sopenharmony_ci { 2008141cc406Sopenharmony_ci if (s == handle) 2009141cc406Sopenharmony_ci break; 2010141cc406Sopenharmony_ci prev = s; 2011141cc406Sopenharmony_ci } 2012141cc406Sopenharmony_ci if (!s) 2013141cc406Sopenharmony_ci { 2014141cc406Sopenharmony_ci DBG (ERROR_MESSAGE, "close: invalid handle %p\n", handle); 2015141cc406Sopenharmony_ci return; /* oops, not a handle we know about */ 2016141cc406Sopenharmony_ci } 2017141cc406Sopenharmony_ci 2018141cc406Sopenharmony_ci if (prev) 2019141cc406Sopenharmony_ci prev->next = s->next; 2020141cc406Sopenharmony_ci else 2021141cc406Sopenharmony_ci first_handle = s->next; 2022141cc406Sopenharmony_ci 2023141cc406Sopenharmony_ci free (handle); 2024141cc406Sopenharmony_ci} 2025141cc406Sopenharmony_ci 2026141cc406Sopenharmony_ciconst SANE_Option_Descriptor * 2027141cc406Sopenharmony_cisane_get_option_descriptor (SANE_Handle handle, SANE_Int option) 2028141cc406Sopenharmony_ci{ 2029141cc406Sopenharmony_ci Apple_Scanner *s = handle; 2030141cc406Sopenharmony_ci 2031141cc406Sopenharmony_ci if ((unsigned) option >= NUM_OPTIONS) 2032141cc406Sopenharmony_ci return 0; 2033141cc406Sopenharmony_ci return s->opt + option; 2034141cc406Sopenharmony_ci} 2035141cc406Sopenharmony_ci 2036141cc406Sopenharmony_ciSANE_Status 2037141cc406Sopenharmony_cisane_control_option (SANE_Handle handle, SANE_Int option, 2038141cc406Sopenharmony_ci SANE_Action action, void *val, SANE_Int * info) 2039141cc406Sopenharmony_ci{ 2040141cc406Sopenharmony_ci Apple_Scanner *s = handle; 2041141cc406Sopenharmony_ci SANE_Status status; 2042141cc406Sopenharmony_ci SANE_Word cap; 2043141cc406Sopenharmony_ci 2044141cc406Sopenharmony_ci 2045141cc406Sopenharmony_ci DBG (FLOW_CONTROL, "(%s): Entering on control_option for option %s (%d).\n", 2046141cc406Sopenharmony_ci (action == SANE_ACTION_GET_VALUE) ? "get" : "set", 2047141cc406Sopenharmony_ci s->opt[option].name, option); 2048141cc406Sopenharmony_ci 2049141cc406Sopenharmony_ci if (val || action == SANE_ACTION_GET_VALUE) 2050141cc406Sopenharmony_ci switch (s->opt[option].type) 2051141cc406Sopenharmony_ci { 2052141cc406Sopenharmony_ci case SANE_TYPE_STRING: 2053141cc406Sopenharmony_ci DBG (FLOW_CONTROL, "Value %s\n", (action == SANE_ACTION_GET_VALUE) ? 2054141cc406Sopenharmony_ci s->val[option].s : (char *) val); 2055141cc406Sopenharmony_ci break; 2056141cc406Sopenharmony_ci case SANE_TYPE_FIXED: 2057141cc406Sopenharmony_ci { 2058141cc406Sopenharmony_ci double v1, v2; 2059141cc406Sopenharmony_ci SANE_Fixed f; 2060141cc406Sopenharmony_ci v1 = SANE_UNFIX (s->val[option].w); 2061141cc406Sopenharmony_ci f = *(SANE_Fixed *) val; 2062141cc406Sopenharmony_ci v2 = SANE_UNFIX (f); 2063141cc406Sopenharmony_ci DBG (FLOW_CONTROL, "Value %g (Fixed)\n", 2064141cc406Sopenharmony_ci (action == SANE_ACTION_GET_VALUE) ? v1 : v2); 2065141cc406Sopenharmony_ci break; 2066141cc406Sopenharmony_ci } 2067141cc406Sopenharmony_ci default: 2068141cc406Sopenharmony_ci DBG (FLOW_CONTROL, "Value %u (Int).\n", 2069141cc406Sopenharmony_ci (action == SANE_ACTION_GET_VALUE) 2070141cc406Sopenharmony_ci ? s->val[option].w : *(SANE_Int *) val); 2071141cc406Sopenharmony_ci break; 2072141cc406Sopenharmony_ci } 2073141cc406Sopenharmony_ci 2074141cc406Sopenharmony_ci 2075141cc406Sopenharmony_ci if (info) 2076141cc406Sopenharmony_ci *info = 0; 2077141cc406Sopenharmony_ci 2078141cc406Sopenharmony_ci if (s->scanning) 2079141cc406Sopenharmony_ci return SANE_STATUS_DEVICE_BUSY; 2080141cc406Sopenharmony_ci 2081141cc406Sopenharmony_ci if (option >= NUM_OPTIONS) 2082141cc406Sopenharmony_ci return SANE_STATUS_INVAL; 2083141cc406Sopenharmony_ci 2084141cc406Sopenharmony_ci cap = s->opt[option].cap; 2085141cc406Sopenharmony_ci 2086141cc406Sopenharmony_ci if (!SANE_OPTION_IS_ACTIVE (cap)) 2087141cc406Sopenharmony_ci return SANE_STATUS_INVAL; 2088141cc406Sopenharmony_ci 2089141cc406Sopenharmony_ci 2090141cc406Sopenharmony_ci if (action == SANE_ACTION_GET_VALUE) 2091141cc406Sopenharmony_ci { 2092141cc406Sopenharmony_ci switch (option) 2093141cc406Sopenharmony_ci { 2094141cc406Sopenharmony_ci /* word options: */ 2095141cc406Sopenharmony_ci case OPT_NUM_OPTS: 2096141cc406Sopenharmony_ci case OPT_RESOLUTION: 2097141cc406Sopenharmony_ci case OPT_PREVIEW: 2098141cc406Sopenharmony_ci case OPT_TL_X: 2099141cc406Sopenharmony_ci case OPT_TL_Y: 2100141cc406Sopenharmony_ci case OPT_BR_X: 2101141cc406Sopenharmony_ci case OPT_BR_Y: 2102141cc406Sopenharmony_ci case OPT_BRIGHTNESS: 2103141cc406Sopenharmony_ci case OPT_CONTRAST: 2104141cc406Sopenharmony_ci case OPT_THRESHOLD: 2105141cc406Sopenharmony_ci case OPT_AUTOBACKGROUND: 2106141cc406Sopenharmony_ci case OPT_AUTOBACKGROUND_THRESHOLD: 2107141cc406Sopenharmony_ci case OPT_VOLT_REF: 2108141cc406Sopenharmony_ci case OPT_VOLT_REF_TOP: 2109141cc406Sopenharmony_ci case OPT_VOLT_REF_BOTTOM: 2110141cc406Sopenharmony_ci 2111141cc406Sopenharmony_ci case OPT_LAMP: 2112141cc406Sopenharmony_ci case OPT_WAIT: 2113141cc406Sopenharmony_ci case OPT_CALIBRATE: 2114141cc406Sopenharmony_ci case OPT_LED: 2115141cc406Sopenharmony_ci case OPT_CCD: 2116141cc406Sopenharmony_ci case OPT_MTF_CIRCUIT: 2117141cc406Sopenharmony_ci case OPT_ICP: 2118141cc406Sopenharmony_ci case OPT_POLARITY: 2119141cc406Sopenharmony_ci 2120141cc406Sopenharmony_ci case OPT_CUSTOM_CCT: 2121141cc406Sopenharmony_ci case OPT_CUSTOM_GAMMA: 2122141cc406Sopenharmony_ci *(SANE_Word *) val = s->val[option].w; 2123141cc406Sopenharmony_ci return SANE_STATUS_GOOD; 2124141cc406Sopenharmony_ci 2125141cc406Sopenharmony_ci /* word-array options: */ 2126141cc406Sopenharmony_ci 2127141cc406Sopenharmony_ci case OPT_CCT: 2128141cc406Sopenharmony_ci case OPT_GAMMA_VECTOR_R: 2129141cc406Sopenharmony_ci case OPT_GAMMA_VECTOR_G: 2130141cc406Sopenharmony_ci case OPT_GAMMA_VECTOR_B: 2131141cc406Sopenharmony_ci memcpy (val, s->val[option].wa, s->opt[option].size); 2132141cc406Sopenharmony_ci return SANE_STATUS_GOOD; 2133141cc406Sopenharmony_ci 2134141cc406Sopenharmony_ci /* string options: */ 2135141cc406Sopenharmony_ci 2136141cc406Sopenharmony_ci case OPT_MODE: 2137141cc406Sopenharmony_ci/* 2138141cc406Sopenharmony_ciTODO: This is to protect the mode string to be ruined from the dll? 2139141cc406Sopenharmony_cibackend. I do not know why. It's definitely an overkill and should be 2140141cc406Sopenharmony_cieliminated. 2141141cc406Sopenharmony_ci status = sanei_constrain_value (s->opt + option, s->val[option].s, 2142141cc406Sopenharmony_ci info); 2143141cc406Sopenharmony_ci*/ 2144141cc406Sopenharmony_ci case OPT_MODEL: 2145141cc406Sopenharmony_ci case OPT_GRAYMAP: 2146141cc406Sopenharmony_ci case OPT_HALFTONE_PATTERN: 2147141cc406Sopenharmony_ci case OPT_HALFTONE_FILE: 2148141cc406Sopenharmony_ci case OPT_SPEED: 2149141cc406Sopenharmony_ci case OPT_COLOR_SENSOR: 2150141cc406Sopenharmony_ci strcpy (val, s->val[option].s); 2151141cc406Sopenharmony_ci return SANE_STATUS_GOOD; 2152141cc406Sopenharmony_ci 2153141cc406Sopenharmony_ci/* Some Buttons */ 2154141cc406Sopenharmony_ci case OPT_DOWNLOAD_CALIBRATION_VECTOR: 2155141cc406Sopenharmony_ci case OPT_DOWNLOAD_CCT: 2156141cc406Sopenharmony_ci case OPT_DOWNLOAD_GAMMA: 2157141cc406Sopenharmony_ci return SANE_STATUS_INVAL; 2158141cc406Sopenharmony_ci 2159141cc406Sopenharmony_ci } 2160141cc406Sopenharmony_ci } 2161141cc406Sopenharmony_ci else if (action == SANE_ACTION_SET_VALUE) 2162141cc406Sopenharmony_ci { 2163141cc406Sopenharmony_ci if (!SANE_OPTION_IS_SETTABLE (cap)) 2164141cc406Sopenharmony_ci return SANE_STATUS_INVAL; 2165141cc406Sopenharmony_ci 2166141cc406Sopenharmony_ci status = sanei_constrain_value (s->opt + option, val, info); 2167141cc406Sopenharmony_ci 2168141cc406Sopenharmony_ci if (status != SANE_STATUS_GOOD) 2169141cc406Sopenharmony_ci return status; 2170141cc406Sopenharmony_ci 2171141cc406Sopenharmony_ci 2172141cc406Sopenharmony_ci switch (option) 2173141cc406Sopenharmony_ci { 2174141cc406Sopenharmony_ci /* (mostly) side-effect-free word options: */ 2175141cc406Sopenharmony_ci case OPT_RESOLUTION: 2176141cc406Sopenharmony_ci case OPT_TL_X: 2177141cc406Sopenharmony_ci case OPT_TL_Y: 2178141cc406Sopenharmony_ci case OPT_BR_X: 2179141cc406Sopenharmony_ci case OPT_BR_Y: 2180141cc406Sopenharmony_ci 2181141cc406Sopenharmony_ci s->val[option].w = *(SANE_Word *) val; 2182141cc406Sopenharmony_ci calc_parameters (s); 2183141cc406Sopenharmony_ci 2184141cc406Sopenharmony_ci if (info) 2185141cc406Sopenharmony_ci *info |= SANE_INFO_RELOAD_PARAMS 2186141cc406Sopenharmony_ci | SANE_INFO_RELOAD_OPTIONS 2187141cc406Sopenharmony_ci | SANE_INFO_INEXACT; 2188141cc406Sopenharmony_ci 2189141cc406Sopenharmony_ci return SANE_STATUS_GOOD; 2190141cc406Sopenharmony_ci 2191141cc406Sopenharmony_ci /* fall through */ 2192141cc406Sopenharmony_ci case OPT_BRIGHTNESS: 2193141cc406Sopenharmony_ci case OPT_CONTRAST: 2194141cc406Sopenharmony_ci case OPT_THRESHOLD: 2195141cc406Sopenharmony_ci case OPT_AUTOBACKGROUND_THRESHOLD: 2196141cc406Sopenharmony_ci case OPT_VOLT_REF_TOP: 2197141cc406Sopenharmony_ci case OPT_VOLT_REF_BOTTOM: 2198141cc406Sopenharmony_ci case OPT_LAMP: 2199141cc406Sopenharmony_ci case OPT_WAIT: 2200141cc406Sopenharmony_ci case OPT_CALIBRATE: 2201141cc406Sopenharmony_ci case OPT_LED: 2202141cc406Sopenharmony_ci case OPT_CCD: 2203141cc406Sopenharmony_ci case OPT_MTF_CIRCUIT: 2204141cc406Sopenharmony_ci case OPT_ICP: 2205141cc406Sopenharmony_ci case OPT_POLARITY: 2206141cc406Sopenharmony_ci s->val[option].w = *(SANE_Word *) val; 2207141cc406Sopenharmony_ci return SANE_STATUS_GOOD; 2208141cc406Sopenharmony_ci 2209141cc406Sopenharmony_ci /* Simple Strings */ 2210141cc406Sopenharmony_ci case OPT_GRAYMAP: 2211141cc406Sopenharmony_ci case OPT_HALFTONE_FILE: 2212141cc406Sopenharmony_ci case OPT_SPEED: 2213141cc406Sopenharmony_ci if (s->val[option].s) 2214141cc406Sopenharmony_ci free (s->val[option].s); 2215141cc406Sopenharmony_ci s->val[option].s = strdup (val); 2216141cc406Sopenharmony_ci return SANE_STATUS_GOOD; 2217141cc406Sopenharmony_ci 2218141cc406Sopenharmony_ci /* Boolean */ 2219141cc406Sopenharmony_ci case OPT_PREVIEW: 2220141cc406Sopenharmony_ci s->val[option].w = *(SANE_Bool *) val; 2221141cc406Sopenharmony_ci return SANE_STATUS_GOOD; 2222141cc406Sopenharmony_ci 2223141cc406Sopenharmony_ci 2224141cc406Sopenharmony_ci /* side-effect-free word-array options: */ 2225141cc406Sopenharmony_ci case OPT_CCT: 2226141cc406Sopenharmony_ci case OPT_GAMMA_VECTOR_R: 2227141cc406Sopenharmony_ci case OPT_GAMMA_VECTOR_G: 2228141cc406Sopenharmony_ci case OPT_GAMMA_VECTOR_B: 2229141cc406Sopenharmony_ci memcpy (s->val[option].wa, val, s->opt[option].size); 2230141cc406Sopenharmony_ci return SANE_STATUS_GOOD; 2231141cc406Sopenharmony_ci 2232141cc406Sopenharmony_ci 2233141cc406Sopenharmony_ci /* options with light side-effects: */ 2234141cc406Sopenharmony_ci 2235141cc406Sopenharmony_ci case OPT_HALFTONE_PATTERN: 2236141cc406Sopenharmony_ci if (info) 2237141cc406Sopenharmony_ci *info |= SANE_INFO_RELOAD_OPTIONS; 2238141cc406Sopenharmony_ci if (s->val[option].s) 2239141cc406Sopenharmony_ci free (s->val[option].s); 2240141cc406Sopenharmony_ci s->val[option].s = strdup (val); 2241141cc406Sopenharmony_ci if (!strcmp (val, "download")) 2242141cc406Sopenharmony_ci { 2243141cc406Sopenharmony_ci return SANE_STATUS_UNSUPPORTED; 2244141cc406Sopenharmony_ci /* TODO: ENABLE(OPT_HALFTONE_FILE); */ 2245141cc406Sopenharmony_ci } 2246141cc406Sopenharmony_ci else 2247141cc406Sopenharmony_ci DISABLE (OPT_HALFTONE_FILE); 2248141cc406Sopenharmony_ci return SANE_STATUS_GOOD; 2249141cc406Sopenharmony_ci 2250141cc406Sopenharmony_ci case OPT_AUTOBACKGROUND: 2251141cc406Sopenharmony_ci if (info) 2252141cc406Sopenharmony_ci *info |= SANE_INFO_RELOAD_OPTIONS; 2253141cc406Sopenharmony_ci s->val[option].w = *(SANE_Bool *) val; 2254141cc406Sopenharmony_ci if (*(SANE_Bool *) val) 2255141cc406Sopenharmony_ci { 2256141cc406Sopenharmony_ci DISABLE (OPT_THRESHOLD); 2257141cc406Sopenharmony_ci ENABLE (OPT_AUTOBACKGROUND_THRESHOLD); 2258141cc406Sopenharmony_ci } 2259141cc406Sopenharmony_ci else 2260141cc406Sopenharmony_ci { 2261141cc406Sopenharmony_ci ENABLE (OPT_THRESHOLD); 2262141cc406Sopenharmony_ci DISABLE (OPT_AUTOBACKGROUND_THRESHOLD); 2263141cc406Sopenharmony_ci } 2264141cc406Sopenharmony_ci return SANE_STATUS_GOOD; 2265141cc406Sopenharmony_ci case OPT_VOLT_REF: 2266141cc406Sopenharmony_ci if (info) 2267141cc406Sopenharmony_ci *info |= SANE_INFO_RELOAD_OPTIONS; 2268141cc406Sopenharmony_ci s->val[option].w = *(SANE_Bool *) val; 2269141cc406Sopenharmony_ci if (*(SANE_Bool *) val) 2270141cc406Sopenharmony_ci { 2271141cc406Sopenharmony_ci DISABLE(OPT_BRIGHTNESS); 2272141cc406Sopenharmony_ci DISABLE(OPT_CONTRAST); 2273141cc406Sopenharmony_ci ENABLE(OPT_VOLT_REF_TOP); 2274141cc406Sopenharmony_ci ENABLE(OPT_VOLT_REF_BOTTOM); 2275141cc406Sopenharmony_ci } 2276141cc406Sopenharmony_ci else 2277141cc406Sopenharmony_ci { 2278141cc406Sopenharmony_ci ENABLE(OPT_BRIGHTNESS); 2279141cc406Sopenharmony_ci ENABLE(OPT_CONTRAST); 2280141cc406Sopenharmony_ci DISABLE(OPT_VOLT_REF_TOP); 2281141cc406Sopenharmony_ci DISABLE(OPT_VOLT_REF_BOTTOM); 2282141cc406Sopenharmony_ci } 2283141cc406Sopenharmony_ci return SANE_STATUS_GOOD; 2284141cc406Sopenharmony_ci 2285141cc406Sopenharmony_ci/* Actions: Buttons */ 2286141cc406Sopenharmony_ci 2287141cc406Sopenharmony_ci case OPT_DOWNLOAD_CALIBRATION_VECTOR: 2288141cc406Sopenharmony_ci case OPT_DOWNLOAD_CCT: 2289141cc406Sopenharmony_ci case OPT_DOWNLOAD_GAMMA: 2290141cc406Sopenharmony_ci /* TODO: fix {down/up}loads */ 2291141cc406Sopenharmony_ci return SANE_STATUS_UNSUPPORTED; 2292141cc406Sopenharmony_ci 2293141cc406Sopenharmony_ci case OPT_CUSTOM_CCT: 2294141cc406Sopenharmony_ci s->val[OPT_CUSTOM_CCT].w=*(SANE_Word *) val; 2295141cc406Sopenharmony_ci if (s->val[OPT_CUSTOM_CCT].w) 2296141cc406Sopenharmony_ci { 2297141cc406Sopenharmony_ci ENABLE(OPT_CCT); 2298141cc406Sopenharmony_ci ENABLE(OPT_DOWNLOAD_CCT); 2299141cc406Sopenharmony_ci } 2300141cc406Sopenharmony_ci else 2301141cc406Sopenharmony_ci { 2302141cc406Sopenharmony_ci DISABLE(OPT_CCT); 2303141cc406Sopenharmony_ci DISABLE(OPT_DOWNLOAD_CCT); 2304141cc406Sopenharmony_ci } 2305141cc406Sopenharmony_ci if (info) 2306141cc406Sopenharmony_ci *info |= SANE_INFO_RELOAD_OPTIONS; 2307141cc406Sopenharmony_ci return SANE_STATUS_GOOD; 2308141cc406Sopenharmony_ci 2309141cc406Sopenharmony_ci case OPT_CUSTOM_GAMMA: 2310141cc406Sopenharmony_ci s->val[OPT_CUSTOM_GAMMA].w = *(SANE_Word *) val; 2311141cc406Sopenharmony_ci gamma_update(s); 2312141cc406Sopenharmony_ci if (info) 2313141cc406Sopenharmony_ci *info |= SANE_INFO_RELOAD_OPTIONS; 2314141cc406Sopenharmony_ci return SANE_STATUS_GOOD; 2315141cc406Sopenharmony_ci 2316141cc406Sopenharmony_ci case OPT_COLOR_SENSOR: 2317141cc406Sopenharmony_ci if (s->val[option].s) 2318141cc406Sopenharmony_ci free (s->val[option].s); 2319141cc406Sopenharmony_ci s->val[option].s = strdup (val); 2320141cc406Sopenharmony_ci gamma_update(s); 2321141cc406Sopenharmony_ci if (info) 2322141cc406Sopenharmony_ci *info |= SANE_INFO_RELOAD_OPTIONS | SANE_INFO_RELOAD_PARAMS; 2323141cc406Sopenharmony_ci return SANE_STATUS_GOOD; 2324141cc406Sopenharmony_ci 2325141cc406Sopenharmony_ci /* HEAVY (RADIOACTIVE) SIDE EFFECTS: CHECKME */ 2326141cc406Sopenharmony_ci case OPT_MODE: 2327141cc406Sopenharmony_ci if (s->val[option].s) 2328141cc406Sopenharmony_ci free (s->val[option].s); 2329141cc406Sopenharmony_ci s->val[option].s = strdup (val); 2330141cc406Sopenharmony_ci 2331141cc406Sopenharmony_ci status = mode_update (s, val); 2332141cc406Sopenharmony_ci if (status != SANE_STATUS_GOOD) 2333141cc406Sopenharmony_ci return status; 2334141cc406Sopenharmony_ci 2335141cc406Sopenharmony_ci if (info) 2336141cc406Sopenharmony_ci *info |= SANE_INFO_RELOAD_OPTIONS | SANE_INFO_RELOAD_PARAMS; 2337141cc406Sopenharmony_ci return SANE_STATUS_GOOD; 2338141cc406Sopenharmony_ci 2339141cc406Sopenharmony_ci } /* End of switch */ 2340141cc406Sopenharmony_ci } /* End of SET_VALUE */ 2341141cc406Sopenharmony_ci return SANE_STATUS_INVAL; 2342141cc406Sopenharmony_ci} 2343141cc406Sopenharmony_ci 2344141cc406Sopenharmony_ciSANE_Status 2345141cc406Sopenharmony_cisane_get_parameters (SANE_Handle handle, SANE_Parameters * params) 2346141cc406Sopenharmony_ci{ 2347141cc406Sopenharmony_ci Apple_Scanner *s = handle; 2348141cc406Sopenharmony_ci 2349141cc406Sopenharmony_ci DBG (FLOW_CONTROL, "Entering sane_get_parameters\n"); 2350141cc406Sopenharmony_ci calc_parameters (s); 2351141cc406Sopenharmony_ci 2352141cc406Sopenharmony_ci 2353141cc406Sopenharmony_ci if (params) 2354141cc406Sopenharmony_ci *params = s->params; 2355141cc406Sopenharmony_ci return SANE_STATUS_GOOD; 2356141cc406Sopenharmony_ci} 2357141cc406Sopenharmony_ci 2358141cc406Sopenharmony_ciSANE_Status 2359141cc406Sopenharmony_cisane_start (SANE_Handle handle) 2360141cc406Sopenharmony_ci{ 2361141cc406Sopenharmony_ci Apple_Scanner *s = handle; 2362141cc406Sopenharmony_ci SANE_Status status; 2363141cc406Sopenharmony_ci 2364141cc406Sopenharmony_ci /* First make sure we have a current parameter set. Some of the 2365141cc406Sopenharmony_ci parameters will be overwritten below, but that's OK. */ 2366141cc406Sopenharmony_ci 2367141cc406Sopenharmony_ci calc_parameters (s); 2368141cc406Sopenharmony_ci 2369141cc406Sopenharmony_ci if (s->fd < 0) 2370141cc406Sopenharmony_ci { 2371141cc406Sopenharmony_ci /* this is the first (and maybe only) pass... */ 2372141cc406Sopenharmony_ci 2373141cc406Sopenharmony_ci status = sanei_scsi_open (s->hw->sane.name, &s->fd, sense_handler, 0); 2374141cc406Sopenharmony_ci if (status != SANE_STATUS_GOOD) 2375141cc406Sopenharmony_ci { 2376141cc406Sopenharmony_ci DBG (ERROR_MESSAGE, "open: open of %s failed: %s\n", 2377141cc406Sopenharmony_ci s->hw->sane.name, sane_strstatus (status)); 2378141cc406Sopenharmony_ci return status; 2379141cc406Sopenharmony_ci } 2380141cc406Sopenharmony_ci } 2381141cc406Sopenharmony_ci 2382141cc406Sopenharmony_ci status = wait_ready (s->fd); 2383141cc406Sopenharmony_ci if (status != SANE_STATUS_GOOD) 2384141cc406Sopenharmony_ci { 2385141cc406Sopenharmony_ci DBG (ERROR_MESSAGE, "open: wait_ready() failed: %s\n", 2386141cc406Sopenharmony_ci sane_strstatus (status)); 2387141cc406Sopenharmony_ci goto stop_scanner_and_return; 2388141cc406Sopenharmony_ci } 2389141cc406Sopenharmony_ci 2390141cc406Sopenharmony_ci status = mode_select (s); 2391141cc406Sopenharmony_ci if (status != SANE_STATUS_GOOD) 2392141cc406Sopenharmony_ci { 2393141cc406Sopenharmony_ci DBG (ERROR_MESSAGE, "sane_start: mode_select command failed: %s\n", 2394141cc406Sopenharmony_ci sane_strstatus (status)); 2395141cc406Sopenharmony_ci goto stop_scanner_and_return; 2396141cc406Sopenharmony_ci } 2397141cc406Sopenharmony_ci 2398141cc406Sopenharmony_ci status = scan_area_and_windows (s); 2399141cc406Sopenharmony_ci if (status != SANE_STATUS_GOOD) 2400141cc406Sopenharmony_ci { 2401141cc406Sopenharmony_ci DBG (ERROR_MESSAGE, "open: set scan area command failed: %s\n", 2402141cc406Sopenharmony_ci sane_strstatus (status)); 2403141cc406Sopenharmony_ci goto stop_scanner_and_return; 2404141cc406Sopenharmony_ci } 2405141cc406Sopenharmony_ci 2406141cc406Sopenharmony_ci status = request_sense (s); 2407141cc406Sopenharmony_ci if (status != SANE_STATUS_GOOD) 2408141cc406Sopenharmony_ci { 2409141cc406Sopenharmony_ci DBG (ERROR_MESSAGE, "sane_start: request_sense revealed error: %s\n", 2410141cc406Sopenharmony_ci sane_strstatus (status)); 2411141cc406Sopenharmony_ci goto stop_scanner_and_return; 2412141cc406Sopenharmony_ci } 2413141cc406Sopenharmony_ci 2414141cc406Sopenharmony_ci s->scanning = SANE_TRUE; 2415141cc406Sopenharmony_ci s->AbortedByUser = SANE_FALSE; 2416141cc406Sopenharmony_ci 2417141cc406Sopenharmony_ci status = start_scan (s); 2418141cc406Sopenharmony_ci if (status != SANE_STATUS_GOOD) 2419141cc406Sopenharmony_ci goto stop_scanner_and_return; 2420141cc406Sopenharmony_ci 2421141cc406Sopenharmony_ci return SANE_STATUS_GOOD; 2422141cc406Sopenharmony_ci 2423141cc406Sopenharmony_cistop_scanner_and_return: 2424141cc406Sopenharmony_ci s->scanning = SANE_FALSE; 2425141cc406Sopenharmony_ci s->AbortedByUser = SANE_FALSE; 2426141cc406Sopenharmony_ci return status; 2427141cc406Sopenharmony_ci} 2428141cc406Sopenharmony_ci 2429141cc406Sopenharmony_ciSANE_Status 2430141cc406Sopenharmony_cisane_read (SANE_Handle handle, SANE_Byte * buf, SANE_Int max_len, 2431141cc406Sopenharmony_ci SANE_Int * len) 2432141cc406Sopenharmony_ci{ 2433141cc406Sopenharmony_ci Apple_Scanner *s = handle; 2434141cc406Sopenharmony_ci SANE_Status status; 2435141cc406Sopenharmony_ci 2436141cc406Sopenharmony_ci uint8_t get_data_status[10]; 2437141cc406Sopenharmony_ci uint8_t read[10]; 2438141cc406Sopenharmony_ci 2439141cc406Sopenharmony_ci#ifdef RESERVE_RELEASE_HACK 2440141cc406Sopenharmony_ci uint8_t reserve[6]; 2441141cc406Sopenharmony_ci uint8_t release[6]; 2442141cc406Sopenharmony_ci#endif 2443141cc406Sopenharmony_ci 2444141cc406Sopenharmony_ci uint8_t result[12]; 2445141cc406Sopenharmony_ci size_t size; 2446141cc406Sopenharmony_ci SANE_Int data_length = 0; 2447141cc406Sopenharmony_ci SANE_Int data_av = 0; 2448141cc406Sopenharmony_ci SANE_Int offset = 0; 2449141cc406Sopenharmony_ci SANE_Int rread = 0; 2450141cc406Sopenharmony_ci SANE_Bool Pseudo8bit = SANE_FALSE; 2451141cc406Sopenharmony_ci 2452141cc406Sopenharmony_ci#ifdef NEUTRALIZE_BACKEND 2453141cc406Sopenharmony_ci *len=max_len; 2454141cc406Sopenharmony_ci return SANE_STATUS_GOOD; 2455141cc406Sopenharmony_ci 2456141cc406Sopenharmony_ci#else 2457141cc406Sopenharmony_ci *len = 0; 2458141cc406Sopenharmony_ci if (!s->scanning) return SANE_STATUS_EOF; 2459141cc406Sopenharmony_ci 2460141cc406Sopenharmony_ci 2461141cc406Sopenharmony_ci if (!strcmp (s->val[OPT_MODE].s, "Gray16")) 2462141cc406Sopenharmony_ci Pseudo8bit = SANE_TRUE; 2463141cc406Sopenharmony_ci 2464141cc406Sopenharmony_ci /* TODO: The current function only implements for APPLESCANNER In 2465141cc406Sopenharmony_ci order to use the COLORONESCANNER you have to study the docs to 2466141cc406Sopenharmony_ci see how it the parameters get modified before scan. From this 2467141cc406Sopenharmony_ci starting point it should be trivial to use a ONESCANNER int the 2468141cc406Sopenharmony_ci gray256 mode but I don't have one from these pets in home. MF */ 2469141cc406Sopenharmony_ci 2470141cc406Sopenharmony_ci 2471141cc406Sopenharmony_ci memset (get_data_status, 0, sizeof (get_data_status)); 2472141cc406Sopenharmony_ci get_data_status[0] = APPLE_SCSI_GET_DATA_STATUS; 2473141cc406Sopenharmony_ci get_data_status[1] = 1; /* Wait */ 2474141cc406Sopenharmony_ci STORE24 (get_data_status + 6, sizeof (result)); 2475141cc406Sopenharmony_ci 2476141cc406Sopenharmony_ci memset (read, 0, sizeof (read)); 2477141cc406Sopenharmony_ci read[0] = APPLE_SCSI_READ_SCANNED_DATA; 2478141cc406Sopenharmony_ci 2479141cc406Sopenharmony_ci 2480141cc406Sopenharmony_ci#ifdef RESERVE_RELEASE_HACK 2481141cc406Sopenharmony_ci memset (reserve, 0, sizeof (reserve)); 2482141cc406Sopenharmony_ci reserve[0] = APPLE_SCSI_RESERVE; 2483141cc406Sopenharmony_ci 2484141cc406Sopenharmony_ci reserve[1]=CONTROLLER_SCSI_ID; 2485141cc406Sopenharmony_ci reserve[1]=reserve[1] << 1; 2486141cc406Sopenharmony_ci reserve[1]|=SETTHIRDPARTY; 2487141cc406Sopenharmony_ci 2488141cc406Sopenharmony_ci memset (release, 0, sizeof (release)); 2489141cc406Sopenharmony_ci release[0] = APPLE_SCSI_RELEASE; 2490141cc406Sopenharmony_ci release[1]=CONTROLLER_SCSI_ID; 2491141cc406Sopenharmony_ci release[1]=reserve[1] << 1; 2492141cc406Sopenharmony_ci release[1]|=SETTHIRDPARTY; 2493141cc406Sopenharmony_ci 2494141cc406Sopenharmony_ci#endif 2495141cc406Sopenharmony_ci 2496141cc406Sopenharmony_ci do 2497141cc406Sopenharmony_ci { 2498141cc406Sopenharmony_ci size = sizeof (result); 2499141cc406Sopenharmony_ci status = sanei_scsi_cmd (s->fd, get_data_status, 2500141cc406Sopenharmony_ci sizeof (get_data_status), result, &size); 2501141cc406Sopenharmony_ci 2502141cc406Sopenharmony_ci if (status != SANE_STATUS_GOOD) 2503141cc406Sopenharmony_ci return status; 2504141cc406Sopenharmony_ci if (!size) 2505141cc406Sopenharmony_ci { 2506141cc406Sopenharmony_ci DBG (ERROR_MESSAGE, "sane_read: cannot get_data_status.\n"); 2507141cc406Sopenharmony_ci return SANE_STATUS_IO_ERROR; 2508141cc406Sopenharmony_ci } 2509141cc406Sopenharmony_ci 2510141cc406Sopenharmony_ci data_length = READ24 (result); 2511141cc406Sopenharmony_ci data_av = READ24 (result + 9); 2512141cc406Sopenharmony_ci 2513141cc406Sopenharmony_ci if (data_length) 2514141cc406Sopenharmony_ci { 2515141cc406Sopenharmony_ci /* if (result[3] & 1) Scanner Blocked: Retrieve data */ 2516141cc406Sopenharmony_ci if ((result[3] & 1) || data_av) 2517141cc406Sopenharmony_ci { 2518141cc406Sopenharmony_ci DBG (IO_MESSAGE, 2519141cc406Sopenharmony_ci "sane_read: (status) Available in scanner buffer %u.\n", 2520141cc406Sopenharmony_ci data_av); 2521141cc406Sopenharmony_ci 2522141cc406Sopenharmony_ci if (Pseudo8bit) 2523141cc406Sopenharmony_ci if ((data_av << 1) + offset > max_len) 2524141cc406Sopenharmony_ci rread = (max_len - offset) >> 1; 2525141cc406Sopenharmony_ci else 2526141cc406Sopenharmony_ci rread = data_av; 2527141cc406Sopenharmony_ci else if (data_av + offset > max_len) 2528141cc406Sopenharmony_ci rread = max_len - offset; 2529141cc406Sopenharmony_ci else 2530141cc406Sopenharmony_ci rread = data_av; 2531141cc406Sopenharmony_ci 2532141cc406Sopenharmony_ci DBG (IO_MESSAGE, 2533141cc406Sopenharmony_ci "sane_read: (action) Actual read request for %u bytes.\n", 2534141cc406Sopenharmony_ci rread); 2535141cc406Sopenharmony_ci 2536141cc406Sopenharmony_ci size = rread; 2537141cc406Sopenharmony_ci 2538141cc406Sopenharmony_ci STORE24 (read + 6, rread); 2539141cc406Sopenharmony_ci 2540141cc406Sopenharmony_ci#ifdef RESERVE_RELEASE_HACK 2541141cc406Sopenharmony_ci { 2542141cc406Sopenharmony_ci SANE_Status status; 2543141cc406Sopenharmony_ci DBG(IO_MESSAGE,"Reserving the SCSI bus.\n"); 2544141cc406Sopenharmony_ci status=sanei_scsi_cmd (s->fd,reserve,sizeof(reserve),0,0); 2545141cc406Sopenharmony_ci DBG(IO_MESSAGE,"Reserving... status:= %d\n",status); 2546141cc406Sopenharmony_ci } 2547141cc406Sopenharmony_ci#endif /* RESERVE_RELEASE_HACK */ 2548141cc406Sopenharmony_ci 2549141cc406Sopenharmony_ci status = sanei_scsi_cmd (s->fd, read, sizeof (read), 2550141cc406Sopenharmony_ci buf + offset, &size); 2551141cc406Sopenharmony_ci 2552141cc406Sopenharmony_ci#ifdef RESERVE_RELEASE_HACK 2553141cc406Sopenharmony_ci { 2554141cc406Sopenharmony_ci SANE_Status status; 2555141cc406Sopenharmony_ci DBG(IO_MESSAGE,"Releasing the SCSI bus.\n"); 2556141cc406Sopenharmony_ci status=sanei_scsi_cmd (s->fd,release,sizeof(release),0,0); 2557141cc406Sopenharmony_ci DBG(IO_MESSAGE,"Releasing... status:= %d\n",status); 2558141cc406Sopenharmony_ci } 2559141cc406Sopenharmony_ci#endif /* RESERVE_RELEASE_HACK */ 2560141cc406Sopenharmony_ci 2561141cc406Sopenharmony_ci 2562141cc406Sopenharmony_ci if (Pseudo8bit) 2563141cc406Sopenharmony_ci { 2564141cc406Sopenharmony_ci SANE_Int byte; 2565141cc406Sopenharmony_ci SANE_Int pos = offset + (rread << 1) - 1; 2566141cc406Sopenharmony_ci SANE_Byte B; 2567141cc406Sopenharmony_ci for (byte = offset + rread - 1; byte >= offset; byte--) 2568141cc406Sopenharmony_ci { 2569141cc406Sopenharmony_ci B = buf[byte]; 2570141cc406Sopenharmony_ci buf[pos--] = 255 - (B << 4); /* low (right) nibble */ 2571141cc406Sopenharmony_ci buf[pos--] = 255 - (B & 0xF0); /* high (left) nibble */ 2572141cc406Sopenharmony_ci } 2573141cc406Sopenharmony_ci offset += size << 1; 2574141cc406Sopenharmony_ci } 2575141cc406Sopenharmony_ci else 2576141cc406Sopenharmony_ci offset += size; 2577141cc406Sopenharmony_ci 2578141cc406Sopenharmony_ci DBG (IO_MESSAGE, "sane_read: Buffer %u of %u full %g%%\n", 2579141cc406Sopenharmony_ci offset, max_len, (double) (offset * 100. / max_len)); 2580141cc406Sopenharmony_ci } 2581141cc406Sopenharmony_ci } 2582141cc406Sopenharmony_ci } 2583141cc406Sopenharmony_ci while (offset < max_len && data_length != 0 && !s->AbortedByUser); 2584141cc406Sopenharmony_ci 2585141cc406Sopenharmony_ci 2586141cc406Sopenharmony_ci if (s->AbortedByUser) 2587141cc406Sopenharmony_ci { 2588141cc406Sopenharmony_ci s->scanning = SANE_FALSE; 2589141cc406Sopenharmony_ci status = sanei_scsi_cmd (s->fd, test_unit_ready, 2590141cc406Sopenharmony_ci sizeof (test_unit_ready), 0, 0); 2591141cc406Sopenharmony_ci if (status != SANE_STATUS_GOOD) 2592141cc406Sopenharmony_ci return status; 2593141cc406Sopenharmony_ci return SANE_STATUS_CANCELLED; 2594141cc406Sopenharmony_ci } 2595141cc406Sopenharmony_ci 2596141cc406Sopenharmony_ci if (!data_length) /* If not blocked */ 2597141cc406Sopenharmony_ci { 2598141cc406Sopenharmony_ci s->scanning = SANE_FALSE; 2599141cc406Sopenharmony_ci 2600141cc406Sopenharmony_ci DBG (IO_MESSAGE, "sane_read: (status) Oups! No more data..."); 2601141cc406Sopenharmony_ci if (!offset) 2602141cc406Sopenharmony_ci { 2603141cc406Sopenharmony_ci *len = 0; 2604141cc406Sopenharmony_ci DBG (IO_MESSAGE, "EOF\n"); 2605141cc406Sopenharmony_ci return SANE_STATUS_EOF; 2606141cc406Sopenharmony_ci } 2607141cc406Sopenharmony_ci else 2608141cc406Sopenharmony_ci { 2609141cc406Sopenharmony_ci *len = offset; 2610141cc406Sopenharmony_ci DBG (IO_MESSAGE, "GOOD\n"); 2611141cc406Sopenharmony_ci return SANE_STATUS_GOOD; 2612141cc406Sopenharmony_ci } 2613141cc406Sopenharmony_ci } 2614141cc406Sopenharmony_ci 2615141cc406Sopenharmony_ci 2616141cc406Sopenharmony_ci DBG (FLOW_CONTROL, 2617141cc406Sopenharmony_ci "sane_read: Normal Exiting (?), Aborted=%u, data_length=%u\n", 2618141cc406Sopenharmony_ci s->AbortedByUser, data_length); 2619141cc406Sopenharmony_ci *len = offset; 2620141cc406Sopenharmony_ci 2621141cc406Sopenharmony_ci return SANE_STATUS_GOOD; 2622141cc406Sopenharmony_ci 2623141cc406Sopenharmony_ci#endif /* NEUTRALIZE_BACKEND */ 2624141cc406Sopenharmony_ci} 2625141cc406Sopenharmony_ci 2626141cc406Sopenharmony_civoid 2627141cc406Sopenharmony_cisane_cancel (SANE_Handle handle) 2628141cc406Sopenharmony_ci{ 2629141cc406Sopenharmony_ci Apple_Scanner *s = handle; 2630141cc406Sopenharmony_ci 2631141cc406Sopenharmony_ci if (s->scanning) 2632141cc406Sopenharmony_ci { 2633141cc406Sopenharmony_ci if (s->AbortedByUser) 2634141cc406Sopenharmony_ci { 2635141cc406Sopenharmony_ci DBG (FLOW_CONTROL, 2636141cc406Sopenharmony_ci "sane_cancel: Already Aborted. Please Wait...\n"); 2637141cc406Sopenharmony_ci } 2638141cc406Sopenharmony_ci else 2639141cc406Sopenharmony_ci { 2640141cc406Sopenharmony_ci s->scanning=SANE_FALSE; 2641141cc406Sopenharmony_ci s->AbortedByUser = SANE_TRUE; 2642141cc406Sopenharmony_ci DBG (FLOW_CONTROL, "sane_cancel: Signal Caught! Aborting...\n"); 2643141cc406Sopenharmony_ci } 2644141cc406Sopenharmony_ci } 2645141cc406Sopenharmony_ci else 2646141cc406Sopenharmony_ci { 2647141cc406Sopenharmony_ci if (s->AbortedByUser) 2648141cc406Sopenharmony_ci { 2649141cc406Sopenharmony_ci DBG (FLOW_CONTROL, "sane_cancel: Scan has not been Initiated yet, " 2650141cc406Sopenharmony_ci "or it is already aborted.\n"); 2651141cc406Sopenharmony_ci s->AbortedByUser = SANE_FALSE; 2652141cc406Sopenharmony_ci sanei_scsi_cmd (s->fd, test_unit_ready, 2653141cc406Sopenharmony_ci sizeof (test_unit_ready), 0, 0); 2654141cc406Sopenharmony_ci } 2655141cc406Sopenharmony_ci else 2656141cc406Sopenharmony_ci { 2657141cc406Sopenharmony_ci DBG (FLOW_CONTROL, "sane_cancel: Scan has not been Initiated " 2658141cc406Sopenharmony_ci "yet (or it's over).\n"); 2659141cc406Sopenharmony_ci } 2660141cc406Sopenharmony_ci } 2661141cc406Sopenharmony_ci 2662141cc406Sopenharmony_ci return; 2663141cc406Sopenharmony_ci} 2664141cc406Sopenharmony_ci 2665141cc406Sopenharmony_ciSANE_Status 2666141cc406Sopenharmony_cisane_set_io_mode (SANE_Handle handle, SANE_Bool non_blocking) 2667141cc406Sopenharmony_ci{ 2668141cc406Sopenharmony_ciDBG (FLOW_CONTROL,"sane_set_io_mode: Entering.\n"); 2669141cc406Sopenharmony_ci 2670141cc406Sopenharmony_ci (void) handle; /* silence gcc */ 2671141cc406Sopenharmony_ci 2672141cc406Sopenharmony_ciif (non_blocking) 2673141cc406Sopenharmony_ci { 2674141cc406Sopenharmony_ci DBG (FLOW_CONTROL, "sane_set_io_mode: Don't call me please. " 2675141cc406Sopenharmony_ci "Unimplemented function\n"); 2676141cc406Sopenharmony_ci return SANE_STATUS_UNSUPPORTED; 2677141cc406Sopenharmony_ci } 2678141cc406Sopenharmony_ci 2679141cc406Sopenharmony_cireturn SANE_STATUS_GOOD; 2680141cc406Sopenharmony_ci} 2681141cc406Sopenharmony_ci 2682141cc406Sopenharmony_ciSANE_Status 2683141cc406Sopenharmony_cisane_get_select_fd (SANE_Handle handle, SANE_Int * fd) 2684141cc406Sopenharmony_ci{ 2685141cc406Sopenharmony_ci (void) handle; /* silence gcc */ 2686141cc406Sopenharmony_ci (void) fd; /* silence gcc */ 2687141cc406Sopenharmony_ci 2688141cc406Sopenharmony_ci DBG (FLOW_CONTROL, "sane_get_select_fd: Don't call me please. " 2689141cc406Sopenharmony_ci "Unimplemented function\n"); 2690141cc406Sopenharmony_ci return SANE_STATUS_UNSUPPORTED; 2691141cc406Sopenharmony_ci} 2692