1 /* sane - Scanner Access Now Easy.
2 Copyright (C) 2000-2003 Jochen Eisinger <jochen.eisinger@gmx.net>
3 This file is part of the SANE package.
4
5 This program is free software; you can redistribute it and/or
6 modify it under the terms of the GNU General Public License as
7 published by the Free Software Foundation; either version 2 of the
8 License, or (at your option) any later version.
9
10 This program is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program. If not, see <https://www.gnu.org/licenses/>.
17
18 As a special exception, the authors of SANE give permission for
19 additional uses of the libraries contained in this release of SANE.
20
21 The exception is that, if you link a SANE library with other files
22 to produce an executable, this does not by itself cause the
23 resulting executable to be covered by the GNU General Public
24 License. Your use of that executable is in no way restricted on
25 account of linking the SANE library code into it.
26
27 This exception does not, however, invalidate any other reasons why
28 the executable file might be covered by the GNU General Public
29 License.
30
31 If you submit changes to SANE to the maintainers to be included in
32 a subsequent release, you agree by submitting the changes that
33 those changes may be distributed with this exception intact.
34
35 If you write modifications of your own for SANE, it is your choice
36 whether to permit this exception to apply to your modifications.
37 If you do not wish that, delete this exception notice.
38
39 This file implements a SANE backend for Mustek PP flatbed scanners. */
40
41 #include "../include/sane/config.h"
42
43 #if defined(HAVE_STDLIB_H)
44 # include <stdlib.h>
45 #endif
46 #include <stdio.h>
47 #include <ctype.h>
48 #include <errno.h>
49 #include <limits.h>
50 #include <signal.h>
51 #if defined(HAVE_STRING_H)
52 # include <string.h>
53 #elif defined(HAVE_STRINGS_H)
54 # include <strings.h>
55 #endif
56 #if defined(HAVE_UNISTD_H)
57 # include <unistd.h>
58 #endif
59 #include <math.h>
60 #include <fcntl.h>
61 #include <time.h>
62 #if defined(HAVE_SYS_TIME_H)
63 # include <sys/time.h>
64 #endif
65 #if defined(HAVE_SYS_TYPES_H)
66 # include <sys/types.h>
67 #endif
68 #include <sys/wait.h>
69
70 #define BACKEND_NAME mustek_pp
71
72 #include "../include/sane/sane.h"
73 #include "../include/sane/sanei.h"
74 #include "../include/sane/saneopts.h"
75
76 #include "../include/sane/sanei_backend.h"
77
78 #include "../include/sane/sanei_config.h"
79 #define MUSTEK_PP_CONFIG_FILE "mustek_pp.conf"
80
81 #include "../include/sane/sanei_pa4s2.h"
82
83 #include "mustek_pp.h"
84 #include "mustek_pp_drivers.h"
85
86 #define MIN(a,b) ((a) < (b) ? (a) : (b))
87
88 /* converts millimeter to pixels at a given resolution */
89 #define MM_TO_PIXEL(mm, dpi) (((float )mm * 5.0 / 127.0) * (float)dpi)
90 /* and back */
91 #define PIXEL_TO_MM(pixel, dpi) (((float )pixel / (float )dpi) * 127.0 / 5.0)
92
93 /* if you change the source, please set MUSTEK_PP_STATE to "devel". Do *not*
94 * change the MUSTEK_PP_BUILD. */
95 #define MUSTEK_PP_BUILD 13
96 #define MUSTEK_PP_STATE "beta"
97
98
99 /* auth callback... since basic user authentication is done by saned, this
100 * callback mechanism isn't used */
101 SANE_Auth_Callback sane_auth;
102
103 /* count of present devices */
104 static int num_devices = 0;
105
106 /* list of present devices */
107 static Mustek_pp_Device *devlist = NULL;
108
109 /* temporary array of configuration options used during device attachment */
110 static Mustek_pp_config_option *cfgoptions = NULL;
111 static int numcfgoptions = 0;
112
113 /* list of pointers to the SANE_Device structures of the Mustek_pp_Devices */
114 static SANE_Device **devarray = NULL;
115
116 /* currently active Handles */
117 static Mustek_pp_Handle *first_hndl = NULL;
118
119 static SANE_String_Const mustek_pp_modes[4] = {SANE_VALUE_SCAN_MODE_LINEART, SANE_VALUE_SCAN_MODE_GRAY, SANE_VALUE_SCAN_MODE_COLOR, NULL};
120 static SANE_Word mustek_pp_modes_size = 10;
121
122 static SANE_String_Const mustek_pp_speeds[6] = {"Slowest", "Slower", "Normal", "Faster", "Fastest", NULL};
123 static SANE_Word mustek_pp_speeds_size = 8;
124 static SANE_Word mustek_pp_depths[5] = {4, 8, 10, 12, 16};
125
126 /* prototypes */
127 static void free_cfg_options(int *numoptions, Mustek_pp_config_option** options);
128 static SANE_Status do_eof(Mustek_pp_Handle *hndl);
129 static SANE_Status do_stop(Mustek_pp_Handle *hndl);
130 static int reader_process (Mustek_pp_Handle * hndl, int pipe);
131 static SANE_Status sane_attach(SANE_String_Const port, SANE_String_Const name,
132 SANE_Int driver, SANE_Int info);
133 static void init_options(Mustek_pp_Handle *hndl);
134 static void attach_device(SANE_String *driver, SANE_String *name,
135 SANE_String *port, SANE_String *option_ta);
136
137
138 /*
139 * Auxiliary function for freeing arrays of configuration options,
140 */
141 static void
free_cfg_options(int *numoptions, Mustek_pp_config_option** options)142 free_cfg_options(int *numoptions, Mustek_pp_config_option** options)
143 {
144 int i;
145 if (*numoptions)
146 {
147 for (i=0; i<*numoptions; ++i)
148 {
149 free ((*options)[i].name);
150 free ((*options)[i].value);
151 }
152 free (*options);
153 }
154 *options = NULL;
155 *numoptions = 0;
156 }
157
158 /* do_eof:
159 * closes the pipeline
160 *
161 * Description:
162 * closes the pipe (read-only end)
163 */
164 static SANE_Status
do_eof(Mustek_pp_Handle *hndl)165 do_eof (Mustek_pp_Handle *hndl)
166 {
167 if (hndl->pipe >= 0) {
168
169 close (hndl->pipe);
170 hndl->pipe = -1;
171 }
172
173 return SANE_STATUS_EOF;
174 }
175
176 /* do_stop:
177 * ends the reader_process and stops the scanner
178 *
179 * Description:
180 * kills the reader process with a SIGTERM and cancels the scanner
181 */
182 static SANE_Status
do_stop(Mustek_pp_Handle *hndl)183 do_stop(Mustek_pp_Handle *hndl)
184 {
185
186 int exit_status;
187
188 do_eof (hndl);
189
190 if (hndl->reader > 0) {
191
192 DBG (3, "do_stop: terminating reader process\n");
193 kill (hndl->reader, SIGTERM);
194
195 while (wait (&exit_status) != hndl->reader);
196
197 DBG ((exit_status == SANE_STATUS_GOOD ? 3 : 1),
198 "do_stop: reader_process terminated with status ``%s''\n",
199 sane_strstatus(exit_status));
200 hndl->reader = 0;
201 hndl->dev->func->stop (hndl);
202
203 return exit_status;
204
205 }
206
207 hndl->dev->func->stop (hndl);
208
209 return SANE_STATUS_GOOD;
210 }
211
212 /* sigterm_handler:
213 * cancel scanner when receiving a SIGTERM
214 *
215 * Description:
216 * just exit... reader_process takes care that nothing bad will happen
217 *
218 * EDG - Jan 14, 2004:
219 * Make sure that the parport is released again by the child process
220 * under all circumstances, because otherwise the parent process may no
221 * longer be able to claim it (they share the same file descriptor, and
222 * the kernel doesn't release the child's claim because the file
223 * descriptor isn't cleaned up). If that would happen, the lamp may stay
224 * on and may not return to its home position, unless the scanner
225 * frontend is restarted.
226 * (This happens only when sanei_pa4s2 uses libieee1284 AND
227 * libieee1284 goes via /dev/parportX).
228 *
229 */
230 static int fd_to_release = 0;
231 /*ARGSUSED*/
232 static void
sigterm_handler(int signal __UNUSED__)233 sigterm_handler (int signal __UNUSED__)
234 {
235 sanei_pa4s2_enable(fd_to_release, SANE_FALSE);
236 _exit (SANE_STATUS_GOOD);
237 }
238
239 /* reader_process:
240 * receives data from the scanner and stuff it into the pipeline
241 *
242 * Description:
243 * The signal handle for SIGTERM is initialized.
244 *
245 */
246 static int
reader_process(Mustek_pp_Handle * hndl, int pipe)247 reader_process (Mustek_pp_Handle * hndl, int pipe)
248 {
249 sigset_t sigterm_set;
250 struct SIGACTION act;
251 FILE *fp;
252 SANE_Status status;
253 int line;
254 int size, elem;
255
256 SANE_Byte *buffer;
257
258 sigemptyset (&sigterm_set);
259 sigaddset (&sigterm_set, SIGTERM);
260
261 if (!(buffer = malloc (hndl->params.bytes_per_line)))
262 return SANE_STATUS_NO_MEM;
263
264 if (!(fp = fdopen(pipe, "w")))
265 return SANE_STATUS_IO_ERROR;
266
267 fd_to_release = hndl->fd;
268 memset (&act, 0, sizeof(act));
269 act.sa_handler = sigterm_handler;
270 sigaction (SIGTERM, &act, NULL);
271
272 if ((status = hndl->dev->func->start (hndl)) != SANE_STATUS_GOOD)
273 return status;
274
275 size = hndl->params.bytes_per_line;
276 elem = 1;
277
278 for (line=0; line<hndl->params.lines ; line++) {
279
280 sigprocmask (SIG_BLOCK, &sigterm_set, NULL);
281
282 hndl->dev->func->read (hndl, buffer);
283
284 if (getppid() == 1) {
285 /* The parent process has died. Stop the scan (to make
286 sure that the lamp is off and returns home). This is
287 a safety measure to make sure that we don't break
288 the scanner in case the frontend crashes. */
289 DBG (1, "reader_process: front-end died; aborting.\n");
290 hndl->dev->func->stop (hndl);
291 return SANE_STATUS_CANCELLED;
292 }
293
294 sigprocmask (SIG_UNBLOCK, &sigterm_set, NULL);
295
296 fwrite (buffer, size, elem, fp);
297 }
298
299 fclose (fp);
300
301 free (buffer);
302
303 return SANE_STATUS_GOOD;
304 }
305
306
307
308 /* sane_attach:
309 * adds a new entry to the Mustek_pp_Device *devlist list
310 *
311 * Description:
312 * After memory for a new device entry is allocated, the
313 * parameters for the device are determined by a call to
314 * capabilities().
315 *
316 * Afterwards the new device entry is inserted into the
317 * devlist
318 *
319 */
320 static SANE_Status
sane_attach(SANE_String_Const port, SANE_String_Const name, SANE_Int driver, SANE_Int info)321 sane_attach (SANE_String_Const port, SANE_String_Const name, SANE_Int driver, SANE_Int info)
322 {
323 Mustek_pp_Device *dev;
324
325 DBG (3, "sane_attach: attaching device ``%s'' to port %s (driver %s v%s by %s)\n",
326 name, port, Mustek_pp_Drivers[driver].driver,
327 Mustek_pp_Drivers[driver].version,
328 Mustek_pp_Drivers[driver].author);
329
330 if ((dev = malloc (sizeof (Mustek_pp_Device))) == NULL) {
331
332 DBG (1, "sane_attach: not enough free memory\n");
333 return SANE_STATUS_NO_MEM;
334
335 }
336
337 memset (dev, 0, sizeof (Mustek_pp_Device));
338
339 memset (&dev->sane, 0, sizeof (SANE_Device));
340
341 dev->func = &Mustek_pp_Drivers[driver];
342
343 dev->sane.name = dev->name = strdup (name);
344 dev->port = strdup (port);
345 dev->info = info; /* Modified by EDG */
346
347 /* Transfer the options parsed from the configuration file */
348 dev->numcfgoptions = numcfgoptions;
349 dev->cfgoptions = cfgoptions;
350 numcfgoptions = 0;
351 cfgoptions = NULL;
352
353 dev->func->capabilities (info, &dev->model, &dev->vendor, &dev->type,
354 &dev->maxres, &dev->minres, &dev->maxhsize, &dev->maxvsize,
355 &dev->caps);
356
357 dev->sane.model = dev->model;
358 dev->sane.vendor = dev->vendor;
359 dev->sane.type = dev->type;
360
361 dev->next = devlist;
362 devlist = dev;
363
364 num_devices++;
365
366 return SANE_STATUS_GOOD;
367 }
368
369
370 /* init_options:
371 * Sets up the option descriptors for a device
372 *
373 * Description:
374 */
375 static void
init_options(Mustek_pp_Handle *hndl)376 init_options(Mustek_pp_Handle *hndl)
377 {
378 int i;
379
380 memset (hndl->opt, 0, sizeof (hndl->opt));
381 memset (hndl->val, 0, sizeof (hndl->val));
382
383 for (i = 0; i < NUM_OPTIONS; ++i)
384 {
385 hndl->opt[i].size = sizeof (SANE_Word);
386 hndl->opt[i].cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT;
387 }
388
389 hndl->opt[OPT_NUM_OPTS].name = SANE_NAME_NUM_OPTIONS;
390 hndl->opt[OPT_NUM_OPTS].title = SANE_TITLE_NUM_OPTIONS;
391 hndl->opt[OPT_NUM_OPTS].desc = SANE_DESC_NUM_OPTIONS;
392 hndl->opt[OPT_NUM_OPTS].type = SANE_TYPE_INT;
393 hndl->opt[OPT_NUM_OPTS].cap = SANE_CAP_SOFT_DETECT;
394 hndl->val[OPT_NUM_OPTS].w = NUM_OPTIONS;
395
396 /* "Mode" group: */
397
398 hndl->opt[OPT_MODE_GROUP].title = "Scan Mode";
399 hndl->opt[OPT_MODE_GROUP].desc = "";
400 hndl->opt[OPT_MODE_GROUP].type = SANE_TYPE_GROUP;
401 hndl->opt[OPT_MODE_GROUP].cap = 0;
402 hndl->opt[OPT_MODE_GROUP].constraint_type = SANE_CONSTRAINT_NONE;
403 hndl->opt[OPT_MODE_GROUP].size = 0;
404
405 /* scan mode */
406 hndl->opt[OPT_MODE].name = SANE_NAME_SCAN_MODE;
407 hndl->opt[OPT_MODE].title = SANE_TITLE_SCAN_MODE;
408 hndl->opt[OPT_MODE].desc = SANE_DESC_SCAN_MODE;
409 hndl->opt[OPT_MODE].type = SANE_TYPE_STRING;
410 hndl->opt[OPT_MODE].constraint_type = SANE_CONSTRAINT_STRING_LIST;
411 hndl->opt[OPT_MODE].size = mustek_pp_modes_size;
412 hndl->opt[OPT_MODE].constraint.string_list = mustek_pp_modes;
413 hndl->val[OPT_MODE].s = strdup (mustek_pp_modes[2]);
414
415 /* resolution */
416 hndl->opt[OPT_RESOLUTION].name = SANE_NAME_SCAN_RESOLUTION;
417 hndl->opt[OPT_RESOLUTION].title = SANE_TITLE_SCAN_RESOLUTION;
418 hndl->opt[OPT_RESOLUTION].desc = SANE_DESC_SCAN_RESOLUTION;
419 hndl->opt[OPT_RESOLUTION].type = SANE_TYPE_FIXED;
420 hndl->opt[OPT_RESOLUTION].unit = SANE_UNIT_DPI;
421 hndl->opt[OPT_RESOLUTION].constraint_type = SANE_CONSTRAINT_RANGE;
422 hndl->opt[OPT_RESOLUTION].constraint.range = &hndl->dpi_range;
423 hndl->val[OPT_RESOLUTION].w = SANE_FIX (hndl->dev->minres);
424 hndl->dpi_range.min = SANE_FIX (hndl->dev->minres);
425 hndl->dpi_range.max = SANE_FIX (hndl->dev->maxres);
426 hndl->dpi_range.quant = SANE_FIX (1);
427
428 /* speed */
429 hndl->opt[OPT_SPEED].name = SANE_NAME_SCAN_SPEED;
430 hndl->opt[OPT_SPEED].title = SANE_TITLE_SCAN_SPEED;
431 hndl->opt[OPT_SPEED].desc = SANE_DESC_SCAN_SPEED;
432 hndl->opt[OPT_SPEED].type = SANE_TYPE_STRING;
433 hndl->opt[OPT_SPEED].size = mustek_pp_speeds_size;
434 hndl->opt[OPT_SPEED].constraint_type = SANE_CONSTRAINT_STRING_LIST;
435 hndl->opt[OPT_SPEED].constraint.string_list = mustek_pp_speeds;
436 hndl->val[OPT_SPEED].s = strdup (mustek_pp_speeds[2]);
437
438 if (! (hndl->dev->caps & CAP_SPEED_SELECT))
439 hndl->opt[OPT_SPEED].cap |= SANE_CAP_INACTIVE;
440
441 /* preview */
442 hndl->opt[OPT_PREVIEW].name = SANE_NAME_PREVIEW;
443 hndl->opt[OPT_PREVIEW].title = SANE_TITLE_PREVIEW;
444 hndl->opt[OPT_PREVIEW].desc = SANE_DESC_PREVIEW;
445 hndl->opt[OPT_PREVIEW].cap = SANE_CAP_SOFT_DETECT | SANE_CAP_SOFT_SELECT;
446 hndl->val[OPT_PREVIEW].w = SANE_FALSE;
447
448 /* gray preview */
449 hndl->opt[OPT_GRAY_PREVIEW].name = SANE_NAME_GRAY_PREVIEW;
450 hndl->opt[OPT_GRAY_PREVIEW].title = SANE_TITLE_GRAY_PREVIEW;
451 hndl->opt[OPT_GRAY_PREVIEW].desc = SANE_DESC_GRAY_PREVIEW;
452 hndl->opt[OPT_GRAY_PREVIEW].type = SANE_TYPE_BOOL;
453 hndl->val[OPT_GRAY_PREVIEW].w = SANE_FALSE;
454
455 /* color dept */
456 hndl->opt[OPT_DEPTH].name = SANE_NAME_BIT_DEPTH;
457 hndl->opt[OPT_DEPTH].title = SANE_TITLE_BIT_DEPTH;
458 hndl->opt[OPT_DEPTH].desc =
459 "Number of bits per sample for color scans, typical values are 8 for truecolor (24bpp)"
460 "up to 16 for far-to-many-color (48bpp).";
461 hndl->opt[OPT_DEPTH].type = SANE_TYPE_INT;
462 hndl->opt[OPT_DEPTH].constraint_type = SANE_CONSTRAINT_WORD_LIST;
463 hndl->opt[OPT_DEPTH].constraint.word_list = mustek_pp_depths;
464 hndl->opt[OPT_DEPTH].unit = SANE_UNIT_BIT;
465 hndl->opt[OPT_DEPTH].size = sizeof(SANE_Word);
466 hndl->val[OPT_DEPTH].w = 8;
467
468 if ( !(hndl->dev->caps & CAP_DEPTH))
469 hndl->opt[OPT_DEPTH].cap |= SANE_CAP_INACTIVE;
470
471
472 /* "Geometry" group: */
473
474 hndl->opt[OPT_GEOMETRY_GROUP].title = "Geometry";
475 hndl->opt[OPT_GEOMETRY_GROUP].desc = "";
476 hndl->opt[OPT_GEOMETRY_GROUP].type = SANE_TYPE_GROUP;
477 hndl->opt[OPT_GEOMETRY_GROUP].cap = SANE_CAP_ADVANCED;
478 hndl->opt[OPT_GEOMETRY_GROUP].constraint_type = SANE_CONSTRAINT_NONE;
479 hndl->opt[OPT_GEOMETRY_GROUP].size = 0;
480
481 /* top-left x */
482 hndl->opt[OPT_TL_X].name = SANE_NAME_SCAN_TL_X;
483 hndl->opt[OPT_TL_X].title = SANE_TITLE_SCAN_TL_X;
484 hndl->opt[OPT_TL_X].desc = SANE_DESC_SCAN_TL_X;
485 hndl->opt[OPT_TL_X].type = SANE_TYPE_FIXED;
486 hndl->opt[OPT_TL_X].unit = SANE_UNIT_MM;
487 hndl->opt[OPT_TL_X].constraint_type = SANE_CONSTRAINT_RANGE;
488 hndl->opt[OPT_TL_X].constraint.range = &hndl->x_range;
489 hndl->x_range.min = SANE_FIX (0);
490 hndl->x_range.max = SANE_FIX (PIXEL_TO_MM(hndl->dev->maxhsize,hndl->dev->maxres));
491 hndl->x_range.quant = 0;
492 hndl->val[OPT_TL_X].w = hndl->x_range.min;
493
494 /* top-left y */
495 hndl->opt[OPT_TL_Y].name = SANE_NAME_SCAN_TL_Y;
496 hndl->opt[OPT_TL_Y].title = SANE_TITLE_SCAN_TL_Y;
497 hndl->opt[OPT_TL_Y].desc = SANE_DESC_SCAN_TL_Y;
498 hndl->opt[OPT_TL_Y].type = SANE_TYPE_FIXED;
499 hndl->opt[OPT_TL_Y].unit = SANE_UNIT_MM;
500 hndl->opt[OPT_TL_Y].constraint_type = SANE_CONSTRAINT_RANGE;
501 hndl->opt[OPT_TL_Y].constraint.range = &hndl->y_range;
502 hndl->y_range.min = SANE_FIX(0);
503 hndl->y_range.max = SANE_FIX(PIXEL_TO_MM(hndl->dev->maxvsize,hndl->dev->maxres));
504 hndl->y_range.quant = 0;
505 hndl->val[OPT_TL_Y].w = hndl->y_range.min;
506
507 /* bottom-right x */
508 hndl->opt[OPT_BR_X].name = SANE_NAME_SCAN_BR_X;
509 hndl->opt[OPT_BR_X].title = SANE_TITLE_SCAN_BR_X;
510 hndl->opt[OPT_BR_X].desc = SANE_DESC_SCAN_BR_X;
511 hndl->opt[OPT_BR_X].type = SANE_TYPE_FIXED;
512 hndl->opt[OPT_BR_X].unit = SANE_UNIT_MM;
513 hndl->opt[OPT_BR_X].constraint_type = SANE_CONSTRAINT_RANGE;
514 hndl->opt[OPT_BR_X].constraint.range = &hndl->x_range;
515 hndl->val[OPT_BR_X].w = hndl->x_range.max;
516
517 /* bottom-right y */
518 hndl->opt[OPT_BR_Y].name = SANE_NAME_SCAN_BR_Y;
519 hndl->opt[OPT_BR_Y].title = SANE_TITLE_SCAN_BR_Y;
520 hndl->opt[OPT_BR_Y].desc = SANE_DESC_SCAN_BR_Y;
521 hndl->opt[OPT_BR_Y].type = SANE_TYPE_FIXED;
522 hndl->opt[OPT_BR_Y].unit = SANE_UNIT_MM;
523 hndl->opt[OPT_BR_Y].constraint_type = SANE_CONSTRAINT_RANGE;
524 hndl->opt[OPT_BR_Y].constraint.range = &hndl->y_range;
525 hndl->val[OPT_BR_Y].w = hndl->y_range.max;
526
527 /* "Enhancement" group: */
528
529 hndl->opt[OPT_ENHANCEMENT_GROUP].title = "Enhancement";
530 hndl->opt[OPT_ENHANCEMENT_GROUP].desc = "";
531 hndl->opt[OPT_ENHANCEMENT_GROUP].type = SANE_TYPE_GROUP;
532 hndl->opt[OPT_ENHANCEMENT_GROUP].cap = 0;
533 hndl->opt[OPT_ENHANCEMENT_GROUP].constraint_type = SANE_CONSTRAINT_NONE;
534 hndl->opt[OPT_ENHANCEMENT_GROUP].size = 0;
535
536
537 /* custom-gamma table */
538 hndl->opt[OPT_CUSTOM_GAMMA].name = SANE_NAME_CUSTOM_GAMMA;
539 hndl->opt[OPT_CUSTOM_GAMMA].title = SANE_TITLE_CUSTOM_GAMMA;
540 hndl->opt[OPT_CUSTOM_GAMMA].desc = SANE_DESC_CUSTOM_GAMMA;
541 hndl->opt[OPT_CUSTOM_GAMMA].type = SANE_TYPE_BOOL;
542 hndl->val[OPT_CUSTOM_GAMMA].w = SANE_FALSE;
543
544 if ( !(hndl->dev->caps & CAP_GAMMA_CORRECT))
545 hndl->opt[OPT_CUSTOM_GAMMA].cap |= SANE_CAP_INACTIVE;
546
547 /* grayscale gamma vector */
548 hndl->opt[OPT_GAMMA_VECTOR].name = SANE_NAME_GAMMA_VECTOR;
549 hndl->opt[OPT_GAMMA_VECTOR].title = SANE_TITLE_GAMMA_VECTOR;
550 hndl->opt[OPT_GAMMA_VECTOR].desc = SANE_DESC_GAMMA_VECTOR;
551 hndl->opt[OPT_GAMMA_VECTOR].type = SANE_TYPE_INT;
552 hndl->opt[OPT_GAMMA_VECTOR].cap |= SANE_CAP_INACTIVE;
553 hndl->opt[OPT_GAMMA_VECTOR].unit = SANE_UNIT_NONE;
554 hndl->opt[OPT_GAMMA_VECTOR].size = 256 * sizeof (SANE_Word);
555 hndl->opt[OPT_GAMMA_VECTOR].constraint_type = SANE_CONSTRAINT_RANGE;
556 hndl->opt[OPT_GAMMA_VECTOR].constraint.range = &hndl->gamma_range;
557 hndl->val[OPT_GAMMA_VECTOR].wa = &hndl->gamma_table[0][0];
558
559 /* red gamma vector */
560 hndl->opt[OPT_GAMMA_VECTOR_R].name = SANE_NAME_GAMMA_VECTOR_R;
561 hndl->opt[OPT_GAMMA_VECTOR_R].title = SANE_TITLE_GAMMA_VECTOR_R;
562 hndl->opt[OPT_GAMMA_VECTOR_R].desc = SANE_DESC_GAMMA_VECTOR_R;
563 hndl->opt[OPT_GAMMA_VECTOR_R].type = SANE_TYPE_INT;
564 hndl->opt[OPT_GAMMA_VECTOR_R].cap |= SANE_CAP_INACTIVE;
565 hndl->opt[OPT_GAMMA_VECTOR_R].unit = SANE_UNIT_NONE;
566 hndl->opt[OPT_GAMMA_VECTOR_R].size = 256 * sizeof (SANE_Word);
567 hndl->opt[OPT_GAMMA_VECTOR_R].constraint_type = SANE_CONSTRAINT_RANGE;
568 hndl->opt[OPT_GAMMA_VECTOR_R].constraint.range = &hndl->gamma_range;
569 hndl->val[OPT_GAMMA_VECTOR_R].wa = &hndl->gamma_table[1][0];
570
571 /* green gamma vector */
572 hndl->opt[OPT_GAMMA_VECTOR_G].name = SANE_NAME_GAMMA_VECTOR_G;
573 hndl->opt[OPT_GAMMA_VECTOR_G].title = SANE_TITLE_GAMMA_VECTOR_G;
574 hndl->opt[OPT_GAMMA_VECTOR_G].desc = SANE_DESC_GAMMA_VECTOR_G;
575 hndl->opt[OPT_GAMMA_VECTOR_G].type = SANE_TYPE_INT;
576 hndl->opt[OPT_GAMMA_VECTOR_G].cap |= SANE_CAP_INACTIVE;
577 hndl->opt[OPT_GAMMA_VECTOR_G].unit = SANE_UNIT_NONE;
578 hndl->opt[OPT_GAMMA_VECTOR_G].size = 256 * sizeof (SANE_Word);
579 hndl->opt[OPT_GAMMA_VECTOR_G].constraint_type = SANE_CONSTRAINT_RANGE;
580 hndl->opt[OPT_GAMMA_VECTOR_G].constraint.range = &hndl->gamma_range;
581 hndl->val[OPT_GAMMA_VECTOR_G].wa = &hndl->gamma_table[2][0];
582
583 /* blue gamma vector */
584 hndl->opt[OPT_GAMMA_VECTOR_B].name = SANE_NAME_GAMMA_VECTOR_B;
585 hndl->opt[OPT_GAMMA_VECTOR_B].title = SANE_TITLE_GAMMA_VECTOR_B;
586 hndl->opt[OPT_GAMMA_VECTOR_B].desc = SANE_DESC_GAMMA_VECTOR_B;
587 hndl->opt[OPT_GAMMA_VECTOR_B].type = SANE_TYPE_INT;
588 hndl->opt[OPT_GAMMA_VECTOR_B].cap |= SANE_CAP_INACTIVE;
589 hndl->opt[OPT_GAMMA_VECTOR_B].unit = SANE_UNIT_NONE;
590 hndl->opt[OPT_GAMMA_VECTOR_B].size = 256 * sizeof (SANE_Word);
591 hndl->opt[OPT_GAMMA_VECTOR_B].constraint_type = SANE_CONSTRAINT_RANGE;
592 hndl->opt[OPT_GAMMA_VECTOR_B].constraint.range = &hndl->gamma_range;
593 hndl->val[OPT_GAMMA_VECTOR_B].wa = &hndl->gamma_table[3][0];
594
595 hndl->gamma_range.min = 0;
596 hndl->gamma_range.max = 255;
597 hndl->gamma_range.quant = 1;
598
599 hndl->opt[OPT_INVERT].name = SANE_NAME_NEGATIVE;
600 hndl->opt[OPT_INVERT].title = SANE_TITLE_NEGATIVE;
601 hndl->opt[OPT_INVERT].desc = SANE_DESC_NEGATIVE;
602 hndl->opt[OPT_INVERT].type = SANE_TYPE_BOOL;
603 hndl->val[OPT_INVERT].w = SANE_FALSE;
604
605 if (! (hndl->dev->caps & CAP_INVERT))
606 hndl->opt[OPT_INVERT].cap |= SANE_CAP_INACTIVE;
607
608
609 }
610
611 /* attach_device:
612 * Attempts to attach a device to the list after parsing of a section
613 * of the configuration file.
614 *
615 * Description:
616 * After parsing a scanner section of the config file, this function
617 * is called to look for a driver with a matching name. When found,
618 * this driver is called to initialize the device.
619 */
620 static void
attach_device(SANE_String *driver, SANE_String *name, SANE_String *port, SANE_String *option_ta)621 attach_device(SANE_String *driver, SANE_String *name,
622 SANE_String *port, SANE_String *option_ta)
623 {
624 int found = 0, driver_no, port_no;
625 const char **ports;
626
627 if (!strcmp (*port, "*"))
628 {
629 ports = sanei_pa4s2_devices();
630 DBG (3, "sanei_init: auto probing port\n");
631 }
632 else
633 {
634 ports = malloc (sizeof(char *) * 2);
635 ports[0] = *port;
636 ports[1] = NULL;
637 }
638
639 for (port_no=0; ports[port_no] != NULL; port_no++)
640 {
641 for (driver_no=0 ; driver_no<MUSTEK_PP_NUM_DRIVERS ; driver_no++)
642 {
643 if (strcasecmp (Mustek_pp_Drivers[driver_no].driver, *driver) == 0)
644 {
645 Mustek_pp_Drivers[driver_no].init (
646 (*option_ta == 0 ? CAP_NOTHING : CAP_TA),
647 ports[port_no], *name, sane_attach);
648 found = 1;
649 break;
650 }
651 }
652 }
653
654 free (ports);
655
656 if (found == 0)
657 {
658 DBG (1, "sane_init: no scanner detected\n");
659 DBG (3, "sane_init: either the driver name ``%s'' is invalid, or no scanner was detected\n", *driver);
660 }
661
662 free (*name);
663 free (*port);
664 free (*driver);
665 if (*option_ta)
666 free (*option_ta);
667 *name = *port = *driver = *option_ta = 0;
668
669 /* In case of a successful initialization, the configuration options
670 should have been transferred to the device, but this function can
671 deal with that. */
672 free_cfg_options(&numcfgoptions, &cfgoptions);
673 }
674
675 /* sane_init:
676 * Reads configuration file and registers hardware driver
677 *
678 * Description:
679 * in *version_code the SANE version this backend was compiled with and the
680 * version of the backend is returned. The value of authorize is stored in
681 * the global variable sane_auth.
682 *
683 * Next the configuration file is read. If it isn't present, all drivers
684 * are auto-probed with default values (port 0x378, with and without TA).
685 *
686 * The configuration file is expected to contain lines of the form
687 *
688 * scanner <name> <port> <driver> [<option_ta>]
689 *
690 * where <name> is a arbitrary name to identify this entry
691 * <port> is the port where the scanner is attached to
692 * <driver> is the name of the driver to use
693 *
694 * if the optional argument "option_ta" is present the driver uses special
695 * parameters fitting for a transparency adapter.
696 */
697
698 SANE_Status
sane_init(SANE_Int * version_code, SANE_Auth_Callback authorize)699 sane_init (SANE_Int * version_code, SANE_Auth_Callback authorize)
700 {
701 FILE *fp;
702 char config_line[1024];
703 const char *config_line_ptr;
704 int line=0, driver_no;
705 char *driver = 0, *port = 0, *name = 0, *option_ta = 0;
706
707 DBG_INIT ();
708 DBG (3, "sane-mustek_pp, version 0.%d-%s. build for SANE %s\n",
709 MUSTEK_PP_BUILD, MUSTEK_PP_STATE, VERSION);
710 DBG (3, "backend by Jochen Eisinger <jochen.eisinger@gmx.net>\n");
711
712 if (version_code != NULL)
713 *version_code = SANE_VERSION_CODE (SANE_CURRENT_MAJOR, SANE_CURRENT_MINOR, MUSTEK_PP_BUILD);
714
715 sane_auth = authorize;
716
717
718 fp = sanei_config_open (MUSTEK_PP_CONFIG_FILE);
719
720 if (fp == NULL)
721 {
722 char driver_name[64];
723 const char **devices = sanei_pa4s2_devices();
724 int device_no;
725
726 DBG (2, "sane_init: could not open configuration file\n");
727
728 for (device_no = 0; devices[device_no] != NULL; device_no++)
729 {
730 DBG (3, "sane_init: trying ``%s''\n", devices[device_no]);
731 for (driver_no=0 ; driver_no<MUSTEK_PP_NUM_DRIVERS ; driver_no++)
732 {
733 Mustek_pp_Drivers[driver_no].init(CAP_NOTHING, devices[device_no],
734 Mustek_pp_Drivers[driver_no].driver, sane_attach);
735
736 snprintf (driver_name, 64, "%s-ta",
737 Mustek_pp_Drivers[driver_no].driver);
738
739 Mustek_pp_Drivers[driver_no].init(CAP_TA, devices[device_no],
740 driver_name, sane_attach);
741 }
742 }
743
744 free (devices);
745 return SANE_STATUS_GOOD;
746 }
747
748 while (sanei_config_read (config_line, 1023, fp))
749 {
750 line++;
751 if ((!*config_line) || (*config_line == '#'))
752 continue;
753
754 config_line_ptr = config_line;
755
756 if (strncmp(config_line_ptr, "scanner", 7) == 0)
757 {
758 config_line_ptr += 7;
759
760 if (name)
761 {
762 /* Parsing of previous scanner + options is finished. Attach
763 the device before we parse the next section. */
764 attach_device(&driver, &name, &port, &option_ta);
765 }
766
767 config_line_ptr = sanei_config_skip_whitespace (config_line_ptr);
768 if (!*config_line_ptr)
769 {
770 DBG (1, "sane_init: parse error in line %d after ``scanner''\n",
771 line);
772 continue;
773 }
774
775 config_line_ptr = sanei_config_get_string (config_line_ptr, &name);
776 if ((name == NULL) || (!*name))
777 {
778 DBG (1, "sane_init: parse error in line %d after ``scanner''\n",
779 line);
780 if (name != NULL)
781 free (name);
782 name = 0;
783 continue;
784 }
785
786 config_line_ptr = sanei_config_skip_whitespace (config_line_ptr);
787 if (!*config_line_ptr)
788 {
789 DBG (1, "sane_init: parse error in line %d after "
790 "``scanner %s''\n", line, name);
791 free (name);
792 name = 0;
793 continue;
794 }
795
796 config_line_ptr = sanei_config_get_string (config_line_ptr, &port);
797 if ((port == NULL) || (!*port))
798 {
799 DBG (1, "sane_init: parse error in line %d after "
800 "``scanner %s''\n", line, name);
801 free (name);
802 name = 0;
803 if (port != NULL)
804 free (port);
805 port = 0;
806 continue;
807 }
808
809 config_line_ptr = sanei_config_skip_whitespace (config_line_ptr);
810 if (!*config_line_ptr)
811 {
812 DBG (1, "sane_init: parse error in line %d after "
813 "``scanner %s %s''\n", line, name, port);
814 free (name);
815 free (port);
816 name = 0;
817 port = 0;
818 continue;
819 }
820
821 config_line_ptr = sanei_config_get_string (config_line_ptr, &driver);
822 if ((driver == NULL) || (!*driver))
823 {
824 DBG (1, "sane_init: parse error in line %d after "
825 "``scanner %s %s''\n", line, name, port);
826 free (name);
827 name = 0;
828 free (port);
829 port = 0;
830 if (driver != NULL)
831 free (driver);
832 driver = 0;
833 continue;
834 }
835
836 config_line_ptr = sanei_config_skip_whitespace (config_line_ptr);
837
838 if (*config_line_ptr)
839 {
840 config_line_ptr = sanei_config_get_string (config_line_ptr,
841 &option_ta);
842
843 if ((option_ta == NULL) || (!*option_ta) ||
844 (strcasecmp (option_ta, "use_ta") != 0))
845 {
846 DBG (1, "sane_init: parse error in line %d after "
847 "``scanner %s %s %s''\n", line, name, port, driver);
848 free (name);
849 free (port);
850 free (driver);
851 if (option_ta)
852 free (option_ta);
853 name = port = driver = option_ta = 0;
854 continue;
855 }
856 }
857
858 if (*config_line_ptr)
859 {
860 DBG (1, "sane_init: parse error in line %d after "
861 "``scanner %s %s %s %s\n", line, name, port, driver,
862 (option_ta == 0 ? "" : option_ta));
863 free (name);
864 free (port);
865 free (driver);
866 if (option_ta)
867 free (option_ta);
868 name = port = driver = option_ta = 0;
869 continue;
870 }
871 }
872 else if (strncmp(config_line_ptr, "option", 6) == 0)
873 {
874 /* Format for options: option <name> [<value>]
875 Note that the value is optional. */
876 char *optname, *optval = 0;
877 Mustek_pp_config_option *tmpoptions;
878
879 config_line_ptr += 6;
880 config_line_ptr = sanei_config_skip_whitespace (config_line_ptr);
881 if (!*config_line_ptr)
882 {
883 DBG (1, "sane_init: parse error in line %d after ``option''\n",
884 line);
885 continue;
886 }
887
888 config_line_ptr = sanei_config_get_string (config_line_ptr, &optname);
889 if ((optname == NULL) || (!*optname))
890 {
891 DBG (1, "sane_init: parse error in line %d after ``option''\n",
892 line);
893 if (optname != NULL)
894 free (optname);
895 continue;
896 }
897
898 config_line_ptr = sanei_config_skip_whitespace (config_line_ptr);
899 if (*config_line_ptr)
900 {
901 /* The option has a value.
902 No need to check the value; that's up to the backend */
903 config_line_ptr = sanei_config_get_string (config_line_ptr,
904 &optval);
905
906 config_line_ptr = sanei_config_skip_whitespace (config_line_ptr);
907 }
908
909 if (*config_line_ptr)
910 {
911 DBG (1, "sane_init: parse error in line %d after "
912 "``option %s %s''\n", line, optname,
913 (optval == 0 ? "" : optval));
914 free (optname);
915 if (optval)
916 free (optval);
917 continue;
918 }
919
920 if (!strcmp (optname, "no_epp"))
921 {
922 u_int pa4s2_options;
923 if (name)
924 DBG (2, "sane_init: global option found in local scope, "
925 "executing anyway\n");
926 free (optname);
927 if (optval)
928 {
929 DBG (1, "sane_init: unexpected value for option no_epp\n");
930 free (optval);
931 continue;
932 }
933 DBG (3, "sane_init: disabling mode EPP\n");
934 sanei_pa4s2_options (&pa4s2_options, SANE_FALSE);
935 pa4s2_options |= SANEI_PA4S2_OPT_NO_EPP;
936 sanei_pa4s2_options (&pa4s2_options, SANE_TRUE);
937 continue;
938 }
939 else if (!name)
940 {
941 DBG (1, "sane_init: parse error in line %d: unexpected "
942 " ``option''\n", line);
943 free (optname);
944 if (optval)
945 free (optval);
946 continue;
947 }
948
949
950 /* Extend the (global) array of options */
951 tmpoptions = realloc(cfgoptions,
952 (numcfgoptions+1)*sizeof(cfgoptions[0]));
953 if (!tmpoptions)
954 {
955 DBG (1, "sane_init: not enough memory for device options\n");
956 free_cfg_options(&numcfgoptions, &cfgoptions);
957 return SANE_STATUS_NO_MEM;
958 }
959
960 cfgoptions = tmpoptions;
961 cfgoptions[numcfgoptions].name = optname;
962 cfgoptions[numcfgoptions].value = optval;
963 ++numcfgoptions;
964 }
965 else
966 {
967 DBG (1, "sane_init: parse error at beginning of line %d\n", line);
968 continue;
969 }
970
971 }
972
973 /* If we hit the end of the file, we still may have to process the
974 last driver */
975 if (name)
976 attach_device(&driver, &name, &port, &option_ta);
977
978 fclose(fp);
979 return SANE_STATUS_GOOD;
980
981 }
982
983 /* sane_exit:
984 * Unloads all drivers and frees allocated memory
985 *
986 * Description:
987 * All open devices are closed first. Then all registered devices
988 * are removed.
989 *
990 */
991
992 void
sane_exit(void)993 sane_exit (void)
994 {
995 Mustek_pp_Handle *hndl;
996 Mustek_pp_Device *dev;
997
998 if (first_hndl)
999 DBG (3, "sane_exit: closing open devices\n");
1000
1001 while (first_hndl)
1002 {
1003 hndl = first_hndl;
1004 sane_close (hndl);
1005 }
1006
1007 dev = devlist;
1008 num_devices = 0;
1009 devlist = NULL;
1010
1011 while (dev) {
1012
1013 free (dev->port);
1014 free (dev->name);
1015 free (dev->vendor);
1016 free (dev->model);
1017 free (dev->type);
1018 free_cfg_options (&dev->numcfgoptions, &dev->cfgoptions);
1019 dev = dev->next;
1020
1021 }
1022
1023 if (devarray != NULL)
1024 free (devarray);
1025 devarray = NULL;
1026
1027 DBG (3, "sane_exit: all drivers unloaded\n");
1028
1029 }
1030
1031 /* sane_get_devices:
1032 * Returns a list of registered devices
1033 *
1034 * Description:
1035 * A possible present old device_list is removed first. A new
1036 * devarray is allocated and filled with pointers to the
1037 * SANE_Device structures of the Mustek_pp_Devices
1038 */
1039 /*ARGSUSED*/
1040 SANE_Status
sane_get_devices(const SANE_Device *** device_list, SANE_Bool local_only __UNUSED__)1041 sane_get_devices (const SANE_Device *** device_list,
1042 SANE_Bool local_only __UNUSED__)
1043 {
1044 int ctr;
1045 Mustek_pp_Device *dev;
1046
1047 if (devarray != NULL)
1048 free (devarray);
1049
1050 devarray = malloc ((num_devices + 1) * sizeof (devarray[0]));
1051
1052 if (devarray == NULL)
1053 {
1054 DBG (1, "sane_get_devices: not enough memory for device list\n");
1055 return SANE_STATUS_NO_MEM;
1056 }
1057
1058 dev = devlist;
1059
1060 for (ctr=0 ; ctr<num_devices ; ctr++) {
1061 devarray[ctr] = &dev->sane;
1062 dev = dev->next;
1063 }
1064
1065 devarray[num_devices] = NULL;
1066 *device_list = (const SANE_Device **)devarray;
1067
1068 return SANE_STATUS_GOOD;
1069 }
1070
1071 /* sane_open:
1072 * opens a device and prepares it for operation
1073 *
1074 * Description:
1075 * The device identified by ``devicename'' is looked
1076 * up in the list, or if devicename is zero, the
1077 * first device from the list is taken.
1078 *
1079 * open is called for the selected device.
1080 *
1081 * The handle is set up with default values, and the
1082 * option descriptors are initialized
1083 */
1084
1085 SANE_Status
sane_open(SANE_String_Const devicename, SANE_Handle * handle)1086 sane_open (SANE_String_Const devicename, SANE_Handle * handle)
1087 {
1088
1089 Mustek_pp_Handle *hndl;
1090 Mustek_pp_Device *dev;
1091 SANE_Status status;
1092 int fd, i;
1093
1094 if (devicename[0]) {
1095
1096 dev = devlist;
1097
1098 while (dev) {
1099
1100 if (strcmp (dev->name, devicename) == 0)
1101 break;
1102
1103 dev = dev->next;
1104
1105 }
1106
1107 if (!dev) {
1108
1109 DBG (1, "sane_open: unknown devicename ``%s''\n", devicename);
1110 return SANE_STATUS_INVAL;
1111
1112 }
1113 } else
1114 dev = devlist;
1115
1116 if (!dev) {
1117 DBG (1, "sane_open: no devices present...\n");
1118 return SANE_STATUS_INVAL;
1119 }
1120
1121 DBG (3, "sane_open: Using device ``%s'' (driver %s v%s by %s)\n",
1122 dev->name, dev->func->driver, dev->func->version, dev->func->author);
1123
1124 if ((hndl = malloc (sizeof (Mustek_pp_Handle))) == NULL) {
1125
1126 DBG (1, "sane_open: not enough free memory for the handle\n");
1127 return SANE_STATUS_NO_MEM;
1128
1129 }
1130
1131 if ((status = dev->func->open (dev->port, dev->caps, &fd)) != SANE_STATUS_GOOD) {
1132
1133 DBG (1, "sane_open: could not open device (%s)\n",
1134 sane_strstatus (status));
1135 return status;
1136
1137 }
1138
1139 hndl->next = first_hndl;
1140 hndl->dev = dev;
1141 hndl->fd = fd;
1142 hndl->state = STATE_IDLE;
1143 hndl->pipe = -1;
1144
1145 init_options (hndl);
1146
1147 dev->func->setup (hndl);
1148
1149 /* Initialize driver-specific configuration options. This must be
1150 done after calling the setup() function because only then the
1151 driver is guaranteed to be fully initialized */
1152 for (i = 0; i<dev->numcfgoptions; ++i)
1153 {
1154 status = dev->func->config (hndl,
1155 dev->cfgoptions[i].name,
1156 dev->cfgoptions[i].value);
1157 if (status != SANE_STATUS_GOOD)
1158 {
1159 DBG (1, "sane_open: could not set option %s for device (%s)\n",
1160 dev->cfgoptions[i].name, sane_strstatus (status));
1161
1162 /* Question: should the initialization be aborted when an
1163 option cannot be handled ?
1164 The driver should have reasonable built-in defaults, so
1165 an illegal option value or an unknown option should not
1166 be fatal. Therefore, it's probably ok to ignore the error. */
1167 }
1168 }
1169
1170 first_hndl = hndl;
1171
1172 *handle = hndl;
1173
1174 return SANE_STATUS_GOOD;
1175 }
1176
1177 /* sane_close:
1178 * closes a given device and frees all resources
1179 *
1180 * Description:
1181 * The handle is searched in the list of active handles.
1182 * If it's found, the handle is removed.
1183 *
1184 * If the associated device is still scanning, the process
1185 * is cancelled.
1186 *
1187 * Then the backend makes sure, the lamp was at least
1188 * 2 seconds on.
1189 *
1190 * Afterwards the selected handle is closed
1191 */
1192 void
sane_close(SANE_Handle handle)1193 sane_close (SANE_Handle handle)
1194 {
1195 Mustek_pp_Handle *prev, *hndl;
1196
1197 prev = NULL;
1198
1199 for (hndl = first_hndl; hndl; hndl = hndl->next)
1200 {
1201 if (hndl == handle)
1202 break;
1203 prev = hndl;
1204 }
1205
1206 if (hndl == NULL)
1207 {
1208 DBG (2, "sane_close: unknown device handle\n");
1209 return;
1210 }
1211
1212 if (hndl->state == STATE_SCANNING) {
1213 sane_cancel (handle);
1214 do_eof (handle);
1215 }
1216
1217 if (prev != NULL)
1218 prev->next = hndl->next;
1219 else
1220 first_hndl = hndl->next;
1221
1222 DBG (3, "sane_close: maybe waiting for lamp...\n");
1223 if (hndl->lamp_on)
1224 while (time (NULL) - hndl->lamp_on < 2)
1225 sleep (1);
1226
1227 hndl->dev->func->close (hndl);
1228
1229 DBG (3, "sane_close: device closed\n");
1230
1231 free (handle);
1232
1233 }
1234
1235 /* sane_get_option_descriptor:
1236 * does what it says
1237 *
1238 * Description:
1239 *
1240 */
1241
1242 const SANE_Option_Descriptor *
sane_get_option_descriptor(SANE_Handle handle, SANE_Int option)1243 sane_get_option_descriptor (SANE_Handle handle, SANE_Int option)
1244 {
1245 Mustek_pp_Handle *hndl = handle;
1246
1247 if ((unsigned) option >= NUM_OPTIONS)
1248 {
1249 DBG (2, "sane_get_option_descriptor: option %d doesn't exist\n", option);
1250 return NULL;
1251 }
1252
1253 return hndl->opt + option;
1254 }
1255
1256
1257 /* sane_control_option:
1258 * Reads or writes an option
1259 *
1260 * Description:
1261 * If a pointer to info is given, the value is initialized to zero
1262 * while scanning options cannot be read or written. next a basic
1263 * check whether the request is valid is done.
1264 *
1265 * Depending on ``action'' the value of the option is either read
1266 * (in the first block) or written (in the second block). auto
1267 * values aren't supported.
1268 *
1269 * before a value is written, some checks are performed. Depending
1270 * on the option, that is written, other options also change
1271 *
1272 */
1273 SANE_Status
sane_control_option(SANE_Handle handle, SANE_Int option, SANE_Action action, void *val, SANE_Int * info)1274 sane_control_option (SANE_Handle handle, SANE_Int option,
1275 SANE_Action action, void *val, SANE_Int * info)
1276 {
1277 Mustek_pp_Handle *hndl = handle;
1278 SANE_Status status;
1279 SANE_Word w, cap;
1280
1281 if (info)
1282 *info = 0;
1283
1284 if (hndl->state == STATE_SCANNING)
1285 {
1286 DBG (2, "sane_control_option: device is scanning\n");
1287 return SANE_STATUS_DEVICE_BUSY;
1288 }
1289
1290 if ((unsigned int) option >= NUM_OPTIONS)
1291 {
1292 DBG (2, "sane_control_option: option %d doesn't exist\n", option);
1293 return SANE_STATUS_INVAL;
1294 }
1295
1296 cap = hndl->opt[option].cap;
1297
1298 if (!SANE_OPTION_IS_ACTIVE (cap))
1299 {
1300 DBG (2, "sane_control_option: option %d isn't active\n", option);
1301 return SANE_STATUS_INVAL;
1302 }
1303
1304 if (action == SANE_ACTION_GET_VALUE)
1305 {
1306
1307 switch (option)
1308 {
1309 /* word options: */
1310 case OPT_PREVIEW:
1311 case OPT_GRAY_PREVIEW:
1312 case OPT_RESOLUTION:
1313 case OPT_TL_X:
1314 case OPT_TL_Y:
1315 case OPT_BR_X:
1316 case OPT_BR_Y:
1317 case OPT_NUM_OPTS:
1318 case OPT_CUSTOM_GAMMA:
1319 case OPT_INVERT:
1320 case OPT_DEPTH:
1321
1322 *(SANE_Word *) val = hndl->val[option].w;
1323 return SANE_STATUS_GOOD;
1324
1325 /* word-array options: */
1326 case OPT_GAMMA_VECTOR:
1327 case OPT_GAMMA_VECTOR_R:
1328 case OPT_GAMMA_VECTOR_G:
1329 case OPT_GAMMA_VECTOR_B:
1330
1331 memcpy (val, hndl->val[option].wa, hndl->opt[option].size);
1332 return SANE_STATUS_GOOD;
1333
1334 /* string options: */
1335 case OPT_MODE:
1336 case OPT_SPEED:
1337
1338 strcpy (val, hndl->val[option].s);
1339 return SANE_STATUS_GOOD;
1340 }
1341 }
1342 else if (action == SANE_ACTION_SET_VALUE)
1343 {
1344
1345 if (!SANE_OPTION_IS_SETTABLE (cap))
1346 {
1347 DBG (2, "sane_control_option: option can't be set (%s)\n",
1348 hndl->opt[option].name);
1349 return SANE_STATUS_INVAL;
1350 }
1351
1352 status = sanei_constrain_value (hndl->opt + option, val, info);
1353
1354 if (status != SANE_STATUS_GOOD)
1355 {
1356 DBG (2, "sane_control_option: constrain_value failed (%s)\n",
1357 sane_strstatus (status));
1358 return status;
1359 }
1360
1361 switch (option)
1362 {
1363 /* (mostly) side-effect-free word options: */
1364 case OPT_RESOLUTION:
1365 case OPT_TL_X:
1366 case OPT_BR_X:
1367 case OPT_TL_Y:
1368 case OPT_BR_Y:
1369 case OPT_PREVIEW:
1370 case OPT_GRAY_PREVIEW:
1371 case OPT_INVERT:
1372 case OPT_DEPTH:
1373
1374 if (info)
1375 *info |= SANE_INFO_RELOAD_PARAMS;
1376
1377 hndl->val[option].w = *(SANE_Word *) val;
1378 return SANE_STATUS_GOOD;
1379
1380 /* side-effect-free word-array options: */
1381 case OPT_GAMMA_VECTOR:
1382 case OPT_GAMMA_VECTOR_R:
1383 case OPT_GAMMA_VECTOR_G:
1384 case OPT_GAMMA_VECTOR_B:
1385
1386 memcpy (hndl->val[option].wa, val, hndl->opt[option].size);
1387 return SANE_STATUS_GOOD;
1388
1389 /* side-effect-free string options: */
1390 case OPT_SPEED:
1391
1392 if (hndl->val[option].s)
1393 free (hndl->val[option].s);
1394
1395 hndl->val[option].s = strdup (val);
1396 return SANE_STATUS_GOOD;
1397
1398
1399 /* options with side-effects: */
1400
1401 case OPT_CUSTOM_GAMMA:
1402 w = *(SANE_Word *) val;
1403
1404 if (w == hndl->val[OPT_CUSTOM_GAMMA].w)
1405 return SANE_STATUS_GOOD; /* no change */
1406
1407 if (info)
1408 *info |= SANE_INFO_RELOAD_OPTIONS;
1409
1410 hndl->val[OPT_CUSTOM_GAMMA].w = w;
1411
1412 if (w == SANE_TRUE)
1413 {
1414 const char *mode = hndl->val[OPT_MODE].s;
1415
1416 if (strcmp (mode, SANE_VALUE_SCAN_MODE_GRAY) == 0)
1417 hndl->opt[OPT_GAMMA_VECTOR].cap &= ~SANE_CAP_INACTIVE;
1418 else if (strcmp (mode, SANE_VALUE_SCAN_MODE_COLOR) == 0)
1419 {
1420 hndl->opt[OPT_GAMMA_VECTOR].cap &= ~SANE_CAP_INACTIVE;
1421 hndl->opt[OPT_GAMMA_VECTOR_R].cap &= ~SANE_CAP_INACTIVE;
1422 hndl->opt[OPT_GAMMA_VECTOR_G].cap &= ~SANE_CAP_INACTIVE;
1423 hndl->opt[OPT_GAMMA_VECTOR_B].cap &= ~SANE_CAP_INACTIVE;
1424 }
1425 }
1426 else
1427 {
1428 hndl->opt[OPT_GAMMA_VECTOR].cap |= SANE_CAP_INACTIVE;
1429 hndl->opt[OPT_GAMMA_VECTOR_R].cap |= SANE_CAP_INACTIVE;
1430 hndl->opt[OPT_GAMMA_VECTOR_G].cap |= SANE_CAP_INACTIVE;
1431 hndl->opt[OPT_GAMMA_VECTOR_B].cap |= SANE_CAP_INACTIVE;
1432 }
1433
1434 return SANE_STATUS_GOOD;
1435
1436 case OPT_MODE:
1437 {
1438 char *old_val = hndl->val[option].s;
1439
1440 if (old_val)
1441 {
1442 if (strcmp (old_val, val) == 0)
1443 return SANE_STATUS_GOOD; /* no change */
1444
1445 free (old_val);
1446 }
1447
1448 if (info)
1449 *info |= SANE_INFO_RELOAD_OPTIONS | SANE_INFO_RELOAD_PARAMS;
1450
1451 hndl->val[option].s = strdup (val);
1452
1453 hndl->opt[OPT_CUSTOM_GAMMA].cap |= SANE_CAP_INACTIVE;
1454 hndl->opt[OPT_GAMMA_VECTOR].cap |= SANE_CAP_INACTIVE;
1455 hndl->opt[OPT_GAMMA_VECTOR_R].cap |= SANE_CAP_INACTIVE;
1456 hndl->opt[OPT_GAMMA_VECTOR_G].cap |= SANE_CAP_INACTIVE;
1457 hndl->opt[OPT_GAMMA_VECTOR_B].cap |= SANE_CAP_INACTIVE;
1458
1459 hndl->opt[OPT_DEPTH].cap |= SANE_CAP_INACTIVE;
1460
1461 if ((hndl->dev->caps & CAP_DEPTH) && (strcmp(val, SANE_VALUE_SCAN_MODE_COLOR) == 0))
1462 hndl->opt[OPT_DEPTH].cap &= ~SANE_CAP_INACTIVE;
1463
1464 if (!(hndl->dev->caps & CAP_GAMMA_CORRECT))
1465 return SANE_STATUS_GOOD;
1466
1467 if (strcmp (val, SANE_VALUE_SCAN_MODE_LINEART) != 0)
1468 hndl->opt[OPT_CUSTOM_GAMMA].cap &= ~SANE_CAP_INACTIVE;
1469
1470 if (hndl->val[OPT_CUSTOM_GAMMA].w == SANE_TRUE)
1471 {
1472 if (strcmp (val, SANE_VALUE_SCAN_MODE_GRAY) == 0)
1473 hndl->opt[OPT_GAMMA_VECTOR].cap &= ~SANE_CAP_INACTIVE;
1474 else if (strcmp (val, SANE_VALUE_SCAN_MODE_COLOR) == 0)
1475 {
1476 hndl->opt[OPT_GAMMA_VECTOR].cap &= ~SANE_CAP_INACTIVE;
1477 hndl->opt[OPT_GAMMA_VECTOR_R].cap &= ~SANE_CAP_INACTIVE;
1478 hndl->opt[OPT_GAMMA_VECTOR_G].cap &= ~SANE_CAP_INACTIVE;
1479 hndl->opt[OPT_GAMMA_VECTOR_B].cap &= ~SANE_CAP_INACTIVE;
1480 }
1481 }
1482
1483 return SANE_STATUS_GOOD;
1484 }
1485 }
1486 }
1487
1488 DBG (2, "sane_control_option: unknown action\n");
1489 return SANE_STATUS_INVAL;
1490 }
1491
1492
1493 /* sane_get_parameters:
1494 * returns the set of parameters, that is used for the next scan
1495 *
1496 * Description:
1497 *
1498 * First of all it is impossible to change the parameter set
1499 * while scanning.
1500 *
1501 * sane_get_parameters not only returns the parameters for
1502 * the next scan, it also sets them, i.e. converts the
1503 * options in actually parameters.
1504 *
1505 * The following parameters are set:
1506 *
1507 * scanmode: according to the option SCANMODE, but
1508 * 24bit color, if PREVIEW is selected and
1509 * grayscale if GRAY_PREVIEW is selected
1510 * depth: the bit depth for color modes (if
1511 * supported) or 24bit by default
1512 * (ignored in bw/grayscale or if not
1513 * supported)
1514 * dpi: resolution
1515 * invert: if supported else defaults to false
1516 * gamma: if supported and selected
1517 * ta: if supported by the device
1518 * speed: selected speed (or fastest if not
1519 * supported)
1520 * scanarea: the scanarea is calculated from the
1521 * selections the user has mode. note
1522 * that the area may slightly differ from
1523 * the scanarea selected due to rounding
1524 * note also, that a scanarea of
1525 * (0,0)-(100,100) will include all pixels
1526 * where 0 <= x < 100 and 0 <= y < 100
1527 * afterwards, all values are copied into the SANE_Parameters
1528 * structure.
1529 */
1530 SANE_Status
sane_get_parameters(SANE_Handle handle, SANE_Parameters * params)1531 sane_get_parameters (SANE_Handle handle, SANE_Parameters * params)
1532 {
1533 Mustek_pp_Handle *hndl = handle;
1534 char *mode;
1535 int dpi, ctr;
1536
1537 if (hndl->state != STATE_SCANNING)
1538 {
1539
1540
1541 memset (&hndl->params, 0, sizeof (hndl->params));
1542
1543
1544 if ((hndl->dev->caps & CAP_DEPTH) && (hndl->mode == MODE_COLOR))
1545 hndl->depth = hndl->val[OPT_DEPTH].w;
1546 else
1547 hndl->depth = 8;
1548
1549 dpi = (int) (SANE_UNFIX (hndl->val[OPT_RESOLUTION].w) + 0.5);
1550
1551 hndl->res = dpi;
1552
1553 if (hndl->dev->caps & CAP_INVERT)
1554 hndl->invert = hndl->val[OPT_INVERT].w;
1555 else
1556 hndl->invert = SANE_FALSE;
1557
1558 if (hndl->dev->caps & CAP_TA)
1559 hndl->use_ta = SANE_TRUE;
1560 else
1561 hndl->use_ta = SANE_FALSE;
1562
1563 if ((hndl->dev->caps & CAP_GAMMA_CORRECT) && (hndl->val[OPT_CUSTOM_GAMMA].w == SANE_TRUE))
1564 hndl->do_gamma = SANE_TRUE;
1565 else
1566 hndl->do_gamma = SANE_FALSE;
1567
1568 if (hndl->dev->caps & CAP_SPEED_SELECT) {
1569
1570 for (ctr=SPEED_SLOWEST; ctr<=SPEED_FASTEST; ctr++)
1571 if (strcmp(mustek_pp_speeds[ctr], hndl->val[OPT_SPEED].s) == 0)
1572 hndl->speed = ctr;
1573
1574
1575
1576 } else
1577 hndl->speed = SPEED_NORMAL;
1578
1579 mode = hndl->val[OPT_MODE].s;
1580
1581 if (strcmp (mode, SANE_VALUE_SCAN_MODE_LINEART) == 0)
1582 hndl->mode = MODE_BW;
1583 else if (strcmp (mode, SANE_VALUE_SCAN_MODE_GRAY) == 0)
1584 hndl->mode = MODE_GRAYSCALE;
1585 else
1586 hndl->mode = MODE_COLOR;
1587
1588 if (hndl->val[OPT_PREVIEW].w == SANE_TRUE)
1589 {
1590
1591 hndl->speed = SPEED_FASTEST;
1592 hndl->depth = 8;
1593 if (! hndl->use_ta)
1594 hndl->invert = SANE_FALSE;
1595 hndl->do_gamma = SANE_FALSE;
1596
1597 if (hndl->val[OPT_GRAY_PREVIEW].w == SANE_TRUE)
1598 hndl->mode = MODE_GRAYSCALE;
1599 else {
1600 hndl->mode = MODE_COLOR;
1601 }
1602
1603 }
1604
1605 hndl->topX =
1606 MIN ((int)
1607 (MM_TO_PIXEL (SANE_UNFIX(hndl->val[OPT_TL_X].w), hndl->dev->maxres) +
1608 0.5), hndl->dev->maxhsize);
1609 hndl->topY =
1610 MIN ((int)
1611 (MM_TO_PIXEL (SANE_UNFIX(hndl->val[OPT_TL_Y].w), hndl->dev->maxres) +
1612 0.5), hndl->dev->maxvsize);
1613
1614 hndl->bottomX =
1615 MIN ((int)
1616 (MM_TO_PIXEL (SANE_UNFIX(hndl->val[OPT_BR_X].w), hndl->dev->maxres) +
1617 0.5), hndl->dev->maxhsize);
1618 hndl->bottomY =
1619 MIN ((int)
1620 (MM_TO_PIXEL (SANE_UNFIX(hndl->val[OPT_BR_Y].w), hndl->dev->maxres) +
1621 0.5), hndl->dev->maxvsize);
1622
1623 /* If necessary, swap the upper and lower boundaries to avoid negative
1624 distances. */
1625 if (hndl->topX > hndl->bottomX) {
1626 SANE_Int tmp = hndl->topX;
1627 hndl->topX = hndl->bottomX;
1628 hndl->bottomX = tmp;
1629 }
1630 if (hndl->topY > hndl->bottomY) {
1631 SANE_Int tmp = hndl->topY;
1632 hndl->topY = hndl->bottomY;
1633 hndl->bottomY = tmp;
1634 }
1635
1636 hndl->params.pixels_per_line = (hndl->bottomX - hndl->topX) * hndl->res
1637 / hndl->dev->maxres;
1638
1639 hndl->params.bytes_per_line = hndl->params.pixels_per_line;
1640
1641 switch (hndl->mode)
1642 {
1643
1644 case MODE_BW:
1645 hndl->params.bytes_per_line /= 8;
1646
1647 if ((hndl->params.pixels_per_line % 8) != 0)
1648 hndl->params.bytes_per_line++;
1649
1650 hndl->params.depth = 1;
1651 break;
1652
1653 case MODE_GRAYSCALE:
1654 hndl->params.depth = 8;
1655 hndl->params.format = SANE_FRAME_GRAY;
1656 break;
1657
1658 case MODE_COLOR:
1659 hndl->params.depth = hndl->depth;
1660 hndl->params.bytes_per_line *= 3;
1661 if (hndl->depth > 8)
1662 hndl->params.bytes_per_line *= 2;
1663 hndl->params.format = SANE_FRAME_RGB;
1664 break;
1665
1666 }
1667
1668 hndl->params.last_frame = SANE_TRUE;
1669
1670 hndl->params.lines = (hndl->bottomY - hndl->topY) * hndl->res /
1671 hndl->dev->maxres;
1672 }
1673 else
1674 DBG (2, "sane_get_parameters: can't set parameters while scanning\n");
1675
1676 if (params != NULL)
1677 *params = hndl->params;
1678
1679 return SANE_STATUS_GOOD;
1680
1681 }
1682
1683
1684 /* sane_start:
1685 * starts the scan. data acquisition will start immediately
1686 *
1687 * Description:
1688 *
1689 */
1690 SANE_Status
sane_start(SANE_Handle handle)1691 sane_start (SANE_Handle handle)
1692 {
1693 Mustek_pp_Handle *hndl = handle;
1694 int pipeline[2];
1695
1696 if (hndl->state == STATE_SCANNING) {
1697 DBG (2, "sane_start: device is already scanning\n");
1698 return SANE_STATUS_DEVICE_BUSY;
1699
1700 }
1701
1702 sane_get_parameters (hndl, NULL);
1703
1704 if (pipe(pipeline) < 0) {
1705 DBG (1, "sane_start: could not initialize pipe (%s)\n",
1706 strerror(errno));
1707 return SANE_STATUS_IO_ERROR;
1708 }
1709
1710 hndl->reader = fork();
1711
1712 if (hndl->reader == 0) {
1713
1714 sigset_t ignore_set;
1715 struct SIGACTION act;
1716
1717 close (pipeline[0]);
1718
1719 sigfillset (&ignore_set);
1720 sigdelset (&ignore_set, SIGTERM);
1721 sigprocmask (SIG_SETMASK, &ignore_set, NULL);
1722
1723 memset (&act, 0, sizeof(act));
1724 sigaction (SIGTERM, &act, NULL);
1725
1726 _exit (reader_process (hndl, pipeline[1]));
1727
1728 }
1729
1730 close (pipeline[1]);
1731
1732 hndl->pipe = pipeline[0];
1733
1734 hndl->state = STATE_SCANNING;
1735
1736 return SANE_STATUS_GOOD;
1737
1738 }
1739
1740
1741 /* sane_read:
1742 * receives data from pipeline and passes it to the caller
1743 *
1744 * Description:
1745 * ditto
1746 */
1747 SANE_Status
sane_read(SANE_Handle handle, SANE_Byte * buf, SANE_Int max_len, SANE_Int * len)1748 sane_read (SANE_Handle handle, SANE_Byte * buf, SANE_Int max_len,
1749 SANE_Int * len)
1750 {
1751 Mustek_pp_Handle *hndl = handle;
1752 SANE_Int nread;
1753
1754
1755 if (hndl->state == STATE_CANCELLED) {
1756 DBG (2, "sane_read: device already cancelled\n");
1757 do_eof (hndl);
1758 hndl->state = STATE_IDLE;
1759 return SANE_STATUS_CANCELLED;
1760 }
1761
1762 if (hndl->state != STATE_SCANNING) {
1763 DBG (1, "sane_read: device isn't scanning\n");
1764 return SANE_STATUS_INVAL;
1765 }
1766
1767
1768 *len = nread = 0;
1769
1770 while (*len < max_len) {
1771
1772 nread = read(hndl->pipe, buf + *len, max_len - *len);
1773
1774 if (hndl->state == STATE_CANCELLED) {
1775
1776 *len = 0;
1777 DBG(3, "sane_read: scan was cancelled\n");
1778
1779 do_eof (hndl);
1780 hndl->state = STATE_IDLE;
1781 return SANE_STATUS_CANCELLED;
1782
1783 }
1784
1785 if (nread < 0) {
1786
1787 if (errno == EAGAIN) {
1788
1789 if (*len == 0)
1790 DBG(3, "sane_read: no data at the moment\n");
1791 else
1792 DBG(3, "sane_read: %d bytes read\n", *len);
1793
1794 return SANE_STATUS_GOOD;
1795
1796 } else {
1797
1798 DBG(1, "sane_read: IO error (%s)\n", strerror(errno));
1799
1800 hndl->state = STATE_IDLE;
1801 do_stop(hndl);
1802
1803 do_eof (hndl);
1804
1805 *len = 0;
1806 return SANE_STATUS_IO_ERROR;
1807
1808 }
1809 }
1810
1811 *len += nread;
1812
1813 if (nread == 0) {
1814
1815 if (*len == 0) {
1816
1817 DBG (3, "sane_read: read finished\n");
1818 do_stop(hndl);
1819
1820 hndl->state = STATE_IDLE;
1821
1822 return do_eof(hndl);
1823
1824 }
1825
1826 DBG(3, "sane_read: read last buffer of %d bytes\n",
1827 *len);
1828
1829 return SANE_STATUS_GOOD;
1830
1831 }
1832
1833 }
1834
1835 DBG(3, "sane_read: read full buffer of %d bytes\n", *len);
1836
1837 return SANE_STATUS_GOOD;
1838 }
1839
1840
1841 /* sane_cancel:
1842 * stops a scan and ends the reader process
1843 *
1844 * Description:
1845 *
1846 */
1847 void
sane_cancel(SANE_Handle handle)1848 sane_cancel (SANE_Handle handle)
1849 {
1850 Mustek_pp_Handle *hndl = handle;
1851
1852 if (hndl->state != STATE_SCANNING)
1853 return;
1854
1855 hndl->state = STATE_CANCELLED;
1856
1857 do_stop (hndl);
1858
1859 }
1860
1861
1862 /* sane_set_io_mode:
1863 * toggles between blocking and non-blocking reading
1864 *
1865 * Description:
1866 *
1867 */
1868 SANE_Status
sane_set_io_mode(SANE_Handle handle, SANE_Bool non_blocking)1869 sane_set_io_mode (SANE_Handle handle, SANE_Bool non_blocking)
1870 {
1871
1872 Mustek_pp_Handle *hndl=handle;
1873
1874 if (hndl->state != STATE_SCANNING)
1875 return SANE_STATUS_INVAL;
1876
1877
1878 if (fcntl (hndl->pipe, F_SETFL, non_blocking ? O_NONBLOCK : 0) < 0) {
1879
1880 DBG(1, "sane_set_io_mode: can't set io mode\n");
1881
1882 return SANE_STATUS_IO_ERROR;
1883
1884 }
1885
1886 return SANE_STATUS_GOOD;
1887 }
1888
1889
1890 /* sane_get_select_fd:
1891 * returns the pipeline fd for direct reading
1892 *
1893 * Description:
1894 * to allow the frontend to receive the data directly it
1895 * can read from the pipeline itself
1896 */
1897 SANE_Status
sane_get_select_fd(SANE_Handle handle, SANE_Int * fd)1898 sane_get_select_fd (SANE_Handle handle, SANE_Int * fd)
1899 {
1900 Mustek_pp_Handle *hndl=handle;
1901
1902 if (hndl->state != STATE_SCANNING)
1903 return SANE_STATUS_INVAL;
1904
1905 *fd = hndl->pipe;
1906
1907 return SANE_STATUS_GOOD;
1908 }
1909
1910 /* include drivers */
1911 #include "mustek_pp_decl.h"
1912 #include "mustek_pp_null.c"
1913 #include "mustek_pp_cis.h"
1914 #include "mustek_pp_cis.c"
1915 #include "mustek_pp_ccd300.h"
1916 #include "mustek_pp_ccd300.c"
1917