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