1141cc406Sopenharmony_ci/* sane - Scanner Access Now Easy. 2141cc406Sopenharmony_ci Copyright (C) 1998, Feico W. Dillema 3141cc406Sopenharmony_ci This file is part of the SANE package. 4141cc406Sopenharmony_ci 5141cc406Sopenharmony_ci This program is free software; you can redistribute it and/or 6141cc406Sopenharmony_ci modify it under the terms of the GNU General Public License as 7141cc406Sopenharmony_ci published by the Free Software Foundation; either version 2 of the 8141cc406Sopenharmony_ci License, or (at your option) any later version. 9141cc406Sopenharmony_ci 10141cc406Sopenharmony_ci This program is distributed in the hope that it will be useful, but 11141cc406Sopenharmony_ci WITHOUT ANY WARRANTY; without even the implied warranty of 12141cc406Sopenharmony_ci MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13141cc406Sopenharmony_ci General Public License for more details. 14141cc406Sopenharmony_ci 15141cc406Sopenharmony_ci You should have received a copy of the GNU General Public License 16141cc406Sopenharmony_ci along with this program. If not, see <https://www.gnu.org/licenses/>. 17141cc406Sopenharmony_ci 18141cc406Sopenharmony_ci As a special exception, the authors of SANE give permission for 19141cc406Sopenharmony_ci additional uses of the libraries contained in this release of SANE. 20141cc406Sopenharmony_ci 21141cc406Sopenharmony_ci The exception is that, if you link a SANE library with other files 22141cc406Sopenharmony_ci to produce an executable, this does not by itself cause the 23141cc406Sopenharmony_ci resulting executable to be covered by the GNU General Public 24141cc406Sopenharmony_ci License. Your use of that executable is in no way restricted on 25141cc406Sopenharmony_ci account of linking the SANE library code into it. 26141cc406Sopenharmony_ci 27141cc406Sopenharmony_ci This exception does not, however, invalidate any other reasons why 28141cc406Sopenharmony_ci the executable file might be covered by the GNU General Public 29141cc406Sopenharmony_ci License. 30141cc406Sopenharmony_ci 31141cc406Sopenharmony_ci If you submit changes to SANE to the maintainers to be included in 32141cc406Sopenharmony_ci a subsequent release, you agree by submitting the changes that 33141cc406Sopenharmony_ci those changes may be distributed with this exception intact. 34141cc406Sopenharmony_ci 35141cc406Sopenharmony_ci If you write modifications of your own for SANE, it is your choice 36141cc406Sopenharmony_ci whether to permit this exception to apply to your modifications. 37141cc406Sopenharmony_ci If you do not wish that, delete this exception notice. 38141cc406Sopenharmony_ci*/ 39141cc406Sopenharmony_ci 40141cc406Sopenharmony_ci/* 41141cc406Sopenharmony_ci This file implements a SANE backend for Ricoh flatbed scanners. 42141cc406Sopenharmony_ci*/ 43141cc406Sopenharmony_ci 44141cc406Sopenharmony_ci#include "../include/sane/config.h" 45141cc406Sopenharmony_ci 46141cc406Sopenharmony_ci#include <limits.h> 47141cc406Sopenharmony_ci#include <stdlib.h> 48141cc406Sopenharmony_ci#include <stdarg.h> 49141cc406Sopenharmony_ci#include <string.h> 50141cc406Sopenharmony_ci#include <time.h> 51141cc406Sopenharmony_ci#include <sys/time.h> 52141cc406Sopenharmony_ci#include <unistd.h> 53141cc406Sopenharmony_ci#include <ctype.h> 54141cc406Sopenharmony_ci 55141cc406Sopenharmony_ci#include "../include/sane/sane.h" 56141cc406Sopenharmony_ci#include "../include/sane/saneopts.h" 57141cc406Sopenharmony_ci#include "../include/sane/sanei_scsi.h" 58141cc406Sopenharmony_ci 59141cc406Sopenharmony_ci#define BACKEND_NAME ricoh 60141cc406Sopenharmony_ci#include "../include/sane/sanei_backend.h" 61141cc406Sopenharmony_ci 62141cc406Sopenharmony_ci#ifndef PATH_MAX 63141cc406Sopenharmony_ci# define PATH_MAX 1024 64141cc406Sopenharmony_ci#endif 65141cc406Sopenharmony_ci 66141cc406Sopenharmony_ci#include "../include/sane/sanei_config.h" 67141cc406Sopenharmony_ci#define RICOH_CONFIG_FILE "ricoh.conf" 68141cc406Sopenharmony_ci 69141cc406Sopenharmony_ci#include "ricoh.h" 70141cc406Sopenharmony_ci 71141cc406Sopenharmony_ci#define MAX(a,b) ((a) > (b) ? (a) : (b)) 72141cc406Sopenharmony_ci 73141cc406Sopenharmony_cistatic const SANE_Device **devlist = NULL; 74141cc406Sopenharmony_cistatic int num_devices = 0; 75141cc406Sopenharmony_cistatic Ricoh_Device *first_dev = NULL; 76141cc406Sopenharmony_cistatic Ricoh_Scanner *first_handle = NULL; 77141cc406Sopenharmony_cistatic int is50 = 0; 78141cc406Sopenharmony_ci 79141cc406Sopenharmony_ci#include "ricoh-scsi.c" 80141cc406Sopenharmony_ci 81141cc406Sopenharmony_cistatic size_t 82141cc406Sopenharmony_cimax_string_size (const SANE_String_Const strings[]) 83141cc406Sopenharmony_ci{ 84141cc406Sopenharmony_ci size_t size, max_size = 0; 85141cc406Sopenharmony_ci int i; 86141cc406Sopenharmony_ci DBG (11, ">> max_string_size\n"); 87141cc406Sopenharmony_ci 88141cc406Sopenharmony_ci for (i = 0; strings[i]; ++i) 89141cc406Sopenharmony_ci { 90141cc406Sopenharmony_ci size = strlen (strings[i]) + 1; 91141cc406Sopenharmony_ci if (size > max_size) 92141cc406Sopenharmony_ci max_size = size; 93141cc406Sopenharmony_ci } 94141cc406Sopenharmony_ci 95141cc406Sopenharmony_ci DBG (11, "<< max_string_size\n"); 96141cc406Sopenharmony_ci return max_size; 97141cc406Sopenharmony_ci} 98141cc406Sopenharmony_ci 99141cc406Sopenharmony_cistatic SANE_Status 100141cc406Sopenharmony_ciattach (const char *devnam, Ricoh_Device ** devp) 101141cc406Sopenharmony_ci{ 102141cc406Sopenharmony_ci SANE_Status status; 103141cc406Sopenharmony_ci Ricoh_Device *dev; 104141cc406Sopenharmony_ci 105141cc406Sopenharmony_ci int fd; 106141cc406Sopenharmony_ci struct inquiry_data ibuf; 107141cc406Sopenharmony_ci struct measurements_units_page mup; 108141cc406Sopenharmony_ci struct ricoh_window_data wbuf; 109141cc406Sopenharmony_ci size_t buf_size; 110141cc406Sopenharmony_ci char *str; 111141cc406Sopenharmony_ci DBG (11, ">> attach\n"); 112141cc406Sopenharmony_ci 113141cc406Sopenharmony_ci for (dev = first_dev; dev; dev = dev->next) 114141cc406Sopenharmony_ci { 115141cc406Sopenharmony_ci if (strcmp (dev->sane.name, devnam) == 0) 116141cc406Sopenharmony_ci { 117141cc406Sopenharmony_ci if (devp) 118141cc406Sopenharmony_ci *devp = dev; 119141cc406Sopenharmony_ci return (SANE_STATUS_GOOD); 120141cc406Sopenharmony_ci } 121141cc406Sopenharmony_ci } 122141cc406Sopenharmony_ci 123141cc406Sopenharmony_ci DBG (3, "attach: opening %s\n", devnam); 124141cc406Sopenharmony_ci status = sanei_scsi_open (devnam, &fd, NULL, NULL); 125141cc406Sopenharmony_ci if (status != SANE_STATUS_GOOD) 126141cc406Sopenharmony_ci { 127141cc406Sopenharmony_ci DBG (1, "attach: open failed: %s\n", sane_strstatus (status)); 128141cc406Sopenharmony_ci return (status); 129141cc406Sopenharmony_ci } 130141cc406Sopenharmony_ci 131141cc406Sopenharmony_ci DBG (3, "attach: sending INQUIRY\n"); 132141cc406Sopenharmony_ci memset (&ibuf, 0, sizeof (ibuf)); 133141cc406Sopenharmony_ci buf_size = sizeof(ibuf); 134141cc406Sopenharmony_ci status = inquiry (fd, &ibuf, &buf_size); 135141cc406Sopenharmony_ci if (status != SANE_STATUS_GOOD) 136141cc406Sopenharmony_ci { 137141cc406Sopenharmony_ci DBG (1, "attach: inquiry failed: %s\n", sane_strstatus (status)); 138141cc406Sopenharmony_ci sanei_scsi_close (fd); 139141cc406Sopenharmony_ci return (status); 140141cc406Sopenharmony_ci } 141141cc406Sopenharmony_ci 142141cc406Sopenharmony_ci if (ibuf.devtype != 6 143141cc406Sopenharmony_ci || strncmp ((char *)ibuf.vendor, "RICOH", 5) != 0 144141cc406Sopenharmony_ci || (strncmp ((char *)ibuf.product, "IS50", 4) != 0 145141cc406Sopenharmony_ci && strncmp ((char *)ibuf.product, "IS60", 4) != 0)) 146141cc406Sopenharmony_ci { 147141cc406Sopenharmony_ci DBG (1, "attach: device doesn't look like the Ricoh scanner I know\n"); 148141cc406Sopenharmony_ci sanei_scsi_close (fd); 149141cc406Sopenharmony_ci return (SANE_STATUS_INVAL); 150141cc406Sopenharmony_ci } 151141cc406Sopenharmony_ci is50 = (strncmp ((char *)ibuf.product, "IS50", 4) == 0); 152141cc406Sopenharmony_ci 153141cc406Sopenharmony_ci DBG (3, "attach: sending TEST_UNIT_READY\n"); 154141cc406Sopenharmony_ci status = test_unit_ready (fd); 155141cc406Sopenharmony_ci if (status != SANE_STATUS_GOOD) 156141cc406Sopenharmony_ci { 157141cc406Sopenharmony_ci DBG (1, "attach: test unit ready failed (%s)\n", 158141cc406Sopenharmony_ci sane_strstatus (status)); 159141cc406Sopenharmony_ci sanei_scsi_close (fd); 160141cc406Sopenharmony_ci return (status); 161141cc406Sopenharmony_ci } 162141cc406Sopenharmony_ci 163141cc406Sopenharmony_ci DBG (3, "attach: sending OBJECT POSITION\n"); 164141cc406Sopenharmony_ci status = object_position (fd); 165141cc406Sopenharmony_ci if (status != SANE_STATUS_GOOD) 166141cc406Sopenharmony_ci { 167141cc406Sopenharmony_ci DBG (1, "attach: OBJECT POSITION failed\n"); 168141cc406Sopenharmony_ci sanei_scsi_close (fd); 169141cc406Sopenharmony_ci return (SANE_STATUS_INVAL); 170141cc406Sopenharmony_ci } 171141cc406Sopenharmony_ci 172141cc406Sopenharmony_ci memset (&mup, 0, sizeof (mup)); 173141cc406Sopenharmony_ci mup.page_code = MEASUREMENTS_PAGE; 174141cc406Sopenharmony_ci mup.parameter_length = 0x06; 175141cc406Sopenharmony_ci mup.bmu = INCHES; 176141cc406Sopenharmony_ci mup.mud[0] = (DEFAULT_MUD >> 8) & 0xff; 177141cc406Sopenharmony_ci mup.mud[1] = (DEFAULT_MUD & 0xff); 178141cc406Sopenharmony_ci 179141cc406Sopenharmony_ci#if 0 180141cc406Sopenharmony_ci DBG (3, "attach: sending MODE SELECT\n"); 181141cc406Sopenharmony_ci status = mode_select (fd, (struct mode_pages *) &mup); 182141cc406Sopenharmony_ci if (status != SANE_STATUS_GOOD) 183141cc406Sopenharmony_ci { 184141cc406Sopenharmony_ci DBG (1, "attach: MODE_SELECT failed\n"); 185141cc406Sopenharmony_ci sanei_scsi_close (fd); 186141cc406Sopenharmony_ci return (SANE_STATUS_INVAL); 187141cc406Sopenharmony_ci } 188141cc406Sopenharmony_ci#endif 189141cc406Sopenharmony_ci 190141cc406Sopenharmony_ci#if 0 191141cc406Sopenharmony_ci DBG (3, "attach: sending MODE SENSE\n"); 192141cc406Sopenharmony_ci memset (&mup, 0, sizeof (mup)); 193141cc406Sopenharmony_ci status = mode_sense (fd, (struct mode_pages *) &mup, PC_CURRENT | MEASUREMENTS_PAGE); 194141cc406Sopenharmony_ci if (status != SANE_STATUS_GOOD) 195141cc406Sopenharmony_ci { 196141cc406Sopenharmony_ci DBG (1, "attach: MODE_SENSE failed\n"); 197141cc406Sopenharmony_ci sanei_scsi_close (fd); 198141cc406Sopenharmony_ci return (SANE_STATUS_INVAL); 199141cc406Sopenharmony_ci } 200141cc406Sopenharmony_ci#endif 201141cc406Sopenharmony_ci 202141cc406Sopenharmony_ci DBG (3, "attach: sending GET WINDOW\n"); 203141cc406Sopenharmony_ci memset (&wbuf, 0, sizeof (wbuf)); 204141cc406Sopenharmony_ci status = get_window (fd, &wbuf); 205141cc406Sopenharmony_ci if (status != SANE_STATUS_GOOD) 206141cc406Sopenharmony_ci { 207141cc406Sopenharmony_ci DBG (1, "attach: GET_WINDOW failed %d\n", status); 208141cc406Sopenharmony_ci sanei_scsi_close (fd); 209141cc406Sopenharmony_ci DBG (11, "<< attach\n"); 210141cc406Sopenharmony_ci return (SANE_STATUS_INVAL); 211141cc406Sopenharmony_ci } 212141cc406Sopenharmony_ci 213141cc406Sopenharmony_ci sanei_scsi_close (fd); 214141cc406Sopenharmony_ci 215141cc406Sopenharmony_ci dev = malloc (sizeof (*dev)); 216141cc406Sopenharmony_ci if (!dev) 217141cc406Sopenharmony_ci return (SANE_STATUS_NO_MEM); 218141cc406Sopenharmony_ci memset (dev, 0, sizeof (*dev)); 219141cc406Sopenharmony_ci 220141cc406Sopenharmony_ci dev->sane.name = strdup (devnam); 221141cc406Sopenharmony_ci dev->sane.vendor = "RICOH"; 222141cc406Sopenharmony_ci 223141cc406Sopenharmony_ci size_t prod_rev_size = sizeof(ibuf.product) + sizeof(ibuf.revision) + 1; 224141cc406Sopenharmony_ci str = malloc (prod_rev_size); 225141cc406Sopenharmony_ci if (str) 226141cc406Sopenharmony_ci { 227141cc406Sopenharmony_ci snprintf (str, prod_rev_size, "%.*s%.*s", 228141cc406Sopenharmony_ci (int) sizeof(ibuf.product), (const char *) ibuf.product, 229141cc406Sopenharmony_ci (int) sizeof(ibuf.revision), (const char *) ibuf.revision); 230141cc406Sopenharmony_ci } 231141cc406Sopenharmony_ci dev->sane.model = str; 232141cc406Sopenharmony_ci dev->sane.type = "flatbed scanner"; 233141cc406Sopenharmony_ci 234141cc406Sopenharmony_ci DBG (5, "dev->sane.name = %s\n", dev->sane.name); 235141cc406Sopenharmony_ci DBG (5, "dev->sane.vendor = %s\n", dev->sane.vendor); 236141cc406Sopenharmony_ci DBG (5, "dev->sane.model = %s\n", dev->sane.model); 237141cc406Sopenharmony_ci DBG (5, "dev->sane.type = %s\n", dev->sane.type); 238141cc406Sopenharmony_ci 239141cc406Sopenharmony_ci dev->info.xres_default = _2btol(wbuf.x_res); 240141cc406Sopenharmony_ci dev->info.yres_default = _2btol(wbuf.y_res); 241141cc406Sopenharmony_ci dev->info.image_mode_default = wbuf.image_comp; 242141cc406Sopenharmony_ci 243141cc406Sopenharmony_ci /* if you throw the MRIF bit the brightness control reverses too */ 244141cc406Sopenharmony_ci /* so I reverse the reversal in software for symmetry's sake */ 245141cc406Sopenharmony_ci /* I should make this into an option */ 246141cc406Sopenharmony_ci 247141cc406Sopenharmony_ci if (wbuf.image_comp == RICOH_GRAYSCALE || wbuf.image_comp == RICOH_DITHERED_MONOCHROME) 248141cc406Sopenharmony_ci { 249141cc406Sopenharmony_ci dev->info.brightness_default = 256 - wbuf.brightness; 250141cc406Sopenharmony_ci if (is50) 251141cc406Sopenharmony_ci dev->info.contrast_default = wbuf.contrast; 252141cc406Sopenharmony_ci else 253141cc406Sopenharmony_ci dev->info.contrast_default = 256 - wbuf.contrast; 254141cc406Sopenharmony_ci } 255141cc406Sopenharmony_ci else /* wbuf.image_comp == RICOH_BINARY_MONOCHROME */ 256141cc406Sopenharmony_ci { 257141cc406Sopenharmony_ci dev->info.brightness_default = wbuf.brightness; 258141cc406Sopenharmony_ci dev->info.contrast_default = wbuf.contrast; 259141cc406Sopenharmony_ci } 260141cc406Sopenharmony_ci 261141cc406Sopenharmony_ci#if 1 262141cc406Sopenharmony_ci dev->info.bmu = mup.bmu; 263141cc406Sopenharmony_ci dev->info.mud = _2btol(mup.mud); 264141cc406Sopenharmony_ci if (dev->info.mud == 0) { 265141cc406Sopenharmony_ci /* The RICOH says it uses points as default Basic Measurement Unit */ 266141cc406Sopenharmony_ci /* but gives a Measurement Unit Divisor of zero */ 267141cc406Sopenharmony_ci /* So, we set it to the default (SCSI-standard) of 1200 */ 268141cc406Sopenharmony_ci /* with BMU in inches, i.e. 1200 points equal 1 inch */ 269141cc406Sopenharmony_ci dev->info.bmu = INCHES; 270141cc406Sopenharmony_ci dev->info.mud = DEFAULT_MUD; 271141cc406Sopenharmony_ci } 272141cc406Sopenharmony_ci#else 273141cc406Sopenharmony_ci dev->info.bmu = INCHES; 274141cc406Sopenharmony_ci dev->info.mud = DEFAULT_MUD; 275141cc406Sopenharmony_ci#endif 276141cc406Sopenharmony_ci 277141cc406Sopenharmony_ci DBG (5, "xres_default=%d\n", dev->info.xres_default); 278141cc406Sopenharmony_ci DBG (5, "xres_range.max=%d\n", dev->info.xres_range.max); 279141cc406Sopenharmony_ci DBG (5, "xres_range.min=%d\n", dev->info.xres_range.min); 280141cc406Sopenharmony_ci 281141cc406Sopenharmony_ci DBG (5, "yres_default=%d\n", dev->info.yres_default); 282141cc406Sopenharmony_ci DBG (5, "yres_range.max=%d\n", dev->info.yres_range.max); 283141cc406Sopenharmony_ci DBG (5, "yres_range.min=%d\n", dev->info.yres_range.min); 284141cc406Sopenharmony_ci 285141cc406Sopenharmony_ci DBG (5, "x_range.max=%d\n", dev->info.x_range.max); 286141cc406Sopenharmony_ci DBG (5, "y_range.max=%d\n", dev->info.y_range.max); 287141cc406Sopenharmony_ci 288141cc406Sopenharmony_ci DBG (5, "image_mode=%d\n", dev->info.image_mode_default); 289141cc406Sopenharmony_ci 290141cc406Sopenharmony_ci DBG (5, "brightness=%d\n", dev->info.brightness_default); 291141cc406Sopenharmony_ci DBG (5, "contrast=%d\n", dev->info.contrast_default); 292141cc406Sopenharmony_ci 293141cc406Sopenharmony_ci DBG (5, "bmu=%d\n", dev->info.bmu); 294141cc406Sopenharmony_ci DBG (5, "mud=%d\n", dev->info.mud); 295141cc406Sopenharmony_ci 296141cc406Sopenharmony_ci ++num_devices; 297141cc406Sopenharmony_ci dev->next = first_dev; 298141cc406Sopenharmony_ci first_dev = dev; 299141cc406Sopenharmony_ci 300141cc406Sopenharmony_ci if (devp) 301141cc406Sopenharmony_ci *devp = dev; 302141cc406Sopenharmony_ci 303141cc406Sopenharmony_ci DBG (11, "<< attach\n"); 304141cc406Sopenharmony_ci return (SANE_STATUS_GOOD); 305141cc406Sopenharmony_ci} 306141cc406Sopenharmony_ci 307141cc406Sopenharmony_cistatic SANE_Status 308141cc406Sopenharmony_ciattach_one(const char *devnam) 309141cc406Sopenharmony_ci{ 310141cc406Sopenharmony_ci attach (devnam, NULL); 311141cc406Sopenharmony_ci return SANE_STATUS_GOOD; 312141cc406Sopenharmony_ci} 313141cc406Sopenharmony_ci 314141cc406Sopenharmony_cistatic SANE_Status 315141cc406Sopenharmony_ciinit_options (Ricoh_Scanner * s) 316141cc406Sopenharmony_ci{ 317141cc406Sopenharmony_ci int i; 318141cc406Sopenharmony_ci DBG (11, ">> init_options\n"); 319141cc406Sopenharmony_ci 320141cc406Sopenharmony_ci memset (s->opt, 0, sizeof (s->opt)); 321141cc406Sopenharmony_ci memset (s->val, 0, sizeof (s->val)); 322141cc406Sopenharmony_ci 323141cc406Sopenharmony_ci for (i = 0; i < NUM_OPTIONS; ++i) 324141cc406Sopenharmony_ci { 325141cc406Sopenharmony_ci s->opt[i].size = sizeof (SANE_Word); 326141cc406Sopenharmony_ci s->opt[i].cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT; 327141cc406Sopenharmony_ci } 328141cc406Sopenharmony_ci 329141cc406Sopenharmony_ci s->opt[OPT_NUM_OPTS].title = SANE_TITLE_NUM_OPTIONS; 330141cc406Sopenharmony_ci s->opt[OPT_NUM_OPTS].desc = SANE_DESC_NUM_OPTIONS; 331141cc406Sopenharmony_ci s->opt[OPT_NUM_OPTS].type = SANE_TYPE_INT; 332141cc406Sopenharmony_ci s->opt[OPT_NUM_OPTS].cap = SANE_CAP_SOFT_DETECT; 333141cc406Sopenharmony_ci s->val[OPT_NUM_OPTS].w = NUM_OPTIONS; 334141cc406Sopenharmony_ci 335141cc406Sopenharmony_ci /* "Mode" group: */ 336141cc406Sopenharmony_ci s->opt[OPT_MODE_GROUP].title = "Scan Mode"; 337141cc406Sopenharmony_ci s->opt[OPT_MODE_GROUP].desc = ""; 338141cc406Sopenharmony_ci s->opt[OPT_MODE_GROUP].type = SANE_TYPE_GROUP; 339141cc406Sopenharmony_ci s->opt[OPT_MODE_GROUP].cap = 0; 340141cc406Sopenharmony_ci s->opt[OPT_MODE_GROUP].constraint_type = SANE_CONSTRAINT_NONE; 341141cc406Sopenharmony_ci 342141cc406Sopenharmony_ci /* scan mode */ 343141cc406Sopenharmony_ci s->opt[OPT_MODE].name = SANE_NAME_SCAN_MODE; 344141cc406Sopenharmony_ci s->opt[OPT_MODE].title = SANE_TITLE_SCAN_MODE; 345141cc406Sopenharmony_ci s->opt[OPT_MODE].desc = SANE_DESC_SCAN_MODE; 346141cc406Sopenharmony_ci s->opt[OPT_MODE].type = SANE_TYPE_STRING; 347141cc406Sopenharmony_ci s->opt[OPT_MODE].size = max_string_size (mode_list); 348141cc406Sopenharmony_ci s->opt[OPT_MODE].constraint_type = SANE_CONSTRAINT_STRING_LIST; 349141cc406Sopenharmony_ci s->opt[OPT_MODE].constraint.string_list = mode_list; 350141cc406Sopenharmony_ci s->val[OPT_MODE].s = strdup (mode_list[s->hw->info.image_mode_default]); 351141cc406Sopenharmony_ci 352141cc406Sopenharmony_ci /* x resolution */ 353141cc406Sopenharmony_ci s->opt[OPT_X_RESOLUTION].name = "X" SANE_NAME_SCAN_RESOLUTION; 354141cc406Sopenharmony_ci s->opt[OPT_X_RESOLUTION].title = "X " SANE_TITLE_SCAN_RESOLUTION; 355141cc406Sopenharmony_ci s->opt[OPT_X_RESOLUTION].desc = SANE_DESC_SCAN_RESOLUTION; 356141cc406Sopenharmony_ci s->opt[OPT_X_RESOLUTION].type = SANE_TYPE_INT; 357141cc406Sopenharmony_ci s->opt[OPT_X_RESOLUTION].unit = SANE_UNIT_DPI; 358141cc406Sopenharmony_ci s->opt[OPT_X_RESOLUTION].constraint_type = SANE_CONSTRAINT_RANGE; 359141cc406Sopenharmony_ci s->opt[OPT_X_RESOLUTION].constraint.range = &is60_res_range; 360141cc406Sopenharmony_ci s->val[OPT_X_RESOLUTION].w = s->hw->info.xres_default; 361141cc406Sopenharmony_ci if (is50) 362141cc406Sopenharmony_ci s->opt[OPT_X_RESOLUTION].constraint.range = &is50_res_range; 363141cc406Sopenharmony_ci else 364141cc406Sopenharmony_ci s->opt[OPT_X_RESOLUTION].constraint.range = &is60_res_range; 365141cc406Sopenharmony_ci 366141cc406Sopenharmony_ci /* y resolution */ 367141cc406Sopenharmony_ci s->opt[OPT_Y_RESOLUTION].name = "Y" SANE_NAME_SCAN_RESOLUTION; 368141cc406Sopenharmony_ci s->opt[OPT_Y_RESOLUTION].title = "Y " SANE_TITLE_SCAN_RESOLUTION; 369141cc406Sopenharmony_ci s->opt[OPT_Y_RESOLUTION].desc = SANE_DESC_SCAN_RESOLUTION; 370141cc406Sopenharmony_ci s->opt[OPT_Y_RESOLUTION].type = SANE_TYPE_INT; 371141cc406Sopenharmony_ci s->opt[OPT_Y_RESOLUTION].unit = SANE_UNIT_DPI; 372141cc406Sopenharmony_ci s->opt[OPT_Y_RESOLUTION].constraint_type = SANE_CONSTRAINT_RANGE; 373141cc406Sopenharmony_ci s->val[OPT_Y_RESOLUTION].w = s->hw->info.yres_default; 374141cc406Sopenharmony_ci if (is50) 375141cc406Sopenharmony_ci s->opt[OPT_Y_RESOLUTION].constraint.range = &is50_res_range; 376141cc406Sopenharmony_ci else 377141cc406Sopenharmony_ci s->opt[OPT_Y_RESOLUTION].constraint.range = &is60_res_range; 378141cc406Sopenharmony_ci 379141cc406Sopenharmony_ci /* "Geometry" group: */ 380141cc406Sopenharmony_ci s->opt[OPT_GEOMETRY_GROUP].title = "Geometry"; 381141cc406Sopenharmony_ci s->opt[OPT_GEOMETRY_GROUP].desc = ""; 382141cc406Sopenharmony_ci s->opt[OPT_GEOMETRY_GROUP].type = SANE_TYPE_GROUP; 383141cc406Sopenharmony_ci s->opt[OPT_GEOMETRY_GROUP].cap = SANE_CAP_ADVANCED; 384141cc406Sopenharmony_ci s->opt[OPT_GEOMETRY_GROUP].constraint_type = SANE_CONSTRAINT_NONE; 385141cc406Sopenharmony_ci 386141cc406Sopenharmony_ci /* top-left x */ 387141cc406Sopenharmony_ci s->opt[OPT_TL_X].name = SANE_NAME_SCAN_TL_X; 388141cc406Sopenharmony_ci s->opt[OPT_TL_X].title = SANE_TITLE_SCAN_TL_X; 389141cc406Sopenharmony_ci s->opt[OPT_TL_X].desc = SANE_DESC_SCAN_TL_X; 390141cc406Sopenharmony_ci s->opt[OPT_TL_X].type = SANE_TYPE_INT; 391141cc406Sopenharmony_ci s->opt[OPT_TL_X].unit = SANE_UNIT_PIXEL; 392141cc406Sopenharmony_ci s->opt[OPT_TL_X].constraint_type = SANE_CONSTRAINT_RANGE; 393141cc406Sopenharmony_ci s->opt[OPT_TL_X].constraint.range = &default_x_range; 394141cc406Sopenharmony_ci s->val[OPT_TL_X].w = 0; 395141cc406Sopenharmony_ci 396141cc406Sopenharmony_ci /* top-left y */ 397141cc406Sopenharmony_ci s->opt[OPT_TL_Y].name = SANE_NAME_SCAN_TL_Y; 398141cc406Sopenharmony_ci s->opt[OPT_TL_Y].title = SANE_TITLE_SCAN_TL_Y; 399141cc406Sopenharmony_ci s->opt[OPT_TL_Y].desc = SANE_DESC_SCAN_TL_Y; 400141cc406Sopenharmony_ci s->opt[OPT_TL_Y].type = SANE_TYPE_INT; 401141cc406Sopenharmony_ci s->opt[OPT_TL_Y].unit = SANE_UNIT_PIXEL; 402141cc406Sopenharmony_ci s->opt[OPT_TL_Y].constraint_type = SANE_CONSTRAINT_RANGE; 403141cc406Sopenharmony_ci s->opt[OPT_TL_Y].constraint.range = &default_y_range; 404141cc406Sopenharmony_ci s->val[OPT_TL_Y].w = 0; 405141cc406Sopenharmony_ci 406141cc406Sopenharmony_ci /* bottom-right x */ 407141cc406Sopenharmony_ci s->opt[OPT_BR_X].name = SANE_NAME_SCAN_BR_X; 408141cc406Sopenharmony_ci s->opt[OPT_BR_X].title = SANE_TITLE_SCAN_BR_X; 409141cc406Sopenharmony_ci s->opt[OPT_BR_X].desc = SANE_DESC_SCAN_BR_X; 410141cc406Sopenharmony_ci s->opt[OPT_BR_X].type = SANE_TYPE_INT; 411141cc406Sopenharmony_ci s->opt[OPT_BR_X].unit = SANE_UNIT_PIXEL; 412141cc406Sopenharmony_ci s->opt[OPT_BR_X].constraint_type = SANE_CONSTRAINT_RANGE; 413141cc406Sopenharmony_ci s->opt[OPT_BR_X].constraint.range = &default_x_range; 414141cc406Sopenharmony_ci s->val[OPT_BR_X].w = default_x_range.max; 415141cc406Sopenharmony_ci 416141cc406Sopenharmony_ci /* bottom-right y */ 417141cc406Sopenharmony_ci s->opt[OPT_BR_Y].name = SANE_NAME_SCAN_BR_Y; 418141cc406Sopenharmony_ci s->opt[OPT_BR_Y].title = SANE_TITLE_SCAN_BR_Y; 419141cc406Sopenharmony_ci s->opt[OPT_BR_Y].desc = SANE_DESC_SCAN_BR_Y; 420141cc406Sopenharmony_ci s->opt[OPT_BR_Y].type = SANE_TYPE_INT; 421141cc406Sopenharmony_ci s->opt[OPT_BR_Y].unit = SANE_UNIT_PIXEL; 422141cc406Sopenharmony_ci s->opt[OPT_BR_Y].constraint_type = SANE_CONSTRAINT_RANGE; 423141cc406Sopenharmony_ci s->opt[OPT_BR_Y].constraint.range = &default_y_range; 424141cc406Sopenharmony_ci s->val[OPT_BR_Y].w = default_y_range.max; 425141cc406Sopenharmony_ci 426141cc406Sopenharmony_ci /* "Enhancement" group: */ 427141cc406Sopenharmony_ci s->opt[OPT_ENHANCEMENT_GROUP].title = "Enhancement"; 428141cc406Sopenharmony_ci s->opt[OPT_ENHANCEMENT_GROUP].desc = ""; 429141cc406Sopenharmony_ci s->opt[OPT_ENHANCEMENT_GROUP].type = SANE_TYPE_GROUP; 430141cc406Sopenharmony_ci s->opt[OPT_ENHANCEMENT_GROUP].cap = 0; 431141cc406Sopenharmony_ci s->opt[OPT_ENHANCEMENT_GROUP].constraint_type = SANE_CONSTRAINT_NONE; 432141cc406Sopenharmony_ci 433141cc406Sopenharmony_ci /* brightness */ 434141cc406Sopenharmony_ci s->opt[OPT_BRIGHTNESS].name = SANE_NAME_BRIGHTNESS; 435141cc406Sopenharmony_ci s->opt[OPT_BRIGHTNESS].title = SANE_TITLE_BRIGHTNESS; 436141cc406Sopenharmony_ci s->opt[OPT_BRIGHTNESS].desc = SANE_DESC_BRIGHTNESS; 437141cc406Sopenharmony_ci s->opt[OPT_BRIGHTNESS].type = SANE_TYPE_INT; 438141cc406Sopenharmony_ci s->opt[OPT_BRIGHTNESS].unit = SANE_UNIT_NONE; 439141cc406Sopenharmony_ci s->opt[OPT_BRIGHTNESS].constraint_type = SANE_CONSTRAINT_RANGE; 440141cc406Sopenharmony_ci s->opt[OPT_BRIGHTNESS].constraint.range = &u8_range; 441141cc406Sopenharmony_ci s->val[OPT_BRIGHTNESS].w = s->hw->info.brightness_default; 442141cc406Sopenharmony_ci 443141cc406Sopenharmony_ci /* contrast */ 444141cc406Sopenharmony_ci s->opt[OPT_CONTRAST].name = SANE_NAME_CONTRAST; 445141cc406Sopenharmony_ci s->opt[OPT_CONTRAST].title = SANE_TITLE_CONTRAST; 446141cc406Sopenharmony_ci s->opt[OPT_CONTRAST].desc = SANE_DESC_CONTRAST; 447141cc406Sopenharmony_ci s->opt[OPT_CONTRAST].type = SANE_TYPE_INT; 448141cc406Sopenharmony_ci s->opt[OPT_CONTRAST].unit = SANE_UNIT_NONE; 449141cc406Sopenharmony_ci s->opt[OPT_CONTRAST].constraint_type = SANE_CONSTRAINT_RANGE; 450141cc406Sopenharmony_ci s->opt[OPT_CONTRAST].constraint.range = &u8_range; 451141cc406Sopenharmony_ci s->val[OPT_CONTRAST].w = s->hw->info.contrast_default; 452141cc406Sopenharmony_ci 453141cc406Sopenharmony_ci DBG (11, "<< init_options\n"); 454141cc406Sopenharmony_ci return SANE_STATUS_GOOD; 455141cc406Sopenharmony_ci} 456141cc406Sopenharmony_ci 457141cc406Sopenharmony_cistatic SANE_Status 458141cc406Sopenharmony_cido_cancel (Ricoh_Scanner * s) 459141cc406Sopenharmony_ci{ 460141cc406Sopenharmony_ci SANE_Status status; 461141cc406Sopenharmony_ci DBG (11, ">> do_cancel\n"); 462141cc406Sopenharmony_ci 463141cc406Sopenharmony_ci DBG (3, "cancel: sending OBJECT POSITION\n"); 464141cc406Sopenharmony_ci status = object_position (s->fd); 465141cc406Sopenharmony_ci if (status != SANE_STATUS_GOOD) 466141cc406Sopenharmony_ci { 467141cc406Sopenharmony_ci DBG (1, "cancel: OBJECT POSITION failed\n"); 468141cc406Sopenharmony_ci } 469141cc406Sopenharmony_ci 470141cc406Sopenharmony_ci s->scanning = SANE_FALSE; 471141cc406Sopenharmony_ci 472141cc406Sopenharmony_ci if (s->fd >= 0) 473141cc406Sopenharmony_ci { 474141cc406Sopenharmony_ci sanei_scsi_close (s->fd); 475141cc406Sopenharmony_ci s->fd = -1; 476141cc406Sopenharmony_ci } 477141cc406Sopenharmony_ci 478141cc406Sopenharmony_ci DBG (11, "<< do_cancel\n"); 479141cc406Sopenharmony_ci return (SANE_STATUS_CANCELLED); 480141cc406Sopenharmony_ci} 481141cc406Sopenharmony_ci 482141cc406Sopenharmony_ciSANE_Status 483141cc406Sopenharmony_cisane_init (SANE_Int * version_code, SANE_Auth_Callback authorize) 484141cc406Sopenharmony_ci{ 485141cc406Sopenharmony_ci char devnam[PATH_MAX] = "/dev/scanner"; 486141cc406Sopenharmony_ci FILE *fp; 487141cc406Sopenharmony_ci 488141cc406Sopenharmony_ci (void) authorize; /* silence gcc */ 489141cc406Sopenharmony_ci 490141cc406Sopenharmony_ci DBG_INIT (); 491141cc406Sopenharmony_ci DBG (11, ">> sane_init\n"); 492141cc406Sopenharmony_ci 493141cc406Sopenharmony_ci#if defined PACKAGE && defined VERSION 494141cc406Sopenharmony_ci DBG (2, "sane_init: " PACKAGE " " VERSION "\n"); 495141cc406Sopenharmony_ci#endif 496141cc406Sopenharmony_ci 497141cc406Sopenharmony_ci if (version_code) 498141cc406Sopenharmony_ci *version_code = SANE_VERSION_CODE (SANE_CURRENT_MAJOR, SANE_CURRENT_MINOR, 0); 499141cc406Sopenharmony_ci 500141cc406Sopenharmony_ci fp = sanei_config_open(RICOH_CONFIG_FILE); 501141cc406Sopenharmony_ci if (fp) 502141cc406Sopenharmony_ci { 503141cc406Sopenharmony_ci char line[PATH_MAX], *lp; 504141cc406Sopenharmony_ci size_t len; 505141cc406Sopenharmony_ci 506141cc406Sopenharmony_ci /* read config file */ 507141cc406Sopenharmony_ci while (sanei_config_read (line, sizeof (line), fp)) 508141cc406Sopenharmony_ci { 509141cc406Sopenharmony_ci if (line[0] == '#') /* ignore line comments */ 510141cc406Sopenharmony_ci continue; 511141cc406Sopenharmony_ci len = strlen (line); 512141cc406Sopenharmony_ci 513141cc406Sopenharmony_ci if (!len) 514141cc406Sopenharmony_ci continue; /* ignore empty lines */ 515141cc406Sopenharmony_ci 516141cc406Sopenharmony_ci /* skip white space: */ 517141cc406Sopenharmony_ci for (lp = line; isspace(*lp); ++lp) 518141cc406Sopenharmony_ci ; 519141cc406Sopenharmony_ci strcpy (devnam, lp); 520141cc406Sopenharmony_ci } 521141cc406Sopenharmony_ci fclose (fp); 522141cc406Sopenharmony_ci } 523141cc406Sopenharmony_ci sanei_config_attach_matching_devices (devnam, attach_one); 524141cc406Sopenharmony_ci DBG (11, "<< sane_init\n"); 525141cc406Sopenharmony_ci return SANE_STATUS_GOOD; 526141cc406Sopenharmony_ci} 527141cc406Sopenharmony_ci 528141cc406Sopenharmony_civoid 529141cc406Sopenharmony_cisane_exit (void) 530141cc406Sopenharmony_ci{ 531141cc406Sopenharmony_ci Ricoh_Device *dev, *next; 532141cc406Sopenharmony_ci DBG (11, ">> sane_exit\n"); 533141cc406Sopenharmony_ci 534141cc406Sopenharmony_ci for (dev = first_dev; dev; dev = next) 535141cc406Sopenharmony_ci { 536141cc406Sopenharmony_ci next = dev->next; 537141cc406Sopenharmony_ci free ((void *) dev->sane.name); 538141cc406Sopenharmony_ci free ((void *) dev->sane.model); 539141cc406Sopenharmony_ci free (dev); 540141cc406Sopenharmony_ci } 541141cc406Sopenharmony_ci 542141cc406Sopenharmony_ci if (devlist) 543141cc406Sopenharmony_ci free (devlist); 544141cc406Sopenharmony_ci 545141cc406Sopenharmony_ci DBG (11, "<< sane_exit\n"); 546141cc406Sopenharmony_ci} 547141cc406Sopenharmony_ci 548141cc406Sopenharmony_ciSANE_Status 549141cc406Sopenharmony_cisane_get_devices (const SANE_Device *** device_list, SANE_Bool local_only) 550141cc406Sopenharmony_ci{ 551141cc406Sopenharmony_ci Ricoh_Device *dev; 552141cc406Sopenharmony_ci int i; 553141cc406Sopenharmony_ci 554141cc406Sopenharmony_ci (void) local_only; /* silence gcc */ 555141cc406Sopenharmony_ci 556141cc406Sopenharmony_ci DBG (11, ">> sane_get_devices\n"); 557141cc406Sopenharmony_ci 558141cc406Sopenharmony_ci if (devlist) 559141cc406Sopenharmony_ci free (devlist); 560141cc406Sopenharmony_ci devlist = malloc ((num_devices + 1) * sizeof (devlist[0])); 561141cc406Sopenharmony_ci if (!devlist) 562141cc406Sopenharmony_ci return (SANE_STATUS_NO_MEM); 563141cc406Sopenharmony_ci 564141cc406Sopenharmony_ci i = 0; 565141cc406Sopenharmony_ci for (dev = first_dev; dev; dev = dev->next) 566141cc406Sopenharmony_ci devlist[i++] = &dev->sane; 567141cc406Sopenharmony_ci devlist[i++] = 0; 568141cc406Sopenharmony_ci 569141cc406Sopenharmony_ci *device_list = devlist; 570141cc406Sopenharmony_ci 571141cc406Sopenharmony_ci DBG (11, "<< sane_get_devices\n"); 572141cc406Sopenharmony_ci return SANE_STATUS_GOOD; 573141cc406Sopenharmony_ci} 574141cc406Sopenharmony_ci 575141cc406Sopenharmony_ciSANE_Status 576141cc406Sopenharmony_cisane_open (SANE_String_Const devnam, SANE_Handle * handle) 577141cc406Sopenharmony_ci{ 578141cc406Sopenharmony_ci SANE_Status status; 579141cc406Sopenharmony_ci Ricoh_Device *dev; 580141cc406Sopenharmony_ci Ricoh_Scanner *s; 581141cc406Sopenharmony_ci DBG (11, ">> sane_open\n"); 582141cc406Sopenharmony_ci 583141cc406Sopenharmony_ci if (devnam[0] == '\0') 584141cc406Sopenharmony_ci { 585141cc406Sopenharmony_ci for (dev = first_dev; dev; dev = dev->next) 586141cc406Sopenharmony_ci { 587141cc406Sopenharmony_ci if (strcmp (dev->sane.name, devnam) == 0) 588141cc406Sopenharmony_ci break; 589141cc406Sopenharmony_ci } 590141cc406Sopenharmony_ci 591141cc406Sopenharmony_ci if (!dev) 592141cc406Sopenharmony_ci { 593141cc406Sopenharmony_ci status = attach (devnam, &dev); 594141cc406Sopenharmony_ci if (status != SANE_STATUS_GOOD) 595141cc406Sopenharmony_ci return (status); 596141cc406Sopenharmony_ci } 597141cc406Sopenharmony_ci } 598141cc406Sopenharmony_ci else 599141cc406Sopenharmony_ci { 600141cc406Sopenharmony_ci dev = first_dev; 601141cc406Sopenharmony_ci } 602141cc406Sopenharmony_ci 603141cc406Sopenharmony_ci if (!dev) 604141cc406Sopenharmony_ci return (SANE_STATUS_INVAL); 605141cc406Sopenharmony_ci 606141cc406Sopenharmony_ci s = malloc (sizeof (*s)); 607141cc406Sopenharmony_ci if (!s) 608141cc406Sopenharmony_ci return SANE_STATUS_NO_MEM; 609141cc406Sopenharmony_ci memset (s, 0, sizeof (*s)); 610141cc406Sopenharmony_ci 611141cc406Sopenharmony_ci s->fd = -1; 612141cc406Sopenharmony_ci s->hw = dev; 613141cc406Sopenharmony_ci 614141cc406Sopenharmony_ci init_options (s); 615141cc406Sopenharmony_ci 616141cc406Sopenharmony_ci s->next = first_handle; 617141cc406Sopenharmony_ci first_handle = s; 618141cc406Sopenharmony_ci 619141cc406Sopenharmony_ci *handle = s; 620141cc406Sopenharmony_ci 621141cc406Sopenharmony_ci DBG (11, "<< sane_open\n"); 622141cc406Sopenharmony_ci return SANE_STATUS_GOOD; 623141cc406Sopenharmony_ci} 624141cc406Sopenharmony_ci 625141cc406Sopenharmony_civoid 626141cc406Sopenharmony_cisane_close (SANE_Handle handle) 627141cc406Sopenharmony_ci{ 628141cc406Sopenharmony_ci Ricoh_Scanner *s = (Ricoh_Scanner *) handle; 629141cc406Sopenharmony_ci DBG (11, ">> sane_close\n"); 630141cc406Sopenharmony_ci 631141cc406Sopenharmony_ci if (s->fd != -1) 632141cc406Sopenharmony_ci sanei_scsi_close (s->fd); 633141cc406Sopenharmony_ci free (s); 634141cc406Sopenharmony_ci 635141cc406Sopenharmony_ci DBG (11, ">> sane_close\n"); 636141cc406Sopenharmony_ci} 637141cc406Sopenharmony_ci 638141cc406Sopenharmony_ciconst SANE_Option_Descriptor * 639141cc406Sopenharmony_cisane_get_option_descriptor (SANE_Handle handle, SANE_Int option) 640141cc406Sopenharmony_ci{ 641141cc406Sopenharmony_ci Ricoh_Scanner *s = handle; 642141cc406Sopenharmony_ci DBG (11, ">> sane_get_option_descriptor\n"); 643141cc406Sopenharmony_ci 644141cc406Sopenharmony_ci if ((unsigned) option >= NUM_OPTIONS) 645141cc406Sopenharmony_ci return (0); 646141cc406Sopenharmony_ci 647141cc406Sopenharmony_ci DBG (11, "<< sane_get_option_descriptor\n"); 648141cc406Sopenharmony_ci return (s->opt + option); 649141cc406Sopenharmony_ci} 650141cc406Sopenharmony_ci 651141cc406Sopenharmony_ciSANE_Status 652141cc406Sopenharmony_cisane_control_option (SANE_Handle handle, SANE_Int option, 653141cc406Sopenharmony_ci SANE_Action action, void *val, SANE_Int * info) 654141cc406Sopenharmony_ci{ 655141cc406Sopenharmony_ci Ricoh_Scanner *s = handle; 656141cc406Sopenharmony_ci SANE_Status status; 657141cc406Sopenharmony_ci SANE_Word cap; 658141cc406Sopenharmony_ci DBG (11, ">> sane_control_option\n"); 659141cc406Sopenharmony_ci 660141cc406Sopenharmony_ci if (info) 661141cc406Sopenharmony_ci *info = 0; 662141cc406Sopenharmony_ci 663141cc406Sopenharmony_ci if (s->scanning) 664141cc406Sopenharmony_ci return (SANE_STATUS_DEVICE_BUSY); 665141cc406Sopenharmony_ci if (option >= NUM_OPTIONS) 666141cc406Sopenharmony_ci return (SANE_STATUS_INVAL); 667141cc406Sopenharmony_ci 668141cc406Sopenharmony_ci cap = s->opt[option].cap; 669141cc406Sopenharmony_ci if (!SANE_OPTION_IS_ACTIVE (cap)) 670141cc406Sopenharmony_ci return (SANE_STATUS_INVAL); 671141cc406Sopenharmony_ci 672141cc406Sopenharmony_ci if (action == SANE_ACTION_GET_VALUE) 673141cc406Sopenharmony_ci { 674141cc406Sopenharmony_ci switch (option) 675141cc406Sopenharmony_ci { 676141cc406Sopenharmony_ci /* word options: */ 677141cc406Sopenharmony_ci case OPT_X_RESOLUTION: 678141cc406Sopenharmony_ci case OPT_Y_RESOLUTION: 679141cc406Sopenharmony_ci case OPT_TL_X: 680141cc406Sopenharmony_ci case OPT_TL_Y: 681141cc406Sopenharmony_ci case OPT_BR_X: 682141cc406Sopenharmony_ci case OPT_BR_Y: 683141cc406Sopenharmony_ci case OPT_NUM_OPTS: 684141cc406Sopenharmony_ci case OPT_BRIGHTNESS: 685141cc406Sopenharmony_ci case OPT_CONTRAST: 686141cc406Sopenharmony_ci *(SANE_Word *) val = s->val[option].w; 687141cc406Sopenharmony_ci return (SANE_STATUS_GOOD); 688141cc406Sopenharmony_ci 689141cc406Sopenharmony_ci /* string options: */ 690141cc406Sopenharmony_ci case OPT_MODE: 691141cc406Sopenharmony_ci strcpy (val, s->val[option].s); 692141cc406Sopenharmony_ci return (SANE_STATUS_GOOD); 693141cc406Sopenharmony_ci } 694141cc406Sopenharmony_ci } 695141cc406Sopenharmony_ci else if (action == SANE_ACTION_SET_VALUE) 696141cc406Sopenharmony_ci { 697141cc406Sopenharmony_ci if (!SANE_OPTION_IS_SETTABLE (cap)) 698141cc406Sopenharmony_ci return (SANE_STATUS_INVAL); 699141cc406Sopenharmony_ci 700141cc406Sopenharmony_ci status = sanei_constrain_value (s->opt + option, val, info); 701141cc406Sopenharmony_ci if (status != SANE_STATUS_GOOD) 702141cc406Sopenharmony_ci return status; 703141cc406Sopenharmony_ci 704141cc406Sopenharmony_ci switch (option) 705141cc406Sopenharmony_ci { 706141cc406Sopenharmony_ci /* (mostly) side-effect-free word options: */ 707141cc406Sopenharmony_ci case OPT_X_RESOLUTION: 708141cc406Sopenharmony_ci case OPT_Y_RESOLUTION: 709141cc406Sopenharmony_ci case OPT_TL_X: 710141cc406Sopenharmony_ci case OPT_TL_Y: 711141cc406Sopenharmony_ci case OPT_BR_X: 712141cc406Sopenharmony_ci case OPT_BR_Y: 713141cc406Sopenharmony_ci if (info && s->val[option].w != *(SANE_Word *) val) 714141cc406Sopenharmony_ci *info |= SANE_INFO_RELOAD_PARAMS; 715141cc406Sopenharmony_ci /* fall through */ 716141cc406Sopenharmony_ci case OPT_NUM_OPTS: 717141cc406Sopenharmony_ci case OPT_BRIGHTNESS: 718141cc406Sopenharmony_ci case OPT_CONTRAST: 719141cc406Sopenharmony_ci s->val[option].w = *(SANE_Word *) val; 720141cc406Sopenharmony_ci return (SANE_STATUS_GOOD); 721141cc406Sopenharmony_ci 722141cc406Sopenharmony_ci case OPT_MODE: 723141cc406Sopenharmony_ci if (info && strcmp (s->val[option].s, (SANE_String) val)) 724141cc406Sopenharmony_ci *info |= SANE_INFO_RELOAD_OPTIONS | SANE_INFO_RELOAD_PARAMS; 725141cc406Sopenharmony_ci if (s->val[option].s) 726141cc406Sopenharmony_ci free (s->val[option].s); 727141cc406Sopenharmony_ci s->val[option].s = strdup (val); 728141cc406Sopenharmony_ci return (SANE_STATUS_GOOD); 729141cc406Sopenharmony_ci } 730141cc406Sopenharmony_ci } 731141cc406Sopenharmony_ci 732141cc406Sopenharmony_ci DBG (11, "<< sane_control_option\n"); 733141cc406Sopenharmony_ci return (SANE_STATUS_INVAL); 734141cc406Sopenharmony_ci} 735141cc406Sopenharmony_ci 736141cc406Sopenharmony_ciSANE_Status 737141cc406Sopenharmony_cisane_get_parameters (SANE_Handle handle, SANE_Parameters * params) 738141cc406Sopenharmony_ci{ 739141cc406Sopenharmony_ci Ricoh_Scanner *s = handle; 740141cc406Sopenharmony_ci DBG (11, ">> sane_get_parameters\n"); 741141cc406Sopenharmony_ci 742141cc406Sopenharmony_ci if (!s->scanning) 743141cc406Sopenharmony_ci { 744141cc406Sopenharmony_ci int width, length, xres, yres; 745141cc406Sopenharmony_ci const char *mode; 746141cc406Sopenharmony_ci 747141cc406Sopenharmony_ci memset (&s->params, 0, sizeof (s->params)); 748141cc406Sopenharmony_ci 749141cc406Sopenharmony_ci width = s->val[OPT_BR_X].w - s->val[OPT_TL_X].w; 750141cc406Sopenharmony_ci length = s->val[OPT_BR_Y].w - s->val[OPT_TL_Y].w; 751141cc406Sopenharmony_ci xres = s->val[OPT_X_RESOLUTION].w; 752141cc406Sopenharmony_ci yres = s->val[OPT_Y_RESOLUTION].w; 753141cc406Sopenharmony_ci 754141cc406Sopenharmony_ci /* make best-effort guess at what parameters will look like once 755141cc406Sopenharmony_ci scanning starts. */ 756141cc406Sopenharmony_ci if (xres > 0 && yres > 0 && width > 0 && length > 0) 757141cc406Sopenharmony_ci { 758141cc406Sopenharmony_ci s->params.pixels_per_line = width * xres / s->hw->info.mud; 759141cc406Sopenharmony_ci s->params.lines = length * yres / s->hw->info.mud; 760141cc406Sopenharmony_ci } 761141cc406Sopenharmony_ci 762141cc406Sopenharmony_ci mode = s->val[OPT_MODE].s; 763141cc406Sopenharmony_ci if (strcmp (mode, SANE_VALUE_SCAN_MODE_LINEART) == 0 || strcmp (mode, SANE_VALUE_SCAN_MODE_HALFTONE) == 0) 764141cc406Sopenharmony_ci { 765141cc406Sopenharmony_ci s->params.format = SANE_FRAME_GRAY; 766141cc406Sopenharmony_ci s->params.bytes_per_line = s->params.pixels_per_line / 8; 767141cc406Sopenharmony_ci /* the Ricoh truncates to the byte boundary, so: chop! */ 768141cc406Sopenharmony_ci s->params.pixels_per_line = s->params.bytes_per_line * 8; 769141cc406Sopenharmony_ci s->params.depth = 1; 770141cc406Sopenharmony_ci } 771141cc406Sopenharmony_ci else /* if (strcmp (mode, SANE_VALUE_SCAN_MODE_GRAY) == 0) */ 772141cc406Sopenharmony_ci { 773141cc406Sopenharmony_ci s->params.format = SANE_FRAME_GRAY; 774141cc406Sopenharmony_ci s->params.bytes_per_line = s->params.pixels_per_line; 775141cc406Sopenharmony_ci s->params.depth = 8; 776141cc406Sopenharmony_ci } 777141cc406Sopenharmony_ci s->params.last_frame = SANE_TRUE; 778141cc406Sopenharmony_ci } 779141cc406Sopenharmony_ci 780141cc406Sopenharmony_ci if (params) 781141cc406Sopenharmony_ci *params = s->params; 782141cc406Sopenharmony_ci 783141cc406Sopenharmony_ci DBG (1, "%d pixels per line, %d bytes, %d lines high, total %lu bytes, " 784141cc406Sopenharmony_ci "dpi=%d\n", s->params.pixels_per_line, s->params.bytes_per_line, 785141cc406Sopenharmony_ci s->params.lines, (u_long) s->bytes_to_read, s->val[OPT_Y_RESOLUTION].w); 786141cc406Sopenharmony_ci 787141cc406Sopenharmony_ci DBG (11, "<< sane_get_parameters\n"); 788141cc406Sopenharmony_ci return (SANE_STATUS_GOOD); 789141cc406Sopenharmony_ci} 790141cc406Sopenharmony_ci 791141cc406Sopenharmony_ci 792141cc406Sopenharmony_ciSANE_Status 793141cc406Sopenharmony_cisane_start (SANE_Handle handle) 794141cc406Sopenharmony_ci{ 795141cc406Sopenharmony_ci char *mode_str; 796141cc406Sopenharmony_ci Ricoh_Scanner *s = handle; 797141cc406Sopenharmony_ci SANE_Status status; 798141cc406Sopenharmony_ci struct ricoh_window_data wbuf; 799141cc406Sopenharmony_ci struct measurements_units_page mup; 800141cc406Sopenharmony_ci 801141cc406Sopenharmony_ci DBG (11, ">> sane_start\n"); 802141cc406Sopenharmony_ci 803141cc406Sopenharmony_ci /* First make sure we have a current parameter set. Some of the 804141cc406Sopenharmony_ci parameters will be overwritten below, but that's OK. */ 805141cc406Sopenharmony_ci status = sane_get_parameters (s, 0); 806141cc406Sopenharmony_ci if (status != SANE_STATUS_GOOD) 807141cc406Sopenharmony_ci return status; 808141cc406Sopenharmony_ci 809141cc406Sopenharmony_ci status = sanei_scsi_open (s->hw->sane.name, &s->fd, 0, 0); 810141cc406Sopenharmony_ci if (status != SANE_STATUS_GOOD) 811141cc406Sopenharmony_ci { 812141cc406Sopenharmony_ci DBG (1, "open of %s failed: %s\n", 813141cc406Sopenharmony_ci s->hw->sane.name, sane_strstatus (status)); 814141cc406Sopenharmony_ci return (status); 815141cc406Sopenharmony_ci } 816141cc406Sopenharmony_ci 817141cc406Sopenharmony_ci mode_str = s->val[OPT_MODE].s; 818141cc406Sopenharmony_ci s->xres = s->val[OPT_X_RESOLUTION].w; 819141cc406Sopenharmony_ci s->yres = s->val[OPT_Y_RESOLUTION].w; 820141cc406Sopenharmony_ci s->ulx = s->val[OPT_TL_X].w; 821141cc406Sopenharmony_ci s->uly = s->val[OPT_TL_Y].w; 822141cc406Sopenharmony_ci s->width = s->val[OPT_BR_X].w - s->val[OPT_TL_X].w; 823141cc406Sopenharmony_ci s->length = s->val[OPT_BR_Y].w - s->val[OPT_TL_Y].w; 824141cc406Sopenharmony_ci s->brightness = s->val[OPT_BRIGHTNESS].w; 825141cc406Sopenharmony_ci s->contrast = s->val[OPT_CONTRAST].w; 826141cc406Sopenharmony_ci s->bpp = s->params.depth; 827141cc406Sopenharmony_ci if (strcmp (mode_str, SANE_VALUE_SCAN_MODE_LINEART) == 0) 828141cc406Sopenharmony_ci { 829141cc406Sopenharmony_ci s->image_composition = RICOH_BINARY_MONOCHROME; 830141cc406Sopenharmony_ci } 831141cc406Sopenharmony_ci else if (strcmp (mode_str, SANE_VALUE_SCAN_MODE_HALFTONE) == 0) 832141cc406Sopenharmony_ci { 833141cc406Sopenharmony_ci s->image_composition = RICOH_DITHERED_MONOCHROME; 834141cc406Sopenharmony_ci } 835141cc406Sopenharmony_ci else if (strcmp (mode_str, SANE_VALUE_SCAN_MODE_GRAY) == 0) 836141cc406Sopenharmony_ci { 837141cc406Sopenharmony_ci s->image_composition = RICOH_GRAYSCALE; 838141cc406Sopenharmony_ci } 839141cc406Sopenharmony_ci 840141cc406Sopenharmony_ci memset (&wbuf, 0, sizeof (wbuf)); 841141cc406Sopenharmony_ci _lto2b(sizeof(wbuf) - 8, wbuf.len); 842141cc406Sopenharmony_ci _lto2b(s->xres, wbuf.x_res); 843141cc406Sopenharmony_ci _lto2b(s->yres, wbuf.y_res); 844141cc406Sopenharmony_ci _lto4b(s->ulx, wbuf.x_org); 845141cc406Sopenharmony_ci _lto4b(s->uly, wbuf.y_org); 846141cc406Sopenharmony_ci _lto4b(s->width, wbuf.width); 847141cc406Sopenharmony_ci _lto4b(s->length, wbuf.length); 848141cc406Sopenharmony_ci 849141cc406Sopenharmony_ci wbuf.image_comp = s->image_composition; 850141cc406Sopenharmony_ci /* if you throw the MRIF bit the brightness control reverses too */ 851141cc406Sopenharmony_ci /* so I reverse the reversal in software for symmetry's sake */ 852141cc406Sopenharmony_ci if (wbuf.image_comp == RICOH_GRAYSCALE || wbuf.image_comp == RICOH_DITHERED_MONOCHROME) 853141cc406Sopenharmony_ci { 854141cc406Sopenharmony_ci if (wbuf.image_comp == RICOH_GRAYSCALE) 855141cc406Sopenharmony_ci wbuf.mrif_filtering_gamma_id = (SANE_Byte) 0x90; 856141cc406Sopenharmony_ci if (wbuf.image_comp == RICOH_DITHERED_MONOCHROME) 857141cc406Sopenharmony_ci wbuf.mrif_filtering_gamma_id = (SANE_Byte) 0x10; 858141cc406Sopenharmony_ci wbuf.brightness = 256 - (SANE_Byte) s->brightness; 859141cc406Sopenharmony_ci if (is50) 860141cc406Sopenharmony_ci wbuf.contrast = (SANE_Byte) s->contrast; 861141cc406Sopenharmony_ci else 862141cc406Sopenharmony_ci wbuf.contrast = 256 - (SANE_Byte) s->contrast; 863141cc406Sopenharmony_ci } 864141cc406Sopenharmony_ci else /* wbuf.image_comp == RICOH_BINARY_MONOCHROME */ 865141cc406Sopenharmony_ci { 866141cc406Sopenharmony_ci wbuf.mrif_filtering_gamma_id = (SANE_Byte) 0x00; 867141cc406Sopenharmony_ci wbuf.brightness = (SANE_Byte) s->brightness; 868141cc406Sopenharmony_ci wbuf.contrast = (SANE_Byte) s->contrast; 869141cc406Sopenharmony_ci } 870141cc406Sopenharmony_ci 871141cc406Sopenharmony_ci wbuf.threshold = 0; 872141cc406Sopenharmony_ci wbuf.bits_per_pixel = s->bpp; 873141cc406Sopenharmony_ci 874141cc406Sopenharmony_ci wbuf.halftone_pattern[0] = 2; 875141cc406Sopenharmony_ci wbuf.halftone_pattern[1] = 0; 876141cc406Sopenharmony_ci wbuf.pad_type = 3; 877141cc406Sopenharmony_ci wbuf.bit_ordering[0] = 0; 878141cc406Sopenharmony_ci wbuf.bit_ordering[1] = 3; 879141cc406Sopenharmony_ci 880141cc406Sopenharmony_ci DBG (5, "xres=%d\n", _2btol(wbuf.x_res)); 881141cc406Sopenharmony_ci DBG (5, "yres=%d\n", _2btol(wbuf.y_res)); 882141cc406Sopenharmony_ci DBG (5, "ulx=%d\n", _4btol(wbuf.x_org)); 883141cc406Sopenharmony_ci DBG (5, "uly=%d\n", _4btol(wbuf.y_org)); 884141cc406Sopenharmony_ci DBG (5, "width=%d\n", _4btol(wbuf.width)); 885141cc406Sopenharmony_ci DBG (5, "length=%d\n", _4btol(wbuf.length)); 886141cc406Sopenharmony_ci DBG (5, "image_comp=%d\n", wbuf.image_comp); 887141cc406Sopenharmony_ci 888141cc406Sopenharmony_ci DBG (11, "sane_start: sending SET WINDOW\n"); 889141cc406Sopenharmony_ci status = set_window (s->fd, &wbuf); 890141cc406Sopenharmony_ci if (status != SANE_STATUS_GOOD) 891141cc406Sopenharmony_ci { 892141cc406Sopenharmony_ci DBG (1, "SET WINDOW failed: %s\n", sane_strstatus (status)); 893141cc406Sopenharmony_ci return (status); 894141cc406Sopenharmony_ci } 895141cc406Sopenharmony_ci 896141cc406Sopenharmony_ci DBG (11, "sane_start: sending GET WINDOW\n"); 897141cc406Sopenharmony_ci memset (&wbuf, 0, sizeof (wbuf)); 898141cc406Sopenharmony_ci status = get_window (s->fd, &wbuf); 899141cc406Sopenharmony_ci if (status != SANE_STATUS_GOOD) 900141cc406Sopenharmony_ci { 901141cc406Sopenharmony_ci DBG (1, "GET WINDOW failed: %s\n", sane_strstatus (status)); 902141cc406Sopenharmony_ci return (status); 903141cc406Sopenharmony_ci } 904141cc406Sopenharmony_ci DBG (5, "xres=%d\n", _2btol(wbuf.x_res)); 905141cc406Sopenharmony_ci DBG (5, "yres=%d\n", _2btol(wbuf.y_res)); 906141cc406Sopenharmony_ci DBG (5, "ulx=%d\n", _4btol(wbuf.x_org)); 907141cc406Sopenharmony_ci DBG (5, "uly=%d\n", _4btol(wbuf.y_org)); 908141cc406Sopenharmony_ci DBG (5, "width=%d\n", _4btol(wbuf.width)); 909141cc406Sopenharmony_ci DBG (5, "length=%d\n", _4btol(wbuf.length)); 910141cc406Sopenharmony_ci DBG (5, "image_comp=%d\n", wbuf.image_comp); 911141cc406Sopenharmony_ci 912141cc406Sopenharmony_ci DBG (11, "sane_start: sending MODE SELECT\n"); 913141cc406Sopenharmony_ci memset (&mup, 0, sizeof (mup)); 914141cc406Sopenharmony_ci mup.page_code = MEASUREMENTS_PAGE; 915141cc406Sopenharmony_ci mup.parameter_length = 0x06; 916141cc406Sopenharmony_ci mup.bmu = INCHES; 917141cc406Sopenharmony_ci mup.mud[0] = (DEFAULT_MUD >> 8) & 0xff; 918141cc406Sopenharmony_ci mup.mud[1] = (DEFAULT_MUD & 0xff); 919141cc406Sopenharmony_ci 920141cc406Sopenharmony_ci status = mode_select (s->fd, (struct mode_pages *) &mup); 921141cc406Sopenharmony_ci if (status != SANE_STATUS_GOOD) 922141cc406Sopenharmony_ci { 923141cc406Sopenharmony_ci DBG (1, "attach: MODE_SELECT failed\n"); 924141cc406Sopenharmony_ci return (SANE_STATUS_INVAL); 925141cc406Sopenharmony_ci } 926141cc406Sopenharmony_ci 927141cc406Sopenharmony_ci status = trigger_scan (s->fd); 928141cc406Sopenharmony_ci if (status != SANE_STATUS_GOOD) 929141cc406Sopenharmony_ci { 930141cc406Sopenharmony_ci DBG (1, "start of scan failed: %s\n", sane_strstatus (status)); 931141cc406Sopenharmony_ci return (status); 932141cc406Sopenharmony_ci } 933141cc406Sopenharmony_ci 934141cc406Sopenharmony_ci /* Wait for scanner to become ready to transmit data */ 935141cc406Sopenharmony_ci status = ricoh_wait_ready (s); 936141cc406Sopenharmony_ci if (status != SANE_STATUS_GOOD) 937141cc406Sopenharmony_ci { 938141cc406Sopenharmony_ci DBG (1, "GET DATA STATUS failed: %s\n", sane_strstatus (status)); 939141cc406Sopenharmony_ci return (status); 940141cc406Sopenharmony_ci } 941141cc406Sopenharmony_ci 942141cc406Sopenharmony_ci s->bytes_to_read = s->params.bytes_per_line * s->params.lines; 943141cc406Sopenharmony_ci 944141cc406Sopenharmony_ci DBG (1, "%d pixels per line, %d bytes, %d lines high, total %lu bytes, " 945141cc406Sopenharmony_ci "dpi=%d\n", s->params.pixels_per_line, s->params.bytes_per_line, 946141cc406Sopenharmony_ci s->params.lines, (u_long) s->bytes_to_read, s->val[OPT_Y_RESOLUTION].w); 947141cc406Sopenharmony_ci 948141cc406Sopenharmony_ci s->scanning = SANE_TRUE; 949141cc406Sopenharmony_ci 950141cc406Sopenharmony_ci DBG (11, "<< sane_start\n"); 951141cc406Sopenharmony_ci return (SANE_STATUS_GOOD); 952141cc406Sopenharmony_ci} 953141cc406Sopenharmony_ci 954141cc406Sopenharmony_ciSANE_Status 955141cc406Sopenharmony_cisane_read (SANE_Handle handle, SANE_Byte * buf, SANE_Int max_len, 956141cc406Sopenharmony_ci SANE_Int * len) 957141cc406Sopenharmony_ci{ 958141cc406Sopenharmony_ci Ricoh_Scanner *s = handle; 959141cc406Sopenharmony_ci SANE_Status status; 960141cc406Sopenharmony_ci size_t nread; 961141cc406Sopenharmony_ci DBG (11, ">> sane_read\n"); 962141cc406Sopenharmony_ci 963141cc406Sopenharmony_ci *len = 0; 964141cc406Sopenharmony_ci 965141cc406Sopenharmony_ci DBG (11, "sane_read: bytes left to read: %ld\n", (u_long) s->bytes_to_read); 966141cc406Sopenharmony_ci 967141cc406Sopenharmony_ci if (s->bytes_to_read == 0) 968141cc406Sopenharmony_ci { 969141cc406Sopenharmony_ci do_cancel (s); 970141cc406Sopenharmony_ci return (SANE_STATUS_EOF); 971141cc406Sopenharmony_ci } 972141cc406Sopenharmony_ci 973141cc406Sopenharmony_ci if (!s->scanning) { 974141cc406Sopenharmony_ci DBG (11, "sane_read: scanning is false!\n"); 975141cc406Sopenharmony_ci return (do_cancel (s)); 976141cc406Sopenharmony_ci } 977141cc406Sopenharmony_ci 978141cc406Sopenharmony_ci nread = max_len; 979141cc406Sopenharmony_ci if (nread > s->bytes_to_read) 980141cc406Sopenharmony_ci nread = s->bytes_to_read; 981141cc406Sopenharmony_ci 982141cc406Sopenharmony_ci DBG (11, "sane_read: read %ld bytes\n", (u_long) nread); 983141cc406Sopenharmony_ci status = read_data (s->fd, buf, &nread); 984141cc406Sopenharmony_ci if (status != SANE_STATUS_GOOD) 985141cc406Sopenharmony_ci { 986141cc406Sopenharmony_ci DBG (11, "sane_read: read error\n"); 987141cc406Sopenharmony_ci do_cancel (s); 988141cc406Sopenharmony_ci return (SANE_STATUS_IO_ERROR); 989141cc406Sopenharmony_ci } 990141cc406Sopenharmony_ci *len = nread; 991141cc406Sopenharmony_ci s->bytes_to_read -= nread; 992141cc406Sopenharmony_ci 993141cc406Sopenharmony_ci DBG (11, "<< sane_read\n"); 994141cc406Sopenharmony_ci return (SANE_STATUS_GOOD); 995141cc406Sopenharmony_ci} 996141cc406Sopenharmony_ci 997141cc406Sopenharmony_civoid 998141cc406Sopenharmony_cisane_cancel (SANE_Handle handle) 999141cc406Sopenharmony_ci{ 1000141cc406Sopenharmony_ci Ricoh_Scanner *s = handle; 1001141cc406Sopenharmony_ci DBG (11, ">> sane_cancel\n"); 1002141cc406Sopenharmony_ci 1003141cc406Sopenharmony_ci s->scanning = SANE_FALSE; 1004141cc406Sopenharmony_ci 1005141cc406Sopenharmony_ci DBG (11, "<< sane_cancel\n"); 1006141cc406Sopenharmony_ci} 1007141cc406Sopenharmony_ci 1008141cc406Sopenharmony_ciSANE_Status 1009141cc406Sopenharmony_cisane_set_io_mode (SANE_Handle handle, SANE_Bool non_blocking) 1010141cc406Sopenharmony_ci{ 1011141cc406Sopenharmony_ci (void) handle; /* silence gcc */ 1012141cc406Sopenharmony_ci (void) non_blocking; /* silence gcc */ 1013141cc406Sopenharmony_ci 1014141cc406Sopenharmony_ci DBG (5, ">> sane_set_io_mode\n"); 1015141cc406Sopenharmony_ci DBG (5, "<< sane_set_io_mode\n"); 1016141cc406Sopenharmony_ci 1017141cc406Sopenharmony_ci return SANE_STATUS_UNSUPPORTED; 1018141cc406Sopenharmony_ci} 1019141cc406Sopenharmony_ci 1020141cc406Sopenharmony_ciSANE_Status 1021141cc406Sopenharmony_cisane_get_select_fd (SANE_Handle handle, SANE_Int * fd) 1022141cc406Sopenharmony_ci{ 1023141cc406Sopenharmony_ci (void) handle; /* silence gcc */ 1024141cc406Sopenharmony_ci (void) fd; /* silence gcc */ 1025141cc406Sopenharmony_ci 1026141cc406Sopenharmony_ci DBG (5, ">> sane_get_select_fd\n"); 1027141cc406Sopenharmony_ci DBG (5, "<< sane_get_select_fd\n"); 1028141cc406Sopenharmony_ci 1029141cc406Sopenharmony_ci return SANE_STATUS_UNSUPPORTED; 1030141cc406Sopenharmony_ci} 1031