1 /* sane - Scanner Access Now Easy.
2    Copyright (C) 1998, Feico W. Dillema
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 
40 /*
41         This file implements a SANE backend for Ricoh flatbed scanners.
42 */
43 
44 #include "../include/sane/config.h"
45 
46 #include <limits.h>
47 #include <stdlib.h>
48 #include <stdarg.h>
49 #include <string.h>
50 #include <time.h>
51 #include <sys/time.h>
52 #include <unistd.h>
53 #include <ctype.h>
54 
55 #include "../include/sane/sane.h"
56 #include "../include/sane/saneopts.h"
57 #include "../include/sane/sanei_scsi.h"
58 
59 #define BACKEND_NAME ricoh
60 #include "../include/sane/sanei_backend.h"
61 
62 #ifndef PATH_MAX
63 # define PATH_MAX	1024
64 #endif
65 
66 #include "../include/sane/sanei_config.h"
67 #define RICOH_CONFIG_FILE "ricoh.conf"
68 
69 #include "ricoh.h"
70 
71 #define MAX(a,b)	((a) > (b) ? (a) : (b))
72 
73 static const SANE_Device **devlist = NULL;
74 static int num_devices = 0;
75 static Ricoh_Device *first_dev = NULL;
76 static Ricoh_Scanner *first_handle = NULL;
77 static int is50 = 0;
78 
79 #include "ricoh-scsi.c"
80 
81 static size_t
max_string_size(const SANE_String_Const strings[])82 max_string_size (const SANE_String_Const strings[])
83 {
84   size_t size, max_size = 0;
85   int i;
86   DBG (11, ">> max_string_size\n");
87 
88   for (i = 0; strings[i]; ++i)
89     {
90       size = strlen (strings[i]) + 1;
91       if (size > max_size)
92         max_size = size;
93     }
94 
95   DBG (11, "<< max_string_size\n");
96   return max_size;
97 }
98 
99 static SANE_Status
attach(const char *devnam, Ricoh_Device ** devp)100 attach (const char *devnam, Ricoh_Device ** devp)
101 {
102   SANE_Status status;
103   Ricoh_Device *dev;
104 
105   int fd;
106   struct inquiry_data ibuf;
107   struct measurements_units_page mup;
108   struct ricoh_window_data wbuf;
109   size_t buf_size;
110   char *str;
111   DBG (11, ">> attach\n");
112 
113   for (dev = first_dev; dev; dev = dev->next)
114     {
115       if (strcmp (dev->sane.name, devnam) == 0)
116         {
117           if (devp)
118             *devp = dev;
119           return (SANE_STATUS_GOOD);
120         }
121     }
122 
123   DBG (3, "attach: opening %s\n", devnam);
124   status = sanei_scsi_open (devnam, &fd, NULL, NULL);
125   if (status != SANE_STATUS_GOOD)
126     {
127       DBG (1, "attach: open failed: %s\n", sane_strstatus (status));
128       return (status);
129     }
130 
131   DBG (3, "attach: sending INQUIRY\n");
132   memset (&ibuf, 0, sizeof (ibuf));
133   buf_size = sizeof(ibuf);
134   status = inquiry (fd, &ibuf, &buf_size);
135   if (status != SANE_STATUS_GOOD)
136     {
137       DBG (1, "attach: inquiry failed: %s\n", sane_strstatus (status));
138       sanei_scsi_close (fd);
139       return (status);
140     }
141 
142   if (ibuf.devtype != 6
143       || strncmp ((char *)ibuf.vendor, "RICOH", 5) != 0
144       || (strncmp ((char *)ibuf.product, "IS50", 4) != 0
145 	  && strncmp ((char *)ibuf.product, "IS60", 4) != 0))
146     {
147       DBG (1, "attach: device doesn't look like the Ricoh scanner I know\n");
148       sanei_scsi_close (fd);
149       return (SANE_STATUS_INVAL);
150     }
151   is50 = (strncmp ((char *)ibuf.product, "IS50", 4) == 0);
152 
153   DBG (3, "attach: sending TEST_UNIT_READY\n");
154   status = test_unit_ready (fd);
155   if (status != SANE_STATUS_GOOD)
156     {
157       DBG (1, "attach: test unit ready failed (%s)\n",
158            sane_strstatus (status));
159       sanei_scsi_close (fd);
160       return (status);
161     }
162 
163   DBG (3, "attach: sending OBJECT POSITION\n");
164   status = object_position (fd);
165   if (status != SANE_STATUS_GOOD)
166     {
167       DBG (1, "attach: OBJECT POSITION failed\n");
168       sanei_scsi_close (fd);
169       return (SANE_STATUS_INVAL);
170     }
171 
172   memset (&mup, 0, sizeof (mup));
173   mup.page_code = MEASUREMENTS_PAGE;
174   mup.parameter_length = 0x06;
175   mup.bmu = INCHES;
176   mup.mud[0] = (DEFAULT_MUD >> 8) & 0xff;
177   mup.mud[1] = (DEFAULT_MUD & 0xff);
178 
179 #if 0
180   DBG (3, "attach: sending MODE SELECT\n");
181   status = mode_select (fd, (struct mode_pages *) &mup);
182   if (status != SANE_STATUS_GOOD)
183     {
184       DBG (1, "attach: MODE_SELECT failed\n");
185       sanei_scsi_close (fd);
186       return (SANE_STATUS_INVAL);
187     }
188 #endif
189 
190 #if 0
191   DBG (3, "attach: sending MODE SENSE\n");
192   memset (&mup, 0, sizeof (mup));
193   status = mode_sense (fd, (struct mode_pages *) &mup, PC_CURRENT | MEASUREMENTS_PAGE);
194   if (status != SANE_STATUS_GOOD)
195     {
196       DBG (1, "attach: MODE_SENSE failed\n");
197       sanei_scsi_close (fd);
198       return (SANE_STATUS_INVAL);
199     }
200 #endif
201 
202   DBG (3, "attach: sending GET WINDOW\n");
203   memset (&wbuf, 0, sizeof (wbuf));
204   status = get_window (fd, &wbuf);
205   if (status != SANE_STATUS_GOOD)
206     {
207       DBG (1, "attach: GET_WINDOW failed %d\n", status);
208       sanei_scsi_close (fd);
209       DBG (11, "<< attach\n");
210       return (SANE_STATUS_INVAL);
211     }
212 
213   sanei_scsi_close (fd);
214 
215   dev = malloc (sizeof (*dev));
216   if (!dev)
217     return (SANE_STATUS_NO_MEM);
218   memset (dev, 0, sizeof (*dev));
219 
220   dev->sane.name = strdup (devnam);
221   dev->sane.vendor = "RICOH";
222 
223   size_t prod_rev_size = sizeof(ibuf.product) + sizeof(ibuf.revision) + 1;
224   str = malloc (prod_rev_size);
225   if (str)
226     {
227       snprintf (str, prod_rev_size, "%.*s%.*s",
228                 (int) sizeof(ibuf.product), (const char *) ibuf.product,
229                 (int) sizeof(ibuf.revision), (const char *) ibuf.revision);
230     }
231   dev->sane.model = str;
232   dev->sane.type = "flatbed scanner";
233 
234   DBG (5, "dev->sane.name = %s\n", dev->sane.name);
235   DBG (5, "dev->sane.vendor = %s\n", dev->sane.vendor);
236   DBG (5, "dev->sane.model = %s\n", dev->sane.model);
237   DBG (5, "dev->sane.type = %s\n", dev->sane.type);
238 
239   dev->info.xres_default = _2btol(wbuf.x_res);
240   dev->info.yres_default = _2btol(wbuf.y_res);
241   dev->info.image_mode_default = wbuf.image_comp;
242 
243   /* if you throw the MRIF bit the brightness control reverses too */
244   /* so I reverse the reversal in software for symmetry's sake */
245   /* I should make this into an option */
246 
247   if (wbuf.image_comp == RICOH_GRAYSCALE || wbuf.image_comp == RICOH_DITHERED_MONOCHROME)
248     {
249       dev->info.brightness_default = 256 - wbuf.brightness;
250       if (is50)
251 	dev->info.contrast_default = wbuf.contrast;
252       else
253 	dev->info.contrast_default = 256 - wbuf.contrast;
254     }
255   else /* wbuf.image_comp == RICOH_BINARY_MONOCHROME */
256     {
257       dev->info.brightness_default = wbuf.brightness;
258       dev->info.contrast_default = wbuf.contrast;
259     }
260 
261 #if 1
262   dev->info.bmu = mup.bmu;
263   dev->info.mud = _2btol(mup.mud);
264   if (dev->info.mud == 0) {
265     /* The RICOH says it uses points as default Basic Measurement Unit */
266     /* but gives a Measurement Unit Divisor of zero */
267     /* So, we set it to the default (SCSI-standard) of 1200 */
268     /* with BMU in inches, i.e. 1200 points equal 1 inch */
269     dev->info.bmu = INCHES;
270     dev->info.mud = DEFAULT_MUD;
271   }
272 #else
273     dev->info.bmu = INCHES;
274     dev->info.mud = DEFAULT_MUD;
275 #endif
276 
277   DBG (5, "xres_default=%d\n", dev->info.xres_default);
278   DBG (5, "xres_range.max=%d\n", dev->info.xres_range.max);
279   DBG (5, "xres_range.min=%d\n", dev->info.xres_range.min);
280 
281   DBG (5, "yres_default=%d\n", dev->info.yres_default);
282   DBG (5, "yres_range.max=%d\n", dev->info.yres_range.max);
283   DBG (5, "yres_range.min=%d\n", dev->info.yres_range.min);
284 
285   DBG (5, "x_range.max=%d\n", dev->info.x_range.max);
286   DBG (5, "y_range.max=%d\n", dev->info.y_range.max);
287 
288   DBG (5, "image_mode=%d\n", dev->info.image_mode_default);
289 
290   DBG (5, "brightness=%d\n", dev->info.brightness_default);
291   DBG (5, "contrast=%d\n", dev->info.contrast_default);
292 
293   DBG (5, "bmu=%d\n", dev->info.bmu);
294   DBG (5, "mud=%d\n", dev->info.mud);
295 
296   ++num_devices;
297   dev->next = first_dev;
298   first_dev = dev;
299 
300   if (devp)
301     *devp = dev;
302 
303   DBG (11, "<< attach\n");
304   return (SANE_STATUS_GOOD);
305 }
306 
307 static SANE_Status
attach_one(const char *devnam)308 attach_one(const char *devnam)
309 {
310   attach (devnam, NULL);
311   return SANE_STATUS_GOOD;
312 }
313 
314 static SANE_Status
init_options(Ricoh_Scanner * s)315 init_options (Ricoh_Scanner * s)
316 {
317   int i;
318   DBG (11, ">> init_options\n");
319 
320   memset (s->opt, 0, sizeof (s->opt));
321   memset (s->val, 0, sizeof (s->val));
322 
323   for (i = 0; i < NUM_OPTIONS; ++i)
324     {
325       s->opt[i].size = sizeof (SANE_Word);
326       s->opt[i].cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT;
327     }
328 
329   s->opt[OPT_NUM_OPTS].title = SANE_TITLE_NUM_OPTIONS;
330   s->opt[OPT_NUM_OPTS].desc = SANE_DESC_NUM_OPTIONS;
331   s->opt[OPT_NUM_OPTS].type = SANE_TYPE_INT;
332   s->opt[OPT_NUM_OPTS].cap = SANE_CAP_SOFT_DETECT;
333   s->val[OPT_NUM_OPTS].w = NUM_OPTIONS;
334 
335   /* "Mode" group: */
336   s->opt[OPT_MODE_GROUP].title = "Scan Mode";
337   s->opt[OPT_MODE_GROUP].desc = "";
338   s->opt[OPT_MODE_GROUP].type = SANE_TYPE_GROUP;
339   s->opt[OPT_MODE_GROUP].cap = 0;
340   s->opt[OPT_MODE_GROUP].constraint_type = SANE_CONSTRAINT_NONE;
341 
342   /* scan mode */
343   s->opt[OPT_MODE].name = SANE_NAME_SCAN_MODE;
344   s->opt[OPT_MODE].title = SANE_TITLE_SCAN_MODE;
345   s->opt[OPT_MODE].desc = SANE_DESC_SCAN_MODE;
346   s->opt[OPT_MODE].type = SANE_TYPE_STRING;
347   s->opt[OPT_MODE].size = max_string_size (mode_list);
348   s->opt[OPT_MODE].constraint_type = SANE_CONSTRAINT_STRING_LIST;
349   s->opt[OPT_MODE].constraint.string_list = mode_list;
350   s->val[OPT_MODE].s = strdup (mode_list[s->hw->info.image_mode_default]);
351 
352   /* x resolution */
353   s->opt[OPT_X_RESOLUTION].name = "X" SANE_NAME_SCAN_RESOLUTION;
354   s->opt[OPT_X_RESOLUTION].title = "X " SANE_TITLE_SCAN_RESOLUTION;
355   s->opt[OPT_X_RESOLUTION].desc = SANE_DESC_SCAN_RESOLUTION;
356   s->opt[OPT_X_RESOLUTION].type = SANE_TYPE_INT;
357   s->opt[OPT_X_RESOLUTION].unit = SANE_UNIT_DPI;
358   s->opt[OPT_X_RESOLUTION].constraint_type = SANE_CONSTRAINT_RANGE;
359   s->opt[OPT_X_RESOLUTION].constraint.range = &is60_res_range;
360   s->val[OPT_X_RESOLUTION].w = s->hw->info.xres_default;
361   if (is50)
362     s->opt[OPT_X_RESOLUTION].constraint.range = &is50_res_range;
363   else
364     s->opt[OPT_X_RESOLUTION].constraint.range = &is60_res_range;
365 
366   /* y resolution */
367   s->opt[OPT_Y_RESOLUTION].name = "Y" SANE_NAME_SCAN_RESOLUTION;
368   s->opt[OPT_Y_RESOLUTION].title = "Y " SANE_TITLE_SCAN_RESOLUTION;
369   s->opt[OPT_Y_RESOLUTION].desc = SANE_DESC_SCAN_RESOLUTION;
370   s->opt[OPT_Y_RESOLUTION].type = SANE_TYPE_INT;
371   s->opt[OPT_Y_RESOLUTION].unit = SANE_UNIT_DPI;
372   s->opt[OPT_Y_RESOLUTION].constraint_type = SANE_CONSTRAINT_RANGE;
373   s->val[OPT_Y_RESOLUTION].w =  s->hw->info.yres_default;
374   if (is50)
375     s->opt[OPT_Y_RESOLUTION].constraint.range = &is50_res_range;
376   else
377     s->opt[OPT_Y_RESOLUTION].constraint.range = &is60_res_range;
378 
379   /* "Geometry" group: */
380   s->opt[OPT_GEOMETRY_GROUP].title = "Geometry";
381   s->opt[OPT_GEOMETRY_GROUP].desc = "";
382   s->opt[OPT_GEOMETRY_GROUP].type = SANE_TYPE_GROUP;
383   s->opt[OPT_GEOMETRY_GROUP].cap = SANE_CAP_ADVANCED;
384   s->opt[OPT_GEOMETRY_GROUP].constraint_type = SANE_CONSTRAINT_NONE;
385 
386   /* top-left x */
387   s->opt[OPT_TL_X].name = SANE_NAME_SCAN_TL_X;
388   s->opt[OPT_TL_X].title = SANE_TITLE_SCAN_TL_X;
389   s->opt[OPT_TL_X].desc = SANE_DESC_SCAN_TL_X;
390   s->opt[OPT_TL_X].type = SANE_TYPE_INT;
391   s->opt[OPT_TL_X].unit = SANE_UNIT_PIXEL;
392   s->opt[OPT_TL_X].constraint_type = SANE_CONSTRAINT_RANGE;
393   s->opt[OPT_TL_X].constraint.range = &default_x_range;
394   s->val[OPT_TL_X].w = 0;
395 
396   /* top-left y */
397   s->opt[OPT_TL_Y].name = SANE_NAME_SCAN_TL_Y;
398   s->opt[OPT_TL_Y].title = SANE_TITLE_SCAN_TL_Y;
399   s->opt[OPT_TL_Y].desc = SANE_DESC_SCAN_TL_Y;
400   s->opt[OPT_TL_Y].type = SANE_TYPE_INT;
401   s->opt[OPT_TL_Y].unit = SANE_UNIT_PIXEL;
402   s->opt[OPT_TL_Y].constraint_type = SANE_CONSTRAINT_RANGE;
403   s->opt[OPT_TL_Y].constraint.range = &default_y_range;
404   s->val[OPT_TL_Y].w = 0;
405 
406   /* bottom-right x */
407   s->opt[OPT_BR_X].name = SANE_NAME_SCAN_BR_X;
408   s->opt[OPT_BR_X].title = SANE_TITLE_SCAN_BR_X;
409   s->opt[OPT_BR_X].desc = SANE_DESC_SCAN_BR_X;
410   s->opt[OPT_BR_X].type = SANE_TYPE_INT;
411   s->opt[OPT_BR_X].unit = SANE_UNIT_PIXEL;
412   s->opt[OPT_BR_X].constraint_type = SANE_CONSTRAINT_RANGE;
413   s->opt[OPT_BR_X].constraint.range = &default_x_range;
414   s->val[OPT_BR_X].w = default_x_range.max;
415 
416   /* bottom-right y */
417   s->opt[OPT_BR_Y].name = SANE_NAME_SCAN_BR_Y;
418   s->opt[OPT_BR_Y].title = SANE_TITLE_SCAN_BR_Y;
419   s->opt[OPT_BR_Y].desc = SANE_DESC_SCAN_BR_Y;
420   s->opt[OPT_BR_Y].type = SANE_TYPE_INT;
421   s->opt[OPT_BR_Y].unit = SANE_UNIT_PIXEL;
422   s->opt[OPT_BR_Y].constraint_type = SANE_CONSTRAINT_RANGE;
423   s->opt[OPT_BR_Y].constraint.range = &default_y_range;
424   s->val[OPT_BR_Y].w = default_y_range.max;
425 
426   /* "Enhancement" group: */
427   s->opt[OPT_ENHANCEMENT_GROUP].title = "Enhancement";
428   s->opt[OPT_ENHANCEMENT_GROUP].desc = "";
429   s->opt[OPT_ENHANCEMENT_GROUP].type = SANE_TYPE_GROUP;
430   s->opt[OPT_ENHANCEMENT_GROUP].cap = 0;
431   s->opt[OPT_ENHANCEMENT_GROUP].constraint_type = SANE_CONSTRAINT_NONE;
432 
433   /* brightness */
434   s->opt[OPT_BRIGHTNESS].name = SANE_NAME_BRIGHTNESS;
435   s->opt[OPT_BRIGHTNESS].title = SANE_TITLE_BRIGHTNESS;
436   s->opt[OPT_BRIGHTNESS].desc = SANE_DESC_BRIGHTNESS;
437   s->opt[OPT_BRIGHTNESS].type = SANE_TYPE_INT;
438   s->opt[OPT_BRIGHTNESS].unit = SANE_UNIT_NONE;
439   s->opt[OPT_BRIGHTNESS].constraint_type = SANE_CONSTRAINT_RANGE;
440   s->opt[OPT_BRIGHTNESS].constraint.range = &u8_range;
441   s->val[OPT_BRIGHTNESS].w =  s->hw->info.brightness_default;
442 
443   /* contrast */
444   s->opt[OPT_CONTRAST].name = SANE_NAME_CONTRAST;
445   s->opt[OPT_CONTRAST].title = SANE_TITLE_CONTRAST;
446   s->opt[OPT_CONTRAST].desc = SANE_DESC_CONTRAST;
447   s->opt[OPT_CONTRAST].type = SANE_TYPE_INT;
448   s->opt[OPT_CONTRAST].unit = SANE_UNIT_NONE;
449   s->opt[OPT_CONTRAST].constraint_type = SANE_CONSTRAINT_RANGE;
450   s->opt[OPT_CONTRAST].constraint.range = &u8_range;
451   s->val[OPT_CONTRAST].w =  s->hw->info.contrast_default;
452 
453   DBG (11, "<< init_options\n");
454   return SANE_STATUS_GOOD;
455 }
456 
457 static SANE_Status
do_cancel(Ricoh_Scanner * s)458 do_cancel (Ricoh_Scanner * s)
459 {
460   SANE_Status status;
461   DBG (11, ">> do_cancel\n");
462 
463   DBG (3, "cancel: sending OBJECT POSITION\n");
464   status = object_position (s->fd);
465   if (status != SANE_STATUS_GOOD)
466     {
467       DBG (1, "cancel: OBJECT POSITION failed\n");
468     }
469 
470   s->scanning = SANE_FALSE;
471 
472   if (s->fd >= 0)
473     {
474       sanei_scsi_close (s->fd);
475       s->fd = -1;
476     }
477 
478   DBG (11, "<< do_cancel\n");
479   return (SANE_STATUS_CANCELLED);
480 }
481 
482 SANE_Status
sane_init(SANE_Int * version_code, SANE_Auth_Callback authorize)483 sane_init (SANE_Int * version_code, SANE_Auth_Callback authorize)
484 {
485   char devnam[PATH_MAX] = "/dev/scanner";
486   FILE *fp;
487 
488   (void) authorize;		/* silence gcc */
489 
490   DBG_INIT ();
491   DBG (11, ">> sane_init\n");
492 
493 #if defined PACKAGE && defined VERSION
494   DBG (2, "sane_init: " PACKAGE " " VERSION "\n");
495 #endif
496 
497   if (version_code)
498     *version_code = SANE_VERSION_CODE (SANE_CURRENT_MAJOR, SANE_CURRENT_MINOR, 0);
499 
500   fp = sanei_config_open(RICOH_CONFIG_FILE);
501   if (fp)
502     {
503       char line[PATH_MAX], *lp;
504       size_t len;
505 
506       /* read config file */
507       while (sanei_config_read (line, sizeof (line), fp))
508         {
509           if (line[0] == '#')           /* ignore line comments */
510             continue;
511           len = strlen (line);
512 
513           if (!len)
514             continue;                   /* ignore empty lines */
515 
516 	  /* skip white space: */
517 	  for (lp = line; isspace(*lp); ++lp)
518             ;
519           strcpy (devnam, lp);
520         }
521       fclose (fp);
522     }
523   sanei_config_attach_matching_devices (devnam, attach_one);
524   DBG (11, "<< sane_init\n");
525   return SANE_STATUS_GOOD;
526 }
527 
528 void
sane_exit(void)529 sane_exit (void)
530 {
531   Ricoh_Device *dev, *next;
532   DBG (11, ">> sane_exit\n");
533 
534   for (dev = first_dev; dev; dev = next)
535     {
536       next = dev->next;
537       free ((void *) dev->sane.name);
538       free ((void *) dev->sane.model);
539       free (dev);
540     }
541 
542   if (devlist)
543     free (devlist);
544 
545   DBG (11, "<< sane_exit\n");
546 }
547 
548 SANE_Status
sane_get_devices(const SANE_Device *** device_list, SANE_Bool local_only)549 sane_get_devices (const SANE_Device *** device_list, SANE_Bool local_only)
550 {
551   Ricoh_Device *dev;
552   int i;
553 
554   (void) local_only;		/* silence gcc */
555 
556   DBG (11, ">> sane_get_devices\n");
557 
558   if (devlist)
559     free (devlist);
560   devlist = malloc ((num_devices + 1) * sizeof (devlist[0]));
561   if (!devlist)
562     return (SANE_STATUS_NO_MEM);
563 
564   i = 0;
565   for (dev = first_dev; dev; dev = dev->next)
566     devlist[i++] = &dev->sane;
567   devlist[i++] = 0;
568 
569   *device_list = devlist;
570 
571   DBG (11, "<< sane_get_devices\n");
572   return SANE_STATUS_GOOD;
573 }
574 
575 SANE_Status
sane_open(SANE_String_Const devnam, SANE_Handle * handle)576 sane_open (SANE_String_Const devnam, SANE_Handle * handle)
577 {
578   SANE_Status status;
579   Ricoh_Device *dev;
580   Ricoh_Scanner *s;
581   DBG (11, ">> sane_open\n");
582 
583   if (devnam[0] == '\0')
584     {
585       for (dev = first_dev; dev; dev = dev->next)
586         {
587           if (strcmp (dev->sane.name, devnam) == 0)
588             break;
589         }
590 
591       if (!dev)
592         {
593           status = attach (devnam, &dev);
594           if (status != SANE_STATUS_GOOD)
595             return (status);
596         }
597     }
598   else
599     {
600       dev = first_dev;
601     }
602 
603   if (!dev)
604     return (SANE_STATUS_INVAL);
605 
606   s = malloc (sizeof (*s));
607   if (!s)
608     return SANE_STATUS_NO_MEM;
609   memset (s, 0, sizeof (*s));
610 
611   s->fd = -1;
612   s->hw = dev;
613 
614   init_options (s);
615 
616   s->next = first_handle;
617   first_handle = s;
618 
619   *handle = s;
620 
621   DBG (11, "<< sane_open\n");
622   return SANE_STATUS_GOOD;
623 }
624 
625 void
sane_close(SANE_Handle handle)626 sane_close (SANE_Handle handle)
627 {
628   Ricoh_Scanner *s = (Ricoh_Scanner *) handle;
629   DBG (11, ">> sane_close\n");
630 
631   if (s->fd != -1)
632     sanei_scsi_close (s->fd);
633   free (s);
634 
635   DBG (11, ">> sane_close\n");
636 }
637 
638 const SANE_Option_Descriptor *
sane_get_option_descriptor(SANE_Handle handle, SANE_Int option)639 sane_get_option_descriptor (SANE_Handle handle, SANE_Int option)
640 {
641   Ricoh_Scanner *s = handle;
642   DBG (11, ">> sane_get_option_descriptor\n");
643 
644   if ((unsigned) option >= NUM_OPTIONS)
645     return (0);
646 
647   DBG (11, "<< sane_get_option_descriptor\n");
648   return (s->opt + option);
649 }
650 
651 SANE_Status
sane_control_option(SANE_Handle handle, SANE_Int option, SANE_Action action, void *val, SANE_Int * info)652 sane_control_option (SANE_Handle handle, SANE_Int option,
653                      SANE_Action action, void *val, SANE_Int * info)
654 {
655   Ricoh_Scanner *s = handle;
656   SANE_Status status;
657   SANE_Word cap;
658   DBG (11, ">> sane_control_option\n");
659 
660   if (info)
661     *info = 0;
662 
663   if (s->scanning)
664     return (SANE_STATUS_DEVICE_BUSY);
665   if (option >= NUM_OPTIONS)
666     return (SANE_STATUS_INVAL);
667 
668   cap = s->opt[option].cap;
669   if (!SANE_OPTION_IS_ACTIVE (cap))
670     return (SANE_STATUS_INVAL);
671 
672   if (action == SANE_ACTION_GET_VALUE)
673     {
674       switch (option)
675         {
676           /* word options: */
677         case OPT_X_RESOLUTION:
678         case OPT_Y_RESOLUTION:
679         case OPT_TL_X:
680         case OPT_TL_Y:
681         case OPT_BR_X:
682         case OPT_BR_Y:
683         case OPT_NUM_OPTS:
684         case OPT_BRIGHTNESS:
685         case OPT_CONTRAST:
686           *(SANE_Word *) val = s->val[option].w;
687           return (SANE_STATUS_GOOD);
688 
689           /* string options: */
690         case OPT_MODE:
691           strcpy (val, s->val[option].s);
692           return (SANE_STATUS_GOOD);
693         }
694     }
695   else if (action == SANE_ACTION_SET_VALUE)
696     {
697       if (!SANE_OPTION_IS_SETTABLE (cap))
698         return (SANE_STATUS_INVAL);
699 
700       status = sanei_constrain_value (s->opt + option, val, info);
701       if (status != SANE_STATUS_GOOD)
702         return status;
703 
704       switch (option)
705         {
706           /* (mostly) side-effect-free word options: */
707         case OPT_X_RESOLUTION:
708         case OPT_Y_RESOLUTION:
709         case OPT_TL_X:
710         case OPT_TL_Y:
711         case OPT_BR_X:
712         case OPT_BR_Y:
713           if (info && s->val[option].w != *(SANE_Word *) val)
714             *info |= SANE_INFO_RELOAD_PARAMS;
715           /* fall through */
716         case OPT_NUM_OPTS:
717         case OPT_BRIGHTNESS:
718         case OPT_CONTRAST:
719           s->val[option].w = *(SANE_Word *) val;
720           return (SANE_STATUS_GOOD);
721 
722         case OPT_MODE:
723           if (info && strcmp (s->val[option].s, (SANE_String) val))
724             *info |= SANE_INFO_RELOAD_OPTIONS | SANE_INFO_RELOAD_PARAMS;
725           if (s->val[option].s)
726             free (s->val[option].s);
727           s->val[option].s = strdup (val);
728           return (SANE_STATUS_GOOD);
729         }
730     }
731 
732   DBG (11, "<< sane_control_option\n");
733   return (SANE_STATUS_INVAL);
734 }
735 
736 SANE_Status
sane_get_parameters(SANE_Handle handle, SANE_Parameters * params)737 sane_get_parameters (SANE_Handle handle, SANE_Parameters * params)
738 {
739   Ricoh_Scanner *s = handle;
740   DBG (11, ">> sane_get_parameters\n");
741 
742   if (!s->scanning)
743     {
744       int width, length, xres, yres;
745       const char *mode;
746 
747       memset (&s->params, 0, sizeof (s->params));
748 
749       width = s->val[OPT_BR_X].w - s->val[OPT_TL_X].w;
750       length = s->val[OPT_BR_Y].w - s->val[OPT_TL_Y].w;
751       xres = s->val[OPT_X_RESOLUTION].w;
752       yres = s->val[OPT_Y_RESOLUTION].w;
753 
754       /* make best-effort guess at what parameters will look like once
755          scanning starts.  */
756       if (xres > 0 && yres > 0 && width > 0 && length > 0)
757         {
758           s->params.pixels_per_line = width * xres / s->hw->info.mud;
759           s->params.lines = length * yres / s->hw->info.mud;
760         }
761 
762       mode = s->val[OPT_MODE].s;
763       if (strcmp (mode, SANE_VALUE_SCAN_MODE_LINEART) == 0 || strcmp (mode, SANE_VALUE_SCAN_MODE_HALFTONE) == 0)
764         {
765           s->params.format = SANE_FRAME_GRAY;
766           s->params.bytes_per_line = s->params.pixels_per_line / 8;
767 	  /* the Ricoh truncates to the byte boundary, so: chop! */
768           s->params.pixels_per_line = s->params.bytes_per_line * 8;
769           s->params.depth = 1;
770         }
771       else /* if (strcmp (mode, SANE_VALUE_SCAN_MODE_GRAY) == 0) */
772         {
773           s->params.format = SANE_FRAME_GRAY;
774           s->params.bytes_per_line = s->params.pixels_per_line;
775           s->params.depth = 8;
776         }
777       s->params.last_frame = SANE_TRUE;
778     }
779 
780   if (params)
781     *params = s->params;
782 
783   DBG (1, "%d pixels per line, %d bytes, %d lines high, total %lu bytes, "
784        "dpi=%d\n", s->params.pixels_per_line, s->params.bytes_per_line,
785        s->params.lines, (u_long) s->bytes_to_read, s->val[OPT_Y_RESOLUTION].w);
786 
787   DBG (11, "<< sane_get_parameters\n");
788   return (SANE_STATUS_GOOD);
789 }
790 
791 
792 SANE_Status
sane_start(SANE_Handle handle)793 sane_start (SANE_Handle handle)
794 {
795   char *mode_str;
796   Ricoh_Scanner *s = handle;
797   SANE_Status status;
798   struct ricoh_window_data wbuf;
799   struct measurements_units_page mup;
800 
801   DBG (11, ">> sane_start\n");
802 
803   /* First make sure we have a current parameter set.  Some of the
804      parameters will be overwritten below, but that's OK.  */
805   status = sane_get_parameters (s, 0);
806   if (status != SANE_STATUS_GOOD)
807     return status;
808 
809   status = sanei_scsi_open (s->hw->sane.name, &s->fd, 0, 0);
810   if (status != SANE_STATUS_GOOD)
811     {
812       DBG (1, "open of %s failed: %s\n",
813            s->hw->sane.name, sane_strstatus (status));
814       return (status);
815     }
816 
817   mode_str = s->val[OPT_MODE].s;
818   s->xres = s->val[OPT_X_RESOLUTION].w;
819   s->yres = s->val[OPT_Y_RESOLUTION].w;
820   s->ulx = s->val[OPT_TL_X].w;
821   s->uly = s->val[OPT_TL_Y].w;
822   s->width = s->val[OPT_BR_X].w - s->val[OPT_TL_X].w;
823   s->length = s->val[OPT_BR_Y].w - s->val[OPT_TL_Y].w;
824   s->brightness = s->val[OPT_BRIGHTNESS].w;
825   s->contrast = s->val[OPT_CONTRAST].w;
826   s->bpp = s->params.depth;
827   if (strcmp (mode_str, SANE_VALUE_SCAN_MODE_LINEART) == 0)
828     {
829       s->image_composition = RICOH_BINARY_MONOCHROME;
830     }
831   else if (strcmp (mode_str, SANE_VALUE_SCAN_MODE_HALFTONE) == 0)
832     {
833       s->image_composition = RICOH_DITHERED_MONOCHROME;
834     }
835   else if (strcmp (mode_str, SANE_VALUE_SCAN_MODE_GRAY) == 0)
836     {
837       s->image_composition = RICOH_GRAYSCALE;
838     }
839 
840   memset (&wbuf, 0, sizeof (wbuf));
841   _lto2b(sizeof(wbuf) - 8, wbuf.len);
842   _lto2b(s->xres, wbuf.x_res);
843   _lto2b(s->yres, wbuf.y_res);
844   _lto4b(s->ulx, wbuf.x_org);
845   _lto4b(s->uly, wbuf.y_org);
846   _lto4b(s->width, wbuf.width);
847   _lto4b(s->length, wbuf.length);
848 
849   wbuf.image_comp = s->image_composition;
850   /* if you throw the MRIF bit the brightness control reverses too */
851   /* so I reverse the reversal in software for symmetry's sake */
852   if (wbuf.image_comp == RICOH_GRAYSCALE || wbuf.image_comp == RICOH_DITHERED_MONOCHROME)
853     {
854       if (wbuf.image_comp == RICOH_GRAYSCALE)
855 	wbuf.mrif_filtering_gamma_id = (SANE_Byte) 0x90;
856       if (wbuf.image_comp == RICOH_DITHERED_MONOCHROME)
857 	wbuf.mrif_filtering_gamma_id = (SANE_Byte) 0x10;
858       wbuf.brightness = 256 - (SANE_Byte) s->brightness;
859       if (is50)
860         wbuf.contrast = (SANE_Byte) s->contrast;
861       else
862         wbuf.contrast = 256 - (SANE_Byte) s->contrast;
863     }
864   else /* wbuf.image_comp == RICOH_BINARY_MONOCHROME */
865     {
866       wbuf.mrif_filtering_gamma_id = (SANE_Byte) 0x00;
867       wbuf.brightness = (SANE_Byte) s->brightness;
868       wbuf.contrast = (SANE_Byte) s->contrast;
869     }
870 
871   wbuf.threshold = 0;
872   wbuf.bits_per_pixel = s->bpp;
873 
874   wbuf.halftone_pattern[0] = 2;
875   wbuf.halftone_pattern[1] = 0;
876   wbuf.pad_type = 3;
877   wbuf.bit_ordering[0] = 0;
878   wbuf.bit_ordering[1] = 3;
879 
880   DBG (5, "xres=%d\n", _2btol(wbuf.x_res));
881   DBG (5, "yres=%d\n", _2btol(wbuf.y_res));
882   DBG (5, "ulx=%d\n", _4btol(wbuf.x_org));
883   DBG (5, "uly=%d\n", _4btol(wbuf.y_org));
884   DBG (5, "width=%d\n", _4btol(wbuf.width));
885   DBG (5, "length=%d\n", _4btol(wbuf.length));
886   DBG (5, "image_comp=%d\n", wbuf.image_comp);
887 
888   DBG (11, "sane_start: sending SET WINDOW\n");
889   status = set_window (s->fd, &wbuf);
890   if (status != SANE_STATUS_GOOD)
891     {
892       DBG (1, "SET WINDOW failed: %s\n", sane_strstatus (status));
893       return (status);
894     }
895 
896   DBG (11, "sane_start: sending GET WINDOW\n");
897   memset (&wbuf, 0, sizeof (wbuf));
898   status = get_window (s->fd, &wbuf);
899   if (status != SANE_STATUS_GOOD)
900     {
901       DBG (1, "GET WINDOW failed: %s\n", sane_strstatus (status));
902       return (status);
903     }
904   DBG (5, "xres=%d\n", _2btol(wbuf.x_res));
905   DBG (5, "yres=%d\n", _2btol(wbuf.y_res));
906   DBG (5, "ulx=%d\n", _4btol(wbuf.x_org));
907   DBG (5, "uly=%d\n", _4btol(wbuf.y_org));
908   DBG (5, "width=%d\n", _4btol(wbuf.width));
909   DBG (5, "length=%d\n", _4btol(wbuf.length));
910   DBG (5, "image_comp=%d\n", wbuf.image_comp);
911 
912   DBG (11, "sane_start: sending MODE SELECT\n");
913   memset (&mup, 0, sizeof (mup));
914   mup.page_code = MEASUREMENTS_PAGE;
915   mup.parameter_length = 0x06;
916   mup.bmu = INCHES;
917   mup.mud[0] = (DEFAULT_MUD >> 8) & 0xff;
918   mup.mud[1] = (DEFAULT_MUD & 0xff);
919 
920   status = mode_select (s->fd, (struct mode_pages *) &mup);
921   if (status != SANE_STATUS_GOOD)
922     {
923       DBG (1, "attach: MODE_SELECT failed\n");
924       return (SANE_STATUS_INVAL);
925     }
926 
927   status = trigger_scan (s->fd);
928   if (status != SANE_STATUS_GOOD)
929     {
930       DBG (1, "start of scan failed: %s\n", sane_strstatus (status));
931       return (status);
932     }
933 
934   /* Wait for scanner to become ready to transmit data */
935   status = ricoh_wait_ready (s);
936   if (status != SANE_STATUS_GOOD)
937     {
938       DBG (1, "GET DATA STATUS failed: %s\n", sane_strstatus (status));
939       return (status);
940     }
941 
942   s->bytes_to_read = s->params.bytes_per_line * s->params.lines;
943 
944   DBG (1, "%d pixels per line, %d bytes, %d lines high, total %lu bytes, "
945        "dpi=%d\n", s->params.pixels_per_line, s->params.bytes_per_line,
946        s->params.lines, (u_long) s->bytes_to_read, s->val[OPT_Y_RESOLUTION].w);
947 
948   s->scanning = SANE_TRUE;
949 
950   DBG (11, "<< sane_start\n");
951   return (SANE_STATUS_GOOD);
952 }
953 
954 SANE_Status
sane_read(SANE_Handle handle, SANE_Byte * buf, SANE_Int max_len, SANE_Int * len)955 sane_read (SANE_Handle handle, SANE_Byte * buf, SANE_Int max_len,
956            SANE_Int * len)
957 {
958   Ricoh_Scanner *s = handle;
959   SANE_Status status;
960   size_t nread;
961   DBG (11, ">> sane_read\n");
962 
963   *len = 0;
964 
965   DBG (11, "sane_read: bytes left to read: %ld\n", (u_long) s->bytes_to_read);
966 
967   if (s->bytes_to_read == 0)
968     {
969       do_cancel (s);
970       return (SANE_STATUS_EOF);
971     }
972 
973   if (!s->scanning) {
974     DBG (11, "sane_read: scanning is false!\n");
975     return (do_cancel (s));
976   }
977 
978   nread = max_len;
979   if (nread > s->bytes_to_read)
980     nread = s->bytes_to_read;
981 
982   DBG (11, "sane_read: read %ld bytes\n", (u_long) nread);
983   status = read_data (s->fd, buf, &nread);
984   if (status != SANE_STATUS_GOOD)
985     {
986       DBG (11, "sane_read: read error\n");
987       do_cancel (s);
988       return (SANE_STATUS_IO_ERROR);
989     }
990   *len = nread;
991   s->bytes_to_read -= nread;
992 
993   DBG (11, "<< sane_read\n");
994   return (SANE_STATUS_GOOD);
995 }
996 
997 void
sane_cancel(SANE_Handle handle)998 sane_cancel (SANE_Handle handle)
999 {
1000   Ricoh_Scanner *s = handle;
1001   DBG (11, ">> sane_cancel\n");
1002 
1003   s->scanning = SANE_FALSE;
1004 
1005   DBG (11, "<< sane_cancel\n");
1006 }
1007 
1008 SANE_Status
sane_set_io_mode(SANE_Handle handle, SANE_Bool non_blocking)1009 sane_set_io_mode (SANE_Handle handle, SANE_Bool non_blocking)
1010 {
1011   (void) handle;		/* silence gcc */
1012   (void) non_blocking;		/* silence gcc */
1013 
1014   DBG (5, ">> sane_set_io_mode\n");
1015   DBG (5, "<< sane_set_io_mode\n");
1016 
1017   return SANE_STATUS_UNSUPPORTED;
1018 }
1019 
1020 SANE_Status
sane_get_select_fd(SANE_Handle handle, SANE_Int * fd)1021 sane_get_select_fd (SANE_Handle handle, SANE_Int * fd)
1022 {
1023   (void) handle;		/* silence gcc */
1024   (void) fd;			/* silence gcc */
1025 
1026   DBG (5, ">> sane_get_select_fd\n");
1027   DBG (5, "<< sane_get_select_fd\n");
1028 
1029   return SANE_STATUS_UNSUPPORTED;
1030 }
1031