2006-05-26 07:49:24 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								/* SANE - Scanner Access Now Easy.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								   Copyright  ( C )  2006  Wittawat  Yamwong  < wittawat @ web . de > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								   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 . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								#  include ".. / include /sane/config.h" 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  <errno.h> 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  <string.h> 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  <stdlib.h> 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  <signal.h>		/* sigaction(POSIX) */ 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  <unistd.h>		/* POSIX: write read close pipe */ 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# ifdef HAVE_FCNTL_H 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								#  include <fcntl.h> 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# endif 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  "pixma_rename.h" 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  "pixma.h" 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								#  define DEBUG_NOT_STATIC 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								#  include ".. / include /sane/sane.h" 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								#  include ".. / include /sane/sanei.h" 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								#  include ".. / include /sane/saneopts.h" 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								#  include ".. / include /sane/sanei_thread.h" 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								#  include ".. / include /sane/sanei_backend.h" 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# ifdef NDEBUG 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								#  define PDBG(x) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# else 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								#   define PDBG(x) IF_DBG(x) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# endif  /* NDEBUG */ 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# ifdef __GNUC__ 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								#  define UNUSED(v) (void) v 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# else 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								#  define UNUSED(v) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# endif 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# define DECL_CTX pixma_sane_t *ss = check_handle(h) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# define OPT_IN_CTX ss->opt 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# define SOD(opt)  OPT_IN_CTX[opt].sod 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# define OVAL(opt) OPT_IN_CTX[opt].val 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# define AUTO_GAMMA 2.2 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  "pixma_sane_options.h"	/* generated by gen_options.py */ 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								typedef  struct  pixma_sane_t  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  struct  pixma_sane_t  * next ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  pixma_t  * s ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  pixma_scan_param_t  sp ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  SANE_Bool  cancel ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  /* valid states: idle, !idle && scanning, !idle && !scanning */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  SANE_Bool  idle ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  SANE_Bool  scanning ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  SANE_Status  last_read_status ; 	/* valid if !idle && !scanning */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  option_descriptor_t  opt [ opt_last ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  SANE_Range  xrange ,  yrange ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  SANE_Word  dpi_list [ 9 ] ; 	/* up to 9600 dpi */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  SANE_String_Const  mode_list [ 3 ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  uint8_t  gamma_table [ 4096 ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  SANE_String_Const  source_list [ 4 ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  pixma_paper_source_t  source_map [ 4 ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  unsigned  byte_pos_in_line ,  output_line_size ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  unsigned  image_bytes_read ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  unsigned  page_count ; 		/* valid for ADF */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  int  reader_taskid ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  int  wpipe ,  rpipe ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  SANE_Bool  reader_stop ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  pixma_sane_t ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  const  char  vendor_str [ ]  =  " CANON " ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  const  char  type_str [ ]  =  SANE_I18N  ( " multi-function peripheral " ) ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  pixma_sane_t  * first_scanner  =  NULL ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  const  SANE_Device  * * dev_list  =  NULL ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  SANE_Status  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								map_error  ( int  error )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  if  ( error  > =  0 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    return  SANE_STATUS_GOOD ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  switch  ( error ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    case  - ENOMEM : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      return  SANE_STATUS_NO_MEM ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    case  - ECANCELED : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      return  SANE_STATUS_CANCELLED ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    case  - EBUSY : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      return  SANE_STATUS_DEVICE_BUSY ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    case  - EINVAL : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      return  SANE_STATUS_INVAL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    case  - EACCES : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      return  SANE_STATUS_ACCESS_DENIED ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    case  - EDEADLK : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      return  SANE_STATUS_JAMMED ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    case  - ENODATA : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      return  SANE_STATUS_NO_DOCS ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    case  - ENOLCK : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      return  SANE_STATUS_COVER_OPEN ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    case  - EPROTO : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    case  - ENODEV : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    case  - EIO : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    case  - ETIMEDOUT : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      return  SANE_STATUS_IO_ERROR ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    default : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      PDBG  ( pixma_dbg  ( 1 ,  " BUG: unmapped error %d %s \n " ,  error , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										       strerror  ( - error ) ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      return  SANE_STATUS_IO_ERROR ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								getenv_atoi  ( const  char  * name ,  int  def )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  const  char  * str  =  getenv  ( name ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  return  ( str )  ?  atoi  ( str )  :  def ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  void  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								cleanup_device_list  ( void )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  if  ( dev_list ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      int  i ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      for  ( i  =  0 ;  dev_list [ i ] ;  i + + ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									  free  ( dev_list [ i ] - > name ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									  free  ( dev_list [ i ] - > model ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									  free  ( dev_list [ i ] ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  free  ( dev_list ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  dev_list  =  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  void  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								find_scanners  ( void )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  unsigned  i ,  nscanners ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  cleanup_device_list  ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  nscanners  =  pixma_find_scanners  ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  dev_list  = 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    ( const  SANE_Device  * * )  calloc  ( nscanners  +  1 ,  sizeof  ( * dev_list ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  if  ( ! dev_list ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  for  ( i  =  0 ;  i  ! =  nscanners ;  i + + ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      SANE_Device  * sdev  =  ( SANE_Device  * )  calloc  ( 1 ,  sizeof  ( * sdev ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      char  * name ,  * model ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      if  ( ! sdev ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									goto  nomem ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      name  =  strdup  ( pixma_get_device_id  ( i ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      model  =  strdup  ( pixma_get_device_model  ( i ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      if  ( ! name  | |  ! model ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									  free  ( name ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									  free  ( model ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									  free  ( sdev ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									  goto  nomem ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      sdev - > name  =  name ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      sdev - > model  =  model ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      sdev - > vendor  =  vendor_str ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      sdev - > type  =  type_str ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      dev_list [ i ]  =  sdev ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  /* dev_list is already NULL terminated by calloc(). */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								nomem :  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  PDBG  ( pixma_dbg  ( 1 ,  " WARNING:not enough memory for device list \n " ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  pixma_sane_t  *  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								check_handle  ( SANE_Handle  h )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  pixma_sane_t  * p ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  for  ( p  =  first_scanner ;  p  & &  ( SANE_Handle )  p  ! =  h ;  p  =  p - > next ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  return  p ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  void  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								update_button_state  ( pixma_sane_t  *  ss ,  SANE_Int  *  info )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  SANE_Int  b1  =  OVAL  ( opt_button_1 ) . w ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  SANE_Int  b2  =  OVAL  ( opt_button_2 ) . w ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  uint32_t  ev  =  pixma_wait_event  ( ss - > s ,  300 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  switch  ( ev  &  ~ PIXMA_EV_ACTION_MASK ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    case  PIXMA_EV_BUTTON1 : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      b1  =  ( ev  &  PIXMA_EV_ACTION_MASK )  +  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    case  PIXMA_EV_BUTTON2 : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      b2  =  ( ev  &  PIXMA_EV_ACTION_MASK )  +  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  if  ( b1  ! =  OVAL  ( opt_button_1 ) . w  | |  b2  ! =  OVAL  ( opt_button_2 ) . w ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    * info  | =  SANE_INFO_RELOAD_OPTIONS ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  OVAL  ( opt_button_1 ) . w  =  b1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  OVAL  ( opt_button_2 ) . w  =  b2 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  void  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								clamp_value  ( pixma_sane_t  *  ss ,  SANE_Int  n ,  void  * v ,  SANE_Int  *  info )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  SANE_Option_Descriptor  * sod  =  & SOD  ( n ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  SANE_Word  * va  =  ( SANE_Word  * )  v ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  const  SANE_Range  * range  =  sod - > constraint . range ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  int  i ,  nmemb ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  nmemb  =  sod - > size  /  sizeof  ( SANE_Word ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  for  ( i  =  0 ;  i  <  nmemb ;  i + + ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      SANE_Word  value  =  va [ i ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      if  ( value  <  range - > min ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									  value  =  range - > min ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      else  if  ( value  >  range - > max ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									  value  =  range - > max ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      if  ( range - > quant  ! =  0 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									  value  =  ( value  -  range - > min  +  range - > quant  /  2 )  / 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									    range - > quant  *  range - > quant ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      if  ( value  ! =  va [ i ] ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									  va [ i ]  =  value ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									  * info  | =  SANE_INFO_INEXACT ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  void  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								select_value_from_list  ( pixma_sane_t  *  ss ,  SANE_Int  n ,  void  * v ,  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											SANE_Int  *  info ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  SANE_Option_Descriptor  * sod  =  & SOD  ( n ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  SANE_Word  * va  =  ( SANE_Word  * )  v ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  const  SANE_Word  * list  =  sod - > constraint . word_list ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  int  i ,  j ,  nmemb ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  nmemb  =  sod - > size  /  sizeof  ( SANE_Word ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  for  ( i  =  0 ;  i  <  nmemb ;  i + + ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      SANE_Word  value  =  va [ i ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      SANE_Word  mindelta  =  abs  ( value  -  list [ 1 ] ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      SANE_Word  nearest  =  list [ 1 ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      for  ( j  =  2 ;  j  < =  list [ 0 ] ;  j + + ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									  SANE_Word  delta  =  abs  ( value  -  list [ j ] ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									  if  ( delta  <  mindelta ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									    { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									      mindelta  =  delta ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									      nearest  =  list [ j ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									  if  ( mindelta  = =  0 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									    break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      if  ( va [ i ]  ! =  nearest ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									  va [ i ]  =  nearest ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									  * info  | =  SANE_INFO_INEXACT ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  SANE_Status  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								control_scalar_option  ( pixma_sane_t  *  ss ,  SANE_Int  n ,  SANE_Action  a ,  void  * v ,  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										       SANE_Int  *  info ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  option_descriptor_t  * opt  =  & ( OPT_IN_CTX [ n ] ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  SANE_Word  val ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  switch  ( a ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    case  SANE_ACTION_GET_VALUE : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      switch  ( opt - > sod . type ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  SANE_TYPE_BOOL : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  SANE_TYPE_INT : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  SANE_TYPE_FIXED : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									  * ( SANE_Word  * )  v  =  opt - > val . w ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									  break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									default : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									  return  SANE_STATUS_UNSUPPORTED ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      return  SANE_STATUS_GOOD ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    case  SANE_ACTION_SET_VALUE : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      switch  ( opt - > sod . type ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  SANE_TYPE_BOOL : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									  val  =  * ( SANE_Word  * )  v ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									  if  ( val  ! =  SANE_TRUE  & &  val  ! =  SANE_FALSE ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									    return  SANE_STATUS_INVAL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									  opt - > val . w  =  val ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									  break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  SANE_TYPE_INT : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  SANE_TYPE_FIXED : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									  if  ( opt - > sod . constraint_type  = =  SANE_CONSTRAINT_RANGE ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									    clamp_value  ( ss ,  n ,  v ,  info ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									  else  if  ( opt - > sod . constraint_type  = =  SANE_CONSTRAINT_WORD_LIST ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									    select_value_from_list  ( ss ,  n ,  v ,  info ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									  opt - > val . w  =  * ( SANE_Word  * )  v ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									  break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									default : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									  return  SANE_STATUS_UNSUPPORTED ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      * info  | =  opt - > info ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      return  SANE_STATUS_GOOD ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    case  SANE_ACTION_SET_AUTO : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      switch  ( opt - > sod . type ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  SANE_TYPE_BOOL : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  SANE_TYPE_INT : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  SANE_TYPE_FIXED : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									  opt - > val . w  =  opt - > def . w ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									  break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									default : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									  return  SANE_STATUS_UNSUPPORTED ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      * info  | =  opt - > info ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      return  SANE_STATUS_GOOD ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  return  SANE_STATUS_UNSUPPORTED ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  SANE_Status  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								control_string_option  ( pixma_sane_t  *  ss ,  SANE_Int  n ,  SANE_Action  a ,  void  * v ,  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										       SANE_Int  *  info ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  option_descriptor_t  * opt  =  & ( OPT_IN_CTX [ n ] ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  const  SANE_String_Const  * slist  =  opt - > sod . constraint . string_list ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  SANE_String  str  =  ( SANE_String )  v ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  int  i ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  if  ( opt - > sod . constraint_type  = =  SANE_CONSTRAINT_NONE ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      switch  ( a ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  SANE_ACTION_GET_VALUE : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									  strcpy  ( str ,  opt - > val . s ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									  break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  SANE_ACTION_SET_AUTO : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									  str  =  opt - > def . s ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									  /* fall through */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  SANE_ACTION_SET_VALUE : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									  strncpy  ( opt - > val . s ,  str ,  opt - > sod . size ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									  * info  | =  opt - > info ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									  break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      return  SANE_STATUS_GOOD ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  else 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      switch  ( a ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  SANE_ACTION_GET_VALUE : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									  strcpy  ( str ,  slist [ opt - > val . w ] ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									  break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  SANE_ACTION_SET_AUTO : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									  str  =  opt - > def . ptr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									  /* fall through */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  SANE_ACTION_SET_VALUE : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									  i  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									  while  ( slist [ i ]  & &  strcasecmp  ( str ,  slist [ i ] )  ! =  0 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									    i + + ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									  if  ( ! slist [ i ] ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									    return  SANE_STATUS_INVAL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									  if  ( strcmp  ( slist [ i ] ,  str )  ! =  0 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									    { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									      strcpy  ( str ,  slist [ i ] ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									      * info  | =  SANE_INFO_INEXACT ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									  opt - > val . w  =  i ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									  * info  | =  opt - > info ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									  break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      return  SANE_STATUS_GOOD ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  SANE_Status  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								control_option  ( pixma_sane_t  *  ss ,  SANE_Int  n ,  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										SANE_Action  a ,  void  * v ,  SANE_Int  *  info ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  int  result ,  i ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  result  =  SANE_STATUS_UNSUPPORTED ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  switch  ( n ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    case  opt_gamma_table : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      switch  ( a ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  SANE_ACTION_SET_VALUE : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									  clamp_value  ( ss ,  n ,  v ,  info ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									  for  ( i  =  0 ;  i  ! =  4096 ;  i + + ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									    ss - > gamma_table [ i ]  =  * ( ( SANE_Int  * )  v  +  i ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									  break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  SANE_ACTION_GET_VALUE : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									  for  ( i  =  0 ;  i  ! =  4096 ;  i + + ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									    * ( ( SANE_Int  * )  v  +  i )  =  ss - > gamma_table [ i ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									  break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  SANE_ACTION_SET_AUTO : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									  pixma_fill_gamma_table  ( AUTO_GAMMA ,  ss - > gamma_table , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												  sizeof  ( ss - > gamma_table ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									  break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									default : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									  return  SANE_STATUS_UNSUPPORTED ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      return  SANE_STATUS_GOOD ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    case  opt_button_update : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      if  ( a  = =  SANE_ACTION_SET_VALUE ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									  update_button_state  ( ss ,  info ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									  return  SANE_STATUS_GOOD ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      else 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									  return  SANE_STATUS_INVAL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  switch  ( SOD  ( n ) . type ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    case  SANE_TYPE_BOOL : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    case  SANE_TYPE_INT : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    case  SANE_TYPE_FIXED : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      result  =  control_scalar_option  ( ss ,  n ,  a ,  v ,  info ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    case  SANE_TYPE_STRING : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      result  =  control_string_option  ( ss ,  n ,  a ,  v ,  info ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    case  SANE_TYPE_BUTTON : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    case  SANE_TYPE_GROUP : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      PDBG  ( pixma_dbg  ( 1 ,  " BUG:control_option():Unhandled option \n " ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      result  =  SANE_STATUS_INVAL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  if  ( result  ! =  SANE_STATUS_GOOD ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    return  result ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  switch  ( n ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    case  opt_custom_gamma : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      if  ( a  = =  SANE_ACTION_SET_VALUE  | |  a  = =  SANE_ACTION_SET_AUTO ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									  SANE_Word  save  =  SOD  ( opt_gamma_table ) . cap ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									  if  ( OVAL  ( opt_custom_gamma ) . b ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									    SOD  ( opt_gamma_table ) . cap  & =  ~ SANE_CAP_INACTIVE ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									  else 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									    SOD  ( opt_gamma_table ) . cap  | =  SANE_CAP_INACTIVE ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									  if  ( save  ! =  SOD  ( opt_gamma_table ) . cap ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									    * info  | =  SANE_INFO_RELOAD_OPTIONS ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  return  result ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# ifndef NDEBUG 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  void  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								print_scan_param  ( int  level ,  const  pixma_scan_param_t  *  sp )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  pixma_dbg  ( level ,  " Scan parameters \n " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  pixma_dbg  ( level ,  "   line_size=%u image_size=%u channels=%u depth=%u \n " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									     sp - > line_size ,  sp - > image_size ,  sp - > channels ,  sp - > depth ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  pixma_dbg  ( level ,  "   dpi=%ux%u offset=(%u,%u) dimension=%ux%u \n " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									     sp - > xdpi ,  sp - > ydpi ,  sp - > x ,  sp - > y ,  sp - > w ,  sp - > h ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  pixma_dbg  ( level ,  "   gamma_table=%p source=%d \n " ,  sp - > gamma_table , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									     sp - > source ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# endif 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								calc_scan_param  ( pixma_sane_t  *  ss ,  pixma_scan_param_t  *  sp )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  int  x1 ,  y1 ,  x2 ,  y2 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  int  error ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  memset  ( sp ,  0 ,  sizeof  ( * sp ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  sp - > channels  =  ( OVAL  ( opt_mode ) . w  = =  0 )  ?  3  :  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  sp - > xdpi  =  sp - > ydpi  =  OVAL  ( opt_resolution ) . w ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# define PIXEL(x,dpi) (int)((SANE_UNFIX(x)  /  25.4 * (dpi)) + 0.5) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  x1  =  PIXEL  ( OVAL  ( opt_tl_x ) . w ,  sp - > xdpi ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  x2  =  PIXEL  ( OVAL  ( opt_br_x ) . w ,  sp - > xdpi ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  if  ( x2  <  x1 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      int  temp  =  x1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      x1  =  x2 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      x2  =  temp ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  y1  =  PIXEL  ( OVAL  ( opt_tl_y ) . w ,  sp - > ydpi ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  y2  =  PIXEL  ( OVAL  ( opt_br_y ) . w ,  sp - > ydpi ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  if  ( y2  <  y1 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      int  temp  =  y1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      y1  =  y2 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      y2  =  temp ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# undef PIXEL 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  sp - > x  =  x1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  sp - > y  =  y1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  sp - > w  =  x2  -  x1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  sp - > h  =  y2  -  y1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  if  ( sp - > w  = =  0 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    sp - > w  =  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  if  ( sp - > h  = =  0 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    sp - > h  =  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  sp - > gamma_table  =  ( OVAL  ( opt_custom_gamma ) . b )  ?  ss - > gamma_table  :  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  sp - > source  =  ss - > source_map [ OVAL  ( opt_source ) . w ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  error  =  pixma_check_scan_param  ( ss - > s ,  sp ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  if  ( error  <  0 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      PDBG  ( pixma_dbg  ( 1 ,  " BUG:calc_scan_param():%s \n " ,  strerror  ( - error ) ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      PDBG  ( print_scan_param  ( 1 ,  sp ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  return  error ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  void  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								init_option_descriptors  ( pixma_sane_t  *  ss )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  const  pixma_config_t  * cfg ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  int  i ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  cfg  =  pixma_get_config  ( ss - > s ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  /* setup range for the scan area. */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  ss - > xrange . min  =  SANE_FIX  ( 0 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  ss - > xrange . max  =  SANE_FIX  ( cfg - > width  /  75.0  *  25.4 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  ss - > xrange . quant  =  SANE_FIX  ( 0 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  ss - > yrange . min  =  SANE_FIX  ( 0 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  ss - > yrange . max  =  SANE_FIX  ( cfg - > height  /  75.0  *  25.4 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  ss - > yrange . quant  =  SANE_FIX  ( 0 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  /* setup dpi up to the value supported by the scanner. */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  i  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  do 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      i + + ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      ss - > dpi_list [ i ]  =  75  *  ( 1  < <  ( i  -  1 ) ) ; 	/* 75 x 2^(i-1) */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  while  ( ( unsigned )  ss - > dpi_list [ i ]  ! =  cfg - > xdpi ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  ss - > dpi_list [ 0 ]  =  i ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  /* mode_list and source_list were already NULL-terminated,
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								   *  because  the  whole  pixma_sane_t  was  cleared  during  allocation .  */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  /* setup available mode. */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  ss - > mode_list [ 0 ]  =  SANE_I18N  ( " Color " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  if  ( cfg - > cap  &  PIXMA_CAP_GRAY ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      ss - > mode_list [ 1 ]  =  SANE_I18N  ( " Gray " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  /* setup paper source */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  i  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  ss - > source_list [ i ]  =  SANE_I18N  ( " Flatbed " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  ss - > source_map [ i ]  =  PIXMA_SOURCE_FLATBED ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  i + + ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  if  ( cfg - > cap  &  PIXMA_CAP_ADF ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      ss - > source_list [ i ]  =  SANE_I18N  ( " Automatic Document Feeder " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      ss - > source_map [ i ]  =  PIXMA_SOURCE_ADF ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      i + + ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  build_option_descriptors  ( ss ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  /* Enable options that are available only in some scanners. */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  if  ( cfg - > cap  &  PIXMA_CAP_GAMMA_TABLE ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      SOD  ( opt_custom_gamma ) . cap  & =  ~ SANE_CAP_INACTIVE ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      sane_control_option  ( ss ,  opt_custom_gamma ,  SANE_ACTION_SET_AUTO , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											   NULL ,  NULL ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      pixma_fill_gamma_table  ( AUTO_GAMMA ,  ss - > gamma_table ,  4096 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  if  ( cfg - > cap  &  PIXMA_CAP_EVENTS ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    SOD  ( opt_button_controlled ) . cap  & =  ~ SANE_CAP_INACTIVE ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# ifndef RETSIGTYPE 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# define RETSIGTYPE void 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# endif 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/* Writing to reader_ss outside reader_process() is a BUG! */  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  pixma_sane_t  * reader_ss  =  NULL ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  RETSIGTYPE  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								reader_signal_handler  ( int  sig )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  UNUSED  ( sig ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  if  ( reader_ss ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      reader_ss - > reader_stop  =  SANE_TRUE ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      pixma_cancel  ( reader_ss - > s ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								write_all  ( pixma_sane_t  *  ss ,  void  * buf_ ,  size_t  size )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  uint8_t  * buf  =  ( uint8_t  * )  buf_ ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  int  count ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  while  ( size  ! =  0  & &  ! ss - > reader_stop ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      count  =  write  ( ss - > wpipe ,  buf ,  size ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      if  ( count  = =  - 1  & &  errno  ! =  EINTR ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      if  ( count  = =  - 1  & &  errno  = =  EINTR ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      buf  + =  count ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      size  - =  count ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  return  buf  -  ( uint8_t  * )  buf_ ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/* NOTE: reader_loop() runs either in a separate thread or process. */  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  SANE_Status  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								reader_loop  ( pixma_sane_t  *  ss )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  void  * buf ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  unsigned  bufsize ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  int  count  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  PDBG  ( pixma_dbg  ( 3 ,  " Reader task started \n " ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  bufsize  =  ss - > sp . line_size  +  1 ; 	/* XXX: "odd" bufsize for testing pixma_read_image() */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  buf  =  malloc  ( bufsize ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  if  ( ! buf ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      count  =  - ENOMEM ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      goto  done ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  pixma_enable_background  ( ss - > s ,  1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  if  ( OVAL  ( opt_button_controlled ) . b  & &  ss - > page_count  = =  0 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      int  start  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# ifndef NDEBUG 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      pixma_dbg  ( 1 ,  " ==== Button-controlled scan mode is enabled. \n " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      pixma_dbg  ( 1 ,  " ==== To proceed, presse 'SCAN' or 'COLOR' button.  " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 " To cancel, press 'GRAY' button. \n " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# endif 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      while  ( pixma_wait_event  ( ss - > s ,  10 )  ! =  0 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      while  ( ! start ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									  uint32_t  events ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									  if  ( ss - > reader_stop ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									    { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									      count  =  - ECANCELED ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									      goto  done ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									  events  =  pixma_wait_event  ( ss - > s ,  1000 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									  switch  ( events  &  ~ PIXMA_EV_ACTION_MASK ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									    { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									    case  PIXMA_EV_BUTTON1 : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									      start  =  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									      break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									    case  PIXMA_EV_BUTTON2 : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									      count  =  - ENODATA ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									      goto  done ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  count  =  pixma_scan  ( ss - > s ,  & ss - > sp ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  if  ( count  > =  0 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      while  ( ( count  =  pixma_read_image  ( ss - > s ,  buf ,  bufsize ) )  >  0 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									  if  ( write_all  ( ss ,  buf ,  count )  ! =  count ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									    pixma_cancel  ( ss - > s ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								done :  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  pixma_enable_background  ( ss - > s ,  0 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  free  ( buf ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  close  ( ss - > wpipe ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  ss - > wpipe  =  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  if  ( count  > =  0 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      PDBG  ( pixma_dbg  ( 3 ,  " Reader task terminated \n " ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  else 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      PDBG  ( pixma_dbg  ( 2 ,  " Reader task terminated: %s \n " ,  strerror  ( - count ) ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  return  map_error  ( count ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								reader_process  ( void  * arg )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  pixma_sane_t  * ss  =  ( pixma_sane_t  * )  arg ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  struct  sigaction  sa ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  reader_ss  =  ss ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  memset  ( & sa ,  0 ,  sizeof  ( sa ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  sigemptyset  ( & sa . sa_mask ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  sa . sa_handler  =  reader_signal_handler ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  /* FIXME: which signal else? */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  sigaction  ( SIGHUP ,  & sa ,  NULL ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  sigaction  ( SIGINT ,  & sa ,  NULL ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  sigaction  ( SIGPIPE ,  & sa ,  NULL ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  sigaction  ( SIGTERM ,  & sa ,  NULL ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  close  ( ss - > rpipe ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  ss - > rpipe  =  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  return  reader_loop  ( ss ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								reader_thread  ( void  * arg )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  pixma_sane_t  * ss  =  ( pixma_sane_t  * )  arg ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# ifdef USE_PTHREAD 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  /* Block SIGPIPE. We will handle this in reader_loop() by checking
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								     ss - > reader_stop  and  the  return  value  from  write ( ) .  */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  sigset_t  sigs ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  sigemptyset  ( & sigs ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  sigaddset  ( & sigs ,  SIGPIPE ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  pthread_sigmask  ( SIG_BLOCK ,  & sigs ,  NULL ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# endif 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  return  reader_loop  ( ss ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								terminate_reader_task  ( pixma_sane_t  *  ss ,  int  * exit_code )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  int  result ,  pid ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  int  status  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  pid  =  ss - > reader_taskid ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  if  ( pid  < =  0 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    return  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  if  ( sanei_thread_is_forked  ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      sanei_thread_kill  ( pid ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  else 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      ss - > reader_stop  =  SANE_TRUE ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      pixma_cancel  ( ss - > s ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  result  =  sanei_thread_waitpid  ( pid ,  & status ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  ss - > reader_taskid  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  if  ( result  = =  pid ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      if  ( exit_code ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									* exit_code  =  status ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      return  pid ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  else 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      PDBG  ( pixma_dbg  ( 1 ,  " WARNING:waitpid() failed:%s \n " ,  strerror  ( errno ) ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      return  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								start_reader_task  ( pixma_sane_t  *  ss )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  int  fds [ 2 ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  int  pid ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  int  is_forked ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  if  ( ss - > rpipe  ! =  - 1  | |  ss - > wpipe  ! =  - 1 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      PDBG  ( pixma_dbg 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									    ( 1 ,  " BUG:rpipe = %d, wpipe = %d \n " ,  ss - > rpipe ,  ss - > wpipe ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      close  ( ss - > rpipe ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      close  ( ss - > wpipe ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      ss - > rpipe  =  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      ss - > wpipe  =  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  if  ( ss - > reader_taskid  >  0 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      PDBG  ( pixma_dbg  ( 1 ,  " BUG:reader_taskid(%d) != 0 \n " ,  ss - > reader_taskid ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      terminate_reader_task  ( ss ,  NULL ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  if  ( pipe  ( fds )  = =  - 1 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      PDBG  ( pixma_dbg  ( 1 ,  " ERROR:start_reader_task():pipe() failed %s \n " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										       strerror  ( errno ) ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      return  - ENOMEM ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  ss - > rpipe  =  fds [ 0 ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  ss - > wpipe  =  fds [ 1 ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  ss - > reader_stop  =  SANE_FALSE ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  is_forked  =  sanei_thread_is_forked  ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  if  ( is_forked ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      pid  =  sanei_thread_begin  ( reader_process ,  ss ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      if  ( pid  >  0 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									  close  ( ss - > wpipe ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									  ss - > wpipe  =  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  else 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      pid  =  sanei_thread_begin  ( reader_thread ,  ss ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  if  ( pid  = =  - 1 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      close  ( ss - > wpipe ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      close  ( ss - > rpipe ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      ss - > wpipe  =  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      ss - > rpipe  =  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      PDBG  ( pixma_dbg  ( 1 ,  " ERROR:unable to start reader task \n " ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      return  - ENOMEM ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  PDBG  ( pixma_dbg  ( 3 ,  " Reader task id=%d (%s) \n " ,  pid , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										   ( is_forked )  ?  " forked "  :  " threaded " ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  ss - > reader_taskid  =  pid ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  return  pid ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  SANE_Status  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								read_image  ( pixma_sane_t  *  ss ,  void  * buf ,  unsigned  size ,  int  * readlen )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  int  count ,  status ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  if  ( readlen ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    * readlen  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  if  ( ss - > image_bytes_read  > =  ss - > sp . image_size ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    return  SANE_STATUS_EOF ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  do 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      if  ( ss - > cancel ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/* ss->rpipe has already been closed by sane_cancel(). */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  SANE_STATUS_CANCELLED ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      count  =  read  ( ss - > rpipe ,  buf ,  size ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  while  ( count  = =  - 1  & &  errno  = =  EINTR ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  if  ( count  = =  - 1 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      if  ( errno  = =  EAGAIN ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  SANE_STATUS_GOOD ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      if  ( ! ss - > cancel ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									  PDBG  ( pixma_dbg  ( 1 ,  " WARNING:read_image():read() failed %s \n " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											   strerror  ( errno ) ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      close  ( ss - > rpipe ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      ss - > rpipe  =  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      terminate_reader_task  ( ss ,  NULL ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      return  SANE_STATUS_IO_ERROR ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  /* here count >= 0 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  ss - > image_bytes_read  + =  count ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  if  ( ss - > image_bytes_read  >  ss - > sp . image_size ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      PDBG  ( pixma_dbg  ( 1 ,  " BUG:ss->image_bytes_read > ss->sp.image_size \n " ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  if  ( ss - > image_bytes_read  > =  ss - > sp . image_size ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      close  ( ss - > rpipe ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      ss - > rpipe  =  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      terminate_reader_task  ( ss ,  NULL ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  else  if  ( count  = =  0 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      PDBG  ( pixma_dbg  ( 3 ,  " read_image():reader task closed the pipe: " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										       " %u bytes received, %u bytes expected \n " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										       ss - > image_bytes_read ,  ss - > sp . image_size ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      close  ( ss - > rpipe ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      ss - > rpipe  =  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      count  =  terminate_reader_task  ( ss ,  & status ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      return  ( count  >  0 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									      & &  status  ! =  SANE_STATUS_GOOD )  ?  status  :  SANE_STATUS_IO_ERROR ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  if  ( readlen ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    * readlen  =  count ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  return  SANE_STATUS_GOOD ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/*******************************************************************
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 * *  SANE  API 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								SANE_Status  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								sane_init  ( SANE_Int  *  version_code ,  SANE_Auth_Callback  authorize )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  int  status ,  myversion ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  UNUSED  ( authorize ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  if  ( ! version_code ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    return  SANE_STATUS_INVAL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  myversion  =  100  *  PIXMA_VERSION_MAJOR  +  PIXMA_VERSION_MINOR ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  * version_code  =  SANE_VERSION_CODE  ( V_MAJOR ,  V_MINOR ,  myversion ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  DBG_INIT  ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  sanei_thread_init  ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  pixma_set_debug_level  ( DBG_LEVEL ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  status  =  pixma_init  ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  if  ( status  <  0 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      PDBG  ( pixma_dbg  ( 2 ,  " pixma_init() returned %s \n " ,  strerror  ( - status ) ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  return  map_error  ( status ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								sane_exit  ( void )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  while  ( first_scanner ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    sane_close  ( first_scanner ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  cleanup_device_list  ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  pixma_cleanup  ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								SANE_Status  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								sane_get_devices  ( const  SANE_Device  * * *  device_list ,  SANE_Bool  local_only )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  UNUSED  ( local_only ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  if  ( ! device_list ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    return  SANE_STATUS_INVAL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  find_scanners  ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  * device_list  =  dev_list ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  return  ( dev_list )  ?  SANE_STATUS_GOOD  :  SANE_STATUS_NO_MEM ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								SANE_Status  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								sane_open  ( SANE_String_Const  name ,  SANE_Handle  *  h )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  unsigned  i ,  nscanners ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  int  error  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  pixma_sane_t  * ss  =  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  const  pixma_config_t  * cfg ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  if  ( ! name  | |  ! h ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    return  SANE_STATUS_INVAL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  * h  =  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  nscanners  =  pixma_find_scanners  ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  if  ( nscanners  = =  0 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    return  SANE_STATUS_INVAL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  if  ( name [ 0 ]  = =  ' \0 ' ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    name  =  pixma_get_device_id  ( 0 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  /* Have we already opened the scanner? */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  for  ( ss  =  first_scanner ;  ss ;  ss  =  ss - > next ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      if  ( strcmp  ( pixma_get_string  ( ss - > s ,  PIXMA_STRING_ID ) ,  name )  = =  0 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									  /* We have already opened it! */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									  return  SANE_STATUS_DEVICE_BUSY ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  i  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  while  ( strcmp  ( pixma_get_device_id  ( i ) ,  name )  ! =  0 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      if  ( + + i  > =  nscanners ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  SANE_STATUS_INVAL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  cfg  =  pixma_get_device_config  ( i ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  if  ( ( cfg - > cap  &  PIXMA_CAP_EXPERIMENT )  ! =  0 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# ifndef NDEBUG 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      pixma_dbg  ( 1 ,  " WARNING: " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 " Experimental backend CAN DAMAGE your hardware! \n " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      if  ( getenv_atoi  ( " PIXMA_EXPERIMENT " ,  0 )  = =  0 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									  pixma_dbg  ( 1 ,  " Experimental SANE backend for %s is disabled  " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										     " by default. \n " ,  pixma_get_device_model  ( i ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									  pixma_dbg  ( 1 ,  " To enable it, set the environment variable  " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										     " PIXMA_EXPERIMENT to non-zero. \n " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									  return  SANE_STATUS_UNSUPPORTED ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# else 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      return  SANE_STATUS_UNSUPPORTED ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# endif 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  ss  =  ( pixma_sane_t  * )  calloc  ( 1 ,  sizeof  ( * ss ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  if  ( ! ss ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    return  SANE_STATUS_NO_MEM ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  ss - > next  =  first_scanner ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  first_scanner  =  ss ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  ss - > wpipe  =  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  ss - > rpipe  =  - 1 ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-06-03 00:37:11 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  ss - > idle  =  SANE_TRUE ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  ss - > scanning  =  SANE_FALSE ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-05-26 07:49:24 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  error  =  pixma_open  ( i ,  & ss - > s ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  if  ( error  <  0 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      PDBG  ( pixma_dbg  ( 2 ,  " pixma_open() returned %s \n " ,  strerror  ( - error ) ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      sane_close  ( ss ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      return  map_error  ( error ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  pixma_enable_background  ( ss - > s ,  0 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  init_option_descriptors  ( ss ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  * h  =  ss ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  return  SANE_STATUS_GOOD ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								sane_close  ( SANE_Handle  h )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  pixma_sane_t  * * p ,  * ss ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  for  ( p  =  & first_scanner ;  * p  & &  * p  ! =  ( pixma_sane_t  * )  h ;  p  =  & ( ( * p ) - > next ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  if  ( ! ( * p ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  ss  =  * p ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  sane_cancel  ( ss ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  pixma_close  ( ss - > s ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  * p  =  ss - > next ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  free  ( ss ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								const  SANE_Option_Descriptor  *  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								sane_get_option_descriptor  ( SANE_Handle  h ,  SANE_Int  n )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  DECL_CTX ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  if  ( ss  & &  0  < =  n  & &  n  <  opt_last ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    return  & SOD  ( n ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  return  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								SANE_Status  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								sane_control_option  ( SANE_Handle  h ,  SANE_Int  n ,  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										     SANE_Action  a ,  void  * v ,  SANE_Int  *  i ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  DECL_CTX ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  SANE_Int  info  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  int  error ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  option_descriptor_t  * opt ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  if  ( i ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    * i  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  if  ( ! ss ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    return  SANE_STATUS_INVAL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  if  ( n  <  0  | |  n  > =  opt_last ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    return  SANE_STATUS_UNSUPPORTED ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  if  ( ! ss - > idle  & &  a  ! =  SANE_ACTION_GET_VALUE ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    return  SANE_STATUS_INVAL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  opt  =  & ( OPT_IN_CTX [ n ] ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  if  ( ! SANE_OPTION_IS_ACTIVE  ( opt - > sod . cap ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    return  SANE_STATUS_INVAL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  switch  ( a ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    case  SANE_ACTION_SET_VALUE : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      if  ( ( opt - > sod . type  ! =  SANE_TYPE_BUTTON  & &  ! v )  | | 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									  ! SANE_OPTION_IS_SETTABLE  ( opt - > sod . cap ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  SANE_STATUS_INVAL ; 	/* or _UNSUPPORTED? */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    case  SANE_ACTION_SET_AUTO : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      if  ( ! ( opt - > sod . cap  &  SANE_CAP_AUTOMATIC )  | | 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									  ! SANE_OPTION_IS_SETTABLE  ( opt - > sod . cap ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  SANE_STATUS_INVAL ; 	/* or _UNSUPPORTED? */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    case  SANE_ACTION_GET_VALUE : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      if  ( ! v  | |  ! ( opt - > sod . cap  &  SANE_CAP_SOFT_DETECT ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  SANE_STATUS_INVAL ; 	/* or _UNSUPPORTED? */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    default : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      return  SANE_STATUS_UNSUPPORTED ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  error  =  control_option  ( ss ,  n ,  a ,  v ,  & info ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  if  ( error  = =  SANE_STATUS_GOOD  & &  i ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    * i  =  info ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  return  error ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								SANE_Status  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								sane_get_parameters  ( SANE_Handle  h ,  SANE_Parameters  *  p )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  DECL_CTX ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  pixma_scan_param_t  temp ,  * sp ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  if  ( ! ss  | |  ! p ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    return  SANE_STATUS_INVAL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  if  ( ! ss - > idle ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      sp  =  & ss - > sp ; 		/* sp is calculated in sane_start() */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  else 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      calc_scan_param  ( ss ,  & temp ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      sp  =  & temp ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  p - > format  =  ( sp - > channels  = =  3 )  ?  SANE_FRAME_RGB  :  SANE_FRAME_GRAY ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  p - > last_frame  =  SANE_TRUE ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  p - > lines  =  sp - > h ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  p - > depth  =  sp - > depth ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  p - > pixels_per_line  =  sp - > w ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  /* p->bytes_per_line = sp->line_size; NOTE: It should work this way, but it doesn't. No SANE frontend can cope with this. */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  p - > bytes_per_line  =  sp - > w  *  sp - > channels  *  ( sp - > depth  /  8 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  return  SANE_STATUS_GOOD ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								SANE_Status  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								sane_start  ( SANE_Handle  h )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  DECL_CTX ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  int  error  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  if  ( ! ss ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    return  SANE_STATUS_INVAL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  if  ( ! ss - > idle  & &  ss - > scanning ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    return  SANE_STATUS_INVAL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  ss - > cancel  =  SANE_FALSE ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  if  ( calc_scan_param  ( ss ,  & ss - > sp )  <  0 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    return  SANE_STATUS_INVAL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  ss - > image_bytes_read  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  /* TODO: Check paper here in sane_start(). A function like
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								     pixma_get_status ( )  is  needed .  */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  error  =  start_reader_task  ( ss ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  if  ( error  > =  0 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      ss - > output_line_size  =  ss - > sp . w  *  ss - > sp . channels  *  ( ss - > sp . depth  /  8 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      ss - > byte_pos_in_line  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      if  ( ss - > idle  | |  ss - > source_map [ OVAL  ( opt_source ) . w ]  ! =  PIXMA_SOURCE_ADF ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ss - > page_count  =  0 ; 	/* start from idle state or scan from flatbed or TPU */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      else 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ss - > page_count + + ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      ss - > last_read_status  =  SANE_STATUS_GOOD ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      ss - > scanning  =  SANE_TRUE ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      ss - > idle  =  SANE_FALSE ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  return  map_error  ( error ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								SANE_Status  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								sane_read  ( SANE_Handle  h ,  SANE_Byte  *  buf ,  SANE_Int  maxlen ,  SANE_Int  *  len )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  DECL_CTX ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  int  sum ,  n ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  SANE_Byte  temp [ 16 ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  SANE_Status  status ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  if  ( len ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    * len  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  if  ( ! ss  | |  ! buf  | |  ! len ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    return  SANE_STATUS_INVAL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  if  ( ss - > cancel ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    return  SANE_STATUS_CANCELLED ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  if  ( ss - > idle ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    return  SANE_STATUS_INVAL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  if  ( ! ss - > scanning ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    return  ss - > last_read_status ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  status  =  SANE_STATUS_GOOD ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  if  ( ( ss - > sp . line_size  -  ss - > output_line_size )  = =  0 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      status  =  read_image  ( ss ,  buf ,  maxlen ,  & sum ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  else 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      /* FIXME: Because there is no frontend that can cope with padding at
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								         the  end  of  line ,  we ' ve  to  remove  it  here  in  the  backend !  */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      sum  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      while  ( sum  <  maxlen ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									  if  ( ss - > byte_pos_in_line  <  ss - > output_line_size ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									    { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									      n  =  ss - > output_line_size  -  ss - > byte_pos_in_line ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									      if  ( ( maxlen  -  sum )  <  n ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										n  =  maxlen  -  sum ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									      status  =  read_image  ( ss ,  buf ,  n ,  & n ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									      if  ( n  = =  0 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									      sum  + =  n ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									      buf  + =  n ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									      ss - > byte_pos_in_line  + =  n ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									  else 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									    { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									      /* skip padding */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									      n  =  ss - > sp . line_size  -  ss - > byte_pos_in_line ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									      status  =  read_image  ( ss ,  temp ,  n ,  & n ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									      if  ( n  = =  0 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									      ss - > byte_pos_in_line  + =  n ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									      if  ( ss - > byte_pos_in_line  = =  ss - > sp . line_size ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ss - > byte_pos_in_line  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  if  ( ss - > cancel ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    status  =  SANE_STATUS_CANCELLED ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  else  if  ( ( status  = =  SANE_STATUS_GOOD  | |  status  = =  SANE_STATUS_EOF )  & & 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									   sum  >  0 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      * len  =  sum ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      status  =  SANE_STATUS_GOOD ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  ss - > scanning  =  ( status  = =  SANE_STATUS_GOOD ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  ss - > last_read_status  =  status ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  return  status ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								sane_cancel  ( SANE_Handle  h )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  DECL_CTX ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  if  ( ! ss ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  ss - > cancel  =  SANE_TRUE ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  if  ( ss - > idle ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  close  ( ss - > rpipe ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  ss - > rpipe  =  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  terminate_reader_task  ( ss ,  NULL ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  ss - > idle  =  SANE_TRUE ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								SANE_Status  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								sane_set_io_mode  ( SANE_Handle  h ,  SANE_Bool  m )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  DECL_CTX ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  if  ( ! ss  | |  ss - > idle  | |  ss - > rpipe  = =  - 1 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    return  SANE_STATUS_INVAL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# ifdef HAVE_FCNTL_H 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  PDBG  ( pixma_dbg  ( 2 ,  " Setting %sblocking mode \n " ,  ( m )  ?  " non- "  :  " " ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  if  ( fcntl  ( ss - > rpipe ,  F_SETFL ,  ( m )  ?  O_NONBLOCK  :  0 )  = =  - 1 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      PDBG  ( pixma_dbg  ( 1 ,  " WARNING:fcntl(F_SETFL):%s \n " ,  strerror  ( errno ) ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      return  SANE_STATUS_UNSUPPORTED ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  return  SANE_STATUS_GOOD ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# else 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  return  ( m )  ?  SANE_STATUS_UNSUPPORTED  :  SANE_STATUS_GOOD ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# endif 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								SANE_Status  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								sane_get_select_fd  ( SANE_Handle  h ,  SANE_Int  *  fd )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  DECL_CTX ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  * fd  =  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  if  ( ! ss  | |  ! fd  | |  ss - > idle  | |  ss - > rpipe  = =  - 1 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    return  SANE_STATUS_INVAL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  * fd  =  ss - > rpipe ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  return  SANE_STATUS_GOOD ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/*
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								BEGIN  SANE_Option_Descriptor  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								rem  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								type  group  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  title  Scan  mode 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								type  int  resolution  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  unit  dpi 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  constraint  @ word_list  =  ss - > dpi_list 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  default  75 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  title  @ SANE_TITLE_SCAN_RESOLUTION 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  desc   @ SANE_DESC_SCAN_RESOLUTION 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  cap  soft_select  soft_detect  automatic 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  info  reload_params 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								type  string  mode [ 10 ]  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  default  Color 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  constraint  @ string_list  =  ss - > mode_list 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  title  @ SANE_TITLE_SCAN_MODE 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  desc   @ SANE_DESC_SCAN_MODE 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  cap  soft_select  soft_detect  automatic 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  info  reload_params 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								type  string  source [ 30 ]  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  constraint  @ string_list  =  ss - > source_list 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  title  @ SANE_TITLE_SCAN_SOURCE 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  desc   @ SANE_DESC_SCAN_SOURCE 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  default  Flatbed 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  cap  soft_select  soft_detect 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								type  bool  button - controlled  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  title  Button - controlled  scan  ( experimental ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  desc  When  enabled ,  scan  process  will  not  start  immediately .  To  proceed ,  press  \ " SCAN \"  button (for MP150) or  \" COLOR \"  button (for other models). To cancel, press  \" GRAY \"  button. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  default  SANE_FALSE 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  cap  soft_select  soft_detect  inactive 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								rem  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								type  group  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  title  Gamma 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								type  bool  custom - gamma  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  default  SANE_TRUE 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  title  @ SANE_TITLE_CUSTOM_GAMMA 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  desc   @ SANE_DESC_CUSTOM_GAMMA 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  cap  soft_select  soft_detect  automatic  inactive 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								type  int  gamma - table [ 4096 ]  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  constraint  ( 0 , 255 , 0 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  title  @ SANE_TITLE_GAMMA_VECTOR 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  desc   @ SANE_DESC_GAMMA_VECTOR 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  cap  soft_select  soft_detect  automatic  inactive 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								rem  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								type  group  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  title  Geometry 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								type  fixed  tl - x  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  unit  mm 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  default  0 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  constraint  @ range  =  & ss - > xrange 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  title  @ SANE_TITLE_SCAN_TL_X 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  desc   @ SANE_DESC_SCAN_TL_X 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  cap  soft_select  soft_detect  automatic 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  info  reload_params 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								type  fixed  tl - y  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  unit  mm 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  default  0 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  constraint  @ range  =  & ss - > yrange 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  title  @ SANE_TITLE_SCAN_TL_Y 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  desc   @ SANE_DESC_SCAN_TL_Y 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  cap  soft_select  soft_detect  automatic 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  info  reload_params 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								type  fixed  br - x  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  unit  mm 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  default  _MAX 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  constraint  @ range  =  & ss - > xrange 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  title  @ SANE_TITLE_SCAN_BR_X 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  desc   @ SANE_DESC_SCAN_BR_X 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  cap  soft_select  soft_detect  automatic 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  info  reload_params 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								type  fixed  br - y  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  unit  mm 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  default  _MAX 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  constraint  @ range  =  & ss - > yrange 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  title  @ SANE_TITLE_SCAN_BR_Y 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  desc   @ SANE_DESC_SCAN_BR_Y 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  cap  soft_select  soft_detect  automatic 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  info  reload_params 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								rem  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								type  group  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  title  Buttons 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								type  button  button - update  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  title  Update  button  state 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  cap  soft_select  soft_detect  advanced 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								type  int  button - 1  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  default  0 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  title  Button  1 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  cap  soft_select  soft_detect  advanced 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								type  int  button - 2  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  default  0 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  title  Button  2 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  cap  soft_select  soft_detect  advanced 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								rem  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								END  SANE_Option_Descriptor  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								*/  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  "pixma_sane_options.c"	/* generated by gen_options.py */