~ubuntu-branches/ubuntu/vivid/sane-backends/vivid

« back to all changes in this revision

Viewing changes to backend/magicolor.c

  • Committer: Bazaar Package Importer
  • Author(s): Julien BLACHE
  • Date: 2011-02-16 19:00:55 UTC
  • mfrom: (1.2.2 upstream) (21.1.2 experimental)
  • Revision ID: james.westby@ubuntu.com-20110216190055-wz0c33eracchkxts
Tags: 1.0.22-1
* New upstream release.
  + epson2: reject scan area settings that would lead to a division by zero
    (closes: #581181).

* debian/control:
  + Bump Standards-Version to 3.9.1 (no changes).
  + Demote libsane-extras-* to Recommends again.
* debian/rules:
  + Add acl (>= 2.2.49-4) to udev substvar for ACL utilities in /bin.
  + Use sane-desc -m udev+acl (closes: #591767, #612815).
* debian/libsane.README.Debian:
  + Update; mention ConsoleKit and the udev rules now using ACLs.

* debian/patches/sane-desc_udev+acl.patch:
  + Added; compared to experimental, setfacl is now in /bin.
* debian/patches/fix_xerox_mfp_color_mode.patch,
  debian/patches/use_libsane_matched_for_scsi.patch,
  debian/patches/allow_dll.d_symlinks.patch,
  debian/patches/saned_exit_avahi_process.patch,
  debian/patches/xerox_mfp_new_ids.patch,
  debian/patches/scsi_perfection_2450.patch,
  debian/patches/scsi_scanjet_4c.patch,
  debian/patches/genesys_disable_raw_data_log.patch,
  debian/patches/fix_epson2_commands.patch,
  debian/patches/fix_epson2_cancel.patch:
  + Removed; merged upstream.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * magicolor.c - SANE library for Magicolor scanners.
 
3
 *
 
4
 * (C) 2010 Reinhold Kainhofer <reinhold@kainhofer.com>
 
5
 *
 
6
 * Based on the epson2 sane backend:
 
7
 * Based on Kazuhiro Sasayama previous
 
8
 * Work on epson.[ch] file from the SANE package.
 
9
 * Please see those files for additional copyrights.
 
10
 * Copyright (C) 2006-10 Tower Technologies
 
11
 * Author: Alessandro Zummo <a.zummo@towertech.it>
 
12
 *
 
13
 * This file is part of the SANE package.
 
14
 *
 
15
 * This program is free software; you can redistribute it and/or
 
16
 * modify it under the terms of the GNU General Public License as
 
17
 * published by the Free Software Foundation, version 2.
 
18
 */
 
19
 
 
20
#define MAGICOLOR_VERSION       0
 
21
#define MAGICOLOR_REVISION      0
 
22
#define MAGICOLOR_BUILD 1
 
23
 
 
24
/* debugging levels:
 
25
 *
 
26
 *     127      mc_recv buffer
 
27
 *     125      mc_send buffer
 
28
 *      35      fine-grained status and progress
 
29
 *      30      sane_read
 
30
 *      25      setvalue, getvalue, control_option
 
31
 *      20      low-level (I/O) mc_* functions
 
32
 *      15      mid-level mc_* functions
 
33
 *      10      high-level cmd_* functions
 
34
 *       7      open/close/attach
 
35
 *       6      print_params
 
36
 *       5      basic functions
 
37
 *       3      status info and progress
 
38
 *       2      scanner info and capabilities
 
39
 *       1      errors & warnings
 
40
 */
 
41
 
 
42
#include "sane/config.h"
 
43
 
 
44
#include <limits.h>
 
45
#include <stdio.h>
 
46
#include <string.h>
 
47
#include <stdlib.h>
 
48
#include <ctype.h>
 
49
#include <fcntl.h>
 
50
#include <unistd.h>
 
51
#include <errno.h>
 
52
#include <sys/time.h>
 
53
#include <math.h>
 
54
#include <poll.h>
 
55
 
 
56
 
 
57
#if HAVE_LIBSNMP
 
58
#include <net-snmp/net-snmp-config.h>
 
59
#include <net-snmp/net-snmp-includes.h>
 
60
#include <net-snmp/library/snmp_transport.h>
 
61
#include <arpa/inet.h>
 
62
#endif
 
63
 
 
64
#include "../include/sane/saneopts.h"
 
65
#include "../include/sane/sanei_usb.h"
 
66
#include "../include/sane/sanei_tcp.h"
 
67
#include "../include/sane/sanei_udp.h"
 
68
#include "../include/sane/sanei_config.h"
 
69
#include "../include/sane/sanei_backend.h"
 
70
 
 
71
#include "magicolor.h"
 
72
 
 
73
 
 
74
#define min(x,y) (((x)<(y))?(x):(y))
 
75
 
 
76
 
 
77
 
 
78
/****************************************************************************
 
79
 *   Devices supported by this backend
 
80
 ****************************************************************************/
 
81
 
 
82
 
 
83
 
 
84
/*          Scanner command type
 
85
 *          |     Start scan
 
86
 *          |     |     Poll for error
 
87
 *          |     |     |     Stop scan?
 
88
 *          |     |     |     |     Query image parameters
 
89
 *          |     |     |     |     |     set scan parameters
 
90
 *          |     |     |     |     |     |     Get status?
 
91
 *          |     |     |     |     |     |     |     Read scanned data
 
92
 *          |     |     |     |     |     |     |     |     Unknown
 
93
 *          |     |     |     |     |     |     |     |     |     Unknown
 
94
 *          |     |     |     |     |     |     |     |     |     |     Net wrapper command type
 
95
 *          |     |     |     |     |     |     |     |     |     |     |     Net Welcome
 
96
 *          |     |     |     |     |     |     |     |     |     |     |     |     Net Lock
 
97
 *          |     |     |     |     |     |     |     |     |     |     |     |     |     Net Lock ACK
 
98
 *          |     |     |     |     |     |     |     |     |     |     |     |     |     |     Net Unlock
 
99
 *          |     |     |     |     |     |     |     |     |     |     |     |     |     |     |
 
100
*/
 
101
static struct MagicolorCmd magicolor_cmd[] = {
 
102
  {"mc1690mf", CMD, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x12, NET, 0x00, 0x01, 0x02, 0x03}
 
103
};
 
104
 
 
105
static SANE_Int magicolor_default_resolutions[] = {150, 300, 600};
 
106
static SANE_Int magicolor_default_depths[] = {1,8};
 
107
 
 
108
static struct MagicolorCap magicolor_cap[] = {
 
109
 
 
110
  /* KONICA MINOLTA magicolor 1690MF, USB ID 0x123b:2089 */
 
111
  {
 
112
      0x2089, "mc1690mf", "KONICA MINOLTA magicolor 1690MF", "1.3.6.1.4.1.183341.1.1.2.1.32.3.2",
 
113
      -1, 0x85,
 
114
      600, {150, 600, 0}, magicolor_default_resolutions, 3,  /* 600 dpi max, 3 resolutions */
 
115
      8, magicolor_default_depths,                          /* color depth 8 default, 1 and 8 possible */
 
116
      {1, 9, 0},                                             /* brightness ranges (TODO!) */
 
117
      {0, SANE_FIX(0x13f8 * MM_PER_INCH / 600), 0}, {0, SANE_FIX(0x1b9c * MM_PER_INCH / 600), 0}, /* FBF x/y ranges (TODO!) */
 
118
      SANE_TRUE, SANE_FALSE, /* non-duplex ADF, x/y ranges (TODO!) */
 
119
      {0, SANE_FIX(0x1390 * MM_PER_INCH / 600), 0}, {0, SANE_FIX(0x20dc * MM_PER_INCH / 600), 0},
 
120
  }
 
121
 
 
122
};
 
123
 
 
124
static int MC_SNMP_Timeout = 2500;
 
125
static int MC_Scan_Data_Timeout = 15000;
 
126
static int MC_Request_Timeout = 5000;
 
127
 
 
128
 
 
129
 
 
130
/****************************************************************************
 
131
 *   General configuration parameter definitions
 
132
 ****************************************************************************/
 
133
 
 
134
 
 
135
/*
 
136
 * Definition of the mode_param struct, that is used to
 
137
 * specify the valid parameters for the different scan modes.
 
138
 *
 
139
 * The depth variable gets updated when the bit depth is modified.
 
140
 */
 
141
 
 
142
static struct mode_param mode_params[] = {
 
143
        {0x00, 1, 1},  /* Lineart, 1 color, 1 bit */
 
144
        {0x02, 1, 24}, /* Grayscale, 1 color, 24 bit */
 
145
        {0x03, 3, 24}  /* Color, 3 colors, 24 bit */
 
146
};
 
147
 
 
148
static SANE_String_Const mode_list[] = {
 
149
        SANE_VALUE_SCAN_MODE_LINEART,
 
150
        SANE_VALUE_SCAN_MODE_GRAY,
 
151
        SANE_VALUE_SCAN_MODE_COLOR,
 
152
        NULL
 
153
};
 
154
 
 
155
static const SANE_String_Const adf_mode_list[] = {
 
156
        SANE_I18N("Simplex"),
 
157
        SANE_I18N("Duplex"),
 
158
        NULL
 
159
};
 
160
 
 
161
/* Define the different scan sources */
 
162
 
 
163
#define FBF_STR SANE_I18N("Flatbed")
 
164
#define ADF_STR SANE_I18N("Automatic Document Feeder")
 
165
 
 
166
/*
 
167
 * source list need one dummy entry (save device settings is crashing).
 
168
 * NOTE: no const - this list gets created while exploring the capabilities
 
169
 * of the scanner.
 
170
 */
 
171
 
 
172
static SANE_String_Const source_list[] = {
 
173
        FBF_STR,
 
174
        NULL,
 
175
        NULL,
 
176
        NULL
 
177
};
 
178
 
 
179
/* Some utility functions */
 
180
 
 
181
static size_t
 
182
max_string_size(const SANE_String_Const strings[])
 
183
{
 
184
        size_t size, max_size = 0;
 
185
        int i;
 
186
 
 
187
        for (i = 0; strings[i]; i++) {
 
188
                size = strlen(strings[i]) + 1;
 
189
                if (size > max_size)
 
190
                        max_size = size;
 
191
        }
 
192
        return max_size;
 
193
}
 
194
 
 
195
static SANE_Status attach_one_usb(SANE_String_Const devname);
 
196
static SANE_Status attach_one_net(SANE_String_Const devname, unsigned int device);
 
197
 
 
198
static void
 
199
print_params(const SANE_Parameters params)
 
200
{
 
201
        DBG(6, "params.format          = %d\n", params.format);
 
202
        DBG(6, "params.last_frame      = %d\n", params.last_frame);
 
203
        DBG(6, "params.bytes_per_line  = %d\n", params.bytes_per_line);
 
204
        DBG(6, "params.pixels_per_line = %d\n", params.pixels_per_line);
 
205
        DBG(6, "params.lines           = %d\n", params.lines);
 
206
        DBG(6, "params.depth           = %d\n", params.depth);
 
207
}
 
208
 
 
209
 
 
210
 
 
211
/****************************************************************************
 
212
 *   Low-level Network communication functions
 
213
 ****************************************************************************/
 
214
 
 
215
 
 
216
#define MAGICOLOR_SNMP_SYSDESCR_OID  ".1.3.6.1.2.1.1.1.0"
 
217
#define MAGICOLOR_SNMP_SYSOBJECT_OID ".1.3.6.1.2.1.1.2.0"
 
218
#define MAGICOLOR_SNMP_MAC_OID       ".1.3.6.1.2.1.2.2.1.6.1"
 
219
#define MAGICOLOR_SNMP_DEVICE_TREE   ".1.3.6.1.4.1.18334.1.1.1.1.1"
 
220
 
 
221
 
 
222
/* We don't have a packet wrapper, which holds packet size etc., so we
 
223
   don't have to use a *read_raw and a *_read function... */
 
224
static int
 
225
sanei_magicolor_net_read(struct Magicolor_Scanner *s, unsigned char *buf, size_t wanted,
 
226
                       SANE_Status * status)
 
227
{
 
228
        size_t size, read = 0;
 
229
        struct pollfd fds[1];
 
230
 
 
231
        *status = SANE_STATUS_GOOD;
 
232
 
 
233
        /* poll for data-to-be-read (using a 5 seconds timeout) */
 
234
        fds[0].fd = s->fd;
 
235
        fds[0].events = POLLIN;
 
236
        if (poll (fds, 1, MC_Request_Timeout) <= 0) {
 
237
                *status = SANE_STATUS_IO_ERROR;
 
238
                return read;
 
239
        }
 
240
 
 
241
        while (read < wanted) {
 
242
                size = sanei_tcp_read(s->fd, buf + read, wanted - read);
 
243
 
 
244
                if (size == 0)
 
245
                        break;
 
246
 
 
247
                read += size;
 
248
        }
 
249
 
 
250
        if (read < wanted)
 
251
                *status = SANE_STATUS_IO_ERROR;
 
252
 
 
253
        return read;
 
254
}
 
255
 
 
256
/* We need to optionally pad the buffer with 0x00 to send 64-byte chunks.
 
257
   On the other hand, the 0x04 commands don't need this, so we need two
 
258
   functions, one *_write function that pads the buffer and then calls
 
259
    *_write_raw */
 
260
static int
 
261
sanei_magicolor_net_write_raw(struct Magicolor_Scanner *s,
 
262
                              const unsigned char *buf, size_t buf_size,
 
263
                              SANE_Status *status)
 
264
{
 
265
        sanei_tcp_write(s->fd, buf, buf_size);
 
266
        /* TODO: Check whether sending failed... */
 
267
 
 
268
        *status = SANE_STATUS_GOOD;
 
269
        return buf_size;
 
270
}
 
271
 
 
272
static int
 
273
sanei_magicolor_net_write(struct Magicolor_Scanner *s,
 
274
                          const unsigned char *buf, size_t buf_size,
 
275
                          SANE_Status *status)
 
276
{
 
277
        size_t len = 64;
 
278
        unsigned char *new_buf = malloc(len);
 
279
        if (!new_buf) {
 
280
                *status = SANE_STATUS_NO_MEM;
 
281
                return 0;
 
282
        }
 
283
        memset(new_buf, 0x00, len);
 
284
        if (buf_size > len)
 
285
                buf_size = len;
 
286
        if (buf_size)
 
287
                memcpy(new_buf, buf, buf_size);
 
288
        return sanei_magicolor_net_write_raw (s, new_buf, len, status);
 
289
}
 
290
 
 
291
static SANE_Status
 
292
sanei_magicolor_net_open(struct Magicolor_Scanner *s)
 
293
{
 
294
        SANE_Status status;
 
295
        unsigned char buf[5];
 
296
 
 
297
        ssize_t read;
 
298
        struct timeval tv;
 
299
        struct MagicolorCmd *cmd = s->hw->cmd;
 
300
 
 
301
        tv.tv_sec = 5;
 
302
        tv.tv_usec = 0;
 
303
 
 
304
        setsockopt(s->fd, SOL_SOCKET, SO_RCVTIMEO, (char *)&tv,  sizeof(tv));
 
305
 
 
306
        DBG(1, "%s\n", __func__);
 
307
 
 
308
        /* the scanner sends a kind of welcome msg */
 
309
        read = sanei_magicolor_net_read(s, buf, 3, &status);
 
310
        if (read != 3)
 
311
                return SANE_STATUS_IO_ERROR;
 
312
        if (buf[0] != cmd->net_wrapper_cmd || buf[1] != cmd->net_welcome) {
 
313
                DBG (32, "Invalid welcome message received, Expected 0x%02x %02x 00, but got 0x%02x %02x %02x\n",
 
314
                        cmd->net_wrapper_cmd, cmd->net_welcome, buf[0], buf[1], buf[2]);
 
315
                return SANE_STATUS_IO_ERROR;
 
316
        } else if (buf[2] != 0x00) {
 
317
                /* TODO: Handle response "04 00 01", indicating an error! */
 
318
                DBG (32, "Welcome message received, busy status %02x\n", buf[2]);
 
319
                /* TODO: Return a human-readable error message (Unable to connect to scanner, scanner is not ready) */
 
320
                return SANE_STATUS_DEVICE_BUSY;
 
321
        }
 
322
 
 
323
        buf[0] = cmd->net_wrapper_cmd;
 
324
        buf[1] = cmd->net_lock;
 
325
        buf[2] = 0x00;
 
326
        /* Copy the device's USB id to bytes 3-4: */
 
327
        buf[3] = s->hw->cap->id & 0xff;
 
328
        buf[4] = (s->hw->cap->id >> 8) & 0xff;
 
329
 
 
330
        DBG(32, "Proper welcome message received, locking the scanner...\n");
 
331
        sanei_magicolor_net_write_raw(s, buf, 5, &status);
 
332
 
 
333
        read = sanei_magicolor_net_read(s, buf, 3, &status);
 
334
        if (read != 3)
 
335
                return SANE_STATUS_IO_ERROR;
 
336
        if (buf[0] != cmd->net_wrapper_cmd || buf[1] != cmd->net_lock_ack || buf[2] != 0x00) {
 
337
                DBG (32, "Welcome message received, Expected 0x%x %x 00, but got 0x%x %x %x\n",
 
338
                        cmd->net_wrapper_cmd, cmd->net_lock_ack, buf[0], buf[1], buf[2]);
 
339
                return SANE_STATUS_IO_ERROR;
 
340
        }
 
341
 
 
342
        DBG(32, "scanner locked\n");
 
343
 
 
344
        return status;
 
345
}
 
346
 
 
347
static SANE_Status
 
348
sanei_magicolor_net_close(struct Magicolor_Scanner *s)
 
349
{
 
350
        SANE_Status status;
 
351
        struct MagicolorCmd *cmd = s->hw->cmd;
 
352
        unsigned char buf[3];
 
353
 
 
354
        DBG(1, "%s\n", __func__);
 
355
        buf[0] = cmd->net_wrapper_cmd;
 
356
        buf[1] = cmd->net_unlock;
 
357
        buf[2] = 0x00;
 
358
        sanei_magicolor_net_write_raw(s, buf, 3, &status);
 
359
        return status;
 
360
}
 
361
 
 
362
 
 
363
 
 
364
/****************************************************************************
 
365
 *   Low-level USB communication functions
 
366
 ****************************************************************************/
 
367
 
 
368
#define SANE_MAGICOLOR_VENDOR_ID        (0x132b)
 
369
 
 
370
SANE_Word sanei_magicolor_usb_product_ids[] = {
 
371
  0x2089, /* magicolor 1690MF */
 
372
  0                             /* last entry - this is used for devices that are specified
 
373
                                   in the config file as "usb <vendor> <product>" */
 
374
};
 
375
 
 
376
static int
 
377
sanei_magicolor_getNumberOfUSBProductIds (void)
 
378
{
 
379
  return sizeof (sanei_magicolor_usb_product_ids) / sizeof (SANE_Word);
 
380
}
 
381
 
 
382
 
 
383
 
 
384
 
 
385
/****************************************************************************
 
386
 *   Magicolor low-level communication commands
 
387
 ****************************************************************************/
 
388
 
 
389
static void dump_hex_buffer_dense (int level, const unsigned char *buf, size_t buf_size)
 
390
{
 
391
        size_t k;
 
392
        char msg[1024], fmt_buf[1024];
 
393
        memset (&msg[0], 0x00, 1024);
 
394
        memset (&fmt_buf[0], 0x00, 1024);
 
395
        for (k = 0; k < min(buf_size, 80); k++) {
 
396
                if (k % 16 == 0) {
 
397
                        if (k>0) {
 
398
                                DBG (level, "%s\n", msg);
 
399
                                memset (&msg[0], 0x00, 1024);
 
400
                        }
 
401
                        sprintf (fmt_buf, "     0x%04lx  ", (unsigned long)k);
 
402
                        strcat (msg, fmt_buf);
 
403
                }
 
404
                if (k % 8 == 0) {
 
405
                        strcat (msg, " ");
 
406
                }
 
407
                sprintf (fmt_buf, " %02x" , buf[k]);
 
408
                strcat (msg, fmt_buf);
 
409
        }
 
410
        if (msg[0] != 0 ) {
 
411
                DBG (level, "%s\n", msg);
 
412
        }
 
413
}
 
414
 
 
415
/* Create buffers containing the command and arguments. Length of reserved
 
416
 * buffer is returned. It's the caller's job to free the buffer! */
 
417
static int mc_create_buffer (Magicolor_Scanner *s, unsigned char cmd_type, unsigned char cmd,
 
418
                      unsigned char **buf, unsigned char* arg1, size_t len1,
 
419
                      SANE_Status *status)
 
420
{
 
421
        unsigned char* b = NULL;
 
422
        size_t buf_len = 2+4+len1+4;
 
423
        NOT_USED (s);
 
424
        if (len1 <= 0)
 
425
                buf_len = 6; /* no args, just cmd + final 0x00 00 00 00 */
 
426
        *buf = b = malloc (buf_len);
 
427
        memset (b, 0x00, buf_len);
 
428
        if (!b) {
 
429
                *status = SANE_STATUS_NO_MEM;
 
430
                return 0;
 
431
        }
 
432
        b[0] = cmd_type;
 
433
        b[1] = cmd;
 
434
        if (len1>0) {
 
435
                b[2] = len1 & 0xff;
 
436
                b[3] = (len1 >> 8) & 0xff;
 
437
                b[4] = (len1 >> 16) & 0xff;
 
438
                b[5] = (len1 >> 24) & 0xff;
 
439
                if (arg1)
 
440
                        memcpy(b+6, arg1, len1);
 
441
        }
 
442
        /* Writing the final 0x00 00 00 00 is not necessary, they are 0x00 already */
 
443
        *status = SANE_STATUS_GOOD;
 
444
        return buf_len;
 
445
}
 
446
 
 
447
static int mc_create_buffer2 (Magicolor_Scanner *s, unsigned char cmd_type, unsigned char cmd,
 
448
                       unsigned char **buf, unsigned char* arg1, size_t len1,
 
449
                       unsigned char* arg2, size_t len2, SANE_Status *status)
 
450
{
 
451
        unsigned char* b = NULL;
 
452
        size_t buf_len = 2+4+len1+4+len2+4;
 
453
        /* If any of the two args has size 0, use the simpler mc_create_buffer */
 
454
        if (len1<=0)
 
455
                return mc_create_buffer (s, cmd_type, cmd, buf, arg2, len2, status);
 
456
        else if (len2<=0)
 
457
                return mc_create_buffer (s, cmd_type, cmd, buf, arg1, len1, status);
 
458
        /* Allocate memory and copy over args and their lengths */
 
459
        *buf = b = malloc (buf_len);
 
460
        if (!b) {
 
461
                *status = SANE_STATUS_NO_MEM;
 
462
                return 0;
 
463
        }
 
464
        memset (b, 0x00, buf_len);
 
465
        b[0] = cmd_type;
 
466
        b[1] = cmd;
 
467
        /* copy over the argument length in lower endian */
 
468
        b[2] = len1 & 0xff;
 
469
        b[3] = (len1 >> 8) & 0xff;
 
470
        b[4] = (len1 >> 16) & 0xff;
 
471
        b[5] = (len1 >> 24) & 0xff;
 
472
        if (arg1) {
 
473
                /* Copy the arguments */
 
474
                memcpy(b+6, arg1, len1);
 
475
        }
 
476
        /* copy over the second argument length in little endian */
 
477
        b[6+len1] = len2 & 0xff;
 
478
        b[7+len1] = (len2 >> 8) & 0xff;
 
479
        b[8+len1] = (len2 >> 16) & 0xff;
 
480
        b[9+len1] = (len2 >> 24) & 0xff;
 
481
        if (arg2) {
 
482
                memcpy(b+10+len1, arg2, len2);
 
483
        }
 
484
        *status = SANE_STATUS_GOOD;
 
485
        return buf_len;
 
486
}
 
487
 
 
488
static int
 
489
mc_send(Magicolor_Scanner * s, void *buf, size_t buf_size, SANE_Status * status)
 
490
{
 
491
        DBG(15, "%s: size = %lu\n", __func__, (u_long) buf_size);
 
492
 
 
493
        if (DBG_LEVEL >= 125) {
 
494
                const unsigned char *s = buf;
 
495
                DBG(125, "Cmd: 0x%02x %02x, complete buffer:\n", s[0], s[1]);
 
496
                dump_hex_buffer_dense (125, s, buf_size);
 
497
        }
 
498
 
 
499
        if (s->hw->connection == SANE_MAGICOLOR_NET) {
 
500
                return sanei_magicolor_net_write(s, buf, buf_size, status);
 
501
        } else if (s->hw->connection == SANE_MAGICOLOR_USB) {
 
502
                size_t n;
 
503
                n = buf_size;
 
504
                *status = sanei_usb_write_bulk(s->fd, buf, &n);
 
505
                DBG(125, "USB: wrote %lu bytes, status: %s\n", (unsigned long)n, sane_strstatus(*status));
 
506
                return n;
 
507
        }
 
508
 
 
509
        *status = SANE_STATUS_INVAL;
 
510
        return 0;
 
511
        /* never reached */
 
512
}
 
513
 
 
514
static ssize_t
 
515
mc_recv(Magicolor_Scanner * s, void *buf, ssize_t buf_size,
 
516
            SANE_Status * status)
 
517
{
 
518
        ssize_t n = 0;
 
519
 
 
520
        DBG(15, "%s: size = %ld, buf = %p\n", __func__, (long) buf_size, buf);
 
521
 
 
522
        if (s->hw->connection == SANE_MAGICOLOR_NET) {
 
523
                n = sanei_magicolor_net_read(s, buf, buf_size, status);
 
524
        } else if (s->hw->connection == SANE_MAGICOLOR_USB) {
 
525
                /* !!! only report an error if we don't read anything */
 
526
                n = buf_size;   /* buf_size gets overwritten */
 
527
                *status =
 
528
                        sanei_usb_read_bulk(s->fd, (SANE_Byte *) buf,
 
529
                                            (size_t *) & n);
 
530
 
 
531
                if (n > 0)
 
532
                        *status = SANE_STATUS_GOOD;
 
533
        }
 
534
 
 
535
        if (n < buf_size) {
 
536
                DBG(1, "%s: expected = %lu, got = %ld\n", __func__,
 
537
                    (u_long) buf_size, (long) n);
 
538
                *status = SANE_STATUS_IO_ERROR;
 
539
        }
 
540
 
 
541
        /* dump buffer if appropriate */
 
542
        if (DBG_LEVEL >= 127 && n > 0) {
 
543
                const unsigned char* b=buf;
 
544
                dump_hex_buffer_dense (125, b, buf_size);
 
545
        }
 
546
 
 
547
        return n;
 
548
}
 
549
 
 
550
/* Simple function to exchange a fixed amount of
 
551
 * data with the scanner
 
552
 */
 
553
static SANE_Status
 
554
mc_txrx(Magicolor_Scanner * s, unsigned char *txbuf, size_t txlen,
 
555
            unsigned char *rxbuf, size_t rxlen)
 
556
{
 
557
        SANE_Status status;
 
558
 
 
559
        mc_send(s, txbuf, txlen, &status);
 
560
        if (status != SANE_STATUS_GOOD) {
 
561
                DBG(1, "%s: tx err, %s\n", __func__, sane_strstatus(status));
 
562
                return status;
 
563
        }
 
564
 
 
565
        mc_recv(s, rxbuf, rxlen, &status);
 
566
        if (status != SANE_STATUS_GOOD) {
 
567
                DBG(1, "%s: rx err, %s\n", __func__, sane_strstatus(status));
 
568
        }
 
569
 
 
570
        return status;
 
571
}
 
572
 
 
573
 
 
574
 
 
575
 
 
576
 
 
577
/****************************************************************************
 
578
 *   Magicolor high-level communication commands
 
579
 ****************************************************************************/
 
580
 
 
581
 
 
582
/** 0x03 09 01 - Request last error
 
583
 * <- Information block (0x00 for OK, 0x01 for ERROR)
 
584
 */
 
585
static SANE_Status
 
586
cmd_request_error (SANE_Handle handle)
 
587
{
 
588
        Magicolor_Scanner *s = (Magicolor_Scanner *) handle;
 
589
        SANE_Status status;
 
590
        unsigned char params[1];
 
591
        unsigned char *buf;
 
592
        size_t buflen;
 
593
 
 
594
        DBG(8, "%s\n", __func__);
 
595
 
 
596
        if (s->hw->cmd->request_status == 0)
 
597
                return SANE_STATUS_UNSUPPORTED;
 
598
 
 
599
        buflen = mc_create_buffer (s, s->hw->cmd->scanner_cmd, s->hw->cmd->request_error,
 
600
                                   &buf, NULL, 1, &status);
 
601
        if (buflen <= 0 ) {
 
602
                return SANE_STATUS_NO_MEM;
 
603
        } else if (status != SANE_STATUS_GOOD) {
 
604
                return status;
 
605
        }
 
606
 
 
607
        status = mc_txrx (s, buf, buflen, params, 1);
 
608
        free(buf);
 
609
        if (status != SANE_STATUS_GOOD)
 
610
                return status;
 
611
 
 
612
        DBG(1, "status: %02x\n", params[0]);
 
613
 
 
614
        switch (params[0]) {
 
615
                case STATUS_READY:
 
616
                        DBG(1, " ready\n");
 
617
                        break;
 
618
                case STATUS_ADF_JAM:
 
619
                        DBG(1, " paper jam in ADF\n");
 
620
                        return SANE_STATUS_JAMMED;
 
621
                        break;
 
622
                case STATUS_OPEN:
 
623
                        DBG(1, " printer door open or waiting for button press\n");
 
624
                        return SANE_STATUS_COVER_OPEN;
 
625
                        break;
 
626
                case STATUS_NOT_READY:
 
627
                        DBG(1, " scanner not ready (in use on another interface or warming up)\n");
 
628
                        return SANE_STATUS_DEVICE_BUSY;
 
629
                        break;
 
630
                default:
 
631
                        DBG(1, " unknown status 0x%x\n", params[0]);
 
632
        }
 
633
        return status;
 
634
}
 
635
 
 
636
/** 0x03 0d  - Request status command */
 
637
static SANE_Status
 
638
cmd_request_status(SANE_Handle handle, unsigned char *b)
 
639
{
 
640
        Magicolor_Scanner *s = (Magicolor_Scanner *) handle;
 
641
        SANE_Status status;
 
642
        unsigned char *buf;
 
643
        size_t buflen;
 
644
 
 
645
        DBG(8, "%s\n", __func__);
 
646
        if (!b) {
 
647
                DBG(1, "%s called with NULL buffer\n", __func__);
 
648
                return SANE_STATUS_INVAL;
 
649
        }
 
650
        memset (b, 0x00, 0x0b); /* initialize all 0x0b bytes with 0 */
 
651
        buflen = mc_create_buffer (s, s->hw->cmd->scanner_cmd, s->hw->cmd->request_status,
 
652
                                   &buf, NULL, 0x0b, &status);
 
653
        if (buflen <= 0 ) {
 
654
                return SANE_STATUS_NO_MEM;
 
655
        } else if (status != SANE_STATUS_GOOD) {
 
656
                return status;
 
657
        }
 
658
 
 
659
        status = mc_txrx (s, buf, buflen, b, 0x0b);
 
660
        free (buf);
 
661
        if (status != SANE_STATUS_GOOD)
 
662
                DBG(8, "%s: Status NOT successfully retrieved\n", __func__);
 
663
        else {
 
664
                DBG(8, "%s: Status successfully retrieved:\n", __func__);
 
665
                /* TODO: debug output of the returned parameters... */
 
666
                DBG (11, "  ADF status: 0x%02x", b[1]);
 
667
                if (b[1] & ADF_LOADED) {
 
668
                        DBG (11, " loaded\n");
 
669
                } else {
 
670
                        DBG (11, " not loaded\n");
 
671
                }
 
672
        }
 
673
        return status;
 
674
}
 
675
 
 
676
 
 
677
/** 0x03 08  - Start scan command */
 
678
static SANE_Status
 
679
cmd_start_scan (SANE_Handle handle, size_t value)
 
680
{
 
681
        Magicolor_Scanner *s = (Magicolor_Scanner *) handle;
 
682
        SANE_Status status;
 
683
        unsigned char params1[4], params2[1];
 
684
        unsigned char *buf;
 
685
        size_t buflen;
 
686
 
 
687
        DBG(8, "%s\n", __func__);
 
688
        /* Copy params to buffers */
 
689
        /* arg1 is expected returned bytes per line, 4-byte little endian */
 
690
        /* arg2 is unknown, seems to be always 0x00 */
 
691
        params1[0] = value & 0xff;
 
692
        params1[1] = (value >> 8) & 0xff;
 
693
        params1[2] = (value >> 16) & 0xff;
 
694
        params1[3] = (value >> 24) & 0xff;
 
695
 
 
696
        params2[0] = 0x00;
 
697
        buflen = mc_create_buffer2 (s, s->hw->cmd->scanner_cmd, s->hw->cmd->start_scanning,
 
698
                                    &buf, params1, 4, params2, 1, &status);
 
699
        if (buflen <= 0 ) {
 
700
                return SANE_STATUS_NO_MEM;
 
701
        } else if (status != SANE_STATUS_GOOD) {
 
702
                return status;
 
703
        }
 
704
 
 
705
        mc_send(s, buf, buflen, &status);
 
706
        free (buf);
 
707
        if (status != SANE_STATUS_GOOD)
 
708
                DBG(8, "%s: Data NOT successfully sent\n", __func__);
 
709
        else
 
710
                DBG(8, "%s: Data successfully sent\n", __func__);
 
711
        return status;
 
712
}
 
713
 
 
714
/** 0x03 0a  - Cancel(?) Scan command */
 
715
/* TODO: Does this command really mean CANCEL??? */
 
716
static SANE_Status
 
717
cmd_cancel_scan (SANE_Handle handle)
 
718
{
 
719
        Magicolor_Scanner *s = (Magicolor_Scanner *) handle;
 
720
        SANE_Status status;
 
721
        unsigned char *buf;
 
722
        size_t buflen;
 
723
 
 
724
        DBG(8, "%s\n", __func__);
 
725
        buflen = mc_create_buffer (s, s->hw->cmd->scanner_cmd, s->hw->cmd->stop_scanning,
 
726
                                    &buf, NULL, 0, &status);
 
727
        if (buflen <= 0 ) {
 
728
                return SANE_STATUS_NO_MEM;
 
729
        } else if (status != SANE_STATUS_GOOD) {
 
730
                return status;
 
731
        }
 
732
 
 
733
        mc_send(s, buf, buflen, &status);
 
734
        free (buf);
 
735
        if (status != SANE_STATUS_GOOD)
 
736
                DBG(8, "%s: Data NOT successfully sent\n", __func__);
 
737
        else
 
738
                DBG(8, "%s: Data successfully sent\n", __func__);
 
739
        return status;
 
740
}
 
741
 
 
742
/** 0x03 12  - Finish(?) scan command */
 
743
/* TODO: Does this command really mean FINISH??? */
 
744
static SANE_Status
 
745
cmd_finish_scan (SANE_Handle handle)
 
746
{
 
747
        Magicolor_Scanner *s = (Magicolor_Scanner *) handle;
 
748
        SANE_Status status;
 
749
        unsigned char *buf, returned[0x0b];
 
750
        size_t buflen;
 
751
 
 
752
        DBG(8, "%s\n", __func__);
 
753
        buflen = mc_create_buffer (s, s->hw->cmd->scanner_cmd, s->hw->cmd->unknown2,
 
754
                                    &buf, NULL, 0x0b, &status);
 
755
        if (buflen <= 0 ) {
 
756
                return SANE_STATUS_NO_MEM;
 
757
        } else if (status != SANE_STATUS_GOOD) {
 
758
                return status;
 
759
        }
 
760
        memset (&returned[0], 0x00, 0x0b);
 
761
 
 
762
        status = mc_txrx (s, buf, buflen, returned, 0x0b);
 
763
        free (buf);
 
764
        if (status != SANE_STATUS_GOOD)
 
765
                DBG(8, "%s: Data NOT successfully sent\n", __func__);
 
766
        else
 
767
                DBG(8, "%s: Data successfully sent\n", __func__);
 
768
        return status;
 
769
}
 
770
 
 
771
/** 0x03 0b  - Get scanning parameters command
 
772
 *    input buffer seems to be 0x00 always */
 
773
static SANE_Status
 
774
cmd_get_scanning_parameters(SANE_Handle handle,
 
775
                            SANE_Frame *format, SANE_Int *depth,
 
776
                            SANE_Int *data_pixels, SANE_Int *pixels_per_line,
 
777
                            SANE_Int *lines)
 
778
{
 
779
        Magicolor_Scanner *s = (Magicolor_Scanner *) handle;
 
780
        SANE_Status status;
 
781
        unsigned char *txbuf, rxbuf[8];
 
782
        size_t buflen;
 
783
        NOT_USED (format);
 
784
        NOT_USED (depth);
 
785
 
 
786
        DBG(8, "%s\n", __func__);
 
787
        buflen = mc_create_buffer (s, s->hw->cmd->scanner_cmd,
 
788
                                   s->hw->cmd->request_scan_parameters,
 
789
                                   &txbuf, NULL, 8, &status);
 
790
        if (buflen <= 0 ) {
 
791
                return SANE_STATUS_NO_MEM;
 
792
        } else if (status != SANE_STATUS_GOOD) {
 
793
                return status;
 
794
        }
 
795
 
 
796
        status = mc_txrx (s, txbuf, buflen, rxbuf, 8);
 
797
        free (txbuf);
 
798
        if (status != SANE_STATUS_GOOD)
 
799
                DBG(8, "%s: Parameters NOT successfully retrieved\n", __func__);
 
800
        else {
 
801
                DBG(8, "%s: Parameters successfully retrieved\n", __func__);
 
802
 
 
803
                /* Assign px_per_line and lines. Bytes 7-8 must match 3-4 */
 
804
                if (rxbuf[2]!=rxbuf[6] || rxbuf[3]!=rxbuf[7]) {
 
805
                        DBG (1, "%s: ERROR: Returned image parameters indicate an "
 
806
                                "unsupported device: Bytes 3-4 do not match "
 
807
                                "bytes 7-8! Trying to continue with bytes 3-4.\n",
 
808
                                __func__);
 
809
                        dump_hex_buffer_dense (1, rxbuf, 8);
 
810
                }
 
811
                /* Read returned values, encoded in 2-byte little endian */
 
812
                *data_pixels = rxbuf[1] * 0x100 + rxbuf[0];
 
813
                *lines = rxbuf[3] * 0x100 + rxbuf[2];
 
814
                *pixels_per_line = rxbuf[5] * 0x100 + rxbuf[4];
 
815
                DBG (8, "%s: data_pixels = 0x%x (%u), lines = 0x%x (%u), "
 
816
                        "pixels_per_line = 0x%x (%u)\n", __func__,
 
817
                        *data_pixels, *data_pixels,
 
818
                        *lines, *lines,
 
819
                        *pixels_per_line, *pixels_per_line);
 
820
        }
 
821
 
 
822
        return status;
 
823
}
 
824
 
 
825
/** 0x03 0c  - Set scanning parameters command */
 
826
static SANE_Status
 
827
cmd_set_scanning_parameters(SANE_Handle handle,
 
828
        unsigned char resolution, unsigned char color_mode,
 
829
        unsigned char brightness, unsigned char contrast,
 
830
        int tl_x, int tl_y, int width, int height, unsigned char source)
 
831
{
 
832
        Magicolor_Scanner *s = (Magicolor_Scanner *) handle;
 
833
        SANE_Status status;
 
834
        unsigned char param[0x11];
 
835
        unsigned char *buf;
 
836
        size_t buflen;
 
837
 
 
838
        DBG(8, "%s\n", __func__);
 
839
        /* Copy over the params to the param byte array */
 
840
        /* Byte structure:
 
841
         *   byte 0:     resolution
 
842
         *   byte 1:     color mode
 
843
         *   byte 2:     brightness
 
844
         *   byte 3:     0xff
 
845
         *   byte 4-5:   x-start
 
846
         *   byte 6-7:   y-start
 
847
         *   byte 8-9:  x-extent
 
848
         *   byte 10-11: y-extent
 
849
         *   byte 12:    source (ADF/FBF)
 
850
         **/
 
851
        memset (&param[0], 0x00, 0x11);
 
852
        param[0] = resolution;
 
853
        param[1] = color_mode;
 
854
        param[2] = brightness;
 
855
        param[3] = contrast | 0xff; /* TODO: Always 0xff? What about contrast? */
 
856
        /* Image coordinates are encoded 2-byte little endian: */
 
857
        param[4] = tl_x & 0xff;
 
858
        param[5] = (tl_x >> 8) & 0xff;
 
859
        param[6] = tl_y & 0xff;
 
860
        param[7] = (tl_y >> 8) & 0xff;
 
861
        param[8] = width & 0xff;
 
862
        param[9] = (width >> 8) & 0xff;
 
863
        param[10] = height & 0xff;
 
864
        param[11] = (height >> 8) & 0xff;
 
865
 
 
866
        param[12] = source;
 
867
 
 
868
        /* dump buffer if appropriate */
 
869
        DBG (127, "  Scanning parameter buffer:");
 
870
        dump_hex_buffer_dense (127, param, 0x11);
 
871
 
 
872
        buflen = mc_create_buffer (s, s->hw->cmd->scanner_cmd, s->hw->cmd->set_scan_parameters,
 
873
                                   &buf, param, 0x11, &status);
 
874
        if (buflen <= 0 ) {
 
875
                return SANE_STATUS_NO_MEM;
 
876
        } else if (status != SANE_STATUS_GOOD) {
 
877
                return status;
 
878
        }
 
879
 
 
880
        mc_send(s, buf, buflen, &status);
 
881
        free (buf);
 
882
        if (status != SANE_STATUS_GOOD)
 
883
                DBG(8, "%s: Data NOT successfully sent\n", __func__);
 
884
        else
 
885
                DBG(8, "%s: Data successfully sent\n", __func__);
 
886
        return status;
 
887
}
 
888
 
 
889
/** 0x03 ??  - Request push button status command */
 
890
#if 0
 
891
static SANE_Status
 
892
cmd_request_push_button_status(SANE_Handle handle, unsigned char *bstatus)
 
893
{
 
894
        Magicolor_Scanner *s = (Magicolor_Scanner *) handle;
 
895
        SANE_Status status;
 
896
        unsigned char *buf;
 
897
        size_t buflen;
 
898
 
 
899
        DBG(8, "%s\n", __func__);
 
900
 
 
901
 
 
902
        if (s->hw->cmd->unknown1 == 0)
 
903
                return SANE_STATUS_UNSUPPORTED;
 
904
 
 
905
        DBG(8, "%s: Supported\n", __func__);
 
906
        memset (bstatus, 0x00, 1);
 
907
        buflen = mc_create_buffer (s, s->hw->cmd->scanner_cmd, s->hw->cmd->unknown1,
 
908
                                   &buf, bstatus, 1, &status);
 
909
        if (buflen <= 0 ) {
 
910
                return SANE_STATUS_NO_MEM;
 
911
        } else if (status != SANE_STATUS_GOOD) {
 
912
                return status;
 
913
        }
 
914
 
 
915
        status = mc_txrx (s, buf, buflen, bstatus, 1);
 
916
        free(buf);
 
917
        if (status != SANE_STATUS_GOOD)
 
918
                return status;
 
919
 
 
920
        DBG(1, "push button status: %02x ", bstatus[0]);
 
921
        switch (bstatus[0]) {
 
922
                /* TODO: What's the response code for button pressed??? */
 
923
                default:
 
924
                        DBG(1, " unknown\n");
 
925
                        status = SANE_STATUS_UNSUPPORTED;
 
926
        }
 
927
        return status;
 
928
}
 
929
#endif
 
930
 
 
931
/** 0x03 0e  - Read data command */
 
932
static SANE_Status
 
933
cmd_read_data (SANE_Handle handle, unsigned char *buf, size_t len)
 
934
{
 
935
        Magicolor_Scanner *s = (Magicolor_Scanner *) handle;
 
936
        SANE_Status status;
 
937
        unsigned char *txbuf;
 
938
        unsigned char param[4];
 
939
        size_t txbuflen;
 
940
        int oldtimeout = MC_Request_Timeout;
 
941
 
 
942
        DBG(8, "%s\n", __func__);
 
943
        param[0] = len & 0xff;
 
944
        param[1] = (len >> 8) & 0xff;
 
945
        param[2] = (len >> 16) & 0xff;
 
946
        param[3] = (len >> 24) & 0xff;
 
947
 
 
948
        txbuflen = mc_create_buffer (s, s->hw->cmd->scanner_cmd, s->hw->cmd->request_data,
 
949
                                   &txbuf, param, 4, &status);
 
950
        if (txbuflen <= 0 ) {
 
951
                return SANE_STATUS_NO_MEM;
 
952
        } else if (status != SANE_STATUS_GOOD) {
 
953
                return status;
 
954
        }
 
955
 
 
956
        /* Temporarily set the poll timeout to 10 seconds instead of 2,
 
957
         * because a color scan needs >5 seconds to initialize. */
 
958
        MC_Request_Timeout = MC_Scan_Data_Timeout;
 
959
        status = mc_txrx (s, txbuf, txbuflen, buf, len);
 
960
        MC_Request_Timeout = oldtimeout;
 
961
        free (txbuf);
 
962
        if (status != SANE_STATUS_GOOD)
 
963
                DBG(8, "%s: Image data NOT successfully retrieved\n", __func__);
 
964
        else {
 
965
                DBG(8, "%s: Image data successfully retrieved\n", __func__);
 
966
        }
 
967
 
 
968
        return status;
 
969
}
 
970
 
 
971
 
 
972
 
 
973
/* TODO: 0x03 0f command (unknown), 0x03 10 command (set button wait) */
 
974
 
 
975
 
 
976
 
 
977
 
 
978
/****************************************************************************
 
979
 *   Magicolor backend high-level operations
 
980
 ****************************************************************************/
 
981
 
 
982
 
 
983
static void
 
984
mc_dev_init(Magicolor_Device *dev, const char *devname, int conntype)
 
985
{
 
986
        DBG(5, "%s\n", __func__);
 
987
 
 
988
        dev->name = NULL;
 
989
        dev->model = NULL;
 
990
        dev->connection = conntype;
 
991
        dev->sane.name = devname;
 
992
        dev->sane.model = NULL;
 
993
        dev->sane.type = "flatbed scanner";
 
994
        dev->sane.vendor = "Magicolor";
 
995
        dev->cap = &magicolor_cap[MAGICOLOR_CAP_DEFAULT];
 
996
        dev->cmd = &magicolor_cmd[MAGICOLOR_LEVEL_DEFAULT];
 
997
        /* Change default level when using a network connection */
 
998
        if (dev->connection == SANE_MAGICOLOR_NET)
 
999
                dev->cmd = &magicolor_cmd[MAGICOLOR_LEVEL_NET];
 
1000
}
 
1001
 
 
1002
static SANE_Status
 
1003
mc_dev_post_init(struct Magicolor_Device *dev)
 
1004
{
 
1005
        DBG(5, "%s\n", __func__);
 
1006
        NOT_USED (dev);
 
1007
        /* Correct device parameters if needed */
 
1008
        return SANE_STATUS_GOOD;
 
1009
}
 
1010
 
 
1011
static SANE_Status
 
1012
mc_set_model(Magicolor_Scanner * s, const char *model, size_t len)
 
1013
{
 
1014
        unsigned char *buf;
 
1015
        unsigned char *p;
 
1016
        struct Magicolor_Device *dev = s->hw;
 
1017
 
 
1018
        buf = malloc(len + 1);
 
1019
        if (buf == NULL)
 
1020
                return SANE_STATUS_NO_MEM;
 
1021
 
 
1022
        memcpy(buf, model, len);
 
1023
        buf[len] = '\0';
 
1024
 
 
1025
        p = &buf[len - 1];
 
1026
 
 
1027
        while (*p == ' ') {
 
1028
                *p = '\0';
 
1029
                p--;
 
1030
        }
 
1031
 
 
1032
        if (dev->model)
 
1033
                free(dev->model);
 
1034
 
 
1035
        dev->model = strndup((const char *) buf, len);
 
1036
        dev->sane.model = dev->model;
 
1037
        DBG(10, "%s: model is '%s'\n", __func__, dev->model);
 
1038
 
 
1039
        free(buf);
 
1040
 
 
1041
        return SANE_STATUS_GOOD;
 
1042
}
 
1043
 
 
1044
static void
 
1045
mc_set_device (SANE_Handle handle, unsigned int device)
 
1046
{
 
1047
        Magicolor_Scanner *s = (Magicolor_Scanner *) handle;
 
1048
        Magicolor_Device *dev = s->hw;
 
1049
        const char* cmd_level;
 
1050
        int n;
 
1051
 
 
1052
        DBG(1, "%s: 0x%x\n", __func__, device);
 
1053
 
 
1054
        for (n = 0; n < NELEMS (magicolor_cap); n++) {
 
1055
                if (magicolor_cap[n].id == device)
 
1056
                        break;
 
1057
        }
 
1058
        if (n < NELEMS(magicolor_cap)) {
 
1059
                dev->cap = &magicolor_cap[n];
 
1060
        } else {
 
1061
                dev->cap = &magicolor_cap[MAGICOLOR_CAP_DEFAULT];
 
1062
                DBG(1, " unknown device 0x%x, using default %s\n",
 
1063
                    device, dev->cap->model);
 
1064
        }
 
1065
        mc_set_model (s, dev->cap->model, strlen (dev->cap->model));
 
1066
 
 
1067
        cmd_level = dev->cap->cmds;
 
1068
        /* set command type and level */
 
1069
        for (n = 0; n < NELEMS(magicolor_cmd); n++) {
 
1070
                if (!strcmp(cmd_level, magicolor_cmd[n].level))
 
1071
                        break;
 
1072
        }
 
1073
 
 
1074
        if (n < NELEMS(magicolor_cmd)) {
 
1075
                dev->cmd = &magicolor_cmd[n];
 
1076
        } else {
 
1077
                dev->cmd = &magicolor_cmd[MAGICOLOR_LEVEL_DEFAULT];
 
1078
                DBG(1, " unknown command level %s, using %s\n",
 
1079
                    cmd_level, dev->cmd->level);
 
1080
        }
 
1081
}
 
1082
 
 
1083
static SANE_Status
 
1084
mc_discover_capabilities(Magicolor_Scanner *s)
 
1085
{
 
1086
        SANE_Status status;
 
1087
        Magicolor_Device *dev = s->hw;
 
1088
 
 
1089
        SANE_String_Const *source_list_add = source_list;
 
1090
 
 
1091
        DBG(5, "%s\n", __func__);
 
1092
 
 
1093
        /* always add flatbed */
 
1094
        *source_list_add++ = FBF_STR;
 
1095
        /* TODO: How can I check for existence of an ADF??? */
 
1096
        if (dev->cap->ADF)
 
1097
                *source_list_add++ = ADF_STR;
 
1098
 
 
1099
        /* TODO: Is there any capability that we can extract from the
 
1100
         *       device by some scanne command? So far, it looks like
 
1101
         *       the device does not support any reporting. I don't even
 
1102
         *       see a way to determine which device we are talking to!
 
1103
         */
 
1104
 
 
1105
 
 
1106
        /* request error status */
 
1107
        status = cmd_request_error(s);
 
1108
        if (status != SANE_STATUS_GOOD)
 
1109
                return status;
 
1110
 
 
1111
        dev->x_range = &dev->cap->fbf_x_range;
 
1112
        dev->y_range = &dev->cap->fbf_y_range;
 
1113
 
 
1114
        DBG(5, "   x-range: %f %f\n", SANE_UNFIX(dev->x_range->min), SANE_UNFIX(dev->x_range->max));
 
1115
        DBG(5, "   y-range: %f %f\n", SANE_UNFIX(dev->y_range->min), SANE_UNFIX(dev->y_range->max));
 
1116
 
 
1117
        DBG(5, "End of %s, status:%s\n", __func__, sane_strstatus(status));
 
1118
        *source_list_add = NULL; /* add end marker to source list */
 
1119
        return status;
 
1120
}
 
1121
 
 
1122
static SANE_Status
 
1123
mc_setup_block_mode (Magicolor_Scanner *s)
 
1124
{
 
1125
        /* block_len should always be a multiple of bytes_per_line, so
 
1126
         * we retrieve only whole lines at once */
 
1127
        s->block_len = (int)(0xff00/s->scan_bytes_per_line) * s->scan_bytes_per_line;
 
1128
        s->blocks = s->data_len / s->block_len;
 
1129
        s->last_len = s->data_len - (s->blocks * s->block_len);
 
1130
        if (s->last_len>0)
 
1131
                s->blocks++;
 
1132
        DBG(5, "%s: block_len=0x%x, last_len=0x%0x, blocks=%d\n", __func__, s->block_len, s->last_len, s->blocks);
 
1133
        s->counter = 0;
 
1134
        s->bytes_read_in_line = 0;
 
1135
        if (s->line_buffer)
 
1136
                free(s->line_buffer);
 
1137
        s->line_buffer = malloc(s->scan_bytes_per_line);
 
1138
        if (s->line_buffer == NULL) {
 
1139
                DBG(1, "out of memory (line %d)\n", __LINE__);
 
1140
                return SANE_STATUS_NO_MEM;
 
1141
        }
 
1142
 
 
1143
 
 
1144
        DBG (5, " %s: Setup block mode - scan_bytes_per_line=%d, pixels_per_line=%d, depth=%d, data_len=%x, block_len=%x, blocks=%d, last_len=%x\n",
 
1145
                __func__, s->scan_bytes_per_line, s->params.pixels_per_line, s->params.depth, s->data_len, s->block_len, s->blocks, s->last_len);
 
1146
        return SANE_STATUS_GOOD;
 
1147
}
 
1148
 
 
1149
/* Call the 0x03 0c command to set scanning parameters from the s->opt list */
 
1150
static SANE_Status
 
1151
mc_set_scanning_parameters(Magicolor_Scanner * s)
 
1152
{
 
1153
        SANE_Status status;
 
1154
        unsigned char rs, source, brightness;
 
1155
        struct mode_param *mparam = &mode_params[s->val[OPT_MODE].w];
 
1156
        SANE_Int scan_pixels_per_line = 0;
 
1157
 
 
1158
        DBG(1, "%s\n", __func__);
 
1159
 
 
1160
        /* Find the resolution in the res list and assign the index to buf[1] */
 
1161
        for (rs=0; rs < s->hw->cap->res_list_size; rs++ ) {
 
1162
                if ( s->val[OPT_RESOLUTION].w == s->hw->cap->res_list[rs] )
 
1163
                        break;
 
1164
        }
 
1165
 
 
1166
        if (SANE_OPTION_IS_ACTIVE(s->opt[OPT_BRIGHTNESS].cap)) {
 
1167
                brightness = s->val[OPT_BRIGHTNESS].w;
 
1168
        } else {
 
1169
                brightness = 5;
 
1170
        }
 
1171
 
 
1172
        /* ADF used? */
 
1173
        if (strcmp(source_list[s->val[OPT_SOURCE].w], ADF_STR) == 0) {
 
1174
                /* Use ADF */
 
1175
                source = 0x01;
 
1176
        } else {
 
1177
                source = 0x00;
 
1178
        }
 
1179
 
 
1180
        /* TODO: Any way to set PREVIEW??? */
 
1181
 
 
1182
        /* Remaining bytes unused */
 
1183
        status = cmd_set_scanning_parameters(s,
 
1184
                                             rs, mparam->flags,  /* res, color mode */
 
1185
                                             brightness, 0xff, /* brightness, contrast? */
 
1186
                                             s->left, s->top,  /* top/left start */
 
1187
                                             s->width, s->height, /* extent */
 
1188
                                             source); /* source */
 
1189
 
 
1190
        if (status != SANE_STATUS_GOOD)
 
1191
                DBG (2, "%s: Command cmd_set_scanning_parameters failed, %s\n",
 
1192
                     __func__, sane_strstatus(status));
 
1193
 
 
1194
        /* Now query the scanner for the current image parameters */
 
1195
        status = cmd_get_scanning_parameters (s,
 
1196
                        &s->params.format, &s->params.depth,
 
1197
                        &scan_pixels_per_line,
 
1198
                        &s->params.pixels_per_line, &s->params.lines);
 
1199
        if (status != SANE_STATUS_GOOD) {
 
1200
                DBG (2, "%s: Command cmd_get_scanning_parameters failed, %s\n",
 
1201
                     __func__, sane_strstatus(status));
 
1202
                return status;
 
1203
        }
 
1204
 
 
1205
        /* Calculate how many bytes are really used per line */
 
1206
        s->params.bytes_per_line = ceil (s->params.pixels_per_line * s->params.depth / 8.0);
 
1207
        if (s->val[OPT_MODE].w == MODE_COLOR)
 
1208
                s->params.bytes_per_line *= 3;
 
1209
 
 
1210
        /* Calculate how many bytes per line will be returned by the scanner.
 
1211
         * The values needed for this are returned by get_scannign_parameters */
 
1212
        s->scan_bytes_per_line = ceil (scan_pixels_per_line * s->params.depth / 8.0);
 
1213
        if (s->val[OPT_MODE].w == MODE_COLOR) {
 
1214
                s->scan_bytes_per_line *= 3;
 
1215
        }
 
1216
        s->data_len = s->params.lines * s->scan_bytes_per_line;
 
1217
 
 
1218
        status = mc_setup_block_mode (s);
 
1219
        if (status != SANE_STATUS_GOOD)
 
1220
                DBG (2, "%s: Command mc_setup_block_mode failed, %s\n",
 
1221
                     __func__, sane_strstatus(status));
 
1222
 
 
1223
        DBG (1, "%s: bytes_read  in line: %d\n", __func__, s->bytes_read_in_line);
 
1224
 
 
1225
        return status;
 
1226
}
 
1227
 
 
1228
static SANE_Status
 
1229
mc_check_adf(Magicolor_Scanner * s)
 
1230
{
 
1231
        SANE_Status status;
 
1232
        unsigned char buf[0x0b];
 
1233
 
 
1234
        DBG(5, "%s\n", __func__);
 
1235
 
 
1236
        status = cmd_request_status(s, buf);
 
1237
        if (status != SANE_STATUS_GOOD)
 
1238
                return status;
 
1239
 
 
1240
        if (!(buf[1] & ADF_LOADED))
 
1241
                return SANE_STATUS_NO_DOCS;
 
1242
 
 
1243
        /* TODO: Check for jam in ADF */
 
1244
        return SANE_STATUS_GOOD;
 
1245
}
 
1246
 
 
1247
static SANE_Status
 
1248
mc_scan_finish(Magicolor_Scanner * s)
 
1249
{
 
1250
        SANE_Status status;
 
1251
        DBG(5, "%s\n", __func__);
 
1252
 
 
1253
        /* If we have not yet read all data, cancel the scan */
 
1254
        if (s->buf && !s->eof)
 
1255
                status = cmd_cancel_scan (s);
 
1256
 
 
1257
        if (s->line_buffer)
 
1258
                free (s->line_buffer);
 
1259
        s->line_buffer = NULL;
 
1260
        free(s->buf);
 
1261
        s->buf = s->end = s->ptr = NULL;
 
1262
 
 
1263
        /* TODO: Any magicolor command for "scan finished"? */
 
1264
        status = cmd_finish_scan (s);
 
1265
 
 
1266
        status = cmd_request_error(s);
 
1267
        if (status != SANE_STATUS_GOOD)
 
1268
                cmd_cancel_scan (s);
 
1269
                return status;
 
1270
 
 
1271
        /* XXX required? */
 
1272
        /* TODO:        cmd_reset(s);*/
 
1273
        return SANE_STATUS_GOOD;
 
1274
}
 
1275
 
 
1276
static void
 
1277
mc_copy_image_data(Magicolor_Scanner * s, SANE_Byte * data, SANE_Int max_length,
 
1278
                   SANE_Int * length)
 
1279
{
 
1280
        DBG (1, "%s: bytes_read  in line: %d\n", __func__, s->bytes_read_in_line);
 
1281
        if (s->params.format == SANE_FRAME_RGB) {
 
1282
                SANE_Int bytes_available, scan_pixels_per_line = s->scan_bytes_per_line/3;
 
1283
                *length = 0;
 
1284
 
 
1285
                while ((max_length >= s->params.bytes_per_line) && (s->ptr < s->end)) {
 
1286
                        SANE_Int bytes_to_copy = s->scan_bytes_per_line - s->bytes_read_in_line;
 
1287
                        /* First, fill the line buffer for the current line: */
 
1288
                        bytes_available = (s->end - s->ptr);
 
1289
                        /* Don't copy more than we have buffer and available */
 
1290
                        if (bytes_to_copy > bytes_available)
 
1291
                                bytes_to_copy = bytes_available;
 
1292
 
 
1293
                        if (bytes_to_copy > 0) {
 
1294
                                memcpy (s->line_buffer + s->bytes_read_in_line, s->ptr, bytes_to_copy);
 
1295
                                s->ptr += bytes_to_copy;
 
1296
                                s->bytes_read_in_line += bytes_to_copy;
 
1297
                        }
 
1298
 
 
1299
                        /* We have filled as much as possible of the current line
 
1300
                         * with data from the scanner. If we have a complete line,
 
1301
                         * copy it over. */
 
1302
                        if ((s->bytes_read_in_line >= s->scan_bytes_per_line) &&
 
1303
                            (s->params.bytes_per_line <= max_length))
 
1304
                        {
 
1305
                                SANE_Int i;
 
1306
                                SANE_Byte *line = s->line_buffer;
 
1307
                                *length += s->params.bytes_per_line;
 
1308
                                for (i=0; i< s->params.pixels_per_line; ++i) {
 
1309
                                        *data++ = line[0];
 
1310
                                        *data++ = line[scan_pixels_per_line];
 
1311
                                        *data++ = line[2 * scan_pixels_per_line];
 
1312
                                        line++;
 
1313
                                }
 
1314
                                max_length -= s->params.bytes_per_line;
 
1315
                                s->bytes_read_in_line -= s->scan_bytes_per_line;
 
1316
                        }
 
1317
                }
 
1318
 
 
1319
        } else {
 
1320
                /* B/W and Grayscale use the same structure, so we use the same code */
 
1321
                SANE_Int bytes_available;
 
1322
                *length = 0;
 
1323
 
 
1324
                while ((max_length != 0) && (s->ptr < s->end)) {
 
1325
                        SANE_Int bytes_to_skip, bytes_to_copy;
 
1326
                        bytes_available = (s->end - s->ptr);
 
1327
                        bytes_to_copy = s->params.bytes_per_line - s->bytes_read_in_line;
 
1328
                        bytes_to_skip = s->scan_bytes_per_line - s->bytes_read_in_line;
 
1329
 
 
1330
                        /* Don't copy more than we have buffer */
 
1331
                        if (bytes_to_copy > max_length) {
 
1332
                                bytes_to_copy = max_length;
 
1333
                                bytes_to_skip = max_length;
 
1334
                        }
 
1335
 
 
1336
                        /* Don't copy/skip more bytes than we have read in */
 
1337
                        if (bytes_to_copy > bytes_available)
 
1338
                                bytes_to_copy = bytes_available;
 
1339
                        if (bytes_to_skip > bytes_available)
 
1340
                                bytes_to_skip = bytes_available;
 
1341
 
 
1342
                        if (bytes_to_copy > 0) {
 
1343
                                /* we have not yet copied all pixels of the line */
 
1344
                                memcpy (data, s->ptr, bytes_to_copy);
 
1345
                                max_length -= bytes_to_copy;
 
1346
                                *length += bytes_to_copy;
 
1347
                                data += bytes_to_copy;
 
1348
                        }
 
1349
                        if (bytes_to_skip > 0) {
 
1350
                                s->ptr += bytes_to_skip;
 
1351
                                s->bytes_read_in_line += bytes_to_skip;
 
1352
                        }
 
1353
                        if (s->bytes_read_in_line >= s->scan_bytes_per_line)
 
1354
                                s->bytes_read_in_line -= s->scan_bytes_per_line;
 
1355
 
 
1356
                }
 
1357
        }
 
1358
}
 
1359
 
 
1360
static SANE_Status
 
1361
mc_init_parameters(Magicolor_Scanner * s)
 
1362
{
 
1363
        int dpi, optres;
 
1364
        struct mode_param *mparam;
 
1365
 
 
1366
        DBG(5, "%s\n", __func__);
 
1367
 
 
1368
        memset(&s->params, 0, sizeof(SANE_Parameters));
 
1369
 
 
1370
        dpi = s->val[OPT_RESOLUTION].w;
 
1371
        optres = s->hw->cap->optical_res;
 
1372
 
 
1373
        mparam = &mode_params[s->val[OPT_MODE].w];
 
1374
 
 
1375
        if (SANE_UNFIX(s->val[OPT_BR_Y].w) == 0 ||
 
1376
                SANE_UNFIX(s->val[OPT_BR_X].w) == 0)
 
1377
                return SANE_STATUS_INVAL;
 
1378
 
 
1379
        /* TODO: Use OPT_RESOLUTION or fixed 600dpi for left/top/width/height? */
 
1380
        s->left = ((SANE_UNFIX(s->val[OPT_TL_X].w) / MM_PER_INCH) * optres) + 0.5;
 
1381
 
 
1382
        s->top = ((SANE_UNFIX(s->val[OPT_TL_Y].w) / MM_PER_INCH) * optres) + 0.5;
 
1383
 
 
1384
        s->width =
 
1385
                ((SANE_UNFIX(s->val[OPT_BR_X].w -
 
1386
                           s->val[OPT_TL_X].w) / MM_PER_INCH) * optres) + 0.5;
 
1387
 
 
1388
        s->height =
 
1389
                ((SANE_UNFIX(s->val[OPT_BR_Y].w -
 
1390
                           s->val[OPT_TL_Y].w) / MM_PER_INCH) * optres) + 0.5;
 
1391
 
 
1392
        s->params.pixels_per_line = s->width * dpi / optres + 0.5;
 
1393
        s->params.lines = s->height * dpi / optres + 0.5;
 
1394
 
 
1395
 
 
1396
        DBG(1, "%s: resolution = %d, preview = %d\n",
 
1397
                __func__, dpi, s->val[OPT_PREVIEW].w);
 
1398
 
 
1399
        DBG(1, "%s: %p %p tlx %f tly %f brx %f bry %f [mm]\n",
 
1400
            __func__, (void *) s, (void *) s->val,
 
1401
            SANE_UNFIX(s->val[OPT_TL_X].w), SANE_UNFIX(s->val[OPT_TL_Y].w),
 
1402
            SANE_UNFIX(s->val[OPT_BR_X].w), SANE_UNFIX(s->val[OPT_BR_Y].w));
 
1403
 
 
1404
        /*
 
1405
         * The default color depth is stored in mode_params.depth:
 
1406
         */
 
1407
        DBG(1, " %s, vor depth\n", __func__);
 
1408
 
 
1409
        if (mode_params[s->val[OPT_MODE].w].depth == 1)
 
1410
                s->params.depth = 1;
 
1411
        else
 
1412
                s->params.depth = s->val[OPT_BIT_DEPTH].w;
 
1413
 
 
1414
        s->params.last_frame = SANE_TRUE;
 
1415
 
 
1416
        s->params.bytes_per_line = ceil (s->params.depth * s->params.pixels_per_line / 8.0);
 
1417
 
 
1418
        switch (s->val[OPT_MODE].w) {
 
1419
        case MODE_BINARY:
 
1420
        case MODE_GRAY:
 
1421
                s->params.format = SANE_FRAME_GRAY;
 
1422
                break;
 
1423
        case MODE_COLOR:
 
1424
                s->params.format = SANE_FRAME_RGB;
 
1425
                s->params.bytes_per_line *= 3;
 
1426
                break;
 
1427
        }
 
1428
 
 
1429
 
 
1430
        DBG(1, "%s: Parameters are format=%d, bytes_per_line=%d, lines=%d\n", __func__, s->params.format, s->params.bytes_per_line, s->params.lines);
 
1431
        return (s->params.lines > 0) ? SANE_STATUS_GOOD : SANE_STATUS_INVAL;
 
1432
}
 
1433
 
 
1434
static SANE_Status
 
1435
mc_start_scan(Magicolor_Scanner * s)
 
1436
{
 
1437
        SANE_Status status = cmd_start_scan (s, s->data_len);
 
1438
        if (status != SANE_STATUS_GOOD ) {
 
1439
                DBG (1, "%s: starting the scan failed (%s)\n", __func__, sane_strstatus(status));
 
1440
        }
 
1441
        return status;
 
1442
}
 
1443
 
 
1444
static SANE_Status
 
1445
mc_read(struct Magicolor_Scanner *s)
 
1446
{
 
1447
        SANE_Status status = SANE_STATUS_GOOD;
 
1448
        ssize_t buf_len = 0;
 
1449
 
 
1450
        /* did we passed everything we read to sane? */
 
1451
        if (s->ptr == s->end) {
 
1452
 
 
1453
                if (s->eof)
 
1454
                        return SANE_STATUS_EOF;
 
1455
 
 
1456
                s->counter++;
 
1457
                buf_len = s->block_len;
 
1458
 
 
1459
                if (s->counter == s->blocks && s->last_len)
 
1460
                        buf_len = s->last_len;
 
1461
 
 
1462
                DBG(18, "%s: block %d/%d, size %lu\n", __func__,
 
1463
                        s->counter, s->blocks,
 
1464
                        (unsigned long) buf_len);
 
1465
 
 
1466
                /* receive image data + error code */
 
1467
                status = cmd_read_data (s, s->buf, buf_len);
 
1468
                if (status != SANE_STATUS_GOOD) {
 
1469
                        DBG (1, "%s: Receiving image data failed (%s)\n",
 
1470
                                        __func__, sane_strstatus(status));
 
1471
                        cmd_cancel_scan(s);
 
1472
                        return status;
 
1473
                }
 
1474
 
 
1475
                DBG(18, "%s: successfully read %lu bytes\n", __func__, (unsigned long) buf_len);
 
1476
 
 
1477
                if (s->counter < s->blocks) {
 
1478
                        if (s->canceling) {
 
1479
                                cmd_cancel_scan(s);
 
1480
                                return SANE_STATUS_CANCELLED;
 
1481
                        }
 
1482
                } else
 
1483
                        s->eof = SANE_TRUE;
 
1484
 
 
1485
                s->end = s->buf + buf_len;
 
1486
                s->ptr = s->buf;
 
1487
        }
 
1488
 
 
1489
        return status;
 
1490
}
 
1491
 
 
1492
 
 
1493
 
 
1494
 
 
1495
/****************************************************************************
 
1496
 *   SANE API implementation (high-level functions)
 
1497
 ****************************************************************************/
 
1498
 
 
1499
 
 
1500
static struct MagicolorCap *
 
1501
mc_get_device_from_identification (const char*ident)
 
1502
{
 
1503
        int n;
 
1504
        for (n = 0; n < NELEMS (magicolor_cap); n++) {
 
1505
                if (strcmp (magicolor_cap[n].model, ident) || strcmp (magicolor_cap[n].OID, ident))
 
1506
                        return &magicolor_cap[n];
 
1507
        }
 
1508
        return NULL;
 
1509
}
 
1510
 
 
1511
 
 
1512
/*
 
1513
 * close_scanner()
 
1514
 *
 
1515
 * Close the open scanner. Depending on the connection method, a different
 
1516
 * close function is called.
 
1517
 */
 
1518
static void
 
1519
close_scanner(Magicolor_Scanner *s)
 
1520
{
 
1521
        DBG(7, "%s: fd = %d\n", __func__, s->fd);
 
1522
 
 
1523
        if (s->fd == -1)
 
1524
                return;
 
1525
 
 
1526
        mc_scan_finish(s);
 
1527
        if (s->hw->connection == SANE_MAGICOLOR_NET) {
 
1528
                sanei_magicolor_net_close(s);
 
1529
                sanei_tcp_close(s->fd);
 
1530
        } else if (s->hw->connection == SANE_MAGICOLOR_USB) {
 
1531
                sanei_usb_close(s->fd);
 
1532
        }
 
1533
 
 
1534
        s->fd = -1;
 
1535
}
 
1536
 
 
1537
static SANE_Bool
 
1538
split_scanner_name (const char *name, char * IP, unsigned int *model)
 
1539
{
 
1540
        const char *device = name;
 
1541
        const char *qm;
 
1542
        *model = 0;
 
1543
        /* cut off leading net: */
 
1544
        if (strncmp(device, "net:", 4) == 0)
 
1545
                device = &device[4];
 
1546
 
 
1547
        qm = strchr(device, '?');
 
1548
        if (qm != NULL) {
 
1549
                size_t len = qm-device;
 
1550
                strncpy (IP, device, len);
 
1551
                IP[len] = '\0';
 
1552
                qm++;
 
1553
                if (strncmp(qm, "model=", 6) == 0) {
 
1554
                        qm += 6;
 
1555
                        if (!sscanf(qm, "0x%x", model))
 
1556
                                sscanf(qm, "%x", model);
 
1557
                }
 
1558
        } else {
 
1559
                strcpy (IP, device);
 
1560
        }
 
1561
        return SANE_TRUE;
 
1562
}
 
1563
 
 
1564
/*
 
1565
 * open_scanner()
 
1566
 *
 
1567
 * Open the scanner device. Depending on the connection method,
 
1568
 * different open functions are called.
 
1569
 */
 
1570
 
 
1571
static SANE_Status
 
1572
open_scanner(Magicolor_Scanner *s)
 
1573
{
 
1574
        SANE_Status status = 0;
 
1575
 
 
1576
        DBG(7, "%s: %s\n", __func__, s->hw->sane.name);
 
1577
 
 
1578
        if (s->fd != -1) {
 
1579
                DBG(7, "scanner is already open: fd = %d\n", s->fd);
 
1580
                return SANE_STATUS_GOOD;        /* no need to open the scanner */
 
1581
        }
 
1582
 
 
1583
        if (s->hw->connection == SANE_MAGICOLOR_NET) {
 
1584
                /* device name has the form net:ipaddr?model=... */
 
1585
                char IP[1024];
 
1586
                unsigned int model = 0;
 
1587
                if (!split_scanner_name (s->hw->sane.name, IP, &model))
 
1588
                        return SANE_STATUS_INVAL;
 
1589
                status = sanei_tcp_open(IP, 4567, &s->fd);
 
1590
                if (model>0)
 
1591
                        mc_set_device (s, model);
 
1592
                if (status == SANE_STATUS_GOOD) {
 
1593
                        DBG(7, "awaiting welcome message\n");
 
1594
                        status = sanei_magicolor_net_open (s);
 
1595
                }
 
1596
 
 
1597
        } else if (s->hw->connection == SANE_MAGICOLOR_USB) {
 
1598
                status = sanei_usb_open(s->hw->sane.name, &s->fd);
 
1599
                if (s->hw->cap->out_ep>0)
 
1600
                        sanei_usb_set_endpoint (s->fd,
 
1601
                                USB_DIR_OUT | USB_ENDPOINT_TYPE_BULK, s->hw->cap->out_ep);
 
1602
                if (s->hw->cap->in_ep>0)
 
1603
                        sanei_usb_set_endpoint (s->fd,
 
1604
                                USB_DIR_IN | USB_ENDPOINT_TYPE_BULK, s->hw->cap->in_ep);
 
1605
        }
 
1606
 
 
1607
        if (status == SANE_STATUS_ACCESS_DENIED) {
 
1608
                DBG(1, "please check that you have permissions on the device.\n");
 
1609
                DBG(1, "if this is a multi-function device with a printer,\n");
 
1610
                DBG(1, "disable any conflicting driver (like usblp).\n");
 
1611
        }
 
1612
 
 
1613
        if (status != SANE_STATUS_GOOD)
 
1614
                DBG(1, "%s open failed: %s\n", s->hw->sane.name,
 
1615
                        sane_strstatus(status));
 
1616
        else
 
1617
                DBG(3, "scanner opened\n");
 
1618
 
 
1619
        return status;
 
1620
}
 
1621
 
 
1622
static SANE_Status
 
1623
detect_usb(struct Magicolor_Scanner *s)
 
1624
{
 
1625
        SANE_Status status;
 
1626
        int vendor, product;
 
1627
        int i, numIds;
 
1628
        SANE_Bool is_valid;
 
1629
 
 
1630
        /* if the sanei_usb_get_vendor_product call is not supported,
 
1631
         * then we just ignore this and rely on the user to config
 
1632
         * the correct device.
 
1633
         */
 
1634
 
 
1635
        status = sanei_usb_get_vendor_product(s->fd, &vendor, &product);
 
1636
        if (status != SANE_STATUS_GOOD) {
 
1637
                DBG(1, "the device cannot be verified - will continue\n");
 
1638
                return SANE_STATUS_GOOD;
 
1639
        }
 
1640
 
 
1641
        /* check the vendor ID to see if we are dealing with an MAGICOLOR device */
 
1642
        if (vendor != SANE_MAGICOLOR_VENDOR_ID) {
 
1643
                /* this is not a supported vendor ID */
 
1644
                DBG(1, "not an Magicolor device at %s (vendor id=0x%x)\n",
 
1645
                    s->hw->sane.name, vendor);
 
1646
                return SANE_STATUS_INVAL;
 
1647
        }
 
1648
 
 
1649
        numIds = sanei_magicolor_getNumberOfUSBProductIds();
 
1650
        is_valid = SANE_FALSE;
 
1651
        i = 0;
 
1652
 
 
1653
        /* check all known product IDs to verify that we know
 
1654
         *         about the device */
 
1655
        while (i != numIds && !is_valid) {
 
1656
                if (product == sanei_magicolor_usb_product_ids[i])
 
1657
                        is_valid = SANE_TRUE;
 
1658
                i++;
 
1659
        }
 
1660
 
 
1661
        if (is_valid == SANE_FALSE) {
 
1662
                DBG(1, "the device at %s is not a supported (product id=0x%x)\n",
 
1663
                    s->hw->sane.name, product);
 
1664
                return SANE_STATUS_INVAL;
 
1665
        }
 
1666
 
 
1667
        DBG(2, "found valid Magicolor scanner: 0x%x/0x%x (vendorID/productID)\n",
 
1668
            vendor, product);
 
1669
 
 
1670
        return SANE_STATUS_GOOD;
 
1671
}
 
1672
 
 
1673
/*
 
1674
 * used by attach* and sane_get_devices
 
1675
 * a ptr to a single-linked list of Magicolor_Device structs
 
1676
 * a ptr to a null term array of ptrs to SANE_Device structs
 
1677
 */
 
1678
static int num_devices;         /* number of scanners attached to backend */
 
1679
static Magicolor_Device *first_dev;     /* first MAGICOLOR scanner in list */
 
1680
static const SANE_Device **devlist = NULL;
 
1681
 
 
1682
static struct Magicolor_Scanner *
 
1683
scanner_create(struct Magicolor_Device *dev, SANE_Status *status)
 
1684
{
 
1685
        struct Magicolor_Scanner *s;
 
1686
 
 
1687
        s = malloc(sizeof(struct Magicolor_Scanner));
 
1688
        if (s == NULL) {
 
1689
                *status = SANE_STATUS_NO_MEM;
 
1690
                return NULL;
 
1691
        }
 
1692
 
 
1693
        memset(s, 0x00, sizeof(struct Magicolor_Scanner));
 
1694
 
 
1695
        s->fd = -1;
 
1696
        s->hw = dev;
 
1697
 
 
1698
        return s;
 
1699
}
 
1700
 
 
1701
static struct Magicolor_Scanner *
 
1702
device_detect(const char *name, int type, SANE_Status *status)
 
1703
{
 
1704
        struct Magicolor_Scanner *s;
 
1705
        struct Magicolor_Device *dev;
 
1706
 
 
1707
        /* try to find the device in our list */
 
1708
        for (dev = first_dev; dev; dev = dev->next) {
 
1709
                if (strcmp(dev->sane.name, name) == 0) {
 
1710
                        dev->missing = 0;
 
1711
                        DBG (10, "%s: Device %s already attached!\n", __func__,
 
1712
                             name);
 
1713
                        return scanner_create(dev, status);
 
1714
                }
 
1715
        }
 
1716
 
 
1717
        if (type == SANE_MAGICOLOR_NODEV) {
 
1718
                *status = SANE_STATUS_INVAL;
 
1719
                return NULL;
 
1720
        }
 
1721
 
 
1722
        /* alloc and clear our device structure */
 
1723
        dev = malloc(sizeof(*dev));
 
1724
        if (!dev) {
 
1725
                *status = SANE_STATUS_NO_MEM;
 
1726
                return NULL;
 
1727
        }
 
1728
        memset(dev, 0x00, sizeof(struct Magicolor_Device));
 
1729
 
 
1730
        s = scanner_create(dev, status);
 
1731
        if (s == NULL)
 
1732
                return NULL;
 
1733
 
 
1734
        mc_dev_init(dev, name, type);
 
1735
 
 
1736
        *status = open_scanner(s);
 
1737
        if (*status != SANE_STATUS_GOOD) {
 
1738
                free(s);
 
1739
                return NULL;
 
1740
        }
 
1741
 
 
1742
        /* from now on, close_scanner() must be called */
 
1743
 
 
1744
        /* USB requires special care */
 
1745
        if (dev->connection == SANE_MAGICOLOR_USB) {
 
1746
                *status = detect_usb(s);
 
1747
        }
 
1748
 
 
1749
        if (*status != SANE_STATUS_GOOD)
 
1750
                goto close;
 
1751
 
 
1752
        /* set name and model (if not already set) */
 
1753
        if (dev->model == NULL)
 
1754
                mc_set_model(s, "generic", 7);
 
1755
 
 
1756
        dev->name = strdup(name);
 
1757
        dev->sane.name = dev->name;
 
1758
 
 
1759
        *status = mc_discover_capabilities(s);
 
1760
        if (*status != SANE_STATUS_GOOD)
 
1761
                goto close;
 
1762
 
 
1763
        if (source_list[0] == NULL || dev->cap->dpi_range.min == 0) {
 
1764
                DBG(1, "something is wrong in the discovery process, aborting.\n");
 
1765
                *status = SANE_STATUS_IO_ERROR;
 
1766
                goto close;
 
1767
        }
 
1768
 
 
1769
        mc_dev_post_init(dev);
 
1770
 
 
1771
        /* add this scanner to the device list */
 
1772
        num_devices++;
 
1773
        dev->missing = 0;
 
1774
        dev->next = first_dev;
 
1775
        first_dev = dev;
 
1776
 
 
1777
        return s;
 
1778
 
 
1779
        close:
 
1780
        close_scanner(s);
 
1781
        free(s);
 
1782
        return NULL;
 
1783
}
 
1784
 
 
1785
#if HAVE_LIBSNMP
 
1786
/** Handle one SNMP response (whether received sync or async) and if describes
 
1787
 * a magicolor device, attach it. Returns the number of attached devices (0
 
1788
 * or 1) */
 
1789
static int
 
1790
mc_network_discovery_handle (struct snmp_pdu *pdu)
 
1791
{
 
1792
        netsnmp_variable_list *varlist = pdu->variables, *vp;
 
1793
        oid anOID[MAX_OID_LEN];
 
1794
        size_t anOID_len = MAX_OID_LEN;
 
1795
        /* Device information variables */
 
1796
        char ip_addr[1024];
 
1797
        char model[1024];
 
1798
        char device[1024];
 
1799
        /* remote IP detection variables */
 
1800
        netsnmp_indexed_addr_pair *responder = (netsnmp_indexed_addr_pair *) pdu->transport_data;
 
1801
        struct sockaddr_in *remote = NULL;
 
1802
        struct MagicolorCap *cap;
 
1803
 
 
1804
        DBG(5, "%s: Handling SNMP response \n", __func__);
 
1805
 
 
1806
        if (responder == NULL || pdu->transport_data_length != sizeof(netsnmp_indexed_addr_pair )) {
 
1807
                DBG(1, "%s: Unable to extract IP address from SNMP response.\n",
 
1808
                    __func__);
 
1809
                return 0;
 
1810
        }
 
1811
        remote = (struct sockaddr_in *) &(responder->remote_addr);
 
1812
        if (remote == NULL) {
 
1813
                DBG(1, "%s: Unable to extract IP address from SNMP response.\n",
 
1814
                        __func__);
 
1815
                return 0;
 
1816
        }
 
1817
        snprintf(ip_addr, sizeof(ip_addr), "%s", inet_ntoa(remote->sin_addr));
 
1818
        DBG(35, "%s: IP Address of responder is %s\n", __func__, ip_addr);
 
1819
 
 
1820
        /* System Object ID (Unique OID identifying model)
 
1821
         * This determines whether we really have a magicolor device */
 
1822
        anOID_len = MAX_OID_LEN;
 
1823
        read_objid(MAGICOLOR_SNMP_SYSOBJECT_OID, anOID, &anOID_len);
 
1824
        vp = find_varbind_in_list (varlist, anOID, anOID_len);
 
1825
        if (vp) {
 
1826
                size_t value_len = vp->val_len/sizeof(oid);
 
1827
                if (vp->type != ASN_OBJECT_ID) {
 
1828
                        DBG (3, "%s: SystemObjectID does not return an OID, device is not a magicolor device\n", __func__);
 
1829
                        return 0;
 
1830
                }
 
1831
                snprint_objid (device, sizeof(device), vp->val.objid, value_len);
 
1832
                DBG (5, "%s: Device object ID is '%s'\n", __func__, device);
 
1833
 
 
1834
                anOID_len = MAX_OID_LEN;
 
1835
                read_objid (MAGICOLOR_SNMP_DEVICE_TREE, anOID, &anOID_len);
 
1836
                if (netsnmp_oid_is_subtree (anOID, anOID_len,
 
1837
                                vp->val.objid, value_len) == 0) {
 
1838
                        DBG (5, "%s: Device appears to be a magicolor device (OID=%s)\n", __func__, device);
 
1839
                } else {
 
1840
                        DBG (5, "%s: Device is not a Magicolor device\n", __func__);
 
1841
                        return 0;
 
1842
                }
 
1843
        }
 
1844
 
 
1845
        /* Retrieve sysDescr (i.e. model name) */
 
1846
        anOID_len = MAX_OID_LEN;
 
1847
        read_objid(MAGICOLOR_SNMP_SYSDESCR_OID, anOID, &anOID_len);
 
1848
        vp = find_varbind_in_list (varlist, anOID, anOID_len);
 
1849
        if (vp) {
 
1850
                memcpy(model,vp->val.string,vp->val_len);
 
1851
                model[vp->val_len] = '\0';
 
1852
                DBG (5, "%s: Found model: %s\n", __func__, model);
 
1853
        }
 
1854
 
 
1855
        DBG (1, "%s: Detected device '%s' on IP %s\n",
 
1856
             __func__, model, ip_addr);
 
1857
 
 
1858
        vp = pdu->variables;
 
1859
        /* TODO: attach the IP with attach_one_net(ip) */
 
1860
        cap = mc_get_device_from_identification (device);
 
1861
        if (cap) {
 
1862
                DBG(1, "%s: Found autodiscovered device: %s (type 0x%x)\n", __func__, cap->model, cap->id);
 
1863
                attach_one_net (ip_addr, cap->id);
 
1864
                return 1;
 
1865
        }
 
1866
        return 0;
 
1867
}
 
1868
 
 
1869
static int
 
1870
mc_network_discovery_cb (int operation, struct snmp_session *sp, int reqid,
 
1871
                         struct snmp_pdu *pdu, void *magic)
 
1872
{
 
1873
        NOT_USED (reqid);
 
1874
        NOT_USED (sp);
 
1875
        DBG(5, "%s: Received broadcast response \n", __func__);
 
1876
 
 
1877
        if (operation == NETSNMP_CALLBACK_OP_RECEIVED_MESSAGE) {
 
1878
                int nr = mc_network_discovery_handle (pdu);
 
1879
                int *m = (int*)magic;
 
1880
                *m += nr;
 
1881
                DBG(5, "%s: Added %d discovered host(s) for SNMP response.\n", __func__, nr);
 
1882
        }
 
1883
 
 
1884
        return 1;
 
1885
}
 
1886
#endif
 
1887
 
 
1888
/* Use SNMP for automatic network discovery. If host is given, try to detect
 
1889
 * that one host (using sync SNMP, otherwise send an SNMP broadcast (async).
 
1890
 */
 
1891
static int
 
1892
mc_network_discovery(const char*host)
 
1893
{
 
1894
#if HAVE_LIBSNMP
 
1895
        netsnmp_session session, *ss;
 
1896
        netsnmp_pdu *pdu;
 
1897
        oid anOID[MAX_OID_LEN];
 
1898
        size_t anOID_len = MAX_OID_LEN;
 
1899
        int nr = 0; /* Nr of added hosts */
 
1900
 
 
1901
 
 
1902
        DBG(1, "%s: running network discovery \n", __func__);
 
1903
 
 
1904
        /* Win32: init winsock */
 
1905
        SOCK_STARTUP;
 
1906
        init_snmp("sane-magicolor-backend");
 
1907
        snmp_sess_init (&session);
 
1908
        session.version = SNMP_VERSION_2c;
 
1909
        session.community = "public";
 
1910
        session.community_len = strlen (session.community);
 
1911
        if (host) {
 
1912
                session.peername = host;
 
1913
        } else {
 
1914
                /* Do a network discovery via a broadcast */
 
1915
                session.peername = "255.255.255.255";
 
1916
                session.flags   |= SNMP_FLAGS_UDP_BROADCAST;
 
1917
                session.callback = mc_network_discovery_cb;
 
1918
                session.callback_magic = &nr;
 
1919
        }
 
1920
 
 
1921
        ss = snmp_open (&session); /* establish the session */
 
1922
        if (!ss) {
 
1923
                snmp_sess_perror ("ack", &session);
 
1924
                SOCK_CLEANUP;
 
1925
                return 0;
 
1926
        }
 
1927
 
 
1928
        /* Create the PDU for the data for our request and add the three
 
1929
         * desired OIDs to the PDU */
 
1930
        pdu = snmp_pdu_create (SNMP_MSG_GET);
 
1931
 
 
1932
        /* SNMPv2-MIB::sysDescr.0 */
 
1933
        anOID_len = MAX_OID_LEN;
 
1934
        if (read_objid(MAGICOLOR_SNMP_SYSDESCR_OID, anOID, &anOID_len)) {
 
1935
                snmp_add_null_var (pdu, anOID, anOID_len);
 
1936
        }
 
1937
        /* SNMPv2-MIB::sysObjectID.0 */
 
1938
        anOID_len = MAX_OID_LEN;
 
1939
        if (read_objid(MAGICOLOR_SNMP_SYSOBJECT_OID, anOID, &anOID_len)) {
 
1940
                snmp_add_null_var (pdu, anOID, anOID_len);
 
1941
        }
 
1942
        /* IF-MIB::ifPhysAddress.1 */
 
1943
        anOID_len = MAX_OID_LEN;
 
1944
        if (read_objid(MAGICOLOR_SNMP_MAC_OID, anOID, &anOID_len)) {
 
1945
                snmp_add_null_var (pdu, anOID, anOID_len);
 
1946
        }
 
1947
        /* TODO: Add more interesting OIDs, in particular vendor OIDs */
 
1948
 
 
1949
        /* Now send out the request and wait for responses for some time.
 
1950
         * If we get a response, connect to that device (in the callback),
 
1951
         * otherwise we probably don't have a magicolor device in the
 
1952
         * LAN (or SNMP is turned off, in which case we have no way to detect
 
1953
         * it.
 
1954
         */
 
1955
        DBG(100, "%s: Sending SNMP packet\n", __func__);
 
1956
        if (host) {
 
1957
                /* sync request to given hostname, immediately read the reply */
 
1958
                netsnmp_pdu *response = 0;
 
1959
                int status = snmp_synch_response(ss, pdu, &response);
 
1960
                if (status == STAT_SUCCESS && response->errstat == SNMP_ERR_NOERROR) {
 
1961
                        nr = mc_network_discovery_handle (response);
 
1962
                }
 
1963
                if (response)
 
1964
                        snmp_free_pdu(response);
 
1965
 
 
1966
 
 
1967
        } else {
 
1968
                /* No hostname, so do a broadcast */
 
1969
                struct timeval nowtime, endtime; /* end time for SNMP scan */
 
1970
                struct timeval timeout;
 
1971
                int i=0;
 
1972
 
 
1973
                if (!snmp_send(ss, pdu)) {
 
1974
                        snmp_free_pdu(pdu);
 
1975
                        DBG(100, "%s: Sending SNMP packet NOT successful\n", __func__);
 
1976
                        return 0;
 
1977
                }
 
1978
                /* listen for responses for MC_AutoDetectionTimeout milliseconds: */
 
1979
                /* First get the final timeout time */
 
1980
                gettimeofday (&nowtime, NULL);
 
1981
                timeout.tv_sec = MC_SNMP_Timeout / 1000;
 
1982
                timeout.tv_usec = (MC_SNMP_Timeout % 1000) * 1000;
 
1983
                timeradd (&nowtime, &timeout, &endtime);
 
1984
 
 
1985
                while (timercmp(&nowtime, &endtime, <)) {
 
1986
                        int fds = 0, block = 0;
 
1987
                        fd_set fdset;
 
1988
                        DBG(1, "    loop=%d\n", i++);
 
1989
                        timeout.tv_sec = 0;
 
1990
                        /* Use a 125ms timeout for select. If we get a response, 
 
1991
                         * the loop will be entered earlier again, anyway */
 
1992
                        timeout.tv_usec = 125000;
 
1993
                        FD_ZERO (&fdset);
 
1994
                        snmp_select_info (&fds, &fdset, &timeout, &block);
 
1995
                        fds = select (fds, &fdset, NULL, NULL, /*block?NULL:*/&timeout);
 
1996
                        if (fds) snmp_read(&fdset);
 
1997
                        else snmp_timeout();
 
1998
                        gettimeofday(&nowtime, NULL);
 
1999
                }
 
2000
        }
 
2001
 
 
2002
        /* Clean up */
 
2003
        snmp_close(ss);
 
2004
        SOCK_CLEANUP;
 
2005
        DBG (5, "%s: Discovered %d host(s)\n", __func__, nr);
 
2006
        return nr;
 
2007
 
 
2008
#else
 
2009
        DBG (1, "%s: net-snmp library not enabled, auto-detecting network scanners not supported.\n", __func__);
 
2010
        NOT_USED (host);
 
2011
        return 0;
 
2012
#endif
 
2013
}
 
2014
 
 
2015
static SANE_Status
 
2016
attach(const char *name, int type)
 
2017
{
 
2018
        SANE_Status status;
 
2019
        Magicolor_Scanner *s;
 
2020
 
 
2021
        DBG(7, "%s: devname = %s, type = %d\n", __func__, name, type);
 
2022
 
 
2023
        s = device_detect(name, type, &status);
 
2024
        if(s == NULL)
 
2025
                return status;
 
2026
 
 
2027
        close_scanner(s);
 
2028
        free(s);
 
2029
        return status;
 
2030
}
 
2031
 
 
2032
SANE_Status
 
2033
attach_one_usb(const char *dev)
 
2034
{
 
2035
        DBG(7, "%s: dev = %s\n", __func__, dev);
 
2036
        return attach(dev, SANE_MAGICOLOR_USB);
 
2037
}
 
2038
 
 
2039
static SANE_Status
 
2040
attach_one_net(const char *dev, unsigned int model)
 
2041
{
 
2042
        char name[1024];
 
2043
 
 
2044
        DBG(7, "%s: dev = %s\n", __func__, dev);
 
2045
        if (model > 0) {
 
2046
                snprintf(name, 1024, "net:%s?model=0x%x", dev, model);
 
2047
        } else {
 
2048
                snprintf(name, 1024, "net:%s", dev);
 
2049
        }
 
2050
 
 
2051
        return attach(name, SANE_MAGICOLOR_NET);
 
2052
}
 
2053
 
 
2054
static SANE_Status
 
2055
attach_one_config(SANEI_Config __sane_unused__ *config, const char *line)
 
2056
{
 
2057
        int vendor, product, timeout;
 
2058
 
 
2059
        int len = strlen(line);
 
2060
 
 
2061
        DBG(7, "%s: len = %d, line = %s\n", __func__, len, line);
 
2062
 
 
2063
        if (sscanf(line, "usb %i %i", &vendor, &product) == 2) {
 
2064
                /* add the vendor and product IDs to the list of
 
2065
                 *                 known devices before we call the attach function */
 
2066
 
 
2067
                int numIds = sanei_magicolor_getNumberOfUSBProductIds();
 
2068
 
 
2069
                if (vendor != SANE_MAGICOLOR_VENDOR_ID)
 
2070
                        return SANE_STATUS_INVAL; /* this is not a KONICA MINOLTA device */
 
2071
 
 
2072
                sanei_magicolor_usb_product_ids[numIds - 1] = product;
 
2073
                sanei_usb_attach_matching_devices(line, attach_one_usb);
 
2074
 
 
2075
        } else if (strncmp(line, "usb", 3) == 0 && len == 3) {
 
2076
                int i, numIds;
 
2077
 
 
2078
                numIds = sanei_magicolor_getNumberOfUSBProductIds();
 
2079
 
 
2080
                for (i = 0; i < numIds; i++) {
 
2081
                        sanei_usb_find_devices(SANE_MAGICOLOR_VENDOR_ID,
 
2082
                                               sanei_magicolor_usb_product_ids[i], attach_one_usb);
 
2083
                }
 
2084
 
 
2085
        } else if (strncmp(line, "net", 3) == 0) {
 
2086
 
 
2087
                /* remove the "net" sub string */
 
2088
                const char *name = sanei_config_skip_whitespace(line + 3);
 
2089
                char IP[1024];
 
2090
                unsigned int model = 0;
 
2091
 
 
2092
                if (strncmp(name, "autodiscovery", 13) == 0) {
 
2093
                        DBG (50, "%s: Initiating network autodiscovervy via SNMP\n", __func__);
 
2094
                        mc_network_discovery(NULL);
 
2095
                } else if (sscanf(name, "%s %x", IP, &model) == 2) {
 
2096
                        DBG(50, "%s: Using network device on IP %s, forcing model 0x%x\n", __func__, IP, model);
 
2097
                        attach_one_net(IP, model);
 
2098
                } else {
 
2099
                        /* use SNMP to detect the type. If not successful,
 
2100
                         * add the host with model type 0 */
 
2101
                        DBG(50, "%s: Using network device on IP %s, trying to autodetect model\n", __func__, IP);
 
2102
                        if (mc_network_discovery(name)==0) {
 
2103
                                DBG(1, "%s: Autodetecting device model failed, using default model\n", __func__);
 
2104
                                attach_one_net(name, 0);
 
2105
                        }
 
2106
                }
 
2107
 
 
2108
        } else if (sscanf(line, "snmp-timeout %i\n", &timeout)) {
 
2109
                /* Timeout for SNMP network discovery */
 
2110
                DBG(50, "%s: SNMP timeout set to %d\n", __func__, timeout);
 
2111
                MC_SNMP_Timeout = timeout;
 
2112
 
 
2113
        } else if (sscanf(line, "scan-data-timeout %i\n", &timeout)) {
 
2114
                /* Timeout for scan data requests */
 
2115
                DBG(50, "%s: Scan data timeout set to %d\n", __func__, timeout);
 
2116
                MC_Scan_Data_Timeout = timeout;
 
2117
 
 
2118
        } else if (sscanf(line, "request-timeout %i\n", &timeout)) {
 
2119
                /* Timeout for all other read requests */
 
2120
                DBG(50, "%s: Request timeout set to %d\n", __func__, timeout);
 
2121
                MC_Request_Timeout = timeout;
 
2122
        
 
2123
        } else {
 
2124
                /* TODO: Warning about unparsable line! */
 
2125
        }
 
2126
 
 
2127
        return SANE_STATUS_GOOD;
 
2128
}
 
2129
 
 
2130
static void
 
2131
free_devices(void)
 
2132
{
 
2133
        Magicolor_Device *dev, *next;
 
2134
 
 
2135
        DBG(5, "%s\n", __func__);
 
2136
 
 
2137
        for (dev = first_dev; dev; dev = next) {
 
2138
                next = dev->next;
 
2139
                free(dev->name);
 
2140
                free(dev->model);
 
2141
                free(dev);
 
2142
        }
 
2143
 
 
2144
        if (devlist)
 
2145
                free(devlist);
 
2146
        devlist = NULL;
 
2147
        first_dev = NULL;
 
2148
}
 
2149
 
 
2150
SANE_Status
 
2151
sane_init(SANE_Int *version_code, SANE_Auth_Callback __sane_unused__ authorize)
 
2152
{
 
2153
        DBG_INIT();
 
2154
        DBG(2, "%s: " PACKAGE " " VERSION "\n", __func__);
 
2155
 
 
2156
        DBG(1, "magicolor backend, version %i.%i.%i\n",
 
2157
            MAGICOLOR_VERSION, MAGICOLOR_REVISION, MAGICOLOR_BUILD);
 
2158
 
 
2159
        if (version_code != NULL)
 
2160
                *version_code = SANE_VERSION_CODE(SANE_CURRENT_MAJOR, V_MINOR,
 
2161
                                                  MAGICOLOR_BUILD);
 
2162
 
 
2163
        sanei_usb_init();
 
2164
 
 
2165
        return SANE_STATUS_GOOD;
 
2166
}
 
2167
 
 
2168
/* Clean up the list of attached scanners. */
 
2169
void
 
2170
sane_exit(void)
 
2171
{
 
2172
        DBG(5, "%s\n", __func__);
 
2173
        free_devices();
 
2174
}
 
2175
 
 
2176
SANE_Status
 
2177
sane_get_devices(const SANE_Device ***device_list, SANE_Bool __sane_unused__ local_only)
 
2178
{
 
2179
        Magicolor_Device *dev, *s, *prev=0;
 
2180
        int i;
 
2181
 
 
2182
        DBG(5, "%s\n", __func__);
 
2183
 
 
2184
        sanei_usb_init();
 
2185
 
 
2186
        /* mark all existing scanners as missing, attach_one will remove mark */
 
2187
        for (s = first_dev; s; s = s->next) {
 
2188
                s->missing = 1;
 
2189
        }
 
2190
 
 
2191
        /* Read the config, mark each device as found, possibly add new devs */
 
2192
        sanei_configure_attach(MAGICOLOR_CONFIG_FILE, NULL,
 
2193
                               attach_one_config);
 
2194
 
 
2195
        /*delete missing scanners from list*/
 
2196
        for (s = first_dev; s;) {
 
2197
                if (s->missing) {
 
2198
                        DBG (5, "%s: missing scanner %s\n", __func__, s->name);
 
2199
 
 
2200
                        /*splice s out of list by changing pointer in prev to next*/
 
2201
                        if (prev) {
 
2202
                                prev->next = s->next;
 
2203
                                free (s);
 
2204
                                s = prev->next;
 
2205
                                num_devices--;
 
2206
                        } else {
 
2207
                                /*remove s from head of list */
 
2208
                                first_dev = s->next;
 
2209
                                free(s);
 
2210
                                s = first_dev;
 
2211
                                prev=NULL;
 
2212
                                num_devices--;
 
2213
                        }
 
2214
                } else {
 
2215
                        prev = s;
 
2216
                        s = prev->next;
 
2217
                }
 
2218
        }
 
2219
 
 
2220
        DBG (15, "%s: found %d scanner(s)\n", __func__, num_devices);
 
2221
        for (s = first_dev; s; s=s->next) {
 
2222
                DBG (15, "%s: found scanner %s\n", __func__, s->name);
 
2223
        }
 
2224
 
 
2225
        if (devlist)
 
2226
                free (devlist);
 
2227
 
 
2228
        devlist = malloc((num_devices + 1) * sizeof(devlist[0]));
 
2229
        if (!devlist) {
 
2230
                DBG(1, "out of memory (line %d)\n", __LINE__);
 
2231
                return SANE_STATUS_NO_MEM;
 
2232
        }
 
2233
 
 
2234
        DBG(5, "%s - results:\n", __func__);
 
2235
 
 
2236
        for (i = 0, dev = first_dev; i < num_devices && dev; dev = dev->next, i++) {
 
2237
                DBG(1, " %d (%d): %s\n", i, dev->connection, dev->model);
 
2238
                devlist[i] = &dev->sane;
 
2239
        }
 
2240
 
 
2241
        devlist[i] = NULL;
 
2242
 
 
2243
        if(device_list){
 
2244
                *device_list = devlist;
 
2245
        }
 
2246
 
 
2247
        return SANE_STATUS_GOOD;
 
2248
}
 
2249
 
 
2250
static SANE_Status
 
2251
init_options(Magicolor_Scanner *s)
 
2252
{
 
2253
        int i;
 
2254
        SANE_Word *res_list;
 
2255
 
 
2256
        for (i = 0; i < NUM_OPTIONS; i++) {
 
2257
                s->opt[i].size = sizeof(SANE_Word);
 
2258
                s->opt[i].cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT;
 
2259
        }
 
2260
 
 
2261
        s->opt[OPT_NUM_OPTS].title = SANE_TITLE_NUM_OPTIONS;
 
2262
        s->opt[OPT_NUM_OPTS].desc = SANE_DESC_NUM_OPTIONS;
 
2263
        s->opt[OPT_NUM_OPTS].type = SANE_TYPE_INT;
 
2264
        s->opt[OPT_NUM_OPTS].cap = SANE_CAP_SOFT_DETECT;
 
2265
        s->val[OPT_NUM_OPTS].w = NUM_OPTIONS;
 
2266
 
 
2267
        /* "Scan Mode" group: */
 
2268
 
 
2269
        s->opt[OPT_MODE_GROUP].name = SANE_NAME_STANDARD;
 
2270
        s->opt[OPT_MODE_GROUP].title = SANE_TITLE_STANDARD;
 
2271
        s->opt[OPT_MODE_GROUP].desc = SANE_DESC_STANDARD;
 
2272
        s->opt[OPT_MODE_GROUP].type = SANE_TYPE_GROUP;
 
2273
        s->opt[OPT_MODE_GROUP].cap = 0;
 
2274
 
 
2275
        /* scan mode */
 
2276
        s->opt[OPT_MODE].name = SANE_NAME_SCAN_MODE;
 
2277
        s->opt[OPT_MODE].title = SANE_TITLE_SCAN_MODE;
 
2278
        s->opt[OPT_MODE].desc = SANE_DESC_SCAN_MODE;
 
2279
        s->opt[OPT_MODE].type = SANE_TYPE_STRING;
 
2280
        s->opt[OPT_MODE].size = max_string_size(mode_list);
 
2281
        s->opt[OPT_MODE].constraint_type = SANE_CONSTRAINT_STRING_LIST;
 
2282
        s->opt[OPT_MODE].constraint.string_list = mode_list;
 
2283
        s->val[OPT_MODE].w = 0; /* Binary */
 
2284
 
 
2285
        /* bit depth */
 
2286
        s->opt[OPT_BIT_DEPTH].name = SANE_NAME_BIT_DEPTH;
 
2287
        s->opt[OPT_BIT_DEPTH].title = SANE_TITLE_BIT_DEPTH;
 
2288
        s->opt[OPT_BIT_DEPTH].desc = SANE_DESC_BIT_DEPTH;
 
2289
        s->opt[OPT_BIT_DEPTH].type = SANE_TYPE_INT;
 
2290
        s->opt[OPT_BIT_DEPTH].unit = SANE_UNIT_NONE;
 
2291
        s->opt[OPT_BIT_DEPTH].constraint_type = SANE_CONSTRAINT_WORD_LIST;
 
2292
        s->opt[OPT_BIT_DEPTH].constraint.word_list = s->hw->cap->depth_list;
 
2293
        s->opt[OPT_BIT_DEPTH].cap |= SANE_CAP_INACTIVE;
 
2294
        s->val[OPT_BIT_DEPTH].w = s->hw->cap->depth_list[1];    /* the first "real" element is the default */
 
2295
 
 
2296
        if (s->hw->cap->depth_list[0] == 1)     /* only one element in the list -> hide the option */
 
2297
                s->opt[OPT_BIT_DEPTH].cap |= SANE_CAP_INACTIVE;
 
2298
 
 
2299
 
 
2300
        /* brightness */
 
2301
        s->opt[OPT_BRIGHTNESS].name = SANE_NAME_BRIGHTNESS;
 
2302
        s->opt[OPT_BRIGHTNESS].title = SANE_TITLE_BRIGHTNESS;
 
2303
        s->opt[OPT_BRIGHTNESS].desc = SANE_DESC_BRIGHTNESS;
 
2304
        s->opt[OPT_BRIGHTNESS].type = SANE_TYPE_INT;
 
2305
        s->opt[OPT_BRIGHTNESS].unit = SANE_UNIT_NONE;
 
2306
        s->opt[OPT_BRIGHTNESS].constraint_type = SANE_CONSTRAINT_RANGE;
 
2307
        s->opt[OPT_BRIGHTNESS].constraint.range = &s->hw->cap->brightness;
 
2308
        s->val[OPT_BRIGHTNESS].w = 5;   /* Normal */
 
2309
 
 
2310
        /* resolution */
 
2311
        s->opt[OPT_RESOLUTION].name = SANE_NAME_SCAN_RESOLUTION;
 
2312
        s->opt[OPT_RESOLUTION].title = SANE_TITLE_SCAN_RESOLUTION;
 
2313
        s->opt[OPT_RESOLUTION].desc = SANE_DESC_SCAN_RESOLUTION;
 
2314
        s->opt[OPT_RESOLUTION].type = SANE_TYPE_INT;
 
2315
        s->opt[OPT_RESOLUTION].unit = SANE_UNIT_DPI;
 
2316
        s->opt[OPT_RESOLUTION].constraint_type = SANE_CONSTRAINT_WORD_LIST;
 
2317
        res_list = malloc((s->hw->cap->res_list_size + 1) * sizeof(SANE_Word));
 
2318
        if (res_list == NULL) {
 
2319
                return SANE_STATUS_NO_MEM;
 
2320
        }
 
2321
        *(res_list) = s->hw->cap->res_list_size;
 
2322
        memcpy(&(res_list[1]), s->hw->cap->res_list, s->hw->cap->res_list_size * sizeof(SANE_Word));
 
2323
        s->opt[OPT_RESOLUTION].constraint.word_list = res_list;
 
2324
        s->val[OPT_RESOLUTION].w = s->hw->cap->dpi_range.min;
 
2325
 
 
2326
 
 
2327
        /* preview */
 
2328
        s->opt[OPT_PREVIEW].name = SANE_NAME_PREVIEW;
 
2329
        s->opt[OPT_PREVIEW].title = SANE_TITLE_PREVIEW;
 
2330
        s->opt[OPT_PREVIEW].desc = SANE_DESC_PREVIEW;
 
2331
        s->opt[OPT_PREVIEW].type = SANE_TYPE_BOOL;
 
2332
        s->val[OPT_PREVIEW].w = SANE_FALSE;
 
2333
 
 
2334
        /* source */
 
2335
        s->opt[OPT_SOURCE].name = SANE_NAME_SCAN_SOURCE;
 
2336
        s->opt[OPT_SOURCE].title = SANE_TITLE_SCAN_SOURCE;
 
2337
        s->opt[OPT_SOURCE].desc = SANE_DESC_SCAN_SOURCE;
 
2338
        s->opt[OPT_SOURCE].type = SANE_TYPE_STRING;
 
2339
        s->opt[OPT_SOURCE].size = max_string_size(source_list);
 
2340
        s->opt[OPT_SOURCE].constraint_type = SANE_CONSTRAINT_STRING_LIST;
 
2341
        s->opt[OPT_SOURCE].constraint.string_list = source_list;
 
2342
        s->val[OPT_SOURCE].w = 0;       /* always use Flatbed as default */
 
2343
        
 
2344
        s->opt[OPT_ADF_MODE].name = "adf-mode";
 
2345
        s->opt[OPT_ADF_MODE].title = SANE_I18N("ADF Mode");
 
2346
        s->opt[OPT_ADF_MODE].desc =
 
2347
        SANE_I18N("Selects the ADF mode (simplex/duplex)");
 
2348
        s->opt[OPT_ADF_MODE].type = SANE_TYPE_STRING;
 
2349
        s->opt[OPT_ADF_MODE].size = max_string_size(adf_mode_list);
 
2350
        s->opt[OPT_ADF_MODE].constraint_type = SANE_CONSTRAINT_STRING_LIST;
 
2351
        s->opt[OPT_ADF_MODE].constraint.string_list = adf_mode_list;
 
2352
        s->val[OPT_ADF_MODE].w = 0;     /* simplex */
 
2353
        if ((!s->hw->cap->ADF) || (s->hw->cap->adf_duplex == SANE_FALSE))
 
2354
                s->opt[OPT_ADF_MODE].cap |= SANE_CAP_INACTIVE;
 
2355
 
 
2356
 
 
2357
        /* "Geometry" group: */
 
2358
        s->opt[OPT_GEOMETRY_GROUP].name = SANE_NAME_GEOMETRY;
 
2359
        s->opt[OPT_GEOMETRY_GROUP].title = SANE_TITLE_GEOMETRY;
 
2360
        s->opt[OPT_GEOMETRY_GROUP].desc = SANE_DESC_GEOMETRY;
 
2361
        s->opt[OPT_GEOMETRY_GROUP].type = SANE_TYPE_GROUP;
 
2362
        s->opt[OPT_GEOMETRY_GROUP].cap = SANE_CAP_ADVANCED;
 
2363
 
 
2364
        /* top-left x */
 
2365
        s->opt[OPT_TL_X].name = SANE_NAME_SCAN_TL_X;
 
2366
        s->opt[OPT_TL_X].title = SANE_TITLE_SCAN_TL_X;
 
2367
        s->opt[OPT_TL_X].desc = SANE_DESC_SCAN_TL_X;
 
2368
        s->opt[OPT_TL_X].type = SANE_TYPE_FIXED;
 
2369
        s->opt[OPT_TL_X].unit = SANE_UNIT_MM;
 
2370
        s->opt[OPT_TL_X].constraint_type = SANE_CONSTRAINT_RANGE;
 
2371
        s->opt[OPT_TL_X].constraint.range = s->hw->x_range;
 
2372
        s->val[OPT_TL_X].w = 0;
 
2373
 
 
2374
        /* top-left y */
 
2375
        s->opt[OPT_TL_Y].name = SANE_NAME_SCAN_TL_Y;
 
2376
        s->opt[OPT_TL_Y].title = SANE_TITLE_SCAN_TL_Y;
 
2377
        s->opt[OPT_TL_Y].desc = SANE_DESC_SCAN_TL_Y;
 
2378
        s->opt[OPT_TL_Y].type = SANE_TYPE_FIXED;
 
2379
        s->opt[OPT_TL_Y].unit = SANE_UNIT_MM;
 
2380
        s->opt[OPT_TL_Y].constraint_type = SANE_CONSTRAINT_RANGE;
 
2381
        s->opt[OPT_TL_Y].constraint.range = s->hw->y_range;
 
2382
        s->val[OPT_TL_Y].w = 0;
 
2383
 
 
2384
        /* bottom-right x */
 
2385
        s->opt[OPT_BR_X].name = SANE_NAME_SCAN_BR_X;
 
2386
        s->opt[OPT_BR_X].title = SANE_TITLE_SCAN_BR_X;
 
2387
        s->opt[OPT_BR_X].desc = SANE_DESC_SCAN_BR_X;
 
2388
        s->opt[OPT_BR_X].type = SANE_TYPE_FIXED;
 
2389
        s->opt[OPT_BR_X].unit = SANE_UNIT_MM;
 
2390
        s->opt[OPT_BR_X].constraint_type = SANE_CONSTRAINT_RANGE;
 
2391
        s->opt[OPT_BR_X].constraint.range = s->hw->x_range;
 
2392
        s->val[OPT_BR_X].w = s->hw->x_range->max;
 
2393
 
 
2394
        /* bottom-right y */
 
2395
        s->opt[OPT_BR_Y].name = SANE_NAME_SCAN_BR_Y;
 
2396
        s->opt[OPT_BR_Y].title = SANE_TITLE_SCAN_BR_Y;
 
2397
        s->opt[OPT_BR_Y].desc = SANE_DESC_SCAN_BR_Y;
 
2398
        s->opt[OPT_BR_Y].type = SANE_TYPE_FIXED;
 
2399
        s->opt[OPT_BR_Y].unit = SANE_UNIT_MM;
 
2400
        s->opt[OPT_BR_Y].constraint_type = SANE_CONSTRAINT_RANGE;
 
2401
        s->opt[OPT_BR_Y].constraint.range = s->hw->y_range;
 
2402
        s->val[OPT_BR_Y].w = s->hw->y_range->max;
 
2403
 
 
2404
        return SANE_STATUS_GOOD;
 
2405
}
 
2406
 
 
2407
SANE_Status
 
2408
sane_open(SANE_String_Const name, SANE_Handle *handle)
 
2409
{
 
2410
        SANE_Status status;
 
2411
        Magicolor_Scanner *s = NULL;
 
2412
 
 
2413
        int l = strlen(name);
 
2414
 
 
2415
        DBG(7, "%s: name = %s\n", __func__, name);
 
2416
 
 
2417
        /* probe if empty device name provided */
 
2418
        if (l == 0) {
 
2419
 
 
2420
                status = sane_get_devices(NULL,0);
 
2421
                if (status != SANE_STATUS_GOOD) {
 
2422
                        return status;
 
2423
                }
 
2424
 
 
2425
                if (first_dev == NULL) {
 
2426
                        DBG(1, "no device detected\n");
 
2427
                        return SANE_STATUS_INVAL;
 
2428
                }
 
2429
 
 
2430
                s = device_detect(first_dev->sane.name, first_dev->connection,
 
2431
                                        &status);
 
2432
                if (s == NULL) {
 
2433
                        DBG(1, "cannot open a perfectly valid device (%s),"
 
2434
                                " please report to the authors\n", name);
 
2435
                        return SANE_STATUS_INVAL;
 
2436
                }
 
2437
 
 
2438
        } else {
 
2439
 
 
2440
                if (strncmp(name, "net:", 4) == 0) {
 
2441
                        s = device_detect(name, SANE_MAGICOLOR_NET, &status);
 
2442
                        if (s == NULL)
 
2443
                                return status;
 
2444
                } else if (strncmp(name, "libusb:", 7) == 0) {
 
2445
                        s = device_detect(name, SANE_MAGICOLOR_USB, &status);
 
2446
                        if (s == NULL)
 
2447
                                return status;
 
2448
                } else {
 
2449
 
 
2450
                        /* as a last resort, check for a match
 
2451
                         * in the device list. This should handle platforms without libusb.
 
2452
                         */
 
2453
                        if (first_dev == NULL) {
 
2454
                                status = sane_get_devices(NULL,0);
 
2455
                                if (status != SANE_STATUS_GOOD) {
 
2456
                                        return status;
 
2457
                                }
 
2458
                        }
 
2459
 
 
2460
                        s = device_detect(name, SANE_MAGICOLOR_NODEV, &status);
 
2461
                        if (s == NULL) {
 
2462
                                DBG(1, "invalid device name: %s\n", name);
 
2463
                                return SANE_STATUS_INVAL;
 
2464
                        }
 
2465
                }
 
2466
        }
 
2467
 
 
2468
 
 
2469
        /* s is always valid here */
 
2470
 
 
2471
        DBG(1, "handle obtained\n");
 
2472
 
 
2473
        init_options(s);
 
2474
 
 
2475
        *handle = (SANE_Handle) s;
 
2476
 
 
2477
        status = open_scanner(s);
 
2478
        if (status != SANE_STATUS_GOOD) {
 
2479
                free(s);
 
2480
                return status;
 
2481
        }
 
2482
 
 
2483
        return status;
 
2484
}
 
2485
 
 
2486
void
 
2487
sane_close(SANE_Handle handle)
 
2488
{
 
2489
        Magicolor_Scanner *s;
 
2490
 
 
2491
        /*
 
2492
         * XXX Test if there is still data pending from
 
2493
         * the scanner. If so, then do a cancel
 
2494
         */
 
2495
 
 
2496
        s = (Magicolor_Scanner *) handle;
 
2497
 
 
2498
        if (s->fd != -1)
 
2499
                close_scanner(s);
 
2500
 
 
2501
        free(s);
 
2502
}
 
2503
 
 
2504
const SANE_Option_Descriptor *
 
2505
sane_get_option_descriptor(SANE_Handle handle, SANE_Int option)
 
2506
{
 
2507
        Magicolor_Scanner *s = (Magicolor_Scanner *) handle;
 
2508
 
 
2509
        if (option < 0 || option >= NUM_OPTIONS)
 
2510
                return NULL;
 
2511
 
 
2512
        return s->opt + option;
 
2513
}
 
2514
 
 
2515
static const SANE_String_Const *
 
2516
search_string_list(const SANE_String_Const *list, SANE_String value)
 
2517
{
 
2518
        while (*list != NULL && strcmp(value, *list) != 0)
 
2519
                list++;
 
2520
 
 
2521
        return ((*list == NULL) ? NULL : list);
 
2522
}
 
2523
 
 
2524
/*
 
2525
    Activate, deactivate an option. Subroutines so we can add
 
2526
    debugging info if we want. The change flag is set to TRUE
 
2527
    if we changed an option. If we did not change an option,
 
2528
    then the value of the changed flag is not modified.
 
2529
*/
 
2530
 
 
2531
static void
 
2532
activateOption(Magicolor_Scanner *s, SANE_Int option, SANE_Bool *change)
 
2533
{
 
2534
        if (!SANE_OPTION_IS_ACTIVE(s->opt[option].cap)) {
 
2535
                s->opt[option].cap &= ~SANE_CAP_INACTIVE;
 
2536
                *change = SANE_TRUE;
 
2537
        }
 
2538
}
 
2539
 
 
2540
static void
 
2541
deactivateOption(Magicolor_Scanner *s, SANE_Int option, SANE_Bool *change)
 
2542
{
 
2543
        if (SANE_OPTION_IS_ACTIVE(s->opt[option].cap)) {
 
2544
                s->opt[option].cap |= SANE_CAP_INACTIVE;
 
2545
                *change = SANE_TRUE;
 
2546
        }
 
2547
}
 
2548
 
 
2549
static SANE_Status
 
2550
getvalue(SANE_Handle handle, SANE_Int option, void *value)
 
2551
{
 
2552
        Magicolor_Scanner *s = (Magicolor_Scanner *) handle;
 
2553
        SANE_Option_Descriptor *sopt = &(s->opt[option]);
 
2554
        Option_Value *sval = &(s->val[option]);
 
2555
 
 
2556
        DBG(17, "%s: option = %d\n", __func__, option);
 
2557
 
 
2558
        switch (option) {
 
2559
 
 
2560
        case OPT_NUM_OPTS:
 
2561
        case OPT_BIT_DEPTH:
 
2562
        case OPT_BRIGHTNESS:
 
2563
        case OPT_RESOLUTION:
 
2564
        case OPT_PREVIEW:
 
2565
        case OPT_TL_X:
 
2566
        case OPT_TL_Y:
 
2567
        case OPT_BR_X:
 
2568
        case OPT_BR_Y:
 
2569
                *((SANE_Word *) value) = sval->w;
 
2570
                break;
 
2571
 
 
2572
        case OPT_MODE:
 
2573
        case OPT_SOURCE:
 
2574
        case OPT_ADF_MODE:
 
2575
                strcpy((char *) value, sopt->constraint.string_list[sval->w]);
 
2576
                break;
 
2577
 
 
2578
        default:
 
2579
                return SANE_STATUS_INVAL;
 
2580
        }
 
2581
 
 
2582
        return SANE_STATUS_GOOD;
 
2583
}
 
2584
 
 
2585
 
 
2586
/*
 
2587
 * Handles setting the source (flatbed, or auto document feeder (ADF)).
 
2588
 *
 
2589
 */
 
2590
 
 
2591
static void
 
2592
change_source(Magicolor_Scanner *s, SANE_Int optindex, char *value)
 
2593
{
 
2594
        int force_max = SANE_FALSE;
 
2595
        SANE_Bool dummy;
 
2596
 
 
2597
        DBG(1, "%s: optindex = %d, source = '%s'\n", __func__, optindex,
 
2598
            value);
 
2599
 
 
2600
        if (s->val[OPT_SOURCE].w == optindex)
 
2601
                return;
 
2602
 
 
2603
        s->val[OPT_SOURCE].w = optindex;
 
2604
 
 
2605
        if (s->val[OPT_TL_X].w == s->hw->x_range->min
 
2606
            && s->val[OPT_TL_Y].w == s->hw->y_range->min
 
2607
            && s->val[OPT_BR_X].w == s->hw->x_range->max
 
2608
            && s->val[OPT_BR_Y].w == s->hw->y_range->max) {
 
2609
                force_max = SANE_TRUE;
 
2610
        }
 
2611
 
 
2612
        if (strcmp(ADF_STR, value) == 0) {
 
2613
                s->hw->x_range = &s->hw->cap->adf_x_range;
 
2614
                s->hw->y_range = &s->hw->cap->adf_y_range;
 
2615
                if (s->hw->cap->adf_duplex) {
 
2616
                        activateOption(s, OPT_ADF_MODE, &dummy);
 
2617
                } else {
 
2618
                        deactivateOption(s, OPT_ADF_MODE, &dummy);
 
2619
                        s->val[OPT_ADF_MODE].w = 0;
 
2620
                }
 
2621
 
 
2622
                DBG(1, "adf activated (%d)\n",s->hw->cap->adf_duplex);
 
2623
 
 
2624
        } else {
 
2625
                /* ADF not active */
 
2626
                s->hw->x_range = &s->hw->cap->fbf_x_range;
 
2627
                s->hw->y_range = &s->hw->cap->fbf_y_range;
 
2628
 
 
2629
                deactivateOption(s, OPT_ADF_MODE, &dummy);
 
2630
        }
 
2631
 
 
2632
        s->opt[OPT_BR_X].constraint.range = s->hw->x_range;
 
2633
        s->opt[OPT_BR_Y].constraint.range = s->hw->y_range;
 
2634
 
 
2635
        if (s->val[OPT_TL_X].w < s->hw->x_range->min || force_max)
 
2636
                s->val[OPT_TL_X].w = s->hw->x_range->min;
 
2637
 
 
2638
        if (s->val[OPT_TL_Y].w < s->hw->y_range->min || force_max)
 
2639
                s->val[OPT_TL_Y].w = s->hw->y_range->min;
 
2640
 
 
2641
        if (s->val[OPT_BR_X].w > s->hw->x_range->max || force_max)
 
2642
                s->val[OPT_BR_X].w = s->hw->x_range->max;
 
2643
 
 
2644
        if (s->val[OPT_BR_Y].w > s->hw->y_range->max || force_max)
 
2645
                s->val[OPT_BR_Y].w = s->hw->y_range->max;
 
2646
 
 
2647
}
 
2648
 
 
2649
static SANE_Status
 
2650
setvalue(SANE_Handle handle, SANE_Int option, void *value, SANE_Int *info)
 
2651
{
 
2652
        Magicolor_Scanner *s = (Magicolor_Scanner *) handle;
 
2653
        SANE_Option_Descriptor *sopt = &(s->opt[option]);
 
2654
        Option_Value *sval = &(s->val[option]);
 
2655
 
 
2656
        SANE_Status status;
 
2657
        const SANE_String_Const *optval = NULL;
 
2658
        int optindex = 0;
 
2659
        SANE_Bool reload = SANE_FALSE;
 
2660
 
 
2661
        DBG(17, "%s: option = %d, value = %p, as word: %d\n", __func__, option, value, *(SANE_Word *) value);
 
2662
 
 
2663
        status = sanei_constrain_value(sopt, value, info);
 
2664
        if (status != SANE_STATUS_GOOD)
 
2665
                return status;
 
2666
 
 
2667
        if (info && value && (*info & SANE_INFO_INEXACT)
 
2668
            && sopt->type == SANE_TYPE_INT)
 
2669
                DBG(17, "%s: constrained val = %d\n", __func__,
 
2670
                    *(SANE_Word *) value);
 
2671
 
 
2672
        if (sopt->constraint_type == SANE_CONSTRAINT_STRING_LIST) {
 
2673
                optval = search_string_list(sopt->constraint.string_list,
 
2674
                                            (char *) value);
 
2675
                if (optval == NULL)
 
2676
                        return SANE_STATUS_INVAL;
 
2677
                optindex = optval - sopt->constraint.string_list;
 
2678
        }
 
2679
 
 
2680
        switch (option) {
 
2681
 
 
2682
        case OPT_MODE:
 
2683
        {
 
2684
                sval->w = optindex;
 
2685
                /* if binary, then disable the bit depth selection */
 
2686
                if (optindex == 0) {
 
2687
                        s->opt[OPT_BIT_DEPTH].cap |= SANE_CAP_INACTIVE;
 
2688
                } else {
 
2689
                        if (s->hw->cap->depth_list[0] == 1)
 
2690
                                s->opt[OPT_BIT_DEPTH].cap |=
 
2691
                                        SANE_CAP_INACTIVE;
 
2692
                        else {
 
2693
                                s->opt[OPT_BIT_DEPTH].cap &=
 
2694
                                        ~SANE_CAP_INACTIVE;
 
2695
                                s->val[OPT_BIT_DEPTH].w =
 
2696
                                        mode_params[optindex].depth;
 
2697
                        }
 
2698
                }
 
2699
                reload = SANE_TRUE;
 
2700
                break;
 
2701
        }
 
2702
 
 
2703
        case OPT_BIT_DEPTH:
 
2704
                sval->w = *((SANE_Word *) value);
 
2705
                mode_params[s->val[OPT_MODE].w].depth = sval->w;
 
2706
                reload = SANE_TRUE;
 
2707
                break;
 
2708
 
 
2709
        case OPT_RESOLUTION:
 
2710
                sval->w = *((SANE_Word *) value);
 
2711
                DBG(17, "setting resolution to %d\n", sval->w);
 
2712
                reload = SANE_TRUE;
 
2713
                break;
 
2714
 
 
2715
        case OPT_BR_X:
 
2716
        case OPT_BR_Y:
 
2717
                sval->w = *((SANE_Word *) value);
 
2718
                if (SANE_UNFIX(sval->w) == 0) {
 
2719
                        DBG(17, "invalid br-x or br-y\n");
 
2720
                        return SANE_STATUS_INVAL;
 
2721
                }
 
2722
                /* passthru */
 
2723
        case OPT_TL_X:
 
2724
        case OPT_TL_Y:
 
2725
                sval->w = *((SANE_Word *) value);
 
2726
                DBG(17, "setting size to %f\n", SANE_UNFIX(sval->w));
 
2727
                if (NULL != info)
 
2728
                        *info |= SANE_INFO_RELOAD_PARAMS;
 
2729
                break;
 
2730
 
 
2731
        case OPT_SOURCE:
 
2732
                change_source(s, optindex, (char *) value);
 
2733
                reload = SANE_TRUE;
 
2734
                break;
 
2735
 
 
2736
        case OPT_ADF_MODE:
 
2737
                sval->w = optindex;     /* Simple lists */
 
2738
                break;
 
2739
 
 
2740
        case OPT_BRIGHTNESS:
 
2741
        case OPT_PREVIEW:       /* needed? */
 
2742
                sval->w = *((SANE_Word *) value);
 
2743
                break;
 
2744
 
 
2745
        default:
 
2746
                return SANE_STATUS_INVAL;
 
2747
        }
 
2748
 
 
2749
        if (reload && info != NULL)
 
2750
                *info |= SANE_INFO_RELOAD_OPTIONS | SANE_INFO_RELOAD_PARAMS;
 
2751
 
 
2752
        DBG(17, "%s: end\n", __func__);
 
2753
 
 
2754
        return SANE_STATUS_GOOD;
 
2755
}
 
2756
 
 
2757
SANE_Status
 
2758
sane_control_option(SANE_Handle handle, SANE_Int option, SANE_Action action,
 
2759
                    void *value, SANE_Int *info)
 
2760
{
 
2761
        DBG(17, "%s: action = %x, option = %d\n", __func__, action, option);
 
2762
 
 
2763
        if (option < 0 || option >= NUM_OPTIONS)
 
2764
                return SANE_STATUS_INVAL;
 
2765
 
 
2766
        if (info != NULL)
 
2767
                *info = 0;
 
2768
 
 
2769
        switch (action) {
 
2770
        case SANE_ACTION_GET_VALUE:
 
2771
                return getvalue(handle, option, value);
 
2772
 
 
2773
        case SANE_ACTION_SET_VALUE:
 
2774
                return setvalue(handle, option, value, info);
 
2775
 
 
2776
        default:
 
2777
                return SANE_STATUS_INVAL;
 
2778
        }
 
2779
 
 
2780
        return SANE_STATUS_INVAL;
 
2781
}
 
2782
 
 
2783
SANE_Status
 
2784
sane_get_parameters(SANE_Handle handle, SANE_Parameters *params)
 
2785
{
 
2786
        Magicolor_Scanner *s = (Magicolor_Scanner *) handle;
 
2787
 
 
2788
        DBG(5, "%s\n", __func__);
 
2789
 
 
2790
        if (params == NULL)
 
2791
                DBG(1, "%s: params is NULL\n", __func__);
 
2792
 
 
2793
        /*
 
2794
         * If sane_start was already called, then just retrieve the parameters
 
2795
         * from the scanner data structure
 
2796
         */
 
2797
 
 
2798
        if (!s->eof && s->ptr != NULL) {
 
2799
                DBG(5, "scan in progress, returning saved params structure\n");
 
2800
        } else {
 
2801
                /* otherwise initialize the params structure and gather the data */
 
2802
                mc_init_parameters(s);
 
2803
        }
 
2804
 
 
2805
        if (params != NULL)
 
2806
                *params = s->params;
 
2807
 
 
2808
        print_params(s->params);
 
2809
 
 
2810
        return SANE_STATUS_GOOD;
 
2811
}
 
2812
 
 
2813
/*
 
2814
 * This function is part of the SANE API and gets called from the front end to
 
2815
 * start the scan process.
 
2816
 */
 
2817
 
 
2818
SANE_Status
 
2819
sane_start(SANE_Handle handle)
 
2820
{
 
2821
        Magicolor_Scanner *s = (Magicolor_Scanner *) handle;
 
2822
        SANE_Status status;
 
2823
 
 
2824
        DBG(5, "%s\n", __func__);
 
2825
 
 
2826
        /* calc scanning parameters */
 
2827
        status = mc_init_parameters(s);
 
2828
        if (status != SANE_STATUS_GOOD)
 
2829
                return status;
 
2830
 
 
2831
        print_params(s->params);
 
2832
 
 
2833
        /* set scanning parameters; also query the current image
 
2834
         * parameters from the sanner and save
 
2835
         * them to s->params */
 
2836
        status = mc_set_scanning_parameters(s);
 
2837
 
 
2838
        if (status != SANE_STATUS_GOOD)
 
2839
                return status;
 
2840
 
 
2841
        /* if we scan from ADF, check if it is loaded */
 
2842
        if (strcmp(source_list[s->val[OPT_SOURCE].w], ADF_STR) == 0) {
 
2843
                status = mc_check_adf(s);
 
2844
                if (status != SANE_STATUS_GOOD)
 
2845
                        return status;
 
2846
        }
 
2847
 
 
2848
        /* prepare buffer here so that a memory allocation failure
 
2849
         * will leave the scanner in a sane state.
 
2850
         */
 
2851
        s->buf = realloc(s->buf, s->block_len);
 
2852
        if (s->buf == NULL)
 
2853
                return SANE_STATUS_NO_MEM;
 
2854
 
 
2855
        s->eof = SANE_FALSE;
 
2856
        s->ptr = s->end = s->buf;
 
2857
        s->canceling = SANE_FALSE;
 
2858
 
 
2859
        /* start scanning */
 
2860
        DBG(1, "%s: scanning...\n", __func__);
 
2861
 
 
2862
        status = mc_start_scan(s);
 
2863
 
 
2864
        if (status != SANE_STATUS_GOOD) {
 
2865
                DBG(1, "%s: start failed: %s\n", __func__,
 
2866
                    sane_strstatus(status));
 
2867
 
 
2868
                return status;
 
2869
        }
 
2870
 
 
2871
        return status;
 
2872
}
 
2873
 
 
2874
/* this moves data from our buffers to SANE */
 
2875
 
 
2876
SANE_Status
 
2877
sane_read(SANE_Handle handle, SANE_Byte *data, SANE_Int max_length,
 
2878
          SANE_Int *length)
 
2879
{
 
2880
        SANE_Status status;
 
2881
        Magicolor_Scanner *s = (Magicolor_Scanner *) handle;
 
2882
 
 
2883
        if (s->buf == NULL || s->canceling)
 
2884
                return SANE_STATUS_CANCELLED;
 
2885
 
 
2886
        *length = 0;
 
2887
 
 
2888
        status = mc_read(s);
 
2889
 
 
2890
        if (status == SANE_STATUS_CANCELLED) {
 
2891
                mc_scan_finish(s);
 
2892
                return status;
 
2893
        }
 
2894
 
 
2895
        DBG(18, "moving data %p %p, %d (%d lines)\n",
 
2896
                s->ptr, s->end,
 
2897
                max_length, max_length / s->params.bytes_per_line);
 
2898
 
 
2899
        mc_copy_image_data(s, data, max_length, length);
 
2900
 
 
2901
        DBG(18, "%d lines read, status: %d\n",
 
2902
                *length / s->params.bytes_per_line, status);
 
2903
 
 
2904
        /* continue reading if appropriate */
 
2905
        if (status == SANE_STATUS_GOOD)
 
2906
                return status;
 
2907
 
 
2908
        mc_scan_finish(s);
 
2909
 
 
2910
        return status;
 
2911
}
 
2912
 
 
2913
/*
 
2914
 * void sane_cancel(SANE_Handle handle)
 
2915
 *
 
2916
 * Set the cancel flag to true. The next time the backend requests data
 
2917
 * from the scanner the CAN message will be sent.
 
2918
 */
 
2919
 
 
2920
void
 
2921
sane_cancel(SANE_Handle handle)
 
2922
{
 
2923
        Magicolor_Scanner *s = (Magicolor_Scanner *) handle;
 
2924
 
 
2925
        s->canceling = SANE_TRUE;
 
2926
}
 
2927
 
 
2928
/*
 
2929
 * SANE_Status sane_set_io_mode()
 
2930
 *
 
2931
 * not supported - for asynchronous I/O
 
2932
 */
 
2933
 
 
2934
SANE_Status
 
2935
sane_set_io_mode(SANE_Handle __sane_unused__ handle,
 
2936
        SANE_Bool __sane_unused__ non_blocking)
 
2937
{
 
2938
        return SANE_STATUS_UNSUPPORTED;
 
2939
}
 
2940
 
 
2941
/*
 
2942
 * SANE_Status sane_get_select_fd()
 
2943
 *
 
2944
 * not supported - for asynchronous I/O
 
2945
 */
 
2946
 
 
2947
SANE_Status
 
2948
sane_get_select_fd(SANE_Handle __sane_unused__ handle,
 
2949
        SANE_Int __sane_unused__ *fd)
 
2950
{
 
2951
        return SANE_STATUS_UNSUPPORTED;
 
2952
}