kopia lustrzana https://gitlab.com/sane-project/backends
2000-11-20 Henning Meier-Geinitz <hmg@gmx.de>
* AUTHORS: Added Eugene S. Weiss. * PROJECTS: Removed Artec as6e backend. * README: Added link to man sane-as6e.5. * TODO: Removed as6e. * doc/Makefile.in: Added generation of as6e manpage. * backend/Makefile.in: Added entries for as6e. * backend/dll.conf: Added as6e. * backend/as6e.c backend/as6e.h backend/as6e.desc doc/sane-as6e.man: Added backend for Artec AS6E parallel port scanner (from Eugene S. Weiss <yossarian@users.sourceforge.net>).DEVEL_2_0_BRANCH-1
rodzic
f0d5bc32ea
commit
32d8b87c92
2
AUTHORS
2
AUTHORS
|
@ -12,6 +12,7 @@ Backends:
|
||||||
agfafocus: Karl Anders Øygard
|
agfafocus: Karl Anders Øygard
|
||||||
apple: Milon Firikis
|
apple: Milon Firikis
|
||||||
artec: Chris Pinkham (*)
|
artec: Chris Pinkham (*)
|
||||||
|
as6e: Eugene S. Weiss (*)
|
||||||
avision: Meino Christian Cramer, Rene Rebe(*)
|
avision: Meino Christian Cramer, Rene Rebe(*)
|
||||||
canon: Helmut Koeberle, Manuel Panea (*), and Markus Mertinat
|
canon: Helmut Koeberle, Manuel Panea (*), and Markus Mertinat
|
||||||
coolscan: Didier Carlier, Andreas Rick (*)
|
coolscan: Didier Carlier, Andreas Rick (*)
|
||||||
|
@ -80,6 +81,7 @@ David F. Skoll <dskoll@iname.com>
|
||||||
David Huggins-Daines <bn711@freenet.carleton.ca>
|
David Huggins-Daines <bn711@freenet.carleton.ca>
|
||||||
David Mosberger <David.Mosberger@acm.org>
|
David Mosberger <David.Mosberger@acm.org>
|
||||||
Didier Carlier <didier@sema.be>
|
Didier Carlier <didier@sema.be>
|
||||||
|
Eugene S. Weiss <yossarian@users.sourceforge.net>
|
||||||
FUKUDA Kazuya <fukuda@avm.nhe.nec.co.jp>
|
FUKUDA Kazuya <fukuda@avm.nhe.nec.co.jp>
|
||||||
Juergen G. Schimmer <schimmi@nbgm.siemens.de>
|
Juergen G. Schimmer <schimmi@nbgm.siemens.de>
|
||||||
Feico W. Dillema <dillema@acm.org>
|
Feico W. Dillema <dillema@acm.org>
|
||||||
|
|
5
PROJECTS
5
PROJECTS
|
@ -1,4 +1,4 @@
|
||||||
PROJECTS (2000-11-15)
|
PROJECTS (2000-11-19)
|
||||||
|
|
||||||
Here is a list of projects that various people have expressed interest
|
Here is a list of projects that various people have expressed interest
|
||||||
in. Before starting working on one of these projects, it may be a
|
in. Before starting working on one of these projects, it may be a
|
||||||
|
@ -16,9 +16,6 @@ wip Work in progress. There is (more or less) working code. For details,
|
||||||
Backends:
|
Backends:
|
||||||
---------
|
---------
|
||||||
|
|
||||||
Artec AS6E (wip)
|
|
||||||
http://as6edriver.sourceforge.net/
|
|
||||||
|
|
||||||
Autobrightness/contrast for cameras etc. (planned?)
|
Autobrightness/contrast for cameras etc. (planned?)
|
||||||
David Mosberger
|
David Mosberger
|
||||||
|
|
||||||
|
|
1
README
1
README
|
@ -105,6 +105,7 @@ below:
|
||||||
AGFA SnapScan sane-snapscan(5)
|
AGFA SnapScan sane-snapscan(5)
|
||||||
Apple sane-apple(5)
|
Apple sane-apple(5)
|
||||||
Artec sane-artec(5)
|
Artec sane-artec(5)
|
||||||
|
Artec AS6E parport sane-as6e(5)
|
||||||
Avision sane-avision(5)
|
Avision sane-avision(5)
|
||||||
Canon sane-canon(5)
|
Canon sane-canon(5)
|
||||||
Nikon Coolscan sane-coolscan(5)
|
Nikon Coolscan sane-coolscan(5)
|
||||||
|
|
|
@ -51,10 +51,10 @@ COMPILE = $(CC) -c $(CFLAGS) $(DEFS) $(INCLUDES) $(CPPFLAGS)
|
||||||
|
|
||||||
@SET_MAKE@
|
@SET_MAKE@
|
||||||
|
|
||||||
PRELOADABLE_BACKENDS = abaton agfafocus apple artec avision canon coolscan \
|
PRELOADABLE_BACKENDS = abaton agfafocus apple artec as6e avision canon \
|
||||||
dc25 @DC210@ dmc epson hp m3096g microtek microtek2 mustek mustek_pp \
|
coolscan dc25 @DC210@ dmc epson hp m3096g microtek microtek2 mustek \
|
||||||
@NET@ pie @PINT@ plustek pnm @QCAM@ ricoh s9036 sharp snapscan sp15c \
|
mustek_pp @NET@ pie @PINT@ plustek pnm @QCAM@ ricoh s9036 sharp \
|
||||||
st400 tamarack umax @V4L@
|
snapscan sp15c st400 tamarack umax @V4L@
|
||||||
ALL_BACKENDS = $(PRELOADABLE_BACKENDS) dll
|
ALL_BACKENDS = $(PRELOADABLE_BACKENDS) dll
|
||||||
|
|
||||||
LIBS = $(addprefix libsane-,$(addsuffix .la,$(ALL_BACKENDS)))
|
LIBS = $(addprefix libsane-,$(addsuffix .la,$(ALL_BACKENDS)))
|
||||||
|
@ -176,6 +176,8 @@ libsane-apple.la: ../sanei/sanei_scsi.lo
|
||||||
libsane-artec.la: ../sanei/sanei_config2.lo
|
libsane-artec.la: ../sanei/sanei_config2.lo
|
||||||
libsane-artec.la: ../sanei/sanei_constrain_value.lo
|
libsane-artec.la: ../sanei/sanei_constrain_value.lo
|
||||||
libsane-artec.la: ../sanei/sanei_scsi.lo
|
libsane-artec.la: ../sanei/sanei_scsi.lo
|
||||||
|
libsane-as6e.la: ../sanei/sanei_config2.lo
|
||||||
|
libsane-as6e.la: ../sanei/sanei_constrain_value.lo
|
||||||
libsane-avision.la: ../sanei/sanei_config2.lo
|
libsane-avision.la: ../sanei/sanei_config2.lo
|
||||||
libsane-avision.la: ../sanei/sanei_constrain_value.lo
|
libsane-avision.la: ../sanei/sanei_constrain_value.lo
|
||||||
libsane-avision.la: ../sanei/sanei_scsi.lo
|
libsane-avision.la: ../sanei/sanei_scsi.lo
|
||||||
|
|
|
@ -0,0 +1,895 @@
|
||||||
|
/***************************************************************************
|
||||||
|
as6e.c - description
|
||||||
|
-------------------
|
||||||
|
begin : Mon Feb 21 20:27:05 EST 2000
|
||||||
|
copyright : (C) 2000 by Eugene Weiss
|
||||||
|
email : eweiss@sas.upenn.edu
|
||||||
|
***************************************************************************/
|
||||||
|
|
||||||
|
/***************************************************************************
|
||||||
|
* *
|
||||||
|
* This program is free software; you can redistribute it and/or modify *
|
||||||
|
* it under the terms of the GNU General Public License as published by *
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or *
|
||||||
|
* (at your option) any later version. *
|
||||||
|
|
||||||
|
|
||||||
|
* *
|
||||||
|
***************************************************************************/
|
||||||
|
|
||||||
|
#include "../include/sane/config.h"
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
#include <limits.h>
|
||||||
|
#include <stdarg.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <signal.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
|
||||||
|
#include "as6e.h"
|
||||||
|
|
||||||
|
#include "../include/sane/sane.h"
|
||||||
|
#include "../include/sane/saneopts.h"
|
||||||
|
|
||||||
|
#define BACKENDNAME as6e
|
||||||
|
#include "../include/sane/sanei_backend.h"
|
||||||
|
#include "../include/sane/sanei_config.h"
|
||||||
|
|
||||||
|
static int num_devices;
|
||||||
|
static AS6E_Device *first_dev;
|
||||||
|
static AS6E_Scan *first_handle;
|
||||||
|
|
||||||
|
static SANE_Status attach (const char *devname, AS6E_Device ** devp);
|
||||||
|
/* static SANE_Status attach_one (const char *dev); */
|
||||||
|
|
||||||
|
static const SANE_String_Const mode_list[] = {
|
||||||
|
"Lineart", "Gray", "Color",
|
||||||
|
0
|
||||||
|
};
|
||||||
|
|
||||||
|
static const SANE_Word resolution_list[] = {
|
||||||
|
4, 300, 200, 100, 50
|
||||||
|
};
|
||||||
|
|
||||||
|
static const SANE_Range x_range = {
|
||||||
|
SANE_FIX (0),
|
||||||
|
SANE_FIX (215.91),
|
||||||
|
SANE_FIX (0)
|
||||||
|
};
|
||||||
|
|
||||||
|
static const SANE_Range y_range = {
|
||||||
|
SANE_FIX (0),
|
||||||
|
SANE_FIX (297.19),
|
||||||
|
SANE_FIX (0)
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
static const SANE_Range brightness_range = {
|
||||||
|
-100,
|
||||||
|
100,
|
||||||
|
1
|
||||||
|
};
|
||||||
|
|
||||||
|
static const SANE_Range contrast_range = {
|
||||||
|
-100,
|
||||||
|
100,
|
||||||
|
1
|
||||||
|
};
|
||||||
|
|
||||||
|
/*--------------------------------------------------------------------------*/
|
||||||
|
static SANE_Int as6e_unit_convert (SANE_Fixed value)
|
||||||
|
{
|
||||||
|
|
||||||
|
double precise;
|
||||||
|
SANE_Int return_value;
|
||||||
|
|
||||||
|
precise = SANE_UNFIX (value);
|
||||||
|
precise = (precise * 300) / MM_PER_INCH;
|
||||||
|
return_value = precise;
|
||||||
|
return return_value;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*--------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
SANE_Status
|
||||||
|
sane_read (SANE_Handle handle, SANE_Byte * buf, SANE_Int max_len,
|
||||||
|
SANE_Int * len)
|
||||||
|
{
|
||||||
|
AS6E_Scan *s = handle;
|
||||||
|
SANE_Word buffer_offset = 0;
|
||||||
|
int written = 0, bytes_read = 0, maxbytes;
|
||||||
|
SANE_Word bytecounter, linebufcounter, ctlbytes;
|
||||||
|
SANE_Byte *linebuffer;
|
||||||
|
|
||||||
|
DBG (3, "\nreading %d bytes, %d bytes in carryover buffer", max_len,
|
||||||
|
s->scan_buffer_count);
|
||||||
|
|
||||||
|
if (s->image_counter >= s->bytes_to_read)
|
||||||
|
{
|
||||||
|
*len = 0;
|
||||||
|
if (s->scanning)
|
||||||
|
{
|
||||||
|
read (s->as6e_params.ctlinpipe, &written, sizeof (written));
|
||||||
|
if (written != -1)
|
||||||
|
printf ("\npipe error");
|
||||||
|
DBG (3, "\ntrying to read -1 ...written = %d", written);
|
||||||
|
}
|
||||||
|
s->scanning = SANE_FALSE;
|
||||||
|
DBG (1, "\nimage data complete, sending EOF...");
|
||||||
|
return SANE_STATUS_EOF;
|
||||||
|
} /*image complete */
|
||||||
|
|
||||||
|
linebuffer = s->line_buffer;
|
||||||
|
if (s->scan_buffer_count > 0)
|
||||||
|
{ /*there are leftover bytes from the last call */
|
||||||
|
if (s->scan_buffer_count <= max_len)
|
||||||
|
{
|
||||||
|
for (*len = 0; *len < s->scan_buffer_count; (*len)++)
|
||||||
|
{
|
||||||
|
buf[*len] = s->scan_buffer[*len];
|
||||||
|
buffer_offset++;
|
||||||
|
}
|
||||||
|
s->scan_buffer_count = 0;
|
||||||
|
if (s->scan_buffer_count == max_len)
|
||||||
|
{
|
||||||
|
s->scan_buffer_count = 0;
|
||||||
|
s->image_counter += max_len;
|
||||||
|
DBG (3, "\nreturning %d bytes from the carryover buffer", *len);
|
||||||
|
return SANE_STATUS_GOOD;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (*len = 0; *len < max_len; (*len)++)
|
||||||
|
buf[*len] = s->scan_buffer[*len];
|
||||||
|
|
||||||
|
for (bytecounter = max_len;
|
||||||
|
bytecounter < s->scan_buffer_count; bytecounter++)
|
||||||
|
s->scan_buffer[bytecounter - max_len]
|
||||||
|
= s->scan_buffer[bytecounter];
|
||||||
|
|
||||||
|
s->scan_buffer_count -= max_len;
|
||||||
|
s->image_counter += max_len;
|
||||||
|
DBG (3, "\nreturning %d bytes from the carryover buffer", *len);
|
||||||
|
return SANE_STATUS_GOOD;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
*len = 0; /*no bytes in the buffer */
|
||||||
|
if (!s->scanning)
|
||||||
|
{
|
||||||
|
DBG (1, "\nscan over returning %d", *len);
|
||||||
|
if (s->scan_buffer_count)
|
||||||
|
return SANE_STATUS_GOOD;
|
||||||
|
else
|
||||||
|
return SANE_STATUS_EOF;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
while (*len < max_len)
|
||||||
|
{
|
||||||
|
DBG (3, "\ntrying to read number of bytes...");
|
||||||
|
ctlbytes = read (s->as6e_params.ctlinpipe, &written, sizeof (written));
|
||||||
|
DBG (3, "\nbytes written = %d, ctlbytes =%d", written, ctlbytes);
|
||||||
|
fflush (stdout);
|
||||||
|
if ((s->cancelled) && (written == 0))
|
||||||
|
{ /*first clear -1 from pipe */
|
||||||
|
DBG (1, "\nsending SANE_STATUS_CANCELLED");
|
||||||
|
read (s->as6e_params.ctlinpipe, &written, sizeof (written));
|
||||||
|
s->scanning = SANE_FALSE;
|
||||||
|
return SANE_STATUS_CANCELLED;
|
||||||
|
}
|
||||||
|
if (written == -1)
|
||||||
|
{
|
||||||
|
DBG (1, "\n-1READ Scanner through. returning %d bytes", *len);
|
||||||
|
s->image_counter += *len;
|
||||||
|
s->scanning = SANE_FALSE;
|
||||||
|
return SANE_STATUS_GOOD;
|
||||||
|
}
|
||||||
|
linebufcounter = 0;
|
||||||
|
DBG (3,
|
||||||
|
"\nlinebufctr reset, len =%d written =%d bytes_read =%d, max = %d",
|
||||||
|
*len, written, bytes_read, max_len);
|
||||||
|
maxbytes = written;
|
||||||
|
while (linebufcounter < written)
|
||||||
|
{
|
||||||
|
DBG (4, "\ntrying to read data pipe");
|
||||||
|
bytes_read =
|
||||||
|
read (s->as6e_params.datapipe, linebuffer + linebufcounter,
|
||||||
|
maxbytes);
|
||||||
|
linebufcounter += bytes_read;
|
||||||
|
maxbytes -= bytes_read;
|
||||||
|
DBG (3, "\nbytes_read = %d linebufcounter = %d", bytes_read,
|
||||||
|
linebufcounter);}
|
||||||
|
DBG (3, "\nwritten =%d max_len =%d len =%d", written, max_len, *len);
|
||||||
|
if (written <= (max_len - *len))
|
||||||
|
{
|
||||||
|
for (bytecounter = 0; bytecounter < written; bytecounter++)
|
||||||
|
{
|
||||||
|
buf[bytecounter + buffer_offset] = linebuffer[bytecounter];
|
||||||
|
(*len)++;
|
||||||
|
}
|
||||||
|
buffer_offset += written;
|
||||||
|
DBG (3, "\nbuffer offset = %d", buffer_offset);
|
||||||
|
}
|
||||||
|
else if (max_len > *len)
|
||||||
|
{ /*there's still room to send data */
|
||||||
|
for (bytecounter = 0; bytecounter < (max_len - *len); bytecounter++)
|
||||||
|
buf[bytecounter + buffer_offset] = linebuffer[bytecounter];
|
||||||
|
DBG (3, "\ntopping off buffer");
|
||||||
|
for (bytecounter = (max_len - *len); bytecounter < written;
|
||||||
|
bytecounter++)
|
||||||
|
{
|
||||||
|
|
||||||
|
s->scan_buffer[s->scan_buffer_count + bytecounter -
|
||||||
|
(max_len - *len)] = linebuffer[bytecounter];
|
||||||
|
}
|
||||||
|
s->scan_buffer_count += (written - (max_len - *len));
|
||||||
|
*len = max_len;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{ /*everything goes into the carryover buffer */
|
||||||
|
for (bytecounter = 0; bytecounter < written; bytecounter++)
|
||||||
|
s->scan_buffer[s->scan_buffer_count + bytecounter]
|
||||||
|
= linebuffer[bytecounter]; s->scan_buffer_count += written;
|
||||||
|
}
|
||||||
|
} /*while there's space in the buffer */
|
||||||
|
s->image_counter += *len;
|
||||||
|
DBG (3, "\nimage ctr = %d bytes_to_read = %d returning %d",
|
||||||
|
s->image_counter, s->bytes_to_read, *len);
|
||||||
|
|
||||||
|
return SANE_STATUS_GOOD;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*--------------------------------------------------------------------------*/
|
||||||
|
void
|
||||||
|
sane_cancel (SANE_Handle h)
|
||||||
|
{
|
||||||
|
AS6E_Scan *s = h;
|
||||||
|
SANE_Word test;
|
||||||
|
DBG (2, "\ntrying to cancel...");
|
||||||
|
if (s->scanning)
|
||||||
|
{
|
||||||
|
test = kill (s->child_pid, SIGUSR1);
|
||||||
|
if (test == 0)
|
||||||
|
s->cancelled = SANE_TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*--------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
SANE_Status
|
||||||
|
sane_start (SANE_Handle handle)
|
||||||
|
{
|
||||||
|
AS6E_Scan *s = handle;
|
||||||
|
SANE_Status status;
|
||||||
|
int repeat = 1;
|
||||||
|
SANE_Word numbytes;
|
||||||
|
int scan_params[8];
|
||||||
|
/* First make sure we have a current parameter set. Some of the
|
||||||
|
* parameters will be overwritten below, but that's OK. */
|
||||||
|
DBG (2, "\nsane_start");
|
||||||
|
status = sane_get_parameters (s, 0);
|
||||||
|
if (status != SANE_STATUS_GOOD)
|
||||||
|
return status;
|
||||||
|
DBG (1, "\nGot params again...");
|
||||||
|
numbytes = write (s->as6e_params.ctloutpipe, &repeat, sizeof (repeat));
|
||||||
|
if (numbytes != sizeof (repeat))
|
||||||
|
return (SANE_STATUS_IO_ERROR);
|
||||||
|
DBG (1, "\nsending start_scan signal");
|
||||||
|
scan_params[0] = s->as6e_params.resolution;
|
||||||
|
if (strcmp (s->value[OPT_MODE].s, "Color") == 0)
|
||||||
|
scan_params[1] = 0;
|
||||||
|
else if (strcmp (s->value[OPT_MODE].s, "Gray") == 0)
|
||||||
|
scan_params[1] = 1;
|
||||||
|
else if (strcmp (s->value[OPT_MODE].s, "Lineart") == 0)
|
||||||
|
scan_params[1] = 2;
|
||||||
|
else
|
||||||
|
return (SANE_STATUS_JAMMED); /*this should never happen */
|
||||||
|
scan_params[2] = s->as6e_params.startpos;
|
||||||
|
scan_params[3] = s->as6e_params.stoppos;
|
||||||
|
scan_params[4] = s->as6e_params.startline;
|
||||||
|
scan_params[5] = s->as6e_params.stopline;
|
||||||
|
scan_params[6] = s->value[OPT_BRIGHTNESS].w;
|
||||||
|
scan_params[7] = s->value[OPT_CONTRAST].w;
|
||||||
|
DBG (1, "\nscan params = %d %d %d %d %d %d %d %d", scan_params[0],
|
||||||
|
scan_params[1], scan_params[2], scan_params[3],
|
||||||
|
scan_params[4], scan_params[5], scan_params[6], scan_params[7]);
|
||||||
|
numbytes =
|
||||||
|
write (s->as6e_params.ctloutpipe, scan_params, sizeof (scan_params));
|
||||||
|
if (numbytes != sizeof (scan_params))
|
||||||
|
return (SANE_STATUS_IO_ERROR);
|
||||||
|
s->scanning = SANE_TRUE;
|
||||||
|
s->scan_buffer_count = 0;
|
||||||
|
s->image_counter = 0;
|
||||||
|
s->cancelled = 0;
|
||||||
|
return (SANE_STATUS_GOOD);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*--------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
SANE_Status
|
||||||
|
sane_get_parameters (SANE_Handle handle, SANE_Parameters * params)
|
||||||
|
{
|
||||||
|
AS6E_Scan *s = handle;
|
||||||
|
SANE_String mode;
|
||||||
|
SANE_Word divisor = 1;
|
||||||
|
DBG (2, "\nsane_get_parameters");
|
||||||
|
if (!s->scanning)
|
||||||
|
{
|
||||||
|
memset (&s->sane_params, 0, sizeof (s->sane_params));
|
||||||
|
s->as6e_params.resolution = s->value[OPT_RESOLUTION].w;
|
||||||
|
s->as6e_params.startpos = as6e_unit_convert (s->value[OPT_TL_X].w);
|
||||||
|
s->as6e_params.stoppos = as6e_unit_convert (s->value[OPT_BR_X].w);
|
||||||
|
s->as6e_params.startline = as6e_unit_convert (s->value[OPT_TL_Y].w);
|
||||||
|
s->as6e_params.stopline = as6e_unit_convert (s->value[OPT_BR_Y].w);
|
||||||
|
if ((s->as6e_params.resolution == 200)
|
||||||
|
|| (s->as6e_params.resolution == 100)) divisor = 3;
|
||||||
|
else if (s->as6e_params.resolution == 50)
|
||||||
|
divisor = 6; /*get legal values for 200 dpi */
|
||||||
|
s->as6e_params.startpos = (s->as6e_params.startpos / divisor) * divisor;
|
||||||
|
s->as6e_params.stoppos = (s->as6e_params.stoppos / divisor) * divisor;
|
||||||
|
s->as6e_params.startline =
|
||||||
|
(s->as6e_params.startline / divisor) * divisor;
|
||||||
|
s->as6e_params.stopline = (s->as6e_params.stopline / divisor) * divisor;
|
||||||
|
s->sane_params.pixels_per_line =
|
||||||
|
(s->as6e_params.stoppos -
|
||||||
|
s->as6e_params.startpos) * s->as6e_params.resolution / 300;
|
||||||
|
s->sane_params.lines =
|
||||||
|
(s->as6e_params.stopline -
|
||||||
|
s->as6e_params.startline) * s->as6e_params.resolution / 300;
|
||||||
|
mode = s->value[OPT_MODE].s;
|
||||||
|
/* if ((strcmp (s->mode, "Lineart") == 0) ||
|
||||||
|
(strcmp (s->mode, "Halftone") == 0))
|
||||||
|
{
|
||||||
|
s->sane_params.format = SANE_FRAME_GRAY;
|
||||||
|
s->sane_params.bytes_per_line = (s->sane_params.pixels_per_line + 7) / 8;
|
||||||
|
s->sane_params.depth = 1;
|
||||||
|
} */
|
||||||
|
/*else*/ if ((strcmp (mode, "Gray") == 0)
|
||||||
|
|| (strcmp (mode, "Lineart") == 0))
|
||||||
|
{
|
||||||
|
s->sane_params.format = SANE_FRAME_GRAY;
|
||||||
|
s->sane_params.bytes_per_line = s->sane_params.pixels_per_line;
|
||||||
|
s->sane_params.depth = 8;
|
||||||
|
} /*grey frame */
|
||||||
|
else
|
||||||
|
{
|
||||||
|
s->sane_params.format = SANE_FRAME_RGB;
|
||||||
|
s->sane_params.bytes_per_line = 3 * s->sane_params.pixels_per_line;
|
||||||
|
s->sane_params.depth = 8;
|
||||||
|
} /*color frame */
|
||||||
|
s->bytes_to_read = s->sane_params.lines * s->sane_params.bytes_per_line;
|
||||||
|
s->sane_params.last_frame = SANE_TRUE;
|
||||||
|
} /*!scanning */
|
||||||
|
|
||||||
|
if (params)
|
||||||
|
*params = s->sane_params;
|
||||||
|
return (SANE_STATUS_GOOD);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*--------------------------------------------------------------------------*/
|
||||||
|
SANE_Status
|
||||||
|
sane_control_option (SANE_Handle handle, SANE_Int option,
|
||||||
|
SANE_Action action, void *val, SANE_Int * info)
|
||||||
|
{
|
||||||
|
AS6E_Scan *s = handle;
|
||||||
|
SANE_Status status = 0;
|
||||||
|
SANE_Word cap;
|
||||||
|
DBG (2, "\nsane_control_option");
|
||||||
|
if (info)
|
||||||
|
*info = 0;
|
||||||
|
if (s->scanning)
|
||||||
|
return SANE_STATUS_DEVICE_BUSY;
|
||||||
|
if (option >= NUM_OPTIONS)
|
||||||
|
return SANE_STATUS_INVAL;
|
||||||
|
cap = s->options_list[option].cap;
|
||||||
|
if (!SANE_OPTION_IS_ACTIVE (cap))
|
||||||
|
return SANE_STATUS_INVAL;
|
||||||
|
if (action == SANE_ACTION_GET_VALUE)
|
||||||
|
{
|
||||||
|
DBG (1, "sane_control_option %d, get value\n", option);
|
||||||
|
switch (option)
|
||||||
|
{
|
||||||
|
/* word options: */
|
||||||
|
case OPT_RESOLUTION:
|
||||||
|
case OPT_TL_X:
|
||||||
|
case OPT_TL_Y:
|
||||||
|
case OPT_BR_X:
|
||||||
|
case OPT_BR_Y:
|
||||||
|
case OPT_NUM_OPTS:
|
||||||
|
case OPT_CONTRAST:
|
||||||
|
case OPT_BRIGHTNESS:
|
||||||
|
*(SANE_Word *) val = s->value[option].w;
|
||||||
|
return (SANE_STATUS_GOOD);
|
||||||
|
/* string options: */
|
||||||
|
case OPT_MODE:
|
||||||
|
strcpy (val, s->value[option].s);
|
||||||
|
return (SANE_STATUS_GOOD);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (action == SANE_ACTION_SET_VALUE)
|
||||||
|
{
|
||||||
|
DBG (1, "sane_control_option %d, set value\n", option);
|
||||||
|
if (!SANE_OPTION_IS_SETTABLE (cap))
|
||||||
|
return (SANE_STATUS_INVAL);
|
||||||
|
/* status = sanei_constrain_value (s->options_list[option], val, info);*/
|
||||||
|
if (status != SANE_STATUS_GOOD)
|
||||||
|
return (status);
|
||||||
|
switch (option)
|
||||||
|
{
|
||||||
|
/* (mostly) side-effect-free word options: */
|
||||||
|
case OPT_RESOLUTION:
|
||||||
|
case OPT_BR_X:
|
||||||
|
case OPT_BR_Y:
|
||||||
|
case OPT_TL_X:
|
||||||
|
case OPT_TL_Y:
|
||||||
|
if (info && s->value[option].w != *(SANE_Word *) val)
|
||||||
|
*info |= SANE_INFO_RELOAD_PARAMS;
|
||||||
|
/* fall through */
|
||||||
|
case OPT_NUM_OPTS:
|
||||||
|
case OPT_CONTRAST:
|
||||||
|
case OPT_BRIGHTNESS:
|
||||||
|
s->value[option].w = *(SANE_Word *) val;
|
||||||
|
DBG (1, "\nset brightness to");
|
||||||
|
return (SANE_STATUS_GOOD);
|
||||||
|
case OPT_MODE:
|
||||||
|
if (s->value[option].s)
|
||||||
|
free (s->value[option].s);
|
||||||
|
s->value[option].s = strdup (val);
|
||||||
|
return (SANE_STATUS_GOOD);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return (SANE_STATUS_INVAL);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*--------------------------------------------------------------------------*/
|
||||||
|
const SANE_Option_Descriptor *
|
||||||
|
sane_get_option_descriptor (SANE_Handle handle, SANE_Int option)
|
||||||
|
{
|
||||||
|
AS6E_Scan *s = handle;
|
||||||
|
DBG (2, "\nsane_get_option_descriptor");
|
||||||
|
if ((unsigned) option >= NUM_OPTIONS)
|
||||||
|
return (0);
|
||||||
|
return (&s->options_list[option]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*--------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
void
|
||||||
|
sane_close (SANE_Handle handle)
|
||||||
|
{
|
||||||
|
AS6E_Scan *prev, *s;
|
||||||
|
SANE_Word repeat = 0;
|
||||||
|
DBG (2, "\nsane_close");
|
||||||
|
/* remove handle from list of open handles: */
|
||||||
|
prev = 0;
|
||||||
|
for (s = first_handle; s; s = s->next)
|
||||||
|
{
|
||||||
|
if (s == handle)
|
||||||
|
break;
|
||||||
|
prev = s;
|
||||||
|
}
|
||||||
|
if (!s)
|
||||||
|
{
|
||||||
|
DBG (1, "close: invalid handle %p\n", handle);
|
||||||
|
return; /* oops, not a handle we know about */
|
||||||
|
}
|
||||||
|
|
||||||
|
if (s->scanning)
|
||||||
|
sane_cancel (handle);
|
||||||
|
write (s->as6e_params.ctloutpipe, &repeat, sizeof (repeat));
|
||||||
|
close (s->as6e_params.ctloutpipe);
|
||||||
|
free (s->scan_buffer);
|
||||||
|
free (s->line_buffer);
|
||||||
|
if (prev)
|
||||||
|
prev->next = s->next;
|
||||||
|
else
|
||||||
|
first_handle = s;
|
||||||
|
free (handle);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*--------------------------------------------------------------------------*/
|
||||||
|
void
|
||||||
|
sane_exit (void)
|
||||||
|
{
|
||||||
|
AS6E_Device *next;
|
||||||
|
DBG (2, "\nsane_exit");
|
||||||
|
while (first_dev != NULL)
|
||||||
|
{
|
||||||
|
next = first_dev->next;
|
||||||
|
/* free((void *) first_dev->sane.name);*/
|
||||||
|
/* free((void *) first_dev->sane.model);*/
|
||||||
|
free (first_dev);
|
||||||
|
first_dev = next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*--------------------------------------------------------------------------*/
|
||||||
|
static SANE_Status
|
||||||
|
as6e_open (AS6E_Scan * s)
|
||||||
|
{
|
||||||
|
|
||||||
|
int data_processed, exec_result, as6e_status;
|
||||||
|
int ctloutpipe[2], ctlinpipe[2], datapipe[2];
|
||||||
|
char inpipe_desc[32], outpipe_desc[32], datapipe_desc[32];
|
||||||
|
pid_t fork_result;
|
||||||
|
DBG (1, "\nas6e_open");
|
||||||
|
memset (inpipe_desc, '\0', sizeof (inpipe_desc));
|
||||||
|
memset (outpipe_desc, '\0', sizeof (outpipe_desc));
|
||||||
|
memset (datapipe_desc, '\0', sizeof (datapipe_desc));
|
||||||
|
if ((pipe (ctloutpipe) == 0) && (pipe (ctlinpipe) == 0)
|
||||||
|
&& (pipe (datapipe) == 0))
|
||||||
|
{
|
||||||
|
fork_result = fork ();
|
||||||
|
if (fork_result == (pid_t) - 1)
|
||||||
|
{
|
||||||
|
fprintf (stderr, "Fork failure");
|
||||||
|
return (SANE_STATUS_IO_ERROR);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fork_result == 0)
|
||||||
|
{ /*in child */
|
||||||
|
sprintf (inpipe_desc, "%d", ctlinpipe[WRITEPIPE]);
|
||||||
|
sprintf (outpipe_desc, "%d", ctloutpipe[READPIPE]);
|
||||||
|
sprintf (datapipe_desc, "%d", datapipe[WRITEPIPE]);
|
||||||
|
exec_result =
|
||||||
|
execlp ("as6edriver", "as6edriver", "-s", inpipe_desc,
|
||||||
|
outpipe_desc, datapipe_desc, (char *) 0);
|
||||||
|
printf ("\nThe SANE backend was unable to start \"as6edriver\".");
|
||||||
|
printf ("\nThis must be installed in a driectory in your PATH.\n");
|
||||||
|
printf ("\nTo aquire the as6edriver program,");
|
||||||
|
printf ("\ngo to http://as6edriver.sourceforge.net.");
|
||||||
|
write (ctlinpipe[WRITEPIPE], &exec_result, sizeof (exec_result));
|
||||||
|
exit (-1);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{ /*parent process */
|
||||||
|
data_processed =
|
||||||
|
read (ctlinpipe[READPIPE], &as6e_status, sizeof (as6e_status));
|
||||||
|
DBG (1, "%d - read %d status = %d\n", getpid (), data_processed,
|
||||||
|
as6e_status); if (as6e_status == -2)
|
||||||
|
{
|
||||||
|
printf ("\nPort access denied.");
|
||||||
|
return (SANE_STATUS_IO_ERROR);
|
||||||
|
}
|
||||||
|
if (as6e_status == -1)
|
||||||
|
{
|
||||||
|
printf ("\nCould not contact scanner.");
|
||||||
|
return (SANE_STATUS_IO_ERROR);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (as6e_status == 1)
|
||||||
|
printf ("\nUsing nibble mode.");
|
||||||
|
if (as6e_status == 2)
|
||||||
|
printf ("\nUsing byte mode.");
|
||||||
|
if (as6e_status == 3)
|
||||||
|
printf ("\nUsing EPP mode.");
|
||||||
|
s->as6e_params.ctlinpipe = ctlinpipe[READPIPE];
|
||||||
|
s->as6e_params.ctloutpipe = ctloutpipe[WRITEPIPE];
|
||||||
|
s->as6e_params.datapipe = datapipe[READPIPE];
|
||||||
|
s->child_pid = fork_result;
|
||||||
|
return (SANE_STATUS_GOOD);
|
||||||
|
} /*else */
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return (SANE_STATUS_IO_ERROR);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*--------------------------------------------------------------------------*/
|
||||||
|
SANE_Status
|
||||||
|
sane_init (SANE_Int * version_code, SANE_Auth_Callback authorize)
|
||||||
|
{
|
||||||
|
char dev_name[PATH_MAX];
|
||||||
|
size_t len;
|
||||||
|
FILE *fp = NULL;
|
||||||
|
|
||||||
|
DBG_INIT();
|
||||||
|
DBG (2, "\nsane_init");
|
||||||
|
if (version_code)
|
||||||
|
*version_code = SANE_VERSION_CODE (V_MAJOR, V_MINOR, 0);
|
||||||
|
/* fp = sanei_config_open (AS6E_CONFIG_FILE);*/
|
||||||
|
if (!fp)
|
||||||
|
{
|
||||||
|
/* attach ("as6edriver", 0);*/
|
||||||
|
return (attach ("as6edriver", 0));
|
||||||
|
}
|
||||||
|
|
||||||
|
while (fgets (dev_name, sizeof (dev_name), fp))
|
||||||
|
{
|
||||||
|
if (dev_name[0] == '#') /* ignore line comments */
|
||||||
|
continue;
|
||||||
|
len = strlen (dev_name);
|
||||||
|
if (dev_name[len - 1] == '\n')
|
||||||
|
dev_name[--len] = '\0';
|
||||||
|
if (!len)
|
||||||
|
continue; /* ignore empty lines */
|
||||||
|
/* sanei_config_attach_matching_devices (dev_name, attach_one);*/
|
||||||
|
}
|
||||||
|
fclose (fp);
|
||||||
|
return (SANE_STATUS_GOOD);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*--------------------------------------------------------------------------*/
|
||||||
|
/*
|
||||||
|
static SANE_Status
|
||||||
|
attach_one (const char *dev)
|
||||||
|
{
|
||||||
|
DBG (2, "attach_one\n");
|
||||||
|
attach (dev, 0);
|
||||||
|
return (SANE_STATUS_GOOD);
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
/*--------------------------------------------------------------------------*/
|
||||||
|
SANE_Status
|
||||||
|
sane_get_devices (const SANE_Device *** device_list, SANE_Bool local_only)
|
||||||
|
{
|
||||||
|
static const SANE_Device **devlist = 0;
|
||||||
|
AS6E_Device *dev;
|
||||||
|
int i;
|
||||||
|
DBG (3, "\nsane_get_devices");
|
||||||
|
if (devlist)
|
||||||
|
free (devlist);
|
||||||
|
devlist = malloc ((num_devices + 1) * sizeof (devlist[0]));
|
||||||
|
if (!devlist)
|
||||||
|
return SANE_STATUS_NO_MEM;
|
||||||
|
i = 0;
|
||||||
|
for (dev = first_dev; i < num_devices; dev = dev->next)
|
||||||
|
devlist[i++] = &dev->sane;
|
||||||
|
devlist[i++] = 0;
|
||||||
|
*device_list = devlist;
|
||||||
|
return (SANE_STATUS_GOOD);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*--------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
static size_t
|
||||||
|
max_string_size (const SANE_String_Const strings[])
|
||||||
|
{
|
||||||
|
size_t size, max_size = 0;
|
||||||
|
int i;
|
||||||
|
for (i = 0; strings[i]; ++i)
|
||||||
|
{
|
||||||
|
size = strlen (strings[i]) + 1;
|
||||||
|
if (size > max_size)
|
||||||
|
max_size = size;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (max_size);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*--------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
static void
|
||||||
|
initialize_options_list (AS6E_Scan * s)
|
||||||
|
{
|
||||||
|
|
||||||
|
SANE_Int option;
|
||||||
|
DBG (2, "\ninitialize_options_list");
|
||||||
|
for (option = 0; option < NUM_OPTIONS; ++option)
|
||||||
|
{
|
||||||
|
s->options_list[option].size = sizeof (SANE_Word);
|
||||||
|
s->options_list[option].cap =
|
||||||
|
SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT;}
|
||||||
|
|
||||||
|
s->options_list[OPT_NUM_OPTS].name = SANE_NAME_NUM_OPTIONS;
|
||||||
|
s->options_list[OPT_NUM_OPTS].title = SANE_TITLE_NUM_OPTIONS;
|
||||||
|
s->options_list[OPT_NUM_OPTS].desc = SANE_DESC_NUM_OPTIONS;
|
||||||
|
s->options_list[OPT_NUM_OPTS].type = SANE_TYPE_INT;
|
||||||
|
s->options_list[OPT_NUM_OPTS].unit = SANE_UNIT_NONE;
|
||||||
|
s->options_list[OPT_NUM_OPTS].size = sizeof (SANE_Word);
|
||||||
|
s->options_list[OPT_NUM_OPTS].cap = SANE_CAP_SOFT_DETECT;
|
||||||
|
s->options_list[OPT_NUM_OPTS].constraint_type = SANE_CONSTRAINT_NONE;
|
||||||
|
s->value[OPT_NUM_OPTS].w = NUM_OPTIONS;
|
||||||
|
s->options_list[OPT_MODE].name = SANE_NAME_SCAN_MODE;
|
||||||
|
s->options_list[OPT_MODE].title = SANE_TITLE_SCAN_MODE;
|
||||||
|
s->options_list[OPT_MODE].desc = SANE_DESC_SCAN_MODE;
|
||||||
|
s->options_list[OPT_MODE].type = SANE_TYPE_STRING;
|
||||||
|
s->options_list[OPT_MODE].size = max_string_size (mode_list);
|
||||||
|
s->options_list[OPT_MODE].constraint_type = SANE_CONSTRAINT_STRING_LIST;
|
||||||
|
s->options_list[OPT_MODE].constraint.string_list = mode_list;
|
||||||
|
s->value[OPT_MODE].s = strdup (mode_list[2]);
|
||||||
|
s->options_list[OPT_RESOLUTION].name = SANE_NAME_SCAN_RESOLUTION;
|
||||||
|
s->options_list[OPT_RESOLUTION].title = SANE_TITLE_SCAN_RESOLUTION;
|
||||||
|
s->options_list[OPT_RESOLUTION].desc = SANE_DESC_SCAN_RESOLUTION;
|
||||||
|
s->options_list[OPT_RESOLUTION].type = SANE_TYPE_INT;
|
||||||
|
s->options_list[OPT_RESOLUTION].unit = SANE_UNIT_DPI;
|
||||||
|
s->options_list[OPT_RESOLUTION].constraint_type = SANE_CONSTRAINT_WORD_LIST;
|
||||||
|
s->options_list[OPT_RESOLUTION].constraint.word_list = resolution_list;
|
||||||
|
s->value[OPT_RESOLUTION].w = 200;
|
||||||
|
s->options_list[OPT_TL_X].name = SANE_NAME_SCAN_TL_X;
|
||||||
|
s->options_list[OPT_TL_X].title = SANE_TITLE_SCAN_TL_X;
|
||||||
|
s->options_list[OPT_TL_X].desc = SANE_DESC_SCAN_TL_X;
|
||||||
|
s->options_list[OPT_TL_X].type = SANE_TYPE_FIXED;
|
||||||
|
s->options_list[OPT_TL_X].unit = SANE_UNIT_MM;
|
||||||
|
s->options_list[OPT_TL_X].constraint_type = SANE_CONSTRAINT_RANGE;
|
||||||
|
s->options_list[OPT_TL_X].constraint.range = &x_range;
|
||||||
|
s->value[OPT_TL_X].w = s->options_list[OPT_TL_X].constraint.range->min;
|
||||||
|
s->options_list[OPT_TL_Y].name = SANE_NAME_SCAN_TL_Y;
|
||||||
|
s->options_list[OPT_TL_Y].title = SANE_TITLE_SCAN_TL_Y;
|
||||||
|
s->options_list[OPT_TL_Y].desc = SANE_DESC_SCAN_TL_Y;
|
||||||
|
s->options_list[OPT_TL_Y].type = SANE_TYPE_FIXED;
|
||||||
|
s->options_list[OPT_TL_Y].unit = SANE_UNIT_MM;
|
||||||
|
s->options_list[OPT_TL_Y].constraint_type = SANE_CONSTRAINT_RANGE;
|
||||||
|
s->options_list[OPT_TL_Y].constraint.range = &y_range;
|
||||||
|
s->value[OPT_TL_Y].w = s->options_list[OPT_TL_Y].constraint.range->min;
|
||||||
|
s->options_list[OPT_BR_X].name = SANE_NAME_SCAN_BR_X;
|
||||||
|
s->options_list[OPT_BR_X].title = SANE_TITLE_SCAN_BR_X;
|
||||||
|
s->options_list[OPT_BR_X].desc = SANE_DESC_SCAN_BR_X;
|
||||||
|
s->options_list[OPT_BR_X].type = SANE_TYPE_FIXED;
|
||||||
|
s->options_list[OPT_BR_X].unit = SANE_UNIT_MM;
|
||||||
|
s->options_list[OPT_BR_X].constraint_type = SANE_CONSTRAINT_RANGE;
|
||||||
|
s->options_list[OPT_BR_X].constraint.range = &x_range;
|
||||||
|
s->value[OPT_BR_X].w = s->options_list[OPT_BR_X].constraint.range->max;
|
||||||
|
s->options_list[OPT_BR_Y].name = SANE_NAME_SCAN_BR_Y;
|
||||||
|
s->options_list[OPT_BR_Y].title = SANE_TITLE_SCAN_BR_Y;
|
||||||
|
s->options_list[OPT_BR_Y].desc = SANE_DESC_SCAN_BR_Y;
|
||||||
|
s->options_list[OPT_BR_Y].type = SANE_TYPE_FIXED;
|
||||||
|
s->options_list[OPT_BR_Y].unit = SANE_UNIT_MM;
|
||||||
|
s->options_list[OPT_BR_Y].constraint_type = SANE_CONSTRAINT_RANGE;
|
||||||
|
s->options_list[OPT_BR_Y].constraint.range = &y_range;
|
||||||
|
s->value[OPT_BR_Y].w = s->options_list[OPT_BR_Y].constraint.range->max;
|
||||||
|
s->options_list[OPT_CONTRAST].name = SANE_NAME_CONTRAST;
|
||||||
|
s->options_list[OPT_CONTRAST].title = SANE_TITLE_CONTRAST;
|
||||||
|
s->options_list[OPT_CONTRAST].desc = SANE_DESC_CONTRAST;
|
||||||
|
s->options_list[OPT_CONTRAST].type = SANE_TYPE_INT;
|
||||||
|
s->options_list[OPT_CONTRAST].unit = SANE_UNIT_NONE;
|
||||||
|
s->options_list[OPT_CONTRAST].constraint_type = SANE_CONSTRAINT_RANGE;
|
||||||
|
s->options_list[OPT_CONTRAST].constraint.range = &brightness_range;
|
||||||
|
s->value[OPT_BRIGHTNESS].w = 10;
|
||||||
|
s->options_list[OPT_BRIGHTNESS].name = SANE_NAME_BRIGHTNESS;
|
||||||
|
s->options_list[OPT_BRIGHTNESS].title = SANE_TITLE_BRIGHTNESS;
|
||||||
|
s->options_list[OPT_BRIGHTNESS].desc = SANE_DESC_BRIGHTNESS;
|
||||||
|
s->options_list[OPT_BRIGHTNESS].type = SANE_TYPE_INT;
|
||||||
|
s->options_list[OPT_BRIGHTNESS].unit = SANE_UNIT_NONE;
|
||||||
|
s->options_list[OPT_BRIGHTNESS].constraint_type = SANE_CONSTRAINT_RANGE;
|
||||||
|
s->options_list[OPT_BRIGHTNESS].constraint.range = &contrast_range;
|
||||||
|
s->value[OPT_CONTRAST].w = -32;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*--------------------------------------------------------------------------*/
|
||||||
|
static int
|
||||||
|
check_for_driver (const char *devname)
|
||||||
|
{
|
||||||
|
#define NAMESIZE 128
|
||||||
|
struct stat statbuf;
|
||||||
|
mode_t modes;
|
||||||
|
char *path;
|
||||||
|
char fullname[NAMESIZE];
|
||||||
|
char dir[NAMESIZE];
|
||||||
|
int count = 0, offset = 0;
|
||||||
|
|
||||||
|
path = getenv ("PATH");
|
||||||
|
while (path[count] != '\0')
|
||||||
|
{
|
||||||
|
memset (fullname, '\0', sizeof (fullname));
|
||||||
|
memset (dir, '\0', sizeof (dir));
|
||||||
|
while ((path[count] != ':') && (path[count] != '\0'))
|
||||||
|
{
|
||||||
|
dir[count - offset] = path[count];
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
strncpy (fullname, dir, NAMESIZE);
|
||||||
|
strncat (fullname, "/", NAMESIZE);
|
||||||
|
strncat (fullname, devname, NAMESIZE);
|
||||||
|
stat (fullname, &statbuf);
|
||||||
|
modes = statbuf.st_mode;
|
||||||
|
if (S_ISREG (modes))
|
||||||
|
return (1); /* found as6edriver */
|
||||||
|
if (path[count] == '\0')
|
||||||
|
return (0); /* end of path --no driver found */
|
||||||
|
count++;
|
||||||
|
offset = count;
|
||||||
|
}
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*--------------------------------------------------------------------------*/
|
||||||
|
static SANE_Status
|
||||||
|
attach (const char *devname, AS6E_Device ** devp)
|
||||||
|
{
|
||||||
|
|
||||||
|
AS6E_Device *dev;
|
||||||
|
|
||||||
|
/* SANE_Status status; */
|
||||||
|
DBG (2, "\nattach");
|
||||||
|
for (dev = first_dev; dev; dev = dev->next)
|
||||||
|
{
|
||||||
|
if (strcmp (dev->sane.name, devname) == 0)
|
||||||
|
{
|
||||||
|
if (devp)
|
||||||
|
*devp = dev;
|
||||||
|
return (SANE_STATUS_GOOD);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
dev = malloc (sizeof (*dev));
|
||||||
|
if (!dev)
|
||||||
|
return (SANE_STATUS_NO_MEM);
|
||||||
|
memset (dev, 0, sizeof (*dev));
|
||||||
|
dev->sane.name = strdup (devname);
|
||||||
|
if (!check_for_driver (devname))
|
||||||
|
return (SANE_STATUS_INVAL);
|
||||||
|
|
||||||
|
dev->sane.model = "AS6E";
|
||||||
|
dev->sane.vendor = "Artec";
|
||||||
|
dev->sane.type = "flatbed scanner";
|
||||||
|
++num_devices;
|
||||||
|
dev->next = first_dev;
|
||||||
|
first_dev = dev;
|
||||||
|
if (devp)
|
||||||
|
*devp = dev;
|
||||||
|
return (SANE_STATUS_GOOD);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*--------------------------------------------------------------------------*/
|
||||||
|
SANE_Status
|
||||||
|
sane_open (SANE_String_Const devicename, SANE_Handle * handle)
|
||||||
|
{
|
||||||
|
SANE_Status status;
|
||||||
|
AS6E_Device *dev;
|
||||||
|
AS6E_Scan *s;
|
||||||
|
DBG (2, "\nsane_open");
|
||||||
|
if (devicename[0])
|
||||||
|
{
|
||||||
|
for (dev = first_dev; dev; dev = dev->next)
|
||||||
|
if (strcmp (dev->sane.name, devicename) == 0)
|
||||||
|
break;
|
||||||
|
if (!dev)
|
||||||
|
{
|
||||||
|
status = attach (devicename, &dev);
|
||||||
|
if (status != SANE_STATUS_GOOD)
|
||||||
|
return (status);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* empty devicname -> use first device */
|
||||||
|
dev = first_dev;
|
||||||
|
}
|
||||||
|
if (!dev)
|
||||||
|
return SANE_STATUS_INVAL;
|
||||||
|
s = malloc (sizeof (*s));
|
||||||
|
if (!s)
|
||||||
|
return SANE_STATUS_NO_MEM;
|
||||||
|
memset (s, 0, sizeof (*s));
|
||||||
|
s->scan_buffer = malloc (SCAN_BUF_SIZE);
|
||||||
|
if (!s->scan_buffer)
|
||||||
|
return SANE_STATUS_NO_MEM;
|
||||||
|
memset (s->scan_buffer, 0, SCAN_BUF_SIZE);
|
||||||
|
s->line_buffer = malloc (SCAN_BUF_SIZE);
|
||||||
|
if (!s->line_buffer)
|
||||||
|
return SANE_STATUS_NO_MEM;
|
||||||
|
memset (s->line_buffer, 0, SCAN_BUF_SIZE);
|
||||||
|
status = as6e_open (s);
|
||||||
|
if (status != SANE_STATUS_GOOD)
|
||||||
|
return status;
|
||||||
|
initialize_options_list (s);
|
||||||
|
s->scanning = 0;
|
||||||
|
/* insert newly opened handle into list of open handles: */
|
||||||
|
s->next = first_handle;
|
||||||
|
first_handle = s;
|
||||||
|
*handle = s;
|
||||||
|
return (status);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*--------------------------------------------------------------------------*/
|
||||||
|
SANE_Status
|
||||||
|
sane_set_io_mode (SANE_Handle handle, SANE_Bool non_blocking)
|
||||||
|
{
|
||||||
|
DBG (2, "sane_set_io_mode( %p, %d )\n", handle, non_blocking);
|
||||||
|
return (SANE_STATUS_UNSUPPORTED);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
SANE_Status
|
||||||
|
sane_get_select_fd (SANE_Handle handle, SANE_Int * fd)
|
||||||
|
{
|
||||||
|
return SANE_STATUS_UNSUPPORTED;
|
||||||
|
}
|
|
@ -8,10 +8,10 @@
|
||||||
; All other information is optional (but what good is the file without it?).
|
; All other information is optional (but what good is the file without it?).
|
||||||
;
|
;
|
||||||
|
|
||||||
:backend "as6e" ; name of backend
|
:backend "as6e" ; name of backend
|
||||||
:version "(0.4.0)" ; version of backend
|
:version "0.4.2" ; version of backend
|
||||||
:status :alpha ; :alpha, :beta, :stable, :new
|
:status :new ; :alpha, :beta, :stable, :new
|
||||||
;:manpage "sane-as6e" ; name of manpage (if it exists)
|
:manpage "sane-as6e" ; name of manpage (if it exists)
|
||||||
:url "http://as6edriver.sourceforge.net/"
|
:url "http://as6edriver.sourceforge.net/"
|
||||||
|
|
||||||
:devicetype :scanner
|
:devicetype :scanner
|
||||||
|
@ -21,7 +21,7 @@
|
||||||
|
|
||||||
:model "AS6E"
|
:model "AS6E"
|
||||||
:interface "Parport"
|
:interface "Parport"
|
||||||
:comment "all modes working"
|
:comment "Requires the program 'as6edriver' to run."
|
||||||
|
|
||||||
|
|
||||||
; :comment and :url specifiers are optional after :mfg, :model, :desc,
|
; :comment and :url specifiers are optional after :mfg, :model, :desc,
|
||||||
|
|
|
@ -0,0 +1,98 @@
|
||||||
|
/***************************************************************************
|
||||||
|
as6e.h - description
|
||||||
|
-------------------
|
||||||
|
begin : Mon Feb 21 2000
|
||||||
|
copyright : (C) 2000 by Eugene Weiss
|
||||||
|
email : eweiss@sas.upenn.edu
|
||||||
|
***************************************************************************/
|
||||||
|
|
||||||
|
/***************************************************************************
|
||||||
|
* *
|
||||||
|
* This program is free software; you can redistribute it and/or modify *
|
||||||
|
* it under the terms of the GNU General Public License as published by *
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or *
|
||||||
|
* (at your option) any later version. *
|
||||||
|
* *
|
||||||
|
***************************************************************************/
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sane/sane.h>
|
||||||
|
|
||||||
|
|
||||||
|
typedef union
|
||||||
|
{
|
||||||
|
SANE_Word w; /* word */
|
||||||
|
SANE_Word *wa; /* word array */
|
||||||
|
SANE_String s; /* string */
|
||||||
|
} Option_Value;
|
||||||
|
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
OPT_NUM_OPTS = 0,
|
||||||
|
OPT_MODE,
|
||||||
|
OPT_RESOLUTION,
|
||||||
|
|
||||||
|
OPT_TL_X, /* top-left x */
|
||||||
|
OPT_TL_Y, /* top-left y */
|
||||||
|
OPT_BR_X, /* bottom-right x */
|
||||||
|
OPT_BR_Y, /* bottom-right y */
|
||||||
|
|
||||||
|
OPT_BRIGHTNESS,
|
||||||
|
OPT_CONTRAST,
|
||||||
|
|
||||||
|
/* must come last */
|
||||||
|
NUM_OPTIONS
|
||||||
|
} AS6E_Option;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
int color;
|
||||||
|
int resolution;
|
||||||
|
int startpos;
|
||||||
|
int stoppos;
|
||||||
|
int startline;
|
||||||
|
int stopline;
|
||||||
|
int ctloutpipe;
|
||||||
|
int ctlinpipe;
|
||||||
|
int datapipe;
|
||||||
|
} AS6E_Params;
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct AS6E_Device
|
||||||
|
{
|
||||||
|
struct AS6E_Device *next;
|
||||||
|
SANE_Device sane;
|
||||||
|
} AS6E_Device;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct AS6E_Scan
|
||||||
|
{
|
||||||
|
struct AS6E_Scan *next;
|
||||||
|
SANE_Option_Descriptor options_list[NUM_OPTIONS];
|
||||||
|
Option_Value value[NUM_OPTIONS];
|
||||||
|
SANE_Bool scanning;
|
||||||
|
SANE_Bool cancelled;
|
||||||
|
SANE_Parameters sane_params;
|
||||||
|
AS6E_Params as6e_params;
|
||||||
|
pid_t child_pid;
|
||||||
|
size_t bytes_to_read;
|
||||||
|
SANE_Byte *scan_buffer;
|
||||||
|
SANE_Byte *line_buffer;
|
||||||
|
SANE_Word scan_buffer_count;
|
||||||
|
SANE_Word image_counter;
|
||||||
|
} AS6E_Scan;
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef PATH_MAX
|
||||||
|
#define PATH_MAX 1024
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define AS6E_CONFIG_FILE "as6e.conf"
|
||||||
|
|
||||||
|
#define READPIPE 0
|
||||||
|
#define WRITEPIPE 1
|
||||||
|
|
||||||
|
#define MM_PER_INCH 25.4
|
||||||
|
|
||||||
|
#define SCAN_BUF_SIZE 32768
|
|
@ -5,6 +5,7 @@ agfafocus
|
||||||
apple
|
apple
|
||||||
avision
|
avision
|
||||||
artec
|
artec
|
||||||
|
as6e
|
||||||
canon
|
canon
|
||||||
coolscan
|
coolscan
|
||||||
#dc25
|
#dc25
|
||||||
|
|
|
@ -31,13 +31,14 @@ LN_S = @LN_S@
|
||||||
@SET_MAKE@
|
@SET_MAKE@
|
||||||
|
|
||||||
SECT1 = saned.1 scanimage.1 xscanimage.1 xcam.1
|
SECT1 = saned.1 scanimage.1 xscanimage.1 xcam.1
|
||||||
SECT5 = sane-abaton.5 sane-agfafocus.5 sane-apple.5 sane-dll.5 sane-dc25.5 \
|
SECT5 = sane-abaton.5 sane-agfafocus.5 sane-apple.5 sane-as6e.5 sane-dll.5 \
|
||||||
sane-dmc.5 sane-epson.5 sane-hp.5 sane-microtek.5 sane-microtek2.5 \
|
sane-dc25.5 sane-dmc.5 sane-epson.5 sane-hp.5 sane-microtek.5 \
|
||||||
sane-mustek.5 sane-net.5 sane-pie.5 sane-pint.5 sane-pnm.5 sane-umax.5 \
|
sane-microtek2.5 sane-mustek.5 sane-net.5 sane-pie.5 sane-pint.5 \
|
||||||
sane-qcam.5 sane-scsi.5 sane-artec.5 sane-fujitsu.5 sane-sharp.5 \
|
sane-pnm.5 sane-umax.5 sane-qcam.5 sane-scsi.5 sane-artec.5 \
|
||||||
sane-s9036.5 sane-tamarack.5 sane-ricoh.5 sane-avision.5 \
|
sane-fujitsu.5 sane-sharp.5 sane-s9036.5 sane-tamarack.5 \
|
||||||
sane-plustek.5 sane-st400.5 sane-mustek_pp.5 sane-dc210.5 \
|
sane-ricoh.5 sane-avision.5 sane-plustek.5 sane-st400.5 \
|
||||||
sane-v4l.5 sane-snapscan.5 sane-canon.5 sane-coolscan.5
|
sane-mustek_pp.5 sane-dc210.5 sane-v4l.5 sane-snapscan.5 \
|
||||||
|
sane-canon.5 sane-coolscan.5
|
||||||
MANPAGES = $(SECT1) $(SECT5)
|
MANPAGES = $(SECT1) $(SECT5)
|
||||||
DOCS = sane.ps sane.dvi
|
DOCS = sane.ps sane.dvi
|
||||||
LATEX = TEXINPUTS=$(srcdir):$$TEXINPUTS latex
|
LATEX = TEXINPUTS=$(srcdir):$$TEXINPUTS latex
|
||||||
|
|
|
@ -0,0 +1,33 @@
|
||||||
|
.TH sane-as6e 5 " November 19, 2000" "SANE Artec AS6E Backend "
|
||||||
|
|
||||||
|
.SH NAME
|
||||||
|
sane-as6e \-SANE backend for using the Artec AS6E parallel port interface scanner.
|
||||||
|
|
||||||
|
.SH DESCRIPTION
|
||||||
|
The
|
||||||
|
.B sane-as6e
|
||||||
|
library implements a SANE (Scanner Access Now Easy) backend
|
||||||
|
that provides access to Artec AS6E flatbed scanner.
|
||||||
|
.B It requires the as6edriver program in order to operate.
|
||||||
|
The as6edriver program is
|
||||||
|
.B not
|
||||||
|
included with the SANE package.
|
||||||
|
It can be found at
|
||||||
|
.B http://as6edriver.sourceforge.net
|
||||||
|
. See the as6edriver documentation for technical information.
|
||||||
|
.PP
|
||||||
|
|
||||||
|
.SH FILES
|
||||||
|
.B as6edriver
|
||||||
|
-driver program that controls the scanner.
|
||||||
|
|
||||||
|
.SH BUGS
|
||||||
|
|
||||||
|
.SH SEE ALSO
|
||||||
|
as6edriver(5)
|
||||||
|
|
||||||
|
.SH AUTHOR
|
||||||
|
Eugene S. Weiss
|
||||||
|
|
||||||
|
.SH EMAIL-CONTACT
|
||||||
|
yossarian@users.sourceforge.net
|
Ładowanie…
Reference in New Issue