1 /*
2 * This program is free software; you can redistribute it and/or
3 * modify it under the terms of the GNU General Public License
4 * as published by the Free Software Foundation; either version
5 * 2 of the License, or (at your option) any later version.
6 */
7
8 /* For putenv */
9 #define _XOPEN_SOURCE
10 #include <stdlib.h>
11 #include <unistd.h>
12 #include <string.h>
13 #include <stdio.h>
14
15 #define __MAIN__
16
17 #include "../backend/umax_pp_low.h"
18 #include "../backend/umax_pp_mid.h"
19
20 static void
Usage(char *name)21 Usage (char *name)
22 {
23 fprintf (stderr,
24 "%s [-c color_mode] [-x coord] [-y coord] [-w width] [-h height] [-g gain] [-z offset] [-d dpi] [-t level] [-s] [-p] [-l 0|1] [-a ioport_addr] [-r]\n",
25 name);
26 }
27
28
29 int
main(int argc, char **argv)30 main (int argc, char **argv)
31 {
32 char dbgstr[80];
33 int probe = 0;
34 int port = 0;
35 const char *name = NULL;
36 int scan = 0;
37 int lamp = -1;
38 int i;
39 int found;
40 int recover = 0;
41 int trace = 0;
42 int maxw, maxh;
43
44 #ifdef HAVE_LINUX_PPDEV_H
45 int fd;
46 #endif
47
48 /* scanning parameters : defaults to preview (75 dpi color, full scan area) */
49 int gain = 0x0;
50 int offset = 0x646;
51 int dpi = 75;
52 int x = 0, y = 0;
53 int width = -1, height = -1;
54 int color = RGB_MODE;
55
56 char **ports;
57 int rc;
58
59
60 /* option parsing */
61 /*
62 -c --color : color mode: RGB, BW, BW12, RGB12
63 -x : x coordinate
64 -y : y coordinate
65 -w --witdh : scan width
66 -h --height : scan height
67 -f --file : session file
68 -p --probe : probe scanner
69 -s --scan : scan
70 -t --trace : execution trace
71 -l --lamp : turn lamp on/off 1/0
72 -d --dpi : set scan resolution
73 -g --gain : set RVB gain
74 -z --offset: set offset
75 -a --addr : io port address
76 -n --name : ppdev device name
77 -r : recover from previous failed scan
78 -m --model : model revision
79 */
80
81
82 i = 1;
83 trace = 0;
84 sanei_umax_pp_setauto (1);
85 while (i < argc)
86 {
87 found = 0;
88
89 if ((strcmp (argv[i], "-p") == 0) || (strcmp (argv[i], "--probe") == 0))
90 {
91 probe = 1;
92 found = 1;
93 }
94
95 if ((strcmp (argv[i], "-c") == 0) || (strcmp (argv[i], "--color") == 0))
96 {
97 if (i == (argc - 1))
98 {
99 Usage (argv[0]);
100 fprintf (stderr, "expected color mode value\n");
101 return 0;
102 }
103 color = 0;
104 i++;
105 found = 1;
106 if (strcmp (argv[i], "RGB") == 0)
107 color = RGB_MODE;
108 if (strcmp (argv[i], "RGB12") == 0)
109 color = RGB12_MODE;
110 if (strcmp (argv[i], "BW") == 0)
111 color = BW_MODE;
112 if (strcmp (argv[i], "BW12") == 0)
113 color = BW12_MODE;
114 if (color == 0)
115 {
116 fprintf (stderr, "unexpected color mode value <%s>\n", argv[i]);
117 fprintf (stderr, "Must be RGB, RGB12, BW, or BW12\n");
118 return 0;
119 }
120 }
121
122
123 if (strcmp (argv[i], "-x") == 0)
124 {
125 if (i == (argc - 1))
126 {
127 Usage (argv[0]);
128 fprintf (stderr, "expected x value\n");
129 return 0;
130 }
131 x = atoi (argv[i + 1]);
132 i++;
133 found = 1;
134 }
135
136 if (strcmp (argv[i], "-y") == 0)
137 {
138 if (i == (argc - 1))
139 {
140 Usage (argv[0]);
141 fprintf (stderr, "expected y value\n");
142 return 0;
143 }
144 y = atoi (argv[i + 1]);
145 i++;
146 found = 1;
147 }
148
149 if ((strcmp (argv[i], "-w") == 0) || (strcmp (argv[i], "--witdh") == 0))
150 {
151 if (i == (argc - 1))
152 {
153 Usage (argv[0]);
154 fprintf (stderr, "expected width value\n");
155 return 0;
156 }
157 width = atoi (argv[i + 1]);
158 i++;
159 found = 1;
160 }
161
162 if ((strcmp (argv[i], "-h") == 0)
163 || (strcmp (argv[i], "--height") == 0))
164 {
165 if (i == (argc - 1))
166 {
167 Usage (argv[0]);
168 fprintf (stderr, "expected height value\n");
169 return 0;
170 }
171 height = atoi (argv[i + 1]);
172 i++;
173 found = 1;
174 }
175
176 if ((strcmp (argv[i], "-t") == 0) || (strcmp (argv[i], "--trace") == 0))
177 {
178 if (i == (argc - 1))
179 {
180 Usage (argv[0]);
181 fprintf (stderr, "expected trace value\n");
182 return 0;
183 }
184 trace = atoi (argv[i + 1]);
185 i++;
186 found = 1;
187 }
188
189
190 if ((strcmp (argv[i], "-r") == 0)
191 || (strcmp (argv[i], "--recover") == 0))
192 {
193 recover = 1;
194 found = 1;
195 }
196
197 if ((strcmp (argv[i], "-s") == 0) || (strcmp (argv[i], "--scan") == 0))
198 {
199 scan = 1;
200 /* we have to probe again if we scan */
201 probe = 1;
202 found = 1;
203 }
204
205 if ((strcmp (argv[i], "-d") == 0) || (strcmp (argv[i], "--dpi") == 0))
206 {
207 if (i == (argc - 1))
208 {
209 Usage (argv[0]);
210 fprintf (stderr, "expected dpi value\n");
211 return 0;
212 }
213 dpi = atoi (argv[i + 1]);
214 if ((dpi < 75) || (dpi > 1200))
215 {
216 fprintf (stderr, "dpi value has to be between 75 and 1200\n");
217 return 0;
218 }
219 if ((dpi != 75)
220 && (dpi != 150)
221 && (dpi != 300) && (dpi != 600) && (dpi != 1200))
222 {
223 fprintf (stderr,
224 "dpi value has to be 75, 150, 300, 600 or 1200\n");
225 return 0;
226 }
227 i++;
228 found = 1;
229 }
230
231 if ((strcmp (argv[i], "-g") == 0)
232 || (strcmp (argv[i], "--gain") == 0))
233 {
234 if (i == (argc - 1))
235 {
236 Usage (argv[0]);
237 fprintf (stderr, "expected hex gain value ( ex: A59 )\n");
238 return 0;
239 }
240 i++;
241 found = 1;
242 if (strlen (argv[i]) != 3)
243 {
244 Usage (argv[0]);
245 fprintf (stderr, "expected hex gain value ( ex: A59 )\n");
246 return 0;
247 }
248 gain = strtol (argv[i], NULL, 16);
249 sanei_umax_pp_setauto (0);
250 }
251
252 if ((strcmp (argv[i], "-z") == 0)
253 || (strcmp (argv[i], "--offset") == 0))
254 {
255 if (i == (argc - 1))
256 {
257 Usage (argv[0]);
258 fprintf (stderr, "expected hex offset value ( ex: A59 )\n");
259 return 0;
260 }
261 i++;
262 found = 1;
263 if (strlen (argv[i]) != 3)
264 {
265 Usage (argv[0]);
266 fprintf (stderr, "expected hex offset value ( ex: A59 )\n");
267 return 0;
268 }
269 offset = strtol (argv[i], NULL, 16);
270 }
271
272 if ((strcmp (argv[i], "-n") == 0) || (strcmp (argv[i], "--name") == 0))
273 {
274 if (i == (argc - 1))
275 {
276 Usage (argv[0]);
277 fprintf (stderr,
278 "expected device name ( ex: /dev/parport0 )\n");
279 return 0;
280 }
281 i++;
282 found = 1;
283 name = argv[i];
284 }
285 if ((strcmp (argv[i], "-a") == 0) || (strcmp (argv[i], "--addr") == 0))
286 {
287 if (i == (argc - 1))
288 {
289 Usage (argv[0]);
290 fprintf (stderr, "expected hex io port value ( ex: 3BC )\n");
291 return 0;
292 }
293 i++;
294 found = 1;
295 if ((strlen (argv[i]) < 3) || (strlen (argv[i]) > 4))
296 {
297 Usage (argv[0]);
298 fprintf (stderr, "expected hex io port value ( ex: 378 )\n");
299 return 0;
300 }
301 port = strtol (argv[i], NULL, 16);
302 }
303
304
305 if ((strcmp (argv[i], "-l") == 0) || (strcmp (argv[i], "--lamp") == 0))
306 {
307 if (i == (argc - 1))
308 {
309 Usage (argv[0]);
310 fprintf (stderr, "expected lamp value\n");
311 return 0;
312 }
313 lamp = atoi (argv[i + 1]);
314 i++;
315 found = 1;
316 }
317
318 if (!found)
319 {
320 Usage (argv[0]);
321 fprintf (stderr, "unexpected argument <%s>\n", argv[i]);
322 return 0;
323 }
324
325 /* next arg */
326 i++;
327 }
328
329 /* since we use DBG, we have to set env var */
330 /* according to the required trace level */
331 if (trace)
332 {
333 sprintf (dbgstr, "SANE_DEBUG_UMAX_PP_LOW=%d", trace);
334 putenv (dbgstr);
335 }
336
337 /* no address or device given */
338 rc = 0;
339 if ((name == NULL) && (port == 0))
340 {
341 /* safe tests: user parallel port devices */
342 ports = sanei_parport_find_device ();
343 if (ports != NULL)
344 {
345 i = 0;
346 rc = 0;
347 while ((ports[i] != NULL) && (rc != 1))
348 {
349 rc = sanei_umax_pp_initPort (port, ports[i]);
350 i++;
351 }
352 }
353
354 /* try for direct hardware access */
355 if (rc != 1)
356 {
357 ports = sanei_parport_find_port ();
358 i = 0;
359 rc = 0;
360 while ((ports[i] != NULL) && (rc != 1))
361 {
362 rc = sanei_umax_pp_initPort (strtol (ports[i], NULL, 16), NULL);
363 i++;
364 }
365 }
366 if (rc != 1)
367 {
368 fprintf (stderr, "failed to detect a valid device or port!\n");
369 return 0;
370 }
371 }
372 else
373 {
374 if (sanei_umax_pp_initPort (port, name) != 1)
375 {
376 if (port)
377 fprintf (stderr, "failed to gain direct access to port 0x%X!\n",
378 port);
379 else
380 fprintf (stderr, "failed to gain access to device %s!\n", name);
381 return 0;
382 }
383 }
384 if (trace)
385 {
386 printf
387 ("UMAX 610P/1220P/2000P scanning program version 6.4 starting ...\n");
388 #ifdef HAVE_LINUX_PPDEV_H
389 printf ("ppdev character device built-in.\n");
390 #endif
391 #ifdef ENABLE_PARPORT_DIRECTIO
392 printf ("direct hardware access built-in.\n");
393 #endif
394 }
395
396
397 /* scanning is the default behaviour */
398 if ((!scan) && (lamp < 0) && (!probe))
399 scan = 1;
400
401
402 /* probe scanner */
403 if ((probe) || (lamp >= 0))
404 {
405 printf ("Probing scanner ....\n");
406 if (sanei_umax_pp_probeScanner (recover) != 1)
407 {
408 if (recover)
409 {
410 sanei_umax_pp_initTransport (recover);
411 sanei_umax_pp_endSession ();
412 if (sanei_umax_pp_probeScanner (recover) != 1)
413 {
414 printf ("Recover failed ....\n");
415 return 0;
416 }
417 printf ("Recover done !\n");
418 }
419 else
420 return 0;
421 }
422
423 /* could be written better .... but it is only test */
424 sanei_umax_pp_endSession ();
425
426 /* init transport layer */
427 if (sanei_umax_pp_initTransport (0) != 1)
428 {
429 printf ("initTransport() failed (%s:%d)\n", __FILE__, __LINE__);
430 return 0;
431 }
432 i = sanei_umax_pp_checkModel ();
433 if (i < 600)
434 {
435 sanei_umax_pp_endSession ();
436 printf ("checkModel() failed (%s:%d)\n", __FILE__, __LINE__);
437 return 0;
438 }
439 printf ("UMAX Astra %dP detected \n", i);
440
441 /* free scanner if a scan is planned */
442 if (scan)
443 sanei_umax_pp_endSession ();
444 printf ("Done ....\n");
445 }
446
447 /* lamp on/off: must come after probing (610p handling) */
448 if (lamp >= 0)
449 {
450 /* init transport layer */
451 if (trace)
452 printf ("Tryning to set lamp %s\n", lamp ? "on" : "off");
453 if (sanei_umax_pp_initTransport (recover) != 1)
454 {
455 printf ("initTransport() failed (%s:%d)\n", __FILE__, __LINE__);
456 return 0;
457 }
458 else
459 {
460 if (trace)
461 printf ("initTransport passed...\n");
462 }
463 if (sanei_umax_pp_setLamp (lamp) == 0)
464 {
465 fprintf (stderr, "Setting lamp state failed!\n");
466 return 0;
467 }
468 else
469 {
470 if (trace)
471 printf ("sanei_umax_pp_setLamp passed...\n");
472 }
473 }
474
475 /* scan */
476 if (scan)
477 {
478 printf ("Scanning ....\n");
479 if (sanei_umax_pp_getastra () < 1210)
480 {
481 maxw = 2550;
482 maxh = 3500;
483 }
484 else
485 {
486 maxw = 5100;
487 maxh = 7000;
488 }
489 if (width < 0)
490 width = maxw;
491 if (height < 0)
492 height = maxh;
493
494 if ((width < 1) || (width > maxw))
495 {
496 fprintf (stderr, "width must be between 1 and %d\n", maxw);
497 return 0;
498 }
499 if (x + width > maxw)
500 {
501 fprintf (stderr,
502 "Right side of scan area exceed physical limits (x+width>%d)\n",
503 maxw);
504 return 0;
505 }
506 if (y < 0 || y > maxh)
507 {
508 fprintf (stderr, "y must be between 0 and %d\n", maxh - 1);
509 return 0;
510 }
511 if (x < 0 || x > maxw)
512 {
513 fprintf (stderr, "x must be between 0 and %d\n", maxw - 1);
514 return 0;
515 }
516 if ((height < 1) || (height > maxh))
517 {
518 fprintf (stderr, "height must be between 1 and %d\n", maxh);
519 return 0;
520 }
521 if (y + height > maxh)
522 {
523 fprintf (stderr,
524 "Bottom side of scan area exceed physical limits (y+height>%d)\n",
525 maxh);
526 return 0;
527 }
528
529 /* init transport layer */
530 /* 0: failed
531 1: success
532 2: retry
533 */
534 do
535 {
536 i = sanei_umax_pp_initTransport (recover);
537 }
538 while (i == 2);
539 if (i != 1)
540 {
541 printf ("initTransport() failed (%s:%d)\n", __FILE__, __LINE__);
542 return 0;
543 }
544 /* init scanner */
545 if (sanei_umax_pp_initScanner (recover) == 0)
546 {
547 sanei_umax_pp_endSession ();
548 return 0;
549 }
550
551 /* set x origin left to right */
552 x = sanei_umax_pp_getLeft () + (maxw - x) - width;
553
554 /* scan */
555 if (sanei_umax_pp_scan
556 (x, y, width, height, dpi, color, gain, offset) != 1)
557 {
558 sanei_umax_pp_endSession ();
559 return 0;
560 }
561
562 /* wait for head parking */
563 sanei_umax_pp_parkWait ();
564 printf ("Done ....\n");
565 }
566 sanei_umax_pp_endSession ();
567 #ifdef HAVE_LINUX_PPDEV_H
568 fd = sanei_umax_pp_getparport ();
569 if (fd > 0)
570 {
571 close (fd);
572 sanei_umax_pp_setparport (0);
573 }
574 #endif
575
576 return 1;
577 }
578