xref: /third_party/backends/backend/hpljm1005.c (revision 141cc406)
1/* sane - Scanner Access Now Easy.
2
3   Copyright (C) 2007-2008 Philippe Rétornaz
4
5   This file is part of the SANE package.
6
7   This program is free software; you can redistribute it and/or
8   modify it under the terms of the GNU General Public License as
9   published by the Free Software Foundation; either version 2 of the
10   License, or (at your option) any later version.
11
12   This program is distributed in the hope that it will be useful, but
13   WITHOUT ANY WARRANTY; without even the implied warranty of
14   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15   General Public License for more details.
16
17   You should have received a copy of the GNU General Public License
18   along with this program.  If not, see <https://www.gnu.org/licenses/>.
19
20   As a special exception, the authors of SANE give permission for
21   additional uses of the libraries contained in this release of SANE.
22
23   The exception is that, if you link a SANE library with other files
24   to produce an executable, this does not by itself cause the
25   resulting executable to be covered by the GNU General Public
26   License.  Your use of that executable is in no way restricted on
27   account of linking the SANE library code into it.
28
29   This exception does not, however, invalidate any other reasons why
30   the executable file might be covered by the GNU General Public
31   License.
32
33   If you submit changes to SANE to the maintainers to be included in
34   a subsequent release, you agree by submitting the changes that
35   those changes may be distributed with this exception intact.
36
37   If you write modifications of your own for SANE, it is your choice
38   whether to permit this exception to apply to your modifications.
39   If you do not wish that, delete this exception notice.
40
41   This backend is for HP LaserJet M1005 MFP
42
43   Highly inspired from the epson backend
44*/
45
46#define BUILD 1
47
48#include  "../include/sane/config.h"
49#include  <math.h>
50
51#include  <limits.h>
52#include  <stdio.h>
53#include  <string.h>
54#include  <stdlib.h>
55#include  <ctype.h>
56#include  <fcntl.h>
57#include  <unistd.h>
58#include  <errno.h>
59#include  <stdint.h>
60#include <netinet/in.h>
61#define  BACKEND_NAME hpljm1005
62#include  "../include/sane/sanei_backend.h"
63#include  "../include/sane/sanei_usb.h"
64#include  "../include/sane/saneopts.h"
65
66#define MAGIC_NUMBER 0x41535001
67#define PKT_READ_STATUS 0x0
68#define PKT_UNKNOW_1 0x1
69#define PKT_START_SCAN 0x2
70#define PKT_GO_IDLE 0x3
71#define PKT_DATA 0x5
72#define PKT_READCONF 0x6
73#define PKT_SETCONF 0x7
74#define PKT_END_DATA 0xe
75#define PKT_RESET 0x15
76
77#define RED_LAYER 0x3
78#define GREEN_LAYER 0x4
79#define BLUE_LAYER 0x5
80#define GRAY_LAYER 0x6
81
82#define MIN_SCAN_ZONE 101
83
84struct usbdev_s
85{
86  SANE_Int vendor_id;
87  SANE_Int product_id;
88  SANE_String_Const vendor_s;
89  SANE_String_Const model_s;
90  SANE_String_Const type_s;
91};
92
93/* Zero-terminated USB VID/PID array */
94static struct usbdev_s usbid[] = {
95  {0x03f0, 0x3b17, "Hewlett-Packard", "LaserJet M1005",
96   "multi-function peripheral"},
97  {0x03f0, 0x5617, "Hewlett-Packard", "LaserJet M1120",
98   "multi-function peripheral"},
99  {0x03f0, 0x5717, "Hewlett-Packard", "LaserJet M1120n",
100   "multi-function peripheral"},
101  {0, 0, NULL, NULL, NULL},
102  {0, 0, NULL, NULL, NULL}
103};
104
105static int cur_idx;
106
107#define BR_CONT_MIN 0x1
108#define BR_CONT_MAX 0xb
109
110#define RGB 1
111#define GRAY 0
112
113#define MAX_X_H 0x350
114#define MAX_Y_H 0x490
115#define MAX_X_S 220
116#define MAX_Y_S 330
117
118#define OPTION_MAX 9
119
120static SANE_Word resolution_list[] = {
121  7, 75, 100, 150, 200, 300, 600, 1200
122};
123static SANE_Range range_x = { 0, MAX_X_S, 0 };
124static SANE_Range range_y = { 0, MAX_Y_S, 0 };
125
126static SANE_Range range_br_cont = { BR_CONT_MIN, BR_CONT_MAX, 0 };
127
128static const SANE_String_Const mode_list[] = {
129  SANE_VALUE_SCAN_MODE_GRAY,
130  SANE_VALUE_SCAN_MODE_COLOR,
131  NULL
132};
133
134#define X1_OFFSET 2
135#define X2_OFFSET 4
136#define Y1_OFFSET 3
137#define Y2_OFFSET 5
138#define RES_OFFSET 1
139#define COLOR_OFFSET 8
140#define BRIGH_OFFSET 6
141#define CONTR_OFFSET 7
142
143#define STATUS_IDLE 0
144#define STATUS_SCANNING 1
145#define STATUS_CANCELING 2
146
147struct device_s
148{
149  struct device_s *next;
150  SANE_String_Const devname;
151  int idx;			/* Index in the usbid array */
152  int dn;			/* Usb "Handle" */
153  SANE_Option_Descriptor optiond[OPTION_MAX];
154  char *buffer;
155  int bufs;
156  int read_offset;
157  int write_offset_r;
158  int write_offset_g;
159  int write_offset_b;
160  int status;
161  int width;
162  int height;
163  SANE_Word optionw[OPTION_MAX];
164  uint32_t conf_data[512];
165  uint32_t packet_data[512];
166};
167
168
169static void
170do_cancel(struct device_s *dev);
171
172
173static struct device_s *devlist_head;
174static int devlist_count;	/* Number of element in the list */
175
176/*
177 * List of pointers to devices - will be dynamically allocated depending
178 * on the number of devices found.
179 */
180static SANE_Device **devlist = NULL;
181
182/* round() is c99, so we provide our own, though this version won't return -0 */
183static double
184round2(double x)
185{
186    return (double)(x >= 0.0) ? (int)(x+0.5) : (int)(x-0.5);
187}
188
189static void
190update_img_size (struct device_s *dev)
191{
192  int dx, dy;
193
194  /* Only update the width when not scanning,
195   * otherwise the scanner give us the correct width */
196  if (dev->status == STATUS_SCANNING)
197    {
198      dev->height = -1;
199      return;
200    }
201
202  dx = dev->optionw[X2_OFFSET] - dev->optionw[X1_OFFSET];
203  dy = dev->optionw[Y2_OFFSET] - dev->optionw[Y1_OFFSET];
204
205  switch (dev->optionw[RES_OFFSET])
206    {
207    case 75:
208      dev->width = round2 ((dx / ((double) MAX_X_S)) * 640);
209      dev->height = round2 ((dy / ((double) MAX_Y_S)) * 880);
210      break;
211    case 100:
212      dev->width = round2 ((dx / ((double) MAX_X_S)) * 848);
213      dev->height = round2 ((dy / ((double) MAX_Y_S)) * 1180);
214      break;
215    case 150:
216      dev->width = round2 ((dx / ((double) MAX_X_S)) * 1264);
217      dev->height = round2 ((dy / ((double) MAX_Y_S)) * 1775);
218      break;
219    case 200:
220      dev->width = round2 ((dx / ((double) MAX_X_S)) * 1696);
221      dev->height = round2 ((dy / ((double) MAX_Y_S)) * 2351);
222      break;
223    case 300:
224      dev->width = round2 ((dx / ((double) MAX_X_S)) * 2528);
225      dev->height = round2 ((dy / ((double) MAX_Y_S)) * 3510);
226      break;
227    case 600:
228      dev->width = round2 ((dx / ((double) MAX_X_S)) * 5088);
229      dev->height = round2 ((dy / ((double) MAX_Y_S)) * 7020);
230      break;
231    case 1200:
232      dev->width = round2 ((dx / ((double) MAX_X_S)) * 10208);
233      dev->height = round2 ((dy / ((double) MAX_Y_S)) * 14025);
234      break;
235    }
236
237    DBG(2,"New image size: %dx%d\n",dev->width, dev->height);
238
239}
240
241/* This function is copy/pasted from the Epson backend */
242static size_t
243max_string_size (const SANE_String_Const strings[])
244{
245  size_t size, max_size = 0;
246  int i;
247
248  for (i = 0; strings[i]; i++)
249    {
250      size = strlen (strings[i]) + 1;
251      if (size > max_size)
252	max_size = size;
253    }
254  return max_size;
255}
256
257
258static SANE_Status
259attach (SANE_String_Const devname)
260{
261  struct device_s *dev;
262
263  dev = malloc (sizeof (struct device_s));
264  if (!dev)
265    return SANE_STATUS_NO_MEM;
266  memset (dev, 0, sizeof (struct device_s));
267
268  dev->devname = devname;
269  DBG(1,"New device found: %s\n",dev->devname);
270
271/* Init the whole structure with default values */
272  /* Number of options */
273  dev->optiond[0].name = "";
274  dev->optiond[0].title = NULL;
275  dev->optiond[0].desc = NULL;
276  dev->optiond[0].type = SANE_TYPE_INT;
277  dev->optiond[0].unit = SANE_UNIT_NONE;
278  dev->optiond[0].size = sizeof (SANE_Word);
279  dev->optionw[0] = OPTION_MAX;
280
281  /* resolution */
282  dev->optiond[RES_OFFSET].name = "resolution";
283  dev->optiond[RES_OFFSET].title = "resolution";
284  dev->optiond[RES_OFFSET].desc = "resolution";
285  dev->optiond[RES_OFFSET].type = SANE_TYPE_INT;
286  dev->optiond[RES_OFFSET].unit = SANE_UNIT_DPI;
287  dev->optiond[RES_OFFSET].type = SANE_TYPE_INT;
288  dev->optiond[RES_OFFSET].size = sizeof (SANE_Word);
289  dev->optiond[RES_OFFSET].cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT;
290  dev->optiond[RES_OFFSET].constraint_type = SANE_CONSTRAINT_WORD_LIST;
291  dev->optiond[RES_OFFSET].constraint.word_list = resolution_list;
292  dev->optionw[RES_OFFSET] = 75;
293
294  /* scan area */
295  dev->optiond[X1_OFFSET].name = "tl-x";
296  dev->optiond[X1_OFFSET].title = "tl-x";
297  dev->optiond[X1_OFFSET].desc = "tl-x";
298  dev->optiond[X1_OFFSET].type = SANE_TYPE_INT;
299  dev->optiond[X1_OFFSET].unit = SANE_UNIT_MM;
300  dev->optiond[X1_OFFSET].size = sizeof (SANE_Word);
301  dev->optiond[X1_OFFSET].cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT;
302  dev->optiond[X1_OFFSET].constraint_type = SANE_CONSTRAINT_RANGE;
303  dev->optiond[X1_OFFSET].constraint.range = &range_x;
304  dev->optionw[X1_OFFSET] = 0;
305
306  dev->optiond[Y1_OFFSET].name = "tl-y";
307  dev->optiond[Y1_OFFSET].title = "tl-y";
308  dev->optiond[Y1_OFFSET].desc = "tl-y";
309  dev->optiond[Y1_OFFSET].type = SANE_TYPE_INT;
310  dev->optiond[Y1_OFFSET].unit = SANE_UNIT_MM;
311  dev->optiond[Y1_OFFSET].size = sizeof (SANE_Word);
312  dev->optiond[Y1_OFFSET].cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT;
313  dev->optiond[Y1_OFFSET].constraint_type = SANE_CONSTRAINT_RANGE;
314  dev->optiond[Y1_OFFSET].constraint.range = &range_y;
315  dev->optionw[Y1_OFFSET] = 0;
316
317  dev->optiond[X2_OFFSET].name = "br-x";
318  dev->optiond[X2_OFFSET].title = "br-x";
319  dev->optiond[X2_OFFSET].desc = "br-x";
320  dev->optiond[X2_OFFSET].type = SANE_TYPE_INT;
321  dev->optiond[X2_OFFSET].unit = SANE_UNIT_MM;
322  dev->optiond[X2_OFFSET].size = sizeof (SANE_Word);
323  dev->optiond[X2_OFFSET].cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT;
324  dev->optiond[X2_OFFSET].constraint_type = SANE_CONSTRAINT_RANGE;
325  dev->optiond[X2_OFFSET].constraint.range = &range_x;
326  dev->optionw[X2_OFFSET] = MAX_X_S;
327
328  dev->optiond[Y2_OFFSET].name = "br-y";
329  dev->optiond[Y2_OFFSET].title = "br-y";
330  dev->optiond[Y2_OFFSET].desc = "br-y";
331  dev->optiond[Y2_OFFSET].type = SANE_TYPE_INT;
332  dev->optiond[Y2_OFFSET].unit = SANE_UNIT_MM;
333  dev->optiond[Y2_OFFSET].size = sizeof (SANE_Word);
334  dev->optiond[Y2_OFFSET].cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT;
335  dev->optiond[Y2_OFFSET].constraint_type = SANE_CONSTRAINT_RANGE;
336  dev->optiond[Y2_OFFSET].constraint.range = &range_y;
337  dev->optionw[Y2_OFFSET] = MAX_Y_S;
338
339  /* brightness */
340  dev->optiond[BRIGH_OFFSET].name = "brightness";
341  dev->optiond[BRIGH_OFFSET].title = "Brightness";
342  dev->optiond[BRIGH_OFFSET].desc = "Set the brightness";
343  dev->optiond[BRIGH_OFFSET].type = SANE_TYPE_INT;
344  dev->optiond[BRIGH_OFFSET].unit = SANE_UNIT_NONE;
345  dev->optiond[BRIGH_OFFSET].size = sizeof (SANE_Word);
346  dev->optiond[BRIGH_OFFSET].cap =
347    SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT;
348  dev->optiond[BRIGH_OFFSET].constraint_type = SANE_CONSTRAINT_RANGE;
349  dev->optiond[BRIGH_OFFSET].constraint.range = &range_br_cont;
350  dev->optionw[BRIGH_OFFSET] = 0x6;
351
352  /* contrast */
353  dev->optiond[CONTR_OFFSET].name = "contrast";
354  dev->optiond[CONTR_OFFSET].title = "Contrast";
355  dev->optiond[CONTR_OFFSET].desc = "Set the contrast";
356  dev->optiond[CONTR_OFFSET].type = SANE_TYPE_INT;
357  dev->optiond[CONTR_OFFSET].unit = SANE_UNIT_NONE;
358  dev->optiond[CONTR_OFFSET].size = sizeof (SANE_Word);
359  dev->optiond[CONTR_OFFSET].cap =
360    SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT;
361  dev->optiond[CONTR_OFFSET].constraint_type = SANE_CONSTRAINT_RANGE;
362  dev->optiond[CONTR_OFFSET].constraint.range = &range_br_cont;
363  dev->optionw[CONTR_OFFSET] = 0x6;
364
365  /* Color */
366  dev->optiond[COLOR_OFFSET].name = SANE_NAME_SCAN_MODE;
367  dev->optiond[COLOR_OFFSET].title = SANE_TITLE_SCAN_MODE;
368  dev->optiond[COLOR_OFFSET].desc = SANE_DESC_SCAN_MODE;
369  dev->optiond[COLOR_OFFSET].type = SANE_TYPE_STRING;
370  dev->optiond[COLOR_OFFSET].size = max_string_size (mode_list);
371  dev->optiond[COLOR_OFFSET].cap =
372    SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT;
373  dev->optiond[COLOR_OFFSET].constraint_type = SANE_CONSTRAINT_STRING_LIST;
374  dev->optiond[COLOR_OFFSET].constraint.string_list = mode_list;
375  dev->optionw[COLOR_OFFSET] = RGB;
376  dev->dn = 0;
377  dev->idx = cur_idx;
378  dev->status = STATUS_IDLE;
379
380  dev->next = devlist_head;
381  devlist_head = dev;
382  devlist_count++;
383
384
385
386  return SANE_STATUS_GOOD;
387}
388
389SANE_Status
390sane_init (SANE_Int * version_code,
391	   SANE_Auth_Callback __sane_unused__ authorize)
392{
393
394  if (version_code != NULL)
395    *version_code = SANE_VERSION_CODE (SANE_CURRENT_MAJOR, SANE_CURRENT_MINOR, BUILD);
396
397  DBG_INIT();
398
399  sanei_usb_init ();
400
401  return SANE_STATUS_GOOD;
402}
403
404void
405sane_exit (void)
406{
407  /* free everything */
408  struct device_s *iter;
409
410  if (devlist)
411    {
412      int i;
413      for (i = 0; devlist[i]; i++)
414	free (devlist[i]);
415      free (devlist);
416      devlist = NULL;
417    }
418  if (devlist_head)
419    {
420      iter = devlist_head->next;
421      free (devlist_head);
422      devlist_head = NULL;
423      while (iter)
424	{
425	  struct device_s *tmp = iter;
426	  iter = iter->next;
427	  free (tmp);
428	}
429    }
430  devlist_count = 0;
431}
432
433SANE_Status
434sane_get_devices (const SANE_Device * **device_list,
435		  SANE_Bool __sane_unused__ local_only)
436{
437  struct device_s *iter;
438  int i;
439
440  devlist_count = 0;
441
442  if (devlist_head)
443    {
444      iter = devlist_head->next;
445      free (devlist_head);
446      devlist_head = NULL;
447      while (iter)
448	{
449	  struct device_s *tmp = iter;
450	  iter = iter->next;
451	  free (tmp);
452	}
453    }
454
455  /* Rebuild our internal scanner list */
456  for (cur_idx = 0; usbid[cur_idx].vendor_id; cur_idx++)
457    sanei_usb_find_devices (usbid[cur_idx].vendor_id,
458			    usbid[cur_idx].product_id, attach);
459
460  if (devlist)
461    {
462      for (i = 0; devlist[i]; i++)
463	free (devlist[i]);
464      free (devlist);
465    }
466
467  /* rebuild the sane-API scanner list array */
468  devlist = malloc (sizeof (devlist[0]) * (devlist_count + 1));
469  if (!devlist)
470    return SANE_STATUS_NO_MEM;
471
472  memset (devlist, 0, sizeof (devlist[0]) * (devlist_count + 1));
473
474  for (i = 0, iter = devlist_head; i < devlist_count; i++, iter = iter->next)
475    {
476      devlist[i] = malloc (sizeof (SANE_Device));
477      if (!devlist[i])
478	{
479	  int j;
480	  for (j = 0; j < i; j++)
481	    free (devlist[j]);
482	  free (devlist);
483	  devlist = NULL;
484	  return SANE_STATUS_NO_MEM;
485	}
486      devlist[i]->name = iter->devname;
487      devlist[i]->vendor = usbid[iter->idx].vendor_s;
488      devlist[i]->model = usbid[iter->idx].model_s;
489      devlist[i]->type = usbid[iter->idx].type_s;
490    }
491  if (device_list)
492    *device_list = (const SANE_Device **) devlist;
493  return SANE_STATUS_GOOD;
494}
495
496SANE_Status
497sane_open (SANE_String_Const name, SANE_Handle * h)
498{
499  struct device_s *dev;
500  int ret;
501
502  if(!devlist_head)
503    sane_get_devices(NULL,(SANE_Bool)0);
504
505  dev = devlist_head;
506
507  if (strlen (name))
508    for (; dev; dev = dev->next)
509      if (!strcmp (name, dev->devname))
510	break;
511
512  if (!dev) {
513    DBG(1,"Unable to find device %s\n",name);
514    return SANE_STATUS_INVAL;
515  }
516
517  DBG(1,"Found device %s\n",name);
518
519  /* Now open the usb device */
520  ret = sanei_usb_open (name, &(dev->dn));
521  if (ret != SANE_STATUS_GOOD) {
522    DBG(1,"Unable to open device %s\n",name);
523    return ret;
524  }
525
526  /* Claim the first interface */
527  ret = sanei_usb_claim_interface (dev->dn, 0);
528  if (ret != SANE_STATUS_GOOD)
529    {
530      sanei_usb_close (dev->dn);
531      /* if we cannot claim the interface, this is because
532         someone else is using it */
533      DBG(1,"Unable to claim scanner interface on device %s\n",name);
534      return SANE_STATUS_DEVICE_BUSY;
535    }
536#ifdef HAVE_SANEI_USB_SET_TIMEOUT
537  sanei_usb_set_timeout (30000);	/* 30s timeout */
538#endif
539
540  *h = dev;
541
542  return SANE_STATUS_GOOD;
543}
544
545void
546sane_close (SANE_Handle h)
547{
548  struct device_s *dev = (struct device_s *) h;
549
550  /* Just in case if sane_cancel() is called
551   * after starting a scan but not while a sane_read
552   */
553  if (dev->status == STATUS_CANCELING)
554    {
555       do_cancel(dev);
556    }
557
558  sanei_usb_release_interface (dev->dn, 0);
559  sanei_usb_close (dev->dn);
560
561}
562
563const SANE_Option_Descriptor *
564sane_get_option_descriptor (SANE_Handle h, SANE_Int option)
565{
566  struct device_s *dev = (struct device_s *) h;
567
568  if (option >= OPTION_MAX || option < 0)
569    return NULL;
570  return &(dev->optiond[option]);
571}
572
573static SANE_Status
574getvalue (SANE_Handle h, SANE_Int option, void *v)
575{
576  struct device_s *dev = (struct device_s *) h;
577
578  if (option != COLOR_OFFSET)
579    *((SANE_Word *) v) = dev->optionw[option];
580  else
581    {
582      strcpy ((char *) v,
583	      dev->optiond[option].constraint.string_list[dev->
584							  optionw[option]]);
585    }
586  return SANE_STATUS_GOOD;
587}
588
589static SANE_Status
590setvalue (SANE_Handle h, SANE_Int option, void *value, SANE_Int * info)
591{
592  struct device_s *dev = (struct device_s *) h;
593  SANE_Status status = SANE_STATUS_GOOD;
594  int s_unit;
595  int s_unit_2;
596
597  if (option == 0)
598    return SANE_STATUS_UNSUPPORTED;
599
600
601  status = sanei_constrain_value (&(dev->optiond[option]), value, info);
602
603  if (status != SANE_STATUS_GOOD)
604    return status;
605
606
607
608  if (info)
609    *info |= SANE_INFO_RELOAD_PARAMS;
610  switch (option)
611    {
612    case X1_OFFSET:
613      dev->optionw[option] = *((SANE_Word *) value);
614      s_unit = (int) round2 ((dev->optionw[option] / ((double) MAX_X_S))
615			    * MAX_X_H);
616      s_unit_2 = (int) round2 ((dev->optionw[X2_OFFSET] / ((double) MAX_X_S))
617			      * MAX_X_H);
618      if (abs (s_unit_2 - s_unit) < MIN_SCAN_ZONE)
619	s_unit = s_unit_2 - MIN_SCAN_ZONE;
620      dev->optionw[option] = round2 ((s_unit / ((double) MAX_X_H)) * MAX_X_S);
621      if (info)
622	*info |= SANE_INFO_INEXACT;
623      break;
624
625    case X2_OFFSET:
626      /* X units */
627      /* convert into "scanner" unit, then back into mm */
628      dev->optionw[option] = *((SANE_Word *) value);
629
630      s_unit = (int) round2 ((dev->optionw[option] / ((double) MAX_X_S))
631			    * MAX_X_H);
632      s_unit_2 = (int) round2 ((dev->optionw[X1_OFFSET] / ((double) MAX_X_S))
633			      * MAX_X_H);
634      if (abs (s_unit_2 - s_unit) < MIN_SCAN_ZONE)
635	s_unit = s_unit_2 + MIN_SCAN_ZONE;
636      dev->optionw[option] = round2 ((s_unit / ((double) MAX_X_H)) * MAX_X_S);
637      if (info)
638	*info |= SANE_INFO_INEXACT;
639      break;
640    case Y1_OFFSET:
641      /* Y units */
642      dev->optionw[option] = *((SANE_Word *) value);
643
644      s_unit = (int) round2 ((dev->optionw[option] / ((double) MAX_Y_S))
645			    * MAX_Y_H);
646
647      s_unit_2 = (int) round2 ((dev->optionw[Y2_OFFSET] / ((double) MAX_Y_S))
648			      * MAX_Y_H);
649      if (abs (s_unit_2 - s_unit) < MIN_SCAN_ZONE)
650	s_unit = s_unit_2 - MIN_SCAN_ZONE;
651
652      dev->optionw[option] = round2 ((s_unit / ((double) MAX_Y_H)) * MAX_Y_S);
653      if (info)
654	*info |= SANE_INFO_INEXACT;
655      break;
656    case Y2_OFFSET:
657      /* Y units */
658      dev->optionw[option] = *((SANE_Word *) value);
659
660      s_unit = (int) round2 ((dev->optionw[option] / ((double) MAX_Y_S))
661			    * MAX_Y_H);
662
663      s_unit_2 = (int) round2 ((dev->optionw[Y1_OFFSET] / ((double) MAX_Y_S))
664			      * MAX_Y_H);
665      if (abs (s_unit_2 - s_unit) < MIN_SCAN_ZONE)
666	s_unit = s_unit_2 + MIN_SCAN_ZONE;
667
668      dev->optionw[option] = round2 ((s_unit / ((double) MAX_Y_H)) * MAX_Y_S);
669      if (info)
670	*info |= SANE_INFO_INEXACT;
671      break;
672    case COLOR_OFFSET:
673      if (!strcmp ((char *) value, mode_list[0]))
674	dev->optionw[option] = GRAY;	/* Gray */
675      else if (!strcmp ((char *) value, mode_list[1]))
676	dev->optionw[option] = RGB;	/* RGB */
677      else
678	return SANE_STATUS_INVAL;
679      break;
680    default:
681      dev->optionw[option] = *((SANE_Word *) value);
682    }
683  return SANE_STATUS_GOOD;
684}
685
686SANE_Status
687sane_control_option (SANE_Handle h, SANE_Int option,
688		     SANE_Action a, void *v, SANE_Int * i)
689{
690
691  if (option < 0 || option >= OPTION_MAX)
692    return SANE_STATUS_INVAL;
693
694  if (i)
695    *i = 0;
696
697
698  switch (a)
699    {
700    case SANE_ACTION_GET_VALUE:
701      return getvalue (h, option, v);
702
703    case SANE_ACTION_SET_VALUE:
704      return setvalue (h, option, v, i);
705
706    default:
707      return SANE_STATUS_INVAL;
708    }
709}
710
711SANE_Status
712sane_get_parameters (SANE_Handle h, SANE_Parameters * p)
713{
714  struct device_s *dev = (struct device_s *) h;
715
716  if (!p)
717    return SANE_STATUS_INVAL;
718
719  p->format =
720    dev->optionw[COLOR_OFFSET] == RGB ? SANE_FRAME_RGB : SANE_FRAME_GRAY;
721  p->last_frame = SANE_TRUE;
722  p->depth = 8;
723
724  update_img_size (dev);
725  p->pixels_per_line = dev->width;
726  p->lines = dev->height;
727  p->bytes_per_line = p->pixels_per_line;
728  if (p->format == SANE_FRAME_RGB)
729    p->bytes_per_line *= 3;
730
731  return SANE_STATUS_GOOD;
732}
733
734static void
735send_pkt (int command, int data_size, struct device_s *dev)
736{
737  size_t size = 32;
738
739  DBG(100,"Sending packet %d, next data size %d, device %s\n", command, data_size, dev->devname);
740
741  memset (dev->packet_data, 0, size);
742  dev->packet_data[0] = htonl (MAGIC_NUMBER);
743  dev->packet_data[1] = htonl (command);
744  dev->packet_data[5] = htonl (data_size);
745  sanei_usb_write_bulk (dev->dn, (unsigned char *) dev->packet_data, &size);
746}
747
748
749/* s: printer status */
750/* Return the next packet size */
751static int
752wait_ack (struct device_s *dev, int *s)
753{
754  SANE_Status ret;
755  size_t size;
756  DBG(100, "Waiting scanner answer on device %s\n",dev->devname);
757  do
758    {
759      size = 32;
760      ret =
761	sanei_usb_read_bulk (dev->dn, (unsigned char *) dev->packet_data,
762			     &size);
763    }
764  while (SANE_STATUS_EOF == ret || size == 0);
765  if (s)
766    *s = ntohl (dev->packet_data[4]);
767  return ntohl (dev->packet_data[5]);
768}
769
770static void
771send_conf (struct device_s *dev)
772{
773  int y1, y2, x1, x2;
774  size_t size = 100;
775  DBG(100,"Sending configuration packet on device %s\n",dev->devname);
776  y1 = (int) round2 ((dev->optionw[Y1_OFFSET] / ((double) MAX_Y_S)) * MAX_Y_H);
777  y2 = (int) round2 ((dev->optionw[Y2_OFFSET] / ((double) MAX_Y_S)) * MAX_Y_H);
778  x1 = (int) round2 ((dev->optionw[X1_OFFSET] / ((double) MAX_X_S)) * MAX_X_H);
779  x2 = (int) round2 ((dev->optionw[X2_OFFSET] / ((double) MAX_X_S)) * MAX_X_H);
780
781  DBG(100,"\t x1: %d, x2: %d, y1: %d, y2: %d\n",x1, x2, y1, y2);
782  DBG(100,"\t brightness: %d, contrast: %d\n", dev->optionw[BRIGH_OFFSET], dev->optionw[CONTR_OFFSET]);
783  DBG(100,"\t resolution: %d\n",dev->optionw[RES_OFFSET]);
784
785  dev->conf_data[0] = htonl (0x15);
786  dev->conf_data[1] = htonl (dev->optionw[BRIGH_OFFSET]);
787  dev->conf_data[2] = htonl (dev->optionw[CONTR_OFFSET]);
788  dev->conf_data[3] = htonl (dev->optionw[RES_OFFSET]);
789  dev->conf_data[4] = htonl (0x1);
790  dev->conf_data[5] = htonl (0x1);
791  dev->conf_data[6] = htonl (0x1);
792  dev->conf_data[7] = htonl (0x1);
793  dev->conf_data[8] = 0;
794  dev->conf_data[9] = 0;
795  dev->conf_data[10] = htonl (0x8);
796  dev->conf_data[11] = 0;
797  dev->conf_data[12] = 0;
798  dev->conf_data[13] = 0;
799  dev->conf_data[14] = 0;
800  dev->conf_data[16] = htonl (y1);
801  dev->conf_data[17] = htonl (x1);
802  dev->conf_data[18] = htonl (y2);
803  dev->conf_data[19] = htonl (x2);
804  dev->conf_data[20] = 0;
805  dev->conf_data[21] = 0;
806  dev->conf_data[22] = htonl (0x491);
807  dev->conf_data[23] = htonl (0x352);
808
809  if (dev->optionw[COLOR_OFFSET] == RGB)
810    {
811      dev->conf_data[15] = htonl (0x2);
812      dev->conf_data[24] = htonl (0x1);
813      DBG(100,"\t Scanning in RGB format\n");
814    }
815  else
816    {
817      dev->conf_data[15] = htonl (0x6);
818      dev->conf_data[24] = htonl (0x0);
819      DBG(100,"\t Scanning in Grayscale format\n");
820    }
821  sanei_usb_write_bulk (dev->dn, (unsigned char *) dev->conf_data, &size);
822}
823
824static SANE_Status
825get_data (struct device_s *dev)
826{
827  int color;
828  size_t size;
829  int packet_size;
830  unsigned char *buffer = (unsigned char *) dev->packet_data;
831  if (dev->status == STATUS_IDLE)
832    return SANE_STATUS_IO_ERROR;
833  /* first wait a standard data pkt */
834  do
835    {
836      size = 32;
837      sanei_usb_read_bulk (dev->dn, buffer, &size);
838      if (size)
839	{
840	  if (ntohl (dev->packet_data[0]) == MAGIC_NUMBER)
841	    {
842	      if (ntohl (dev->packet_data[1]) == PKT_DATA)
843		break;
844	      if (ntohl (dev->packet_data[1]) == PKT_END_DATA)
845		{
846		  dev->status = STATUS_IDLE;
847		  DBG(100,"End of scan encountered on device %s\n",dev->devname);
848		  send_pkt (PKT_GO_IDLE, 0, dev);
849		  wait_ack (dev, NULL);
850		  wait_ack (dev, NULL);
851		  send_pkt (PKT_UNKNOW_1, 0, dev);
852		  wait_ack (dev, NULL);
853		  send_pkt (PKT_RESET, 0, dev);
854		  sleep (2);	/* Time for the scanning head to go back home */
855		  return SANE_STATUS_EOF;
856		}
857	    }
858	}
859    }
860  while (1);
861  packet_size = ntohl (dev->packet_data[5]);
862  if (!dev->buffer)
863    {
864      dev->bufs = packet_size - 24 /* size of header */ ;
865      if (dev->optionw[COLOR_OFFSET] == RGB)
866	dev->bufs *= 3;
867      dev->buffer = malloc (dev->bufs);
868      if (!dev->buffer)
869	return SANE_STATUS_NO_MEM;
870      dev->write_offset_r = 0;
871      dev->write_offset_g = 1;
872      dev->write_offset_b = 2;
873
874    }
875  /* Get the "data header" */
876  do
877    {
878      size = 24;
879      sanei_usb_read_bulk (dev->dn, buffer, &size);
880    }
881  while (!size);
882  color = ntohl (dev->packet_data[0]);
883  packet_size -= size;
884  dev->width = ntohl (dev->packet_data[5]);
885  DBG(100,"Got data size %d on device %s. Scan width: %d\n",packet_size, dev->devname, dev->width);
886  /* Now, read the data */
887  do
888    {
889      int j;
890      int i;
891      int ret;
892      do
893	{
894	  size = packet_size > 512 ? 512 : packet_size;
895	  ret = sanei_usb_read_bulk (dev->dn, buffer, &size);
896	}
897      while (!size || ret != SANE_STATUS_GOOD);
898      packet_size -= size;
899      switch (color)
900	{
901	case RED_LAYER:
902	  DBG(101,"Got red layer data on device %s\n",dev->devname);
903	  i = dev->write_offset_r + 3 * size;
904	  if (i > dev->bufs)
905	    i = dev->bufs;
906	  for (j = 0; dev->write_offset_r < i; dev->write_offset_r += 3)
907	    dev->buffer[dev->write_offset_r] = buffer[j++];
908	  break;
909	case GREEN_LAYER:
910	  DBG(101,"Got green layer data on device %s\n",dev->devname);
911	  i = dev->write_offset_g + 3 * size;
912	  if (i > dev->bufs)
913	    i = dev->bufs;
914	  for (j = 0; dev->write_offset_g < i; dev->write_offset_g += 3)
915	    dev->buffer[dev->write_offset_g] = buffer[j++];
916	  break;
917	case BLUE_LAYER:
918          DBG(101,"Got blue layer data on device %s\n",dev->devname);
919	  i = dev->write_offset_b + 3 * size;
920	  if (i > dev->bufs)
921	    i = dev->bufs;
922	  for (j = 0; dev->write_offset_b < i; dev->write_offset_b += 3)
923	    dev->buffer[dev->write_offset_b] = buffer[j++];
924	  break;
925	case GRAY_LAYER:
926	  DBG(101,"Got gray layer data on device %s\n",dev->devname);
927	  if (dev->write_offset_r + (int)size >= dev->bufs)
928	    size = dev->bufs - dev->write_offset_r;
929	  memcpy (dev->buffer + dev->write_offset_r, buffer, size);
930	  dev->write_offset_r += size;
931	  break;
932	}
933    }
934  while (packet_size > 0);
935  return SANE_STATUS_GOOD;
936}
937
938SANE_Status
939sane_start (SANE_Handle h)
940{
941  struct device_s *dev = (struct device_s *) h;
942  int status;
943  size_t size;
944
945  dev->read_offset = 0;
946  dev->write_offset_r = 0;
947  dev->write_offset_g = 1;
948  dev->write_offset_b = 2;
949
950  free (dev->buffer);
951  dev->buffer = NULL;
952
953
954  send_pkt (PKT_RESET, 0, dev);
955  send_pkt (PKT_READ_STATUS, 0, dev);
956  wait_ack (dev, &status);
957  if (status)
958    return SANE_STATUS_IO_ERROR;
959
960  send_pkt (PKT_READCONF, 0, dev);
961
962  if ((size = wait_ack (dev, NULL)))
963    {
964      sanei_usb_read_bulk (dev->dn, (unsigned char *) dev->conf_data, &size);
965    }
966  send_pkt (PKT_SETCONF, 100, dev);
967  send_conf (dev);
968  wait_ack (dev, NULL);
969
970  send_pkt (PKT_START_SCAN, 0, dev);
971  wait_ack (dev, NULL);
972  if ((size = wait_ack (dev, NULL)))
973    {
974      sanei_usb_read_bulk (dev->dn, (unsigned char *) dev->conf_data, &size);
975    }
976  if ((size = wait_ack (dev, NULL)))
977    {
978      sanei_usb_read_bulk (dev->dn, (unsigned char *) dev->conf_data, &size);
979    }
980  if ((size = wait_ack (dev, NULL)))
981    {
982      sanei_usb_read_bulk (dev->dn, (unsigned char *) dev->conf_data, &size);
983    }
984
985  dev->status = STATUS_SCANNING;
986  /* Get the first data */
987  return get_data (dev);
988}
989
990
991static void
992do_cancel(struct device_s *dev)
993{
994  while (get_data (dev) == SANE_STATUS_GOOD);
995  free (dev->buffer);
996  dev->buffer = NULL;
997}
998
999static int
1000min3 (int r, int g, int b)
1001{
1002  /* Optimize me ! */
1003  g--;
1004  b -= 2;
1005  if (r < g && r < b)
1006    return r;
1007  if (b < r && b < g)
1008    return b;
1009  return g;
1010}
1011
1012SANE_Status
1013sane_read (SANE_Handle h, SANE_Byte * buf, SANE_Int maxlen, SANE_Int * len)
1014{
1015  struct device_s *dev = (struct device_s *) h;
1016  int available;
1017  int ret;
1018  *len = 0;
1019  if (dev->status == STATUS_IDLE)
1020    return SANE_STATUS_IO_ERROR;
1021  if (dev->optionw[COLOR_OFFSET] == RGB)
1022    {
1023      while (min3 (dev->write_offset_r, dev->write_offset_g,
1024		   dev->write_offset_b) <= dev->read_offset)
1025	{
1026	  ret = get_data (dev);
1027	  if (ret != SANE_STATUS_GOOD)
1028	    {
1029	      if (min3 (dev->write_offset_r,
1030			dev->write_offset_g,
1031			dev->write_offset_b) <= dev->read_offset)
1032		return ret;
1033	    }
1034	}
1035      available = min3 (dev->write_offset_r, dev->write_offset_g,
1036			dev->write_offset_b);
1037    }
1038  else
1039    {
1040      while (dev->write_offset_r <= dev->read_offset)
1041	{
1042	  ret = get_data (dev);
1043	  if (ret != SANE_STATUS_GOOD)
1044	    if (dev->write_offset_r <= dev->read_offset)
1045	      return ret;
1046	}
1047      available = dev->write_offset_r;
1048    }
1049  *len = available - dev->read_offset;
1050  if (*len > maxlen)
1051    *len = maxlen;
1052  memcpy (buf, dev->buffer + dev->read_offset, *len);
1053  dev->read_offset += *len;
1054  if (dev->read_offset == dev->bufs)
1055    {
1056      free (dev->buffer);
1057      dev->buffer = NULL;
1058      dev->read_offset = 0;
1059      dev->write_offset_r = 0;
1060      dev->write_offset_g = 1;
1061      dev->write_offset_b = 2;
1062    }
1063
1064  /* Special case where sane_cancel is called while scanning */
1065  if (dev->status == STATUS_CANCELING)
1066    {
1067       do_cancel(dev);
1068       return SANE_STATUS_CANCELLED;
1069    }
1070  return SANE_STATUS_GOOD;
1071}
1072
1073void
1074sane_cancel (SANE_Handle h)
1075{
1076  struct device_s *dev = (struct device_s *) h;
1077
1078
1079  if (dev->status == STATUS_SCANNING)
1080    {
1081      dev->status = STATUS_CANCELING;
1082      return;
1083    }
1084
1085  free (dev->buffer);
1086  dev->buffer = NULL;
1087}
1088
1089SANE_Status
1090sane_set_io_mode (SANE_Handle __sane_unused__ handle,
1091		  SANE_Bool __sane_unused__ non_blocking)
1092{
1093  return SANE_STATUS_UNSUPPORTED;
1094}
1095
1096SANE_Status
1097sane_get_select_fd (SANE_Handle __sane_unused__ handle,
1098		    SANE_Int __sane_unused__ * fd)
1099{
1100  return SANE_STATUS_UNSUPPORTED;
1101}
1102