• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* sane - Scanner Access Now Easy.
2 
3    Copyright (C) 2002 Sergey Vlasov <vsu@altlinux.ru>
4    Copyright (C) 2002 - 2007 Henning Geinitz <sane@geinitz.org>
5    Copyright (C) 2009 Stéphane Voltz <stef.dev@free.fr> for sheetfed
6                       calibration code.
7 
8    This file is part of the SANE package.
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 
45 /*
46  * SANE backend for Grandtech GT-6801 and GT-6816 based scanners
47  */
48 
49 #include "../include/sane/config.h"
50 
51 #define BUILD 84
52 #define MAX_DEBUG
53 #define WARMUP_TIME 60
54 #define CALIBRATION_HEIGHT 2.5
55 #define SHORT_TIMEOUT (1 * 1000)
56 #define LONG_TIMEOUT (30 * 1000)
57 
58 /* Use a reader process if possible (usually faster) */
59 #if defined (HAVE_SYS_SHM_H) && (!defined (USE_PTHREAD)) && (!defined (HAVE_OS2_H))
60 #define USE_FORK
61 #define SHM_BUFFERS 10
62 #endif
63 
64 #define TUNE_CALIBRATOR
65 
66 /* Send coarse white or black calibration to stdout */
67 #if 0
68 #define SAVE_WHITE_CALIBRATION
69 #endif
70 #if 0
71 #define SAVE_BLACK_CALIBRATION
72 #endif
73 
74 /* Debug calibration, print total brightness of the scanned image */
75 #if 0
76 #define DEBUG_BRIGHTNESS
77 #endif
78 
79 /* Debug calibration, print black mark values */
80 #if 0
81 #define DEBUG_BLACK
82 #endif
83 
84 #include <ctype.h>
85 #include <errno.h>
86 #include <fcntl.h>
87 #include <limits.h>
88 #include <signal.h>
89 #include <stdio.h>
90 #include <stdlib.h>
91 #include <string.h>
92 #include <unistd.h>
93 #include <sys/time.h>
94 #include <time.h>
95 #include <math.h>
96 #include <dirent.h>
97 
98 #include "../include/_stdint.h"
99 
100 #include "../include/sane/sane.h"
101 #include "../include/sane/sanei.h"
102 #include "../include/sane/saneopts.h"
103 
104 #define BACKEND_NAME gt68xx
105 
106 #include "../include/sane/sanei_backend.h"
107 #include "../include/sane/sanei_config.h"
108 
109 #ifndef SANE_I18N
110 #define SANE_I18N(text) text
111 #endif
112 
113 #include "gt68xx.h"
114 #include "gt68xx_high.c"
115 #include "gt68xx_devices.c"
116 
117 static SANE_Int num_devices = 0;
118 static GT68xx_Device *first_dev = 0;
119 static GT68xx_Scanner *first_handle = 0;
120 static const SANE_Device **devlist = 0;
121 /* Array of newly attached devices */
122 static GT68xx_Device **new_dev = 0;
123 /* Length of new_dev array */
124 static SANE_Int new_dev_len = 0;
125 /* Number of entries allocated for new_dev */
126 static SANE_Int new_dev_alloced = 0;
127 /* Is this computer little-endian ?*/
128 SANE_Bool little_endian;
129 SANE_Bool debug_options = SANE_FALSE;
130 
131 static SANE_String_Const mode_list[] = {
132   SANE_VALUE_SCAN_MODE_COLOR,
133   SANE_VALUE_SCAN_MODE_GRAY,
134   SANE_VALUE_SCAN_MODE_LINEART,
135   0
136 };
137 
138 static SANE_String_Const gray_mode_list[] = {
139   GT68XX_COLOR_RED,
140   GT68XX_COLOR_GREEN,
141   GT68XX_COLOR_BLUE,
142   0
143 };
144 
145 static SANE_String_Const source_list[] = {
146   SANE_I18N ("Flatbed"),
147   SANE_I18N ("Transparency Adapter"),
148   0
149 };
150 
151 static SANE_Range x_range = {
152   SANE_FIX (0.0),               /* minimum */
153   SANE_FIX (216.0),             /* maximum */
154   SANE_FIX (0.0)                /* quantization */
155 };
156 
157 static SANE_Range y_range = {
158   SANE_FIX (0.0),               /* minimum */
159   SANE_FIX (299.0),             /* maximum */
160   SANE_FIX (0.0)                /* quantization */
161 };
162 
163 static SANE_Range gamma_range = {
164   SANE_FIX (0.01),              /* minimum */
165   SANE_FIX (5.0),               /* maximum */
166   SANE_FIX (0.01)               /* quantization */
167 };
168 
169 static const SANE_Range u8_range = {
170   0,                            /* minimum */
171   255,                          /* maximum */
172   0                             /* quantization */
173 };
174 
175 /* Test if this machine is little endian (from coolscan.c) */
176 static SANE_Bool
calc_little_endian(void)177 calc_little_endian (void)
178 {
179   SANE_Int testvalue = 255;
180   uint8_t *firstbyte = (uint8_t *) & testvalue;
181 
182   if (*firstbyte == 255)
183     return SANE_TRUE;
184   return SANE_FALSE;
185 }
186 
187 static size_t
max_string_size(const SANE_String_Const strings[])188 max_string_size (const SANE_String_Const strings[])
189 {
190   size_t size, max_size = 0;
191   SANE_Int i;
192 
193   for (i = 0; strings[i]; ++i)
194     {
195       size = strlen (strings[i]) + 1;
196       if (size > max_size)
197         max_size = size;
198     }
199   return max_size;
200 }
201 
202 static SANE_Status
get_afe_values(SANE_String_Const cp,GT68xx_AFE_Parameters * afe)203 get_afe_values (SANE_String_Const cp, GT68xx_AFE_Parameters * afe)
204 {
205   SANE_Char *word, *end;
206   int i;
207 
208   for (i = 0; i < 6; i++)
209     {
210       cp = sanei_config_get_string (cp, &word);
211       if (word && *word)
212         {
213           long int long_value;
214           errno = 0;
215           long_value = strtol (word, &end, 0);
216 
217           if (end == word)
218             {
219               DBG (5, "get_afe_values: can't parse %d. parameter `%s'\n",
220                    i + 1, word);
221               free (word);
222               word = 0;
223               return SANE_STATUS_INVAL;
224             }
225           else if (errno)
226             {
227               DBG (5, "get_afe_values: can't parse %d. parameter `%s' "
228                    "(%s)\n", i + 1, word, strerror (errno));
229               free (word);
230               word = 0;
231               return SANE_STATUS_INVAL;
232             }
233           else if (long_value < 0)
234             {
235               DBG (5, "get_afe_values: %d. parameter < 0 (%d)\n", i + 1,
236                    (int) long_value);
237               free (word);
238               word = 0;
239               return SANE_STATUS_INVAL;
240             }
241           else if (long_value > 0x3f)
242             {
243               DBG (5, "get_afe_values: %d. parameter > 0x3f (%d)\n", i + 1,
244                    (int) long_value);
245               free (word);
246               word = 0;
247               return SANE_STATUS_INVAL;
248             }
249           else
250             {
251               DBG (5, "get_afe_values: %d. parameter set to 0x%02x\n", i + 1,
252                    (int) long_value);
253               switch (i)
254                 {
255                 case 0:
256                   afe->r_offset = (SANE_Byte) long_value;
257                   break;
258                 case 1:
259                   afe->r_pga = (SANE_Byte) long_value;
260                   break;
261                 case 2:
262                   afe->g_offset = (SANE_Byte) long_value;
263                   break;
264                 case 3:
265                   afe->g_pga = (SANE_Byte) long_value;
266                   break;
267                 case 4:
268                   afe->b_offset = (SANE_Byte) long_value;
269                   break;
270                 case 5:
271                   afe->b_pga = (SANE_Byte) long_value;
272                   break;
273                 }
274               free (word);
275               word = 0;
276             }
277         }
278       else
279         {
280           DBG (5, "get_afe_values: option `afe' needs 6  parameters\n");
281           return SANE_STATUS_INVAL;
282         }
283     }
284   return SANE_STATUS_GOOD;
285 }
286 
287 static SANE_Status
setup_scan_request(GT68xx_Scanner * s,GT68xx_Scan_Request * scan_request)288 setup_scan_request (GT68xx_Scanner * s, GT68xx_Scan_Request * scan_request)
289 {
290 
291   if (s->dev->model->flags & GT68XX_FLAG_MIRROR_X)
292     scan_request->x0 =
293       s->opt[OPT_TL_X].constraint.range->max - s->val[OPT_BR_X].w;
294   else
295     scan_request->x0 = s->val[OPT_TL_X].w;
296   scan_request->y0 = s->val[OPT_TL_Y].w;
297   scan_request->xs = s->val[OPT_BR_X].w - s->val[OPT_TL_X].w;
298   scan_request->ys = s->val[OPT_BR_Y].w - s->val[OPT_TL_Y].w;
299 
300   if (s->val[OPT_FULL_SCAN].w == SANE_TRUE)
301     {
302       scan_request->x0 -= s->dev->model->x_offset;
303       scan_request->y0 -= (s->dev->model->y_offset);
304       scan_request->xs += s->dev->model->x_offset;
305       scan_request->ys += s->dev->model->y_offset;
306     }
307 
308   scan_request->xdpi = s->val[OPT_RESOLUTION].w;
309   if (scan_request->xdpi > s->dev->model->optical_xdpi)
310     scan_request->xdpi = s->dev->model->optical_xdpi;
311   scan_request->ydpi = s->val[OPT_RESOLUTION].w;
312 
313   if (IS_ACTIVE (OPT_BIT_DEPTH) && !s->val[OPT_PREVIEW].w)
314     scan_request->depth = s->val[OPT_BIT_DEPTH].w;
315   else
316     scan_request->depth = 8;
317 
318   if (strcmp (s->val[OPT_MODE].s, SANE_VALUE_SCAN_MODE_COLOR) == 0)
319     scan_request->color = SANE_TRUE;
320   else
321     scan_request->color = SANE_FALSE;
322 
323   if (strcmp (s->val[OPT_MODE].s, SANE_VALUE_SCAN_MODE_LINEART) == 0)
324     {
325       SANE_Int xs =
326         SANE_UNFIX (scan_request->xs) * scan_request->xdpi / MM_PER_INCH +
327         0.5;
328 
329       if (xs % 8)
330         {
331           scan_request->xs =
332             SANE_FIX ((xs - (xs % 8)) * MM_PER_INCH / scan_request->xdpi);
333           DBG (5, "setup_scan_request: lineart mode, %d pixels %% 8 = %d\n",
334                xs, xs % 8);
335         }
336     }
337 
338   scan_request->calculate = SANE_FALSE;
339   scan_request->lamp = SANE_TRUE;
340   scan_request->mbs = SANE_FALSE;
341 
342   if (strcmp (s->val[OPT_SOURCE].s, "Transparency Adapter") == 0)
343     scan_request->use_ta = SANE_TRUE;
344   else
345     scan_request->use_ta = SANE_FALSE;
346 
347   return SANE_STATUS_GOOD;
348 }
349 
350 static SANE_Status
calc_parameters(GT68xx_Scanner * s)351 calc_parameters (GT68xx_Scanner * s)
352 {
353   SANE_String val;
354   SANE_Status status = SANE_STATUS_GOOD;
355   GT68xx_Scan_Request scan_request;
356   GT68xx_Scan_Parameters scan_params;
357 
358   DBG (5, "calc_parameters: start\n");
359   val = s->val[OPT_MODE].s;
360 
361   s->params.last_frame = SANE_TRUE;
362   if (strcmp (val, SANE_VALUE_SCAN_MODE_GRAY) == 0
363       || strcmp (val, SANE_VALUE_SCAN_MODE_LINEART) == 0)
364     s->params.format = SANE_FRAME_GRAY;
365   else                          /* Color */
366     s->params.format = SANE_FRAME_RGB;
367 
368   setup_scan_request (s, &scan_request);
369   scan_request.calculate = SANE_TRUE;
370 
371   status = gt68xx_device_setup_scan (s->dev, &scan_request, SA_SCAN,
372                                      &scan_params);
373   if (status != SANE_STATUS_GOOD)
374     {
375       DBG (1, "calc_parameters: gt68xx_device_setup_scan returned: %s\n",
376            sane_strstatus (status));
377       return status;
378     }
379 
380   if (strcmp (val, SANE_VALUE_SCAN_MODE_LINEART) == 0)
381     s->params.depth = 1;
382   else
383     s->params.depth = scan_params.depth;
384 
385   s->params.lines = scan_params.pixel_ys;
386   s->params.pixels_per_line = scan_params.pixel_xs;
387   /* Inflate X if necessary */
388   if (s->val[OPT_RESOLUTION].w > s->dev->model->optical_xdpi)
389     s->params.pixels_per_line *=
390       (s->val[OPT_RESOLUTION].w / s->dev->model->optical_xdpi);
391   s->params.bytes_per_line = s->params.pixels_per_line;
392   if (s->params.depth > 8)
393     {
394       s->params.depth = 16;
395       s->params.bytes_per_line *= 2;
396     }
397   else if (s->params.depth == 1)
398     s->params.bytes_per_line /= 8;
399 
400   if (s->params.format == SANE_FRAME_RGB)
401     s->params.bytes_per_line *= 3;
402 
403   DBG (5, "calc_parameters: exit\n");
404   return status;
405 }
406 
407 static SANE_Status
create_bpp_list(GT68xx_Scanner * s,SANE_Int * bpp)408 create_bpp_list (GT68xx_Scanner * s, SANE_Int * bpp)
409 {
410   int count;
411 
412   for (count = 0; bpp[count] != 0; count++)
413     ;
414   s->bpp_list[0] = count;
415   for (count = 0; bpp[count] != 0; count++)
416     {
417       s->bpp_list[s->bpp_list[0] - count] = bpp[count];
418     }
419   return SANE_STATUS_GOOD;
420 }
421 
422 static SANE_Status
init_options(GT68xx_Scanner * s)423 init_options (GT68xx_Scanner * s)
424 {
425   SANE_Int option, count;
426   SANE_Status status;
427   SANE_Word *dpi_list;
428   GT68xx_Model *model = s->dev->model;
429   SANE_Bool has_ta = SANE_FALSE;
430 
431   DBG (5, "init_options: start\n");
432 
433   memset (s->opt, 0, sizeof (s->opt));
434   memset (s->val, 0, sizeof (s->val));
435 
436   for (option = 0; option < NUM_OPTIONS; ++option)
437     {
438       s->opt[option].size = sizeof (SANE_Word);
439       s->opt[option].cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT;
440     }
441   s->opt[OPT_NUM_OPTS].name = SANE_NAME_NUM_OPTIONS;
442   s->opt[OPT_NUM_OPTS].title = SANE_TITLE_NUM_OPTIONS;
443   s->opt[OPT_NUM_OPTS].desc = SANE_DESC_NUM_OPTIONS;
444   s->opt[OPT_NUM_OPTS].type = SANE_TYPE_INT;
445   s->opt[OPT_NUM_OPTS].cap = SANE_CAP_SOFT_DETECT;
446   s->val[OPT_NUM_OPTS].w = NUM_OPTIONS;
447 
448   /* "Mode" group: */
449   s->opt[OPT_MODE_GROUP].title = SANE_I18N ("Scan Mode");
450   s->opt[OPT_MODE_GROUP].desc = "";
451   s->opt[OPT_MODE_GROUP].type = SANE_TYPE_GROUP;
452   s->opt[OPT_MODE_GROUP].size = 0;
453   s->opt[OPT_MODE_GROUP].cap = 0;
454   s->opt[OPT_MODE_GROUP].constraint_type = SANE_CONSTRAINT_NONE;
455 
456   /* scan mode */
457   s->opt[OPT_MODE].name = SANE_NAME_SCAN_MODE;
458   s->opt[OPT_MODE].title = SANE_TITLE_SCAN_MODE;
459   s->opt[OPT_MODE].desc = SANE_DESC_SCAN_MODE;
460   s->opt[OPT_MODE].type = SANE_TYPE_STRING;
461   s->opt[OPT_MODE].constraint_type = SANE_CONSTRAINT_STRING_LIST;
462   s->opt[OPT_MODE].size = max_string_size (mode_list);
463   s->opt[OPT_MODE].constraint.string_list = mode_list;
464   s->val[OPT_MODE].s = strdup (SANE_VALUE_SCAN_MODE_GRAY);
465 
466   /* scan mode */
467   s->opt[OPT_GRAY_MODE_COLOR].name = "gray-mode-color";
468   s->opt[OPT_GRAY_MODE_COLOR].title = SANE_I18N ("Gray mode color");
469   s->opt[OPT_GRAY_MODE_COLOR].desc =
470     SANE_I18N ("Selects which scan color is used "
471                "gray mode (default: green).");
472   s->opt[OPT_GRAY_MODE_COLOR].type = SANE_TYPE_STRING;
473   s->opt[OPT_GRAY_MODE_COLOR].constraint_type = SANE_CONSTRAINT_STRING_LIST;
474   s->opt[OPT_GRAY_MODE_COLOR].size = max_string_size (gray_mode_list);
475   s->opt[OPT_GRAY_MODE_COLOR].constraint.string_list = gray_mode_list;
476   s->val[OPT_GRAY_MODE_COLOR].s = strdup (GT68XX_COLOR_GREEN);
477 
478   /* scan source */
479   s->opt[OPT_SOURCE].name = SANE_NAME_SCAN_SOURCE;
480   s->opt[OPT_SOURCE].title = SANE_TITLE_SCAN_SOURCE;
481   s->opt[OPT_SOURCE].desc = SANE_DESC_SCAN_SOURCE;
482   s->opt[OPT_SOURCE].type = SANE_TYPE_STRING;
483   s->opt[OPT_SOURCE].constraint_type = SANE_CONSTRAINT_STRING_LIST;
484   s->opt[OPT_SOURCE].size = max_string_size (source_list);
485   s->opt[OPT_SOURCE].constraint.string_list = source_list;
486   s->val[OPT_SOURCE].s = strdup ("Flatbed");
487   status = gt68xx_device_get_ta_status (s->dev, &has_ta);
488   if (status != SANE_STATUS_GOOD || !has_ta)
489     DISABLE (OPT_SOURCE);
490 
491   /* preview */
492   s->opt[OPT_PREVIEW].name = SANE_NAME_PREVIEW;
493   s->opt[OPT_PREVIEW].title = SANE_TITLE_PREVIEW;
494   s->opt[OPT_PREVIEW].desc = SANE_DESC_PREVIEW;
495   s->opt[OPT_PREVIEW].type = SANE_TYPE_BOOL;
496   s->opt[OPT_PREVIEW].unit = SANE_UNIT_NONE;
497   s->opt[OPT_PREVIEW].constraint_type = SANE_CONSTRAINT_NONE;
498   s->val[OPT_PREVIEW].w = SANE_FALSE;
499 
500   /* lamp on */
501   s->opt[OPT_LAMP_OFF_AT_EXIT].name = SANE_NAME_LAMP_OFF_AT_EXIT;
502   s->opt[OPT_LAMP_OFF_AT_EXIT].title = SANE_TITLE_LAMP_OFF_AT_EXIT;
503   s->opt[OPT_LAMP_OFF_AT_EXIT].desc = SANE_DESC_LAMP_OFF_AT_EXIT;
504   s->opt[OPT_LAMP_OFF_AT_EXIT].type = SANE_TYPE_BOOL;
505   s->opt[OPT_LAMP_OFF_AT_EXIT].unit = SANE_UNIT_NONE;
506   s->opt[OPT_LAMP_OFF_AT_EXIT].constraint_type = SANE_CONSTRAINT_NONE;
507   s->val[OPT_LAMP_OFF_AT_EXIT].w = SANE_TRUE;
508   if (s->dev->model->is_cis && !(s->dev->model->flags & GT68XX_FLAG_CIS_LAMP))
509     DISABLE (OPT_LAMP_OFF_AT_EXIT);
510 
511   /* bit depth */
512   s->opt[OPT_BIT_DEPTH].name = SANE_NAME_BIT_DEPTH;
513   s->opt[OPT_BIT_DEPTH].title = SANE_TITLE_BIT_DEPTH;
514   s->opt[OPT_BIT_DEPTH].desc = SANE_DESC_BIT_DEPTH;
515   s->opt[OPT_BIT_DEPTH].type = SANE_TYPE_INT;
516   s->opt[OPT_BIT_DEPTH].constraint_type = SANE_CONSTRAINT_WORD_LIST;
517   s->opt[OPT_BIT_DEPTH].size = sizeof (SANE_Word);
518   s->opt[OPT_BIT_DEPTH].constraint.word_list = 0;
519   s->opt[OPT_BIT_DEPTH].constraint.word_list = s->bpp_list;
520   RIE (create_bpp_list (s, s->dev->model->bpp_gray_values));
521   s->val[OPT_BIT_DEPTH].w = 8;
522   if (s->opt[OPT_BIT_DEPTH].constraint.word_list[0] < 2)
523     DISABLE (OPT_BIT_DEPTH);
524 
525   /* resolution */
526   for (count = 0; model->ydpi_values[count] != 0; count++)
527     ;
528   dpi_list = malloc ((count + 1) * sizeof (SANE_Word));
529   if (!dpi_list)
530     return SANE_STATUS_NO_MEM;
531   dpi_list[0] = count;
532   for (count = 0; model->ydpi_values[count] != 0; count++)
533     dpi_list[dpi_list[0] - count] = model->ydpi_values[count];
534   s->opt[OPT_RESOLUTION].name = SANE_NAME_SCAN_RESOLUTION;
535   s->opt[OPT_RESOLUTION].title = SANE_TITLE_SCAN_RESOLUTION;
536   s->opt[OPT_RESOLUTION].desc = SANE_DESC_SCAN_RESOLUTION;
537   s->opt[OPT_RESOLUTION].type = SANE_TYPE_INT;
538   s->opt[OPT_RESOLUTION].unit = SANE_UNIT_DPI;
539   s->opt[OPT_RESOLUTION].constraint_type = SANE_CONSTRAINT_WORD_LIST;
540   s->opt[OPT_RESOLUTION].constraint.word_list = dpi_list;
541   s->val[OPT_RESOLUTION].w = 300;
542 
543   /* backtrack */
544   s->opt[OPT_BACKTRACK].name = SANE_NAME_BACKTRACK;
545   s->opt[OPT_BACKTRACK].title = SANE_TITLE_BACKTRACK;
546   s->opt[OPT_BACKTRACK].desc = SANE_DESC_BACKTRACK;
547   s->opt[OPT_BACKTRACK].type = SANE_TYPE_BOOL;
548   s->val[OPT_BACKTRACK].w = SANE_FALSE;
549 
550   /* "Debug" group: */
551   s->opt[OPT_DEBUG_GROUP].title = SANE_I18N ("Debugging Options");
552   s->opt[OPT_DEBUG_GROUP].desc = "";
553   s->opt[OPT_DEBUG_GROUP].type = SANE_TYPE_GROUP;
554   s->opt[OPT_DEBUG_GROUP].size = 0;
555   s->opt[OPT_DEBUG_GROUP].cap = 0;
556   s->opt[OPT_DEBUG_GROUP].constraint_type = SANE_CONSTRAINT_NONE;
557   if (!debug_options)
558     DISABLE (OPT_DEBUG_GROUP);
559 
560   /* auto warmup */
561   s->opt[OPT_AUTO_WARMUP].name = "auto-warmup";
562   s->opt[OPT_AUTO_WARMUP].title = SANE_I18N ("Automatic warmup");
563   s->opt[OPT_AUTO_WARMUP].desc =
564     SANE_I18N ("Warm-up until the lamp's brightness is constant "
565                "instead of insisting on 60 seconds warm-up time.");
566   s->opt[OPT_AUTO_WARMUP].type = SANE_TYPE_BOOL;
567   s->opt[OPT_AUTO_WARMUP].unit = SANE_UNIT_NONE;
568   s->opt[OPT_AUTO_WARMUP].constraint_type = SANE_CONSTRAINT_NONE;
569   s->val[OPT_AUTO_WARMUP].w = SANE_TRUE;
570   if ((s->dev->model->is_cis
571        && !(s->dev->model->flags & GT68XX_FLAG_CIS_LAMP)) || !debug_options)
572     DISABLE (OPT_AUTO_WARMUP);
573 
574   /* full scan */
575   s->opt[OPT_FULL_SCAN].name = "full-scan";
576   s->opt[OPT_FULL_SCAN].title = SANE_I18N ("Full scan");
577   s->opt[OPT_FULL_SCAN].desc =
578     SANE_I18N ("Scan the complete scanning area including calibration strip. "
579                "Be careful. Don't select the full height. For testing only.");
580   s->opt[OPT_FULL_SCAN].type = SANE_TYPE_BOOL;
581   s->opt[OPT_FULL_SCAN].unit = SANE_UNIT_NONE;
582   s->opt[OPT_FULL_SCAN].constraint_type = SANE_CONSTRAINT_NONE;
583   s->val[OPT_FULL_SCAN].w = SANE_FALSE;
584   if (!debug_options)
585     DISABLE (OPT_FULL_SCAN);
586 
587   /* coarse calibration */
588   s->opt[OPT_COARSE_CAL].name = "coarse-calibration";
589   s->opt[OPT_COARSE_CAL].title = SANE_I18N ("Coarse calibration");
590   s->opt[OPT_COARSE_CAL].desc =
591     SANE_I18N ("Setup gain and offset for scanning automatically. If this "
592                "option is disabled, options for setting the analog frontend "
593                "parameters manually are provided. This option is enabled "
594                "by default. For testing only.");
595   s->opt[OPT_COARSE_CAL].type = SANE_TYPE_BOOL;
596   s->opt[OPT_COARSE_CAL].unit = SANE_UNIT_NONE;
597   s->opt[OPT_COARSE_CAL].constraint_type = SANE_CONSTRAINT_NONE;
598   s->val[OPT_COARSE_CAL].w = SANE_TRUE;
599   if (!debug_options)
600     DISABLE (OPT_COARSE_CAL);
601   if (s->dev->model->flags & GT68XX_FLAG_SHEET_FED)
602     {
603       s->val[OPT_COARSE_CAL].w = SANE_FALSE;
604       DISABLE (OPT_COARSE_CAL);
605     }
606 
607   /* coarse calibration only once */
608   s->opt[OPT_COARSE_CAL_ONCE].name = "coarse-calibration-once";
609   s->opt[OPT_COARSE_CAL_ONCE].title =
610     SANE_I18N ("Coarse calibration for first scan only");
611   s->opt[OPT_COARSE_CAL_ONCE].desc =
612     SANE_I18N ("Coarse calibration is only done for the first scan. Works "
613                "with most scanners and can save scanning time. If the image "
614                "brightness is different with each scan, disable this option. "
615                "For testing only.");
616   s->opt[OPT_COARSE_CAL_ONCE].type = SANE_TYPE_BOOL;
617   s->opt[OPT_COARSE_CAL_ONCE].unit = SANE_UNIT_NONE;
618   s->opt[OPT_COARSE_CAL_ONCE].constraint_type = SANE_CONSTRAINT_NONE;
619   s->val[OPT_COARSE_CAL_ONCE].w = SANE_FALSE;
620   if (!debug_options)
621     DISABLE (OPT_COARSE_CAL_ONCE);
622   if (s->dev->model->flags & GT68XX_FLAG_SHEET_FED)
623     DISABLE (OPT_COARSE_CAL_ONCE);
624 
625   /* calibration */
626   s->opt[OPT_QUALITY_CAL].name = SANE_NAME_QUALITY_CAL;
627   s->opt[OPT_QUALITY_CAL].title = SANE_TITLE_QUALITY_CAL;
628   s->opt[OPT_QUALITY_CAL].desc = SANE_TITLE_QUALITY_CAL;
629   s->opt[OPT_QUALITY_CAL].type = SANE_TYPE_BOOL;
630   s->opt[OPT_QUALITY_CAL].unit = SANE_UNIT_NONE;
631   s->opt[OPT_QUALITY_CAL].constraint_type = SANE_CONSTRAINT_NONE;
632   s->val[OPT_QUALITY_CAL].w = SANE_TRUE;
633   if (!debug_options)
634     DISABLE (OPT_QUALITY_CAL);
635   /* we disable image correction for scanners that can't calibrate */
636   if ((s->dev->model->flags & GT68XX_FLAG_SHEET_FED)
637     &&(!(s->dev->model->flags & GT68XX_FLAG_HAS_CALIBRATE)))
638     {
639       s->val[OPT_QUALITY_CAL].w = SANE_FALSE;
640       DISABLE (OPT_QUALITY_CAL);
641     }
642 
643   /* backtrack lines */
644   s->opt[OPT_BACKTRACK_LINES].name = "backtrack-lines";
645   s->opt[OPT_BACKTRACK_LINES].title = SANE_I18N ("Backtrack lines");
646   s->opt[OPT_BACKTRACK_LINES].desc =
647     SANE_I18N ("Number of lines the scan slider moves back when backtracking "
648                "occurs. That happens when the scanner scans faster than the "
649                "computer can receive the data. Low values cause faster scans "
650                "but increase the risk of omitting lines.");
651   s->opt[OPT_BACKTRACK_LINES].type = SANE_TYPE_INT;
652   s->opt[OPT_BACKTRACK_LINES].unit = SANE_UNIT_NONE;
653   s->opt[OPT_BACKTRACK_LINES].constraint_type = SANE_CONSTRAINT_RANGE;
654   s->opt[OPT_BACKTRACK_LINES].constraint.range = &u8_range;
655   if (s->dev->model->is_cis && !(s->dev->model->flags & GT68XX_FLAG_SHEET_FED))
656     s->val[OPT_BACKTRACK_LINES].w = 0x10;
657   else
658     s->val[OPT_BACKTRACK_LINES].w = 0x3f;
659   if (!debug_options)
660     DISABLE (OPT_BACKTRACK_LINES);
661 
662   /* "Enhancement" group: */
663   s->opt[OPT_ENHANCEMENT_GROUP].title = SANE_I18N ("Enhancement");
664   s->opt[OPT_ENHANCEMENT_GROUP].desc = "";
665   s->opt[OPT_ENHANCEMENT_GROUP].type = SANE_TYPE_GROUP;
666   s->opt[OPT_ENHANCEMENT_GROUP].cap = 0;
667   s->opt[OPT_ENHANCEMENT_GROUP].size = 0;
668   s->opt[OPT_ENHANCEMENT_GROUP].constraint_type = SANE_CONSTRAINT_NONE;
669 
670   /* internal gamma value */
671   s->opt[OPT_GAMMA_VALUE].name = "gamma-value";
672   s->opt[OPT_GAMMA_VALUE].title = SANE_I18N ("Gamma value");
673   s->opt[OPT_GAMMA_VALUE].desc =
674     SANE_I18N ("Sets the gamma value of all channels.");
675   s->opt[OPT_GAMMA_VALUE].type = SANE_TYPE_FIXED;
676   s->opt[OPT_GAMMA_VALUE].unit = SANE_UNIT_NONE;
677   s->opt[OPT_GAMMA_VALUE].constraint_type = SANE_CONSTRAINT_RANGE;
678   s->opt[OPT_GAMMA_VALUE].constraint.range = &gamma_range;
679   s->opt[OPT_GAMMA_VALUE].cap |= SANE_CAP_EMULATED;
680   s->val[OPT_GAMMA_VALUE].w = s->dev->gamma_value;
681 
682   /* threshold */
683   s->opt[OPT_THRESHOLD].name = SANE_NAME_THRESHOLD;
684   s->opt[OPT_THRESHOLD].title = SANE_TITLE_THRESHOLD;
685   s->opt[OPT_THRESHOLD].desc = SANE_DESC_THRESHOLD;
686   s->opt[OPT_THRESHOLD].type = SANE_TYPE_INT;
687   s->opt[OPT_THRESHOLD].unit = SANE_UNIT_NONE;
688   s->opt[OPT_THRESHOLD].constraint_type = SANE_CONSTRAINT_RANGE;
689   s->opt[OPT_THRESHOLD].constraint.range = &u8_range;
690   s->val[OPT_THRESHOLD].w = 128;
691   DISABLE (OPT_THRESHOLD);
692 
693   /* "Geometry" group: */
694   s->opt[OPT_GEOMETRY_GROUP].title = SANE_I18N ("Geometry");
695   s->opt[OPT_GEOMETRY_GROUP].desc = "";
696   s->opt[OPT_GEOMETRY_GROUP].type = SANE_TYPE_GROUP;
697   s->opt[OPT_GEOMETRY_GROUP].cap = SANE_CAP_ADVANCED;
698   s->opt[OPT_GEOMETRY_GROUP].size = 0;
699   s->opt[OPT_GEOMETRY_GROUP].constraint_type = SANE_CONSTRAINT_NONE;
700 
701   x_range.max = model->x_size;
702   y_range.max = model->y_size;
703 
704   /* top-left x */
705   s->opt[OPT_TL_X].name = SANE_NAME_SCAN_TL_X;
706   s->opt[OPT_TL_X].title = SANE_TITLE_SCAN_TL_X;
707   s->opt[OPT_TL_X].desc = SANE_DESC_SCAN_TL_X;
708   s->opt[OPT_TL_X].type = SANE_TYPE_FIXED;
709   s->opt[OPT_TL_X].unit = SANE_UNIT_MM;
710   s->opt[OPT_TL_X].constraint_type = SANE_CONSTRAINT_RANGE;
711   s->opt[OPT_TL_X].constraint.range = &x_range;
712   s->val[OPT_TL_X].w = 0;
713 
714   /* top-left y */
715   s->opt[OPT_TL_Y].name = SANE_NAME_SCAN_TL_Y;
716   s->opt[OPT_TL_Y].title = SANE_TITLE_SCAN_TL_Y;
717   s->opt[OPT_TL_Y].desc = SANE_DESC_SCAN_TL_Y;
718   s->opt[OPT_TL_Y].type = SANE_TYPE_FIXED;
719   s->opt[OPT_TL_Y].unit = SANE_UNIT_MM;
720   s->opt[OPT_TL_Y].constraint_type = SANE_CONSTRAINT_RANGE;
721   s->opt[OPT_TL_Y].constraint.range = &y_range;
722   s->val[OPT_TL_Y].w = 0;
723 
724   /* bottom-right x */
725   s->opt[OPT_BR_X].name = SANE_NAME_SCAN_BR_X;
726   s->opt[OPT_BR_X].title = SANE_TITLE_SCAN_BR_X;
727   s->opt[OPT_BR_X].desc = SANE_DESC_SCAN_BR_X;
728   s->opt[OPT_BR_X].type = SANE_TYPE_FIXED;
729   s->opt[OPT_BR_X].unit = SANE_UNIT_MM;
730   s->opt[OPT_BR_X].constraint_type = SANE_CONSTRAINT_RANGE;
731   s->opt[OPT_BR_X].constraint.range = &x_range;
732   s->val[OPT_BR_X].w = x_range.max;
733 
734   /* bottom-right y */
735   s->opt[OPT_BR_Y].name = SANE_NAME_SCAN_BR_Y;
736   s->opt[OPT_BR_Y].title = SANE_TITLE_SCAN_BR_Y;
737   s->opt[OPT_BR_Y].desc = SANE_DESC_SCAN_BR_Y;
738   s->opt[OPT_BR_Y].type = SANE_TYPE_FIXED;
739   s->opt[OPT_BR_Y].unit = SANE_UNIT_MM;
740   s->opt[OPT_BR_Y].constraint_type = SANE_CONSTRAINT_RANGE;
741   s->opt[OPT_BR_Y].constraint.range = &y_range;
742   s->val[OPT_BR_Y].w = y_range.max;
743 
744   /* sensor group */
745   s->opt[OPT_SENSOR_GROUP].name = SANE_NAME_SENSORS;
746   s->opt[OPT_SENSOR_GROUP].title = SANE_TITLE_SENSORS;
747   s->opt[OPT_SENSOR_GROUP].desc = SANE_DESC_SENSORS;
748   s->opt[OPT_SENSOR_GROUP].type = SANE_TYPE_GROUP;
749   s->opt[OPT_SENSOR_GROUP].constraint_type = SANE_CONSTRAINT_NONE;
750 
751   /* calibration needed */
752   s->opt[OPT_NEED_CALIBRATION_SW].name = "need-calibration";
753   s->opt[OPT_NEED_CALIBRATION_SW].title = SANE_I18N ("Needs calibration");
754   s->opt[OPT_NEED_CALIBRATION_SW].desc = SANE_I18N ("The scanner needs calibration for the current settings");
755   s->opt[OPT_NEED_CALIBRATION_SW].type = SANE_TYPE_BOOL;
756   s->opt[OPT_NEED_CALIBRATION_SW].unit = SANE_UNIT_NONE;
757   if (s->dev->model->flags & GT68XX_FLAG_HAS_CALIBRATE)
758     s->opt[OPT_NEED_CALIBRATION_SW].cap = SANE_CAP_SOFT_DETECT | SANE_CAP_HARD_SELECT | SANE_CAP_ADVANCED;
759   else
760     s->opt[OPT_NEED_CALIBRATION_SW].cap = SANE_CAP_INACTIVE;
761   s->val[OPT_NEED_CALIBRATION_SW].b = 0;
762 
763   /* document present sensor */
764   s->opt[OPT_PAGE_LOADED_SW].name = SANE_NAME_PAGE_LOADED;
765   s->opt[OPT_PAGE_LOADED_SW].title = SANE_TITLE_PAGE_LOADED;
766   s->opt[OPT_PAGE_LOADED_SW].desc = SANE_DESC_PAGE_LOADED;
767   s->opt[OPT_PAGE_LOADED_SW].type = SANE_TYPE_BOOL;
768   s->opt[OPT_PAGE_LOADED_SW].unit = SANE_UNIT_NONE;
769   if (s->dev->model->command_set->document_present)
770     s->opt[OPT_PAGE_LOADED_SW].cap =
771       SANE_CAP_SOFT_DETECT | SANE_CAP_HARD_SELECT | SANE_CAP_ADVANCED;
772   else
773     s->opt[OPT_PAGE_LOADED_SW].cap = SANE_CAP_INACTIVE;
774   s->val[OPT_PAGE_LOADED_SW].b = 0;
775 
776   /* button group */
777   s->opt[OPT_BUTTON_GROUP].name = "Buttons";
778   s->opt[OPT_BUTTON_GROUP].title = SANE_I18N ("Buttons");
779   s->opt[OPT_BUTTON_GROUP].desc = SANE_I18N ("Buttons");
780   s->opt[OPT_BUTTON_GROUP].type = SANE_TYPE_GROUP;
781   s->opt[OPT_BUTTON_GROUP].constraint_type = SANE_CONSTRAINT_NONE;
782 
783   /* calibrate button */
784   s->opt[OPT_CALIBRATE].name = "calibrate";
785   s->opt[OPT_CALIBRATE].title = SANE_I18N ("Calibrate");
786   s->opt[OPT_CALIBRATE].desc =
787     SANE_I18N ("Start calibration using special sheet");
788   s->opt[OPT_CALIBRATE].type = SANE_TYPE_BUTTON;
789   s->opt[OPT_CALIBRATE].unit = SANE_UNIT_NONE;
790   if (s->dev->model->flags & GT68XX_FLAG_HAS_CALIBRATE)
791   s->opt[OPT_CALIBRATE].cap =
792       SANE_CAP_SOFT_DETECT | SANE_CAP_SOFT_SELECT | SANE_CAP_ADVANCED |
793       SANE_CAP_AUTOMATIC;
794   else
795     s->opt[OPT_CALIBRATE].cap = SANE_CAP_INACTIVE;
796   s->val[OPT_CALIBRATE].b = 0;
797 
798   /* clear calibration cache button */
799   s->opt[OPT_CLEAR_CALIBRATION].name = "clear";
800   s->opt[OPT_CLEAR_CALIBRATION].title = SANE_I18N ("Clear calibration");
801   s->opt[OPT_CLEAR_CALIBRATION].desc = SANE_I18N ("Clear calibration cache");
802   s->opt[OPT_CLEAR_CALIBRATION].type = SANE_TYPE_BUTTON;
803   s->opt[OPT_CLEAR_CALIBRATION].unit = SANE_UNIT_NONE;
804   if (s->dev->model->flags & GT68XX_FLAG_HAS_CALIBRATE)
805   s->opt[OPT_CLEAR_CALIBRATION].cap =
806     SANE_CAP_SOFT_DETECT | SANE_CAP_SOFT_SELECT | SANE_CAP_ADVANCED |
807     SANE_CAP_AUTOMATIC;
808   else
809     s->opt[OPT_CLEAR_CALIBRATION].cap = SANE_CAP_INACTIVE;
810   s->val[OPT_CLEAR_CALIBRATION].b = 0;
811 
812 
813   RIE (calc_parameters (s));
814 
815   DBG (5, "init_options: exit\n");
816   return SANE_STATUS_GOOD;
817 }
818 
819 static SANE_Status
attach(SANE_String_Const devname,GT68xx_Device ** devp,SANE_Bool may_wait)820 attach (SANE_String_Const devname, GT68xx_Device ** devp, SANE_Bool may_wait)
821 {
822   GT68xx_Device *dev;
823   SANE_Status status;
824 
825   DBG (5, "attach: start: devp %s NULL, may_wait = %d\n", devp ? "!=" : "==",
826        may_wait);
827   if (!devname)
828     {
829       DBG (1, "attach: devname == NULL\n");
830       return SANE_STATUS_INVAL;
831     }
832 
833   for (dev = first_dev; dev; dev = dev->next)
834     {
835       if (strcmp (dev->file_name, devname) == 0)
836         {
837           if (devp)
838             *devp = dev;
839           dev->missing = SANE_FALSE;
840           DBG (4, "attach: device `%s' was already in device list\n",
841                devname);
842           return SANE_STATUS_GOOD;
843         }
844     }
845 
846   DBG (4, "attach: trying to open device `%s'\n", devname);
847   RIE (gt68xx_device_new (&dev));
848   status = gt68xx_device_open (dev, devname);
849   if (status == SANE_STATUS_GOOD)
850     DBG (4, "attach: device `%s' successfully opened\n", devname);
851   else
852     {
853       DBG (4, "attach: couldn't open device `%s': %s\n", devname,
854            sane_strstatus (status));
855       gt68xx_device_free (dev);
856       if (devp)
857         *devp = 0;
858       return status;
859     }
860 
861   if (!gt68xx_device_is_configured (dev))
862     {
863       GT68xx_Model *model = NULL;
864       DBG (2, "attach: Warning: device `%s' is not listed in device table\n",
865            devname);
866       DBG (2,
867            "attach: If you have manually added it, use override in gt68xx.conf\n");
868       gt68xx_device_get_model ("unknown-scanner", &model);
869       status = gt68xx_device_set_model (dev, model);
870       if (status != SANE_STATUS_GOOD)
871         {
872           DBG (4, "attach: couldn't set model: %s\n",
873                sane_strstatus (status));
874           gt68xx_device_free (dev);
875           if (devp)
876             *devp = 0;
877           return status;
878         }
879       dev->manual_selection = SANE_TRUE;
880     }
881 
882   dev->file_name = strdup (devname);
883   dev->missing = SANE_FALSE;
884   if (!dev->file_name)
885     return SANE_STATUS_NO_MEM;
886   DBG (2, "attach: found %s flatbed scanner %s at %s\n", dev->model->vendor,
887        dev->model->model, dev->file_name);
888   ++num_devices;
889   dev->next = first_dev;
890   first_dev = dev;
891 
892   if (devp)
893     *devp = dev;
894   gt68xx_device_close (dev);
895   DBG (5, "attach: exit\n");
896   return SANE_STATUS_GOOD;
897 }
898 
899 static SANE_Status
attach_one_device(SANE_String_Const devname)900 attach_one_device (SANE_String_Const devname)
901 {
902   GT68xx_Device *dev;
903   SANE_Status status;
904 
905   RIE (attach (devname, &dev, SANE_FALSE));
906 
907   if (dev)
908     {
909       /* Keep track of newly attached devices so we can set options as
910          necessary.  */
911       if (new_dev_len >= new_dev_alloced)
912         {
913           new_dev_alloced += 4;
914           if (new_dev)
915             new_dev =
916               realloc (new_dev, new_dev_alloced * sizeof (new_dev[0]));
917           else
918             new_dev = malloc (new_dev_alloced * sizeof (new_dev[0]));
919           if (!new_dev)
920             {
921               DBG (1, "attach_one_device: out of memory\n");
922               return SANE_STATUS_NO_MEM;
923             }
924         }
925       new_dev[new_dev_len++] = dev;
926     }
927   return SANE_STATUS_GOOD;
928 }
929 
930 #if defined(_WIN32) || defined(HAVE_OS2_H)
931 # define PATH_SEP       "\\"
932 #else
933 # define PATH_SEP       "/"
934 #endif
935 
936 static SANE_Status
download_firmware_file(GT68xx_Device * dev)937 download_firmware_file (GT68xx_Device * dev)
938 {
939   SANE_Status status = SANE_STATUS_GOOD;
940   SANE_Byte *buf = NULL;
941   int size = -1;
942   SANE_Char filename[PATH_MAX], dirname[PATH_MAX], basename[PATH_MAX];
943   FILE *f;
944 
945   if (strncmp (dev->model->firmware_name, PATH_SEP, 1) != 0)
946     {
947       /* probably filename only */
948       snprintf (filename, sizeof(filename), "%s%s%s%s%s%s%s",
949                 STRINGIFY (PATH_SANE_DATA_DIR),
950                 PATH_SEP, "sane", PATH_SEP, "gt68xx", PATH_SEP,
951                 dev->model->firmware_name);
952       snprintf (dirname, sizeof(dirname), "%s%s%s%s%s",
953                 STRINGIFY (PATH_SANE_DATA_DIR),
954                 PATH_SEP, "sane", PATH_SEP, "gt68xx");
955       strncpy (basename, dev->model->firmware_name, sizeof(basename) - 1);
956       basename[sizeof(basename) - 1] = '\0';
957     }
958   else
959     {
960       /* absolute path */
961       char *pos;
962       strncpy (filename, dev->model->firmware_name, sizeof(filename) - 1);
963       filename[sizeof(filename) - 1] = '\0';
964       strncpy (dirname, dev->model->firmware_name, sizeof(dirname) - 1);
965       dirname[sizeof(dirname) - 1] = '\0';
966 
967       pos = strrchr (dirname, PATH_SEP[0]);
968       if (pos)
969         pos[0] = '\0';
970       strncpy (basename, pos + 1, sizeof(basename) - 1);
971       basename[sizeof(basename) - 1] = '\0';
972     }
973 
974   /* first, try to open with exact case */
975   DBG (5, "download_firmware: trying %s\n", filename);
976   f = fopen (filename, "rb");
977   if (!f)
978     {
979       /* and now any case */
980       DIR *dir;
981       struct dirent *direntry;
982 
983       DBG (5,
984            "download_firmware_file: Couldn't open firmware file `%s': %s\n",
985            filename, strerror (errno));
986 
987       dir = opendir (dirname);
988       if (!dir)
989         {
990           DBG (5, "download_firmware: couldn't open directory `%s': %s\n",
991                dirname, strerror (errno));
992           status = SANE_STATUS_INVAL;
993         }
994       if (status == SANE_STATUS_GOOD)
995         {
996           do
997             {
998               direntry = readdir (dir);
999               if (direntry
1000                   && (strncasecmp (direntry->d_name, basename, PATH_MAX) == 0))
1001                 {
1002                   int len = snprintf (filename, sizeof(filename), "%s%s%s",
1003                                       dirname, PATH_SEP, direntry->d_name);
1004                   if ((len < 0) || (len >= (int) sizeof(filename)))
1005                     {
1006                       DBG (5, "download_firmware: filepath `%s%s%s' too long\n",
1007                            dirname, PATH_SEP, direntry->d_name);
1008                       status = SANE_STATUS_INVAL;
1009                     }
1010                   break;
1011                 }
1012             }
1013           while (direntry != 0);
1014           if (direntry == 0)
1015             {
1016               DBG (5, "download_firmware: file `%s' not found\n", filename);
1017               status = SANE_STATUS_INVAL;
1018             }
1019           closedir (dir);
1020         }
1021       if (status == SANE_STATUS_GOOD)
1022         {
1023           DBG (5, "download_firmware: trying %s\n", filename);
1024           f = fopen (filename, "rb");
1025           if (!f)
1026             {
1027               DBG (5,
1028                    "download_firmware_file: Couldn't open firmware file `%s': %s\n",
1029                    filename, strerror (errno));
1030               status = SANE_STATUS_INVAL;
1031             }
1032         }
1033 
1034       if (status != SANE_STATUS_GOOD)
1035         {
1036           DBG (0, "Couldn't open firmware file (`%s'): %s\n",
1037                filename, strerror (errno));
1038         }
1039     }
1040 
1041   if (status == SANE_STATUS_GOOD)
1042     {
1043       fseek (f, 0, SEEK_END);
1044       size = ftell (f);
1045       fseek (f, 0, SEEK_SET);
1046       if (size == -1)
1047         {
1048           DBG (1, "download_firmware_file: error getting size of "
1049                "firmware file \"%s\": %s\n", filename, strerror (errno));
1050           status = SANE_STATUS_INVAL;
1051         }
1052     }
1053 
1054   if (status == SANE_STATUS_GOOD)
1055     {
1056       DBG (5, "firmware size: %d\n", size);
1057       buf = (SANE_Byte *) malloc (size);
1058       if (!buf)
1059         {
1060           DBG (1, "download_firmware_file: cannot allocate %d bytes "
1061                "for firmware\n", size);
1062           status = SANE_STATUS_NO_MEM;
1063         }
1064     }
1065 
1066   if (status == SANE_STATUS_GOOD)
1067     {
1068       int bytes_read = fread (buf, 1, size, f);
1069       if (bytes_read != size)
1070         {
1071           DBG (1, "download_firmware_file: problem reading firmware "
1072                "file \"%s\": %s\n", filename, strerror (errno));
1073           status = SANE_STATUS_INVAL;
1074         }
1075     }
1076 
1077   if (f)
1078     fclose (f);
1079 
1080   if (status == SANE_STATUS_GOOD)
1081     {
1082       status = gt68xx_device_download_firmware (dev, buf, size);
1083       if (status != SANE_STATUS_GOOD)
1084         {
1085           DBG (1, "download_firmware_file: firmware download failed: %s\n",
1086                sane_strstatus (status));
1087         }
1088     }
1089 
1090   if (buf)
1091     free (buf);
1092 
1093   return status;
1094 }
1095 
1096 /** probe for gt68xx devices
1097  * This function scan usb and try to attached to scanner
1098  * configured in gt68xx.conf .
1099  */
probe_gt68xx_devices(void)1100 static SANE_Status probe_gt68xx_devices(void)
1101 {
1102   SANE_Char line[PATH_MAX];
1103   SANE_Char *word;
1104   SANE_String_Const cp;
1105   SANE_Int linenumber;
1106   GT68xx_Device *dev;
1107   FILE *fp;
1108 
1109   /* set up for no new devices detected at first */
1110   new_dev = 0;
1111   new_dev_len = 0;
1112   new_dev_alloced = 0;
1113 
1114   /* mark already detected devices as missing, during device probe
1115    * detected devices will clear this flag */
1116   dev = first_dev;
1117   while(dev!=NULL)
1118     {
1119       dev->missing = SANE_TRUE;
1120       dev = dev->next;
1121     }
1122 
1123   fp = sanei_config_open (GT68XX_CONFIG_FILE);
1124   if (!fp)
1125     {
1126       /* default to /dev/usb/scanner instead of insisting on config file */
1127       DBG (3, "sane_init: couldn't open config file `%s': %s. Using "
1128            "/dev/usb/scanner directly\n", GT68XX_CONFIG_FILE,
1129            strerror (errno));
1130       attach ("/dev/usb/scanner", 0, SANE_FALSE);
1131       return SANE_STATUS_GOOD;
1132     }
1133 
1134   little_endian = calc_little_endian ();
1135   DBG (5, "sane_init: %s endian machine\n", little_endian ? "little" : "big");
1136 
1137   linenumber = 0;
1138   DBG (4, "sane_init: reading config file `%s'\n", GT68XX_CONFIG_FILE);
1139   while (sanei_config_read (line, sizeof (line), fp))
1140     {
1141       word = 0;
1142       linenumber++;
1143 
1144       cp = sanei_config_get_string (line, &word);
1145       if (!word || cp == line)
1146         {
1147           DBG (6, "sane_init: config file line %d: ignoring empty line\n",
1148                linenumber);
1149           if (word)
1150             free (word);
1151           continue;
1152         }
1153       if (word[0] == '#')
1154         {
1155           DBG (6, "sane_init: config file line %d: ignoring comment line\n",
1156                linenumber);
1157           free (word);
1158           continue;
1159         }
1160 
1161       if (strcmp (word, "firmware") == 0)
1162         {
1163           free (word);
1164           word = 0;
1165           cp = sanei_config_get_string (cp, &word);
1166           if (word)
1167             {
1168               int i;
1169               for (i = 0; i < new_dev_len; i++)
1170                 {
1171                   new_dev[i]->model->firmware_name = word;
1172                   DBG (5, "sane_init: device %s: firmware will be loaded "
1173                        "from %s\n", new_dev[i]->model->name,
1174                        new_dev[i]->model->firmware_name);
1175                 }
1176               if (i == 0)
1177                 {
1178                   DBG (5, "sane_init: firmware %s can't be loaded, set device "
1179                        "first\n", word);
1180                   free (word);
1181                 }
1182             }
1183           else
1184             {
1185               DBG (3, "sane_init: option `firmware' needs a parameter\n");
1186             }
1187         }
1188       else if (strcmp (word, "vendor") == 0)
1189         {
1190           free (word);
1191           word = 0;
1192           cp = sanei_config_get_string (cp, &word);
1193           if (word)
1194             {
1195               int i;
1196 
1197               for (i = 0; i < new_dev_len; i++)
1198                 {
1199                   new_dev[i]->model->vendor = word;
1200                   DBG (5, "sane_init: device %s: vendor name set to %s\n",
1201                        new_dev[i]->model->name, new_dev[i]->model->vendor);
1202                 }
1203               if (i == 0)
1204                 {
1205                   DBG (5, "sane_init: can't set vendor name %s, set device "
1206                        "first\n", word);
1207                   free (word);
1208                 }
1209             }
1210           else
1211             {
1212               DBG (3, "sane_init: option `vendor' needs a parameter\n");
1213             }
1214         }
1215       else if (strcmp (word, "model") == 0)
1216         {
1217           free (word);
1218           word = 0;
1219           cp = sanei_config_get_string (cp, &word);
1220           if (word)
1221             {
1222               int i;
1223               for (i = 0; i < new_dev_len; i++)
1224                 {
1225                   new_dev[i]->model->model = word;
1226                   DBG (5, "sane_init: device %s: model name set to %s\n",
1227                        new_dev[i]->model->name, new_dev[i]->model->model);
1228                 }
1229               if (i == 0)
1230                 {
1231                   DBG (5, "sane_init: can't set model name %s, set device "
1232                        "first\n", word);
1233                   free (word);
1234                 }
1235             }
1236           else
1237             {
1238               DBG (3, "sane_init: option `model' needs a parameter\n");
1239             }
1240         }
1241       else if (strcmp (word, "override") == 0)
1242         {
1243           free (word);
1244           word = 0;
1245           cp = sanei_config_get_string (cp, &word);
1246           if (word)
1247             {
1248               int i;
1249               for (i = 0; i < new_dev_len; i++)
1250                 {
1251                   SANE_Status status;
1252                   GT68xx_Device *dev = new_dev[i];
1253                   GT68xx_Model *model;
1254                   if (gt68xx_device_get_model (word, &model) == SANE_TRUE)
1255                     {
1256                       status = gt68xx_device_set_model (dev, model);
1257                       if (status != SANE_STATUS_GOOD)
1258                         DBG (1, "sane_init: couldn't override model: %s\n",
1259                              sane_strstatus (status));
1260                       else
1261                         DBG (5, "sane_init: new model set to %s\n",
1262                              dev->model->name);
1263                     }
1264                   else
1265                     {
1266                       DBG (1, "sane_init: override: model %s not found\n",
1267                            word);
1268                     }
1269                 }
1270               if (i == 0)
1271                 DBG (5, "sane_init: can't override model to %s, set device "
1272                      "first\n", word);
1273               free (word);
1274             }
1275           else
1276             {
1277               DBG (3, "sane_init: option `override' needs a parameter\n");
1278             }
1279         }
1280       else if (strcmp (word, "afe") == 0)
1281         {
1282           GT68xx_AFE_Parameters afe = {0, 0, 0, 0, 0, 0};
1283           SANE_Status status;
1284 
1285           free (word);
1286           word = 0;
1287 
1288           status = get_afe_values (cp, &afe);
1289           if (status == SANE_STATUS_GOOD)
1290             {
1291               int i;
1292               for (i = 0; i < new_dev_len; i++)
1293                 {
1294                   new_dev[i]->model->afe_params = afe;
1295                   DBG (5, "sane_init: device %s: setting new afe values\n",
1296                        new_dev[i]->model->name);
1297                 }
1298               if (i == 0)
1299                 DBG (5,
1300                      "sane_init: can't set afe values, set device first\n");
1301             }
1302           else
1303             DBG (3, "sane_init: can't set afe values\n");
1304         }
1305       else
1306         {
1307           new_dev_len = 0;
1308           DBG (4, "sane_init: config file line %d: trying to attach `%s'\n",
1309                linenumber, line);
1310           sanei_usb_attach_matching_devices (line, attach_one_device);
1311           if (word)
1312             free (word);
1313           word = 0;
1314         }
1315     }
1316 
1317   if (new_dev_alloced > 0)
1318     {
1319       new_dev_len = new_dev_alloced = 0;
1320       free (new_dev);
1321     }
1322 
1323   fclose (fp);
1324   return SANE_STATUS_GOOD;
1325 }
1326 
1327 /* -------------------------- SANE API functions ------------------------- */
1328 
1329 SANE_Status
sane_init(SANE_Int * version_code,SANE_Auth_Callback authorize)1330 sane_init (SANE_Int * version_code, SANE_Auth_Callback authorize)
1331 {
1332   SANE_Status status;
1333 
1334   DBG_INIT ();
1335 #ifdef DBG_LEVEL
1336   if (DBG_LEVEL > 0)
1337     {
1338       DBG (5, "sane_init: debug options are enabled, handle with care\n");
1339       debug_options = SANE_TRUE;
1340     }
1341 #endif
1342   DBG (2, "SANE GT68xx backend version %d.%d build %d from %s\n", SANE_CURRENT_MAJOR,
1343        SANE_CURRENT_MINOR, BUILD, PACKAGE_STRING);
1344 
1345   if (version_code)
1346     *version_code = SANE_VERSION_CODE (SANE_CURRENT_MAJOR, SANE_CURRENT_MINOR, BUILD);
1347 
1348   DBG (5, "sane_init: authorize %s null\n", authorize ? "!=" : "==");
1349 
1350   sanei_usb_init ();
1351 
1352   num_devices = 0;
1353   first_dev = 0;
1354   first_handle = 0;
1355   devlist = 0;
1356   new_dev = 0;
1357   new_dev_len = 0;
1358   new_dev_alloced = 0;
1359 
1360   status = probe_gt68xx_devices ();
1361   DBG (5, "sane_init: exit\n");
1362 
1363   return status;
1364 }
1365 
1366 void
sane_exit(void)1367 sane_exit (void)
1368 {
1369   GT68xx_Device *dev, *next;
1370 
1371   DBG (5, "sane_exit: start\n");
1372   sanei_usb_exit();
1373   for (dev = first_dev; dev; dev = next)
1374     {
1375       next = dev->next;
1376       gt68xx_device_free (dev);
1377     }
1378   first_dev = 0;
1379   first_handle = 0;
1380   if (devlist)
1381     free (devlist);
1382   devlist = 0;
1383 
1384   DBG (5, "sane_exit: exit\n");
1385 }
1386 
1387 SANE_Status
sane_get_devices(const SANE_Device *** device_list,SANE_Bool local_only)1388 sane_get_devices (const SANE_Device *** device_list, SANE_Bool local_only)
1389 {
1390   GT68xx_Device *dev;
1391   SANE_Int dev_num;
1392 
1393   DBG (5, "sane_get_devices: start: local_only = %s\n",
1394        local_only == SANE_TRUE ? "true" : "false");
1395 
1396   /* hot-plug case : detection of newly connected scanners */
1397   sanei_usb_scan_devices ();
1398   probe_gt68xx_devices ();
1399 
1400   if (devlist)
1401     free (devlist);
1402 
1403   devlist = malloc ((num_devices + 1) * sizeof (devlist[0]));
1404   if (!devlist)
1405     return SANE_STATUS_NO_MEM;
1406 
1407   dev_num = 0;
1408   dev = first_dev;
1409   while(dev!=NULL)
1410     {
1411       SANE_Device *sane_device;
1412 
1413       /* don't return devices that have been unplugged */
1414       if(dev->missing==SANE_FALSE)
1415         {
1416           sane_device = malloc (sizeof (*sane_device));
1417           if (!sane_device)
1418             return SANE_STATUS_NO_MEM;
1419           sane_device->name = dev->file_name;
1420           sane_device->vendor = dev->model->vendor;
1421           sane_device->model = dev->model->model;
1422           sane_device->type = strdup ("flatbed scanner");
1423           devlist[dev_num] = sane_device;
1424           dev_num++;
1425         }
1426 
1427       /* next device */
1428       dev = dev->next;
1429     }
1430   devlist[dev_num] = 0;
1431 
1432   *device_list = devlist;
1433 
1434   DBG (5, "sane_get_devices: exit\n");
1435 
1436   return SANE_STATUS_GOOD;
1437 }
1438 
1439 SANE_Status
sane_open(SANE_String_Const devicename,SANE_Handle * handle)1440 sane_open (SANE_String_Const devicename, SANE_Handle * handle)
1441 {
1442   GT68xx_Device *dev;
1443   SANE_Status status;
1444   GT68xx_Scanner *s;
1445   SANE_Bool power_ok;
1446 
1447   DBG (5, "sane_open: start (devicename = `%s')\n", devicename);
1448 
1449   if (devicename[0])
1450     {
1451       /* test for gt68xx short hand name */
1452       if(strcmp(devicename,"gt68xx")!=0)
1453         {
1454           for (dev = first_dev; dev; dev = dev->next)
1455             if (strcmp (dev->file_name, devicename) == 0)
1456               break;
1457 
1458           if (!dev)
1459             {
1460               DBG (5, "sane_open: couldn't find `%s' in devlist, trying attach\n",
1461                    devicename);
1462               RIE (attach (devicename, &dev, SANE_TRUE));
1463             }
1464           else
1465             DBG (5, "sane_open: found `%s' in devlist\n", dev->model->name);
1466         }
1467       else
1468         {
1469           dev = first_dev;
1470           if (dev)
1471             {
1472               devicename = dev->file_name;
1473               DBG (5, "sane_open: default empty devicename, using first device `%s'\n", devicename);
1474             }
1475         }
1476     }
1477   else
1478     {
1479       /* empty devicname -> use first device */
1480       dev = first_dev;
1481       if (dev)
1482         {
1483           devicename = dev->file_name;
1484           DBG (5, "sane_open: empty devicename, trying `%s'\n", devicename);
1485         }
1486     }
1487 
1488   if (!dev)
1489     return SANE_STATUS_INVAL;
1490 
1491   RIE (gt68xx_device_open (dev, devicename));
1492   RIE (gt68xx_device_activate (dev));
1493 
1494   if (dev->model->flags & GT68XX_FLAG_UNTESTED)
1495     {
1496       DBG (0, "WARNING: Your scanner is not fully supported or at least \n");
1497       DBG (0, "         had only limited testing. Please be careful and \n");
1498       DBG (0, "         report any failure/success to \n");
1499       DBG (0, "         sane-devel@alioth-lists.debian.net. Please provide as many\n");
1500       DBG (0, "         details as possible, e.g. the exact name of your\n");
1501       DBG (0, "         scanner and what does (not) work.\n");
1502     }
1503 
1504   if (dev->manual_selection)
1505     {
1506       DBG (0, "WARNING: You have manually added the ids of your scanner \n");
1507       DBG (0,
1508            "         to gt68xx.conf. Please use an appropriate override \n");
1509       DBG (0,
1510            "         for your scanner. Use extreme care and switch off \n");
1511       DBG (0,
1512            "         the scanner immediately if you hear unusual noise. \n");
1513       DBG (0, "         Please report any success to \n");
1514       DBG (0, "         sane-devel@alioth-lists.debian.net. Please provide as many\n");
1515       DBG (0, "         details as possible, e.g. the exact name of your\n");
1516       DBG (0, "         scanner, ids, settings etc.\n");
1517 
1518       if (strcmp (dev->model->name, "unknown-scanner") == 0)
1519         {
1520           GT68xx_USB_Device_Entry *entry;
1521 
1522           DBG (0,
1523                "ERROR: You haven't chosen an override in gt68xx.conf. Please use \n");
1524           DBG (0, "       one of the following: \n");
1525 
1526           for (entry = gt68xx_usb_device_list; entry->model; ++entry)
1527             {
1528               if (strcmp (entry->model->name, "unknown-scanner") != 0)
1529                 DBG (0, "       %s\n", entry->model->name);
1530             }
1531           return SANE_STATUS_UNSUPPORTED;
1532         }
1533     }
1534 
1535   /* The firmware check is disabled by default because it may confuse
1536      some scanners: So the firmware is loaded every time. */
1537 #if 0
1538   RIE (gt68xx_device_check_firmware (dev, &firmware_loaded));
1539   firmware_loaded = SANE_FALSE;
1540   if (firmware_loaded)
1541     DBG (3, "sane_open: firmware already loaded, skipping load\n");
1542   else
1543     RIE (download_firmware_file (dev));
1544   /*  RIE (gt68xx_device_check_firmware (dev, &firmware_loaded)); */
1545   if (!firmware_loaded)
1546     {
1547       DBG (1, "sane_open: firmware still not loaded? Proceeding anyway\n");
1548       /* return SANE_STATUS_IO_ERROR; */
1549     }
1550 #else
1551   RIE (download_firmware_file (dev));
1552 #endif
1553 
1554   RIE (gt68xx_device_get_id (dev));
1555 
1556   if (!(dev->model->flags & GT68XX_FLAG_NO_STOP))
1557     RIE (gt68xx_device_stop_scan (dev));
1558 
1559   RIE (gt68xx_device_get_power_status (dev, &power_ok));
1560   if (power_ok)
1561     {
1562       DBG (5, "sane_open: power ok\n");
1563     }
1564   else
1565     {
1566       DBG (0, "sane_open: power control failure: check power plug!\n");
1567       return SANE_STATUS_IO_ERROR;
1568     }
1569 
1570   RIE (gt68xx_scanner_new (dev, &s));
1571   RIE (gt68xx_device_lamp_control (s->dev, SANE_TRUE, SANE_FALSE));
1572   gettimeofday (&s->lamp_on_time, 0);
1573 
1574   /* insert newly opened handle into list of open handles: */
1575   s->next = first_handle;
1576   first_handle = s;
1577   *handle = s;
1578   s->scanning = SANE_FALSE;
1579   s->first_scan = SANE_TRUE;
1580   s->gamma_table = 0;
1581   s->calibrated = SANE_FALSE;
1582   RIE (init_options (s));
1583   dev->gray_mode_color = 0x02;
1584 
1585   /* try to restore calibration from file */
1586   if((s->dev->model->flags & GT68XX_FLAG_HAS_CALIBRATE))
1587     {
1588       /* error restoring calibration is non blocking */
1589       gt68xx_read_calibration(s);
1590     }
1591 
1592   DBG (5, "sane_open: exit\n");
1593 
1594   return SANE_STATUS_GOOD;
1595 }
1596 
1597 void
sane_close(SANE_Handle handle)1598 sane_close (SANE_Handle handle)
1599 {
1600   GT68xx_Scanner *prev, *s;
1601   GT68xx_Device *dev;
1602 
1603   DBG (5, "sane_close: start\n");
1604 
1605   /* remove handle from list of open handles: */
1606   prev = 0;
1607   for (s = first_handle; s; s = s->next)
1608     {
1609       if (s == handle)
1610         break;
1611       prev = s;
1612     }
1613   if (!s)
1614     {
1615       DBG (5, "close: invalid handle %p\n", handle);
1616       return;                   /* oops, not a handle we know about */
1617     }
1618 
1619   if (prev)
1620     prev->next = s->next;
1621   else
1622     first_handle = s->next;
1623 
1624   if (s->val[OPT_LAMP_OFF_AT_EXIT].w == SANE_TRUE)
1625     gt68xx_device_lamp_control (s->dev, SANE_FALSE, SANE_FALSE);
1626 
1627   dev = s->dev;
1628 
1629   free (s->val[OPT_MODE].s);
1630   free (s->val[OPT_GRAY_MODE_COLOR].s);
1631   free (s->val[OPT_SOURCE].s);
1632   free (dev->file_name);
1633   free ((void *)(size_t)s->opt[OPT_RESOLUTION].constraint.word_list);
1634 
1635   gt68xx_scanner_free (s);
1636 
1637   gt68xx_device_fix_descriptor (dev);
1638 
1639   gt68xx_device_deactivate (dev);
1640   gt68xx_device_close (dev);
1641 
1642   DBG (5, "sane_close: exit\n");
1643 }
1644 
1645 const SANE_Option_Descriptor *
sane_get_option_descriptor(SANE_Handle handle,SANE_Int option)1646 sane_get_option_descriptor (SANE_Handle handle, SANE_Int option)
1647 {
1648   GT68xx_Scanner *s = handle;
1649 
1650   if ((unsigned) option >= NUM_OPTIONS)
1651     return 0;
1652   DBG (5, "sane_get_option_descriptor: option = %s (%d)\n",
1653        s->opt[option].name, option);
1654   return s->opt + option;
1655 }
1656 
1657 SANE_Status
sane_control_option(SANE_Handle handle,SANE_Int option,SANE_Action action,void * val,SANE_Int * info)1658 sane_control_option (SANE_Handle handle, SANE_Int option,
1659                      SANE_Action action, void *val, SANE_Int * info)
1660 {
1661   GT68xx_Scanner *s = handle;
1662   SANE_Status status = SANE_STATUS_GOOD;
1663   SANE_Word cap;
1664   SANE_Int myinfo = 0;
1665 
1666   DBG (5, "sane_control_option: start: action = %s, option = %s (%d)\n",
1667        (action == SANE_ACTION_GET_VALUE) ? "get" :
1668        (action == SANE_ACTION_SET_VALUE) ? "set" :
1669        (action == SANE_ACTION_SET_AUTO) ? "set_auto" : "unknown",
1670        s->opt[option].name, option);
1671 
1672   if (info)
1673     *info = 0;
1674 
1675   if (s->scanning)
1676     {
1677       DBG (1, "sane_control_option: don't call this function while "
1678            "scanning (option = %s (%d))\n", s->opt[option].name, option);
1679 
1680       return SANE_STATUS_DEVICE_BUSY;
1681     }
1682   if (option >= NUM_OPTIONS || option < 0)
1683     {
1684       DBG (1, "sane_control_option: option %d >= NUM_OPTIONS || option < 0\n",
1685            option);
1686       return SANE_STATUS_INVAL;
1687     }
1688 
1689   cap = s->opt[option].cap;
1690 
1691   if (!SANE_OPTION_IS_ACTIVE (cap))
1692     {
1693       DBG (2, "sane_control_option: option %d is inactive\n", option);
1694       return SANE_STATUS_INVAL;
1695     }
1696 
1697   if (action == SANE_ACTION_GET_VALUE)
1698     {
1699       switch (option)
1700         {
1701           /* word options: */
1702         case OPT_NUM_OPTS:
1703         case OPT_RESOLUTION:
1704         case OPT_BIT_DEPTH:
1705         case OPT_FULL_SCAN:
1706         case OPT_COARSE_CAL:
1707         case OPT_COARSE_CAL_ONCE:
1708         case OPT_QUALITY_CAL:
1709         case OPT_BACKTRACK:
1710         case OPT_BACKTRACK_LINES:
1711         case OPT_PREVIEW:
1712         case OPT_LAMP_OFF_AT_EXIT:
1713         case OPT_AUTO_WARMUP:
1714         case OPT_GAMMA_VALUE:
1715         case OPT_THRESHOLD:
1716         case OPT_TL_X:
1717         case OPT_TL_Y:
1718         case OPT_BR_X:
1719         case OPT_BR_Y:
1720           *(SANE_Word *) val = s->val[option].w;
1721           break;
1722           /* string options: */
1723         case OPT_MODE:
1724         case OPT_GRAY_MODE_COLOR:
1725         case OPT_SOURCE:
1726           strcpy (val, s->val[option].s);
1727           break;
1728         case OPT_NEED_CALIBRATION_SW:
1729           *(SANE_Bool *) val = !s->calibrated;
1730           break;
1731         case OPT_PAGE_LOADED_SW:
1732           s->dev->model->command_set->document_present (s->dev, val);
1733           break;
1734         default:
1735           DBG (2, "sane_control_option: can't get unknown option %d\n",
1736                option);
1737         }
1738     }
1739   else if (action == SANE_ACTION_SET_VALUE)
1740     {
1741       if (!SANE_OPTION_IS_SETTABLE (cap))
1742         {
1743           DBG (2, "sane_control_option: option %d is not settable\n", option);
1744           return SANE_STATUS_INVAL;
1745         }
1746 
1747       status = sanei_constrain_value (s->opt + option, val, &myinfo);
1748 
1749       if (status != SANE_STATUS_GOOD)
1750         {
1751           DBG (2, "sane_control_option: sanei_constrain_value returned %s\n",
1752                sane_strstatus (status));
1753           return status;
1754         }
1755 
1756       switch (option)
1757         {
1758         case OPT_RESOLUTION:
1759         case OPT_BIT_DEPTH:
1760         case OPT_FULL_SCAN:
1761         case OPT_PREVIEW:
1762         case OPT_TL_X:
1763         case OPT_TL_Y:
1764         case OPT_BR_X:
1765         case OPT_BR_Y:
1766           s->val[option].w = *(SANE_Word *) val;
1767           RIE (calc_parameters (s));
1768           myinfo |= SANE_INFO_RELOAD_PARAMS;
1769           break;
1770         case OPT_LAMP_OFF_AT_EXIT:
1771         case OPT_AUTO_WARMUP:
1772         case OPT_COARSE_CAL_ONCE:
1773         case OPT_BACKTRACK_LINES:
1774         case OPT_QUALITY_CAL:
1775         case OPT_GAMMA_VALUE:
1776         case OPT_THRESHOLD:
1777           s->val[option].w = *(SANE_Word *) val;
1778           break;
1779         case OPT_GRAY_MODE_COLOR:
1780           if (strcmp (s->val[option].s, val) != 0)
1781             {                   /* something changed */
1782               if (s->val[option].s)
1783                 free (s->val[option].s);
1784               s->val[option].s = strdup (val);
1785             }
1786           break;
1787         case OPT_SOURCE:
1788           if (strcmp (s->val[option].s, val) != 0)
1789             {                   /* something changed */
1790               if (s->val[option].s)
1791                 free (s->val[option].s);
1792               s->val[option].s = strdup (val);
1793               if (strcmp (s->val[option].s, "Transparency Adapter") == 0)
1794                 {
1795                   RIE (gt68xx_device_lamp_control
1796                        (s->dev, SANE_FALSE, SANE_TRUE));
1797                   x_range.max = s->dev->model->x_size_ta;
1798                   y_range.max = s->dev->model->y_size_ta;
1799                 }
1800               else
1801                 {
1802                   RIE (gt68xx_device_lamp_control
1803                        (s->dev, SANE_TRUE, SANE_FALSE));
1804                   x_range.max = s->dev->model->x_size;
1805                   y_range.max = s->dev->model->y_size;
1806                 }
1807               s->first_scan = SANE_TRUE;
1808               myinfo |= SANE_INFO_RELOAD_PARAMS | SANE_INFO_RELOAD_OPTIONS;
1809               gettimeofday (&s->lamp_on_time, 0);
1810             }
1811           break;
1812         case OPT_MODE:
1813           if (s->val[option].s)
1814             free (s->val[option].s);
1815           s->val[option].s = strdup (val);
1816           if (strcmp (s->val[option].s, SANE_VALUE_SCAN_MODE_LINEART) == 0)
1817             {
1818               ENABLE (OPT_THRESHOLD);
1819               DISABLE (OPT_BIT_DEPTH);
1820               ENABLE (OPT_GRAY_MODE_COLOR);
1821             }
1822           else
1823             {
1824               DISABLE (OPT_THRESHOLD);
1825               if (strcmp (s->val[option].s, SANE_VALUE_SCAN_MODE_GRAY) == 0)
1826                 {
1827                   RIE (create_bpp_list (s, s->dev->model->bpp_gray_values));
1828                   ENABLE (OPT_GRAY_MODE_COLOR);
1829                 }
1830               else
1831                 {
1832                   RIE (create_bpp_list (s, s->dev->model->bpp_color_values));
1833                   DISABLE (OPT_GRAY_MODE_COLOR);
1834                 }
1835               if (s->bpp_list[0] < 2)
1836                 DISABLE (OPT_BIT_DEPTH);
1837               else
1838                 ENABLE (OPT_BIT_DEPTH);
1839             }
1840           RIE (calc_parameters (s));
1841           myinfo |= SANE_INFO_RELOAD_PARAMS | SANE_INFO_RELOAD_OPTIONS;
1842           break;
1843 
1844         case OPT_COARSE_CAL:
1845           s->val[option].w = *(SANE_Word *) val;
1846           if (s->val[option].w == SANE_TRUE)
1847             {
1848               ENABLE (OPT_COARSE_CAL_ONCE);
1849               s->first_scan = SANE_TRUE;
1850             }
1851           else
1852             {
1853               DISABLE (OPT_COARSE_CAL_ONCE);
1854             }
1855           myinfo |= SANE_INFO_RELOAD_OPTIONS;
1856           break;
1857 
1858         case OPT_BACKTRACK:
1859           s->val[option].w = *(SANE_Word *) val;
1860           if (s->val[option].w == SANE_TRUE)
1861             ENABLE (OPT_BACKTRACK_LINES);
1862           else
1863             DISABLE (OPT_BACKTRACK_LINES);
1864           myinfo |= SANE_INFO_RELOAD_OPTIONS;
1865           break;
1866 
1867         case OPT_CALIBRATE:
1868           status = gt68xx_sheetfed_scanner_calibrate (s);
1869           myinfo |= SANE_INFO_RELOAD_OPTIONS;
1870           break;
1871 
1872         case OPT_CLEAR_CALIBRATION:
1873           gt68xx_clear_calibration (s);
1874           myinfo |= SANE_INFO_RELOAD_OPTIONS;
1875           break;
1876 
1877         default:
1878           DBG (2, "sane_control_option: can't set unknown option %d\n",
1879                option);
1880         }
1881     }
1882   else
1883     {
1884       DBG (2, "sane_control_option: unknown action %d for option %d\n",
1885            action, option);
1886       return SANE_STATUS_INVAL;
1887     }
1888   if (info)
1889     *info = myinfo;
1890 
1891   DBG (5, "sane_control_option: exit\n");
1892   return status;
1893 }
1894 
1895 SANE_Status
sane_get_parameters(SANE_Handle handle,SANE_Parameters * params)1896 sane_get_parameters (SANE_Handle handle, SANE_Parameters * params)
1897 {
1898   GT68xx_Scanner *s = handle;
1899   SANE_Status status;
1900 
1901   DBG (5, "sane_get_parameters: start\n");
1902 
1903   RIE (calc_parameters (s));
1904   if (params)
1905     *params = s->params;
1906 
1907   DBG (4, "sane_get_parameters: format=%d, last_frame=%d, lines=%d\n",
1908        s->params.format, s->params.last_frame, s->params.lines);
1909   DBG (4, "sane_get_parameters: pixels_per_line=%d, bytes per line=%d\n",
1910        s->params.pixels_per_line, s->params.bytes_per_line);
1911   DBG (3, "sane_get_parameters: pixels %dx%dx%d\n",
1912        s->params.pixels_per_line, s->params.lines, 1 << s->params.depth);
1913 
1914   DBG (5, "sane_get_parameters: exit\n");
1915 
1916   return SANE_STATUS_GOOD;
1917 }
1918 
1919 SANE_Status
sane_start(SANE_Handle handle)1920 sane_start (SANE_Handle handle)
1921 {
1922   GT68xx_Scanner *s = handle;
1923   GT68xx_Scan_Request scan_request;
1924   GT68xx_Scan_Parameters scan_params;
1925   SANE_Status status;
1926   SANE_Int i, gamma_size;
1927   unsigned int *buffer_pointers[3];
1928   SANE_Bool document;
1929 
1930   DBG (5, "sane_start: start\n");
1931 
1932   /* First make sure we have a current parameter set.  Some of the
1933      parameters will be overwritten below, but that's OK.  */
1934   RIE (calc_parameters (s));
1935 
1936   if (s->val[OPT_TL_X].w >= s->val[OPT_BR_X].w)
1937     {
1938       DBG (0, "sane_start: top left x >= bottom right x --- exiting\n");
1939       return SANE_STATUS_INVAL;
1940     }
1941   if (s->val[OPT_TL_Y].w >= s->val[OPT_BR_Y].w)
1942     {
1943       DBG (0, "sane_start: top left y >= bottom right y --- exiting\n");
1944       return SANE_STATUS_INVAL;
1945     }
1946 
1947   if (strcmp (s->val[OPT_GRAY_MODE_COLOR].s, GT68XX_COLOR_BLUE) == 0)
1948     s->dev->gray_mode_color = 0x01;
1949   else if (strcmp (s->val[OPT_GRAY_MODE_COLOR].s, GT68XX_COLOR_GREEN) == 0)
1950     s->dev->gray_mode_color = 0x02;
1951   else
1952     s->dev->gray_mode_color = 0x03;
1953 
1954   setup_scan_request (s, &scan_request);
1955   if (!s->first_scan && s->val[OPT_COARSE_CAL_ONCE].w == SANE_TRUE)
1956     s->auto_afe = SANE_FALSE;
1957   else
1958     s->auto_afe = s->val[OPT_COARSE_CAL].w;
1959 
1960   s->dev->gamma_value = s->val[OPT_GAMMA_VALUE].w;
1961   gamma_size = s->params.depth == 16 ? 65536 : 256;
1962   s->gamma_table = malloc (sizeof (SANE_Int) * gamma_size);
1963   if (!s->gamma_table)
1964     {
1965       DBG (1, "sane_start: couldn't malloc %d bytes for gamma table\n",
1966            gamma_size);
1967       return SANE_STATUS_NO_MEM;
1968     }
1969   for (i = 0; i < gamma_size; i++)
1970     {
1971       s->gamma_table[i] =
1972         (gamma_size - 1) * pow (((double) i + 1) / (gamma_size),
1973                                 1.0 / SANE_UNFIX (s->dev->gamma_value)) + 0.5;
1974       if (s->gamma_table[i] > (gamma_size - 1))
1975         s->gamma_table[i] = (gamma_size - 1);
1976       if (s->gamma_table[i] < 0)
1977         s->gamma_table[i] = 0;
1978 #if 0
1979       printf ("%d %d\n", i, s->gamma_table[i]);
1980 #endif
1981     }
1982 
1983   if(!(s->dev->model->flags & GT68XX_FLAG_HAS_CALIBRATE))
1984     {
1985       s->calib = s->val[OPT_QUALITY_CAL].w;
1986     }
1987 
1988   if (!(s->dev->model->flags & GT68XX_FLAG_NO_STOP))
1989     RIE (gt68xx_device_stop_scan (s->dev));
1990 
1991   if (!(s->dev->model->flags & GT68XX_FLAG_SHEET_FED))
1992     RIE (gt68xx_device_carriage_home (s->dev));
1993 
1994   gt68xx_scanner_wait_for_positioning (s);
1995   gettimeofday (&s->start_time, 0);
1996 
1997   if (s->val[OPT_BACKTRACK].w == SANE_TRUE)
1998     scan_request.backtrack = SANE_TRUE;
1999   else
2000     {
2001       if (s->val[OPT_RESOLUTION].w >= s->dev->model->ydpi_no_backtrack)
2002         scan_request.backtrack = SANE_FALSE;
2003       else
2004         scan_request.backtrack = SANE_TRUE;
2005     }
2006 
2007   if (scan_request.backtrack)
2008     scan_request.backtrack_lines = s->val[OPT_BACKTRACK_LINES].w;
2009   else
2010     scan_request.backtrack_lines = 0;
2011 
2012   /* don't call calibration for scanners that use sheetfed_calibrate */
2013   if(!(s->dev->model->flags & GT68XX_FLAG_HAS_CALIBRATE))
2014     {
2015       RIE (gt68xx_scanner_calibrate (s, &scan_request));
2016     }
2017   else
2018     {
2019       s->calib = s->calibrated;
2020     }
2021 
2022   /* is possible, wait for document to be inserted before scanning */
2023   /* wait for 5 secondes max */
2024   if (s->dev->model->flags & GT68XX_FLAG_SHEET_FED
2025    && s->dev->model->command_set->document_present)
2026     {
2027       i=0;
2028       do
2029         {
2030           RIE(s->dev->model->command_set->document_present(s->dev,&document));
2031           if(document==SANE_FALSE)
2032             {
2033               i++;
2034               sleep(1);
2035             }
2036         } while ((i<5) && (document==SANE_FALSE));
2037       if(document==SANE_FALSE)
2038         {
2039           DBG (4, "sane_start: no document detected after %d s\n",i);
2040           return SANE_STATUS_NO_DOCS;
2041         }
2042     }
2043 
2044   /* some sheetfed scanners need a special operation to move
2045    * paper before starting real scan */
2046   if (s->dev->model->flags & GT68XX_FLAG_SHEET_FED)
2047     {
2048       RIE (gt68xx_sheetfed_move_to_scan_area (s, &scan_request));
2049     }
2050 
2051   /* restore calibration */
2052   if(  (s->dev->model->flags & GT68XX_FLAG_HAS_CALIBRATE)
2053      &&(s->calibrated == SANE_TRUE))
2054     {
2055       /* compute scan parameters */
2056       scan_request.calculate = SANE_TRUE;
2057       gt68xx_device_setup_scan (s->dev, &scan_request, SA_SCAN, &scan_params);
2058 
2059       /* restore settings from calibration stored */
2060       memcpy(s->dev->afe,&(s->afe_params), sizeof(GT68xx_AFE_Parameters));
2061       RIE (gt68xx_assign_calibration (s, scan_params));
2062       scan_request.calculate = SANE_FALSE;
2063     }
2064 
2065   /* send scan request to the scanner */
2066   RIE (gt68xx_scanner_start_scan (s, &scan_request, &scan_params));
2067 
2068   for (i = 0; i < scan_params.overscan_lines; ++i)
2069     RIE (gt68xx_scanner_read_line (s, buffer_pointers));
2070   DBG (4, "sane_start: wanted: dpi=%d, x=%.1f, y=%.1f, width=%.1f, "
2071        "height=%.1f, color=%s\n", scan_request.xdpi,
2072        SANE_UNFIX (scan_request.x0),
2073        SANE_UNFIX (scan_request.y0), SANE_UNFIX (scan_request.xs),
2074        SANE_UNFIX (scan_request.ys), scan_request.color ? "color" : "gray");
2075 
2076   s->line = 0;
2077   s->byte_count = s->reader->params.pixel_xs;
2078   s->total_bytes = 0;
2079   s->first_scan = SANE_FALSE;
2080 
2081 #ifdef DEBUG_BRIGHTNESS
2082   s->average_white = 0;
2083   s->max_white = 0;
2084   s->min_black = 255;
2085 #endif
2086 
2087   s->scanning = SANE_TRUE;
2088 
2089   DBG (5, "sane_start: exit\n");
2090   return SANE_STATUS_GOOD;
2091 }
2092 
2093 SANE_Status
sane_read(SANE_Handle handle,SANE_Byte * buf,SANE_Int max_len,SANE_Int * len)2094 sane_read (SANE_Handle handle, SANE_Byte * buf, SANE_Int max_len,
2095            SANE_Int * len)
2096 {
2097   GT68xx_Scanner *s = handle;
2098   SANE_Status status;
2099   static unsigned int *buffer_pointers[3];
2100   SANE_Int inflate_x;
2101   SANE_Bool lineart;
2102   SANE_Int i, color, colors;
2103 
2104   if (!s)
2105     {
2106       DBG (1, "sane_read: handle is null!\n");
2107       return SANE_STATUS_INVAL;
2108     }
2109 
2110   if (!buf)
2111     {
2112       DBG (1, "sane_read: buf is null!\n");
2113       return SANE_STATUS_INVAL;
2114     }
2115 
2116   if (!len)
2117     {
2118       DBG (1, "sane_read: len is null!\n");
2119       return SANE_STATUS_INVAL;
2120     }
2121 
2122   *len = 0;
2123 
2124   if (!s->scanning)
2125     {
2126       DBG (3, "sane_read: scan was cancelled, is over or has not been "
2127            "initiated yet\n");
2128       return SANE_STATUS_CANCELLED;
2129     }
2130 
2131   DBG (5, "sane_read: start (line %d of %d, byte_count %d of %d)\n",
2132        s->line, s->reader->params.pixel_ys, s->byte_count,
2133        s->reader->params.pixel_xs);
2134 
2135   if (s->line >= s->reader->params.pixel_ys
2136       && s->byte_count >= s->reader->params.pixel_xs)
2137     {
2138       DBG (4, "sane_read: nothing more to scan: EOF\n");
2139       gt68xx_scanner_stop_scan(s);
2140       return SANE_STATUS_EOF;
2141     }
2142 
2143   inflate_x = s->val[OPT_RESOLUTION].w / s->dev->model->optical_xdpi;
2144   if (inflate_x > 1)
2145     DBG (5, "sane_read: inflating x by factor %d\n", inflate_x);
2146   else
2147     inflate_x = 1;
2148 
2149   lineart = (strcmp (s->val[OPT_MODE].s, SANE_VALUE_SCAN_MODE_LINEART) == 0)
2150     ? SANE_TRUE : SANE_FALSE;
2151 
2152   if (s->reader->params.color)
2153     colors = 3;
2154   else
2155     colors = 1;
2156 
2157   while ((*len) < max_len)
2158     {
2159       if (s->byte_count >= s->reader->params.pixel_xs)
2160         {
2161           if (s->line >= s->reader->params.pixel_ys)
2162             {
2163               DBG (4, "sane_read: scan complete: %d bytes, %d total\n",
2164                    *len, s->total_bytes);
2165               return SANE_STATUS_GOOD;
2166             }
2167           DBG (5, "sane_read: getting line %d of %d\n", s->line,
2168                s->reader->params.pixel_ys);
2169           RIE (gt68xx_scanner_read_line (s, buffer_pointers));
2170           s->line++;
2171           s->byte_count = 0;
2172 
2173           /* Apply gamma */
2174           for (color = 0; color < colors; color++)
2175             for (i = 0; i < s->reader->pixels_per_line; i++)
2176               {
2177                 if (s->reader->params.depth > 8)
2178                   buffer_pointers[color][i] =
2179                     s->gamma_table[buffer_pointers[color][i]];
2180                 else
2181                   buffer_pointers[color][i] =
2182                     (s->gamma_table[buffer_pointers[color][i] >> 8] << 8) +
2183                     (s->gamma_table[buffer_pointers[color][i] >> 8]);
2184               }
2185           /* mirror lines */
2186           if (s->dev->model->flags & GT68XX_FLAG_MIRROR_X)
2187             {
2188               unsigned int swap;
2189 
2190               for (color = 0; color < colors; color++)
2191                 {
2192                   for (i = 0; i < s->reader->pixels_per_line / 2; i++)
2193                     {
2194                       swap = buffer_pointers[color][i];
2195                       buffer_pointers[color][i] =
2196                         buffer_pointers[color][s->reader->pixels_per_line -
2197                                                1 - i];
2198                       buffer_pointers[color][s->reader->pixels_per_line - 1 -
2199                                              i] = swap;
2200                     }
2201                 }
2202             }
2203         }
2204       if (lineart)
2205         {
2206           SANE_Int bit;
2207           SANE_Byte threshold = s->val[OPT_THRESHOLD].w;
2208 
2209           buf[*len] = 0;
2210           for (bit = 7; bit >= 0; bit--)
2211             {
2212               SANE_Byte is_black =
2213                 (((buffer_pointers[0][s->byte_count] >> 8) & 0xff) >
2214                  threshold) ? 0 : 1;
2215               buf[*len] |= (is_black << bit);
2216               if ((7 - bit) % inflate_x == (inflate_x - 1))
2217                 s->byte_count++;
2218             }
2219         }
2220       else if (s->reader->params.color)
2221         {
2222           /* color */
2223           if (s->reader->params.depth > 8)
2224             {
2225               SANE_Int color = (s->total_bytes / 2) % 3;
2226               if ((s->total_bytes % 2) == 0)
2227                 {
2228                   if (little_endian)
2229                     buf[*len] = buffer_pointers[color][s->byte_count] & 0xff;
2230                   else
2231                     buf[*len] =
2232                       (buffer_pointers[color][s->byte_count] >> 8) & 0xff;
2233                 }
2234               else
2235                 {
2236                   if (little_endian)
2237                     buf[*len] =
2238                       (buffer_pointers[color][s->byte_count] >> 8) & 0xff;
2239                   else
2240                     buf[*len] = buffer_pointers[color][s->byte_count] & 0xff;
2241 
2242                   if (s->total_bytes % (inflate_x * 6) == (inflate_x * 6 - 1))
2243                     s->byte_count++;
2244                 }
2245             }
2246           else
2247             {
2248               SANE_Int color = s->total_bytes % 3;
2249               buf[*len] = (buffer_pointers[color][s->byte_count] >> 8) & 0xff;
2250               if (s->total_bytes % (inflate_x * 3) == (inflate_x * 3 - 1))
2251                 s->byte_count++;
2252 #ifdef DEBUG_BRIGHTNESS
2253               s->average_white += buf[*len];
2254               s->max_white =
2255                 (buf[*len] > s->max_white) ? buf[*len] : s->max_white;
2256               s->min_black =
2257                 (buf[*len] < s->min_black) ? buf[*len] : s->min_black;
2258 #endif
2259             }
2260         }
2261       else
2262         {
2263           /* gray */
2264           if (s->reader->params.depth > 8)
2265             {
2266               if ((s->total_bytes % 2) == 0)
2267                 {
2268                   if (little_endian)
2269                     buf[*len] = buffer_pointers[0][s->byte_count] & 0xff;
2270                   else
2271                     buf[*len] =
2272                       (buffer_pointers[0][s->byte_count] >> 8) & 0xff;
2273                 }
2274               else
2275                 {
2276                   if (little_endian)
2277                     buf[*len] =
2278                       (buffer_pointers[0][s->byte_count] >> 8) & 0xff;
2279                   else
2280                     buf[*len] = buffer_pointers[0][s->byte_count] & 0xff;
2281                   if (s->total_bytes % (2 * inflate_x) == (2 * inflate_x - 1))
2282                     s->byte_count++;
2283                 }
2284             }
2285           else
2286             {
2287               buf[*len] = (buffer_pointers[0][s->byte_count] >> 8) & 0xff;
2288               if (s->total_bytes % inflate_x == (inflate_x - 1))
2289                 s->byte_count++;
2290             }
2291         }
2292       (*len)++;
2293       s->total_bytes++;
2294     }
2295 
2296   DBG (4, "sane_read: exit (line %d of %d, byte_count %d of %d, %d bytes, "
2297        "%d total)\n",
2298        s->line, s->reader->params.pixel_ys, s->byte_count,
2299        s->reader->params.pixel_xs, *len, s->total_bytes);
2300   return SANE_STATUS_GOOD;
2301 }
2302 
2303 void
sane_cancel(SANE_Handle handle)2304 sane_cancel (SANE_Handle handle)
2305 {
2306   GT68xx_Scanner *s = handle;
2307 
2308   DBG (5, "sane_cancel: start\n");
2309 
2310   if (s->scanning)
2311     {
2312       s->scanning = SANE_FALSE;
2313       if (s->total_bytes != (s->params.bytes_per_line * s->params.lines))
2314         DBG (1, "sane_cancel: warning: scanned %d bytes, expected %d "
2315              "bytes\n", s->total_bytes,
2316              s->params.bytes_per_line * s->params.lines);
2317       else
2318         {
2319           struct timeval now;
2320           int secs;
2321 
2322           gettimeofday (&now, 0);
2323           secs = now.tv_sec - s->start_time.tv_sec;
2324 
2325           DBG (3,
2326                "sane_cancel: scan finished, scanned %d bytes in %d seconds\n",
2327                s->total_bytes, secs);
2328 #ifdef DEBUG_BRIGHTNESS
2329           DBG (1,
2330                "sane_cancel: average white: %d, max_white=%d, min_black=%d\n",
2331                s->average_white / s->total_bytes, s->max_white, s->min_black);
2332 #endif
2333 
2334         }
2335       /* some scanners don't like this command when cancelling a scan */
2336       sanei_usb_set_timeout (SHORT_TIMEOUT);
2337       gt68xx_device_fix_descriptor (s->dev);
2338       gt68xx_scanner_stop_scan (s);
2339       sanei_usb_set_timeout (LONG_TIMEOUT);
2340 
2341       if (s->dev->model->flags & GT68XX_FLAG_SHEET_FED)
2342         {
2343           gt68xx_device_paperfeed (s->dev);
2344         }
2345       else
2346         {
2347           sanei_usb_set_timeout (SHORT_TIMEOUT);
2348           gt68xx_scanner_wait_for_positioning (s);
2349           sanei_usb_set_timeout (LONG_TIMEOUT);
2350           gt68xx_device_carriage_home (s->dev);
2351         }
2352       if (s->gamma_table)
2353         {
2354           free (s->gamma_table);
2355           s->gamma_table = 0;
2356         }
2357     }
2358   else
2359     {
2360       DBG (4, "sane_cancel: scan has not been initiated yet, "
2361            "or it is already aborted\n");
2362     }
2363 
2364   DBG (5, "sane_cancel: exit\n");
2365   return;
2366 }
2367 
2368 SANE_Status
sane_set_io_mode(SANE_Handle handle,SANE_Bool non_blocking)2369 sane_set_io_mode (SANE_Handle handle, SANE_Bool non_blocking)
2370 {
2371   GT68xx_Scanner *s = handle;
2372 
2373   DBG (5, "sane_set_io_mode: handle = %p, non_blocking = %s\n",
2374        handle, non_blocking == SANE_TRUE ? "true" : "false");
2375 
2376   if (!s->scanning)
2377     {
2378       DBG (1, "sane_set_io_mode: not scanning\n");
2379       return SANE_STATUS_INVAL;
2380     }
2381   if (non_blocking)
2382     return SANE_STATUS_UNSUPPORTED;
2383   return SANE_STATUS_GOOD;
2384 }
2385 
2386 SANE_Status
sane_get_select_fd(SANE_Handle handle,SANE_Int * fd)2387 sane_get_select_fd (SANE_Handle handle, SANE_Int * fd)
2388 {
2389   GT68xx_Scanner *s = handle;
2390 
2391   DBG (5, "sane_get_select_fd: handle = %p, fd = %p\n", handle, (void *) fd);
2392 
2393   if (!s->scanning)
2394     {
2395       DBG (1, "sane_get_select_fd: not scanning\n");
2396       return SANE_STATUS_INVAL;
2397     }
2398   return SANE_STATUS_UNSUPPORTED;
2399 }
2400 
2401 /* vim: set sw=2 cino=>2se-1sn-1s{s^-1st0(0u0 smarttab expandtab: */
2402