- moved experimental version to current tree

merge-requests/1/head
Stéphane Voltz 2007-10-01 04:27:24 +00:00
rodzic 8c638f5802
commit dce6df9182
11 zmienionych plików z 6042 dodań i 3215 usunięć

Wyświetl plik

@ -1,6 +1,14 @@
2007-10-01 Stephane Voltz <stef.dev@free.fr>
* doc/sane-umax_pp.man doc/description/umax_pp.desc:
* doc/sane-lexmark.man doc/descriptions/lexmark.desc
backend/Makefile.in backend/lexmark.c backend/lexmark_low.c
backend/lexmark_sensors.c backend/lexmark_models.c
backend/lexmark.conf.in:
moved experimental version to current tree
2007-10-01 Stephane Voltz <stef.dev@free.fr>
* doc/sane-umax_pp.man doc/descriptions/umax_pp.desc:
added Genius ColorPage-Life Pro as supported scanner
by the umax_pp backend

Wyświetl plik

@ -123,7 +123,8 @@ DISTFILES = abaton.c abaton.conf.in abaton.h agfafocus.c agfafocus.conf.in \
hp5400_sane.c hp5400_sanei.c hp5400_sanei.h \
ibm.c ibm.conf.in ibm.h ibm-scsi.c \
leo.c leo.h leo.conf.in \
lexmark.c lexmark-x1100.c lexmark.h lexmark.conf.in \
lexmark.c lexmark_low.c lexmark_sensors.c lexmark_devices.c lexmark.h \
lexmark.conf.in \
lm9830.h \
ma1509.c ma1509.conf.in ma1509.h \
Makefile.in matsushita.c \
@ -315,7 +316,7 @@ EXTRA_hp = hp-accessor hp-device hp-handle hp-hpmem hp-option hp-scl
EXTRA_umax_pp = umax_pp_low umax_pp_mid
EXTRA_epson = epson_scsi epson_usb
EXTRA_epson2 = epson2_scsi epson_usb epson2_net epson2-io epson2-commands
EXTRA_lexmark = lexmark-x1100
EXTRA_lexmark = lexmark_low
EXTRA_pixma = pixma_io_sanei pixma_common pixma_mp150 pixma_mp730 pixma_mp750
# When preloading dll, we need to add in all preloaded objects:

Plik diff jest za duży Load Diff

Wyświetl plik

@ -2,6 +2,7 @@
(C) 2003-2004 Lexmark International, Inc. (Original Source code)
(C) 2005 Fred Odendaal
(C) 2006-2007 Stéphane Voltz <stef.dev@free.fr>
This file is part of the SANE package.
@ -69,11 +70,9 @@
#include "../include/sane/sanei_backend.h"
#define LEXMARK_CONFIG_FILE "lexmark.conf"
#define BUILD 0
#define BUILD 19
#define MAX_OPTION_STRING_SIZE 255
#define MM_PER_INCH 25.4
static Lexmark_Device *first_lexmark_device = 0;
static SANE_Int num_lexmark_device = 0;
@ -89,37 +88,62 @@ static SANE_String_Const mode_list[] = {
NULL
};
/* possible resolutions are: 75x75, 150x150, 300x300, 600X600, 600X1200 */
/* possible resolutions are: 75x75, 150x150, 300x300, 600x600, 600x1200 */
static SANE_Int dpi_list[] = {
static SANE_Int x1100_dpi_list[] = {
5, 75, 150, 300, 600, 1200
};
static SANE_String_Const size_list[] = {
"Wallet", "3x5", "4x6", "5x7", "8x10", "Letter", NULL
static SANE_Int a920_dpi_list[] = {
4, 75, 150, 300, 600
};
static SANE_Int x1200_dpi_list[] = {
4, 75, 150, 300, 600
};
static SANE_Range threshold_range = {
SANE_FIX(0.0), /* minimum */
SANE_FIX(100.0), /* maximum */
SANE_FIX(1.0) /* quantization */
SANE_FIX (0.0), /* minimum */
SANE_FIX (100.0), /* maximum */
SANE_FIX (1.0) /* quantization */
};
static const SANE_Range gain_range = {
0, /* minimum */
31, /* maximum */
0 /* quantization */
};
/* for now known models (2 ...) have the same scan window geometry.
coordinates are expressed in pixels, with a quantization factor of
8 to have 'even' coordinates at 75 dpi */
static SANE_Range x_range = {
0, /* minimum */
5104, /* maximum */
16 /* quantization : 16 is required so we
never have an odd width */
};
static SANE_Range y_range = {
0, /* minimum */
6848, /* maximum */
8 /* quantization */
};
/* static functions */
static SANE_Status init_options (Lexmark_Device * lexmark_device);
static SANE_Status attachLexmark (SANE_String_Const devname);
SANE_Status
init_options (Lexmark_Device * lexmark_device)
init_options (Lexmark_Device * dev)
{
SANE_Option_Descriptor *od;
DBG (2, "init_options: lexmark_device = %p\n", (void *) lexmark_device);
DBG (2, "init_options: dev = %p\n", (void *) dev);
/* number of options */
od = &(lexmark_device->opt[OPT_NUM_OPTS]);
od = &(dev->opt[OPT_NUM_OPTS]);
od->name = SANE_NAME_NUM_OPTIONS;
od->title = SANE_TITLE_NUM_OPTIONS;
od->desc = SANE_DESC_NUM_OPTIONS;
@ -129,10 +153,10 @@ init_options (Lexmark_Device * lexmark_device)
od->cap = SANE_CAP_SOFT_DETECT;
od->constraint_type = SANE_CONSTRAINT_NONE;
od->constraint.range = 0;
lexmark_device->val[OPT_NUM_OPTS].w = NUM_OPTIONS;
dev->val[OPT_NUM_OPTS].w = NUM_OPTIONS;
/* mode - sets the scan mode: Color, Gray, or Line Art */
od = &(lexmark_device->opt[OPT_MODE]);
od = &(dev->opt[OPT_MODE]);
od->name = SANE_NAME_SCAN_MODE;
od->title = SANE_TITLE_SCAN_MODE;
od->desc = SANE_DESC_SCAN_MODE;;
@ -142,13 +166,13 @@ init_options (Lexmark_Device * lexmark_device)
od->cap = SANE_CAP_SOFT_DETECT | SANE_CAP_SOFT_SELECT;
od->constraint_type = SANE_CONSTRAINT_STRING_LIST;
od->constraint.string_list = mode_list;
lexmark_device->val[OPT_MODE].s = malloc (od->size);
if (!lexmark_device->val[OPT_MODE].s)
dev->val[OPT_MODE].s = malloc (od->size);
if (!dev->val[OPT_MODE].s)
return SANE_STATUS_NO_MEM;
strcpy (lexmark_device->val[OPT_MODE].s, SANE_VALUE_SCAN_MODE_COLOR);
strcpy (dev->val[OPT_MODE].s, SANE_VALUE_SCAN_MODE_COLOR);
/* resolution */
od = &(lexmark_device->opt[OPT_RESOLUTION]);
od = &(dev->opt[OPT_RESOLUTION]);
od->name = SANE_NAME_SCAN_RESOLUTION;
od->title = SANE_TITLE_SCAN_RESOLUTION;
od->desc = SANE_DESC_SCAN_RESOLUTION;
@ -157,11 +181,24 @@ init_options (Lexmark_Device * lexmark_device)
od->size = sizeof (SANE_Word);
od->cap = SANE_CAP_SOFT_DETECT | SANE_CAP_SOFT_SELECT;
od->constraint_type = SANE_CONSTRAINT_WORD_LIST;
od->constraint.word_list = dpi_list;
lexmark_device->val[OPT_RESOLUTION].w = 150;
switch (dev->model.sensor_type)
{
case X1100_2C_SENSOR:
case A920_SENSOR:
od->constraint.word_list = a920_dpi_list;
break;
case X1100_B2_SENSOR:
od->constraint.word_list = x1100_dpi_list;
od->constraint.word_list = x1100_dpi_list;
break;
case X1200_SENSOR:
od->constraint.word_list = x1200_dpi_list;
break;
}
dev->val[OPT_RESOLUTION].w = 75;
/* preview mode */
od = &(lexmark_device->opt[OPT_PREVIEW]);
od = &(dev->opt[OPT_PREVIEW]);
od->name = SANE_NAME_PREVIEW;
od->title = SANE_TITLE_PREVIEW;
od->desc = SANE_DESC_PREVIEW;
@ -169,26 +206,72 @@ init_options (Lexmark_Device * lexmark_device)
od->cap = SANE_CAP_SOFT_DETECT | SANE_CAP_SOFT_SELECT;
od->type = SANE_TYPE_BOOL;
od->constraint_type = SANE_CONSTRAINT_NONE;
lexmark_device->val[OPT_PREVIEW].w = SANE_FALSE;
dev->val[OPT_PREVIEW].w = SANE_FALSE;
/* scan size */
od = &(lexmark_device->opt[OPT_SCAN_SIZE]);
od->name = SANE_NAME_PAPER_SIZE;
od->title = SANE_TITLE_PAPER_SIZE;
od->desc = SANE_DESC_PAPER_SIZE;
od->type = SANE_TYPE_STRING;
od->unit = SANE_UNIT_NONE;
od->size = MAX_OPTION_STRING_SIZE;
/* "Geometry" group: */
od = &(dev->opt[OPT_GEOMETRY_GROUP]);
od->name = "";
od->title = SANE_I18N ("Geometry");
od->desc = "";
od->type = SANE_TYPE_GROUP;
od->cap = SANE_CAP_SOFT_DETECT | SANE_CAP_SOFT_SELECT;
od->constraint_type = SANE_CONSTRAINT_STRING_LIST;
od->constraint.string_list = size_list;
lexmark_device->val[OPT_SCAN_SIZE].s = malloc (od->size);
if (!lexmark_device->val[OPT_SCAN_SIZE].s)
return SANE_STATUS_NO_MEM;
strcpy (lexmark_device->val[OPT_SCAN_SIZE].s, "3x5");
od->size = 0;
od->constraint_type = SANE_CONSTRAINT_NONE;
/* top-left x */
od = &(dev->opt[OPT_TL_X]);
od->name = SANE_NAME_SCAN_TL_X;
od->title = SANE_TITLE_SCAN_TL_X;
od->desc = SANE_DESC_SCAN_TL_X;
od->type = SANE_TYPE_INT;
od->cap = SANE_CAP_SOFT_DETECT | SANE_CAP_SOFT_SELECT;
od->size = sizeof (SANE_Word);
od->unit = SANE_UNIT_PIXEL;
od->constraint_type = SANE_CONSTRAINT_RANGE;
od->constraint.range = &x_range;
dev->val[OPT_TL_X].w = 0;
/* top-left y */
od = &(dev->opt[OPT_TL_Y]);
od->name = SANE_NAME_SCAN_TL_Y;
od->title = SANE_TITLE_SCAN_TL_Y;
od->desc = SANE_DESC_SCAN_TL_Y;
od->type = SANE_TYPE_INT;
od->cap = SANE_CAP_SOFT_DETECT | SANE_CAP_SOFT_SELECT;
od->size = sizeof (SANE_Word);
od->unit = SANE_UNIT_PIXEL;
od->constraint_type = SANE_CONSTRAINT_RANGE;
od->constraint.range = &y_range;
dev->val[OPT_TL_Y].w = 0;
/* bottom-right x */
od = &(dev->opt[OPT_BR_X]);
od->name = SANE_NAME_SCAN_BR_X;
od->title = SANE_TITLE_SCAN_BR_X;
od->desc = SANE_DESC_SCAN_BR_X;
od->type = SANE_TYPE_INT;
od->size = sizeof (SANE_Word);
od->cap = SANE_CAP_SOFT_DETECT | SANE_CAP_SOFT_SELECT;
od->unit = SANE_UNIT_PIXEL;
od->constraint_type = SANE_CONSTRAINT_RANGE;
od->constraint.range = &x_range;
dev->val[OPT_BR_X].w = x_range.max;
/* bottom-right y */
od = &(dev->opt[OPT_BR_Y]);
od->name = SANE_NAME_SCAN_BR_Y;
od->title = SANE_TITLE_SCAN_BR_Y;
od->desc = SANE_DESC_SCAN_BR_Y;
od->type = SANE_TYPE_INT;
od->size = sizeof (SANE_Word);
od->cap = SANE_CAP_SOFT_DETECT | SANE_CAP_SOFT_SELECT;
od->unit = SANE_UNIT_PIXEL;
od->constraint_type = SANE_CONSTRAINT_RANGE;
od->constraint.range = &y_range;
dev->val[OPT_BR_Y].w = y_range.max;
/* threshold */
od = &(lexmark_device->opt[OPT_THRESHOLD]);
od = &(dev->opt[OPT_THRESHOLD]);
od->name = SANE_NAME_THRESHOLD;
od->title = SANE_TITLE_THRESHOLD;
od->desc = SANE_DESC_THRESHOLD;
@ -198,7 +281,73 @@ init_options (Lexmark_Device * lexmark_device)
od->cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT | SANE_CAP_INACTIVE;
od->constraint_type = SANE_CONSTRAINT_RANGE;
od->constraint.range = &threshold_range;
lexmark_device->val[OPT_THRESHOLD].w = SANE_FIX(50.0);
dev->val[OPT_THRESHOLD].w = SANE_FIX (50.0);
/* gain group */
dev->opt[OPT_MANUAL_GAIN].name = "manual-channel-gain";
dev->opt[OPT_MANUAL_GAIN].title = SANE_I18N ("Gain");
dev->opt[OPT_MANUAL_GAIN].desc = SANE_I18N ("Color channels gain settings");
dev->opt[OPT_MANUAL_GAIN].type = SANE_TYPE_BOOL;
dev->opt[OPT_MANUAL_GAIN].cap =
SANE_CAP_SOFT_DETECT | SANE_CAP_SOFT_SELECT | SANE_CAP_ADVANCED;
dev->opt[OPT_MANUAL_GAIN].size = sizeof (SANE_Bool);
dev->val[OPT_MANUAL_GAIN].w = SANE_FALSE;
/* gray gain */
dev->opt[OPT_GRAY_GAIN].name = "gray-gain";
dev->opt[OPT_GRAY_GAIN].title = SANE_I18N ("Gray gain");
dev->opt[OPT_GRAY_GAIN].desc = SANE_I18N ("Sets gray channel gain");
dev->opt[OPT_GRAY_GAIN].type = SANE_TYPE_INT;
dev->opt[OPT_GRAY_GAIN].cap =
SANE_CAP_SOFT_DETECT | SANE_CAP_SOFT_SELECT | SANE_CAP_INACTIVE |
SANE_CAP_ADVANCED;
dev->opt[OPT_GRAY_GAIN].unit = SANE_UNIT_NONE;
dev->opt[OPT_GRAY_GAIN].size = sizeof (SANE_Int);
dev->opt[OPT_GRAY_GAIN].constraint_type = SANE_CONSTRAINT_RANGE;
dev->opt[OPT_GRAY_GAIN].constraint.range = &gain_range;
dev->val[OPT_GRAY_GAIN].w = 10;
/* red gain */
dev->opt[OPT_RED_GAIN].name = "red-gain";
dev->opt[OPT_RED_GAIN].title = SANE_I18N ("Red gain");
dev->opt[OPT_RED_GAIN].desc = SANE_I18N ("Sets red channel gain");
dev->opt[OPT_RED_GAIN].type = SANE_TYPE_INT;
dev->opt[OPT_RED_GAIN].cap =
SANE_CAP_SOFT_DETECT | SANE_CAP_SOFT_SELECT | SANE_CAP_INACTIVE |
SANE_CAP_ADVANCED;
dev->opt[OPT_RED_GAIN].unit = SANE_UNIT_NONE;
dev->opt[OPT_RED_GAIN].size = sizeof (SANE_Int);
dev->opt[OPT_RED_GAIN].constraint_type = SANE_CONSTRAINT_RANGE;
dev->opt[OPT_RED_GAIN].constraint.range = &gain_range;
dev->val[OPT_RED_GAIN].w = 10;
/* green gain */
dev->opt[OPT_GREEN_GAIN].name = "green-gain";
dev->opt[OPT_GREEN_GAIN].title = SANE_I18N ("Green gain");
dev->opt[OPT_GREEN_GAIN].desc = SANE_I18N ("Sets green channel gain");
dev->opt[OPT_GREEN_GAIN].type = SANE_TYPE_INT;
dev->opt[OPT_GREEN_GAIN].cap =
SANE_CAP_SOFT_DETECT | SANE_CAP_SOFT_SELECT | SANE_CAP_INACTIVE |
SANE_CAP_ADVANCED;
dev->opt[OPT_GREEN_GAIN].unit = SANE_UNIT_NONE;
dev->opt[OPT_GREEN_GAIN].size = sizeof (SANE_Int);
dev->opt[OPT_GREEN_GAIN].constraint_type = SANE_CONSTRAINT_RANGE;
dev->opt[OPT_GREEN_GAIN].constraint.range = &gain_range;
dev->val[OPT_GREEN_GAIN].w = 10;
/* blue gain */
dev->opt[OPT_BLUE_GAIN].name = "blue-gain";
dev->opt[OPT_BLUE_GAIN].title = SANE_I18N ("Blue gain");
dev->opt[OPT_BLUE_GAIN].desc = SANE_I18N ("Sets blue channel gain");
dev->opt[OPT_BLUE_GAIN].type = SANE_TYPE_INT;
dev->opt[OPT_BLUE_GAIN].cap =
SANE_CAP_SOFT_DETECT | SANE_CAP_SOFT_SELECT | SANE_CAP_INACTIVE |
SANE_CAP_ADVANCED;
dev->opt[OPT_BLUE_GAIN].unit = SANE_UNIT_NONE;
dev->opt[OPT_BLUE_GAIN].size = sizeof (SANE_Int);
dev->opt[OPT_BLUE_GAIN].constraint_type = SANE_CONSTRAINT_RANGE;
dev->opt[OPT_BLUE_GAIN].constraint.range = &gain_range;
dev->val[OPT_BLUE_GAIN].w = 10;
return SANE_STATUS_GOOD;
}
@ -210,6 +359,8 @@ SANE_Status
attachLexmark (SANE_String_Const devname)
{
Lexmark_Device *lexmark_device;
SANE_Int dn, vendor, product;
SANE_Status status;
DBG (2, "attachLexmark: devname=%s\n", devname);
@ -224,10 +375,63 @@ attachLexmark (SANE_String_Const devname)
if (lexmark_device == NULL)
return SANE_STATUS_NO_MEM;
lexmark_device->sane.name = strdup (devname);
lexmark_device->sane.vendor = "Lexmark";
lexmark_device->sane.model = "X1100";
lexmark_device->sane.type = "flatbed scanner";
#ifdef FAKE_USB
status = SANE_STATUS_GOOD;
#else
status = sanei_usb_open (devname, &dn);
#endif
if (status != SANE_STATUS_GOOD)
{
DBG (1, "attachLexmark: couldn't open device `%s': %s\n", devname,
sane_strstatus (status));
return status;
}
else
DBG (2, "attachLexmark: device `%s' successfully opened\n", devname);
#ifdef FAKE_USB
status = SANE_STATUS_GOOD;
/* put the id of the model you want to fake here */
vendor = 0x043d;
product = 0x007d; /* X12xx */
#else
status = sanei_usb_get_vendor_product (dn, &vendor, &product);
#endif
if (status != SANE_STATUS_GOOD)
{
DBG (1,
"attachLexmark: couldn't get vendor and product ids of device `%s': %s\n",
devname, sane_strstatus (status));
#ifndef FAKE_USB
sanei_usb_close (dn);
#endif
return status;
}
#ifndef FAKE_USB
sanei_usb_close (dn);
#endif
DBG (2, "attachLexmark: testing device `%s': 0x%04x:0x%04x, no variant\n",
devname, vendor, product);
if (sanei_lexmark_low_assign_model (lexmark_device,
devname,
vendor,
product,
0) != SANE_STATUS_GOOD)
{
DBG (2, "attachLexmark: unsupported device `%s': 0x%04x:0x%04x\n",
devname, vendor, product);
return SANE_STATUS_UNSUPPORTED;
}
/* there are two variant of the scanner with the same USB id,
* so we need to read registers from scanner to detect which one
* is really connected */
status = sanei_lexmark_low_open_device (lexmark_device);
sanei_usb_close (lexmark_device->devnum);
/* set up scanner start status */
sanei_lexmark_low_init (lexmark_device);
/* Set the default resolution here */
lexmark_device->x_dpi = 75;
@ -239,6 +443,8 @@ attachLexmark (SANE_String_Const devname)
/* Set the default threshold for lineart mode here */
lexmark_device->threshold = 0x80;
lexmark_device->shading_coeff = NULL;
lexmark_device->next = first_lexmark_device;
first_lexmark_device = lexmark_device;
@ -255,12 +461,12 @@ sane_init (SANE_Int * version_code, SANE_Auth_Callback authorize)
const char *lp;
SANE_Int vendor, product;
size_t len;
SANE_Status status;
SANE_Status status = SANE_STATUS_GOOD;
SANE_Auth_Callback auth_callback;
DBG_INIT ();
DBG (1, "SANE Lexmark backend version %d.%d-%d\n", V_MAJOR, V_MINOR, BUILD);
DBG (1, "SANE Lexmark backend version %d.%d-rc2-%d\n", V_MAJOR, V_MINOR, BUILD);
auth_callback = authorize;
@ -269,15 +475,14 @@ sane_init (SANE_Int * version_code, SANE_Auth_Callback authorize)
if (version_code)
*version_code = SANE_VERSION_CODE (V_MAJOR, V_MINOR, BUILD);
status = sanei_lexmark_x1100_init ();
if (status != SANE_STATUS_GOOD)
return status;
#ifndef FAKE_USB
sanei_usb_init ();
#endif
fp = sanei_config_open (LEXMARK_CONFIG_FILE);
if (!fp)
{
/* sanei_lexmark_x1100_destroy (); */
/* sanei_lexmark_low_destroy (); */
return SANE_STATUS_ACCESS_DENIED;
}
@ -292,7 +497,6 @@ sane_init (SANE_Int * version_code, SANE_Auth_Callback authorize)
if (line[len - 1] == '\n')
line[--len] = '\0';
/* lp = (SANE_String) sanei_config_skip_whitespace (line); */
lp = sanei_config_skip_whitespace (line);
/* skip empty lines */
if (*lp == 0)
@ -305,21 +509,23 @@ sane_init (SANE_Int * version_code, SANE_Auth_Callback authorize)
else if ((strncmp ("usb", lp, 3) == 0) && isspace (lp[3]))
{
lp += 3;
/* lp = (SANE_String) sanei_config_skip_whitespace (lp); */
lp = sanei_config_skip_whitespace (lp);
}
else
continue;
#ifdef FAKE_USB
attachLexmark ("FAKE_USB");
#else
sanei_usb_attach_matching_devices (lp, attachLexmark);
#endif
}
fclose (fp);
initialized = SANE_TRUE;
return SANE_STATUS_GOOD;
return status;
}
void
@ -336,7 +542,7 @@ sane_exit (void)
lexmark_device = next_lexmark_device)
{
next_lexmark_device = lexmark_device->next;
sanei_lexmark_x1100_destroy (lexmark_device);
sanei_lexmark_low_destroy (lexmark_device);
free (lexmark_device);
}
@ -384,6 +590,14 @@ sane_get_devices (const SANE_Device *** device_list, SANE_Bool local_only)
return SANE_STATUS_GOOD;
}
/**
* Open the backend, ie return the struct handle of a detected scanner
* The struct returned is choosne if it matches the name given, which is
* usefull when several scanners handled by the backend have been detected.
* However, special case empty string "" and "lexmark" pick the first
* available handle.
*/
SANE_Status
sane_open (SANE_String_Const devicename, SANE_Handle * handle)
{
@ -405,12 +619,16 @@ sane_open (SANE_String_Const devicename, SANE_Handle * handle)
return SANE_STATUS_INVAL;
}
/* walk the linked list of scanner device until ther is a match
* with the device name */
for (lexmark_device = first_lexmark_device; lexmark_device;
lexmark_device = lexmark_device->next)
{
DBG (2, "sane_open: devname from list: %s\n",
lexmark_device->sane.name);
if (strcmp (devicename, lexmark_device->sane.name) == 0)
if (strcmp (devicename, "") == 0
|| strcmp (devicename, "lexmark") == 0
|| strcmp (devicename, lexmark_device->sane.name) == 0)
break;
}
@ -418,7 +636,7 @@ sane_open (SANE_String_Const devicename, SANE_Handle * handle)
if (!lexmark_device)
{
DBG (2, "sane_open: Not a Lexmark device\n");
DBG (2, "sane_open: Not a lexmark device\n");
return SANE_STATUS_INVAL;
}
@ -426,13 +644,10 @@ sane_open (SANE_String_Const devicename, SANE_Handle * handle)
if (status != SANE_STATUS_GOOD)
return status;
/* status = llpddk_open_device (lexmark_device->sane.name); */
status =
sanei_lexmark_x1100_open_device (lexmark_device->sane.name, &(lexmark_device->devnum));
if (status != SANE_STATUS_GOOD)
return status;
status = sanei_lexmark_low_open_device (lexmark_device);
DBG (2, "sane_open: end.\n");
return SANE_STATUS_GOOD;
return status;
}
void
@ -455,8 +670,7 @@ sane_close (SANE_Handle handle)
if (!lexmark_device)
return;
/* llpddk_close_device (); */
sanei_lexmark_x1100_close_device (lexmark_device->devnum);
sanei_lexmark_low_close_device (lexmark_device);
return;
}
@ -486,15 +700,65 @@ sane_get_option_descriptor (SANE_Handle handle, SANE_Int option)
if (!lexmark_device)
return NULL;
if (lexmark_device->opt[option].name)
{
DBG (2, "sane_get_option_descriptor: name=%s\n",
lexmark_device->opt[option].name);
}
return &(lexmark_device->opt[option]);
}
/* rebuilds parameters if needed, called each time SANE_INFO_RELOAD_OPTIONS
is set */
static void
calc_parameters (Lexmark_Device * lexmark_device)
{
if (strcmp (lexmark_device->val[OPT_MODE].s,
SANE_VALUE_SCAN_MODE_LINEART) == 0)
{
lexmark_device->opt[OPT_THRESHOLD].cap &= ~SANE_CAP_INACTIVE;
}
else
{
lexmark_device->opt[OPT_THRESHOLD].cap |= SANE_CAP_INACTIVE;
}
/* changing color mode implies changing gain setting */
if (lexmark_device->val[OPT_MANUAL_GAIN].w == SANE_TRUE)
{
if (strcmp (lexmark_device->val[OPT_MODE].s, SANE_VALUE_SCAN_MODE_COLOR)
!= 0)
{
lexmark_device->opt[OPT_GRAY_GAIN].cap &= ~SANE_CAP_INACTIVE;
lexmark_device->opt[OPT_RED_GAIN].cap |= SANE_CAP_INACTIVE;
lexmark_device->opt[OPT_GREEN_GAIN].cap |= SANE_CAP_INACTIVE;
lexmark_device->opt[OPT_BLUE_GAIN].cap |= SANE_CAP_INACTIVE;
}
else
{
lexmark_device->opt[OPT_GRAY_GAIN].cap |= SANE_CAP_INACTIVE;
lexmark_device->opt[OPT_RED_GAIN].cap &= ~SANE_CAP_INACTIVE;
lexmark_device->opt[OPT_GREEN_GAIN].cap &= ~SANE_CAP_INACTIVE;
lexmark_device->opt[OPT_BLUE_GAIN].cap &= ~SANE_CAP_INACTIVE;
}
}
else
{
lexmark_device->opt[OPT_GRAY_GAIN].cap |= SANE_CAP_INACTIVE;
lexmark_device->opt[OPT_RED_GAIN].cap |= SANE_CAP_INACTIVE;
lexmark_device->opt[OPT_GREEN_GAIN].cap |= SANE_CAP_INACTIVE;
lexmark_device->opt[OPT_BLUE_GAIN].cap |= SANE_CAP_INACTIVE;
}
}
SANE_Status
sane_control_option (SANE_Handle handle, SANE_Int option, SANE_Action action,
void *value, SANE_Int * info)
{
Lexmark_Device *lexmark_device;
SANE_Status status;
SANE_Word w;
DBG (2, "sane_control_option: handle=%p, opt=%d, act=%d, val=%p, info=%p\n",
(void *) handle, option, action, (void *) value, (void *) info);
@ -557,7 +821,7 @@ sane_control_option (SANE_Handle handle, SANE_Int option, SANE_Action action,
info);
if (status != SANE_STATUS_GOOD)
{
DBG(2, "SANE_CONTROL_OPTION: Bad value for range\n");
DBG (2, "SANE_CONTROL_OPTION: Bad value for range\n");
return SANE_STATUS_INVAL;
}
}
@ -569,12 +833,38 @@ sane_control_option (SANE_Handle handle, SANE_Int option, SANE_Action action,
lexmark_device->val[option].w = *(SANE_Int *) value;
sane_get_parameters (handle, 0);
break;
case OPT_TL_X:
case OPT_TL_Y:
case OPT_BR_X:
case OPT_BR_Y:
DBG (2, "Option value set to %d (%s)\n", *(SANE_Word *) value,
lexmark_device->opt[option].name);
lexmark_device->val[option].w = *(SANE_Word *) value;
if (lexmark_device->val[OPT_TL_X].w >
lexmark_device->val[OPT_BR_X].w)
{
w = lexmark_device->val[OPT_TL_X].w;
lexmark_device->val[OPT_TL_X].w =
lexmark_device->val[OPT_BR_X].w;
lexmark_device->val[OPT_BR_X].w = w;
if (info)
*info |= SANE_INFO_RELOAD_PARAMS;
}
if (lexmark_device->val[OPT_TL_Y].w >
lexmark_device->val[OPT_BR_Y].w)
{
w = lexmark_device->val[OPT_TL_Y].w;
lexmark_device->val[OPT_TL_Y].w =
lexmark_device->val[OPT_BR_Y].w;
lexmark_device->val[OPT_BR_Y].w = w;
if (info)
*info |= SANE_INFO_RELOAD_PARAMS;
}
break;
case OPT_THRESHOLD:
lexmark_device->val[option].w = *(SANE_Fixed *) value;
lexmark_device->threshold = 0xFF * (lexmark_device->val[option].w/100);
break;
case OPT_SCAN_SIZE:
strcpy (lexmark_device->val[option].s, value);
lexmark_device->threshold =
(0xFF * lexmark_device->val[option].w) / 100;
break;
case OPT_PREVIEW:
lexmark_device->val[option].w = *(SANE_Int *) value;
@ -592,23 +882,31 @@ sane_control_option (SANE_Handle handle, SANE_Int option, SANE_Action action,
sane_get_parameters (handle, 0);
if (info)
*info |= SANE_INFO_RELOAD_PARAMS;
break;
case OPT_GRAY_GAIN:
case OPT_GREEN_GAIN:
case OPT_RED_GAIN:
case OPT_BLUE_GAIN:
lexmark_device->val[option].w = *(SANE_Word *) value;
return SANE_STATUS_GOOD;
lexmark_device->val[option].w = *(SANE_Int *) value;
break;
case OPT_MODE:
strcpy (lexmark_device->val[option].s, value);
if (strcmp (lexmark_device->val[option].s,
SANE_VALUE_SCAN_MODE_LINEART) == 0)
{
lexmark_device->opt[OPT_THRESHOLD].cap &= ~SANE_CAP_INACTIVE;
}
else
{
lexmark_device->opt[OPT_THRESHOLD].cap |= SANE_CAP_INACTIVE;
}
calc_parameters (lexmark_device);
if (info)
*info |= SANE_INFO_RELOAD_PARAMS | SANE_INFO_RELOAD_OPTIONS;
break;
return SANE_STATUS_GOOD;
case OPT_MANUAL_GAIN:
w = *(SANE_Word *) value;
if (w == lexmark_device->val[OPT_MANUAL_GAIN].w)
return SANE_STATUS_GOOD; /* no change */
lexmark_device->val[OPT_MANUAL_GAIN].w = w;
calc_parameters (lexmark_device);
if (info)
*info |= SANE_INFO_RELOAD_OPTIONS;
return SANE_STATUS_GOOD;
}
if (info != NULL)
@ -623,15 +921,24 @@ sane_control_option (SANE_Handle handle, SANE_Int option, SANE_Action action,
case OPT_NUM_OPTS:
case OPT_RESOLUTION:
case OPT_PREVIEW:
*(SANE_Int *) value = lexmark_device->val[option].w;
DBG(2,"Option value = %d\n", *(SANE_Int *) value);
case OPT_MANUAL_GAIN:
case OPT_GRAY_GAIN:
case OPT_GREEN_GAIN:
case OPT_RED_GAIN:
case OPT_BLUE_GAIN:
case OPT_TL_X:
case OPT_TL_Y:
case OPT_BR_X:
case OPT_BR_Y:
*(SANE_Word *) value = lexmark_device->val[option].w;
DBG (2, "Option value = %d (%s)\n", *(SANE_Word *) value,
lexmark_device->opt[option].name);
break;
case OPT_THRESHOLD:
*(SANE_Fixed *) value = lexmark_device->val[option].w;
DBG(2,"Option value = %f\n", SANE_UNFIX(*(SANE_Fixed *) value));
DBG (2, "Option value = %f\n", SANE_UNFIX (*(SANE_Fixed *) value));
break;
case OPT_MODE:
case OPT_SCAN_SIZE:
strcpy (value, lexmark_device->val[option].s);
break;
default:
@ -655,8 +962,6 @@ sane_get_parameters (SANE_Handle handle, SANE_Parameters * params)
SANE_Parameters *device_params;
SANE_Int xres, yres, width_px, height_px;
SANE_Int channels, bitsperchannel;
double width, height;
SANE_Bool isColourScan;
DBG (2, "sane_get_parameters: handle=%p, params=%p\n", (void *) handle,
(void *) params);
@ -683,7 +988,6 @@ sane_get_parameters (SANE_Handle handle, SANE_Parameters * params)
/* 24 bit colour = 8 bits/channel for each of the RGB channels */
channels = 3;
bitsperchannel = 8;
isColourScan = SANE_TRUE;
/* If not color there is only 1 channel */
if (strcmp (lexmark_device->val[OPT_MODE].s, SANE_VALUE_SCAN_MODE_COLOR)
@ -691,65 +995,17 @@ sane_get_parameters (SANE_Handle handle, SANE_Parameters * params)
{
channels = 1;
bitsperchannel = 8;
isColourScan = SANE_FALSE;
}
/* geometry in pixels */
width_px =
lexmark_device->val[OPT_BR_X].w - lexmark_device->val[OPT_TL_X].w;
height_px =
lexmark_device->val[OPT_BR_Y].w - lexmark_device->val[OPT_TL_Y].w;
DBG (7, "sane_get_parameters: tl=(%d,%d) br=(%d,%d)\n",
lexmark_device->val[OPT_TL_X].w, lexmark_device->val[OPT_TL_Y].w,
lexmark_device->val[OPT_BR_X].w, lexmark_device->val[OPT_BR_Y].w);
/* size in inches */
if (strcmp (lexmark_device->val[OPT_SCAN_SIZE].s, "Wallet") == 0)
{
width = 2.50;
height = 3.50;
}
else if (strcmp (lexmark_device->val[OPT_SCAN_SIZE].s, "3x5") == 0)
{
width = 3.00;
height = 5.00;
}
else if (strcmp (lexmark_device->val[OPT_SCAN_SIZE].s, "4x6") == 0)
{
width = 4.00;
height = 6.00;
}
else if (strcmp (lexmark_device->val[OPT_SCAN_SIZE].s, "5x7") == 0)
{
width = 5.00;
height = 7.00;
}
else if (strcmp (lexmark_device->val[OPT_SCAN_SIZE].s, "8x10") == 0)
{
width = 8.00;
height = 10.00;
}
else if (strcmp (lexmark_device->val[OPT_SCAN_SIZE].s, "Letter") == 0)
{
width = 8.50;
height = 11.00;
}
else
{
DBG (2, "sane_get_parameters - ERROR: Unknown Scan Size option\n");
return SANE_STATUS_INVAL;
}
/* in pixels */
width_px = (SANE_Int) (width * xres);
/* not sure why this is so - if its odd add one */
if ((width_px & 0x01) == 1)
width_px = width_px + 1;
height_px = (SANE_Int) (height * yres);
/* Stashed with device record for easy retrieval later */
lexmark_device->pixel_width = width_px;
lexmark_device->pixel_height = height_px;
/* data_size is the size transferred from the scanner to the backend */
/* therefor bitsperchannel is the same for gray and lineart */
lexmark_device->data_size =
width_px * height_px * channels * (bitsperchannel / 8);
DBG (2, "sane_get_parameters: Data size determined as %lx\n",
lexmark_device->data_size);
/* we must tell the front end the bitsperchannel for lineart is really */
/* only 1, so it can calculate the correct image size */
@ -765,21 +1021,31 @@ sane_get_parameters (SANE_Handle handle, SANE_Parameters * params)
if (channels == 1)
device_params->format = SANE_FRAME_GRAY;
device_params->last_frame = SANE_TRUE;
device_params->lines = height_px;
device_params->lines = (height_px * yres) / 600;
device_params->depth = bitsperchannel;
device_params->pixels_per_line = width_px;
device_params->bytes_per_line =
(SANE_Int) (channels * device_params->pixels_per_line *
(bitsperchannel / 8));
if ( bitsperchannel == 1 )
device_params->pixels_per_line = (width_px * xres) / 600;
/* we always read an even number of sensor pixels */
if (device_params->pixels_per_line & 1)
device_params->pixels_per_line++;
/* data_size is the size transferred from the scanner to the backend */
/* therefore bitsperchannel is the same for gray and lineart */
/* note: bytes_per_line has been divided by 8 in lineart mode */
lexmark_device->data_size =
channels * device_params->pixels_per_line * device_params->lines;
if (bitsperchannel == 1)
{
device_params->bytes_per_line =
(SANE_Int) (device_params->pixels_per_line / 8);
if ((device_params->pixels_per_line % 8) != 0)
device_params->bytes_per_line++;
(SANE_Int) ((7 + device_params->pixels_per_line) / 8);
}
else
{
device_params->bytes_per_line =
(SANE_Int) (channels * device_params->pixels_per_line);
}
DBG (2, "sane_get_parameters: Data size determined as %ld\n",
lexmark_device->data_size);
DBG (2, "sane_get_parameters: \n");
if (device_params->format == SANE_FRAME_GRAY)
@ -792,10 +1058,10 @@ sane_get_parameters (SANE_Handle handle, SANE_Parameters * params)
DBG (2, " last_frame: TRUE\n");
else
DBG (2, " last_frame: FALSE\n");
DBG (2, " lines %x\n", device_params->lines);
DBG (2, " depth %x\n", device_params->depth);
DBG (2, " pixels_per_line %x\n", device_params->pixels_per_line);
DBG (2, " bytes_per_line %x\n", device_params->bytes_per_line);
DBG (2, " lines %d\n", device_params->lines);
DBG (2, " depth %d\n", device_params->depth);
DBG (2, " pixels_per_line %d\n", device_params->pixels_per_line);
DBG (2, " bytes_per_line %d\n", device_params->bytes_per_line);
if (params != 0)
{
@ -815,6 +1081,8 @@ sane_start (SANE_Handle handle)
{
Lexmark_Device *lexmark_device;
SANE_Int offset;
SANE_Status status;
int i;
DBG (2, "sane_start: handle=%p\n", (void *) handle);
@ -834,9 +1102,10 @@ sane_start (SANE_Handle handle)
(lexmark_device->params.pixels_per_line == 0) ||
(lexmark_device->params.bytes_per_line == 0))
{
DBG(2, "sane_start: \n");
DBG(2, " ERROR: Zero size encountered in:\n");
DBG(2, " number of lines, bytes per line, or pixels per line\n");
DBG (2, "sane_start: \n");
DBG (2, " ERROR: Zero size encountered in:\n");
DBG (2,
" number of lines, bytes per line, or pixels per line\n");
return SANE_STATUS_INVAL;
}
@ -850,7 +1119,7 @@ sane_start (SANE_Handle handle)
lexmark_device->cancel_ctr = 0;
/* Find Home */
if (sanei_lexmark_x1100_search_home_fwd (lexmark_device))
if (sanei_lexmark_low_search_home_fwd (lexmark_device))
{
DBG (2, "sane_start: Scan head initially at home position\n");
}
@ -858,24 +1127,37 @@ sane_start (SANE_Handle handle)
{
/* We may have been rewound too far, so move forward the distance from
the edge to the home position */
/* sanei_lexmark_x1100_move_fwd_a_bit(lexmark_device); */
sanei_lexmark_x1100_move_fwd (0x01a8, lexmark_device);
sanei_lexmark_low_move_fwd (0x01a8, lexmark_device,
lexmark_device->shadow_regs);
/* Scan backwards until we find home */
sanei_lexmark_x1100_search_home_bwd (lexmark_device);
sanei_lexmark_low_search_home_bwd (lexmark_device);
}
/* do calibration before offset detection */
sanei_lexmark_low_set_scan_regs (lexmark_device, 0, SANE_FALSE);
status = sanei_lexmark_low_calibration (lexmark_device);
if (status != SANE_STATUS_GOOD)
{
DBG (1, "sane_start: calibration failed : %s ! \n",
sane_strstatus (status));
return status;
}
/* At this point we're somewhere in the dot. We need to read a number of
lines greater than the diameter of the dot and determine how many lines
past the dot we've gone. We then use this information to see how far the
scan head must move before starting the scan. */
offset = sanei_lexmark_x1100_find_start_line (lexmark_device->devnum);
/* offset is in 600 dpi unit */
offset = sanei_lexmark_low_find_start_line (lexmark_device);
DBG (7, "start line offset=%d\n", offset);
/* Set the shadow registers for scan with the options (resolution, mode,
size) set in the front end. Pass the offset so we can get the vert.
start. */
sanei_lexmark_x1100_set_scan_regs (lexmark_device, offset);
sanei_lexmark_low_set_scan_regs (lexmark_device, offset, SANE_TRUE);
if (sanei_lexmark_x1100_start_scan (lexmark_device) == SANE_STATUS_GOOD)
if (sanei_lexmark_low_start_scan (lexmark_device) == SANE_STATUS_GOOD)
{
DBG (2, "sane_start: scan started\n");
return SANE_STATUS_GOOD;
@ -915,7 +1197,7 @@ sane_read (SANE_Handle handle, SANE_Byte * data,
{
DBG (2, "sane_read: Device was cancelled\n");
/* We don't know how far we've gone, so search for home. */
sanei_lexmark_x1100_search_home_bwd (lexmark_device);
sanei_lexmark_low_search_home_bwd (lexmark_device);
return SANE_STATUS_EOF;
}
@ -936,7 +1218,7 @@ sane_read (SANE_Handle handle, SANE_Byte * data,
if (!data)
return SANE_STATUS_INVAL;
bytes_read = sanei_lexmark_x1100_read_scan_data (data, max_length,
bytes_read = sanei_lexmark_low_read_scan_data (data, max_length,
lexmark_device);
if (bytes_read < 0)
return SANE_STATUS_IO_ERROR;
@ -984,8 +1266,8 @@ sane_set_io_mode (SANE_Handle handle, SANE_Bool non_blocking)
{
Lexmark_Device *lexmark_device;
DBG (2, "sane_set_io_mode: handle = %p, non_blocking = %d\n", (void *) handle,
non_blocking);
DBG (2, "sane_set_io_mode: handle = %p, non_blocking = %d\n",
(void *) handle, non_blocking);
if (!initialized)
return SANE_STATUS_INVAL;

Wyświetl plik

@ -1,2 +1,6 @@
#usb /dev/usb/scanner0
# X11xx series
usb 0x043d 0x007c
# X12xx series
usb 0x043d 0x007d
# Dell A920
usb 0x413c 0x5105

Wyświetl plik

@ -2,6 +2,7 @@
lexmark.h - SANE library for Lexmark scanners.
Copyright (C) 2003-2004 Lexmark International, Inc. (original source)
Copyright (C) 2005 Fred Odendaal
Copyright (C) 2006-2007 Stéphane Voltz <stef.dev@free.fr>
This file is part of the SANE package.
@ -44,34 +45,70 @@
#ifndef LEXMARK_H
#define LEXMARK_H
/* Force the backend name for all files using this include */
#ifdef BACKEND_NAME
#undef BACKEND_NAME
#define BACKEND_NAME lexmark
#endif
#define DEBUG_NOT_STATIC
#define SANE_NAME_PAPER_SIZE "paper-size"
#define SANE_TITLE_PAPER_SIZE SANE_I18N("Paper size")
#define SANE_DESC_PAPER_SIZE \
SANE_I18N("Selects the size of the area to be scanned.");
typedef enum
{
OPT_NUM_OPTS = 0,
OPT_MODE,
/* OPT_X_DPI, */
/* OPT_Y_DPI, */
OPT_RESOLUTION,
OPT_PREVIEW,
OPT_SCAN_SIZE,
OPT_THRESHOLD,
OPT_GEOMETRY_GROUP,
OPT_TL_X, /* top-left x */
OPT_TL_Y, /* top-left y */
OPT_BR_X, /* bottom-right x */
OPT_BR_Y, /* bottom-right y */
/* manual gain handling */
OPT_MANUAL_GAIN, /* 6 */
OPT_GRAY_GAIN,
OPT_RED_GAIN,
OPT_GREEN_GAIN,
OPT_BLUE_GAIN,
/* must come last: */
NUM_OPTIONS
}
Lexmark_Options;
/*
* this struct is used to described the specific parts of each model
*/
typedef struct Lexmark_Model
{
SANE_Int vendor_id;
SANE_Int product_id;
SANE_Byte mainboard_id; /* matched against the content of reg B0 */
SANE_String_Const name;
SANE_String_Const vendor;
SANE_String_Const model;
SANE_Int motor_type;
SANE_Int sensor_type;
} Lexmark_Model;
/*
* this struct is used to store per sensor model constants
*/
typedef struct Lexmark_Sensor
{
SANE_Int id;
SANE_Int offset_startx; /* starting x for offset calibration */
SANE_Int offset_endx; /* end x for offset calibration */
SANE_Int offset_threshold; /* target threshold for offset calibration */
SANE_Int xoffset; /* number of unusable pixels on the start of the sensor */
SANE_Int default_gain; /* value of the default gain for a scan */
SANE_Int red_gain_target;
SANE_Int green_gain_target;
SANE_Int blue_gain_target;
SANE_Int gray_gain_target;
SANE_Int red_shading_target;
SANE_Int green_shading_target;
SANE_Int blue_shading_target;
SANE_Int gray_shading_target;
SANE_Int offset_fallback; /* offset to use in case offset calibration fails */
SANE_Int gain_fallback; /* gain to use in case offset calibration fails */
} Lexmark_Sensor;
typedef enum
{
RED = 0,
@ -80,6 +117,16 @@ typedef enum
}
Scan_Regions;
/* struct to hold pre channel settings */
typedef struct Channels
{
SANE_Word red;
SANE_Word green;
SANE_Word blue;
SANE_Word gray;
}
Channels;
/** @name Option_Value union
* convenience union to access option values given to the backend
* @{
@ -131,8 +178,6 @@ typedef struct Lexmark_Device
SANE_Parameters params;
SANE_Int devnum;
long data_size;
SANE_Int pixel_height;
SANE_Int pixel_width;
SANE_Bool initialized;
SANE_Bool eof;
SANE_Int x_dpi;
@ -141,31 +186,62 @@ typedef struct Lexmark_Device
SANE_Bool device_cancelled;
SANE_Int cancel_ctr;
SANE_Byte *transfer_buffer;
size_t bytes_read;
size_t bytes_remaining;
size_t bytes_in_buffer;
SANE_Byte *read_pointer;
Read_Buffer *read_buffer;
SANE_Byte threshold;
Lexmark_Model model; /* per model data */
Lexmark_Sensor *sensor;
SANE_Byte shadow_regs[255]; /* shadow registers */
struct Channels offset;
struct Channels gain;
float *shading_coeff;
}
Lexmark_Device;
/* Maximum transfer size */
#define MAX_XFER_SIZE 0xFFC0
/* motors and sensors type defines */
#define X1100_MOTOR 1
#define A920_MOTOR 2
#define X1100_B2_SENSOR 3
#define A920_SENSOR 4
#define X1100_2C_SENSOR 5
#define X1200_SENSOR 6 /* X1200 on USB 1.0 */
#define X1200_USB2_SENSOR 7 /* X1200 on USB 2.0 */
/* Non-static Function Proto-types (called by lexmark.c) */
SANE_Status sanei_lexmark_x1100_init (void);
void sanei_lexmark_x1100_destroy (Lexmark_Device * dev);
SANE_Status sanei_lexmark_x1100_open_device (SANE_String_Const devname,
SANE_Int * devnum);
void sanei_lexmark_x1100_close_device (SANE_Int devnum);
SANE_Bool sanei_lexmark_x1100_search_home_fwd (Lexmark_Device * dev);
void sanei_lexmark_x1100_move_fwd (SANE_Int distance, Lexmark_Device * dev);
SANE_Bool sanei_lexmark_x1100_search_home_bwd (Lexmark_Device * dev);
SANE_Int sanei_lexmark_x1100_find_start_line (SANE_Int devnum);
SANE_Status sanei_lexmark_x1100_set_scan_regs (Lexmark_Device * dev,
SANE_Int offset);
SANE_Status sanei_lexmark_x1100_start_scan (Lexmark_Device * dev);
long sanei_lexmark_x1100_read_scan_data (SANE_Byte * data, SANE_Int size,
SANE_Status sanei_lexmark_low_init (Lexmark_Device * dev);
void sanei_lexmark_low_destroy (Lexmark_Device * dev);
SANE_Status sanei_lexmark_low_open_device (Lexmark_Device * dev);
void sanei_lexmark_low_close_device (Lexmark_Device * dev);
SANE_Bool sanei_lexmark_low_search_home_fwd (Lexmark_Device * dev);
void sanei_lexmark_low_move_fwd (SANE_Int distance, Lexmark_Device * dev,
SANE_Byte * regs);
SANE_Bool sanei_lexmark_low_search_home_bwd (Lexmark_Device * dev);
SANE_Int sanei_lexmark_low_find_start_line (Lexmark_Device * dev);
SANE_Status sanei_lexmark_low_set_scan_regs (Lexmark_Device * dev,
SANE_Int offset,
SANE_Bool calibrated);
SANE_Status sanei_lexmark_low_start_scan (Lexmark_Device * dev);
long sanei_lexmark_low_read_scan_data (SANE_Byte * data, SANE_Int size,
Lexmark_Device * dev);
SANE_Status sanei_lexmark_low_assign_model (Lexmark_Device * dev,
char *devname, SANE_Int vendor,
SANE_Int product,
SANE_Byte mainboard);
/*
* scanner calibration functions
*/
SANE_Status sanei_lexmark_low_offset_calibration (Lexmark_Device * dev);
SANE_Status sanei_lexmark_low_gain_calibration (Lexmark_Device * dev);
SANE_Status sanei_lexmark_low_shading_calibration (Lexmark_Device * dev);
SANE_Status sanei_lexmark_low_calibration (Lexmark_Device * dev);
#endif /* LEXMARK_H */

5150
backend/lexmark_low.c 100644

Plik diff jest za duży Load Diff

Wyświetl plik

@ -0,0 +1,93 @@
/* sane - Scanner Access Now Easy.
Copyright (C) 2006-2007 Stéphane Voltz <stef.dev@free.fr>
This file is part of the SANE package.
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.
This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston,
MA 02111-1307, USA.
As a special exception, the authors of SANE give permission for
additional uses of the libraries contained in this release of SANE.
The exception is that, if you link a SANE library with other files
to produce an executable, this does not by itself cause the
resulting executable to be covered by the GNU General Public
License. Your use of that executable is in no way restricted on
account of linking the SANE library code into it.
This exception does not, however, invalidate any other reasons why
the executable file might be covered by the GNU General Public
License.
If you submit changes to SANE to the maintainers to be included in
a subsequent release, you agree by submitting the changes that
those changes may be distributed with this exception intact.
If you write modifications of your own for SANE, it is your choice
whether to permit this exception to apply to your modifications.
If you do not wish that, delete this exception notice.
*/
static Lexmark_Model model_list[] = {
{
0x043d, /* vendor id */
0x007c, /* product id */
0xb2, /* submodel id */
"Lexmark X1100", /* name */
"Lexmark", /* vendor */
"X1100/rev. B2", /* model */
X1100_MOTOR, /* X1100 series has 2 sensors */
X1100_B2_SENSOR},
{
0x043d, /* vendor id */
0x007c, /* product id */
0x2c, /* submodel id */
"Lexmark X1100", /* name */
"Lexmark", /* vendor */
"X1100/rev. 2C", /* model */
A920_MOTOR, /* X1100 series has 2 sensors, 2C or B2. It
is detected at sane_open() */
X1100_2C_SENSOR},
{
0x413c, /* vendor id */
0x5105, /* product id */
0x2c, /* submodel id */
"Dell A920", /* name */
"Dell", /* vendor */
"A920", /* model */
A920_MOTOR,
A920_SENSOR},
{
0x043d, /* vendor id */
0x007d, /* product id */
0x87, /* submodel id */
"Lexmark X1200", /* name */
"Lexmark", /* vendor */
"X1200/USB1.1", /* model */
A920_MOTOR,
X1200_SENSOR},
{
0x043d, /* vendor id */
0x007d, /* product id */
0x97, /* submodel id */
"Lexmark X1200", /* name */
"Lexmark", /* vendor */
"X1200/USB2.0", /* model */
A920_MOTOR,
X1200_USB2_SENSOR},
{ /* termination model, must be last */
0, 0, 0, NULL, NULL, NULL, 0, 0}
}; /* end models description */

Wyświetl plik

@ -0,0 +1,122 @@
/* sane - Scanner Access Now Easy.
Copyright (C) 2006-2007 Stéphane Voltz <stef.dev@free.fr>
This file is part of the SANE package.
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.
This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston,
MA 02111-1307, USA.
As a special exception, the authors of SANE give permission for
additional uses of the libraries contained in this release of SANE.
The exception is that, if you link a SANE library with other files
to produce an executable, this does not by itself cause the
resulting executable to be covered by the GNU General Public
License. Your use of that executable is in no way restricted on
account of linking the SANE library code into it.
This exception does not, however, invalidate any other reasons why
the executable file might be covered by the GNU General Public
License.
If you submit changes to SANE to the maintainers to be included in
a subsequent release, you agree by submitting the changes that
those changes may be distributed with this exception intact.
If you write modifications of your own for SANE, it is your choice
whether to permit this exception to apply to your modifications.
If you do not wish that, delete this exception notice.
*/
static Lexmark_Sensor sensor_list[] = {
{
X1100_B2_SENSOR,
/* start x, end x and target average for offset calibration */
48,80,6,
/* usable pixel sensor startx */
106,
/* default gain */
16,
/* gain calibration targets */
180, 180, 180, 180,
/* shading correction targets */
260, 260, 260, 260,
/* offset and gain fallback */
0x70, 17
},
{
X1100_2C_SENSOR,
/* start x, end x and target average for offset calibration */
48,80,12,
/* usable pixel sensor startx */
106,
/* default gain */
10,
/* gain calibration */
140, 150, 150, 150,
/* shading correction */
260, 260, 260, 260,
/* offset and gain fallback */
0x70, 11
},
{ /* USB 1.1 settings */
X1200_SENSOR,
/* start x, end x and target average for offset calibration */
32,64,15,
/* usable pixel sensor startx */
136,
/* default gain */
16,
/* gain calibration */
180, 180, 180, 180,
/* shading correction */
260, 260, 260, 260,
/* offset and gain fallback */
0x86, 16
},
{ /* this one is a 1200 on USB2.0 */
X1200_USB2_SENSOR,
/* start x, end x and target average for offset calibration */
32,64,12,
/* usable pixel sensor startx */
136,
/* default gain */
16,
/* gain calibration */
180, 180, 180, 180,
/* shading correction */
260, 260, 260, 260,
/* offset and gain fallback */
0x86, 16
},
{
A920_SENSOR,
/* start x, end x and target average for offset calibration */
48,80,6,
/* usable pixel sensor startx */
106,
/* default gain */
12,
/* gain calibration target */
130, 145, 150, 145,
/* gain calibration target */
260, 260, 260, 260,
/* offset and gain fallback */
0x70, 13
},
/* termination list sensor, must be last */
{0,0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
};

Wyświetl plik

@ -31,11 +31,10 @@
:status :untested
:model "X1130"
:url "/unsupported/lexmark-x1150.html"
:interface "USB"
:usbid "0x043d" "0x007c"
:status :basic
:comment "The images scanned have a lot of vertical lines"
:status :good
:comment "Supports 75, 150, 300, 600 dpi"
:model "X1140"
:interface "USB"
@ -46,25 +45,35 @@
:url "/unsupported/lexmark-x1150.html"
:interface "USB"
:usbid "0x043d" "0x007c"
:status :minimal
:comment "Colors don't seem to be ok. Scanned white pages appear purple."
:status :good
:comment "Supports 75, 150, 300, 600 dpi"
:model "X1170"
:interface "USB"
:usbid "0x043d" "0x007c"
:status :basic
:comment "Colors aren't so bright. Bed-wide pictures are unscannable because the scan head never reaches the end of the bed (neither with letter selected). It leaves almost 2 cm out."
:status :good
:comment "Supports 75, 150, 300, 600 dpi"
:model "X1180"
:url "/unsupported/lexmark-x1150.html"
:interface "USB"
:usbid "0x043d" "0x007c"
:status :basic
:status :good
:model "X1185"
:interface "USB"
:usbid "0x043d" "0x007c"
:status :basic
:status :good
:comment "Tested with xscanimage. Supports 75, 150, 300, 600, 1200(600x1200) dpi resolutions. Does grayscale or colour scans in the following sizes: wallet, 3x5, 4x6, 5x7, 8x10, letter."
:model "X12xx"
:interface "USB"
:usbid "0x043d" "0x007d"
:status :good
:comment "USB1.1 is OK, USB2.0 needs testing"
:mfg "Dell" ; name a manufacturer
:model "A920"
:interface "USB"
:usbid "0x413c" "0x5105"
:status :good
:comment "Relabelled X11xx model"

Wyświetl plik

@ -1,14 +1,14 @@
.TH sane-lexmark 5 "02 September 2005" "@PACKAGEVERSION@" "SANE Scanner Access Now Easy"
.IX sane-lexmark
.SH NAME
sane-lexmark \- SANE backend for Lexmark X1100 Series scanners
.SH DESCRIPTION
.\" .IX sane-lexmark
.TH "sane-lexmark" "5" "16 April 2007" "@PACKAGEVERSION@" "SANE Scanner Access Now Easy"
.SH "NAME"
sane\-lexmark \- SANE backend for Lexmark X1100/X1200 Series scanners
.SH "DESCRIPTION"
The
.B sane-lexmark
.B sane\-lexmark
library implements a SANE (Scanner Access Now Easy) backend that
provides access to the scanner part of Lexmark X1100 AIOs. This backend
provides access to the scanner part of Lexmark X1100/X1200 AIOs. This backend
should be considered
.B beta-quality
.B beta\-quality
software!
.PP
The scanners that should work with this backend are:
@ -17,13 +17,16 @@ The scanners that should work with this backend are:
.ft CR
.nf
Vendor Model status
---------------------- -----------
\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\- \-\-\-\-\-\-\-\-\-\-\-
Lexmark X1110 untested
Lexmark X1140 untested
Lexmark X1150 untested
Lexmark X1170 untested
Lexmark X1180 basic
Lexmark X1185 basic
Lexmark X1150 good
Lexmark X1170 good
Lexmark X1180 good
Lexmark X1185 complete
Lexmark X12xx good in USB1.1,
not fully tested in USB2.0
Dell A920 good
.fi
.ft R
.RE
@ -38,16 +41,16 @@ maintainer or to the SANE mailing list.
Valid command line options and their syntax can be listed by using
.RS
scanimage --help -d lexmark:usb:<usb port>
scanimage \-\-help \-d lexmark:usb:<usb port>
.RE
.TP
.B Scan Mode Options
.TP
.B --mode
.B \-\-mode
selects the basic mode of operation of the scanner valid choices are
.IR Color ,
.I R Color ,
.I Gray
and
.I Lineart
@ -56,7 +59,7 @@ Grayscale will produce 256 levels of gray (8 bits). Color mode allows for over
16 million different colors produced from 24 bits of color information.
.TP
.B --resolution
.B \-\-resolution
selects the resolution for a scan. The horizontal and vertical resolutions are set
by the value of this option. The scanner is capable of the following resolutions for the specified option value:
.PP
@ -64,87 +67,82 @@ by the value of this option. The scanner is capable of the following resolutions
.ft CR
.nf
Value Hor. Resolution Vert. Resolution
----- --------------- -------------------
\-\-\-\-\- \-\-\-\-\-\-\-\-\-\-\-\-\-\-\- \-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-
75 75dpi 75dpi
150 150dpi 150dpi
300 300dpi 300dpi
600 600dpi 600dpi
1200 600dpi 1200dpi
1200 600dpi 1200dpi (only for X11xx models with 'B2' sensor)
.fi
.ft R
.RE
.TP
.B --preview
.B \-\-preview
requests a preview scan. The resolution used for that scan is 75 dpi
and the scan area and the scan mode are as specified through their options,
or the default if not specified. The default value for preview mode is "no".
.TP
.B --paper-size
selects the size of the area to be scanned. Valid sizes are
.IR Wallet ,
.IR 3x5 ,
.IR 4x6 ,
.IR 5x7 ,
.IR 8x10 ,
.IR Letter ,
the default size is 3x5.
.TP
.B --threshold
selects the minimum-brightness to get a white point. The threshold is only used with Lineart mode scans.
.B \-\-threshold
selects the minimum\-brightness to get a white point. The threshold is only used with Lineart mode scans.
It is specified as a percentage in the range 0..100% (in steps of 1).
The default value of the threshold option is 50.
.SH CONFIGURATION FILE
.SH "CONFIGURATION FILE"
The configuration file @CONFIGDIR@/lexmark.conf contains only the usb device id (eg usb 0x043d 0x007c).
.SH FILES
.SH "FILES"
.TP
.I @LIBDIR@/libsane-lexmark.a
.I @LIBDIR@/libsane\-lexmark.a
The static library implementing this backend.
.TP
.I @LIBDIR@/libsane-lexmark.so
.I @LIBDIR@/libsane\-lexmark.so
The shared library implementing this backend (present on systems that
support dynamic loading).
.SH ENVIRONMENT
.SH "ENVIRONMENT"
.TP
.B SANE_DEBUG_LEXMARK
.B SANE_DEBUG_LEXMARK_LOW
If the library was compiled with debug support enabled, this
environment variable controls the debug level for this backend. E.g.,
a value of 128 requests all debug output to be printed. Smaller levels
a value of 255 requests all debug output to be printed. Smaller levels
reduce verbosity.
.SH LIMITATIONS
.SH "LIMITATIONS"
The windows TWAIN driver has many more options than this SANE
backend. However they are only software adjustments. This backend only
implements what the scanner can support.
.SH BUGS
implements what the scanner can support. For instance, shading correction
(vertical stripes due to sensor variation across its width) is done in
software. Head park position is also detected by software.
The data compression isn't supported for the X1200 serie on USB 1.1,
leading to slow scans.
.SH "BUGS"
.br
Jerky movement on 600dpi gray 8x10 scan.
.br
Color calibration not implemented.
.br
Dark compensation not implemented.
No bugs currently known.
.SH "SEE ALSO"
sane-scsi(5), scanimage(1), xscanimage(1), xsane(1), sane(7)
sane\-scsi(5), scanimage(1), xscanimage(1), xsane(1), sane(7)
.SH AUTHOR
.SH "AUTHOR"
.TP
The package is actively maintained by Fred Odendaal.
The backend was originaly written by Fred Odendaal.
.I http://ca.geocities.com/freshshelf@rogers.com/
.TP
The new version is currently developped by StÃphane Voltz.
.I http://stef.dev.free.fr/sane/lexmark
.SH "CREDITS"
.TP
Many thanks go to:
Julien Furgerot who lend me a Dell A920.
Robert Price, Dani Ele and Dalai Felinto for the time they spent recording
USB activity and testing the experimental version.