1/* 2vim: ts=4 sw=4 noexpandtab 3 */ 4 5/* st400.c - SANE module for Siemens ST400 flatbed scanner 6 7 Copyright (C) 1999-2000 Ingo Wilken (Ingo.Wilken@informatik.uni-oldenburg.de) 8 9 This file is part of the SANE package. 10 11 This program is free software; you can redistribute it and/or 12 modify it under the terms of the GNU General Public License as 13 published by the Free Software Foundation; either version 2 of the 14 License, or (at your option) any later version. 15 16 This program is distributed in the hope that it will be useful, but 17 WITHOUT ANY WARRANTY; without even the implied warranty of 18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 19 General Public License for more details. 20 21 You should have received a copy of the GNU General Public License 22 along with this program. If not, see <https://www.gnu.org/licenses/>. 23 24 As a special exception, the authors of SANE give permission for 25 additional uses of the libraries contained in this release of SANE. 26 27 The exception is that, if you link a SANE library with other files 28 to produce an executable, this does not by itself cause the 29 resulting executable to be covered by the GNU General Public 30 License. Your use of that executable is in no way restricted on 31 account of linking the SANE library code into it. 32 33 This exception does not, however, invalidate any other reasons why 34 the executable file might be covered by the GNU General Public 35 License. 36 37 ************************************************************************* 38 39 This file implements a SANE backend for the Siemens ST400 flatbed scanner. 40 41 Unfortunately, I have no documentation for this scanner. All I have 42 is an old PC Pascal source and an Amiga C source (derived from the 43 Pascal source). Both are quite primitive, and so is this backend... 44 45 Version numbers of this backend follow SANE version scheme: The first 46 number is SANE's major version (i.e. the version of the SANE API that 47 this backend conforms to), the second is the version of this backend. 48 Thus, version 1.2 is the second release of this backend for SANE v1. 49 50 1.0 (08 Mar 1999): First public release, for SANE v1.0.0 51 1.1 (12 Mar 1999): Fixed some stupid bugs (caused crash if accessed via net). 52 1.2 (23 Apr 1999): Oops, got threshold backwards. 53 Tested with SANE 1.0.1. 54 1.3 (27 Apr 1999): Seems the separate MODE SELECT to switch the light on 55 is not necessary. Removed debugging output via syslog, 56 it was only used to track down a bug in saned. Some 57 minor cleanups. Removed illegal version check (only 58 frontends should do this). Made "maxread" and "delay" 59 config options instead of compile-time #define's. 60 Added model check via INQUIRY, and related changes. 61 1.4 (29 Jun 1999): New config options to configure scanner models. 62 See st400.conf for details. These options are only 63 for testing, and will be removed someday. 64 1.5 (26 Mar 2000): Check for optnum >= 0. Fixed some hardcoded paths in 65 manpage. ST400 locks up with reads >64KB - added 66 maxread entry to model struct. Tested with SANE 1.0.2. 67 1.6 (08 Apr 2000): Minor cleanups. 68 1.7 (18 Dec 2001): Security fix from Tim Waugh. Dump inquiry data to 69 "$HOME/st400.dump" instead of "/tmp/st400.dump". 70*/ 71 72#include "../include/sane/config.h" 73 74#include <sys/types.h> 75#include <stdlib.h> 76#include <string.h> 77#include <unistd.h> 78#include <ctype.h> 79#include "../include/sane/sane.h" 80#include "../include/sane/sanei.h" 81#include "../include/sane/sanei_config.h" 82#include "../include/sane/saneopts.h" 83#include "../include/sane/sanei_scsi.h" 84#include "../include/sane/sanei_debug.h" 85#ifndef PATH_MAX 86# define PATH_MAX 1024 87#endif 88 89#define BACKEND_NAME st400 90#include "../include/sane/sanei_backend.h" 91 92#include "st400.h" 93 94/* supported scanners */ 95static ST400_Model st400_models[] = { 96{ 8, "SIEMENS", 16, "ST 400", 6, 0x200000UL, 65536UL, NULL, "Siemens", "ST400", "flatbed scanner" }, 97{ 8, "SIEMENS", 16, "ST 800", 6, 0x200000UL, 65536UL, NULL, "Siemens", "ST800", "flatbed scanner" }, /* to be tested */ 98{ 0, "", 0, "", 6, 0x200000UL, 65536UL, NULL, "Unknown", "untested", "flatbed scanner" }, /* matches anything */ 99 100 /* must be last */ 101 { 0, NULL, 0, NULL, 0, 0, 0, NULL, NULL, NULL, NULL } 102}; 103 104 105static ST400_Device *st400_devices = NULL; 106static unsigned int st400_num_devices = 0; 107static const SANE_Device **st400_device_array = NULL; 108/* The array pointer must stay valid between calls to sane_get_devices(). 109 * So we cannot modify or deallocate the array when a new device is attached 110 * - until the next call to sane_get_devices(). The array_valid bit indicates 111 * whether the array is still in sync with the device list or not (if new 112 * devices have been attached in the meantime). 113 */ 114static struct { 115 unsigned array_valid: 1; 116} st400_status = { 0 }; 117static size_t st400_maxread = 0; 118static size_t st400_light_delay = 0; 119static int st400_dump_data = 0; 120 121/* SCSI commands */ 122#define CMD_TEST_UNIT_READY 0x00 123#define CMD_INQUIRY 0x12 124#define CMD_MODE_SELECT 0x15 125#define CMD_RESERVE 0x16 126#define CMD_RELEASE 0x17 127#define CMD_START_STOP 0x1b 128#define CMD_SET_WINDOW 0x24 129#define CMD_READ_CAPACITY 0x25 /* get window settings - unused */ 130#define CMD_READ10 0x28 131 132/* prototypes */ 133static SANE_Status st400_inquiry( int fd, ST400_Model **modelP ); 134static SANE_Status st400_sense_handler( int fd, SANE_Byte *result, void *arg ); 135static SANE_Status st400_attach( const char *devname, ST400_Device **devP ); 136static SANE_Status st400_attach_one( const char *device ); 137static void st400_init_options( ST400_Device *dev ); 138static SANE_Status st400_set_window( ST400_Device *dev ); 139static SANE_Status st400_wait_ready( int fd ); 140static SANE_Status st400_cmd6( int fd, SANE_Byte cmd, SANE_Byte ctrl ); 141static SANE_Status st400_read10( int fd, SANE_Byte *buf, size_t *lenP ); 142static void st400_reset_options( ST400_Device *dev ); 143 144#undef min 145#define min(a, b) ((a) < (b) ? (a) : (b)) 146#define maxval(bpp) ((1<<(bpp))-1) 147 148/* Debugging levels */ 149#define DERR 0 /* errors */ 150#define DINFO 1 /* misc information */ 151#define DSENSE 2 /* SCSI sense */ 152#define DSCSI 3 /* SCSI commands */ 153#define DOPT 4 /* option control */ 154#define DVAR 5 /* important variables */ 155#define DCODE 6 /* code flow */ 156 157 158/********************************************************************* 159 * low-level SCSI functions 160 *********************************************************************/ 161 162#define set24(m, x) do { \ 163 *((SANE_Byte *)(m)+0) = (SANE_Byte)(((x) >> 16) & 0xff); \ 164 *((SANE_Byte *)(m)+1) = (SANE_Byte)(((x) >> 8) & 0xff); \ 165 *((SANE_Byte *)(m)+2) = (SANE_Byte)(((x) >> 0) & 0xff); \ 166} while(0) 167#define set16(m, x) do { \ 168 *((SANE_Byte *)(m)+0) = (SANE_Byte)(((x) >> 8) & 0xff); \ 169 *((SANE_Byte *)(m)+1) = (SANE_Byte)(((x) >> 0) & 0xff); \ 170} while(0) 171 172 173static int str_at_offset(char *str, size_t offset, unsigned char *data) 174{ 175 size_t len; 176 177 len = strlen(str); 178 return !strncmp((char *)&data[offset], str, len); 179} 180 181 182static SANE_Status 183st400_inquiry( int fd, ST400_Model **modelP ) 184{ 185 struct { SANE_Byte cmd, lun, reserved[2], tr_len, ctrl; } scsi_cmd; 186/* 187 struct { 188 SANE_Byte devtype, devqual, version; 189 SANE_Byte reserved1, additionallength; 190 SANE_Byte reserved2[2], flags; 191 SANE_Byte vendor[8], product[16], release[4]; 192 SANE_Byte reserved3[60]; 193 } inqdata; 194*/ 195 struct { SANE_Byte bytes[96]; } inqdata; 196 197 size_t inqlen; 198 SANE_Status status; 199 ST400_Model *model; 200 201 inqlen = sizeof(inqdata); 202 memset(&scsi_cmd, 0, sizeof(scsi_cmd)); 203 scsi_cmd.cmd = CMD_INQUIRY; 204 scsi_cmd.tr_len = inqlen; 205 206 DBG(DSCSI, "SCSI: sending INQUIRY (%lu bytes)\n", (u_long)inqlen); 207 status = sanei_scsi_cmd(fd, &scsi_cmd, sizeof(scsi_cmd), &inqdata, &inqlen); 208 DBG(DSCSI, "SCSI: result=%s (%lu bytes)\n", sane_strstatus(status), (u_long)inqlen); 209 if( status != SANE_STATUS_GOOD ) 210 return status; 211 212 if( st400_dump_data ) { 213 const char *home = getenv ("HOME"); 214 char basename[] = "st400.dump"; 215 char *name; 216 FILE *fp; 217 218 if (home) { 219 name = malloc (strlen (home) + sizeof (basename) + 1); 220 sprintf (name, "%s/%s", home, basename); 221 } else name = basename; 222 223 fp = fopen(name, "ab"); 224 if( fp != NULL ) { 225 fwrite(inqdata.bytes, 1, inqlen, fp); 226 fclose(fp); 227 } 228 229 if (name != basename) 230 free (name); 231 } 232 233 if( inqlen != sizeof(inqdata) ) 234 return SANE_STATUS_IO_ERROR; 235 236 for( model = st400_models; model->inq_vendor; model++ ) { 237 if( str_at_offset(model->inq_vendor, model->inq_voffset, inqdata.bytes) && str_at_offset(model->inq_model, model->inq_moffset, inqdata.bytes) ) { 238 *modelP = model; 239 DBG(DINFO, "found matching scanner model \"%s %s\" in list\n", model->sane_vendor, model->sane_model); 240 return SANE_STATUS_GOOD; 241 } 242 } 243 244 return SANE_STATUS_UNSUPPORTED; 245} 246 247static SANE_Status 248st400_cmd6( int fd, SANE_Byte cmd, SANE_Byte ctrl ) 249{ 250 struct { SANE_Byte cmd, lun, reserved[2], tr_len, ctrl; } scsi_cmd; 251 SANE_Status status; 252 253 memset(&scsi_cmd, 0, sizeof(scsi_cmd)); 254 scsi_cmd.cmd = cmd; 255 scsi_cmd.ctrl = ctrl; 256 257 DBG(DSCSI, "SCSI: sending cmd6 0x%02x (ctrl=%d)\n", (int)cmd, (int)ctrl); 258 status = sanei_scsi_cmd(fd, &scsi_cmd, sizeof(scsi_cmd), 0, 0); 259 DBG(DSCSI, "SCSI: result=%s\n", sane_strstatus(status)); 260 261 return status; 262} 263 264#define st400_test_ready(fd) st400_cmd6(fd, CMD_TEST_UNIT_READY, 0) 265#define st400_reserve(fd) st400_cmd6(fd, CMD_RESERVE, 0) 266#define st400_release(fd) st400_cmd6(fd, CMD_RELEASE, 0) 267#define st400_start_scan(fd) st400_cmd6(fd, CMD_START_STOP, 0) 268#define st400_light_on(fd) st400_cmd6(fd, CMD_MODE_SELECT, 0x80) 269#define st400_light_off(fd) st400_cmd6(fd, CMD_MODE_SELECT, 0) 270 271 272static SANE_Status 273st400_wait_ready( int fd ) 274{ 275#define SLEEPTIME 100000L /* 100ms */ 276 long max_sleep = 60000000L; /* 60 seconds */ 277 SANE_Status status; 278 279 DBG(DCODE, "st400_wait_ready(%d)\n", fd); 280 281 while(1) { 282 status = st400_test_ready(fd); 283 switch( status ) { 284 case SANE_STATUS_DEVICE_BUSY: 285 if( max_sleep > 0 ) { 286 usleep(SLEEPTIME); /* retry after 100ms */ 287 max_sleep -= SLEEPTIME; 288 break; 289 } 290 /* else fall through */ 291 default: 292 DBG(DERR, "st400_wait_ready: failed, error=%s\n", sane_strstatus(status)); 293 /* fall through */ 294 case SANE_STATUS_GOOD: 295 return status; 296 } 297 } 298 /*NOTREACHED*/ 299} 300 301 302static SANE_Status 303st400_set_window( ST400_Device *dev ) 304{ 305 unsigned short xoff, yoff; 306 SANE_Byte th; 307 308 struct { 309 /* 10byte command */ 310 SANE_Byte cmd, lun, reserved1[4], tr_len[3], ctrl; 311 312 /* 40byte window struct */ 313 SANE_Byte reserved2[6], wd_len[2], winnr, reserved3; 314 SANE_Byte x_res[2], y_res[2]; /* resolution: 200, 300, 400 */ 315 SANE_Byte x_ul[2], y_ul[2]; /* upper left corner */ 316 SANE_Byte width[2], height[2]; 317 SANE_Byte reserved4, threshold; 318 SANE_Byte reserved5, halftone; /* ht: 0 or 2 */ 319 SANE_Byte bitsperpixel, reserved6[13]; /* bpp: 1 or 8 */ 320 } scsi_cmd; 321 /* The PC/Amiga source uses reserved5 to indicate A4/A5 paper size 322 * (values 4 and 5), but a comment implies that this is only for the 323 * scanning program and the value is ignored by the scanner. 324 */ 325 SANE_Status status; 326 327 memset(&scsi_cmd, 0, sizeof(scsi_cmd)); 328 scsi_cmd.cmd = CMD_SET_WINDOW; 329 set24(scsi_cmd.tr_len, 40); 330 set16(scsi_cmd.wd_len, 32); 331 332 /* These offsets seem to be required to avoid damaging the scanner: 333 * If a scan with 0/0 as the top left corner is started, the scanner 334 * seems to try to move the carriage over the bottom end (not a 335 * pretty sound). 336 */ 337 xoff = (11L * dev->val[OPT_RESOLUTION]) / 100; 338 yoff = 6; 339 th = (double)maxval(dev->model->bits) * SANE_UNFIX(dev->val[OPT_THRESHOLD]) / 100.0; 340 341 scsi_cmd.winnr = 1; 342 set16(scsi_cmd.x_res, (unsigned short)dev->val[OPT_RESOLUTION]); 343 set16(scsi_cmd.y_res, (unsigned short)dev->val[OPT_RESOLUTION]); 344 set16(scsi_cmd.x_ul, dev->x + xoff); 345 set16(scsi_cmd.y_ul, dev->wy + yoff); 346 set16(scsi_cmd.width, dev->w); 347 set16(scsi_cmd.height, dev->wh); 348 scsi_cmd.threshold = th; 349 scsi_cmd.halftone = (dev->val[OPT_DEPTH] == 1) ? 0 : 2; 350 scsi_cmd.bitsperpixel = dev->val[OPT_DEPTH]; 351 352 DBG(DSCSI, "SCSI: sending SET_WINDOW (x=%hu y=%hu w=%hu h=%hu wy=%hu wh=%hu th=%d\n", dev->x, dev->y, dev->w, dev->h, dev->wy, dev->wh, (int)th); 353 status = sanei_scsi_cmd(dev->fd, &scsi_cmd, sizeof(scsi_cmd), 0, 0); 354 DBG(DSCSI, "SCSI: result=%s\n", sane_strstatus(status)); 355 356 return status; 357} 358 359static SANE_Status 360st400_read10( int fd, SANE_Byte *buf, size_t *lenP ) 361{ 362 struct { SANE_Byte cmd, lun, res[4], tr_len[3], ctrl; } scsi_cmd; 363 SANE_Status status; 364 365 memset(&scsi_cmd, 0, sizeof(scsi_cmd)); 366 scsi_cmd.cmd = CMD_READ10; 367 set24(scsi_cmd.tr_len, *lenP); 368 369 DBG(DSCSI, "SCSI: sending READ10 (%lu bytes)\n", (u_long)(*lenP)); 370 status = sanei_scsi_cmd(fd, &scsi_cmd, sizeof(scsi_cmd), buf, lenP); 371 DBG(DSCSI, "SCSI: result=%s (%lu bytes)\n", sane_strstatus(status), (u_long)(*lenP)); 372 373 return status; 374} 375 376static SANE_Status 377st400_fill_scanner_buffer( ST400_Device *dev ) 378{ 379 SANE_Status status; 380 381 DBG(DCODE, "st400_fill_scanner_buffer(%p)\n", (void *) dev); 382 383 if( dev->lines_to_read == 0 ) 384 dev->status.eof = 1; 385 if( dev->status.eof ) 386 return SANE_STATUS_EOF; 387 388 dev->wh = dev->model->bufsize / dev->params.bytes_per_line; 389 if( dev->wh > dev->lines_to_read ) 390 dev->wh = dev->lines_to_read; 391 DBG(DVAR, "dev->wh = %hu\n", dev->wh); 392 393 status = st400_set_window(dev); 394 if( status != SANE_STATUS_GOOD ) 395 return status; 396 397 status = st400_start_scan(dev->fd); 398 if( status != SANE_STATUS_GOOD ) 399 return status; 400 401 dev->wy += dev->wh; 402 dev->lines_to_read -= dev->wh; 403 dev->bytes_in_scanner = dev->wh * dev->params.bytes_per_line; 404 405 return SANE_STATUS_GOOD; 406} 407 408static SANE_Status 409st400_fill_backend_buffer( ST400_Device *dev ) 410{ 411 size_t r; 412 SANE_Status status; 413 414 DBG(DCODE, "st400_fill_backend_buffer(%p)\n", (void *) dev); 415 416 if( dev->bytes_in_scanner == 0 ) { 417 status = st400_fill_scanner_buffer(dev); 418 if( status != SANE_STATUS_GOOD ) 419 return status; 420 } 421 422 r = min(dev->bufsize, dev->bytes_in_scanner); 423 status = st400_read10(dev->fd, dev->buffer, &r); 424 if( status == SANE_STATUS_GOOD ) { 425 dev->bufp = dev->buffer; 426 dev->bytes_in_buffer = r; 427 dev->bytes_in_scanner -= r; 428 429 if( r == 0 ) 430 dev->status.eof = 1; 431 } 432 433 return status; 434} 435 436static SANE_Status 437st400_sense_handler( int fd, SANE_Byte *result, void *arg ) 438{ 439 /* ST400_Device *dev = arg; */ 440 SANE_Status status; 441 442 (void) fd; 443 (void) arg; /* silence compilation warnings */ 444 445 switch( result[0] & 0x0f ) { 446 case 0x0: 447 status = SANE_STATUS_GOOD; 448 break; 449 case 0x1: 450 DBG(DSENSE, "SCSI: sense RECOVERED_ERROR\n"); 451 status = SANE_STATUS_GOOD; /* ?? */ 452 break; 453 case 0x2: 454 DBG(DSENSE, "SCSI: sense NOT_READY\n"); 455 status = SANE_STATUS_DEVICE_BUSY; 456 break; 457 case 0x4: 458 DBG(DSENSE, "SCSI: sense HARDWARE_ERROR\n"); 459 status = SANE_STATUS_IO_ERROR; 460 break; 461 case 0x5: 462 DBG(DSENSE, "SCSI: sense ILLEGAL_REQUEST\n"); 463 status = SANE_STATUS_IO_ERROR; 464 break; 465 case 0x6: 466 DBG(DSENSE, "SCSI: sense UNIT_ATTENTION\n"); 467 status = SANE_STATUS_DEVICE_BUSY; 468 break; 469 case 0xb: 470 DBG(DSENSE, "SCSI: sense ABORTED_COMMAND\n"); 471 status = SANE_STATUS_CANCELLED; /* ?? */ 472 break; 473 default: 474 DBG(DSENSE, "SCSI: sense unknown (%d)\n", result[0] & 0x0f); 475 status = SANE_STATUS_IO_ERROR; 476 break; 477 } 478 return status; 479} 480 481 482/********************************************************************* 483 * Sane initializing stuff 484 *********************************************************************/ 485 486static SANE_Status 487st400_attach( const char *devname, ST400_Device **devP ) 488{ 489 ST400_Device *dev; 490 ST400_Model *model; 491 SANE_Status status; 492 int fd; 493 494 DBG(DCODE, "st400_attach(%s, %p)\n", devname, (void *) devP); 495 if( devP ) 496 *devP = NULL; 497 498 for( dev = st400_devices; dev != NULL; dev = dev->next ) { 499 if( strcmp(dev->sane.name, devname) == 0 ) { 500 if( devP ) 501 *devP = dev; 502 DBG(DCODE, "st400_attach: found device in list\n"); 503 return SANE_STATUS_GOOD; 504 } 505 } 506 507 dev = calloc(1, sizeof(*dev)); 508 if( !dev ) 509 return SANE_STATUS_NO_MEM; 510 DBG(DCODE, "st400_attach: new device struct at %p\n", (void *) dev); 511 512 status = sanei_scsi_open(devname, &fd, st400_sense_handler, dev); 513 if( status == SANE_STATUS_GOOD ) { 514 status = st400_inquiry(fd, &model); 515 if( status == SANE_STATUS_GOOD ) 516 status = st400_test_ready(fd); 517 sanei_scsi_close(fd); 518 } 519 if( status != SANE_STATUS_GOOD ) { 520 free(dev); 521 return status; 522 } 523 524 /* initialize device structure */ 525 dev->sane.name = strdup(devname); 526 if( !dev->sane.name ) { 527 free(dev); 528 return SANE_STATUS_NO_MEM; 529 } 530 dev->sane.vendor = model->sane_vendor; 531 dev->sane.model = model->sane_model; 532 dev->sane.type = model->sane_type; 533 dev->status.open = 0; 534 dev->status.scanning = 0; 535 dev->status.eof = 0; 536 dev->fd = -1; 537 dev->buffer = NULL; 538 dev->model = model; 539 540 st400_init_options(dev); 541 542 DBG(DCODE, "st400_attach: everything ok, adding device to list\n"); 543 544 dev->next = st400_devices; 545 st400_devices = dev; 546 ++st400_num_devices; 547 st400_status.array_valid = 0; 548 549 if( devP ) 550 *devP = dev; 551 return SANE_STATUS_GOOD; 552} 553 554static SANE_Status 555st400_attach_one( const char *device ) 556{ 557 DBG(DCODE, "st400_attach_one(%s)\n", device); 558 return st400_attach(device, NULL); 559} 560 561static SANE_Status 562st400_config_get_arg(char **optP, unsigned long *argP, size_t linenum) 563{ 564 int n; 565 566 (void) linenum; /* silence compilation warnings */ 567 568 if( sscanf(*optP, "%lu%n", argP, &n) == 1 ) { 569 *optP += n; 570 *optP = (char *)sanei_config_skip_whitespace(*optP); 571 return SANE_STATUS_GOOD; 572 } 573 return SANE_STATUS_INVAL; 574} 575 576 577static SANE_Status 578st400_config_get_single_arg(char *opt, unsigned long *argP, size_t linenum) 579{ 580 int n; 581 582 if( sscanf(opt, "%lu%n", argP, &n) == 1 ) { 583 opt += n; 584 opt = (char *)sanei_config_skip_whitespace(opt); 585 if( *opt == '\0' ) 586 return SANE_STATUS_GOOD; 587 else { 588 DBG(DERR, "extraneous arguments at line %lu: %s\n", (u_long)linenum, opt); 589 return SANE_STATUS_INVAL; 590 } 591 } 592 DBG(DERR, "invalid option argument at line %lu: %s\n", (u_long)linenum, opt); 593 return SANE_STATUS_INVAL; 594} 595 596 597static SANE_Status 598st400_config_do_option(char *opt, size_t linenum) 599{ 600 unsigned long arg; 601 SANE_Status status; 602 int i; 603 604 status = SANE_STATUS_GOOD; 605 606 opt = (char *)sanei_config_skip_whitespace(opt); 607 if( strncmp(opt, "maxread", 7) == 0 && isspace(opt[7]) ) { 608 opt += 8; 609 status = st400_config_get_single_arg(opt, &arg, linenum); 610 if( status == SANE_STATUS_GOOD ) { 611 if( arg == 0 ) 612 st400_maxread = sanei_scsi_max_request_size; 613 else 614 st400_maxread = (size_t)arg; 615 } 616 } 617 else 618 if( strncmp(opt, "delay", 5) == 0 && isspace(opt[5]) ) { 619 opt += 6; 620 status = st400_config_get_single_arg(opt, &arg, linenum); 621 if( status == SANE_STATUS_GOOD ) 622 st400_light_delay = (size_t)arg; 623 } 624 else 625 if( strncmp(opt, "scanner_bufsize", 15) == 0 && isspace(opt[15]) ) { 626 opt += 16; 627 status = st400_config_get_single_arg(opt, &arg, linenum); 628 if( status == SANE_STATUS_GOOD ) 629 if( st400_devices ) 630 st400_devices->model->bufsize = arg; /* FIXME: changes bufsize for all scanners of this model! */ 631 } 632 else 633 if( strncmp(opt, "scanner_bits", 12) == 0 && isspace(opt[12]) ) { 634 opt += 13; 635 status = st400_config_get_single_arg(opt, &arg, linenum); 636 if( status == SANE_STATUS_GOOD ) 637 if( st400_devices ) 638 st400_devices->model->bits = arg; /* FIXME */ 639 } 640 else 641 if( strncmp(opt, "scanner_maxread", 15) == 0 && isspace(opt[15]) ) { 642 opt += 16; 643 status = st400_config_get_single_arg(opt, &arg, linenum); 644 if( status == SANE_STATUS_GOOD ) 645 if( st400_devices ) 646 st400_devices->model->maxread = arg; /* FIXME */ 647 } 648 else 649 if( strncmp(opt, "scanner_resolutions", 19) == 0 && isspace(opt[19]) ) { 650 opt += 20; 651 st400_devices->model->dpi_list = malloc(16 * sizeof(SANE_Int)); 652 i = 0; 653 do { 654 status = st400_config_get_arg(&opt, &arg, linenum); 655 if( status == SANE_STATUS_GOOD ) { 656 ++i; 657 st400_devices->model->dpi_list[i] = (SANE_Int)arg; 658 } 659 } while( status == SANE_STATUS_GOOD && i < 15 ); 660 st400_devices->model->dpi_list[0] = i; 661 DBG(DINFO, "%d entries for resolution\n", i); 662 status = SANE_STATUS_GOOD; 663 } 664 else 665 if( strncmp(opt, "dump_inquiry", 12) == 0 ) { 666 st400_dump_data = 1; 667 } 668 if( st400_devices ) 669 st400_reset_options(st400_devices); 670 return status; 671} 672 673SANE_Status 674sane_init( SANE_Int *versionP, SANE_Auth_Callback authorize ) 675{ 676 FILE *fp; 677 SANE_Status status; 678 679 DBG_INIT(); 680 DBG(DCODE, "sane_init: version %s null, authorize %s null\n", (versionP) ? "!=" : "==", (authorize) ? "!=" : "=="); 681 682 if( versionP != NULL ) 683 *versionP = SANE_VERSION_CODE(SANE_CURRENT_MAJOR, SANE_CURRENT_MINOR, 0); 684 685 status = SANE_STATUS_GOOD; 686 if( (fp = sanei_config_open(ST400_CONFIG_FILE)) != NULL ) { 687 char line[PATH_MAX], *str; 688 size_t len, linenum; 689 690 linenum = 0; 691 DBG(DCODE, "sane_init: reading config file\n"); 692 while( sanei_config_read(line, sizeof(line), fp) ) { 693 ++linenum; 694 str = line; 695 if( str[0] == '#' ) 696 continue; /* ignore comments */ 697 str = (char *)sanei_config_skip_whitespace(str); 698 len = strlen(str); 699 if( !len ) 700 continue; /* ignore empty lines */ 701 if( strncmp(str, "option", 6) == 0 && isspace(str[6]) ) { 702 DBG(DCODE, "sane_init: config line <%s>\n", line); 703 status = st400_config_do_option(str+7, linenum); 704 } 705 else { 706 DBG(DCODE, "sane_init: attaching device <%s>\n", line); 707 sanei_config_attach_matching_devices(line, st400_attach_one); 708 } 709 if( status != SANE_STATUS_GOOD ) 710 break; 711 } 712 DBG(DCODE, "sane_init: closing config file\n"); 713 fclose(fp); 714 } 715 716 if( status == SANE_STATUS_GOOD && st400_devices == NULL ) { 717 DBG(DCODE, "sane_init: attaching default device <%s>\n", ST400_DEFAULT_DEVICE); 718 sanei_config_attach_matching_devices(ST400_DEFAULT_DEVICE, st400_attach_one); 719 } 720 721 return status; 722} 723 724void 725sane_exit( void ) 726{ 727 ST400_Device *dev; 728 729 DBG(DCODE, "sane_exit()\n"); 730 731 while( (dev = st400_devices) != NULL ) { 732 st400_devices = dev->next; 733 734 sane_close(dev); 735 free((char *)(dev->sane.name)); 736 free(dev); 737 } 738 st400_num_devices = 0; 739 if( st400_device_array ) { 740 DBG(DCODE, "sane_exit: freeing device array\n"); 741 free(st400_device_array); 742 st400_device_array = NULL; 743 st400_status.array_valid = 0; 744 } 745} 746 747SANE_Status 748sane_get_devices( const SANE_Device ***devarrayP, SANE_Bool local_only ) 749{ 750 ST400_Device *dev; 751 unsigned int i; 752 753 DBG(DCODE, "sane_get_devices(%p, %d)\n", (void *) devarrayP, (int)local_only); 754 755 if( !st400_status.array_valid ) { 756 if( st400_device_array ) { 757 DBG(DCODE, "sane_get_devices: freeing old device array\n"); 758 free(st400_device_array); 759 } 760 st400_device_array = malloc((st400_num_devices + 1) * sizeof(*st400_device_array)); 761 if( !st400_device_array ) 762 return SANE_STATUS_NO_MEM; 763 DBG(DCODE, "sane_get_devices: new device array at %p\n", (void *) st400_device_array); 764 765 dev = st400_devices; 766 for( i = 0; i < st400_num_devices; i++ ) { 767 st400_device_array[i] = &dev->sane; 768 dev = dev->next; 769 } 770 st400_device_array[st400_num_devices] = NULL; 771 st400_status.array_valid = 1; 772 } 773 DBG(DCODE, "sane_get_devices: %u entries in device array\n", st400_num_devices); 774 if( devarrayP ) 775 *devarrayP = st400_device_array; 776 return SANE_STATUS_GOOD; 777} 778 779 780SANE_Status 781sane_open( SANE_String_Const devicename, SANE_Handle *handleP ) 782{ 783 ST400_Device *dev; 784 SANE_Status status; 785 786 DBG(DCODE, "sane_open(%s, %p)\n", devicename, (void *) handleP); 787 788 *handleP = NULL; 789 if( devicename && devicename[0] ) { 790 status = st400_attach(devicename, &dev); 791 if( status != SANE_STATUS_GOOD ) 792 return status; 793 } 794 else 795 dev = st400_devices; 796 797 if( !dev ) 798 return SANE_STATUS_INVAL; 799 800 if( dev->status.open ) 801 return SANE_STATUS_DEVICE_BUSY; 802 803 dev->status.open = 1; 804 st400_reset_options(dev); 805 *handleP = (SANE_Handle)dev; 806 807 return SANE_STATUS_GOOD; 808} 809 810 811void 812sane_close( SANE_Handle handle ) 813{ 814 ST400_Device *dev = handle; 815 816 DBG(DCODE, "sane_close(%p)\n", handle); 817 818 if( dev->status.open ) { 819 sane_cancel(dev); 820 dev->status.open = 0; 821 } 822} 823 824 825/* 826 * options 827 */ 828static void 829st400_reset_options( ST400_Device *dev ) 830{ 831 DBG(DCODE, "st400_reset_options(%p)\n", (void *) dev); 832 833 dev->val[OPT_NUM_OPTS] = NUM_OPTIONS; 834 dev->val[OPT_RESOLUTION] = dev->opt[OPT_RESOLUTION].constraint.word_list[1]; 835 dev->val[OPT_DEPTH] = dev->opt[OPT_DEPTH].constraint.word_list[1]; 836 dev->val[OPT_THRESHOLD] = SANE_FIX(50.0); 837 dev->opt[OPT_THRESHOLD].cap &= ~SANE_CAP_INACTIVE; 838 dev->val[OPT_TL_X] = SANE_FIX(0.0); 839 dev->val[OPT_TL_Y] = SANE_FIX(0.0); 840 dev->val[OPT_BR_X] = SANE_FIX(0.0); 841 dev->val[OPT_BR_Y] = SANE_FIX(0.0); 842 843 if( dev->model->dpi_list ) 844 dev->opt[OPT_RESOLUTION].constraint.word_list = dev->model->dpi_list; 845} 846 847static void 848st400_init_options( ST400_Device *dev ) 849{ 850 static const SANE_Int depth_list[] = { 2, 1, 8 }; 851 static const SANE_Int dpi_list[] = { 3, 200, 300, 400 }; 852 static const SANE_Range thres_range = { 853 SANE_FIX(0.0), SANE_FIX(100.0), SANE_FIX(0.0) 854 }; 855 static const SANE_Range x_range = { 856 SANE_FIX(0.0), SANE_FIX(ST400_MAX_X * MM_PER_INCH), SANE_FIX(0.0) 857 }; 858 static const SANE_Range y_range = { 859 SANE_FIX(0.0), SANE_FIX(ST400_MAX_Y * MM_PER_INCH), SANE_FIX(0.0) 860 }; 861 862 DBG(DCODE, "st400_init_options(%p)\n", (void *)dev); 863 864 dev->opt[OPT_NUM_OPTS].name = SANE_NAME_NUM_OPTIONS; 865 dev->opt[OPT_NUM_OPTS].title = SANE_TITLE_NUM_OPTIONS; 866 dev->opt[OPT_NUM_OPTS].desc = SANE_DESC_NUM_OPTIONS; 867 dev->opt[OPT_NUM_OPTS].type = SANE_TYPE_INT; 868 dev->opt[OPT_NUM_OPTS].unit = SANE_UNIT_NONE; 869 dev->opt[OPT_NUM_OPTS].size = sizeof(SANE_Word); 870 dev->opt[OPT_NUM_OPTS].cap = SANE_CAP_SOFT_DETECT; 871 dev->opt[OPT_NUM_OPTS].constraint_type = SANE_CONSTRAINT_NONE; 872 873 dev->opt[OPT_MODE_GROUP].title= "Scan Mode"; 874 dev->opt[OPT_MODE_GROUP].type = SANE_TYPE_GROUP; 875 876 dev->opt[OPT_RESOLUTION].name = SANE_NAME_SCAN_RESOLUTION; 877 dev->opt[OPT_RESOLUTION].title= SANE_TITLE_SCAN_RESOLUTION; 878 dev->opt[OPT_RESOLUTION].desc = SANE_DESC_SCAN_RESOLUTION; 879 dev->opt[OPT_RESOLUTION].type = SANE_TYPE_INT; 880 dev->opt[OPT_RESOLUTION].unit = SANE_UNIT_DPI; 881 dev->opt[OPT_RESOLUTION].size = sizeof(SANE_Word); 882 dev->opt[OPT_RESOLUTION].cap = SANE_CAP_SOFT_SELECT|SANE_CAP_SOFT_DETECT; 883 dev->opt[OPT_RESOLUTION].constraint_type = SANE_CONSTRAINT_WORD_LIST; 884 dev->opt[OPT_RESOLUTION].constraint.word_list = dpi_list; 885 886 dev->opt[OPT_DEPTH].name = SANE_NAME_BIT_DEPTH; 887 dev->opt[OPT_DEPTH].title = SANE_TITLE_BIT_DEPTH; 888 dev->opt[OPT_DEPTH].desc = SANE_DESC_BIT_DEPTH; 889 dev->opt[OPT_DEPTH].type = SANE_TYPE_INT; 890 dev->opt[OPT_DEPTH].unit = SANE_UNIT_BIT; 891 dev->opt[OPT_DEPTH].size = sizeof(SANE_Word); 892 dev->opt[OPT_DEPTH].cap = SANE_CAP_SOFT_SELECT|SANE_CAP_SOFT_DETECT; 893 dev->opt[OPT_DEPTH].constraint_type = SANE_CONSTRAINT_WORD_LIST; 894 dev->opt[OPT_DEPTH].constraint.word_list = depth_list; 895 896 dev->opt[OPT_THRESHOLD].name = SANE_NAME_THRESHOLD; 897 dev->opt[OPT_THRESHOLD].title = SANE_TITLE_THRESHOLD; 898 dev->opt[OPT_THRESHOLD].desc = SANE_DESC_THRESHOLD; 899 dev->opt[OPT_THRESHOLD].type = SANE_TYPE_FIXED; 900 dev->opt[OPT_THRESHOLD].unit = SANE_UNIT_PERCENT; 901 dev->opt[OPT_THRESHOLD].size = sizeof(SANE_Word); 902 dev->opt[OPT_THRESHOLD].cap = SANE_CAP_SOFT_SELECT|SANE_CAP_SOFT_DETECT; 903 dev->opt[OPT_THRESHOLD].constraint_type = SANE_CONSTRAINT_RANGE; 904 dev->opt[OPT_THRESHOLD].constraint.range = &thres_range; 905 906 dev->opt[OPT_GEOMETRY_GROUP].title= "Geometry"; 907 dev->opt[OPT_GEOMETRY_GROUP].type = SANE_TYPE_GROUP; 908 909 dev->opt[OPT_TL_X].name = SANE_NAME_SCAN_TL_X; 910 dev->opt[OPT_TL_X].title = SANE_TITLE_SCAN_TL_X; 911 dev->opt[OPT_TL_X].desc = SANE_DESC_SCAN_TL_X; 912 dev->opt[OPT_TL_X].type = SANE_TYPE_FIXED; 913 dev->opt[OPT_TL_X].unit = SANE_UNIT_MM; 914 dev->opt[OPT_TL_X].size = sizeof(SANE_Word); 915 dev->opt[OPT_TL_X].cap = SANE_CAP_SOFT_SELECT|SANE_CAP_SOFT_DETECT; 916 dev->opt[OPT_TL_X].constraint_type = SANE_CONSTRAINT_RANGE; 917 dev->opt[OPT_TL_X].constraint.range = &x_range; 918 919 dev->opt[OPT_TL_Y].name = SANE_NAME_SCAN_TL_Y; 920 dev->opt[OPT_TL_Y].title = SANE_TITLE_SCAN_TL_Y; 921 dev->opt[OPT_TL_Y].desc = SANE_DESC_SCAN_TL_Y; 922 dev->opt[OPT_TL_Y].type = SANE_TYPE_FIXED; 923 dev->opt[OPT_TL_Y].unit = SANE_UNIT_MM; 924 dev->opt[OPT_TL_Y].size = sizeof(SANE_Word); 925 dev->opt[OPT_TL_Y].cap = SANE_CAP_SOFT_SELECT|SANE_CAP_SOFT_DETECT; 926 dev->opt[OPT_TL_Y].constraint_type = SANE_CONSTRAINT_RANGE; 927 dev->opt[OPT_TL_Y].constraint.range = &y_range; 928 929 dev->opt[OPT_BR_X].name = SANE_NAME_SCAN_BR_X; 930 dev->opt[OPT_BR_X].title = SANE_TITLE_SCAN_BR_X; 931 dev->opt[OPT_BR_X].desc = SANE_DESC_SCAN_BR_X; 932 dev->opt[OPT_BR_X].type = SANE_TYPE_FIXED; 933 dev->opt[OPT_BR_X].unit = SANE_UNIT_MM; 934 dev->opt[OPT_BR_X].size = sizeof(SANE_Word); 935 dev->opt[OPT_BR_X].cap = SANE_CAP_SOFT_SELECT|SANE_CAP_SOFT_DETECT; 936 dev->opt[OPT_BR_X].constraint_type = SANE_CONSTRAINT_RANGE; 937 dev->opt[OPT_BR_X].constraint.range = &x_range; 938 939 dev->opt[OPT_BR_Y].name = SANE_NAME_SCAN_BR_Y; 940 dev->opt[OPT_BR_Y].title = SANE_TITLE_SCAN_BR_Y; 941 dev->opt[OPT_BR_Y].desc = SANE_DESC_SCAN_BR_Y; 942 dev->opt[OPT_BR_Y].type = SANE_TYPE_FIXED; 943 dev->opt[OPT_BR_Y].unit = SANE_UNIT_MM; 944 dev->opt[OPT_BR_Y].size = sizeof(SANE_Word); 945 dev->opt[OPT_BR_Y].cap = SANE_CAP_SOFT_SELECT|SANE_CAP_SOFT_DETECT; 946 dev->opt[OPT_BR_Y].constraint_type = SANE_CONSTRAINT_RANGE; 947 dev->opt[OPT_BR_Y].constraint.range = &y_range; 948 949 st400_reset_options(dev); 950} 951 952const SANE_Option_Descriptor * 953sane_get_option_descriptor( SANE_Handle handle, SANE_Int optnum ) 954{ 955 ST400_Device *dev = handle; 956 957 DBG(DOPT, "sane_get_option_descriptor(%p, %d)\n", handle, (int)optnum); 958 959 if( dev->status.open && optnum >= 0 && optnum < NUM_OPTIONS ) 960 return &dev->opt[optnum]; 961 962 return NULL; 963} 964 965SANE_Status 966sane_control_option( SANE_Handle handle, SANE_Int optnum, 967 SANE_Action action, void *valP, SANE_Int *infoP) 968{ 969 ST400_Device *dev = handle; 970 SANE_Status status; 971 972 DBG(DCODE, "sane_control_option(%p, %d, %d, %p, %p)\n", (void *) handle, (int)optnum, (int)action, valP, (void *) infoP); 973 974 if( infoP ) 975 *infoP = 0; 976 977 if( !dev->status.open ) 978 return SANE_STATUS_INVAL; 979 if( dev->status.scanning ) 980 return SANE_STATUS_DEVICE_BUSY; 981 982 if( optnum < 0 || optnum >= NUM_OPTIONS ) 983 return SANE_STATUS_INVAL; 984 985 switch( action ) { 986 case SANE_ACTION_GET_VALUE: 987 988 DBG(DOPT, "getting option %d (value=%d)\n", (int)optnum, (int)dev->val[optnum]); 989 990 switch( optnum ) { 991 case OPT_NUM_OPTS: 992 case OPT_RESOLUTION: 993 case OPT_DEPTH: 994 case OPT_THRESHOLD: 995 case OPT_TL_X: 996 case OPT_TL_Y: 997 case OPT_BR_X: 998 case OPT_BR_Y: 999 *(SANE_Word *)valP = dev->val[optnum]; 1000 break; 1001 default: 1002 return SANE_STATUS_INVAL; 1003 } 1004 break; 1005 1006 case SANE_ACTION_SET_VALUE: 1007 if( !SANE_OPTION_IS_SETTABLE(dev->opt[optnum].cap) ) 1008 return SANE_STATUS_INVAL; 1009 status = sanei_constrain_value(&dev->opt[optnum], valP, infoP); 1010 if( status != SANE_STATUS_GOOD ) 1011 return status; 1012 1013 DBG(DOPT, "setting option %d to %d\n", (int)optnum, (int)*(SANE_Word *)valP); 1014 1015 switch( optnum ) { 1016 case OPT_DEPTH: 1017 if( *(SANE_Word *)valP != 1 ) 1018 dev->opt[OPT_THRESHOLD].cap |= SANE_CAP_INACTIVE; 1019 else 1020 dev->opt[OPT_THRESHOLD].cap &= ~SANE_CAP_INACTIVE; 1021 if( infoP ) 1022 *infoP |= SANE_INFO_RELOAD_OPTIONS; 1023 /* fall through */ 1024 case OPT_RESOLUTION: 1025 case OPT_TL_X: 1026 case OPT_TL_Y: 1027 case OPT_BR_X: 1028 case OPT_BR_Y: 1029 if( infoP ) 1030 *infoP |= SANE_INFO_RELOAD_PARAMS; 1031 /* fall through */ 1032 case OPT_THRESHOLD: 1033 dev->val[optnum] = *(SANE_Word *)valP; 1034 break; 1035 default: 1036 return SANE_STATUS_INVAL; 1037 } 1038 break; 1039 1040 case SANE_ACTION_SET_AUTO: 1041 1042 DBG(DOPT, "automatic option setting\n"); 1043 1044 return SANE_STATUS_UNSUPPORTED; 1045 1046 default: 1047 return SANE_STATUS_INVAL; 1048 } 1049 return SANE_STATUS_GOOD; 1050} 1051 1052SANE_Status 1053sane_get_parameters( SANE_Handle handle, SANE_Parameters *paramsP ) 1054{ 1055 ST400_Device *dev = handle; 1056 1057 DBG(DCODE, "sane_get_parameters(%p, %p)\n", handle, (void *) paramsP); 1058 1059 if( !dev->status.open ) 1060 return SANE_STATUS_INVAL; 1061 1062 if( !dev->status.scanning ) { 1063 double width, height, dpi; 1064 1065 dev->params.format = SANE_FRAME_GRAY; 1066 dev->params.last_frame = SANE_TRUE; 1067 dev->params.lines = 0; 1068 dev->params.depth = dev->val[OPT_DEPTH]; 1069 1070 width = SANE_UNFIX(dev->val[OPT_BR_X] - dev->val[OPT_TL_X]); 1071 height = SANE_UNFIX(dev->val[OPT_BR_Y] - dev->val[OPT_TL_Y]); 1072 dpi = dev->val[OPT_RESOLUTION]; 1073 1074 /* make best-effort guess at what parameters will look like once 1075 scanning starts. */ 1076 if( dpi > 0.0 && width > 0.0 && height > 0.0 ) { 1077 double dots_per_mm = dpi / MM_PER_INCH; 1078 1079 dev->params.pixels_per_line = width * dots_per_mm + 0.5; 1080 dev->params.lines = height * dots_per_mm + 0.5; 1081 1082 if( dev->params.depth == 1 ) { 1083 /* Pad to an even multiple of 8. This way we can simply 1084 * copy the bytes from the scanner to the SANE buffer 1085 * (only need to invert them). 1086 */ 1087 dev->params.pixels_per_line += 7; 1088 dev->params.pixels_per_line &= ~7; 1089 1090 /*dev->params.bytes_per_line = (dev->params.pixels_per_line + 7)/8;*/ 1091 dev->params.bytes_per_line = dev->params.pixels_per_line/8; 1092 } 1093 else 1094 dev->params.bytes_per_line = dev->params.pixels_per_line; 1095 1096 dev->x = SANE_UNFIX(dev->val[OPT_TL_X]) * dots_per_mm + 0.5; 1097 dev->y = SANE_UNFIX(dev->val[OPT_TL_Y]) * dots_per_mm + 0.5; 1098 dev->w = dev->params.pixels_per_line; 1099 dev->h = dev->params.lines; 1100 1101 DBG(DVAR, "parameters: bpl=%d, x=%hu, y=%hu, w=%hu, h=%hu\n", (int)dev->params.bytes_per_line, dev->x, dev->y, dev->w, dev->h); 1102 } 1103 } 1104 1105 if( paramsP ) 1106 *paramsP = dev->params; 1107 return SANE_STATUS_GOOD; 1108} 1109 1110 1111SANE_Status 1112sane_start( SANE_Handle handle ) 1113{ 1114 ST400_Device *dev = handle; 1115 SANE_Status status; 1116 1117 DBG(DCODE, "sane_start(%p)\n", handle); 1118 1119 if( !dev->status.open ) 1120 return SANE_STATUS_INVAL; 1121 if( dev->status.scanning ) 1122 return SANE_STATUS_DEVICE_BUSY; 1123 1124 status = sane_get_parameters(dev, NULL); 1125 if( status != SANE_STATUS_GOOD ) 1126 return status; 1127 1128 if( !dev->buffer ) { 1129 if( st400_maxread > 0 ) 1130 dev->bufsize = min(st400_maxread, (unsigned int) sanei_scsi_max_request_size); 1131 else 1132 if( dev->model->maxread > 0 ) 1133 dev->bufsize = min(dev->model->maxread, (unsigned int) sanei_scsi_max_request_size); 1134 else 1135 dev->bufsize = sanei_scsi_max_request_size; 1136 DBG(DVAR, "allocating %lu bytes buffer\n", (u_long)dev->bufsize); 1137 dev->buffer = malloc(dev->bufsize); 1138 if( !dev->buffer ) 1139 return SANE_STATUS_NO_MEM; 1140 } 1141 dev->bufp = dev->buffer; 1142 dev->bytes_in_buffer = 0; 1143 1144 if( dev->fd < 0 ) { 1145 status = sanei_scsi_open(dev->sane.name, &dev->fd, st400_sense_handler, dev); 1146 if( status != SANE_STATUS_GOOD ) 1147 goto return_error; 1148 } 1149 1150 dev->status.eof = 0; 1151 1152 status = st400_wait_ready(dev->fd); 1153 if( status != SANE_STATUS_GOOD ) 1154 goto close_and_return; 1155 1156 status = st400_reserve(dev->fd); 1157 if( status != SANE_STATUS_GOOD ) 1158 goto close_and_return; 1159 1160 if( st400_light_delay > 0 ) { 1161 status = st400_light_on(dev->fd); 1162 if( status != SANE_STATUS_GOOD ) 1163 goto release_and_return; 1164 usleep(st400_light_delay * 100000); /* 1/10 seconds */ 1165 } 1166 1167 dev->wy = dev->y; 1168 dev->lines_to_read = dev->h; 1169 dev->bytes_in_scanner = 0; 1170 1171 status = st400_fill_scanner_buffer(dev); 1172 if( status != SANE_STATUS_GOOD ) 1173 goto lightoff_and_return; 1174 1175 /* everything ok */ 1176 dev->status.scanning = 1; 1177 return SANE_STATUS_GOOD; 1178 1179lightoff_and_return: 1180 if( st400_light_delay ) 1181 st400_light_off(dev->fd); 1182release_and_return: 1183 st400_release(dev->fd); 1184close_and_return: 1185 sanei_scsi_close(dev->fd); 1186return_error: 1187 dev->fd = -1; 1188 return status; 1189} 1190 1191void 1192sane_cancel( SANE_Handle handle ) 1193{ 1194 ST400_Device *dev = handle; 1195 1196 DBG(DCODE, "sane_cancel(%p)\n", handle); 1197 1198 if( dev->status.scanning ) { 1199#if 0 1200 st400_stop_scan(dev->fd); 1201#endif 1202 if( st400_light_delay ) 1203 st400_light_off(dev->fd); 1204 st400_release(dev->fd); 1205 sanei_scsi_close(dev->fd); 1206 dev->status.scanning = 0; 1207 dev->fd = -1; 1208 } 1209 if( dev->buffer ) { 1210 free(dev->buffer); 1211 dev->buffer = NULL; 1212 } 1213} 1214 1215 1216SANE_Status 1217sane_read( SANE_Handle handle, SANE_Byte *buf, SANE_Int maxlen, SANE_Int *lenP ) 1218{ 1219 ST400_Device *dev = handle; 1220 SANE_Status status; 1221 size_t r, i; 1222 SANE_Byte val; 1223 1224 DBG(DCODE, "sane_read(%p, %p, %d, %p)\n", handle, (void *) buf, (int) maxlen, (void *) lenP); 1225 1226 *lenP = 0; 1227 if( !dev->status.scanning ) 1228 return SANE_STATUS_INVAL; 1229 if( dev->status.eof ) 1230 return SANE_STATUS_EOF; 1231 1232 status = SANE_STATUS_GOOD; 1233 while( maxlen > 0 ) { 1234 if( dev->bytes_in_buffer == 0 ) { 1235 status = st400_fill_backend_buffer(dev); 1236 if( status == SANE_STATUS_EOF ) 1237 return SANE_STATUS_GOOD; 1238 if( status != SANE_STATUS_GOOD ) { 1239 *lenP = 0; 1240 return status; 1241 } 1242 } 1243 1244 r = min((SANE_Int) dev->bytes_in_buffer, maxlen); 1245 1246 if( dev->val[OPT_DEPTH] == 1 || dev->model->bits == 8 ) { 1247 /* This is simple. We made sure the scanning are is aligned to 1248 * 8 pixels (see sane_get_parameters()), so we can simply copy 1249 * the stuff - only need to invert it. 1250 */ 1251 for( i = 0; i < r; i++ ) 1252 *buf++ = ~(*dev->bufp++); 1253 } 1254 else { 1255 SANE_Byte mv; 1256 1257 /* The scanner sends bytes with 6bit-values (0..63), where 0 means 1258 * white. To convert to 8bit, we invert the values (so 0 means 1259 * black) and then shift them two bits to the left and replicate 1260 * the most- significant bits in the lowest two bits of the 1261 * 8bit-value: 1262 * bit-pattern x x 5 4 3 2 1 0 becomes 5 4 3 2 1 0 5 4 1263 * This is more accurate than simply shifting the values two bits 1264 * to the left (e.g. 6bit-white 00111111 gets converted to 8bit- 1265 * white 11111111 instead of almost-white 11111100) and is still 1266 * reasonably fast. 1267 */ 1268 mv = (SANE_Byte)maxval(dev->model->bits); 1269 1270 /* Note: this works with any bit depth <= 8 */ 1271 for( i = 0; i < r; i++ ) { 1272 val = mv - *dev->bufp++; 1273 val <<= (8 - dev->model->bits); 1274 val += (val >> dev->model->bits); 1275 *buf++ = val; 1276 } 1277 } 1278 maxlen -= r; 1279 dev->bytes_in_buffer -= r; 1280 *lenP += r; 1281 } 1282 return status; 1283} 1284 1285 1286/********************************************************************* 1287 * Advanced functions (not supported) 1288 *********************************************************************/ 1289 1290SANE_Status 1291sane_set_io_mode( SANE_Handle handle, SANE_Bool nonblock ) 1292{ 1293 DBG(DCODE, "sane_set_io_mode(%p, %d)\n", handle, (int)nonblock); 1294 1295 if( nonblock == SANE_TRUE ) 1296 return SANE_STATUS_UNSUPPORTED; 1297 return SANE_STATUS_GOOD; 1298} 1299 1300SANE_Status 1301sane_get_select_fd( SANE_Handle handle, SANE_Int *fdP ) 1302{ 1303 DBG(DCODE, "sane_get_select_fd(%p, %p)\n", handle, (void *) fdP); 1304 1305 return SANE_STATUS_UNSUPPORTED; 1306} 1307/* The End */ 1308