1 /*
2 vim: 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 */
95 static 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 
105 static ST400_Device *st400_devices = NULL;
106 static unsigned int st400_num_devices = 0;
107 static 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  */
114 static struct {
115 	unsigned array_valid: 1;
116 } st400_status = { 0 };
117 static size_t st400_maxread = 0;
118 static size_t st400_light_delay = 0;
119 static 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 */
133 static SANE_Status st400_inquiry( int fd, ST400_Model **modelP );
134 static SANE_Status st400_sense_handler( int fd, SANE_Byte *result, void *arg );
135 static SANE_Status st400_attach( const char *devname, ST400_Device **devP );
136 static SANE_Status st400_attach_one( const char *device );
137 static void st400_init_options( ST400_Device *dev );
138 static SANE_Status st400_set_window( ST400_Device *dev );
139 static SANE_Status st400_wait_ready( int fd );
140 static SANE_Status st400_cmd6( int fd, SANE_Byte cmd, SANE_Byte ctrl );
141 static SANE_Status st400_read10( int fd, SANE_Byte *buf, size_t *lenP );
142 static 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 
str_at_offset(char *str, size_t offset, unsigned char *data)173 static 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 
182 static SANE_Status
st400_inquiry( int fd, ST400_Model **modelP )183 st400_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 
247 static SANE_Status
st400_cmd6( int fd, SANE_Byte cmd, SANE_Byte ctrl )248 st400_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 
272 static SANE_Status
st400_wait_ready( int fd )273 st400_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 
302 static SANE_Status
st400_set_window( ST400_Device *dev )303 st400_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 
359 static SANE_Status
st400_read10( int fd, SANE_Byte *buf, size_t *lenP )360 st400_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 
376 static SANE_Status
st400_fill_scanner_buffer( ST400_Device *dev )377 st400_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 
408 static SANE_Status
st400_fill_backend_buffer( ST400_Device *dev )409 st400_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 
436 static SANE_Status
st400_sense_handler( int fd, SANE_Byte *result, void *arg )437 st400_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 
486 static SANE_Status
st400_attach( const char *devname, ST400_Device **devP )487 st400_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 
554 static SANE_Status
st400_attach_one( const char *device )555 st400_attach_one( const char *device )
556 {
557 	DBG(DCODE, "st400_attach_one(%s)\n", device);
558 	return st400_attach(device, NULL);
559 }
560 
561 static SANE_Status
st400_config_get_arg(char **optP, unsigned long *argP, size_t linenum)562 st400_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 
577 static SANE_Status
st400_config_get_single_arg(char *opt, unsigned long *argP, size_t linenum)578 st400_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 
597 static SANE_Status
st400_config_do_option(char *opt, size_t linenum)598 st400_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 
673 SANE_Status
sane_init( SANE_Int *versionP, SANE_Auth_Callback authorize )674 sane_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 
724 void
sane_exit( void )725 sane_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 
747 SANE_Status
sane_get_devices( const SANE_Device ***devarrayP, SANE_Bool local_only )748 sane_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 
780 SANE_Status
sane_open( SANE_String_Const devicename, SANE_Handle *handleP )781 sane_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 
811 void
sane_close( SANE_Handle handle )812 sane_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  */
828 static void
st400_reset_options( ST400_Device *dev )829 st400_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 
847 static void
st400_init_options( ST400_Device *dev )848 st400_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 
952 const SANE_Option_Descriptor *
sane_get_option_descriptor( SANE_Handle handle, SANE_Int optnum )953 sane_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 
965 SANE_Status
sane_control_option( SANE_Handle handle, SANE_Int optnum, SANE_Action action, void *valP, SANE_Int *infoP)966 sane_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 
1052 SANE_Status
sane_get_parameters( SANE_Handle handle, SANE_Parameters *paramsP )1053 sane_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 
1111 SANE_Status
sane_start( SANE_Handle handle )1112 sane_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 
1179 lightoff_and_return:
1180 	if( st400_light_delay )
1181 		st400_light_off(dev->fd);
1182 release_and_return:
1183 	st400_release(dev->fd);
1184 close_and_return:
1185 	sanei_scsi_close(dev->fd);
1186 return_error:
1187 	dev->fd = -1;
1188 	return status;
1189 }
1190 
1191 void
sane_cancel( SANE_Handle handle )1192 sane_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 
1216 SANE_Status
sane_read( SANE_Handle handle, SANE_Byte *buf, SANE_Int maxlen, SANE_Int *lenP )1217 sane_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 
1290 SANE_Status
sane_set_io_mode( SANE_Handle handle, SANE_Bool nonblock )1291 sane_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 
1300 SANE_Status
sane_get_select_fd( SANE_Handle handle, SANE_Int *fdP )1301 sane_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