• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* sane - Scanner Access Now Easy.
2 
3    Copyright (C) 2002, Nathan Rutman <nathan@gordian.com>
4    Copyright (C) 2001, Marcio Luis Teixeira
5 
6    Parts copyright (C) 1996, 1997 Andreas Beck
7    Parts copyright (C) 2000, 2001 Michael Herder <crapsite@gmx.net>
8    Parts copyright (C) 2001 Henning Meier-Geinitz <henning@meier-geinitz.de>
9 
10    This program is free software; you can redistribute it and/or
11    modify it under the terms of the GNU General Public License as
12    published by the Free Software Foundation; either version 2 of the
13    License, or (at your option) any later version.
14 
15    This program is distributed in the hope that it will be useful, but
16    WITHOUT ANY WARRANTY; without even the implied warranty of
17    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
18    General Public License for more details.
19 
20    You should have received a copy of the GNU General Public License
21    along with this program.  If not, see <https://www.gnu.org/licenses/>.
22 
23    As a special exception, the authors of SANE give permission for
24    additional uses of the libraries contained in this release of SANE.
25 
26    The exception is that, if you link a SANE library with other files
27    to produce an executable, this does not by itself cause the
28    resulting executable to be covered by the GNU General Public
29    License.  Your use of that executable is in no way restricted on
30    account of linking the SANE library code into it.
31 
32    This exception does not, however, invalidate any other reasons why
33    the executable file might be covered by the GNU General Public
34    License.
35 
36    If you submit changes to SANE to the maintainers to be included in
37    a subsequent release, you agree by submitting the changes that
38    those changes may be distributed with this exception intact.
39 
40    If you write modifications of your own for SANE, it is your choice
41    whether to permit this exception to apply to your modifications.
42    If you do not wish that, delete this exception notice.  */
43 
44 #define BUILD 1
45 #define MM_IN_INCH 25.4
46 
47 #include "../include/sane/config.h"
48 
49 #include <stdlib.h>
50 #include <string.h>
51 #include <stdio.h>
52 #include <unistd.h>
53 #include <fcntl.h>
54 #include <sys/ioctl.h>
55 #include <sys/types.h>
56 
57 #include "../include/sane/sane.h"
58 #include "../include/sane/sanei.h"
59 #include "../include/sane/saneopts.h"
60 #include "../include/sane/sanei_config.h"
61 #include "../include/sane/sanei_usb.h"
62 #define BACKEND_NAME        canon630u
63 #define CANONUSB_CONFIG_FILE "canon630u.conf"
64 #include "../include/sane/sanei_backend.h"
65 
66 #include "canon630u-common.c"
67 
68 typedef struct Canon_Device
69 {
70   struct Canon_Device *next;
71   SANE_String name;
72   SANE_Device sane;
73 }
74 Canon_Device;
75 
76 typedef struct Canon_Scanner
77 {
78   struct Canon_Scanner *next;
79   Canon_Device *device;
80   CANON_Handle scan;
81 }
82 Canon_Scanner;
83 
84 static int num_devices = 0;
85 static const SANE_Device **devlist = NULL;
86 static Canon_Device *first_dev = NULL;
87 static Canon_Scanner *first_handle = NULL;
88 
89 static SANE_Parameters parms = {
90   SANE_FRAME_RGB,
91   0,
92   0,				/* Number of bytes returned per scan line: */
93   0,				/* Number of pixels per scan line.  */
94   0,				/* Number of lines for the current scan.  */
95   8				/* Number of bits per sample. */
96 };
97 
98 
99 struct _SANE_Option
100 {
101   SANE_Option_Descriptor *descriptor;
102     SANE_Status (*callback) (struct _SANE_Option * option, SANE_Handle handle,
103 			     SANE_Action action, void *value,
104 			     SANE_Int * info);
105 };
106 
107 typedef struct _SANE_Option SANE_Option;
108 
109 
110 /*-----------------------------------------------------------------*/
111 
112 static SANE_Word getNumberOfOptions (void);	/* Forward declaration */
113 
114 /*
115 This read-only option returns the number of options available for
116 the device. It should be the first option in the options array
117 declared below.
118 */
119 
120 static SANE_Option_Descriptor optionNumOptionsDescriptor = {
121   SANE_NAME_NUM_OPTIONS,
122   SANE_TITLE_NUM_OPTIONS,
123   SANE_DESC_NUM_OPTIONS,
124   SANE_TYPE_INT,
125   SANE_UNIT_NONE,
126   sizeof (SANE_Word),
127   SANE_CAP_SOFT_DETECT,
128   SANE_CONSTRAINT_NONE,
129   {NULL}
130 };
131 
132 static SANE_Status
optionNumOptionsCallback(SANE_Option * option,SANE_Handle handle,SANE_Action action,void * value,SANE_Int * info)133 optionNumOptionsCallback (SANE_Option * option, SANE_Handle handle,
134 			  SANE_Action action, void *value, SANE_Int * info)
135 {
136   (void) option;
137   (void) handle;
138   (void) info;			/* Eliminate warning about unused parameters */
139 
140   if (action != SANE_ACTION_GET_VALUE)
141     return SANE_STATUS_INVAL;
142   *(SANE_Word *) value = getNumberOfOptions ();
143   return SANE_STATUS_GOOD;
144 }
145 
146 /*-----------------------------------------------------------------*/
147 
148 /*
149 This option lets the user force scanner calibration.  Normally, this is
150 done only once, at first scan after powerup.
151  */
152 
153 static SANE_Word optionCalibrateValue = SANE_FALSE;
154 
155 static SANE_Option_Descriptor optionCalibrateDescriptor = {
156   "cal",
157   SANE_I18N ("Calibrate Scanner"),
158   SANE_I18N ("Force scanner calibration before scan"),
159   SANE_TYPE_BOOL,
160   SANE_UNIT_NONE,
161   sizeof (SANE_Word),
162   SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT,
163   SANE_CONSTRAINT_NONE,
164   {NULL}
165 };
166 
167 static SANE_Status
optionCalibrateCallback(SANE_Option * option,SANE_Handle handle,SANE_Action action,void * value,SANE_Int * info)168 optionCalibrateCallback (SANE_Option * option, SANE_Handle handle,
169 			 SANE_Action action, void *value, SANE_Int * info)
170 {
171   (void) handle;
172   (void) option;		/* Eliminate warning about unused parameters */
173 
174   switch (action)
175     {
176     case SANE_ACTION_SET_AUTO:
177       return SANE_STATUS_INVAL;
178       break;
179     case SANE_ACTION_SET_VALUE:
180       *info |= SANE_INFO_RELOAD_PARAMS;
181       optionCalibrateValue = *(SANE_Bool *) value;
182       break;
183     case SANE_ACTION_GET_VALUE:
184       *(SANE_Word *) value = optionCalibrateValue;
185       break;
186     }
187   return SANE_STATUS_GOOD;
188 }
189 
190 /*-----------------------------------------------------------------*/
191 
192 /*
193 This option lets the user select the scan resolution. The Canon fb630u
194 scanner supports the following resolutions: 75, 150, 300, 600, 1200
195 */
196 
197 static const SANE_Word optionResolutionList[] = {
198   4,				/* Number of elements */
199   75, 150, 300, 600		/* Resolution list */
200     /* also 600x1200, but ignore that for now. */
201 };
202 
203 static SANE_Option_Descriptor optionResolutionDescriptor = {
204   SANE_NAME_SCAN_RESOLUTION,
205   SANE_TITLE_SCAN_RESOLUTION,
206   SANE_DESC_SCAN_RESOLUTION,
207   SANE_TYPE_INT,
208   SANE_UNIT_DPI,
209   sizeof (SANE_Word),
210   SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT | SANE_CAP_AUTOMATIC,
211   SANE_CONSTRAINT_WORD_LIST,
212   {(const SANE_String_Const *) optionResolutionList}
213 };
214 
215 static SANE_Word optionResolutionValue = 75;
216 
217 static SANE_Status
optionResolutionCallback(SANE_Option * option,SANE_Handle handle,SANE_Action action,void * value,SANE_Int * info)218 optionResolutionCallback (SANE_Option * option, SANE_Handle handle,
219 			  SANE_Action action, void *value, SANE_Int * info)
220 {
221   SANE_Status status;
222   SANE_Word autoValue = 75;
223 
224   (void) handle;		/* Eliminate warning about unused parameters */
225 
226   switch (action)
227     {
228     case SANE_ACTION_SET_AUTO:
229       status =
230 	sanei_constrain_value (option->descriptor, (void *) &autoValue, info);
231       if (status != SANE_STATUS_GOOD)
232 	return status;
233       optionResolutionValue = autoValue;
234       *info |= SANE_INFO_RELOAD_PARAMS;
235       break;
236     case SANE_ACTION_SET_VALUE:
237       *info |= SANE_INFO_RELOAD_PARAMS;
238       optionResolutionValue = *(SANE_Word *) value;
239       break;
240     case SANE_ACTION_GET_VALUE:
241       *(SANE_Word *) value = optionResolutionValue;
242       break;
243     }
244   return SANE_STATUS_GOOD;
245 }
246 
247 /*-----------------------------------------------------------------*/
248 
249 #ifdef GRAY
250 /*
251 This option lets the user select a gray scale scan
252 */
253 static SANE_Word optionGrayscaleValue = SANE_FALSE;
254 
255 static SANE_Option_Descriptor optionGrayscaleDescriptor = {
256   "gray",
257   SANE_I18N ("Grayscale scan"),
258   SANE_I18N ("Do a grayscale rather than color scan"),
259   SANE_TYPE_BOOL,
260   SANE_UNIT_NONE,
261   sizeof (SANE_Word),
262   SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT,
263   SANE_CONSTRAINT_NONE,
264   {NULL}
265 };
266 
267 static SANE_Status
optionGrayscaleCallback(SANE_Option * option,SANE_Handle handle,SANE_Action action,void * value,SANE_Int * info)268 optionGrayscaleCallback (SANE_Option * option, SANE_Handle handle,
269 			 SANE_Action action, void *value, SANE_Int * info)
270 {
271   (void) handle;
272   (void) option;		/* Eliminate warning about unused parameters */
273 
274   switch (action)
275     {
276     case SANE_ACTION_SET_AUTO:
277       return SANE_STATUS_INVAL;
278       break;
279     case SANE_ACTION_SET_VALUE:
280       *info |= SANE_INFO_RELOAD_PARAMS;
281       optionGrayscaleValue = *(SANE_Bool *) value;
282       break;
283     case SANE_ACTION_GET_VALUE:
284       *(SANE_Word *) value = optionGrayscaleValue;
285       break;
286     }
287   return SANE_STATUS_GOOD;
288 }
289 #endif /* GRAY */
290 
291 /*-----------------------------------------------------------------*/
292 
293 /* Analog Gain setting */
294 static const SANE_Range aGainRange = {
295   0,				/* minimum */
296   64,				/* maximum */
297   1				/* quantization */
298 };
299 
300 static SANE_Int optionAGainValue = 1;
301 
302 static SANE_Option_Descriptor optionAGainDescriptor = {
303   "gain",
304   SANE_I18N ("Analog Gain"),
305   SANE_I18N ("Increase or decrease the analog gain of the CCD array"),
306   SANE_TYPE_INT,
307   SANE_UNIT_NONE,
308   sizeof (SANE_Int),
309   SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT | SANE_CAP_ADVANCED,
310   SANE_CONSTRAINT_RANGE,
311   {(const SANE_String_Const *) &aGainRange}
312 };
313 
314 static SANE_Status
optionAGainCallback(SANE_Option * option,SANE_Handle handle,SANE_Action action,void * value,SANE_Int * info)315 optionAGainCallback (SANE_Option * option, SANE_Handle handle,
316 		     SANE_Action action, void *value, SANE_Int * info)
317 {
318   (void) option;
319   (void) handle;
320   (void) info;			/* Eliminate warning about unused parameters */
321 
322   switch (action)
323     {
324     case SANE_ACTION_SET_AUTO:
325       return SANE_STATUS_INVAL;
326       break;
327     case SANE_ACTION_SET_VALUE:
328       optionAGainValue = *(SANE_Int *) value;
329       *info |= SANE_INFO_RELOAD_PARAMS;
330       break;
331     case SANE_ACTION_GET_VALUE:
332       *(SANE_Int *) value = optionAGainValue;
333       break;
334     }
335   return SANE_STATUS_GOOD;
336 }
337 
338 /*-----------------------------------------------------------------*/
339 
340 /* Scanner gamma setting */
341 static SANE_Fixed optionGammaValue = SANE_FIX (1.6);
342 
343 static SANE_Option_Descriptor optionGammaDescriptor = {
344   "gamma",
345   SANE_I18N ("Gamma Correction"),
346   SANE_I18N ("Selects the gamma corrected transfer curve"),
347   SANE_TYPE_FIXED,
348   SANE_UNIT_NONE,
349   sizeof (SANE_Int),
350   SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT | SANE_CAP_ADVANCED,
351   SANE_CONSTRAINT_NONE,
352   {NULL}
353 };
354 
355 
356 static SANE_Status
optionGammaCallback(SANE_Option * option,SANE_Handle handle,SANE_Action action,void * value,SANE_Int * info)357 optionGammaCallback (SANE_Option * option, SANE_Handle handle,
358 		     SANE_Action action, void *value, SANE_Int * info)
359 {
360   (void) option;
361   (void) handle;
362   (void) info;			/* Eliminate warning about unused parameters */
363 
364   switch (action)
365     {
366     case SANE_ACTION_SET_AUTO:
367       return SANE_STATUS_INVAL;
368       break;
369     case SANE_ACTION_SET_VALUE:
370       optionGammaValue = *(SANE_Fixed *) value;
371       *info |= SANE_INFO_RELOAD_PARAMS;
372       break;
373     case SANE_ACTION_GET_VALUE:
374       *(SANE_Fixed *) value = optionGammaValue;
375       break;
376     }
377   return SANE_STATUS_GOOD;
378 }
379 
380 /*-----------------------------------------------------------------*/
381 
382 /*
383 Scan range
384 */
385 
386 static const SANE_Range widthRange = {
387   0,				/* minimum */
388   SANE_FIX (CANON_MAX_WIDTH * MM_IN_INCH / 600),	/* maximum */
389   0				/* quantization */
390 };
391 
392 static const SANE_Range heightRange = {
393   0,				/* minimum */
394   SANE_FIX (CANON_MAX_HEIGHT * MM_IN_INCH / 600),	/* maximum */
395   0				/* quantization */
396 };
397 
398 /*-----------------------------------------------------------------*/
399 /*
400 This option controls the top-left-x corner of the scan
401 */
402 
403 static SANE_Fixed optionTopLeftXValue = 0;
404 
405 static SANE_Option_Descriptor optionTopLeftXDescriptor = {
406   SANE_NAME_SCAN_TL_X,
407   SANE_TITLE_SCAN_TL_X,
408   SANE_DESC_SCAN_TL_X,
409   SANE_TYPE_FIXED,
410   SANE_UNIT_MM,
411   sizeof (SANE_Fixed),
412   SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT,
413   SANE_CONSTRAINT_RANGE,
414   {(const SANE_String_Const *) &widthRange}
415 };
416 
417 static SANE_Status
optionTopLeftXCallback(SANE_Option * option,SANE_Handle handle,SANE_Action action,void * value,SANE_Int * info)418 optionTopLeftXCallback (SANE_Option * option, SANE_Handle handle,
419 			SANE_Action action, void *value, SANE_Int * info)
420 {
421   (void) option;
422   (void) handle;
423   (void) value;			/* Eliminate warning about unused parameters */
424 
425   switch (action)
426     {
427     case SANE_ACTION_SET_AUTO:
428       return SANE_STATUS_INVAL;
429       break;
430     case SANE_ACTION_SET_VALUE:
431       optionTopLeftXValue = *(SANE_Fixed *) value;
432       *info |= SANE_INFO_RELOAD_PARAMS;
433       break;
434     case SANE_ACTION_GET_VALUE:
435       *(SANE_Fixed *) value = optionTopLeftXValue;
436       break;
437     }
438   return SANE_STATUS_GOOD;
439 }
440 
441 /*-----------------------------------------------------------------*/
442 /*
443 This option controls the top-left-y corner of the scan
444 */
445 
446 static SANE_Fixed optionTopLeftYValue = 0;
447 
448 static SANE_Option_Descriptor optionTopLeftYDescriptor = {
449   SANE_NAME_SCAN_TL_Y,
450   SANE_TITLE_SCAN_TL_Y,
451   SANE_DESC_SCAN_TL_Y,
452   SANE_TYPE_FIXED,
453   SANE_UNIT_MM,
454   sizeof (SANE_Fixed),
455   SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT,
456   SANE_CONSTRAINT_RANGE,
457   {(const SANE_String_Const *) &heightRange}
458 };
459 
460 static SANE_Status
optionTopLeftYCallback(SANE_Option * option,SANE_Handle handle,SANE_Action action,void * value,SANE_Int * info)461 optionTopLeftYCallback (SANE_Option * option, SANE_Handle handle,
462 			SANE_Action action, void *value, SANE_Int * info)
463 {
464   /* Eliminate warnings about unused parameters */
465   (void) option;
466   (void) handle;
467 
468   switch (action)
469     {
470     case SANE_ACTION_SET_AUTO:
471       return SANE_STATUS_INVAL;
472       break;
473     case SANE_ACTION_SET_VALUE:
474       optionTopLeftYValue = *(SANE_Fixed *) value;
475       *info |= SANE_INFO_RELOAD_PARAMS;
476       break;
477     case SANE_ACTION_GET_VALUE:
478       *(SANE_Fixed *) value = optionTopLeftYValue;
479       break;
480     }
481   return SANE_STATUS_GOOD;
482 }
483 
484 /*-----------------------------------------------------------------*/
485 /*
486 This option controls the bot-right-x corner of the scan
487 Default to 215.9mm, max.
488 */
489 
490 static SANE_Fixed optionBotRightXValue = SANE_FIX (215.9);
491 
492 static SANE_Option_Descriptor optionBotRightXDescriptor = {
493   SANE_NAME_SCAN_BR_X,
494   SANE_TITLE_SCAN_BR_X,
495   SANE_DESC_SCAN_BR_X,
496   SANE_TYPE_FIXED,
497   SANE_UNIT_MM,
498   sizeof (SANE_Fixed),
499   SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT,
500   SANE_CONSTRAINT_RANGE,
501   {(const SANE_String_Const *) &widthRange}
502 };
503 
504 static SANE_Status
optionBotRightXCallback(SANE_Option * option,SANE_Handle handle,SANE_Action action,void * value,SANE_Int * info)505 optionBotRightXCallback (SANE_Option * option, SANE_Handle handle,
506 			 SANE_Action action, void *value, SANE_Int * info)
507 {
508   /* Eliminate warnings about unused parameters */
509   (void) option;
510   (void) handle;
511 
512   switch (action)
513     {
514     case SANE_ACTION_SET_AUTO:
515       return SANE_STATUS_INVAL;
516       break;
517     case SANE_ACTION_SET_VALUE:
518       optionBotRightXValue = *(SANE_Fixed *) value;
519       *info |= SANE_INFO_RELOAD_PARAMS;
520       break;
521     case SANE_ACTION_GET_VALUE:
522       *(SANE_Fixed *) value = optionBotRightXValue;
523       break;
524     }
525   return SANE_STATUS_GOOD;
526 }
527 
528 /*-----------------------------------------------------------------*/
529 /*
530 This option controls the bot-right-y corner of the scan
531 Default to 296.3mm, max
532 */
533 
534 static SANE_Fixed optionBotRightYValue = SANE_FIX (296.3);
535 
536 static SANE_Option_Descriptor optionBotRightYDescriptor = {
537   SANE_NAME_SCAN_BR_Y,
538   SANE_TITLE_SCAN_BR_Y,
539   SANE_DESC_SCAN_BR_Y,
540   SANE_TYPE_FIXED,
541   SANE_UNIT_MM,
542   sizeof (SANE_Fixed),
543   SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT,
544   SANE_CONSTRAINT_RANGE,
545   {(const SANE_String_Const *) &heightRange}
546 };
547 
548 static SANE_Status
optionBotRightYCallback(SANE_Option * option,SANE_Handle handle,SANE_Action action,void * value,SANE_Int * info)549 optionBotRightYCallback (SANE_Option * option, SANE_Handle handle,
550 			 SANE_Action action, void *value, SANE_Int * info)
551 {
552   /* Eliminate warnings about unused parameters */
553   (void) option;
554   (void) handle;
555 
556   switch (action)
557     {
558     case SANE_ACTION_SET_AUTO:
559       return SANE_STATUS_INVAL;
560       break;
561     case SANE_ACTION_SET_VALUE:
562       optionBotRightYValue = *(SANE_Fixed *) value;
563       *info |= SANE_INFO_RELOAD_PARAMS;
564       break;
565     case SANE_ACTION_GET_VALUE:
566       *(SANE_Fixed *) value = optionBotRightYValue;
567       break;
568     }
569   return SANE_STATUS_GOOD;
570 }
571 
572 /*-----------------------------------------------------------------*/
573 /*
574 The following array binds the option descriptors to
575 their respective callback routines
576 */
577 
578 static SANE_Option so[] = {
579   {&optionNumOptionsDescriptor, optionNumOptionsCallback},
580   {&optionResolutionDescriptor, optionResolutionCallback},
581   {&optionCalibrateDescriptor, optionCalibrateCallback},
582 #ifdef GRAY
583   {&optionGrayscaleDescriptor, optionGrayscaleCallback},
584 #endif
585   {&optionAGainDescriptor, optionAGainCallback},
586   {&optionGammaDescriptor, optionGammaCallback},
587   {&optionTopLeftXDescriptor, optionTopLeftXCallback},
588   {&optionTopLeftYDescriptor, optionTopLeftYCallback},
589   {&optionBotRightXDescriptor, optionBotRightXCallback},
590   {&optionBotRightYDescriptor, optionBotRightYCallback}
591 };
592 
593 static SANE_Word
getNumberOfOptions(void)594 getNumberOfOptions (void)
595 {
596   return NELEMS (so);
597 }
598 
599 
600 /*
601 This routine dispatches the control message to the appropriate
602 callback routine, it outght to be called by sane_control_option
603 after any driver specific validation.
604 */
605 static SANE_Status
dispatch_control_option(SANE_Handle handle,SANE_Int option,SANE_Action action,void * value,SANE_Int * info)606 dispatch_control_option (SANE_Handle handle, SANE_Int option,
607 			 SANE_Action action, void *value, SANE_Int * info)
608 {
609   SANE_Option *op = so + option;
610   SANE_Int myinfo = 0;
611   SANE_Status status = SANE_STATUS_GOOD;
612 
613   if (option < 0 || option >= NELEMS (so))
614     return SANE_STATUS_INVAL;	/* Unknown option ... */
615 
616   if ((action == SANE_ACTION_SET_VALUE) &&
617       ((op->descriptor->cap & SANE_CAP_SOFT_SELECT) == 0))
618     return SANE_STATUS_INVAL;
619 
620   if ((action == SANE_ACTION_GET_VALUE) &&
621       ((op->descriptor->cap & SANE_CAP_SOFT_DETECT) == 0))
622     return SANE_STATUS_INVAL;
623 
624   if ((action == SANE_ACTION_SET_AUTO) &&
625       ((op->descriptor->cap & SANE_CAP_AUTOMATIC) == 0))
626     return SANE_STATUS_INVAL;
627 
628   if (action == SANE_ACTION_SET_VALUE)
629     {
630       status = sanei_constrain_value (op->descriptor, value, &myinfo);
631       if (status != SANE_STATUS_GOOD)
632 	return status;
633     }
634 
635   status = (op->callback) (op, handle, action, value, &myinfo);
636 
637   if (info)
638     *info = myinfo;
639 
640   return status;
641 }
642 
643 
644 static SANE_Status
attach_scanner(const char * devicename,Canon_Device ** devp)645 attach_scanner (const char *devicename, Canon_Device ** devp)
646 {
647   CANON_Handle scan;
648   Canon_Device *dev;
649   SANE_Status status;
650 
651   DBG (3, "attach_scanner: %s\n", devicename);
652 
653   for (dev = first_dev; dev; dev = dev->next)
654     {
655       if (strcmp (dev->sane.name, devicename) == 0)
656 	{
657 	  if (devp)
658 	    *devp = dev;
659 	  return SANE_STATUS_GOOD;
660 	}
661     }
662 
663   dev = malloc (sizeof (*dev));
664   if (!dev)
665     return SANE_STATUS_NO_MEM;
666   memset (dev, '\0', sizeof (Canon_Device));	/* clear structure */
667 
668   DBG (4, "attach_scanner: opening %s\n", devicename);
669 
670   status = CANON_open_device (&scan, devicename);
671   if (status != SANE_STATUS_GOOD)
672     {
673       DBG (1, "ERROR: attach_scanner: opening %s failed\n", devicename);
674       free (dev);
675       return status;
676     }
677   dev->name = strdup (devicename);
678   dev->sane.name = dev->name;
679   dev->sane.vendor = "CANON";
680   dev->sane.model = CANON_get_device_name (&scan);
681   dev->sane.type = "flatbed scanner";
682   CANON_close_device (&scan);
683 
684   ++num_devices;
685   dev->next = first_dev;
686   first_dev = dev;
687 
688   if (devp)
689     *devp = dev;
690   return SANE_STATUS_GOOD;
691 }
692 
693 
694 /* callback function for sanei_usb_attach_matching_devices
695 */
696 static SANE_Status
attach_one(const char * name)697 attach_one (const char *name)
698 {
699   attach_scanner (name, 0);
700   return SANE_STATUS_GOOD;
701 }
702 
703 
704 /*
705    Find our devices
706  */
707 SANE_Status
sane_init(SANE_Int * version_code,SANE_Auth_Callback authorize)708 sane_init (SANE_Int * version_code, SANE_Auth_Callback authorize)
709 {
710   char config_line[PATH_MAX];
711   size_t len;
712   FILE *fp;
713 
714   DBG_INIT ();
715 
716 #if 0
717   DBG_LEVEL = 10;
718 #endif
719 
720   DBG (2, "sane_init: version_code %s 0, authorize %s 0\n",
721        version_code == 0 ? "=" : "!=", authorize == 0 ? "=" : "!=");
722   DBG (1, "sane_init: SANE Canon630u backend version %d.%d.%d from %s\n",
723        SANE_CURRENT_MAJOR, SANE_CURRENT_MINOR, BUILD, PACKAGE_STRING);
724 
725   if (version_code)
726     *version_code = SANE_VERSION_CODE (SANE_CURRENT_MAJOR, SANE_CURRENT_MINOR, BUILD);
727 
728   sanei_usb_init ();
729 
730   fp = sanei_config_open (CANONUSB_CONFIG_FILE);
731   if (!fp)
732     {
733       /* no config-file: try these */
734       attach_scanner ("/dev/scanner", 0);
735       attach_scanner ("/dev/usbscanner", 0);
736       attach_scanner ("/dev/usb/scanner", 0);
737       return SANE_STATUS_GOOD;
738     }
739 
740   DBG (3, "reading configure file %s\n", CANONUSB_CONFIG_FILE);
741 
742   while (sanei_config_read (config_line, sizeof (config_line), fp))
743     {
744       if (config_line[0] == '#')
745 	continue;		/* ignore line comments */
746 
747       len = strlen (config_line);
748 
749       if (!len)
750 	continue;		/* ignore empty lines */
751 
752       DBG (4, "attach_matching_devices(%s)\n", config_line);
753       sanei_usb_attach_matching_devices (config_line, attach_one);
754     }
755 
756   DBG (4, "finished reading configure file\n");
757 
758   fclose (fp);
759 
760   return SANE_STATUS_GOOD;
761 }
762 
763 
764 void
sane_exit(void)765 sane_exit (void)
766 {
767   Canon_Device *dev, *next;
768 
769   DBG (3, "sane_exit\n");
770 
771   for (dev = first_dev; dev; dev = next)
772     {
773       next = dev->next;
774       free (dev->name);
775       free (dev);
776     }
777 
778   if (devlist)
779     free (devlist);
780   return;
781 }
782 
783 
784 SANE_Status
sane_get_devices(const SANE_Device *** device_list,SANE_Bool local_only)785 sane_get_devices (const SANE_Device *** device_list, SANE_Bool local_only)
786 {
787   Canon_Device *dev;
788   int i;
789 
790   DBG (3, "sane_get_devices(local_only = %d)\n", local_only);
791 
792   if (devlist)
793     free (devlist);
794 
795   devlist = malloc ((num_devices + 1) * sizeof (devlist[0]));
796   if (!devlist)
797     return SANE_STATUS_NO_MEM;
798 
799   i = 0;
800 
801   for (dev = first_dev; i < num_devices; dev = dev->next)
802     devlist[i++] = &dev->sane;
803 
804   devlist[i++] = 0;
805 
806   *device_list = devlist;
807 
808   return SANE_STATUS_GOOD;
809 }
810 
811 
812 SANE_Status
sane_open(SANE_String_Const devicename,SANE_Handle * handle)813 sane_open (SANE_String_Const devicename, SANE_Handle * handle)
814 {
815   Canon_Device *dev;
816   SANE_Status status;
817   Canon_Scanner *scanner;
818 
819   DBG (3, "sane_open\n");
820 
821   if (devicename[0])		/* search for devicename */
822     {
823       DBG (4, "sane_open: devicename=%s\n", devicename);
824 
825       for (dev = first_dev; dev; dev = dev->next)
826 	if (strcmp (dev->sane.name, devicename) == 0)
827 	  break;
828 
829       if (!dev)
830 	{
831 	  status = attach_scanner (devicename, &dev);
832 	  if (status != SANE_STATUS_GOOD)
833 	    return status;
834 	}
835     }
836   else
837     {
838       DBG (2, "sane_open: no devicename, opening first device\n");
839       dev = first_dev;
840     }
841 
842   if (!dev)
843     return SANE_STATUS_INVAL;
844 
845   scanner = malloc (sizeof (*scanner));
846   if (!scanner)
847     return SANE_STATUS_NO_MEM;
848 
849   memset (scanner, 0, sizeof (*scanner));
850   scanner->device = dev;
851 
852   status = CANON_open_device (&scanner->scan, dev->sane.name);
853   if (status != SANE_STATUS_GOOD)
854     {
855       free (scanner);
856       return status;
857     }
858 
859   *handle = scanner;
860 
861   /* insert newly opened handle into list of open handles: */
862   scanner->next = first_handle;
863 
864   first_handle = scanner;
865 
866   return SANE_STATUS_GOOD;
867 }
868 
869 
870 void
sane_close(SANE_Handle handle)871 sane_close (SANE_Handle handle)
872 {
873   Canon_Scanner *prev, *scanner;
874 
875   DBG (3, "sane_close\n");
876 
877   if (!first_handle)
878     {
879       DBG (1, "ERROR: sane_close: no handles opened\n");
880       return;
881     }
882 
883   /* remove handle from list of open handles: */
884 
885   prev = NULL;
886 
887   for (scanner = first_handle; scanner; scanner = scanner->next)
888     {
889       if (scanner == handle)
890 	break;
891 
892       prev = scanner;
893     }
894 
895   if (!scanner)
896     {
897       DBG (1, "ERROR: sane_close: invalid handle %p\n", handle);
898       return;			/* oops, not a handle we know about */
899     }
900 
901   if (prev)
902     prev->next = scanner->next;
903   else
904     first_handle = scanner->next;
905 
906   CANON_close_device (&scanner->scan);
907 
908   free (scanner);
909 }
910 
911 
912 const SANE_Option_Descriptor *
sane_get_option_descriptor(SANE_Handle handle,SANE_Int option)913 sane_get_option_descriptor (SANE_Handle handle, SANE_Int option)
914 {
915   (void) handle;		/* Eliminate compiler warning */
916 
917   DBG (3, "sane_get_option_descriptor: option = %d\n", option);
918   if (option < 0 || option >= NELEMS (so))
919     return NULL;
920   return so[option].descriptor;
921 }
922 
923 SANE_Status
sane_control_option(SANE_Handle handle,SANE_Int option,SANE_Action action,void * value,SANE_Int * info)924 sane_control_option (SANE_Handle handle, SANE_Int option,
925 		     SANE_Action action, void *value, SANE_Int * info)
926 {
927   (void) handle;		/* Eliminate compiler warning */
928 
929   DBG (3,
930        "sane_control_option: handle=%p, opt=%d, act=%d, val=%p, info=%p\n",
931        handle, option, action, value, (void *)info);
932 
933   return dispatch_control_option (handle, option, action, value, info);
934 }
935 
936 
937 SANE_Status
sane_get_parameters(SANE_Handle handle,SANE_Parameters * params)938 sane_get_parameters (SANE_Handle handle, SANE_Parameters * params)
939 {
940   int rc = SANE_STATUS_GOOD;
941   int w =
942     SANE_UNFIX (optionBotRightXValue -
943 		optionTopLeftXValue) / MM_IN_INCH * optionResolutionValue;
944   int h =
945     SANE_UNFIX (optionBotRightYValue -
946 		optionTopLeftYValue) / MM_IN_INCH * optionResolutionValue;
947 
948   (void) handle;		/* Eliminate compiler warning */
949 
950   DBG (3, "sane_get_parameters\n");
951   parms.depth = 8;
952   parms.last_frame = SANE_TRUE;
953   parms.pixels_per_line = w;
954   parms.lines = h;
955 
956 #ifdef GRAY
957   if (optionGrayscaleValue == SANE_TRUE)
958     {
959       parms.format = SANE_FRAME_GRAY;
960       parms.bytes_per_line = w;
961     }
962   else
963 #endif
964     {
965       parms.format = SANE_FRAME_RGB;
966       parms.bytes_per_line = w * 3;
967     }
968   *params = parms;
969   return rc;
970 }
971 
972 
973 SANE_Status
sane_start(SANE_Handle handle)974 sane_start (SANE_Handle handle)
975 {
976   Canon_Scanner *scanner = handle;
977   SANE_Status res;
978 
979   DBG (3, "sane_start\n");
980 
981   res = CANON_set_scan_parameters (&scanner->scan,
982 				   optionCalibrateValue,
983 #ifdef GRAY
984 				   optionGrayscaleValue,
985 #else
986 				   SANE_FALSE,
987 #endif
988 				   SANE_UNFIX (optionTopLeftXValue) /
989 				   MM_IN_INCH * 600,
990 				   SANE_UNFIX (optionTopLeftYValue) /
991 				   MM_IN_INCH * 600,
992 				   SANE_UNFIX (optionBotRightXValue) /
993 				   MM_IN_INCH * 600,
994 				   SANE_UNFIX (optionBotRightYValue) /
995 				   MM_IN_INCH * 600,
996 				   optionResolutionValue,
997 				   optionAGainValue,
998 				   SANE_UNFIX (optionGammaValue));
999 
1000   if (res != SANE_STATUS_GOOD)
1001     return res;
1002 
1003   return CANON_start_scan (&scanner->scan);
1004 }
1005 
1006 
1007 SANE_Status
sane_read(SANE_Handle handle,SANE_Byte * data,SANE_Int max_length,SANE_Int * length)1008 sane_read (SANE_Handle handle, SANE_Byte * data,
1009 	   SANE_Int max_length, SANE_Int * length)
1010 {
1011   Canon_Scanner *scanner = handle;
1012   return CANON_read (&scanner->scan, data, max_length, length);
1013 }
1014 
1015 
1016 void
sane_cancel(SANE_Handle handle)1017 sane_cancel (SANE_Handle handle)
1018 {
1019   DBG (3, "sane_cancel: handle = %p\n", handle);
1020   DBG (3, "sane_cancel: cancelling is unsupported in this backend\n");
1021 }
1022 
1023 
1024 SANE_Status
sane_set_io_mode(SANE_Handle handle,SANE_Bool non_blocking)1025 sane_set_io_mode (SANE_Handle handle, SANE_Bool non_blocking)
1026 {
1027   DBG (3, "sane_set_io_mode: handle = %p, non_blocking = %d\n", handle,
1028        non_blocking);
1029   if (non_blocking != SANE_FALSE)
1030     return SANE_STATUS_UNSUPPORTED;
1031   return SANE_STATUS_GOOD;
1032 }
1033 
1034 
1035 SANE_Status
sane_get_select_fd(SANE_Handle handle,SANE_Int * fd)1036 sane_get_select_fd (SANE_Handle handle, SANE_Int * fd)
1037 {
1038   (void) handle;                /* silence gcc */
1039   (void) fd;                    /* silence gcc */
1040   return SANE_STATUS_UNSUPPORTED;
1041 }
1042