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                 DBG (5, "sane_init: firmware %s can't be loaded, set device "
1178                      "first\n", word);
1179             }
1180           else
1181             {
1182               DBG (3, "sane_init: option `firmware' needs a parameter\n");
1183             }
1184         }
1185       else if (strcmp (word, "vendor") == 0)
1186         {
1187           free (word);
1188           word = 0;
1189           cp = sanei_config_get_string (cp, &word);
1190           if (word)
1191             {
1192               int i;
1193 
1194               for (i = 0; i < new_dev_len; i++)
1195                 {
1196                   new_dev[i]->model->vendor = word;
1197                   DBG (5, "sane_init: device %s: vendor name set to %s\n",
1198                        new_dev[i]->model->name, new_dev[i]->model->vendor);
1199                 }
1200               if (i == 0)
1201                 DBG (5, "sane_init: can't set vendor name %s, set device "
1202                      "first\n", word);
1203             }
1204           else
1205             {
1206               DBG (3, "sane_init: option `vendor' needs a parameter\n");
1207             }
1208         }
1209       else if (strcmp (word, "model") == 0)
1210         {
1211           free (word);
1212           word = 0;
1213           cp = sanei_config_get_string (cp, &word);
1214           if (word)
1215             {
1216               int i;
1217               for (i = 0; i < new_dev_len; i++)
1218                 {
1219                   new_dev[i]->model->model = word;
1220                   DBG (5, "sane_init: device %s: model name set to %s\n",
1221                        new_dev[i]->model->name, new_dev[i]->model->model);
1222                 }
1223               if (i == 0)
1224                 DBG (5, "sane_init: can't set model name %s, set device "
1225                      "first\n", word);
1226               free (word);
1227             }
1228           else
1229             {
1230               DBG (3, "sane_init: option `model' needs a parameter\n");
1231             }
1232         }
1233       else if (strcmp (word, "override") == 0)
1234         {
1235           free (word);
1236           word = 0;
1237           cp = sanei_config_get_string (cp, &word);
1238           if (word)
1239             {
1240               int i;
1241               for (i = 0; i < new_dev_len; i++)
1242                 {
1243                   SANE_Status status;
1244                   GT68xx_Device *dev = new_dev[i];
1245                   GT68xx_Model *model;
1246                   if (gt68xx_device_get_model (word, &model) == SANE_TRUE)
1247                     {
1248                       status = gt68xx_device_set_model (dev, model);
1249                       if (status != SANE_STATUS_GOOD)
1250                         DBG (1, "sane_init: couldn't override model: %s\n",
1251                              sane_strstatus (status));
1252                       else
1253                         DBG (5, "sane_init: new model set to %s\n",
1254                              dev->model->name);
1255                     }
1256                   else
1257                     {
1258                       DBG (1, "sane_init: override: model %s not found\n",
1259                            word);
1260                     }
1261                 }
1262               if (i == 0)
1263                 DBG (5, "sane_init: can't override model to %s, set device "
1264                      "first\n", word);
1265               free (word);
1266             }
1267           else
1268             {
1269               DBG (3, "sane_init: option `override' needs a parameter\n");
1270             }
1271         }
1272       else if (strcmp (word, "afe") == 0)
1273         {
1274           GT68xx_AFE_Parameters afe = {0, 0, 0, 0, 0, 0};
1275           SANE_Status status;
1276 
1277           free (word);
1278           word = 0;
1279 
1280           status = get_afe_values (cp, &afe);
1281           if (status == SANE_STATUS_GOOD)
1282             {
1283               int i;
1284               for (i = 0; i < new_dev_len; i++)
1285                 {
1286                   new_dev[i]->model->afe_params = afe;
1287                   DBG (5, "sane_init: device %s: setting new afe values\n",
1288                        new_dev[i]->model->name);
1289                 }
1290               if (i == 0)
1291                 DBG (5,
1292                      "sane_init: can't set afe values, set device first\n");
1293             }
1294           else
1295             DBG (3, "sane_init: can't set afe values\n");
1296         }
1297       else
1298         {
1299           new_dev_len = 0;
1300           DBG (4, "sane_init: config file line %d: trying to attach `%s'\n",
1301                linenumber, line);
1302           sanei_usb_attach_matching_devices (line, attach_one_device);
1303           if (word)
1304             free (word);
1305           word = 0;
1306         }
1307     }
1308 
1309   if (new_dev_alloced > 0)
1310     {
1311       new_dev_len = new_dev_alloced = 0;
1312       free (new_dev);
1313     }
1314 
1315   fclose (fp);
1316   return SANE_STATUS_GOOD;
1317 }
1318 
1319 /* -------------------------- SANE API functions ------------------------- */
1320 
1321 SANE_Status
sane_init(SANE_Int * version_code,SANE_Auth_Callback authorize)1322 sane_init (SANE_Int * version_code, SANE_Auth_Callback authorize)
1323 {
1324   SANE_Status status;
1325 
1326   DBG_INIT ();
1327 #ifdef DBG_LEVEL
1328   if (DBG_LEVEL > 0)
1329     {
1330       DBG (5, "sane_init: debug options are enabled, handle with care\n");
1331       debug_options = SANE_TRUE;
1332     }
1333 #endif
1334   DBG (2, "SANE GT68xx backend version %d.%d build %d from %s\n", SANE_CURRENT_MAJOR,
1335        V_MINOR, BUILD, PACKAGE_STRING);
1336 
1337   if (version_code)
1338     *version_code = SANE_VERSION_CODE (SANE_CURRENT_MAJOR, V_MINOR, BUILD);
1339 
1340   DBG (5, "sane_init: authorize %s null\n", authorize ? "!=" : "==");
1341 
1342   sanei_usb_init ();
1343 
1344   num_devices = 0;
1345   first_dev = 0;
1346   first_handle = 0;
1347   devlist = 0;
1348   new_dev = 0;
1349   new_dev_len = 0;
1350   new_dev_alloced = 0;
1351 
1352   status = probe_gt68xx_devices ();
1353   DBG (5, "sane_init: exit\n");
1354 
1355   return status;
1356 }
1357 
1358 void
sane_exit(void)1359 sane_exit (void)
1360 {
1361   GT68xx_Device *dev, *next;
1362 
1363   DBG (5, "sane_exit: start\n");
1364   sanei_usb_exit();
1365   for (dev = first_dev; dev; dev = next)
1366     {
1367       next = dev->next;
1368       gt68xx_device_free (dev);
1369     }
1370   first_dev = 0;
1371   first_handle = 0;
1372   if (devlist)
1373     free (devlist);
1374   devlist = 0;
1375 
1376   DBG (5, "sane_exit: exit\n");
1377 }
1378 
1379 SANE_Status
sane_get_devices(const SANE_Device *** device_list,SANE_Bool local_only)1380 sane_get_devices (const SANE_Device *** device_list, SANE_Bool local_only)
1381 {
1382   GT68xx_Device *dev;
1383   SANE_Int dev_num;
1384 
1385   DBG (5, "sane_get_devices: start: local_only = %s\n",
1386        local_only == SANE_TRUE ? "true" : "false");
1387 
1388   /* hot-plug case : detection of newly connected scanners */
1389   sanei_usb_scan_devices ();
1390   probe_gt68xx_devices ();
1391 
1392   if (devlist)
1393     free (devlist);
1394 
1395   devlist = malloc ((num_devices + 1) * sizeof (devlist[0]));
1396   if (!devlist)
1397     return SANE_STATUS_NO_MEM;
1398 
1399   dev_num = 0;
1400   dev = first_dev;
1401   while(dev!=NULL)
1402     {
1403       SANE_Device *sane_device;
1404 
1405       /* don't return devices that have been unplugged */
1406       if(dev->missing==SANE_FALSE)
1407         {
1408           sane_device = malloc (sizeof (*sane_device));
1409           if (!sane_device)
1410             return SANE_STATUS_NO_MEM;
1411           sane_device->name = dev->file_name;
1412           sane_device->vendor = dev->model->vendor;
1413           sane_device->model = dev->model->model;
1414           sane_device->type = strdup ("flatbed scanner");
1415           devlist[dev_num] = sane_device;
1416           dev_num++;
1417         }
1418 
1419       /* next device */
1420       dev = dev->next;
1421     }
1422   devlist[dev_num] = 0;
1423 
1424   *device_list = devlist;
1425 
1426   DBG (5, "sane_get_devices: exit\n");
1427 
1428   return SANE_STATUS_GOOD;
1429 }
1430 
1431 SANE_Status
sane_open(SANE_String_Const devicename,SANE_Handle * handle)1432 sane_open (SANE_String_Const devicename, SANE_Handle * handle)
1433 {
1434   GT68xx_Device *dev;
1435   SANE_Status status;
1436   GT68xx_Scanner *s;
1437   SANE_Bool power_ok;
1438 
1439   DBG (5, "sane_open: start (devicename = `%s')\n", devicename);
1440 
1441   if (devicename[0])
1442     {
1443       /* test for gt68xx short hand name */
1444       if(strcmp(devicename,"gt68xx")!=0)
1445         {
1446           for (dev = first_dev; dev; dev = dev->next)
1447             if (strcmp (dev->file_name, devicename) == 0)
1448               break;
1449 
1450           if (!dev)
1451             {
1452               DBG (5, "sane_open: couldn't find `%s' in devlist, trying attach\n",
1453                    devicename);
1454               RIE (attach (devicename, &dev, SANE_TRUE));
1455             }
1456           else
1457             DBG (5, "sane_open: found `%s' in devlist\n", dev->model->name);
1458         }
1459       else
1460         {
1461           dev = first_dev;
1462           if (dev)
1463             {
1464               devicename = dev->file_name;
1465               DBG (5, "sane_open: default empty devicename, using first device `%s'\n", devicename);
1466             }
1467         }
1468     }
1469   else
1470     {
1471       /* empty devicname -> use first device */
1472       dev = first_dev;
1473       if (dev)
1474         {
1475           devicename = dev->file_name;
1476           DBG (5, "sane_open: empty devicename, trying `%s'\n", devicename);
1477         }
1478     }
1479 
1480   if (!dev)
1481     return SANE_STATUS_INVAL;
1482 
1483   RIE (gt68xx_device_open (dev, devicename));
1484   RIE (gt68xx_device_activate (dev));
1485 
1486   if (dev->model->flags & GT68XX_FLAG_UNTESTED)
1487     {
1488       DBG (0, "WARNING: Your scanner is not fully supported or at least \n");
1489       DBG (0, "         had only limited testing. Please be careful and \n");
1490       DBG (0, "         report any failure/success to \n");
1491       DBG (0, "         sane-devel@alioth-lists.debian.net. Please provide as many\n");
1492       DBG (0, "         details as possible, e.g. the exact name of your\n");
1493       DBG (0, "         scanner and what does (not) work.\n");
1494     }
1495 
1496   if (dev->manual_selection)
1497     {
1498       DBG (0, "WARNING: You have manually added the ids of your scanner \n");
1499       DBG (0,
1500            "         to gt68xx.conf. Please use an appropriate override \n");
1501       DBG (0,
1502            "         for your scanner. Use extreme care and switch off \n");
1503       DBG (0,
1504            "         the scanner immediately if you hear unusual noise. \n");
1505       DBG (0, "         Please report any success to \n");
1506       DBG (0, "         sane-devel@alioth-lists.debian.net. Please provide as many\n");
1507       DBG (0, "         details as possible, e.g. the exact name of your\n");
1508       DBG (0, "         scanner, ids, settings etc.\n");
1509 
1510       if (strcmp (dev->model->name, "unknown-scanner") == 0)
1511         {
1512           GT68xx_USB_Device_Entry *entry;
1513 
1514           DBG (0,
1515                "ERROR: You haven't chosen an override in gt68xx.conf. Please use \n");
1516           DBG (0, "       one of the following: \n");
1517 
1518           for (entry = gt68xx_usb_device_list; entry->model; ++entry)
1519             {
1520               if (strcmp (entry->model->name, "unknown-scanner") != 0)
1521                 DBG (0, "       %s\n", entry->model->name);
1522             }
1523           return SANE_STATUS_UNSUPPORTED;
1524         }
1525     }
1526 
1527   /* The firmware check is disabled by default because it may confuse
1528      some scanners: So the firmware is loaded every time. */
1529 #if 0
1530   RIE (gt68xx_device_check_firmware (dev, &firmware_loaded));
1531   firmware_loaded = SANE_FALSE;
1532   if (firmware_loaded)
1533     DBG (3, "sane_open: firmware already loaded, skipping load\n");
1534   else
1535     RIE (download_firmware_file (dev));
1536   /*  RIE (gt68xx_device_check_firmware (dev, &firmware_loaded)); */
1537   if (!firmware_loaded)
1538     {
1539       DBG (1, "sane_open: firmware still not loaded? Proceeding anyway\n");
1540       /* return SANE_STATUS_IO_ERROR; */
1541     }
1542 #else
1543   RIE (download_firmware_file (dev));
1544 #endif
1545 
1546   RIE (gt68xx_device_get_id (dev));
1547 
1548   if (!(dev->model->flags & GT68XX_FLAG_NO_STOP))
1549     RIE (gt68xx_device_stop_scan (dev));
1550 
1551   RIE (gt68xx_device_get_power_status (dev, &power_ok));
1552   if (power_ok)
1553     {
1554       DBG (5, "sane_open: power ok\n");
1555     }
1556   else
1557     {
1558       DBG (0, "sane_open: power control failure: check power plug!\n");
1559       return SANE_STATUS_IO_ERROR;
1560     }
1561 
1562   RIE (gt68xx_scanner_new (dev, &s));
1563   RIE (gt68xx_device_lamp_control (s->dev, SANE_TRUE, SANE_FALSE));
1564   gettimeofday (&s->lamp_on_time, 0);
1565 
1566   /* insert newly opened handle into list of open handles: */
1567   s->next = first_handle;
1568   first_handle = s;
1569   *handle = s;
1570   s->scanning = SANE_FALSE;
1571   s->first_scan = SANE_TRUE;
1572   s->gamma_table = 0;
1573   s->calibrated = SANE_FALSE;
1574   RIE (init_options (s));
1575   dev->gray_mode_color = 0x02;
1576 
1577   /* try to restore calibration from file */
1578   if((s->dev->model->flags & GT68XX_FLAG_HAS_CALIBRATE))
1579     {
1580       /* error restoring calibration is non blocking */
1581       gt68xx_read_calibration(s);
1582     }
1583 
1584   DBG (5, "sane_open: exit\n");
1585 
1586   return SANE_STATUS_GOOD;
1587 }
1588 
1589 void
sane_close(SANE_Handle handle)1590 sane_close (SANE_Handle handle)
1591 {
1592   GT68xx_Scanner *prev, *s;
1593   GT68xx_Device *dev;
1594 
1595   DBG (5, "sane_close: start\n");
1596 
1597   /* remove handle from list of open handles: */
1598   prev = 0;
1599   for (s = first_handle; s; s = s->next)
1600     {
1601       if (s == handle)
1602         break;
1603       prev = s;
1604     }
1605   if (!s)
1606     {
1607       DBG (5, "close: invalid handle %p\n", handle);
1608       return;                   /* oops, not a handle we know about */
1609     }
1610 
1611   if (prev)
1612     prev->next = s->next;
1613   else
1614     first_handle = s->next;
1615 
1616   if (s->val[OPT_LAMP_OFF_AT_EXIT].w == SANE_TRUE)
1617     gt68xx_device_lamp_control (s->dev, SANE_FALSE, SANE_FALSE);
1618 
1619   dev = s->dev;
1620 
1621   free (s->val[OPT_MODE].s);
1622   free (s->val[OPT_GRAY_MODE_COLOR].s);
1623   free (s->val[OPT_SOURCE].s);
1624   free (dev->file_name);
1625   free ((void *)(size_t)s->opt[OPT_RESOLUTION].constraint.word_list);
1626 
1627   gt68xx_scanner_free (s);
1628 
1629   gt68xx_device_fix_descriptor (dev);
1630 
1631   gt68xx_device_deactivate (dev);
1632   gt68xx_device_close (dev);
1633 
1634   DBG (5, "sane_close: exit\n");
1635 }
1636 
1637 const SANE_Option_Descriptor *
sane_get_option_descriptor(SANE_Handle handle,SANE_Int option)1638 sane_get_option_descriptor (SANE_Handle handle, SANE_Int option)
1639 {
1640   GT68xx_Scanner *s = handle;
1641 
1642   if ((unsigned) option >= NUM_OPTIONS)
1643     return 0;
1644   DBG (5, "sane_get_option_descriptor: option = %s (%d)\n",
1645        s->opt[option].name, option);
1646   return s->opt + option;
1647 }
1648 
1649 SANE_Status
sane_control_option(SANE_Handle handle,SANE_Int option,SANE_Action action,void * val,SANE_Int * info)1650 sane_control_option (SANE_Handle handle, SANE_Int option,
1651                      SANE_Action action, void *val, SANE_Int * info)
1652 {
1653   GT68xx_Scanner *s = handle;
1654   SANE_Status status = SANE_STATUS_GOOD;
1655   SANE_Word cap;
1656   SANE_Int myinfo = 0;
1657 
1658   DBG (5, "sane_control_option: start: action = %s, option = %s (%d)\n",
1659        (action == SANE_ACTION_GET_VALUE) ? "get" :
1660        (action == SANE_ACTION_SET_VALUE) ? "set" :
1661        (action == SANE_ACTION_SET_AUTO) ? "set_auto" : "unknown",
1662        s->opt[option].name, option);
1663 
1664   if (info)
1665     *info = 0;
1666 
1667   if (s->scanning)
1668     {
1669       DBG (1, "sane_control_option: don't call this function while "
1670            "scanning (option = %s (%d))\n", s->opt[option].name, option);
1671 
1672       return SANE_STATUS_DEVICE_BUSY;
1673     }
1674   if (option >= NUM_OPTIONS || option < 0)
1675     {
1676       DBG (1, "sane_control_option: option %d >= NUM_OPTIONS || option < 0\n",
1677            option);
1678       return SANE_STATUS_INVAL;
1679     }
1680 
1681   cap = s->opt[option].cap;
1682 
1683   if (!SANE_OPTION_IS_ACTIVE (cap))
1684     {
1685       DBG (2, "sane_control_option: option %d is inactive\n", option);
1686       return SANE_STATUS_INVAL;
1687     }
1688 
1689   if (action == SANE_ACTION_GET_VALUE)
1690     {
1691       switch (option)
1692         {
1693           /* word options: */
1694         case OPT_NUM_OPTS:
1695         case OPT_RESOLUTION:
1696         case OPT_BIT_DEPTH:
1697         case OPT_FULL_SCAN:
1698         case OPT_COARSE_CAL:
1699         case OPT_COARSE_CAL_ONCE:
1700         case OPT_QUALITY_CAL:
1701         case OPT_BACKTRACK:
1702         case OPT_BACKTRACK_LINES:
1703         case OPT_PREVIEW:
1704         case OPT_LAMP_OFF_AT_EXIT:
1705         case OPT_AUTO_WARMUP:
1706         case OPT_GAMMA_VALUE:
1707         case OPT_THRESHOLD:
1708         case OPT_TL_X:
1709         case OPT_TL_Y:
1710         case OPT_BR_X:
1711         case OPT_BR_Y:
1712           *(SANE_Word *) val = s->val[option].w;
1713           break;
1714           /* string options: */
1715         case OPT_MODE:
1716         case OPT_GRAY_MODE_COLOR:
1717         case OPT_SOURCE:
1718           strcpy (val, s->val[option].s);
1719           break;
1720         case OPT_NEED_CALIBRATION_SW:
1721           *(SANE_Bool *) val = !s->calibrated;
1722           break;
1723         case OPT_PAGE_LOADED_SW:
1724           s->dev->model->command_set->document_present (s->dev, val);
1725           break;
1726         default:
1727           DBG (2, "sane_control_option: can't get unknown option %d\n",
1728                option);
1729         }
1730     }
1731   else if (action == SANE_ACTION_SET_VALUE)
1732     {
1733       if (!SANE_OPTION_IS_SETTABLE (cap))
1734         {
1735           DBG (2, "sane_control_option: option %d is not settable\n", option);
1736           return SANE_STATUS_INVAL;
1737         }
1738 
1739       status = sanei_constrain_value (s->opt + option, val, &myinfo);
1740 
1741       if (status != SANE_STATUS_GOOD)
1742         {
1743           DBG (2, "sane_control_option: sanei_constrain_value returned %s\n",
1744                sane_strstatus (status));
1745           return status;
1746         }
1747 
1748       switch (option)
1749         {
1750         case OPT_RESOLUTION:
1751         case OPT_BIT_DEPTH:
1752         case OPT_FULL_SCAN:
1753         case OPT_PREVIEW:
1754         case OPT_TL_X:
1755         case OPT_TL_Y:
1756         case OPT_BR_X:
1757         case OPT_BR_Y:
1758           s->val[option].w = *(SANE_Word *) val;
1759           RIE (calc_parameters (s));
1760           myinfo |= SANE_INFO_RELOAD_PARAMS;
1761           break;
1762         case OPT_LAMP_OFF_AT_EXIT:
1763         case OPT_AUTO_WARMUP:
1764         case OPT_COARSE_CAL_ONCE:
1765         case OPT_BACKTRACK_LINES:
1766         case OPT_QUALITY_CAL:
1767         case OPT_GAMMA_VALUE:
1768         case OPT_THRESHOLD:
1769           s->val[option].w = *(SANE_Word *) val;
1770           break;
1771         case OPT_GRAY_MODE_COLOR:
1772           if (strcmp (s->val[option].s, val) != 0)
1773             {                   /* something changed */
1774               if (s->val[option].s)
1775                 free (s->val[option].s);
1776               s->val[option].s = strdup (val);
1777             }
1778           break;
1779         case OPT_SOURCE:
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               if (strcmp (s->val[option].s, "Transparency Adapter") == 0)
1786                 {
1787                   RIE (gt68xx_device_lamp_control
1788                        (s->dev, SANE_FALSE, SANE_TRUE));
1789                   x_range.max = s->dev->model->x_size_ta;
1790                   y_range.max = s->dev->model->y_size_ta;
1791                 }
1792               else
1793                 {
1794                   RIE (gt68xx_device_lamp_control
1795                        (s->dev, SANE_TRUE, SANE_FALSE));
1796                   x_range.max = s->dev->model->x_size;
1797                   y_range.max = s->dev->model->y_size;
1798                 }
1799               s->first_scan = SANE_TRUE;
1800               myinfo |= SANE_INFO_RELOAD_PARAMS | SANE_INFO_RELOAD_OPTIONS;
1801               gettimeofday (&s->lamp_on_time, 0);
1802             }
1803           break;
1804         case OPT_MODE:
1805           if (s->val[option].s)
1806             free (s->val[option].s);
1807           s->val[option].s = strdup (val);
1808           if (strcmp (s->val[option].s, SANE_VALUE_SCAN_MODE_LINEART) == 0)
1809             {
1810               ENABLE (OPT_THRESHOLD);
1811               DISABLE (OPT_BIT_DEPTH);
1812               ENABLE (OPT_GRAY_MODE_COLOR);
1813             }
1814           else
1815             {
1816               DISABLE (OPT_THRESHOLD);
1817               if (strcmp (s->val[option].s, SANE_VALUE_SCAN_MODE_GRAY) == 0)
1818                 {
1819                   RIE (create_bpp_list (s, s->dev->model->bpp_gray_values));
1820                   ENABLE (OPT_GRAY_MODE_COLOR);
1821                 }
1822               else
1823                 {
1824                   RIE (create_bpp_list (s, s->dev->model->bpp_color_values));
1825                   DISABLE (OPT_GRAY_MODE_COLOR);
1826                 }
1827               if (s->bpp_list[0] < 2)
1828                 DISABLE (OPT_BIT_DEPTH);
1829               else
1830                 ENABLE (OPT_BIT_DEPTH);
1831             }
1832           RIE (calc_parameters (s));
1833           myinfo |= SANE_INFO_RELOAD_PARAMS | SANE_INFO_RELOAD_OPTIONS;
1834           break;
1835 
1836         case OPT_COARSE_CAL:
1837           s->val[option].w = *(SANE_Word *) val;
1838           if (s->val[option].w == SANE_TRUE)
1839             {
1840               ENABLE (OPT_COARSE_CAL_ONCE);
1841               s->first_scan = SANE_TRUE;
1842             }
1843           else
1844             {
1845               DISABLE (OPT_COARSE_CAL_ONCE);
1846             }
1847           myinfo |= SANE_INFO_RELOAD_OPTIONS;
1848           break;
1849 
1850         case OPT_BACKTRACK:
1851           s->val[option].w = *(SANE_Word *) val;
1852           if (s->val[option].w == SANE_TRUE)
1853             ENABLE (OPT_BACKTRACK_LINES);
1854           else
1855             DISABLE (OPT_BACKTRACK_LINES);
1856           myinfo |= SANE_INFO_RELOAD_OPTIONS;
1857           break;
1858 
1859         case OPT_CALIBRATE:
1860           status = gt68xx_sheetfed_scanner_calibrate (s);
1861           myinfo |= SANE_INFO_RELOAD_OPTIONS;
1862           break;
1863 
1864         case OPT_CLEAR_CALIBRATION:
1865           gt68xx_clear_calibration (s);
1866           myinfo |= SANE_INFO_RELOAD_OPTIONS;
1867           break;
1868 
1869         default:
1870           DBG (2, "sane_control_option: can't set unknown option %d\n",
1871                option);
1872         }
1873     }
1874   else
1875     {
1876       DBG (2, "sane_control_option: unknown action %d for option %d\n",
1877            action, option);
1878       return SANE_STATUS_INVAL;
1879     }
1880   if (info)
1881     *info = myinfo;
1882 
1883   DBG (5, "sane_control_option: exit\n");
1884   return status;
1885 }
1886 
1887 SANE_Status
sane_get_parameters(SANE_Handle handle,SANE_Parameters * params)1888 sane_get_parameters (SANE_Handle handle, SANE_Parameters * params)
1889 {
1890   GT68xx_Scanner *s = handle;
1891   SANE_Status status;
1892 
1893   DBG (5, "sane_get_parameters: start\n");
1894 
1895   RIE (calc_parameters (s));
1896   if (params)
1897     *params = s->params;
1898 
1899   DBG (4, "sane_get_parameters: format=%d, last_frame=%d, lines=%d\n",
1900        s->params.format, s->params.last_frame, s->params.lines);
1901   DBG (4, "sane_get_parameters: pixels_per_line=%d, bytes per line=%d\n",
1902        s->params.pixels_per_line, s->params.bytes_per_line);
1903   DBG (3, "sane_get_parameters: pixels %dx%dx%d\n",
1904        s->params.pixels_per_line, s->params.lines, 1 << s->params.depth);
1905 
1906   DBG (5, "sane_get_parameters: exit\n");
1907 
1908   return SANE_STATUS_GOOD;
1909 }
1910 
1911 SANE_Status
sane_start(SANE_Handle handle)1912 sane_start (SANE_Handle handle)
1913 {
1914   GT68xx_Scanner *s = handle;
1915   GT68xx_Scan_Request scan_request;
1916   GT68xx_Scan_Parameters scan_params;
1917   SANE_Status status;
1918   SANE_Int i, gamma_size;
1919   unsigned int *buffer_pointers[3];
1920   SANE_Bool document;
1921 
1922   DBG (5, "sane_start: start\n");
1923 
1924   /* First make sure we have a current parameter set.  Some of the
1925      parameters will be overwritten below, but that's OK.  */
1926   RIE (calc_parameters (s));
1927 
1928   if (s->val[OPT_TL_X].w >= s->val[OPT_BR_X].w)
1929     {
1930       DBG (0, "sane_start: top left x >= bottom right x --- exiting\n");
1931       return SANE_STATUS_INVAL;
1932     }
1933   if (s->val[OPT_TL_Y].w >= s->val[OPT_BR_Y].w)
1934     {
1935       DBG (0, "sane_start: top left y >= bottom right y --- exiting\n");
1936       return SANE_STATUS_INVAL;
1937     }
1938 
1939   if (strcmp (s->val[OPT_GRAY_MODE_COLOR].s, GT68XX_COLOR_BLUE) == 0)
1940     s->dev->gray_mode_color = 0x01;
1941   else if (strcmp (s->val[OPT_GRAY_MODE_COLOR].s, GT68XX_COLOR_GREEN) == 0)
1942     s->dev->gray_mode_color = 0x02;
1943   else
1944     s->dev->gray_mode_color = 0x03;
1945 
1946   setup_scan_request (s, &scan_request);
1947   if (!s->first_scan && s->val[OPT_COARSE_CAL_ONCE].w == SANE_TRUE)
1948     s->auto_afe = SANE_FALSE;
1949   else
1950     s->auto_afe = s->val[OPT_COARSE_CAL].w;
1951 
1952   s->dev->gamma_value = s->val[OPT_GAMMA_VALUE].w;
1953   gamma_size = s->params.depth == 16 ? 65536 : 256;
1954   s->gamma_table = malloc (sizeof (SANE_Int) * gamma_size);
1955   if (!s->gamma_table)
1956     {
1957       DBG (1, "sane_start: couldn't malloc %d bytes for gamma table\n",
1958            gamma_size);
1959       return SANE_STATUS_NO_MEM;
1960     }
1961   for (i = 0; i < gamma_size; i++)
1962     {
1963       s->gamma_table[i] =
1964         (gamma_size - 1) * pow (((double) i + 1) / (gamma_size),
1965                                 1.0 / SANE_UNFIX (s->dev->gamma_value)) + 0.5;
1966       if (s->gamma_table[i] > (gamma_size - 1))
1967         s->gamma_table[i] = (gamma_size - 1);
1968       if (s->gamma_table[i] < 0)
1969         s->gamma_table[i] = 0;
1970 #if 0
1971       printf ("%d %d\n", i, s->gamma_table[i]);
1972 #endif
1973     }
1974 
1975   if(!(s->dev->model->flags & GT68XX_FLAG_HAS_CALIBRATE))
1976     {
1977       s->calib = s->val[OPT_QUALITY_CAL].w;
1978     }
1979 
1980   if (!(s->dev->model->flags & GT68XX_FLAG_NO_STOP))
1981     RIE (gt68xx_device_stop_scan (s->dev));
1982 
1983   if (!(s->dev->model->flags & GT68XX_FLAG_SHEET_FED))
1984     RIE (gt68xx_device_carriage_home (s->dev));
1985 
1986   gt68xx_scanner_wait_for_positioning (s);
1987   gettimeofday (&s->start_time, 0);
1988 
1989   if (s->val[OPT_BACKTRACK].w == SANE_TRUE)
1990     scan_request.backtrack = SANE_TRUE;
1991   else
1992     {
1993       if (s->val[OPT_RESOLUTION].w >= s->dev->model->ydpi_no_backtrack)
1994         scan_request.backtrack = SANE_FALSE;
1995       else
1996         scan_request.backtrack = SANE_TRUE;
1997     }
1998 
1999   if (scan_request.backtrack)
2000     scan_request.backtrack_lines = s->val[OPT_BACKTRACK_LINES].w;
2001   else
2002     scan_request.backtrack_lines = 0;
2003 
2004   /* don't call calibration for scanners that use sheetfed_calibrate */
2005   if(!(s->dev->model->flags & GT68XX_FLAG_HAS_CALIBRATE))
2006     {
2007       RIE (gt68xx_scanner_calibrate (s, &scan_request));
2008     }
2009   else
2010     {
2011       s->calib = s->calibrated;
2012     }
2013 
2014   /* is possible, wait for document to be inserted before scanning */
2015   /* wait for 5 secondes max */
2016   if (s->dev->model->flags & GT68XX_FLAG_SHEET_FED
2017    && s->dev->model->command_set->document_present)
2018     {
2019       i=0;
2020       do
2021         {
2022           RIE(s->dev->model->command_set->document_present(s->dev,&document));
2023           if(document==SANE_FALSE)
2024             {
2025               i++;
2026               sleep(1);
2027             }
2028         } while ((i<5) && (document==SANE_FALSE));
2029       if(document==SANE_FALSE)
2030         {
2031           DBG (4, "sane_start: no document detected after %d s\n",i);
2032           return SANE_STATUS_NO_DOCS;
2033         }
2034     }
2035 
2036   /* some sheetfed scanners need a special operation to move
2037    * paper before starting real scan */
2038   if (s->dev->model->flags & GT68XX_FLAG_SHEET_FED)
2039     {
2040       RIE (gt68xx_sheetfed_move_to_scan_area (s, &scan_request));
2041     }
2042 
2043   /* restore calibration */
2044   if(  (s->dev->model->flags & GT68XX_FLAG_HAS_CALIBRATE)
2045      &&(s->calibrated == SANE_TRUE))
2046     {
2047       /* compute scan parameters */
2048       scan_request.calculate = SANE_TRUE;
2049       gt68xx_device_setup_scan (s->dev, &scan_request, SA_SCAN, &scan_params);
2050 
2051       /* restore settings from calibration stored */
2052       memcpy(s->dev->afe,&(s->afe_params), sizeof(GT68xx_AFE_Parameters));
2053       RIE (gt68xx_assign_calibration (s, scan_params));
2054       scan_request.calculate = SANE_FALSE;
2055     }
2056 
2057   /* send scan request to the scanner */
2058   RIE (gt68xx_scanner_start_scan (s, &scan_request, &scan_params));
2059 
2060   for (i = 0; i < scan_params.overscan_lines; ++i)
2061     RIE (gt68xx_scanner_read_line (s, buffer_pointers));
2062   DBG (4, "sane_start: wanted: dpi=%d, x=%.1f, y=%.1f, width=%.1f, "
2063        "height=%.1f, color=%s\n", scan_request.xdpi,
2064        SANE_UNFIX (scan_request.x0),
2065        SANE_UNFIX (scan_request.y0), SANE_UNFIX (scan_request.xs),
2066        SANE_UNFIX (scan_request.ys), scan_request.color ? "color" : "gray");
2067 
2068   s->line = 0;
2069   s->byte_count = s->reader->params.pixel_xs;
2070   s->total_bytes = 0;
2071   s->first_scan = SANE_FALSE;
2072 
2073 #ifdef DEBUG_BRIGHTNESS
2074   s->average_white = 0;
2075   s->max_white = 0;
2076   s->min_black = 255;
2077 #endif
2078 
2079   s->scanning = SANE_TRUE;
2080 
2081   DBG (5, "sane_start: exit\n");
2082   return SANE_STATUS_GOOD;
2083 }
2084 
2085 SANE_Status
sane_read(SANE_Handle handle,SANE_Byte * buf,SANE_Int max_len,SANE_Int * len)2086 sane_read (SANE_Handle handle, SANE_Byte * buf, SANE_Int max_len,
2087            SANE_Int * len)
2088 {
2089   GT68xx_Scanner *s = handle;
2090   SANE_Status status;
2091   static unsigned int *buffer_pointers[3];
2092   SANE_Int inflate_x;
2093   SANE_Bool lineart;
2094   SANE_Int i, color, colors;
2095 
2096   if (!s)
2097     {
2098       DBG (1, "sane_read: handle is null!\n");
2099       return SANE_STATUS_INVAL;
2100     }
2101 
2102   if (!buf)
2103     {
2104       DBG (1, "sane_read: buf is null!\n");
2105       return SANE_STATUS_INVAL;
2106     }
2107 
2108   if (!len)
2109     {
2110       DBG (1, "sane_read: len is null!\n");
2111       return SANE_STATUS_INVAL;
2112     }
2113 
2114   *len = 0;
2115 
2116   if (!s->scanning)
2117     {
2118       DBG (3, "sane_read: scan was cancelled, is over or has not been "
2119            "initiated yet\n");
2120       return SANE_STATUS_CANCELLED;
2121     }
2122 
2123   DBG (5, "sane_read: start (line %d of %d, byte_count %d of %d)\n",
2124        s->line, s->reader->params.pixel_ys, s->byte_count,
2125        s->reader->params.pixel_xs);
2126 
2127   if (s->line >= s->reader->params.pixel_ys
2128       && s->byte_count >= s->reader->params.pixel_xs)
2129     {
2130       DBG (4, "sane_read: nothing more to scan: EOF\n");
2131       gt68xx_scanner_stop_scan(s);
2132       return SANE_STATUS_EOF;
2133     }
2134 
2135   inflate_x = s->val[OPT_RESOLUTION].w / s->dev->model->optical_xdpi;
2136   if (inflate_x > 1)
2137     DBG (5, "sane_read: inflating x by factor %d\n", inflate_x);
2138   else
2139     inflate_x = 1;
2140 
2141   lineart = (strcmp (s->val[OPT_MODE].s, SANE_VALUE_SCAN_MODE_LINEART) == 0)
2142     ? SANE_TRUE : SANE_FALSE;
2143 
2144   if (s->reader->params.color)
2145     colors = 3;
2146   else
2147     colors = 1;
2148 
2149   while ((*len) < max_len)
2150     {
2151       if (s->byte_count >= s->reader->params.pixel_xs)
2152         {
2153           if (s->line >= s->reader->params.pixel_ys)
2154             {
2155               DBG (4, "sane_read: scan complete: %d bytes, %d total\n",
2156                    *len, s->total_bytes);
2157               return SANE_STATUS_GOOD;
2158             }
2159           DBG (5, "sane_read: getting line %d of %d\n", s->line,
2160                s->reader->params.pixel_ys);
2161           RIE (gt68xx_scanner_read_line (s, buffer_pointers));
2162           s->line++;
2163           s->byte_count = 0;
2164 
2165           /* Apply gamma */
2166           for (color = 0; color < colors; color++)
2167             for (i = 0; i < s->reader->pixels_per_line; i++)
2168               {
2169                 if (s->reader->params.depth > 8)
2170                   buffer_pointers[color][i] =
2171                     s->gamma_table[buffer_pointers[color][i]];
2172                 else
2173                   buffer_pointers[color][i] =
2174                     (s->gamma_table[buffer_pointers[color][i] >> 8] << 8) +
2175                     (s->gamma_table[buffer_pointers[color][i] >> 8]);
2176               }
2177           /* mirror lines */
2178           if (s->dev->model->flags & GT68XX_FLAG_MIRROR_X)
2179             {
2180               unsigned int swap;
2181 
2182               for (color = 0; color < colors; color++)
2183                 {
2184                   for (i = 0; i < s->reader->pixels_per_line / 2; i++)
2185                     {
2186                       swap = buffer_pointers[color][i];
2187                       buffer_pointers[color][i] =
2188                         buffer_pointers[color][s->reader->pixels_per_line -
2189                                                1 - i];
2190                       buffer_pointers[color][s->reader->pixels_per_line - 1 -
2191                                              i] = swap;
2192                     }
2193                 }
2194             }
2195         }
2196       if (lineart)
2197         {
2198           SANE_Int bit;
2199           SANE_Byte threshold = s->val[OPT_THRESHOLD].w;
2200 
2201           buf[*len] = 0;
2202           for (bit = 7; bit >= 0; bit--)
2203             {
2204               SANE_Byte is_black =
2205                 (((buffer_pointers[0][s->byte_count] >> 8) & 0xff) >
2206                  threshold) ? 0 : 1;
2207               buf[*len] |= (is_black << bit);
2208               if ((7 - bit) % inflate_x == (inflate_x - 1))
2209                 s->byte_count++;
2210             }
2211         }
2212       else if (s->reader->params.color)
2213         {
2214           /* color */
2215           if (s->reader->params.depth > 8)
2216             {
2217               SANE_Int color = (s->total_bytes / 2) % 3;
2218               if ((s->total_bytes % 2) == 0)
2219                 {
2220                   if (little_endian)
2221                     buf[*len] = buffer_pointers[color][s->byte_count] & 0xff;
2222                   else
2223                     buf[*len] =
2224                       (buffer_pointers[color][s->byte_count] >> 8) & 0xff;
2225                 }
2226               else
2227                 {
2228                   if (little_endian)
2229                     buf[*len] =
2230                       (buffer_pointers[color][s->byte_count] >> 8) & 0xff;
2231                   else
2232                     buf[*len] = buffer_pointers[color][s->byte_count] & 0xff;
2233 
2234                   if (s->total_bytes % (inflate_x * 6) == (inflate_x * 6 - 1))
2235                     s->byte_count++;
2236                 }
2237             }
2238           else
2239             {
2240               SANE_Int color = s->total_bytes % 3;
2241               buf[*len] = (buffer_pointers[color][s->byte_count] >> 8) & 0xff;
2242               if (s->total_bytes % (inflate_x * 3) == (inflate_x * 3 - 1))
2243                 s->byte_count++;
2244 #ifdef DEBUG_BRIGHTNESS
2245               s->average_white += buf[*len];
2246               s->max_white =
2247                 (buf[*len] > s->max_white) ? buf[*len] : s->max_white;
2248               s->min_black =
2249                 (buf[*len] < s->min_black) ? buf[*len] : s->min_black;
2250 #endif
2251             }
2252         }
2253       else
2254         {
2255           /* gray */
2256           if (s->reader->params.depth > 8)
2257             {
2258               if ((s->total_bytes % 2) == 0)
2259                 {
2260                   if (little_endian)
2261                     buf[*len] = buffer_pointers[0][s->byte_count] & 0xff;
2262                   else
2263                     buf[*len] =
2264                       (buffer_pointers[0][s->byte_count] >> 8) & 0xff;
2265                 }
2266               else
2267                 {
2268                   if (little_endian)
2269                     buf[*len] =
2270                       (buffer_pointers[0][s->byte_count] >> 8) & 0xff;
2271                   else
2272                     buf[*len] = buffer_pointers[0][s->byte_count] & 0xff;
2273                   if (s->total_bytes % (2 * inflate_x) == (2 * inflate_x - 1))
2274                     s->byte_count++;
2275                 }
2276             }
2277           else
2278             {
2279               buf[*len] = (buffer_pointers[0][s->byte_count] >> 8) & 0xff;
2280               if (s->total_bytes % inflate_x == (inflate_x - 1))
2281                 s->byte_count++;
2282             }
2283         }
2284       (*len)++;
2285       s->total_bytes++;
2286     }
2287 
2288   DBG (4, "sane_read: exit (line %d of %d, byte_count %d of %d, %d bytes, "
2289        "%d total)\n",
2290        s->line, s->reader->params.pixel_ys, s->byte_count,
2291        s->reader->params.pixel_xs, *len, s->total_bytes);
2292   return SANE_STATUS_GOOD;
2293 }
2294 
2295 void
sane_cancel(SANE_Handle handle)2296 sane_cancel (SANE_Handle handle)
2297 {
2298   GT68xx_Scanner *s = handle;
2299 
2300   DBG (5, "sane_cancel: start\n");
2301 
2302   if (s->scanning)
2303     {
2304       s->scanning = SANE_FALSE;
2305       if (s->total_bytes != (s->params.bytes_per_line * s->params.lines))
2306         DBG (1, "sane_cancel: warning: scanned %d bytes, expected %d "
2307              "bytes\n", s->total_bytes,
2308              s->params.bytes_per_line * s->params.lines);
2309       else
2310         {
2311           struct timeval now;
2312           int secs;
2313 
2314           gettimeofday (&now, 0);
2315           secs = now.tv_sec - s->start_time.tv_sec;
2316 
2317           DBG (3,
2318                "sane_cancel: scan finished, scanned %d bytes in %d seconds\n",
2319                s->total_bytes, secs);
2320 #ifdef DEBUG_BRIGHTNESS
2321           DBG (1,
2322                "sane_cancel: average white: %d, max_white=%d, min_black=%d\n",
2323                s->average_white / s->total_bytes, s->max_white, s->min_black);
2324 #endif
2325 
2326         }
2327       /* some scanners don't like this command when cancelling a scan */
2328       sanei_usb_set_timeout (SHORT_TIMEOUT);
2329       gt68xx_device_fix_descriptor (s->dev);
2330       gt68xx_scanner_stop_scan (s);
2331       sanei_usb_set_timeout (LONG_TIMEOUT);
2332 
2333       if (s->dev->model->flags & GT68XX_FLAG_SHEET_FED)
2334         {
2335           gt68xx_device_paperfeed (s->dev);
2336         }
2337       else
2338         {
2339           sanei_usb_set_timeout (SHORT_TIMEOUT);
2340           gt68xx_scanner_wait_for_positioning (s);
2341           sanei_usb_set_timeout (LONG_TIMEOUT);
2342           gt68xx_device_carriage_home (s->dev);
2343         }
2344       if (s->gamma_table)
2345         {
2346           free (s->gamma_table);
2347           s->gamma_table = 0;
2348         }
2349     }
2350   else
2351     {
2352       DBG (4, "sane_cancel: scan has not been initiated yet, "
2353            "or it is already aborted\n");
2354     }
2355 
2356   DBG (5, "sane_cancel: exit\n");
2357   return;
2358 }
2359 
2360 SANE_Status
sane_set_io_mode(SANE_Handle handle,SANE_Bool non_blocking)2361 sane_set_io_mode (SANE_Handle handle, SANE_Bool non_blocking)
2362 {
2363   GT68xx_Scanner *s = handle;
2364 
2365   DBG (5, "sane_set_io_mode: handle = %p, non_blocking = %s\n",
2366        handle, non_blocking == SANE_TRUE ? "true" : "false");
2367 
2368   if (!s->scanning)
2369     {
2370       DBG (1, "sane_set_io_mode: not scanning\n");
2371       return SANE_STATUS_INVAL;
2372     }
2373   if (non_blocking)
2374     return SANE_STATUS_UNSUPPORTED;
2375   return SANE_STATUS_GOOD;
2376 }
2377 
2378 SANE_Status
sane_get_select_fd(SANE_Handle handle,SANE_Int * fd)2379 sane_get_select_fd (SANE_Handle handle, SANE_Int * fd)
2380 {
2381   GT68xx_Scanner *s = handle;
2382 
2383   DBG (5, "sane_get_select_fd: handle = %p, fd = %p\n", handle, (void *) fd);
2384 
2385   if (!s->scanning)
2386     {
2387       DBG (1, "sane_get_select_fd: not scanning\n");
2388       return SANE_STATUS_INVAL;
2389     }
2390   return SANE_STATUS_UNSUPPORTED;
2391 }
2392 
2393 /* vim: set sw=2 cino=>2se-1sn-1s{s^-1st0(0u0 smarttab expandtab: */
2394