| 
									
										
										
										
											2000-08-12 15:11:46 +00:00
										 |  |  | /* sane - Scanner Access Now Easy.
 | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  |    Copyright (C) 2000-2003 Jochen Eisinger <jochen.eisinger@gmx.net> | 
					
						
							| 
									
										
										
										
											2000-08-12 15:11:46 +00:00
										 |  |  |    This file is part of the SANE package. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |    This program is free software; you can redistribute it and/or | 
					
						
							|  |  |  |    modify it under the terms of the GNU General Public License as | 
					
						
							|  |  |  |    published by the Free Software Foundation; either version 2 of the | 
					
						
							|  |  |  |    License, or (at your option) any later version. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |    This program is distributed in the hope that it will be useful, but | 
					
						
							|  |  |  |    WITHOUT ANY WARRANTY; without even the implied warranty of | 
					
						
							|  |  |  |    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU | 
					
						
							|  |  |  |    General Public License for more details. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |    You should have received a copy of the GNU General Public License | 
					
						
							|  |  |  |    along with this program; if not, write to the Free Software | 
					
						
							|  |  |  |    Foundation, Inc., 59 Temple Place - Suite 330, Boston, | 
					
						
							|  |  |  |    MA 02111-1307, USA. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |    As a special exception, the authors of SANE give permission for | 
					
						
							|  |  |  |    additional uses of the libraries contained in this release of SANE. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |    The exception is that, if you link a SANE library with other files | 
					
						
							|  |  |  |    to produce an executable, this does not by itself cause the | 
					
						
							|  |  |  |    resulting executable to be covered by the GNU General Public | 
					
						
							|  |  |  |    License.  Your use of that executable is in no way restricted on | 
					
						
							|  |  |  |    account of linking the SANE library code into it. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |    This exception does not, however, invalidate any other reasons why | 
					
						
							|  |  |  |    the executable file might be covered by the GNU General Public | 
					
						
							|  |  |  |    License. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |    If you submit changes to SANE to the maintainers to be included in | 
					
						
							|  |  |  |    a subsequent release, you agree by submitting the changes that | 
					
						
							|  |  |  |    those changes may be distributed with this exception intact. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |    If you write modifications of your own for SANE, it is your choice | 
					
						
							|  |  |  |    whether to permit this exception to apply to your modifications. | 
					
						
							|  |  |  |    If you do not wish that, delete this exception notice. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |    This file implements a SANE backend for Mustek PP flatbed scanners.  */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2000-11-19 16:17:38 +00:00
										 |  |  | #include "../include/sane/config.h"
 | 
					
						
							| 
									
										
										
										
											2000-08-12 15:11:46 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  | #if defined(HAVE_STDLIB_H)
 | 
					
						
							|  |  |  | # include <stdlib.h>
 | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | #include <stdio.h>
 | 
					
						
							| 
									
										
										
										
											2000-08-12 15:11:46 +00:00
										 |  |  | #include <ctype.h>
 | 
					
						
							|  |  |  | #include <errno.h>
 | 
					
						
							|  |  |  | #include <limits.h>
 | 
					
						
							|  |  |  | #include <signal.h>
 | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  | #if defined(HAVE_STRING_H)
 | 
					
						
							|  |  |  | # include <string.h>
 | 
					
						
							|  |  |  | #elif defined(HAVE_STRINGS_H)
 | 
					
						
							|  |  |  | # include <strings.h>
 | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | #if defined(HAVE_UNISTD_H)
 | 
					
						
							|  |  |  | # include <unistd.h>
 | 
					
						
							|  |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2000-08-12 15:11:46 +00:00
										 |  |  | #include <math.h>
 | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  | #include <fcntl.h>
 | 
					
						
							|  |  |  | #include <time.h>
 | 
					
						
							|  |  |  | #if defined(HAVE_SYS_TIME_H)
 | 
					
						
							|  |  |  | # include <sys/time.h>
 | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | #if defined(HAVE_SYS_TYPES_H)
 | 
					
						
							|  |  |  | # include <sys/types.h>
 | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | #include <sys/wait.h>
 | 
					
						
							| 
									
										
										
										
											2000-08-12 15:11:46 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  | #define BACKEND_NAME	mustek_pp
 | 
					
						
							| 
									
										
										
										
											2000-08-12 15:11:46 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2000-11-19 16:17:38 +00:00
										 |  |  | #include "../include/sane/sane.h"
 | 
					
						
							|  |  |  | #include "../include/sane/sanei.h"
 | 
					
						
							|  |  |  | #include "../include/sane/saneopts.h"
 | 
					
						
							| 
									
										
										
										
											2000-08-12 15:11:46 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2000-11-19 16:17:38 +00:00
										 |  |  | #include "../include/sane/sanei_backend.h"
 | 
					
						
							| 
									
										
										
										
											2000-08-12 15:11:46 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2000-11-19 16:17:38 +00:00
										 |  |  | #include "../include/sane/sanei_config.h"
 | 
					
						
							| 
									
										
										
										
											2000-08-12 15:11:46 +00:00
										 |  |  | #define MUSTEK_PP_CONFIG_FILE "mustek_pp.conf"
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
											
												2003-11-23  Jochen Eisinger <jochen@penguin-breeder.org>
	* backend/mustek_pp.c, sanei/sanei_pa4s2.c: added support for auto
	  probing of the port
	* configure{.in}, backend/mustek_pp_ccd.*, backend/Makefile.in,
	  backend/dll.conf, doc/sane-mustek_pp_ccd.man, doc/sane.man,
	  doc/Makefile.in, doc/descriptions/mustek_pp_ccd.desc: mustek_pp_ccd
	  backend removed
	* backend/mustek_pp.conf, mustek_pp_ccd300.[ch],
	  doc/sane-mustek_pp.man, doc/descriptions/mustek_pp.desc: fixed CCD
	  support for mustek_pp backend
	* backend/mustek_pp_null.c: beautified debug scanner name
											
										 
											2003-11-24 08:58:19 +00:00
										 |  |  | #include "../include/sane/sanei_pa4s2.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-09-12 16:10:33 +00:00
										 |  |  | #include "mustek_pp.h"
 | 
					
						
							|  |  |  | #include "mustek_pp_drivers.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2000-08-12 15:11:46 +00:00
										 |  |  | #define MIN(a,b)	((a) < (b) ? (a) : (b))
 | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  |     | 
					
						
							|  |  |  | /* converts millimeter to pixels at a given resolution */ | 
					
						
							|  |  |  | #define	MM_TO_PIXEL(mm, dpi)	(((float )mm * 5.0 / 127.0) * (float)dpi)
 | 
					
						
							|  |  |  |    /* and back */ | 
					
						
							|  |  |  | #define PIXEL_TO_MM(pixel, dpi) (((float )pixel / (float )dpi) * 127.0 / 5.0)
 | 
					
						
							| 
									
										
										
										
											2000-08-12 15:11:46 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | /* if you change the source, please set MUSTEK_PP_STATE to "devel". Do *not*
 | 
					
						
							|  |  |  |  * change the MUSTEK_PP_BUILD. */ | 
					
						
							| 
									
										
										
											
												2003-11-23  Jochen Eisinger <jochen@penguin-breeder.org>
	* backend/mustek_pp.c, sanei/sanei_pa4s2.c: added support for auto
	  probing of the port
	* configure{.in}, backend/mustek_pp_ccd.*, backend/Makefile.in,
	  backend/dll.conf, doc/sane-mustek_pp_ccd.man, doc/sane.man,
	  doc/Makefile.in, doc/descriptions/mustek_pp_ccd.desc: mustek_pp_ccd
	  backend removed
	* backend/mustek_pp.conf, mustek_pp_ccd300.[ch],
	  doc/sane-mustek_pp.man, doc/descriptions/mustek_pp.desc: fixed CCD
	  support for mustek_pp backend
	* backend/mustek_pp_null.c: beautified debug scanner name
											
										 
											2003-11-24 08:58:19 +00:00
										 |  |  | #define MUSTEK_PP_BUILD	13
 | 
					
						
							|  |  |  | #define MUSTEK_PP_STATE	"beta"
 | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2000-08-12 15:11:46 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  | /* auth callback... since basic user authentication is done by saned, this
 | 
					
						
							|  |  |  |  * callback mechanism isn't used */ | 
					
						
							|  |  |  | SANE_Auth_Callback sane_auth; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* count of present devices */ | 
					
						
							| 
									
										
										
										
											2000-08-12 15:11:46 +00:00
										 |  |  | static int num_devices = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  | /* list of present devices */ | 
					
						
							|  |  |  | static Mustek_pp_Device *devlist = NULL; | 
					
						
							| 
									
										
										
										
											2000-08-12 15:11:46 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  | /* temporary array of configuration options used during device attachment */ | 
					
						
							|  |  |  | static Mustek_pp_config_option *cfgoptions = NULL; | 
					
						
							|  |  |  | static int numcfgoptions = 0; | 
					
						
							| 
									
										
										
										
											2000-08-12 15:11:46 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  | /* list of pointers to the SANE_Device structures of the Mustek_pp_Devices */ | 
					
						
							|  |  |  | static SANE_Device **devarray = NULL; | 
					
						
							| 
									
										
										
										
											2000-08-12 15:11:46 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  | /* currently active Handles */ | 
					
						
							|  |  |  | static Mustek_pp_Handle *first_hndl = NULL; | 
					
						
							| 
									
										
										
										
											2000-08-12 15:11:46 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-01-13 19:49:47 +00:00
										 |  |  | static SANE_String_Const       mustek_pp_modes[4] = {"Lineart", "Grayscale", "Color", NULL}; | 
					
						
							|  |  |  | static SANE_Word               mustek_pp_modes_size = 10; | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  |   | 
					
						
							| 
									
										
										
										
											2003-01-13 19:49:47 +00:00
										 |  |  | static SANE_String_Const       mustek_pp_speeds[6] = {"Slowest", "Slower", "Normal", "Faster", "Fastest", NULL}; | 
					
						
							|  |  |  | static SANE_Word               mustek_pp_speeds_size = 8; | 
					
						
							|  |  |  | static SANE_Word               mustek_pp_depths[5] = {4, 8, 10, 12, 16};    | 
					
						
							| 
									
										
										
										
											2000-08-12 15:11:46 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  | /* prototypes */ | 
					
						
							| 
									
										
										
										
											2003-01-13 19:49:47 +00:00
										 |  |  | static void free_cfg_options(int *numoptions, Mustek_pp_config_option** options); | 
					
						
							|  |  |  | static SANE_Status do_eof(Mustek_pp_Handle *hndl); | 
					
						
							|  |  |  | static SANE_Status do_stop(Mustek_pp_Handle *hndl); | 
					
						
							|  |  |  | static int reader_process (Mustek_pp_Handle * hndl, int pipe); | 
					
						
							|  |  |  | static SANE_Status sane_attach(SANE_String_Const port, SANE_String_Const name,  | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  | 			SANE_Int driver, SANE_Int info); | 
					
						
							| 
									
										
										
										
											2003-01-13 19:49:47 +00:00
										 |  |  | static void init_options(Mustek_pp_Handle *hndl); | 
					
						
							|  |  |  | static void attach_device(SANE_String *driver, SANE_String *name,  | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  | 		   SANE_String *port, SANE_String *option_ta); | 
					
						
							| 
									
										
										
										
											2000-08-12 15:11:46 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2000-11-18 16:42:27 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  | /*
 | 
					
						
							|  |  |  |  * Auxiliary function for freeing arrays of configuration options,  | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2003-01-13 19:49:47 +00:00
										 |  |  | static void  | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  | free_cfg_options(int *numoptions, Mustek_pp_config_option** options) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |    int i; | 
					
						
							|  |  |  |    if (*numoptions) | 
					
						
							|  |  |  |    { | 
					
						
							|  |  |  |       for (i=0; i<*numoptions; ++i) | 
					
						
							|  |  |  |       { | 
					
						
							|  |  |  |          free ((*options)[i].name); | 
					
						
							|  |  |  |          free ((*options)[i].value); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       free (*options); | 
					
						
							|  |  |  |    } | 
					
						
							|  |  |  |    *options = NULL; | 
					
						
							|  |  |  |    *numoptions = 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* do_eof:
 | 
					
						
							|  |  |  |  * 	closes the pipeline | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * ChangeLog: | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Description: | 
					
						
							|  |  |  |  * 	closes the pipe (read-only end) | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2003-01-13 19:49:47 +00:00
										 |  |  | static SANE_Status | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  | do_eof (Mustek_pp_Handle *hndl) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	if (hndl->pipe >= 0) { | 
					
						
							| 
									
										
										
										
											2000-08-12 15:11:46 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  | 		close (hndl->pipe); | 
					
						
							|  |  |  | 		hndl->pipe = -1; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2000-08-12 15:11:46 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  | 	return SANE_STATUS_EOF; | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2000-08-12 15:11:46 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  | /* do_stop:
 | 
					
						
							|  |  |  |  * 	ends the reader_process and stops the scanner | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * ChangeLog: | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Description: | 
					
						
							|  |  |  |  * 	kills the reader process with a SIGTERM and cancels the scanner | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2003-01-13 19:49:47 +00:00
										 |  |  | static SANE_Status | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  | do_stop(Mustek_pp_Handle *hndl) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2000-08-12 15:11:46 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  | 	int	exit_status; | 
					
						
							| 
									
										
										
										
											2000-08-12 15:11:46 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  | 	do_eof (hndl); | 
					
						
							| 
									
										
										
										
											2000-08-12 15:11:46 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  | 	if (hndl->reader > 0) { | 
					
						
							| 
									
										
										
										
											2000-08-12 15:11:46 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  | 		DBG (3, "do_stop: terminating reader process\n"); | 
					
						
							|  |  |  | 		kill (hndl->reader, SIGTERM); | 
					
						
							| 
									
										
										
										
											2000-08-12 15:11:46 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  | 		while (wait (&exit_status) != hndl->reader); | 
					
						
							| 
									
										
										
										
											2000-08-12 15:11:46 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  | 		DBG ((exit_status == SANE_STATUS_GOOD ? 3 : 1), | 
					
						
							| 
									
										
										
										
											2003-01-26 13:45:33 +00:00
										 |  |  | 			       "do_stop: reader_process terminated with status ``%s''\n", | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  | 			       sane_strstatus(exit_status)); | 
					
						
							|  |  |  | 		hndl->reader = 0; | 
					
						
							|  |  |  | 		hndl->dev->func->stop (hndl); | 
					
						
							| 
									
										
										
										
											2000-08-12 15:11:46 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  | 		return exit_status; | 
					
						
							| 
									
										
										
										
											2000-08-12 15:11:46 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2000-08-12 15:11:46 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  | 	hndl->dev->func->stop (hndl); | 
					
						
							| 
									
										
										
										
											2000-08-12 15:11:46 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  | 	return SANE_STATUS_GOOD; | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2000-11-18 16:42:27 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  | /* sigterm_handler:
 | 
					
						
							|  |  |  |  * 	cancel scanner when receiving a SIGTERM | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * ChangeLog: | 
					
						
							| 
									
										
										
										
											2000-11-18 16:42:27 +00:00
										 |  |  |  * | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  |  * Description: | 
					
						
							|  |  |  |  *	just exit... reader_process takes care that nothing bad will happen | 
					
						
							| 
									
										
										
										
											2004-01-15 19:58:03 +00:00
										 |  |  |  * | 
					
						
							|  |  |  |  * EDG - Jan 14, 2004: | 
					
						
							|  |  |  |  *      Make sure that the parport is released again by the child process | 
					
						
							|  |  |  |  *      under all circumstances, because otherwise the parent process may no  | 
					
						
							|  |  |  |  *      longer be able to claim it (they share the same file descriptor, and | 
					
						
							|  |  |  |  *      the kernel doesn't release the child's claim because the file | 
					
						
							|  |  |  |  *      descriptor isn't cleaned up). If that would happen, the lamp may stay | 
					
						
							|  |  |  |  *      on and may not return to its home position, unless the scanner | 
					
						
							|  |  |  |  *      frontend is restarted. | 
					
						
							|  |  |  |  *      (This happens only when sanei_pa4s2 uses libieee1284 AND | 
					
						
							|  |  |  |  *      libieee1284 goes via /dev/parportX). | 
					
						
							|  |  |  |  * | 
					
						
							| 
									
										
										
										
											2000-11-18 16:42:27 +00:00
										 |  |  |  */ | 
					
						
							| 
									
										
										
										
											2004-01-15 19:58:03 +00:00
										 |  |  | static int fd_to_release = 0; | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  | /*ARGSUSED*/ | 
					
						
							|  |  |  | static RETSIGTYPE | 
					
						
							|  |  |  | sigterm_handler (int signal __UNUSED__) | 
					
						
							| 
									
										
										
										
											2000-08-12 15:11:46 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2004-01-15 19:58:03 +00:00
										 |  |  | 	sanei_pa4s2_enable(fd_to_release, SANE_FALSE); | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  | 	_exit (SANE_STATUS_GOOD); | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2000-08-12 15:11:46 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  | /* reader_process:
 | 
					
						
							|  |  |  |  * 	receives data from the scanner and stuff it into the pipeline | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * ChangeLog: | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Description: | 
					
						
							|  |  |  |  * 	The signal handle for SIGTERM is initialized. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2003-01-13 19:49:47 +00:00
										 |  |  | static int | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  | reader_process (Mustek_pp_Handle * hndl, int pipe) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	sigset_t	sigterm_set; | 
					
						
							|  |  |  | 	struct SIGACTION act; | 
					
						
							|  |  |  | 	FILE *fp; | 
					
						
							|  |  |  | 	SANE_Status status; | 
					
						
							|  |  |  | 	int line; | 
					
						
							|  |  |  | 	int size, elem; | 
					
						
							| 
									
										
										
										
											2000-08-12 15:11:46 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  | 	SANE_Byte *buffer; | 
					
						
							| 
									
										
										
										
											2000-08-12 15:11:46 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  | 	sigemptyset (&sigterm_set); | 
					
						
							|  |  |  | 	sigaddset (&sigterm_set, SIGTERM); | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	if (!(buffer = malloc (hndl->params.bytes_per_line))) | 
					
						
							|  |  |  | 		return SANE_STATUS_NO_MEM; | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	if (!(fp = fdopen(pipe, "w"))) | 
					
						
							|  |  |  | 		return SANE_STATUS_IO_ERROR; | 
					
						
							| 
									
										
										
										
											2004-01-15 19:58:03 +00:00
										 |  |  |          | 
					
						
							|  |  |  | 	fd_to_release = hndl->fd; | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  | 	memset (&act, 0, sizeof(act)); | 
					
						
							|  |  |  | 	act.sa_handler = sigterm_handler; | 
					
						
							|  |  |  | 	sigaction (SIGTERM, &act, NULL); | 
					
						
							| 
									
										
										
										
											2000-08-12 15:11:46 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-01-15 19:58:03 +00:00
										 |  |  | 	if ((status = hndl->dev->func->start (hndl)) != SANE_STATUS_GOOD) | 
					
						
							|  |  |  | 		return status; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  |         size = hndl->params.bytes_per_line; | 
					
						
							|  |  |  |   	elem = 1; | 
					
						
							| 
									
										
										
										
											2000-08-12 15:11:46 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  | 	for (line=0; line<hndl->params.lines ; line++) { | 
					
						
							| 
									
										
										
										
											2000-08-12 15:11:46 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  | 		sigprocmask (SIG_BLOCK, &sigterm_set, NULL); | 
					
						
							| 
									
										
										
										
											2000-08-12 15:11:46 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  | 		hndl->dev->func->read (hndl, buffer); | 
					
						
							|  |  |  |                  | 
					
						
							|  |  |  |                 if (getppid() == 1) { | 
					
						
							|  |  |  |                     /* The parent process has died. Stop the scan (to make
 | 
					
						
							|  |  |  |                        sure that the lamp is off and returns home). This is | 
					
						
							|  |  |  |                        a safety measure to make sure that we don't break  | 
					
						
							|  |  |  |                        the scanner in case the frontend crashes. */ | 
					
						
							|  |  |  | 		    DBG (1, "reader_process: front-end died; aborting.\n"); | 
					
						
							|  |  |  |                     hndl->dev->func->stop (hndl); | 
					
						
							|  |  |  |                     return SANE_STATUS_CANCELLED; | 
					
						
							|  |  |  |                 } | 
					
						
							| 
									
										
										
										
											2000-08-12 15:11:46 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  | 		sigprocmask (SIG_UNBLOCK, &sigterm_set, NULL); | 
					
						
							| 
									
										
										
										
											2000-08-12 15:11:46 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  | 		fwrite (buffer, size, elem, fp); | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2000-08-12 15:11:46 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  | 	fclose (fp); | 
					
						
							| 
									
										
										
										
											2000-08-12 15:11:46 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  | 	free (buffer); | 
					
						
							| 
									
										
										
										
											2000-08-12 15:11:46 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  | 	return SANE_STATUS_GOOD; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 		 | 
					
						
							| 
									
										
										
										
											2000-11-18 16:42:27 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2000-08-12 15:11:46 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  | /* sane_attach:
 | 
					
						
							|  |  |  |  * 	adds a new entry to the Mustek_pp_Device *devlist list | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * ChangeLog: | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Description: | 
					
						
							|  |  |  |  * 	After memory for a new device entry is allocated, the | 
					
						
							|  |  |  |  * 	parameters for the device are determined by a call to | 
					
						
							|  |  |  |  * 	capabilities(). | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * 	Afterwards the new device entry is inserted into the | 
					
						
							|  |  |  |  * 	devlist | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2003-01-13 19:49:47 +00:00
										 |  |  | static SANE_Status | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  | sane_attach (SANE_String_Const port, SANE_String_Const name, SANE_Int driver, SANE_Int info) | 
					
						
							| 
									
										
										
										
											2000-08-12 15:11:46 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  | 	Mustek_pp_Device	*dev; | 
					
						
							| 
									
										
										
										
											2000-11-18 16:42:27 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-01-26 13:45:33 +00:00
										 |  |  | 	DBG (3, "sane_attach: attaching device ``%s'' to port %s (driver %s v%s by %s)\n",  | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  | 			name, port, Mustek_pp_Drivers[driver].driver, | 
					
						
							|  |  |  | 				Mustek_pp_Drivers[driver].version, | 
					
						
							|  |  |  | 				Mustek_pp_Drivers[driver].author); | 
					
						
							| 
									
										
										
										
											2000-11-18 16:42:27 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  | 	if ((dev = malloc (sizeof (Mustek_pp_Device))) == NULL) { | 
					
						
							| 
									
										
										
										
											2000-11-18 16:42:27 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  | 		DBG (1, "sane_attach: not enough free memory\n"); | 
					
						
							|  |  |  | 		return SANE_STATUS_NO_MEM; | 
					
						
							| 
									
										
										
										
											2000-08-12 15:11:46 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  | 	memset (dev, 0, sizeof (Mustek_pp_Device)); | 
					
						
							| 
									
										
										
										
											2000-08-12 15:11:46 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  | 	memset (&dev->sane, 0, sizeof (SANE_Device)); | 
					
						
							| 
									
										
										
										
											2000-08-12 15:11:46 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  | 	dev->func = &Mustek_pp_Drivers[driver]; | 
					
						
							| 
									
										
										
										
											2000-08-12 15:11:46 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  | 	dev->sane.name = dev->name = strdup (name); | 
					
						
							|  |  |  | 	dev->port = strdup (port); | 
					
						
							|  |  |  |         dev->info = info; /* Modified by EDG */ | 
					
						
							|  |  |  |          | 
					
						
							|  |  |  |         /* Transfer the options parsed from the configuration file */ | 
					
						
							|  |  |  |         dev->numcfgoptions = numcfgoptions; | 
					
						
							|  |  |  |         dev->cfgoptions = cfgoptions; | 
					
						
							|  |  |  |         numcfgoptions = 0; | 
					
						
							|  |  |  |         cfgoptions = NULL; | 
					
						
							| 
									
										
										
										
											2000-11-18 16:42:27 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  | 	dev->func->capabilities (info, &dev->model, &dev->vendor, &dev->type, | 
					
						
							|  |  |  | 			&dev->maxres, &dev->minres, &dev->maxhsize, &dev->maxvsize, | 
					
						
							|  |  |  | 			&dev->caps); | 
					
						
							| 
									
										
										
										
											2000-08-12 15:11:46 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  | 	dev->sane.model = dev->model; | 
					
						
							|  |  |  | 	dev->sane.vendor = dev->vendor; | 
					
						
							|  |  |  | 	dev->sane.type = dev->type; | 
					
						
							| 
									
										
										
										
											2000-08-12 15:11:46 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  | 	dev->next = devlist; | 
					
						
							|  |  |  | 	devlist = dev; | 
					
						
							| 
									
										
										
										
											2000-08-12 15:11:46 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  | 	num_devices++; | 
					
						
							| 
									
										
										
										
											2000-11-18 16:42:27 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  | 	return SANE_STATUS_GOOD; | 
					
						
							| 
									
										
										
										
											2000-08-12 15:11:46 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  | /* init_options:
 | 
					
						
							|  |  |  |  * 	Sets up the option descriptors for a device | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * ChangeLog: | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Description: | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2003-01-13 19:49:47 +00:00
										 |  |  | static void | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  | init_options(Mustek_pp_Handle *hndl) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   int i; | 
					
						
							| 
									
										
										
										
											2000-08-12 15:11:46 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  |   memset (hndl->opt, 0, sizeof (hndl->opt)); | 
					
						
							|  |  |  |   memset (hndl->val, 0, sizeof (hndl->val)); | 
					
						
							| 
									
										
										
										
											2000-08-12 15:11:46 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  |   for (i = 0; i < NUM_OPTIONS; ++i) | 
					
						
							| 
									
										
										
										
											2000-11-18 16:42:27 +00:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  |       hndl->opt[i].size = sizeof (SANE_Word); | 
					
						
							|  |  |  |       hndl->opt[i].cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT; | 
					
						
							| 
									
										
										
										
											2000-11-18 16:42:27 +00:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-04-02 21:58:44 +00:00
										 |  |  |   hndl->opt[OPT_NUM_OPTS].name = SANE_NAME_NUM_OPTIONS; | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  |   hndl->opt[OPT_NUM_OPTS].title = SANE_TITLE_NUM_OPTIONS; | 
					
						
							|  |  |  |   hndl->opt[OPT_NUM_OPTS].desc = SANE_DESC_NUM_OPTIONS; | 
					
						
							|  |  |  |   hndl->opt[OPT_NUM_OPTS].type = SANE_TYPE_INT; | 
					
						
							|  |  |  |   hndl->opt[OPT_NUM_OPTS].cap = SANE_CAP_SOFT_DETECT; | 
					
						
							|  |  |  |   hndl->val[OPT_NUM_OPTS].w = NUM_OPTIONS; | 
					
						
							| 
									
										
										
										
											2000-11-18 16:42:27 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  |   /* "Mode" group: */ | 
					
						
							| 
									
										
										
										
											2000-11-18 16:42:27 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  |   hndl->opt[OPT_MODE_GROUP].title = "Scan Mode"; | 
					
						
							|  |  |  |   hndl->opt[OPT_MODE_GROUP].desc = ""; | 
					
						
							|  |  |  |   hndl->opt[OPT_MODE_GROUP].type = SANE_TYPE_GROUP; | 
					
						
							|  |  |  |   hndl->opt[OPT_MODE_GROUP].cap = 0; | 
					
						
							|  |  |  |   hndl->opt[OPT_MODE_GROUP].constraint_type = SANE_CONSTRAINT_NONE; | 
					
						
							| 
									
										
										
										
											2003-04-02 21:58:44 +00:00
										 |  |  |   hndl->opt[OPT_MODE_GROUP].size = 0; | 
					
						
							| 
									
										
										
										
											2000-11-18 16:42:27 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  |   /* scan mode */ | 
					
						
							|  |  |  |   hndl->opt[OPT_MODE].name = SANE_NAME_SCAN_MODE; | 
					
						
							|  |  |  |   hndl->opt[OPT_MODE].title = SANE_TITLE_SCAN_MODE; | 
					
						
							|  |  |  |   hndl->opt[OPT_MODE].desc = SANE_DESC_SCAN_MODE; | 
					
						
							|  |  |  |   hndl->opt[OPT_MODE].type = SANE_TYPE_STRING; | 
					
						
							|  |  |  |   hndl->opt[OPT_MODE].constraint_type = SANE_CONSTRAINT_STRING_LIST; | 
					
						
							|  |  |  |   hndl->opt[OPT_MODE].size = mustek_pp_modes_size; | 
					
						
							|  |  |  |   hndl->opt[OPT_MODE].constraint.string_list = mustek_pp_modes; | 
					
						
							|  |  |  |   hndl->val[OPT_MODE].s = strdup (mustek_pp_modes[2]); | 
					
						
							| 
									
										
										
										
											2000-11-18 16:42:27 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  |   /* resolution */ | 
					
						
							|  |  |  |   hndl->opt[OPT_RESOLUTION].name = SANE_NAME_SCAN_RESOLUTION; | 
					
						
							|  |  |  |   hndl->opt[OPT_RESOLUTION].title = SANE_TITLE_SCAN_RESOLUTION; | 
					
						
							|  |  |  |   hndl->opt[OPT_RESOLUTION].desc = SANE_DESC_SCAN_RESOLUTION; | 
					
						
							|  |  |  |   hndl->opt[OPT_RESOLUTION].type = SANE_TYPE_FIXED; | 
					
						
							|  |  |  |   hndl->opt[OPT_RESOLUTION].unit = SANE_UNIT_DPI; | 
					
						
							|  |  |  |   hndl->opt[OPT_RESOLUTION].constraint_type = SANE_CONSTRAINT_RANGE; | 
					
						
							|  |  |  |   hndl->opt[OPT_RESOLUTION].constraint.range = &hndl->dpi_range; | 
					
						
							|  |  |  |   hndl->val[OPT_RESOLUTION].w = SANE_FIX (hndl->dev->minres); | 
					
						
							|  |  |  |   hndl->dpi_range.min = SANE_FIX (hndl->dev->minres); | 
					
						
							|  |  |  |   hndl->dpi_range.max = SANE_FIX (hndl->dev->maxres); | 
					
						
							|  |  |  |   hndl->dpi_range.quant = SANE_FIX (1); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /* speed */ | 
					
						
							|  |  |  |   hndl->opt[OPT_SPEED].name = SANE_NAME_SCAN_SPEED; | 
					
						
							|  |  |  |   hndl->opt[OPT_SPEED].title = SANE_TITLE_SCAN_SPEED; | 
					
						
							|  |  |  |   hndl->opt[OPT_SPEED].desc = SANE_DESC_SCAN_SPEED; | 
					
						
							|  |  |  |   hndl->opt[OPT_SPEED].type = SANE_TYPE_STRING; | 
					
						
							|  |  |  |   hndl->opt[OPT_SPEED].size = mustek_pp_speeds_size; | 
					
						
							|  |  |  |   hndl->opt[OPT_SPEED].constraint_type = SANE_CONSTRAINT_STRING_LIST; | 
					
						
							|  |  |  |   hndl->opt[OPT_SPEED].constraint.string_list = mustek_pp_speeds; | 
					
						
							|  |  |  |   hndl->val[OPT_SPEED].s = strdup (mustek_pp_speeds[2]); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (! (hndl->dev->caps & CAP_SPEED_SELECT)) | 
					
						
							|  |  |  | 	  hndl->opt[OPT_SPEED].cap |= SANE_CAP_INACTIVE; | 
					
						
							| 
									
										
										
										
											2000-11-18 16:42:27 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  |   /* preview */ | 
					
						
							|  |  |  |   hndl->opt[OPT_PREVIEW].name = SANE_NAME_PREVIEW; | 
					
						
							|  |  |  |   hndl->opt[OPT_PREVIEW].title = SANE_TITLE_PREVIEW; | 
					
						
							|  |  |  |   hndl->opt[OPT_PREVIEW].desc = SANE_DESC_PREVIEW; | 
					
						
							|  |  |  |   hndl->opt[OPT_PREVIEW].cap = SANE_CAP_SOFT_DETECT | SANE_CAP_SOFT_SELECT; | 
					
						
							|  |  |  |   hndl->val[OPT_PREVIEW].w = SANE_FALSE; | 
					
						
							| 
									
										
										
										
											2000-11-18 16:42:27 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  |   /* gray preview */ | 
					
						
							|  |  |  |   hndl->opt[OPT_GRAY_PREVIEW].name = SANE_NAME_GRAY_PREVIEW; | 
					
						
							|  |  |  |   hndl->opt[OPT_GRAY_PREVIEW].title = SANE_TITLE_GRAY_PREVIEW; | 
					
						
							|  |  |  |   hndl->opt[OPT_GRAY_PREVIEW].desc = SANE_DESC_GRAY_PREVIEW; | 
					
						
							|  |  |  |   hndl->opt[OPT_GRAY_PREVIEW].type = SANE_TYPE_BOOL; | 
					
						
							|  |  |  |   hndl->val[OPT_GRAY_PREVIEW].w = SANE_FALSE; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /* color dept */ | 
					
						
							|  |  |  |   hndl->opt[OPT_DEPTH].name = SANE_NAME_BIT_DEPTH; | 
					
						
							|  |  |  |   hndl->opt[OPT_DEPTH].title = SANE_TITLE_BIT_DEPTH; | 
					
						
							|  |  |  |   hndl->opt[OPT_DEPTH].desc =  | 
					
						
							|  |  |  | 	  "Number of bits per sample for color scans, typical values are 8 for truecolor (24bpp)" | 
					
						
							|  |  |  | 	  "up to 16 for far-to-many-color (48bpp)."; | 
					
						
							|  |  |  |   hndl->opt[OPT_DEPTH].type = SANE_TYPE_INT; | 
					
						
							|  |  |  |   hndl->opt[OPT_DEPTH].constraint_type = SANE_CONSTRAINT_WORD_LIST; | 
					
						
							|  |  |  |   hndl->opt[OPT_DEPTH].constraint.word_list = mustek_pp_depths; | 
					
						
							|  |  |  |   hndl->opt[OPT_DEPTH].unit = SANE_UNIT_BIT; | 
					
						
							|  |  |  |   hndl->opt[OPT_DEPTH].size = sizeof(SANE_Word); | 
					
						
							|  |  |  |   hndl->val[OPT_DEPTH].w = 8; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if ( !(hndl->dev->caps & CAP_DEPTH)) | 
					
						
							|  |  |  | 	  hndl->opt[OPT_DEPTH].cap |= SANE_CAP_INACTIVE; | 
					
						
							| 
									
										
										
										
											2000-11-18 16:42:27 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  |   /* "Geometry" group: */ | 
					
						
							| 
									
										
										
										
											2000-11-18 16:42:27 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  |   hndl->opt[OPT_GEOMETRY_GROUP].title = "Geometry"; | 
					
						
							|  |  |  |   hndl->opt[OPT_GEOMETRY_GROUP].desc = ""; | 
					
						
							|  |  |  |   hndl->opt[OPT_GEOMETRY_GROUP].type = SANE_TYPE_GROUP; | 
					
						
							|  |  |  |   hndl->opt[OPT_GEOMETRY_GROUP].cap = SANE_CAP_ADVANCED; | 
					
						
							|  |  |  |   hndl->opt[OPT_GEOMETRY_GROUP].constraint_type = SANE_CONSTRAINT_NONE; | 
					
						
							| 
									
										
										
										
											2003-04-02 21:58:44 +00:00
										 |  |  |   hndl->opt[OPT_GEOMETRY_GROUP].size = 0; | 
					
						
							| 
									
										
										
										
											2000-11-18 16:42:27 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  |   /* top-left x */ | 
					
						
							|  |  |  |   hndl->opt[OPT_TL_X].name = SANE_NAME_SCAN_TL_X; | 
					
						
							|  |  |  |   hndl->opt[OPT_TL_X].title = SANE_TITLE_SCAN_TL_X; | 
					
						
							|  |  |  |   hndl->opt[OPT_TL_X].desc = SANE_DESC_SCAN_TL_X; | 
					
						
							|  |  |  |   hndl->opt[OPT_TL_X].type = SANE_TYPE_FIXED; | 
					
						
							|  |  |  |   hndl->opt[OPT_TL_X].unit = SANE_UNIT_MM; | 
					
						
							|  |  |  |   hndl->opt[OPT_TL_X].constraint_type = SANE_CONSTRAINT_RANGE; | 
					
						
							|  |  |  |   hndl->opt[OPT_TL_X].constraint.range = &hndl->x_range; | 
					
						
							|  |  |  |   hndl->x_range.min = SANE_FIX (0); | 
					
						
							|  |  |  |   hndl->x_range.max = SANE_FIX (PIXEL_TO_MM(hndl->dev->maxhsize,hndl->dev->maxres)); | 
					
						
							|  |  |  |   hndl->x_range.quant = 0; | 
					
						
							|  |  |  |   hndl->val[OPT_TL_X].w = hndl->x_range.min; | 
					
						
							| 
									
										
										
										
											2000-08-12 15:11:46 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  |   /* top-left y */ | 
					
						
							|  |  |  |   hndl->opt[OPT_TL_Y].name = SANE_NAME_SCAN_TL_Y; | 
					
						
							|  |  |  |   hndl->opt[OPT_TL_Y].title = SANE_TITLE_SCAN_TL_Y; | 
					
						
							|  |  |  |   hndl->opt[OPT_TL_Y].desc = SANE_DESC_SCAN_TL_Y; | 
					
						
							|  |  |  |   hndl->opt[OPT_TL_Y].type = SANE_TYPE_FIXED; | 
					
						
							|  |  |  |   hndl->opt[OPT_TL_Y].unit = SANE_UNIT_MM; | 
					
						
							|  |  |  |   hndl->opt[OPT_TL_Y].constraint_type = SANE_CONSTRAINT_RANGE; | 
					
						
							|  |  |  |   hndl->opt[OPT_TL_Y].constraint.range = &hndl->y_range; | 
					
						
							|  |  |  |   hndl->y_range.min = SANE_FIX(0); | 
					
						
							|  |  |  |   hndl->y_range.max = SANE_FIX(PIXEL_TO_MM(hndl->dev->maxvsize,hndl->dev->maxres)); | 
					
						
							|  |  |  |   hndl->y_range.quant = 0; | 
					
						
							|  |  |  |   hndl->val[OPT_TL_Y].w = hndl->y_range.min; | 
					
						
							| 
									
										
										
										
											2000-08-12 15:11:46 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  |   /* bottom-right x */ | 
					
						
							|  |  |  |   hndl->opt[OPT_BR_X].name = SANE_NAME_SCAN_BR_X; | 
					
						
							|  |  |  |   hndl->opt[OPT_BR_X].title = SANE_TITLE_SCAN_BR_X; | 
					
						
							|  |  |  |   hndl->opt[OPT_BR_X].desc = SANE_DESC_SCAN_BR_X; | 
					
						
							|  |  |  |   hndl->opt[OPT_BR_X].type = SANE_TYPE_FIXED; | 
					
						
							|  |  |  |   hndl->opt[OPT_BR_X].unit = SANE_UNIT_MM; | 
					
						
							|  |  |  |   hndl->opt[OPT_BR_X].constraint_type = SANE_CONSTRAINT_RANGE; | 
					
						
							|  |  |  |   hndl->opt[OPT_BR_X].constraint.range = &hndl->x_range; | 
					
						
							|  |  |  |   hndl->val[OPT_BR_X].w = hndl->x_range.max; | 
					
						
							| 
									
										
										
										
											2000-08-12 15:11:46 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  |   /* bottom-right y */ | 
					
						
							|  |  |  |   hndl->opt[OPT_BR_Y].name = SANE_NAME_SCAN_BR_Y; | 
					
						
							|  |  |  |   hndl->opt[OPT_BR_Y].title = SANE_TITLE_SCAN_BR_Y; | 
					
						
							|  |  |  |   hndl->opt[OPT_BR_Y].desc = SANE_DESC_SCAN_BR_Y; | 
					
						
							|  |  |  |   hndl->opt[OPT_BR_Y].type = SANE_TYPE_FIXED; | 
					
						
							|  |  |  |   hndl->opt[OPT_BR_Y].unit = SANE_UNIT_MM; | 
					
						
							|  |  |  |   hndl->opt[OPT_BR_Y].constraint_type = SANE_CONSTRAINT_RANGE; | 
					
						
							|  |  |  |   hndl->opt[OPT_BR_Y].constraint.range = &hndl->y_range; | 
					
						
							|  |  |  |   hndl->val[OPT_BR_Y].w = hndl->y_range.max; | 
					
						
							| 
									
										
										
										
											2000-08-12 15:11:46 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  |   /* "Enhancement" group: */ | 
					
						
							| 
									
										
										
										
											2000-08-12 15:11:46 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  |   hndl->opt[OPT_ENHANCEMENT_GROUP].title = "Enhancement"; | 
					
						
							|  |  |  |   hndl->opt[OPT_ENHANCEMENT_GROUP].desc = ""; | 
					
						
							|  |  |  |   hndl->opt[OPT_ENHANCEMENT_GROUP].type = SANE_TYPE_GROUP; | 
					
						
							|  |  |  |   hndl->opt[OPT_ENHANCEMENT_GROUP].cap = 0; | 
					
						
							|  |  |  |   hndl->opt[OPT_ENHANCEMENT_GROUP].constraint_type = SANE_CONSTRAINT_NONE; | 
					
						
							| 
									
										
										
										
											2003-04-02 21:58:44 +00:00
										 |  |  |   hndl->opt[OPT_ENHANCEMENT_GROUP].size = 0; | 
					
						
							| 
									
										
										
										
											2000-08-12 15:11:46 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  |   /* custom-gamma table */ | 
					
						
							|  |  |  |   hndl->opt[OPT_CUSTOM_GAMMA].name = SANE_NAME_CUSTOM_GAMMA; | 
					
						
							|  |  |  |   hndl->opt[OPT_CUSTOM_GAMMA].title = SANE_TITLE_CUSTOM_GAMMA; | 
					
						
							|  |  |  |   hndl->opt[OPT_CUSTOM_GAMMA].desc = SANE_DESC_CUSTOM_GAMMA; | 
					
						
							|  |  |  |   hndl->opt[OPT_CUSTOM_GAMMA].type = SANE_TYPE_BOOL; | 
					
						
							|  |  |  |   hndl->val[OPT_CUSTOM_GAMMA].w = SANE_FALSE; | 
					
						
							| 
									
										
										
										
											2000-08-12 15:11:46 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  |   if ( !(hndl->dev->caps & CAP_GAMMA_CORRECT)) | 
					
						
							|  |  |  | 	  hndl->opt[OPT_CUSTOM_GAMMA].cap |= SANE_CAP_INACTIVE; | 
					
						
							| 
									
										
										
										
											2000-08-12 15:11:46 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  |   /* grayscale gamma vector */ | 
					
						
							|  |  |  |   hndl->opt[OPT_GAMMA_VECTOR].name = SANE_NAME_GAMMA_VECTOR; | 
					
						
							|  |  |  |   hndl->opt[OPT_GAMMA_VECTOR].title = SANE_TITLE_GAMMA_VECTOR; | 
					
						
							|  |  |  |   hndl->opt[OPT_GAMMA_VECTOR].desc = SANE_DESC_GAMMA_VECTOR; | 
					
						
							|  |  |  |   hndl->opt[OPT_GAMMA_VECTOR].type = SANE_TYPE_INT; | 
					
						
							|  |  |  |   hndl->opt[OPT_GAMMA_VECTOR].cap |= SANE_CAP_INACTIVE; | 
					
						
							|  |  |  |   hndl->opt[OPT_GAMMA_VECTOR].unit = SANE_UNIT_NONE; | 
					
						
							|  |  |  |   hndl->opt[OPT_GAMMA_VECTOR].size = 256 * sizeof (SANE_Word); | 
					
						
							|  |  |  |   hndl->opt[OPT_GAMMA_VECTOR].constraint_type = SANE_CONSTRAINT_RANGE; | 
					
						
							|  |  |  |   hndl->opt[OPT_GAMMA_VECTOR].constraint.range = &hndl->gamma_range; | 
					
						
							|  |  |  |   hndl->val[OPT_GAMMA_VECTOR].wa = &hndl->gamma_table[0][0]; | 
					
						
							| 
									
										
										
										
											2000-08-12 15:11:46 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  |   /* red gamma vector */ | 
					
						
							|  |  |  |   hndl->opt[OPT_GAMMA_VECTOR_R].name = SANE_NAME_GAMMA_VECTOR_R; | 
					
						
							|  |  |  |   hndl->opt[OPT_GAMMA_VECTOR_R].title = SANE_TITLE_GAMMA_VECTOR_R; | 
					
						
							|  |  |  |   hndl->opt[OPT_GAMMA_VECTOR_R].desc = SANE_DESC_GAMMA_VECTOR_R; | 
					
						
							|  |  |  |   hndl->opt[OPT_GAMMA_VECTOR_R].type = SANE_TYPE_INT; | 
					
						
							|  |  |  |   hndl->opt[OPT_GAMMA_VECTOR_R].cap |= SANE_CAP_INACTIVE; | 
					
						
							|  |  |  |   hndl->opt[OPT_GAMMA_VECTOR_R].unit = SANE_UNIT_NONE; | 
					
						
							|  |  |  |   hndl->opt[OPT_GAMMA_VECTOR_R].size = 256 * sizeof (SANE_Word); | 
					
						
							|  |  |  |   hndl->opt[OPT_GAMMA_VECTOR_R].constraint_type = SANE_CONSTRAINT_RANGE; | 
					
						
							|  |  |  |   hndl->opt[OPT_GAMMA_VECTOR_R].constraint.range = &hndl->gamma_range; | 
					
						
							|  |  |  |   hndl->val[OPT_GAMMA_VECTOR_R].wa = &hndl->gamma_table[1][0]; | 
					
						
							| 
									
										
										
										
											2000-08-12 15:11:46 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  |   /* green gamma vector */ | 
					
						
							|  |  |  |   hndl->opt[OPT_GAMMA_VECTOR_G].name = SANE_NAME_GAMMA_VECTOR_G; | 
					
						
							|  |  |  |   hndl->opt[OPT_GAMMA_VECTOR_G].title = SANE_TITLE_GAMMA_VECTOR_G; | 
					
						
							|  |  |  |   hndl->opt[OPT_GAMMA_VECTOR_G].desc = SANE_DESC_GAMMA_VECTOR_G; | 
					
						
							|  |  |  |   hndl->opt[OPT_GAMMA_VECTOR_G].type = SANE_TYPE_INT; | 
					
						
							|  |  |  |   hndl->opt[OPT_GAMMA_VECTOR_G].cap |= SANE_CAP_INACTIVE; | 
					
						
							|  |  |  |   hndl->opt[OPT_GAMMA_VECTOR_G].unit = SANE_UNIT_NONE; | 
					
						
							|  |  |  |   hndl->opt[OPT_GAMMA_VECTOR_G].size = 256 * sizeof (SANE_Word); | 
					
						
							|  |  |  |   hndl->opt[OPT_GAMMA_VECTOR_G].constraint_type = SANE_CONSTRAINT_RANGE; | 
					
						
							|  |  |  |   hndl->opt[OPT_GAMMA_VECTOR_G].constraint.range = &hndl->gamma_range; | 
					
						
							|  |  |  |   hndl->val[OPT_GAMMA_VECTOR_G].wa = &hndl->gamma_table[2][0]; | 
					
						
							| 
									
										
										
										
											2000-08-12 15:11:46 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  |   /* blue gamma vector */ | 
					
						
							|  |  |  |   hndl->opt[OPT_GAMMA_VECTOR_B].name = SANE_NAME_GAMMA_VECTOR_B; | 
					
						
							|  |  |  |   hndl->opt[OPT_GAMMA_VECTOR_B].title = SANE_TITLE_GAMMA_VECTOR_B; | 
					
						
							|  |  |  |   hndl->opt[OPT_GAMMA_VECTOR_B].desc = SANE_DESC_GAMMA_VECTOR_B; | 
					
						
							|  |  |  |   hndl->opt[OPT_GAMMA_VECTOR_B].type = SANE_TYPE_INT; | 
					
						
							|  |  |  |   hndl->opt[OPT_GAMMA_VECTOR_B].cap |= SANE_CAP_INACTIVE; | 
					
						
							|  |  |  |   hndl->opt[OPT_GAMMA_VECTOR_B].unit = SANE_UNIT_NONE; | 
					
						
							|  |  |  |   hndl->opt[OPT_GAMMA_VECTOR_B].size = 256 * sizeof (SANE_Word); | 
					
						
							|  |  |  |   hndl->opt[OPT_GAMMA_VECTOR_B].constraint_type = SANE_CONSTRAINT_RANGE; | 
					
						
							|  |  |  |   hndl->opt[OPT_GAMMA_VECTOR_B].constraint.range = &hndl->gamma_range; | 
					
						
							|  |  |  |   hndl->val[OPT_GAMMA_VECTOR_B].wa = &hndl->gamma_table[3][0]; | 
					
						
							| 
									
										
										
										
											2000-08-12 15:11:46 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  |   hndl->gamma_range.min = 0; | 
					
						
							|  |  |  |   hndl->gamma_range.max = 255; | 
					
						
							|  |  |  |   hndl->gamma_range.quant = 1; | 
					
						
							| 
									
										
										
										
											2000-08-12 15:11:46 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  |   hndl->opt[OPT_INVERT].name = SANE_NAME_NEGATIVE; | 
					
						
							|  |  |  |   hndl->opt[OPT_INVERT].title = SANE_TITLE_NEGATIVE; | 
					
						
							|  |  |  |   hndl->opt[OPT_INVERT].desc = SANE_DESC_NEGATIVE; | 
					
						
							|  |  |  |   hndl->opt[OPT_INVERT].type = SANE_TYPE_BOOL; | 
					
						
							|  |  |  |   hndl->val[OPT_INVERT].w = SANE_FALSE; | 
					
						
							| 
									
										
										
										
											2000-08-12 15:11:46 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  |   if (! (hndl->dev->caps & CAP_INVERT)) | 
					
						
							|  |  |  | 	  hndl->opt[OPT_INVERT].cap |= SANE_CAP_INACTIVE; | 
					
						
							| 
									
										
										
										
											2000-08-12 15:11:46 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  | /* attach_device:
 | 
					
						
							|  |  |  |  * 	Attempts to attach a device to the list after parsing of a section | 
					
						
							|  |  |  |  *      of the configuration file. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * ChangeLog: | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Description: | 
					
						
							|  |  |  |  *      After parsing a scanner section of the config file, this function | 
					
						
							|  |  |  |  *      is called to look for a driver with a matching name. When found, | 
					
						
							|  |  |  |  *      this driver is called to initialize the device. | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2003-01-13 19:49:47 +00:00
										 |  |  | static void | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  | attach_device(SANE_String *driver, SANE_String *name,  | 
					
						
							|  |  |  |               SANE_String *port, SANE_String *option_ta) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
											
												2003-11-23  Jochen Eisinger <jochen@penguin-breeder.org>
	* backend/mustek_pp.c, sanei/sanei_pa4s2.c: added support for auto
	  probing of the port
	* configure{.in}, backend/mustek_pp_ccd.*, backend/Makefile.in,
	  backend/dll.conf, doc/sane-mustek_pp_ccd.man, doc/sane.man,
	  doc/Makefile.in, doc/descriptions/mustek_pp_ccd.desc: mustek_pp_ccd
	  backend removed
	* backend/mustek_pp.conf, mustek_pp_ccd300.[ch],
	  doc/sane-mustek_pp.man, doc/descriptions/mustek_pp.desc: fixed CCD
	  support for mustek_pp backend
	* backend/mustek_pp_null.c: beautified debug scanner name
											
										 
											2003-11-24 08:58:19 +00:00
										 |  |  |   int found = 0, driver_no, port_no; | 
					
						
							| 
									
										
										
										
											2004-04-06 18:02:57 +00:00
										 |  |  |   const char **ports; | 
					
						
							| 
									
										
										
											
												2003-11-23  Jochen Eisinger <jochen@penguin-breeder.org>
	* backend/mustek_pp.c, sanei/sanei_pa4s2.c: added support for auto
	  probing of the port
	* configure{.in}, backend/mustek_pp_ccd.*, backend/Makefile.in,
	  backend/dll.conf, doc/sane-mustek_pp_ccd.man, doc/sane.man,
	  doc/Makefile.in, doc/descriptions/mustek_pp_ccd.desc: mustek_pp_ccd
	  backend removed
	* backend/mustek_pp.conf, mustek_pp_ccd300.[ch],
	  doc/sane-mustek_pp.man, doc/descriptions/mustek_pp.desc: fixed CCD
	  support for mustek_pp backend
	* backend/mustek_pp_null.c: beautified debug scanner name
											
										 
											2003-11-24 08:58:19 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |   if (!strcmp (*port, "*")) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |       ports = sanei_pa4s2_devices(); | 
					
						
							|  |  |  |       DBG (3, "sanei_init: auto probing port\n"); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   else | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |       ports = malloc (sizeof(char *) * 2); | 
					
						
							|  |  |  |       ports[0] = *port; | 
					
						
							|  |  |  |       ports[1] = NULL; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   for (port_no=0; ports[port_no] != NULL; port_no++) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |       for (driver_no=0 ; driver_no<MUSTEK_PP_NUM_DRIVERS ; driver_no++) | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |           if (strcasecmp (Mustek_pp_Drivers[driver_no].driver, *driver) == 0) | 
					
						
							|  |  |  |    	     { | 
					
						
							|  |  |  |    	       Mustek_pp_Drivers[driver_no].init ( | 
					
						
							|  |  |  |    	         (*option_ta == 0 ? CAP_NOTHING : CAP_TA), | 
					
						
							|  |  |  |    	         ports[port_no], *name, sane_attach); | 
					
						
							|  |  |  |    	       found = 1; | 
					
						
							|  |  |  |    	       break; | 
					
						
							|  |  |  |    	     } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   free (ports); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (found == 0) | 
					
						
							|  |  |  |     { | 
					
						
							| 
									
										
										
										
											2004-09-06 18:30:54 +00:00
										 |  |  |       DBG (1, "sane_init: no scanner detected\n"); | 
					
						
							|  |  |  |       DBG (3, "sane_init: either the driver name ``%s'' is invalid, or no scanner was detected\n", *driver); | 
					
						
							| 
									
										
										
											
												2003-11-23  Jochen Eisinger <jochen@penguin-breeder.org>
	* backend/mustek_pp.c, sanei/sanei_pa4s2.c: added support for auto
	  probing of the port
	* configure{.in}, backend/mustek_pp_ccd.*, backend/Makefile.in,
	  backend/dll.conf, doc/sane-mustek_pp_ccd.man, doc/sane.man,
	  doc/Makefile.in, doc/descriptions/mustek_pp_ccd.desc: mustek_pp_ccd
	  backend removed
	* backend/mustek_pp.conf, mustek_pp_ccd300.[ch],
	  doc/sane-mustek_pp.man, doc/descriptions/mustek_pp.desc: fixed CCD
	  support for mustek_pp backend
	* backend/mustek_pp_null.c: beautified debug scanner name
											
										 
											2003-11-24 08:58:19 +00:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   free (*name); | 
					
						
							|  |  |  |   free (*port); | 
					
						
							|  |  |  |   free (*driver); | 
					
						
							|  |  |  |   if (*option_ta) | 
					
						
							|  |  |  |     free (*option_ta); | 
					
						
							|  |  |  |   *name = *port = *driver = *option_ta = 0; | 
					
						
							|  |  |  |    | 
					
						
							|  |  |  |   /* In case of a successful initialization, the configuration options
 | 
					
						
							|  |  |  |      should have been transfered to the device, but this function can | 
					
						
							|  |  |  |      deal with that. */ | 
					
						
							|  |  |  |   free_cfg_options(&numcfgoptions, &cfgoptions); | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  | } | 
					
						
							|  |  |  |     | 
					
						
							|  |  |  | /* sane_init:
 | 
					
						
							|  |  |  |  *	Reads configuration file and registers hardware driver  | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * ChangeLog: | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Description: | 
					
						
							|  |  |  |  * 	in *version_code the SANE version this backend was compiled with and the | 
					
						
							|  |  |  |  * 	version of the backend is returned. The value of authorize is stored in | 
					
						
							|  |  |  |  * 	the global variable sane_auth. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * 	Next the configuration file is read. If it isn't present, all drivers | 
					
						
							|  |  |  |  * 	are auto-probed with default values (port 0x378, with and without TA). | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * 	The configuration file is expected to contain lines of the form | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * 	  scanner <name> <port> <driver> [<option_ta>] | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * 	where <name> is a arbitrary name to identify this entry | 
					
						
							|  |  |  |  *            <port> is the port where the scanner is attached to | 
					
						
							|  |  |  |  *            <driver> is the name of the driver to use | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  *      if the optional argument "option_ta" is present the driver uses special | 
					
						
							|  |  |  |  *      parameters fitting for a trasparency adapter. | 
					
						
							|  |  |  |  */ 	 | 
					
						
							| 
									
										
										
										
											2000-08-12 15:11:46 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  | SANE_Status | 
					
						
							|  |  |  | sane_init (SANE_Int * version_code, SANE_Auth_Callback authorize) | 
					
						
							| 
									
										
										
										
											2000-08-12 15:11:46 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  |   FILE *fp; | 
					
						
							|  |  |  |   char config_line[1024]; | 
					
						
							|  |  |  |   const char *config_line_ptr; | 
					
						
							|  |  |  |   int line=0, driver_no; | 
					
						
							|  |  |  |   char *driver = 0, *port = 0, *name = 0, *option_ta = 0; | 
					
						
							| 
									
										
										
										
											2000-08-12 15:11:46 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  |   DBG_INIT (); | 
					
						
							|  |  |  |   DBG (3, "sane-mustek_pp, version 0.%d-%s. build for SANE %s\n", | 
					
						
							|  |  |  | 	MUSTEK_PP_BUILD, MUSTEK_PP_STATE, VERSION); | 
					
						
							|  |  |  |   DBG (3, "backend by Jochen Eisinger <jochen.eisinger@gmx.net>\n"); | 
					
						
							| 
									
										
										
										
											2000-08-12 15:11:46 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  |   if (version_code != NULL) | 
					
						
							|  |  |  |     *version_code = SANE_VERSION_CODE (V_MAJOR, V_MINOR, MUSTEK_PP_BUILD); | 
					
						
							| 
									
										
										
										
											2000-08-12 15:11:46 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  |   sane_auth = authorize; | 
					
						
							| 
									
										
										
										
											2000-08-12 15:11:46 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  |   fp = sanei_config_open (MUSTEK_PP_CONFIG_FILE); | 
					
						
							| 
									
										
										
										
											2000-11-18 16:42:27 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  |   if (fp == NULL) | 
					
						
							| 
									
										
										
										
											2000-11-18 16:42:27 +00:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  |       char driver_name[64]; | 
					
						
							| 
									
										
										
										
											2004-04-06 18:02:57 +00:00
										 |  |  |       const char **devices = sanei_pa4s2_devices(); | 
					
						
							| 
									
										
										
											
												2003-11-23  Jochen Eisinger <jochen@penguin-breeder.org>
	* backend/mustek_pp.c, sanei/sanei_pa4s2.c: added support for auto
	  probing of the port
	* configure{.in}, backend/mustek_pp_ccd.*, backend/Makefile.in,
	  backend/dll.conf, doc/sane-mustek_pp_ccd.man, doc/sane.man,
	  doc/Makefile.in, doc/descriptions/mustek_pp_ccd.desc: mustek_pp_ccd
	  backend removed
	* backend/mustek_pp.conf, mustek_pp_ccd300.[ch],
	  doc/sane-mustek_pp.man, doc/descriptions/mustek_pp.desc: fixed CCD
	  support for mustek_pp backend
	* backend/mustek_pp_null.c: beautified debug scanner name
											
										 
											2003-11-24 08:58:19 +00:00
										 |  |  |       int device_no; | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  | 	 | 
					
						
							|  |  |  |       DBG (2, "sane_init: could not open configuration file\n"); | 
					
						
							|  |  |  |        | 
					
						
							| 
									
										
										
											
												2003-11-23  Jochen Eisinger <jochen@penguin-breeder.org>
	* backend/mustek_pp.c, sanei/sanei_pa4s2.c: added support for auto
	  probing of the port
	* configure{.in}, backend/mustek_pp_ccd.*, backend/Makefile.in,
	  backend/dll.conf, doc/sane-mustek_pp_ccd.man, doc/sane.man,
	  doc/Makefile.in, doc/descriptions/mustek_pp_ccd.desc: mustek_pp_ccd
	  backend removed
	* backend/mustek_pp.conf, mustek_pp_ccd300.[ch],
	  doc/sane-mustek_pp.man, doc/descriptions/mustek_pp.desc: fixed CCD
	  support for mustek_pp backend
	* backend/mustek_pp_null.c: beautified debug scanner name
											
										 
											2003-11-24 08:58:19 +00:00
										 |  |  |       for (device_no = 0; devices[device_no] != NULL; device_no++) | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  | 	  DBG (3, "sane_init: trying ``%s''\n", devices[device_no]); | 
					
						
							|  |  |  |           for (driver_no=0 ; driver_no<MUSTEK_PP_NUM_DRIVERS ; driver_no++) | 
					
						
							|  |  |  | 	    { | 
					
						
							|  |  |  | 	      Mustek_pp_Drivers[driver_no].init(CAP_NOTHING, devices[device_no], | 
					
						
							|  |  |  | 	  	        Mustek_pp_Drivers[driver_no].driver, sane_attach); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	      snprintf (driver_name, 64, "%s-ta", | 
					
						
							|  |  |  | 		    Mustek_pp_Drivers[driver_no].driver); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	      Mustek_pp_Drivers[driver_no].init(CAP_TA, devices[device_no], | 
					
						
							|  |  |  | 		        driver_name, sane_attach); | 
					
						
							|  |  |  | 	    } | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2000-08-12 15:11:46 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
											
												2003-11-23  Jochen Eisinger <jochen@penguin-breeder.org>
	* backend/mustek_pp.c, sanei/sanei_pa4s2.c: added support for auto
	  probing of the port
	* configure{.in}, backend/mustek_pp_ccd.*, backend/Makefile.in,
	  backend/dll.conf, doc/sane-mustek_pp_ccd.man, doc/sane.man,
	  doc/Makefile.in, doc/descriptions/mustek_pp_ccd.desc: mustek_pp_ccd
	  backend removed
	* backend/mustek_pp.conf, mustek_pp_ccd300.[ch],
	  doc/sane-mustek_pp.man, doc/descriptions/mustek_pp.desc: fixed CCD
	  support for mustek_pp backend
	* backend/mustek_pp_null.c: beautified debug scanner name
											
										 
											2003-11-24 08:58:19 +00:00
										 |  |  |       free (devices); | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  |       return SANE_STATUS_GOOD; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2000-08-12 15:11:46 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  |   while (sanei_config_read (config_line, 1023, fp)) | 
					
						
							| 
									
										
										
										
											2000-11-18 16:42:27 +00:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  |       line++; | 
					
						
							|  |  |  |       if ((!*config_line) || (*config_line == '#')) | 
					
						
							|  |  |  | 	continue; | 
					
						
							| 
									
										
										
										
											2000-08-12 15:11:46 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  |       config_line_ptr = config_line; | 
					
						
							| 
									
										
										
										
											2000-08-12 15:11:46 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  |       if (strncmp(config_line_ptr, "scanner", 7) == 0) | 
					
						
							| 
									
										
										
										
											2000-11-18 16:42:27 +00:00
										 |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  | 	  config_line_ptr += 7; | 
					
						
							|  |  |  |            | 
					
						
							|  |  |  |           if (name) | 
					
						
							|  |  |  |           { | 
					
						
							|  |  |  |              /* Parsing of previous scanner + options is finished. Attach
 | 
					
						
							|  |  |  |                 the device before we parse the next section. */ | 
					
						
							|  |  |  |              attach_device(&driver, &name, &port, &option_ta); | 
					
						
							|  |  |  |           } | 
					
						
							|  |  |  |            | 
					
						
							|  |  |  | 	  config_line_ptr = sanei_config_skip_whitespace (config_line_ptr); | 
					
						
							|  |  |  | 	  if (!*config_line_ptr) | 
					
						
							|  |  |  | 	    { | 
					
						
							| 
									
										
										
										
											2003-01-26 13:45:33 +00:00
										 |  |  | 	      DBG (1, "sane_init: parse error in line %d after ``scanner''\n", | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  | 		line); | 
					
						
							|  |  |  | 	      continue; | 
					
						
							|  |  |  | 	    } | 
					
						
							| 
									
										
										
										
											2000-08-12 15:11:46 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  | 	  config_line_ptr = sanei_config_get_string (config_line_ptr, &name); | 
					
						
							|  |  |  | 	  if ((name == NULL) || (!*name)) | 
					
						
							|  |  |  | 	    { | 
					
						
							| 
									
										
										
										
											2003-01-26 13:45:33 +00:00
										 |  |  | 	      DBG (1, "sane_init: parse error in line %d after ``scanner''\n", | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  | 		line); | 
					
						
							|  |  |  | 	      if (name != NULL) | 
					
						
							|  |  |  | 		free (name); | 
					
						
							|  |  |  | 	      name = 0; | 
					
						
							|  |  |  | 	      continue; | 
					
						
							|  |  |  | 	    } | 
					
						
							| 
									
										
										
										
											2000-08-12 15:11:46 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  | 	  config_line_ptr = sanei_config_skip_whitespace (config_line_ptr); | 
					
						
							|  |  |  | 	  if (!*config_line_ptr) | 
					
						
							|  |  |  | 	    { | 
					
						
							|  |  |  | 	      DBG (1, "sane_init: parse error in line %d after " | 
					
						
							| 
									
										
										
										
											2003-01-26 13:45:33 +00:00
										 |  |  | 		"``scanner %s''\n", line, name); | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  | 	      free (name); | 
					
						
							|  |  |  | 	      name = 0; | 
					
						
							|  |  |  | 	      continue; | 
					
						
							|  |  |  | 	    } | 
					
						
							| 
									
										
										
										
											2000-08-12 15:11:46 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  | 	  config_line_ptr = sanei_config_get_string (config_line_ptr, &port); | 
					
						
							|  |  |  | 	  if ((port == NULL) || (!*port)) | 
					
						
							|  |  |  | 	    { | 
					
						
							|  |  |  | 	      DBG (1, "sane_init: parse error in line %d after " | 
					
						
							| 
									
										
										
										
											2003-01-26 13:45:33 +00:00
										 |  |  | 		"``scanner %s''\n", line, name); | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  | 	      free (name); | 
					
						
							|  |  |  | 	      name = 0; | 
					
						
							|  |  |  | 	      if (port != NULL) | 
					
						
							|  |  |  | 		free (port); | 
					
						
							|  |  |  | 	      port = 0; | 
					
						
							|  |  |  | 	      continue; | 
					
						
							|  |  |  | 	    } | 
					
						
							| 
									
										
										
										
											2000-08-12 15:11:46 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  | 	  config_line_ptr = sanei_config_skip_whitespace (config_line_ptr); | 
					
						
							|  |  |  | 	  if (!*config_line_ptr) | 
					
						
							|  |  |  | 	    { | 
					
						
							|  |  |  | 	      DBG (1, "sane_init: parse error in line %d after " | 
					
						
							| 
									
										
										
										
											2003-01-26 13:45:33 +00:00
										 |  |  | 		"``scanner %s %s''\n", line, name, port); | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  | 	      free (name); | 
					
						
							|  |  |  | 	      free (port); | 
					
						
							|  |  |  | 	      name = 0; | 
					
						
							|  |  |  | 	      port = 0; | 
					
						
							|  |  |  | 	      continue; | 
					
						
							|  |  |  | 	    } | 
					
						
							| 
									
										
										
										
											2000-08-12 15:11:46 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  | 	  config_line_ptr = sanei_config_get_string (config_line_ptr, &driver); | 
					
						
							|  |  |  | 	  if ((driver == NULL) || (!*driver)) | 
					
						
							|  |  |  | 	    { | 
					
						
							|  |  |  | 	      DBG (1, "sane_init: parse error in line %d after " | 
					
						
							| 
									
										
										
										
											2003-01-26 13:45:33 +00:00
										 |  |  | 		"``scanner %s %s''\n", line, name, port); | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  | 	      free (name); | 
					
						
							|  |  |  | 	      name = 0; | 
					
						
							|  |  |  | 	      free (port); | 
					
						
							|  |  |  | 	      port = 0; | 
					
						
							|  |  |  | 	      if (driver != NULL) | 
					
						
							|  |  |  | 		free (driver); | 
					
						
							|  |  |  | 	      driver = 0; | 
					
						
							|  |  |  | 	      continue; | 
					
						
							|  |  |  | 	    } | 
					
						
							| 
									
										
										
										
											2000-08-12 15:11:46 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  | 	  config_line_ptr = sanei_config_skip_whitespace (config_line_ptr); | 
					
						
							| 
									
										
										
										
											2000-08-12 15:11:46 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  | 	  if (*config_line_ptr) | 
					
						
							| 
									
										
										
										
											2000-11-18 16:42:27 +00:00
										 |  |  | 	    { | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  | 	      config_line_ptr = sanei_config_get_string (config_line_ptr, | 
					
						
							|  |  |  | 							&option_ta); | 
					
						
							| 
									
										
										
										
											2000-08-12 15:11:46 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  | 	      if ((option_ta == NULL) || (!*option_ta) ||  | 
					
						
							|  |  |  | 		  (strcasecmp (option_ta, "use_ta") != 0)) | 
					
						
							| 
									
										
										
										
											2000-11-18 16:42:27 +00:00
										 |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  | 		  DBG (1, "sane_init: parse error in line %d after " | 
					
						
							| 
									
										
										
										
											2003-01-26 13:45:33 +00:00
										 |  |  | 			"``scanner %s %s %s''\n", line, name, port, driver); | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  | 		  free (name); | 
					
						
							|  |  |  | 		  free (port); | 
					
						
							|  |  |  | 		  free (driver); | 
					
						
							|  |  |  | 		  if (option_ta) | 
					
						
							|  |  |  | 		    free (option_ta); | 
					
						
							|  |  |  | 		  name = port = driver = option_ta = 0; | 
					
						
							| 
									
										
										
										
											2000-11-18 16:42:27 +00:00
										 |  |  | 		  continue; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	    } | 
					
						
							| 
									
										
										
										
											2000-08-12 15:11:46 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  | 	  if (*config_line_ptr) | 
					
						
							|  |  |  | 	    { | 
					
						
							|  |  |  | 	      DBG (1, "sane_init: parse error in line %d after " | 
					
						
							|  |  |  | 			"``scanner %s %s %s %s\n", line, name, port, driver, | 
					
						
							|  |  |  | 			(option_ta == 0 ? "" : option_ta)); | 
					
						
							|  |  |  | 	      free (name); | 
					
						
							|  |  |  | 	      free (port); | 
					
						
							|  |  |  | 	      free (driver); | 
					
						
							|  |  |  | 	      if (option_ta) | 
					
						
							|  |  |  | 		free (option_ta); | 
					
						
							|  |  |  | 	      name = port = driver = option_ta = 0; | 
					
						
							|  |  |  | 	      continue; | 
					
						
							|  |  |  | 	    } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |       else if (strncmp(config_line_ptr, "option", 6) == 0) | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |           /* Format for options: option <name> [<value>] 
 | 
					
						
							|  |  |  |              Note that the value is optional. */    | 
					
						
							|  |  |  |           char *optname, *optval = 0; | 
					
						
							|  |  |  |           Mustek_pp_config_option *tmpoptions; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |           config_line_ptr += 6;          | 
					
						
							|  |  |  |           config_line_ptr = sanei_config_skip_whitespace (config_line_ptr); | 
					
						
							|  |  |  |           if (!*config_line_ptr) | 
					
						
							|  |  |  | 	    { | 
					
						
							| 
									
										
										
										
											2003-01-26 13:45:33 +00:00
										 |  |  | 	      DBG (1, "sane_init: parse error in line %d after ``option''\n", | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  | 	        line); | 
					
						
							|  |  |  | 	      continue; | 
					
						
							|  |  |  | 	    } | 
					
						
							| 
									
										
										
										
											2000-08-12 15:11:46 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  |           config_line_ptr = sanei_config_get_string (config_line_ptr, &optname); | 
					
						
							|  |  |  |           if ((optname == NULL) || (!*optname)) | 
					
						
							|  |  |  | 	    { | 
					
						
							| 
									
										
										
										
											2003-01-26 13:45:33 +00:00
										 |  |  | 	      DBG (1, "sane_init: parse error in line %d after ``option''\n", | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  | 	        line); | 
					
						
							|  |  |  | 	      if (optname != NULL) | 
					
						
							|  |  |  | 	        free (optname); | 
					
						
							|  |  |  | 	      continue; | 
					
						
							|  |  |  | 	    } | 
					
						
							| 
									
										
										
										
											2000-08-12 15:11:46 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  |           config_line_ptr = sanei_config_skip_whitespace (config_line_ptr); | 
					
						
							|  |  |  |           if (*config_line_ptr) | 
					
						
							|  |  |  | 	    { | 
					
						
							|  |  |  |               /* The option has a value.
 | 
					
						
							|  |  |  |                  No need to check the value; that's up to the backend */ | 
					
						
							|  |  |  | 	      config_line_ptr = sanei_config_get_string (config_line_ptr,  | 
					
						
							|  |  |  |                                                          &optval); | 
					
						
							| 
									
										
										
										
											2000-08-12 15:11:46 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  |    	      config_line_ptr = sanei_config_skip_whitespace (config_line_ptr); | 
					
						
							|  |  |  | 	    } | 
					
						
							| 
									
										
										
										
											2000-08-12 15:11:46 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  |           if (*config_line_ptr) | 
					
						
							|  |  |  | 	    { | 
					
						
							|  |  |  | 	      DBG (1, "sane_init: parse error in line %d after " | 
					
						
							| 
									
										
										
										
											2003-01-26 13:45:33 +00:00
										 |  |  | 		        "``option %s %s''\n", line, optname,  | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  | 		        (optval == 0 ? "" : optval)); | 
					
						
							|  |  |  | 	      free (optname); | 
					
						
							|  |  |  | 	      if (optval)  | 
					
						
							|  |  |  |                  free (optval); | 
					
						
							|  |  |  | 	      continue; | 
					
						
							|  |  |  | 	    } | 
					
						
							| 
									
										
										
										
											2000-08-12 15:11:46 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-04-10 11:53:16 +00:00
										 |  |  | 	  if (!strcmp (optname, "no_epp")) | 
					
						
							|  |  |  | 	    { | 
					
						
							|  |  |  | 	      u_int pa4s2_options; | 
					
						
							|  |  |  | 	      if (name) | 
					
						
							|  |  |  | 		DBG (2, "sane_init: global option found in local scope, " | 
					
						
							|  |  |  | 			"executing anyway\n"); | 
					
						
							|  |  |  | 	      free (optname); | 
					
						
							|  |  |  | 	      if (optval) | 
					
						
							|  |  |  | 	        { | 
					
						
							|  |  |  | 	          DBG (1, "sane_init: unexpected value for option no_epp\n"); | 
					
						
							|  |  |  | 	          free (optval); | 
					
						
							|  |  |  | 	          continue; | 
					
						
							|  |  |  | 	        } | 
					
						
							|  |  |  | 	      DBG (3, "sane_init: disabling mode EPP\n"); | 
					
						
							|  |  |  | 	      sanei_pa4s2_options (&pa4s2_options, SANE_FALSE); | 
					
						
							|  |  |  | 	      pa4s2_options |= SANEI_PA4S2_OPT_NO_EPP; | 
					
						
							|  |  |  | 	      sanei_pa4s2_options (&pa4s2_options, SANE_TRUE); | 
					
						
							|  |  |  | 	      continue; | 
					
						
							|  |  |  | 	    } | 
					
						
							|  |  |  | 	  else if (!name) | 
					
						
							|  |  |  | 	    { | 
					
						
							|  |  |  | 	      DBG (1, "sane_init: parse error in line %d: unexpected " | 
					
						
							|  |  |  |                       " ``option''\n", line); | 
					
						
							|  |  |  | 	      free (optname); | 
					
						
							|  |  |  | 	      if (optval)  | 
					
						
							|  |  |  |                  free (optval); | 
					
						
							|  |  |  | 	      continue; | 
					
						
							|  |  |  | 	    } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  |           /* Extend the (global) array of options */ | 
					
						
							|  |  |  |           tmpoptions = realloc(cfgoptions,  | 
					
						
							|  |  |  |                                (numcfgoptions+1)*sizeof(cfgoptions[0])); | 
					
						
							|  |  |  |           if (!tmpoptions) | 
					
						
							|  |  |  |           { | 
					
						
							|  |  |  |              DBG (1, "sane_init: not enough memory for device options\n"); | 
					
						
							|  |  |  |              free_cfg_options(&numcfgoptions, &cfgoptions); | 
					
						
							|  |  |  |              return SANE_STATUS_NO_MEM; | 
					
						
							|  |  |  |           } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |           cfgoptions = tmpoptions; | 
					
						
							|  |  |  |           cfgoptions[numcfgoptions].name = optname; | 
					
						
							|  |  |  |           cfgoptions[numcfgoptions].value = optval; | 
					
						
							|  |  |  |           ++numcfgoptions; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |       else | 
					
						
							| 
									
										
										
										
											2000-08-12 15:11:46 +00:00
										 |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  | 	  DBG (1, "sane_init: parse error at beginning of line %d\n", line); | 
					
						
							|  |  |  | 	  continue; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2000-08-12 15:11:46 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  |     } | 
					
						
							|  |  |  |      | 
					
						
							|  |  |  |   /* If we hit the end of the file, we still may have to process the
 | 
					
						
							|  |  |  |      last driver */ | 
					
						
							|  |  |  |   if (name) | 
					
						
							|  |  |  |      attach_device(&driver, &name, &port, &option_ta); | 
					
						
							| 
									
										
										
										
											2000-08-12 15:11:46 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  |   fclose(fp); | 
					
						
							|  |  |  |   return SANE_STATUS_GOOD; | 
					
						
							| 
									
										
										
										
											2000-08-12 15:11:46 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  | }	 | 
					
						
							| 
									
										
										
										
											2000-08-12 15:11:46 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  | /* sane_exit:
 | 
					
						
							|  |  |  |  *	Unloads all drivers and frees allocated memory | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * ChangeLog: | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Description: | 
					
						
							|  |  |  |  * 	All open devices are closed first. Then all registered devices | 
					
						
							|  |  |  |  * 	are removed. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2000-08-12 15:11:46 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  | void | 
					
						
							|  |  |  | sane_exit (void) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   Mustek_pp_Handle *hndl; | 
					
						
							|  |  |  |   Mustek_pp_Device *dev; | 
					
						
							| 
									
										
										
										
											2000-08-12 15:11:46 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  |   if (first_hndl) | 
					
						
							|  |  |  |     DBG (3, "sane_exit: closing open devices\n"); | 
					
						
							| 
									
										
										
										
											2000-08-12 15:11:46 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  |   while (first_hndl) | 
					
						
							| 
									
										
										
										
											2000-08-12 15:11:46 +00:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  |       hndl = first_hndl; | 
					
						
							|  |  |  |       sane_close (hndl); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2000-08-12 15:11:46 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  |   dev = devlist; | 
					
						
							|  |  |  |   num_devices = 0; | 
					
						
							|  |  |  |   devlist = NULL; | 
					
						
							| 
									
										
										
										
											2000-08-12 15:11:46 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  |   while (dev) { | 
					
						
							| 
									
										
										
										
											2000-08-12 15:11:46 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  | 	  free (dev->port); | 
					
						
							|  |  |  | 	  free (dev->name); | 
					
						
							|  |  |  | 	  free (dev->vendor); | 
					
						
							|  |  |  | 	  free (dev->model); | 
					
						
							|  |  |  | 	  free (dev->type); | 
					
						
							|  |  |  |           free_cfg_options (&dev->numcfgoptions, &dev->cfgoptions); | 
					
						
							|  |  |  | 	  dev = dev->next; | 
					
						
							| 
									
										
										
										
											2000-08-12 15:11:46 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2000-08-12 15:11:46 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  |   if (devarray != NULL) | 
					
						
							|  |  |  |     free (devarray); | 
					
						
							| 
									
										
										
										
											2003-04-02 21:58:44 +00:00
										 |  |  |   devarray = NULL; | 
					
						
							| 
									
										
										
										
											2000-08-12 15:11:46 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  |   DBG (3, "sane_exit: all drivers unloaded\n"); | 
					
						
							| 
									
										
										
										
											2000-11-18 16:42:27 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2000-08-12 15:11:46 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  | /* sane_get_devices:
 | 
					
						
							|  |  |  |  * 	Returns a list of registered devices | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * ChangeLog: | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Description: | 
					
						
							|  |  |  |  * 	A possible present old device_list is removed first. A new | 
					
						
							|  |  |  |  * 	devarray is allocated and filled with pointers to the | 
					
						
							|  |  |  |  * 	SANE_Device structures of the Mustek_pp_Devices | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | /*ARGSUSED*/ | 
					
						
							|  |  |  | SANE_Status | 
					
						
							|  |  |  | sane_get_devices (const SANE_Device *** device_list,  | 
					
						
							|  |  |  | 		  SANE_Bool local_only __UNUSED__) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   int ctr; | 
					
						
							|  |  |  |   Mustek_pp_Device *dev; | 
					
						
							| 
									
										
										
										
											2000-08-12 15:11:46 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  |   if (devarray != NULL) | 
					
						
							|  |  |  |     free (devarray); | 
					
						
							| 
									
										
										
										
											2000-08-12 15:11:46 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  |   devarray = malloc ((num_devices + 1) * sizeof (devarray[0])); | 
					
						
							| 
									
										
										
										
											2000-08-12 15:11:46 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  |   if (devarray == NULL) | 
					
						
							| 
									
										
										
										
											2000-08-12 15:11:46 +00:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  |       DBG (1, "sane_get_devices: not enough memory for device list\n"); | 
					
						
							| 
									
										
										
										
											2000-08-12 15:11:46 +00:00
										 |  |  |       return SANE_STATUS_NO_MEM; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  |   dev = devlist; | 
					
						
							|  |  |  |    | 
					
						
							|  |  |  |   for (ctr=0 ; ctr<num_devices ; ctr++) { | 
					
						
							|  |  |  | 	  devarray[ctr] = &dev->sane; | 
					
						
							|  |  |  | 	  dev = dev->next; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2000-08-12 15:11:46 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  |   devarray[num_devices] = NULL; | 
					
						
							|  |  |  |   *device_list = (const SANE_Device **)devarray; | 
					
						
							| 
									
										
										
										
											2000-11-18 16:42:27 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  |   return SANE_STATUS_GOOD; | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2000-08-12 15:11:46 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  | /* sane_open:
 | 
					
						
							|  |  |  |  * 	opens a device and prepares it for operation | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * ChangeLog: | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Description: | 
					
						
							| 
									
										
										
										
											2003-01-26 13:45:33 +00:00
										 |  |  |  * 	The device identified by ``devicename'' is looked | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  |  * 	up in the list, or if devicename is zero, the | 
					
						
							|  |  |  |  * 	first device from the list is taken. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * 	open is called for the selected device. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * 	The handel is set up with default values, and the | 
					
						
							|  |  |  |  * 	option descriptors are initialized | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2000-08-12 15:11:46 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  | SANE_Status | 
					
						
							|  |  |  | sane_open (SANE_String_Const devicename, SANE_Handle * handle) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2000-08-12 15:11:46 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  | 	Mustek_pp_Handle *hndl; | 
					
						
							|  |  |  | 	Mustek_pp_Device *dev; | 
					
						
							|  |  |  | 	SANE_Status status; | 
					
						
							|  |  |  | 	int	fd, i; | 
					
						
							| 
									
										
										
										
											2000-08-12 15:11:46 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  | 	if (devicename[0]) { | 
					
						
							| 
									
										
										
										
											2000-08-12 15:11:46 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  | 		dev = devlist; | 
					
						
							| 
									
										
										
										
											2000-08-12 15:11:46 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  | 		while (dev) { | 
					
						
							| 
									
										
										
										
											2000-08-12 15:11:46 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  | 			if (strcmp (dev->name, devicename) == 0) | 
					
						
							|  |  |  | 				break; | 
					
						
							| 
									
										
										
										
											2000-08-12 15:11:46 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  | 			dev = dev->next; | 
					
						
							| 
									
										
										
										
											2000-08-12 15:11:46 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2000-08-12 15:11:46 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  | 		if (!dev) { | 
					
						
							| 
									
										
										
										
											2000-08-12 15:11:46 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-01-26 13:45:33 +00:00
										 |  |  | 			DBG (1, "sane_open: unknown devicename ``%s''\n", devicename); | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  | 			return SANE_STATUS_INVAL; | 
					
						
							| 
									
										
										
										
											2000-08-12 15:11:46 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  | 		} | 
					
						
							|  |  |  | 	} else | 
					
						
							|  |  |  | 		dev = devlist; | 
					
						
							| 
									
										
										
										
											2000-08-12 15:11:46 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  | 	if (!dev) { | 
					
						
							|  |  |  | 		DBG (1, "sane_open: no devices present...\n"); | 
					
						
							|  |  |  | 		return SANE_STATUS_INVAL; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2000-08-12 15:11:46 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-01-26 13:45:33 +00:00
										 |  |  | 	DBG (3, "sane_open: Using device ``%s'' (driver %s v%s by %s)\n",  | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  | 			dev->name, dev->func->driver, dev->func->version, dev->func->author); | 
					
						
							| 
									
										
										
										
											2000-11-18 16:42:27 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  | 	if ((hndl = malloc (sizeof (Mustek_pp_Handle))) == NULL) { | 
					
						
							| 
									
										
										
										
											2000-11-18 16:42:27 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  | 		DBG (1, "sane_open: not enough free memory for the handle\n"); | 
					
						
							|  |  |  | 		return SANE_STATUS_NO_MEM; | 
					
						
							| 
									
										
										
										
											2000-08-12 15:11:46 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	if ((status = dev->func->open (dev->port, dev->caps, &fd)) != SANE_STATUS_GOOD) { | 
					
						
							| 
									
										
										
										
											2000-11-18 16:42:27 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  | 		DBG (1, "sane_open: could not open device (%s)\n", | 
					
						
							|  |  |  | 				sane_strstatus (status)); | 
					
						
							|  |  |  | 		return status; | 
					
						
							| 
									
										
										
										
											2000-08-12 15:11:46 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2000-08-12 15:11:46 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  | 	hndl->next = first_hndl; | 
					
						
							|  |  |  | 	hndl->dev = dev; | 
					
						
							|  |  |  | 	hndl->fd = fd; | 
					
						
							|  |  |  | 	hndl->state = STATE_IDLE; | 
					
						
							|  |  |  | 	hndl->pipe = -1; | 
					
						
							| 
									
										
										
										
											2000-08-12 15:11:46 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  | 	init_options (hndl); | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	dev->func->setup (hndl); | 
					
						
							|  |  |  |          | 
					
						
							|  |  |  |         /* Initialize driver-specific configuration options. This must be
 | 
					
						
							|  |  |  |            done after calling the setup() function because only then the | 
					
						
							|  |  |  |            driver is guaranteed to be fully initialized */ | 
					
						
							|  |  |  |         for (i = 0; i<dev->numcfgoptions; ++i) | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |            status = dev->func->config (hndl,  | 
					
						
							|  |  |  | 		  		       dev->cfgoptions[i].name, | 
					
						
							|  |  |  | 				       dev->cfgoptions[i].value); | 
					
						
							|  |  |  |            if (status != SANE_STATUS_GOOD) | 
					
						
							|  |  |  |            { | 
					
						
							|  |  |  |               DBG (1, "sane_open: could not set option %s for device (%s)\n", | 
					
						
							|  |  |  |             		dev->cfgoptions[i].name, sane_strstatus (status)); | 
					
						
							|  |  |  |                | 
					
						
							|  |  |  |               /* Question: should the initialization be aborted when an 
 | 
					
						
							|  |  |  |                  option cannot be handled ?  | 
					
						
							|  |  |  |                  The driver should have reasonable built-in defaults, so  | 
					
						
							|  |  |  |                  an illegal option value or an unknown option should not  | 
					
						
							|  |  |  |                  be fatal. Therefore, it's probably ok to ignore the error. */ | 
					
						
							|  |  |  |            } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	first_hndl = hndl; | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	*handle = hndl; | 
					
						
							| 
									
										
										
										
											2000-08-12 15:11:46 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  | 	return SANE_STATUS_GOOD; | 
					
						
							| 
									
										
										
										
											2000-08-12 15:11:46 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  | /* sane_close:
 | 
					
						
							|  |  |  |  * 	closes a given device and frees all resources | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * ChangeLog: | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Description: | 
					
						
							|  |  |  |  * 	The handle is searched in the list of active handles. | 
					
						
							|  |  |  |  * 	If it's found, the handle is removed. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * 	If the associated device is still scanning, the process | 
					
						
							|  |  |  |  * 	is cancelled. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * 	Then the backend makes sure, the lamp was at least | 
					
						
							|  |  |  |  * 	2 seconds on. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * 	Afterwards the selected handel is closed | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2000-08-12 15:11:46 +00:00
										 |  |  | void | 
					
						
							|  |  |  | sane_close (SANE_Handle handle) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  |   Mustek_pp_Handle *prev, *hndl; | 
					
						
							| 
									
										
										
										
											2000-08-12 15:11:46 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |   prev = NULL; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  |   for (hndl = first_hndl; hndl; hndl = hndl->next) | 
					
						
							| 
									
										
										
										
											2000-08-12 15:11:46 +00:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  |       if (hndl == handle) | 
					
						
							| 
									
										
										
										
											2000-08-12 15:11:46 +00:00
										 |  |  | 	break; | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  |       prev = hndl; | 
					
						
							| 
									
										
										
										
											2000-08-12 15:11:46 +00:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  |   if (hndl == NULL) | 
					
						
							| 
									
										
										
										
											2000-08-12 15:11:46 +00:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  |       DBG (2, "sane_close: unknown device handle\n"); | 
					
						
							|  |  |  |       return; | 
					
						
							| 
									
										
										
										
											2000-08-12 15:11:46 +00:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  |   if (hndl->state == STATE_SCANNING) { | 
					
						
							|  |  |  |     sane_cancel (handle); | 
					
						
							|  |  |  |     do_eof (handle); | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2000-08-12 15:11:46 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |   if (prev != NULL) | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  |     prev->next = hndl->next; | 
					
						
							| 
									
										
										
										
											2000-08-12 15:11:46 +00:00
										 |  |  |   else | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  |     first_hndl = hndl->next; | 
					
						
							| 
									
										
										
										
											2000-08-12 15:11:46 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  |   DBG (3, "sane_close: maybe waiting for lamp...\n"); | 
					
						
							|  |  |  |   if (hndl->lamp_on) | 
					
						
							|  |  |  |     while (time (NULL) - hndl->lamp_on < 2) | 
					
						
							|  |  |  |       sleep (1); | 
					
						
							| 
									
										
										
										
											2000-08-12 15:11:46 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  |   hndl->dev->func->close (hndl); | 
					
						
							| 
									
										
										
										
											2000-08-12 15:11:46 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  |   DBG (3, "sane_close: device closed\n"); | 
					
						
							| 
									
										
										
										
											2000-08-12 15:11:46 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |   free (handle); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  | /* sane_get_option_descriptor:
 | 
					
						
							|  |  |  |  * 	does what it says | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * ChangeLog: | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Description: | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2000-08-12 15:11:46 +00:00
										 |  |  | const SANE_Option_Descriptor * | 
					
						
							|  |  |  | sane_get_option_descriptor (SANE_Handle handle, SANE_Int option) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  |   Mustek_pp_Handle *hndl = handle; | 
					
						
							| 
									
										
										
										
											2000-08-12 15:11:46 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |   if ((unsigned) option >= NUM_OPTIONS) | 
					
						
							|  |  |  |     { | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  |       DBG (2, "sane_get_option_descriptor: option %d doesn't exist\n", option); | 
					
						
							| 
									
										
										
										
											2000-08-12 15:11:46 +00:00
										 |  |  |       return NULL; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  |   return hndl->opt + option; | 
					
						
							| 
									
										
										
										
											2000-08-12 15:11:46 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | /* sane_control_option:
 | 
					
						
							|  |  |  |  * 	Reads or writes an option | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * ChangeLog: | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Desription: | 
					
						
							|  |  |  |  * 	If a pointer to info is given, the value is initialized to zero | 
					
						
							|  |  |  |  *	while scanning options cannot be read or written. next a basic | 
					
						
							|  |  |  |  *	check whether the request is valid is done. | 
					
						
							|  |  |  |  * | 
					
						
							| 
									
										
										
										
											2003-01-26 13:45:33 +00:00
										 |  |  |  *	Depending on ``action'' the value of the option is either read | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  |  *	(in the first block) or written (in the second block). auto | 
					
						
							|  |  |  |  *	values aren't supported. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  *	before a value is written, some checks are performed. Depending | 
					
						
							|  |  |  |  *	on the option, that is written, other options also change  | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2000-08-12 15:11:46 +00:00
										 |  |  | SANE_Status | 
					
						
							|  |  |  | sane_control_option (SANE_Handle handle, SANE_Int option, | 
					
						
							|  |  |  | 		     SANE_Action action, void *val, SANE_Int * info) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  |   Mustek_pp_Handle *hndl = handle; | 
					
						
							| 
									
										
										
										
											2000-08-12 15:11:46 +00:00
										 |  |  |   SANE_Status status; | 
					
						
							|  |  |  |   SANE_Word w, cap; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (info) | 
					
						
							|  |  |  |     *info = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  |   if (hndl->state == STATE_SCANNING) | 
					
						
							| 
									
										
										
										
											2000-08-12 15:11:46 +00:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  |       DBG (2, "sane_control_option: device is scanning\n"); | 
					
						
							| 
									
										
										
										
											2000-08-12 15:11:46 +00:00
										 |  |  |       return SANE_STATUS_DEVICE_BUSY; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if ((unsigned int) option >= NUM_OPTIONS) | 
					
						
							|  |  |  |     { | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  |       DBG (2, "sane_control_option: option %d doesn't exist\n", option); | 
					
						
							| 
									
										
										
										
											2000-08-12 15:11:46 +00:00
										 |  |  |       return SANE_STATUS_INVAL; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  |   cap = hndl->opt[option].cap; | 
					
						
							| 
									
										
										
										
											2000-08-12 15:11:46 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |   if (!SANE_OPTION_IS_ACTIVE (cap)) | 
					
						
							|  |  |  |     { | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  |       DBG (2, "sane_control_option: option %d isn't active\n", option); | 
					
						
							| 
									
										
										
										
											2000-08-12 15:11:46 +00:00
										 |  |  |       return SANE_STATUS_INVAL; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (action == SANE_ACTION_GET_VALUE) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       switch (option) | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 	  /* word options: */ | 
					
						
							|  |  |  | 	case OPT_PREVIEW: | 
					
						
							|  |  |  | 	case OPT_GRAY_PREVIEW: | 
					
						
							|  |  |  | 	case OPT_RESOLUTION: | 
					
						
							|  |  |  | 	case OPT_TL_X: | 
					
						
							|  |  |  | 	case OPT_TL_Y: | 
					
						
							|  |  |  | 	case OPT_BR_X: | 
					
						
							|  |  |  | 	case OPT_BR_Y: | 
					
						
							|  |  |  | 	case OPT_NUM_OPTS: | 
					
						
							|  |  |  | 	case OPT_CUSTOM_GAMMA: | 
					
						
							|  |  |  | 	case OPT_INVERT: | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  | 	case OPT_DEPTH: | 
					
						
							| 
									
										
										
										
											2000-08-12 15:11:46 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  | 	  *(SANE_Word *) val = hndl->val[option].w; | 
					
						
							| 
									
										
										
										
											2000-08-12 15:11:46 +00:00
										 |  |  | 	  return SANE_STATUS_GOOD; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	  /* word-array options: */ | 
					
						
							|  |  |  | 	case OPT_GAMMA_VECTOR: | 
					
						
							|  |  |  | 	case OPT_GAMMA_VECTOR_R: | 
					
						
							|  |  |  | 	case OPT_GAMMA_VECTOR_G: | 
					
						
							|  |  |  | 	case OPT_GAMMA_VECTOR_B: | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  | 	  memcpy (val, hndl->val[option].wa, hndl->opt[option].size); | 
					
						
							| 
									
										
										
										
											2000-08-12 15:11:46 +00:00
										 |  |  | 	  return SANE_STATUS_GOOD; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	  /* string options: */ | 
					
						
							|  |  |  | 	case OPT_MODE: | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  | 	case OPT_SPEED: | 
					
						
							| 
									
										
										
										
											2000-08-12 15:11:46 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  | 	  strcpy (val, hndl->val[option].s); | 
					
						
							| 
									
										
										
										
											2000-08-12 15:11:46 +00:00
										 |  |  | 	  return SANE_STATUS_GOOD; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   else if (action == SANE_ACTION_SET_VALUE) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       if (!SANE_OPTION_IS_SETTABLE (cap)) | 
					
						
							|  |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  | 	  DBG (2, "sane_control_option: option can't be set (%s)\n", | 
					
						
							|  |  |  | 			  hndl->opt[option].name); | 
					
						
							| 
									
										
										
										
											2000-08-12 15:11:46 +00:00
										 |  |  | 	  return SANE_STATUS_INVAL; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  |       status = sanei_constrain_value (hndl->opt + option, val, info); | 
					
						
							| 
									
										
										
										
											2000-08-12 15:11:46 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |       if (status != SANE_STATUS_GOOD) | 
					
						
							|  |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  | 	  DBG (2, "sane_control_option: constrain_value failed (%s)\n", | 
					
						
							| 
									
										
										
										
											2000-08-12 15:11:46 +00:00
										 |  |  | 	       sane_strstatus (status)); | 
					
						
							|  |  |  | 	  return status; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       switch (option) | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 	  /* (mostly) side-effect-free word options: */ | 
					
						
							|  |  |  | 	case OPT_RESOLUTION: | 
					
						
							|  |  |  | 	case OPT_TL_X: | 
					
						
							|  |  |  | 	case OPT_BR_X: | 
					
						
							|  |  |  | 	case OPT_TL_Y: | 
					
						
							|  |  |  | 	case OPT_BR_Y: | 
					
						
							|  |  |  | 	case OPT_PREVIEW: | 
					
						
							|  |  |  | 	case OPT_GRAY_PREVIEW: | 
					
						
							|  |  |  | 	case OPT_INVERT: | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  | 	case OPT_DEPTH: | 
					
						
							| 
									
										
										
										
											2000-08-12 15:11:46 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	  if (info) | 
					
						
							|  |  |  | 	    *info |= SANE_INFO_RELOAD_PARAMS; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  | 	  hndl->val[option].w = *(SANE_Word *) val; | 
					
						
							| 
									
										
										
										
											2000-08-12 15:11:46 +00:00
										 |  |  | 	  return SANE_STATUS_GOOD; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	  /* side-effect-free word-array options: */ | 
					
						
							|  |  |  | 	case OPT_GAMMA_VECTOR: | 
					
						
							|  |  |  | 	case OPT_GAMMA_VECTOR_R: | 
					
						
							|  |  |  | 	case OPT_GAMMA_VECTOR_G: | 
					
						
							|  |  |  | 	case OPT_GAMMA_VECTOR_B: | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  | 	  memcpy (hndl->val[option].wa, val, hndl->opt[option].size); | 
					
						
							|  |  |  | 	  return SANE_STATUS_GOOD; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	  /* side-effect-free string options: */ | 
					
						
							|  |  |  | 	case OPT_SPEED: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	  if (hndl->val[option].s) | 
					
						
							|  |  |  | 		  free (hndl->val[option].s); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	  hndl->val[option].s = strdup (val); | 
					
						
							| 
									
										
										
										
											2000-08-12 15:11:46 +00:00
										 |  |  | 	  return SANE_STATUS_GOOD; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	  /* options with side-effects: */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	case OPT_CUSTOM_GAMMA: | 
					
						
							|  |  |  | 	  w = *(SANE_Word *) val; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  | 	  if (w == hndl->val[OPT_CUSTOM_GAMMA].w) | 
					
						
							| 
									
										
										
										
											2000-08-12 15:11:46 +00:00
										 |  |  | 	    return SANE_STATUS_GOOD;	/* no change */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	  if (info) | 
					
						
							|  |  |  | 	    *info |= SANE_INFO_RELOAD_OPTIONS; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  | 	  hndl->val[OPT_CUSTOM_GAMMA].w = w; | 
					
						
							| 
									
										
										
										
											2000-08-12 15:11:46 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	  if (w == SANE_TRUE) | 
					
						
							|  |  |  | 	    { | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  | 	      const char *mode = hndl->val[OPT_MODE].s; | 
					
						
							| 
									
										
										
										
											2000-08-12 15:11:46 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  | 	      if (strcmp (mode, "Grayscale") == 0) | 
					
						
							|  |  |  | 		hndl->opt[OPT_GAMMA_VECTOR].cap &= ~SANE_CAP_INACTIVE; | 
					
						
							| 
									
										
										
										
											2000-08-12 15:11:46 +00:00
										 |  |  | 	      else if (strcmp (mode, "Color") == 0) | 
					
						
							|  |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  | 		  hndl->opt[OPT_GAMMA_VECTOR].cap &= ~SANE_CAP_INACTIVE; | 
					
						
							|  |  |  | 		  hndl->opt[OPT_GAMMA_VECTOR_R].cap &= ~SANE_CAP_INACTIVE; | 
					
						
							|  |  |  | 		  hndl->opt[OPT_GAMMA_VECTOR_G].cap &= ~SANE_CAP_INACTIVE; | 
					
						
							|  |  |  | 		  hndl->opt[OPT_GAMMA_VECTOR_B].cap &= ~SANE_CAP_INACTIVE; | 
					
						
							| 
									
										
										
										
											2000-08-12 15:11:46 +00:00
										 |  |  | 		} | 
					
						
							|  |  |  | 	    } | 
					
						
							|  |  |  | 	  else | 
					
						
							|  |  |  | 	    { | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  | 	      hndl->opt[OPT_GAMMA_VECTOR].cap |= SANE_CAP_INACTIVE; | 
					
						
							|  |  |  | 	      hndl->opt[OPT_GAMMA_VECTOR_R].cap |= SANE_CAP_INACTIVE; | 
					
						
							|  |  |  | 	      hndl->opt[OPT_GAMMA_VECTOR_G].cap |= SANE_CAP_INACTIVE; | 
					
						
							|  |  |  | 	      hndl->opt[OPT_GAMMA_VECTOR_B].cap |= SANE_CAP_INACTIVE; | 
					
						
							| 
									
										
										
										
											2000-08-12 15:11:46 +00:00
										 |  |  | 	    } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	  return SANE_STATUS_GOOD; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	case OPT_MODE: | 
					
						
							|  |  |  | 	  { | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  | 	    char *old_val = hndl->val[option].s; | 
					
						
							| 
									
										
										
										
											2000-08-12 15:11:46 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	    if (old_val) | 
					
						
							|  |  |  | 	      { | 
					
						
							|  |  |  | 		if (strcmp (old_val, val) == 0) | 
					
						
							|  |  |  | 		  return SANE_STATUS_GOOD;	/* no change */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		free (old_val); | 
					
						
							|  |  |  | 	      } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	    if (info) | 
					
						
							|  |  |  | 	      *info |= SANE_INFO_RELOAD_OPTIONS | SANE_INFO_RELOAD_PARAMS; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  | 	    hndl->val[option].s = strdup (val); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	    hndl->opt[OPT_CUSTOM_GAMMA].cap |= SANE_CAP_INACTIVE; | 
					
						
							|  |  |  | 	    hndl->opt[OPT_GAMMA_VECTOR].cap |= SANE_CAP_INACTIVE; | 
					
						
							|  |  |  | 	    hndl->opt[OPT_GAMMA_VECTOR_R].cap |= SANE_CAP_INACTIVE; | 
					
						
							|  |  |  | 	    hndl->opt[OPT_GAMMA_VECTOR_G].cap |= SANE_CAP_INACTIVE; | 
					
						
							|  |  |  | 	    hndl->opt[OPT_GAMMA_VECTOR_B].cap |= SANE_CAP_INACTIVE; | 
					
						
							| 
									
										
										
										
											2000-08-12 15:11:46 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  | 	    hndl->opt[OPT_DEPTH].cap |= SANE_CAP_INACTIVE; | 
					
						
							|  |  |  | 	     | 
					
						
							|  |  |  | 	    if ((hndl->dev->caps & CAP_DEPTH) && (strcmp(val, "Color") == 0)) | 
					
						
							|  |  |  | 		    hndl->opt[OPT_DEPTH].cap &= ~SANE_CAP_INACTIVE; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	    if (!(hndl->dev->caps & CAP_GAMMA_CORRECT)) | 
					
						
							|  |  |  | 		    return SANE_STATUS_GOOD; | 
					
						
							| 
									
										
										
										
											2000-08-12 15:11:46 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	    if (strcmp (val, "Lineart") != 0) | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  | 	      hndl->opt[OPT_CUSTOM_GAMMA].cap &= ~SANE_CAP_INACTIVE; | 
					
						
							| 
									
										
										
										
											2000-08-12 15:11:46 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  | 	    if (hndl->val[OPT_CUSTOM_GAMMA].w == SANE_TRUE) | 
					
						
							| 
									
										
										
										
											2000-08-12 15:11:46 +00:00
										 |  |  | 	      { | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  | 		if (strcmp (val, "Grayscale") == 0) | 
					
						
							|  |  |  | 		  hndl->opt[OPT_GAMMA_VECTOR].cap &= ~SANE_CAP_INACTIVE; | 
					
						
							| 
									
										
										
										
											2000-08-12 15:11:46 +00:00
										 |  |  | 		else if (strcmp (val, "Color") == 0) | 
					
						
							|  |  |  | 		  { | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  | 		    hndl->opt[OPT_GAMMA_VECTOR].cap &= ~SANE_CAP_INACTIVE; | 
					
						
							|  |  |  | 		    hndl->opt[OPT_GAMMA_VECTOR_R].cap &= ~SANE_CAP_INACTIVE; | 
					
						
							|  |  |  | 		    hndl->opt[OPT_GAMMA_VECTOR_G].cap &= ~SANE_CAP_INACTIVE; | 
					
						
							|  |  |  | 		    hndl->opt[OPT_GAMMA_VECTOR_B].cap &= ~SANE_CAP_INACTIVE; | 
					
						
							| 
									
										
										
										
											2000-08-12 15:11:46 +00:00
										 |  |  | 		  } | 
					
						
							|  |  |  | 	      } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	    return SANE_STATUS_GOOD; | 
					
						
							|  |  |  | 	  } | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  |   DBG (2, "sane_control_option: unknown action\n"); | 
					
						
							| 
									
										
										
										
											2000-08-12 15:11:46 +00:00
										 |  |  |   return SANE_STATUS_INVAL; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  | /* sane_get_parameters:
 | 
					
						
							|  |  |  |  * 	returns the set of parameters, that is used for the next scan | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * ChangeLog: | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Description: | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * 	First of all it is impossible to change the parameter set | 
					
						
							|  |  |  |  * 	while scanning. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * 	sane_get_parameters not only returns the parameters for | 
					
						
							|  |  |  |  * 	the next scan, it also sets them, i.e. converts the | 
					
						
							|  |  |  |  * 	options in actuall parameters. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * 	The following parameters are set: | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * 		scanmode:	according to the option SCANMODE, but | 
					
						
							|  |  |  |  * 				24bit color, if PREVIEW is selected and | 
					
						
							|  |  |  |  * 				grayscale if GRAY_PREVIEW is selected | 
					
						
							|  |  |  |  * 		depth:		the bit depth for color modes (if | 
					
						
							|  |  |  |  * 				supported) or 24bit by default | 
					
						
							|  |  |  |  * 				(ignored in bw/grayscale or if not | 
					
						
							|  |  |  |  * 				supported) | 
					
						
							|  |  |  |  * 		dpi:		resolution  | 
					
						
							|  |  |  |  * 		invert:		if supported else defaults to false | 
					
						
							|  |  |  |  * 		gamma:		if supported and selected | 
					
						
							|  |  |  |  * 		ta:		if supported by the device | 
					
						
							|  |  |  |  * 		speed:		selected speed (or fastest if not | 
					
						
							|  |  |  |  * 				supported) | 
					
						
							|  |  |  |  * 		scanarea:	the scanarea is calculated from the | 
					
						
							|  |  |  |  * 				selections the user has mode. note | 
					
						
							|  |  |  |  * 				that the area may slightly differ from | 
					
						
							|  |  |  |  * 				the scanarea selected due to rounding | 
					
						
							|  |  |  |  * 				note also, that a scanarea of | 
					
						
							|  |  |  |  * 				(0,0)-(100,100) will include all pixels | 
					
						
							|  |  |  |  * 				where 0 <= x < 100 and 0 <= y < 100 | 
					
						
							|  |  |  |  * 	afterwards, all values are copied into the SANE_Parameters | 
					
						
							|  |  |  |  * 	structure. | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2000-08-12 15:11:46 +00:00
										 |  |  | SANE_Status | 
					
						
							|  |  |  | sane_get_parameters (SANE_Handle handle, SANE_Parameters * params) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  |   Mustek_pp_Handle *hndl = handle; | 
					
						
							| 
									
										
										
										
											2000-08-12 15:11:46 +00:00
										 |  |  |   char *mode; | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  |       int dpi, ctr; | 
					
						
							| 
									
										
										
										
											2000-08-12 15:11:46 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  |   if (hndl->state != STATE_SCANNING) | 
					
						
							| 
									
										
										
										
											2000-08-12 15:11:46 +00:00
										 |  |  |     { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  |       memset (&hndl->params, 0, sizeof (hndl->params)); | 
					
						
							| 
									
										
										
										
											2000-08-12 15:11:46 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  |       if ((hndl->dev->caps & CAP_DEPTH) && (hndl->mode == MODE_COLOR)) | 
					
						
							|  |  |  | 	hndl->depth = hndl->val[OPT_DEPTH].w; | 
					
						
							| 
									
										
										
										
											2000-08-12 15:11:46 +00:00
										 |  |  |       else | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  | 	hndl->depth = 8; | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  |       dpi = (int) (SANE_UNFIX (hndl->val[OPT_RESOLUTION].w) + 0.5); | 
					
						
							|  |  |  |        | 
					
						
							|  |  |  |       hndl->res = dpi; | 
					
						
							| 
									
										
										
										
											2000-08-12 15:11:46 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  |       if (hndl->dev->caps & CAP_INVERT) | 
					
						
							|  |  |  | 	hndl->invert = hndl->val[OPT_INVERT].w; | 
					
						
							|  |  |  |       else | 
					
						
							|  |  |  | 	hndl->invert = SANE_FALSE; | 
					
						
							| 
									
										
										
										
											2000-08-12 15:11:46 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  |       if (hndl->dev->caps & CAP_TA) | 
					
						
							|  |  |  | 	hndl->use_ta = SANE_TRUE; | 
					
						
							|  |  |  |       else | 
					
						
							|  |  |  | 	hndl->use_ta = SANE_FALSE; | 
					
						
							| 
									
										
										
										
											2000-11-18 16:42:27 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  |       if ((hndl->dev->caps & CAP_GAMMA_CORRECT) && (hndl->val[OPT_CUSTOM_GAMMA].w == SANE_TRUE)) | 
					
						
							|  |  |  | 	      hndl->do_gamma = SANE_TRUE; | 
					
						
							|  |  |  |       else | 
					
						
							|  |  |  | 	      hndl->do_gamma = SANE_FALSE; | 
					
						
							| 
									
										
										
										
											2000-11-18 16:42:27 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  |       if (hndl->dev->caps & CAP_SPEED_SELECT) { | 
					
						
							| 
									
										
										
										
											2000-11-18 16:42:27 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  | 	      for (ctr=SPEED_SLOWEST; ctr<=SPEED_FASTEST; ctr++) | 
					
						
							|  |  |  | 		      if (strcmp(mustek_pp_speeds[ctr], hndl->val[OPT_SPEED].s) == 0) | 
					
						
							|  |  |  | 			      hndl->speed = ctr; | 
					
						
							| 
									
										
										
										
											2000-08-12 15:11:46 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  | 	       | 
					
						
							| 
									
										
										
										
											2000-08-12 15:11:46 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  |       } else | 
					
						
							|  |  |  | 	      hndl->speed = SPEED_NORMAL; | 
					
						
							|  |  |  | 		       | 
					
						
							|  |  |  |       mode = hndl->val[OPT_MODE].s; | 
					
						
							| 
									
										
										
										
											2000-08-12 15:11:46 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  |       if (strcmp (mode, "Lineart") == 0) | 
					
						
							|  |  |  | 	hndl->mode = MODE_BW; | 
					
						
							|  |  |  |       else if (strcmp (mode, "Grayscale") == 0) | 
					
						
							|  |  |  | 	hndl->mode = MODE_GRAYSCALE; | 
					
						
							|  |  |  |       else | 
					
						
							|  |  |  | 	hndl->mode = MODE_COLOR; | 
					
						
							| 
									
										
										
										
											2000-08-12 15:11:46 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  |       if (hndl->val[OPT_PREVIEW].w == SANE_TRUE) | 
					
						
							|  |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2000-08-12 15:11:46 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  | 			hndl->speed = SPEED_FASTEST; | 
					
						
							|  |  |  | 			hndl->depth = 8; | 
					
						
							|  |  |  | 			if (! hndl->use_ta) | 
					
						
							|  |  |  | 			hndl->invert = SANE_FALSE; | 
					
						
							|  |  |  | 			hndl->do_gamma = SANE_FALSE; | 
					
						
							| 
									
										
										
										
											2000-08-12 15:11:46 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  | 	  if (hndl->val[OPT_GRAY_PREVIEW].w == SANE_TRUE) | 
					
						
							|  |  |  | 	    hndl->mode = MODE_GRAYSCALE; | 
					
						
							|  |  |  | 	  else { | 
					
						
							|  |  |  | 	    hndl->mode = MODE_COLOR; | 
					
						
							|  |  |  | 	  } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2000-08-12 15:11:46 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  |       hndl->topX = | 
					
						
							| 
									
										
										
										
											2000-08-12 15:11:46 +00:00
										 |  |  | 	MIN ((int) | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  | 	     (MM_TO_PIXEL (SANE_UNFIX(hndl->val[OPT_TL_X].w), hndl->dev->maxres) + | 
					
						
							|  |  |  | 	      0.5), hndl->dev->maxhsize); | 
					
						
							|  |  |  |       hndl->topY = | 
					
						
							| 
									
										
										
										
											2000-08-12 15:11:46 +00:00
										 |  |  | 	MIN ((int) | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  | 	     (MM_TO_PIXEL (SANE_UNFIX(hndl->val[OPT_TL_Y].w), hndl->dev->maxres) + | 
					
						
							|  |  |  | 	      0.5), hndl->dev->maxvsize); | 
					
						
							| 
									
										
										
										
											2000-08-12 15:11:46 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  |       hndl->bottomX = | 
					
						
							| 
									
										
										
										
											2000-08-12 15:11:46 +00:00
										 |  |  | 	MIN ((int) | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  | 	     (MM_TO_PIXEL (SANE_UNFIX(hndl->val[OPT_BR_X].w), hndl->dev->maxres) + | 
					
						
							|  |  |  | 	      0.5), hndl->dev->maxhsize); | 
					
						
							|  |  |  |       hndl->bottomY = | 
					
						
							| 
									
										
										
										
											2000-08-12 15:11:46 +00:00
										 |  |  | 	MIN ((int) | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  | 	     (MM_TO_PIXEL (SANE_UNFIX(hndl->val[OPT_BR_Y].w), hndl->dev->maxres) + | 
					
						
							|  |  |  | 	      0.5), hndl->dev->maxvsize); | 
					
						
							|  |  |  |        | 
					
						
							|  |  |  |       /* If necessary, swap the upper and lower boundaries to avoid negative
 | 
					
						
							|  |  |  |          distances. */ | 
					
						
							|  |  |  |       if (hndl->topX > hndl->bottomX) { | 
					
						
							|  |  |  | 	SANE_Int tmp = hndl->topX; | 
					
						
							|  |  |  | 	hndl->topX = hndl->bottomX; | 
					
						
							|  |  |  | 	hndl->bottomX = tmp; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       if (hndl->topY > hndl->bottomY) { | 
					
						
							|  |  |  | 	SANE_Int tmp = hndl->topY; | 
					
						
							|  |  |  | 	hndl->topY = hndl->bottomY; | 
					
						
							|  |  |  | 	hndl->bottomY = tmp; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       hndl->params.pixels_per_line = (hndl->bottomX - hndl->topX) * hndl->res | 
					
						
							|  |  |  | 	/ hndl->dev->maxres; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       hndl->params.bytes_per_line = hndl->params.pixels_per_line; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       switch (hndl->mode) | 
					
						
							| 
									
										
										
										
											2000-08-12 15:11:46 +00:00
										 |  |  | 	{ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  | 	case MODE_BW: | 
					
						
							|  |  |  | 	  hndl->params.bytes_per_line /= 8; | 
					
						
							| 
									
										
										
										
											2000-08-12 15:11:46 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  | 	  if ((hndl->params.pixels_per_line % 8) != 0) | 
					
						
							|  |  |  | 	    hndl->params.bytes_per_line++; | 
					
						
							| 
									
										
										
										
											2000-08-12 15:11:46 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  | 	  hndl->params.depth = 1; | 
					
						
							| 
									
										
										
										
											2000-08-12 15:11:46 +00:00
										 |  |  | 	  break; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  | 	case MODE_GRAYSCALE: | 
					
						
							|  |  |  | 	  hndl->params.depth = 8; | 
					
						
							|  |  |  | 	  hndl->params.format = SANE_FRAME_GRAY; | 
					
						
							| 
									
										
										
										
											2000-08-12 15:11:46 +00:00
										 |  |  | 	  break; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  | 	case MODE_COLOR: | 
					
						
							|  |  |  | 	  hndl->params.depth = hndl->depth; | 
					
						
							|  |  |  | 	  hndl->params.bytes_per_line *= 3; | 
					
						
							|  |  |  | 	  if (hndl->depth > 8) | 
					
						
							|  |  |  | 	    hndl->params.bytes_per_line *= 2; | 
					
						
							|  |  |  | 	  hndl->params.format = SANE_FRAME_RGB; | 
					
						
							| 
									
										
										
										
											2000-08-12 15:11:46 +00:00
										 |  |  | 	  break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  |       hndl->params.last_frame = SANE_TRUE; | 
					
						
							| 
									
										
										
										
											2000-08-12 15:11:46 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  |       hndl->params.lines = (hndl->bottomY - hndl->topY) * hndl->res / | 
					
						
							|  |  |  | 	hndl->dev->maxres; | 
					
						
							| 
									
										
										
										
											2000-08-12 15:11:46 +00:00
										 |  |  |     } | 
					
						
							|  |  |  |   else | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  |       DBG (2, "sane_get_parameters: can't set parameters while scanning\n"); | 
					
						
							| 
									
										
										
										
											2000-08-12 15:11:46 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |   if (params != NULL) | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  |     *params = hndl->params; | 
					
						
							| 
									
										
										
										
											2000-08-12 15:11:46 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |   return SANE_STATUS_GOOD; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | /* sane_start:
 | 
					
						
							|  |  |  |  * 	starts the scan. data aquisition will start immedially | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * ChangeLog: | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Description: | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2000-08-12 15:11:46 +00:00
										 |  |  | SANE_Status | 
					
						
							|  |  |  | sane_start (SANE_Handle handle) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  |   Mustek_pp_Handle	*hndl = handle; | 
					
						
							|  |  |  |   int			pipeline[2]; | 
					
						
							| 
									
										
										
										
											2000-08-12 15:11:46 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  |   if (hndl->state == STATE_SCANNING) { | 
					
						
							|  |  |  | 	  DBG (2, "sane_start: device is already scanning\n"); | 
					
						
							|  |  |  | 	  return SANE_STATUS_DEVICE_BUSY; | 
					
						
							| 
									
										
										
										
											2000-11-18 16:42:27 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2000-11-18 16:42:27 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  | 	sane_get_parameters (hndl, NULL); | 
					
						
							| 
									
										
										
										
											2000-08-12 15:11:46 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  | 	if (pipe(pipeline) < 0) { | 
					
						
							|  |  |  | 		DBG (1, "sane_start: could not initialize pipe (%s)\n", | 
					
						
							|  |  |  | 				strerror(errno)); | 
					
						
							|  |  |  | 		return SANE_STATUS_IO_ERROR; | 
					
						
							| 
									
										
										
										
											2000-08-12 15:11:46 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  | 	hndl->reader = fork(); | 
					
						
							| 
									
										
										
										
											2000-08-12 15:11:46 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  | 	if (hndl->reader == 0) { | 
					
						
							| 
									
										
										
										
											2000-08-12 15:11:46 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  | 		sigset_t	ignore_set; | 
					
						
							|  |  |  | 		struct SIGACTION	act; | 
					
						
							| 
									
										
										
										
											2000-08-12 15:11:46 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  | 		close (pipeline[0]); | 
					
						
							| 
									
										
										
										
											2000-08-12 15:11:46 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  | 		sigfillset (&ignore_set); | 
					
						
							|  |  |  | 		sigdelset (&ignore_set, SIGTERM); | 
					
						
							|  |  |  | 		sigprocmask (SIG_SETMASK, &ignore_set, NULL); | 
					
						
							| 
									
										
										
										
											2000-08-12 15:11:46 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  | 		memset (&act, 0, sizeof(act)); | 
					
						
							|  |  |  | 		sigaction (SIGTERM, &act, NULL); | 
					
						
							| 
									
										
										
										
											2000-08-12 15:11:46 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  | 		_exit (reader_process (hndl, pipeline[1])); | 
					
						
							| 
									
										
										
										
											2000-08-12 15:11:46 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  | 	close (pipeline[1]); | 
					
						
							| 
									
										
										
										
											2000-08-12 15:11:46 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  | 	hndl->pipe = pipeline[0]; | 
					
						
							| 
									
										
										
										
											2000-08-12 15:11:46 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  | 	hndl->state = STATE_SCANNING; | 
					
						
							| 
									
										
										
										
											2000-08-12 15:11:46 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |   return SANE_STATUS_GOOD; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  | /* sane_read:
 | 
					
						
							|  |  |  |  * 	receives data from pipeline and passes it to the caller | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * ChangeLog: | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Description: | 
					
						
							|  |  |  |  * 	ditto | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2000-08-12 15:11:46 +00:00
										 |  |  | SANE_Status | 
					
						
							|  |  |  | sane_read (SANE_Handle handle, SANE_Byte * buf, SANE_Int max_len, | 
					
						
							|  |  |  | 	   SANE_Int * len) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  |   Mustek_pp_Handle	*hndl = handle; | 
					
						
							|  |  |  |   SANE_Int		nread; | 
					
						
							| 
									
										
										
										
											2000-08-12 15:11:46 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  |   if (hndl->state == STATE_CANCELLED) { | 
					
						
							|  |  |  | 	  DBG (2, "sane_read: device already cancelled\n"); | 
					
						
							|  |  |  | 	  do_eof (hndl); | 
					
						
							|  |  |  | 	  hndl->state = STATE_IDLE; | 
					
						
							| 
									
										
										
										
											2000-08-12 15:11:46 +00:00
										 |  |  | 	  return SANE_STATUS_CANCELLED; | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2000-08-12 15:11:46 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  |   if (hndl->state != STATE_SCANNING) { | 
					
						
							|  |  |  | 	  DBG (1, "sane_read: device isn't scanning\n"); | 
					
						
							|  |  |  | 	  return SANE_STATUS_INVAL; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2000-08-12 15:11:46 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  |   *len = nread = 0; | 
					
						
							| 
									
										
										
										
											2000-08-12 15:11:46 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  |   while (*len < max_len) { | 
					
						
							| 
									
										
										
										
											2000-08-12 15:11:46 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  | 	  nread = read(hndl->pipe, buf + *len, max_len - *len); | 
					
						
							| 
									
										
										
										
											2000-08-12 15:11:46 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  | 	  if (hndl->state == STATE_CANCELLED) { | 
					
						
							| 
									
										
										
										
											2000-08-12 15:11:46 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  | 		  *len = 0; | 
					
						
							|  |  |  | 		  DBG(3, "sane_read: scan was cancelled\n"); | 
					
						
							| 
									
										
										
										
											2000-08-12 15:11:46 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  | 		  do_eof (hndl); | 
					
						
							|  |  |  | 		  hndl->state = STATE_IDLE; | 
					
						
							|  |  |  | 		  return SANE_STATUS_CANCELLED; | 
					
						
							| 
									
										
										
										
											2000-08-12 15:11:46 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  | 	  } | 
					
						
							| 
									
										
										
										
											2000-08-12 15:11:46 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  | 	  if (nread < 0) { | 
					
						
							| 
									
										
										
										
											2000-08-12 15:11:46 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  | 		  if (errno == EAGAIN) { | 
					
						
							| 
									
										
										
										
											2000-08-12 15:11:46 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  | 			  if (*len == 0) | 
					
						
							|  |  |  | 				  DBG(3, "sane_read: no data at the moment\n"); | 
					
						
							|  |  |  | 			  else | 
					
						
							|  |  |  | 				  DBG(3, "sane_read: %d bytes read\n", *len); | 
					
						
							| 
									
										
										
										
											2000-08-12 15:11:46 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  | 			  return SANE_STATUS_GOOD; | 
					
						
							| 
									
										
										
										
											2000-08-12 15:11:46 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  | 		  } else { | 
					
						
							| 
									
										
										
										
											2000-08-12 15:11:46 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  | 			  DBG(1, "sane_read: IO error (%s)\n", strerror(errno)); | 
					
						
							| 
									
										
										
										
											2000-08-12 15:11:46 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  | 			  hndl->state = STATE_IDLE; | 
					
						
							|  |  |  | 			  do_stop(hndl); | 
					
						
							| 
									
										
										
										
											2000-08-12 15:11:46 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  | 			  do_eof (hndl); | 
					
						
							| 
									
										
										
										
											2000-08-12 15:11:46 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  | 			  *len = 0; | 
					
						
							|  |  |  | 			  return SANE_STATUS_IO_ERROR; | 
					
						
							| 
									
										
										
										
											2000-08-12 15:11:46 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  | 		  } | 
					
						
							|  |  |  | 	  } | 
					
						
							| 
									
										
										
										
											2000-08-12 15:11:46 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  | 	  *len += nread; | 
					
						
							| 
									
										
										
										
											2000-08-12 15:11:46 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  | 	  if (nread == 0) { | 
					
						
							| 
									
										
										
										
											2000-08-12 15:11:46 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  | 		  if (*len == 0) { | 
					
						
							| 
									
										
										
										
											2000-08-12 15:11:46 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  | 			DBG (3, "sane_read: read finished\n"); | 
					
						
							|  |  |  | 			do_stop(hndl); | 
					
						
							| 
									
										
										
										
											2000-08-12 15:11:46 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  | 			hndl->state = STATE_IDLE; | 
					
						
							| 
									
										
										
										
											2000-08-12 15:11:46 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  | 			return do_eof(hndl); | 
					
						
							| 
									
										
										
										
											2000-08-12 15:11:46 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  | 		  } | 
					
						
							| 
									
										
										
										
											2000-08-12 15:11:46 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  | 		  DBG(3, "sane_read: read last buffer of %d bytes\n", | 
					
						
							|  |  |  | 				  *len); | 
					
						
							| 
									
										
										
										
											2000-08-12 15:11:46 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  | 		  return SANE_STATUS_GOOD; | 
					
						
							| 
									
										
										
										
											2000-08-12 15:11:46 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  | 	  } | 
					
						
							| 
									
										
										
										
											2000-08-12 15:11:46 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2000-08-12 15:11:46 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  |   DBG(3, "sane_read: read full buffer of %d bytes\n", *len); | 
					
						
							| 
									
										
										
										
											2000-08-12 15:11:46 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |   return SANE_STATUS_GOOD; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | /* sane_cancel:
 | 
					
						
							|  |  |  |  * 	stops a scan and ends the reader process | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * ChangeLog: | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Description: | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2000-08-12 15:11:46 +00:00
										 |  |  | void | 
					
						
							|  |  |  | sane_cancel (SANE_Handle handle) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  |   Mustek_pp_Handle *hndl = handle; | 
					
						
							| 
									
										
										
										
											2000-08-12 15:11:46 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  |   if (hndl->state != STATE_SCANNING) | 
					
						
							|  |  |  | 	 return; | 
					
						
							| 
									
										
										
										
											2000-08-12 15:11:46 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  |   hndl->state = STATE_CANCELLED; | 
					
						
							| 
									
										
										
										
											2000-08-12 15:11:46 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  |   do_stop (hndl); | 
					
						
							| 
									
										
										
										
											2000-08-12 15:11:46 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2000-08-12 15:11:46 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  | /* sane_set_io_mode:
 | 
					
						
							|  |  |  |  * 	toggles between blocking and non-blocking reading | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * ChangeLog: | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Description: | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | SANE_Status | 
					
						
							|  |  |  | sane_set_io_mode (SANE_Handle handle, SANE_Bool non_blocking) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2000-08-12 15:11:46 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  | 	Mustek_pp_Handle	*hndl=handle; | 
					
						
							| 
									
										
										
										
											2000-08-12 15:11:46 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  | 	if (hndl->state != STATE_SCANNING) | 
					
						
							|  |  |  | 		return SANE_STATUS_INVAL; | 
					
						
							|  |  |  | 	 | 
					
						
							| 
									
										
										
										
											2000-08-12 15:11:46 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  | 	if (fcntl (hndl->pipe, F_SETFL, non_blocking ? O_NONBLOCK : 0) < 0) { | 
					
						
							| 
									
										
										
										
											2000-08-12 15:11:46 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  | 		DBG(1, "sane_set_io_mode: can't set io mode\n"); | 
					
						
							| 
									
										
										
										
											2000-08-12 15:11:46 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  | 		return SANE_STATUS_IO_ERROR; | 
					
						
							| 
									
										
										
										
											2000-08-12 15:11:46 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2000-08-12 15:11:46 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  | 	return SANE_STATUS_GOOD; | 
					
						
							| 
									
										
										
										
											2000-08-12 15:11:46 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  | /* sane_get_select_fd:
 | 
					
						
							|  |  |  |  * 	returns the pipeline fd for direct reading | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * ChangeLog: | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Description: | 
					
						
							|  |  |  |  * 	to allow the frontend to receive the data directly it | 
					
						
							|  |  |  |  * 	can read from the pipeline itself | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2000-08-12 15:11:46 +00:00
										 |  |  | SANE_Status | 
					
						
							|  |  |  | sane_get_select_fd (SANE_Handle handle, SANE_Int * fd) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  | 	Mustek_pp_Handle	*hndl=handle; | 
					
						
							| 
									
										
										
										
											2000-08-12 15:11:46 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  | 	if (hndl->state != STATE_SCANNING) | 
					
						
							|  |  |  | 		return SANE_STATUS_INVAL; | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	*fd = hndl->pipe; | 
					
						
							| 
									
										
										
										
											2000-08-12 15:11:46 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-01-12 19:44:26 +00:00
										 |  |  | 	return SANE_STATUS_GOOD; | 
					
						
							| 
									
										
										
										
											2000-08-12 15:11:46 +00:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2003-01-13 19:49:47 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | /* include drivers */ | 
					
						
							|  |  |  | #include "mustek_pp_decl.h"
 | 
					
						
							|  |  |  | #include "mustek_pp_null.c"
 | 
					
						
							|  |  |  | #include "mustek_pp_cis.h"
 | 
					
						
							|  |  |  | #include "mustek_pp_cis.c"
 | 
					
						
							|  |  |  | #include "mustek_pp_ccd300.h"
 | 
					
						
							|  |  |  | #include "mustek_pp_ccd300.c"
 |