hp5400: added support for editable colour/bw switch and copy count sensors.

fix-build-obselete-jpeg
Ralph Little 2020-03-07 14:36:27 -08:00
rodzic 090973fa94
commit 28bcb9179d
4 zmienionych plików z 332 dodań i 19 usunięć

Wyświetl plik

@ -1,4 +1,5 @@
/* sane - Scanner Access Now Easy.
Copyright (C) 20020 Ralph Little <skelband@gmail.com>
Copyright (C) 2003 Martijn van Oosterhout <kleptog@svana.org>
Copyright (C) 2003 Thomas Soumarmon <thomas.soumarmon@cogitae.net>
@ -62,6 +63,13 @@
#define HW_DPI 300 /* horizontal resolution of hardware */
#define HW_LPI 300 /* vertical resolution of hardware */
/*
* Names for the Colour/BW switch modes.
*
*/
#define COLOURBW_MODE_COLOUR SANE_I18N("Color")
#define COLOURBW_MODE_GREY SANE_I18N("Gray")
enum ScanType
{
SCAN_TYPE_CALIBRATION,
@ -138,6 +146,16 @@ typedef struct
}
TScanParams;
/*
* Panel settings. We can read and set these.
*
*/
typedef struct
{
SANE_Word copycount; // 0..99 LCD display value
SANE_Word bwcolour; // 1=Colour or 2=Black/White from scan type LEDs
}
TPanelInfo;
#endif /* NO _HP5400_H_ */

Wyświetl plik

@ -181,6 +181,105 @@ GetSensors(THWParams * pHWParams, uint16_t *sensorMap)
return 0;
}
HP5400_SANE_STATIC
int
GetPanelInfo (THWParams * pHWParams, TPanelInfo *panelInfo)
{
struct PanelInfo info;
if (hp5400_command_read (pHWParams->iXferHandle, CMD_READPANEL,
sizeof(info), &info) < 0)
{
HP5400_DBG (DBG_MSG, "failed to read panel info\n");
return -1;
}
panelInfo->copycount = (SANE_Word)info.copycount;
panelInfo->bwcolour = (SANE_Word)info.bwcolour;
return 0;
}
HP5400_SANE_STATIC
int
SetCopyCount(THWParams * pHWParams, SANE_Word copyCount)
{
/*
* I don't know what most of these things are but it is
* necessary to send something sane otherwise we get an error from the scanner.
* I got these settings from a USB trace.
* Hopefully, we will learn what it is all about at some point
* and hopefully it doesn't screw with other settings.
*
*/
uint8_t packetImage[] = {0x02, 0x06, 0x32, 0x01,
0xf2, 0x40, 0x16, 0x01,
0x7b, 0x41, 0x16, 0x01,
0xdc, 0x06, 0x32, 0x01,
0xd7, 0x5b, 0x16, 0x01,
0xac, 0x06, 0x32, 0x01,
0xf8, 0xd7, 0x18, 0x01,
0xd8, 0x06, 0x32, 0x01,
0x2c, 0xf3, 0x12, 0x00,
0x70, 0x8d, 0x18, 0x01,
0x7b, 0x00, 0x00, 0x00};
struct PanelInfo workingInfo;
(void)memcpy(&workingInfo, packetImage, sizeof(workingInfo));
workingInfo.copycount = (uint8_t)copyCount;
if (hp5400_command_write (pHWParams->iXferHandle, CMD_WRITEPANEL,
sizeof(workingInfo), &workingInfo) < 0)
{
HP5400_DBG (DBG_MSG, "failed to write panel info\n");
return -1;
}
return 0;
}
HP5400_SANE_STATIC
int
SetColourBW(THWParams * pHWParams, SANE_Word colourBW)
{
/*
* I don't know what most of these things are but it is
* necessary to send something sane otherwise we get an error from the scanner.
* I got these settings from a USB trace.
* Hopefully, we will learn what it is all about at some point
* and hopefully it doesn't screw with other settings.
*
*/
uint8_t packetImage[] = {0x03, 0x06, 0x32, 0x01,
0xf2, 0x40, 0x16, 0x01,
0x7b, 0x41, 0x16, 0x01,
0xdc, 0x06, 0x32, 0x01,
0xd7, 0x5b, 0x16, 0x01,
0xac, 0x06, 0x32, 0x01,
0xf8, 0xd7, 0x18, 0x01,
0xd8, 0x06, 0x32, 0x01,
0x68, 0xf5, 0x12, 0x00,
0x70, 0x8d, 0x18, 0x01,
0x7b, 0x00, 0x00, 0x00};
struct PanelInfo workingInfo;
(void)memcpy(&workingInfo, packetImage, sizeof(workingInfo));
workingInfo.bwcolour = (uint8_t)colourBW;
if (hp5400_command_write (pHWParams->iXferHandle, CMD_WRITEPANEL,
sizeof(workingInfo), &workingInfo) < 0)
{
HP5400_DBG (DBG_MSG, "failed to write panel info\n");
return -1;
}
return 0;
}
HP5400_SANE_STATIC
int

Wyświetl plik

@ -75,6 +75,8 @@
#define CMD_SCANREQUEST2 0x2500 /* This is for real scans */
#define CMD_SCANRESPONSE 0x3400
#define CMD_GETSENSORS 0x2000
#define CMD_READPANEL 0x2100 // Reads info from the scanner. BW/Col + Copy Count. Others, not sure.
#define CMD_WRITEPANEL 0x2200 // Ditto for setting.
/* Testing stuff to make it work */
#define CMD_SETDPI 0x1500 /* ??? */
@ -132,11 +134,40 @@ PACKED;
struct ScanResponse
{
uint16_t x1; /* Usually 0x0000 or 0x4000 */
uint32_t transfersize; /* Number of bytes to be transferred */
uint32_t xsize; /* Shape of returned bitmap */
uint16_t ysize; /* Why does the X get more bytes? */
uint16_t pad[2]; /* Zero padding to 16 bytes??? */
uint16_t x1; /* Usually 0x0000 or 0x4000 */
uint32_t transfersize; /* Number of bytes to be transferred */
uint32_t xsize; /* Shape of returned bitmap */
uint16_t ysize; /* Why does the X get more bytes? */
uint16_t pad[2]; /* Zero padding to 16 bytes??? */
}
PACKED;
/*
* Note: this is the structure of the response we get from CMD_READPANEL.
* We only know about two items for the moment. The rest will be ignored
* until we understand it better.
*
* 44 bytes in total.
*
* Since we don't know what the other things mean, I will assume that they
* mean the same things for Get and SET. For SET, we will have to GET, change
* what we wish change and SET it back otherwise goodness knows what evil
* we will unleash.
*
* Note that for setting, different values in the buffer seem to apply betwen the copy count
* and the colour/BW switch setting. I don't know what that means at the moment.
*
* I'm calling it PanelInfo because I can't think of anything better.
* That may change as the other values are revealed.
*
*/
struct PanelInfo
{
uint32_t unknown1[10];
uint8_t unknown2;
uint8_t copycount; // 0..99 from the LCD display.
uint8_t bwcolour; // 1 or 2 from the Colour/BW leds.
uint8_t unknown3;
}
PACKED;
@ -162,6 +193,18 @@ HP5400_SANE_STATIC
int
GetSensors (THWParams * pHWParams, uint16_t *sensorMap);
HP5400_SANE_STATIC
int
GetPanelInfo (THWParams * pHWParams, TPanelInfo *panelInfo);
HP5400_SANE_STATIC
int
SetCopyCount(THWParams * pHWParams, SANE_Word copyCount);
HP5400_SANE_STATIC
int
SetColourBW(THWParams * pHWParams, SANE_Word colourBW);
HP5400_SANE_STATIC
int
WarmupLamp (int iHandle);

Wyświetl plik

@ -141,6 +141,9 @@ typedef enum
optSensorCopiesDown,
optSensorColourBW,
optSensorColourBWState,
optSensorCopyCount,
// Unsupported as yet.
//optGroupMisc,
//optLamp,
@ -159,22 +162,36 @@ EOptionIndex;
* of bits can be set in any one query.
*
*/
#define SENSOR_BIT_SCAN 0x0400
#define SENSOR_BIT_WEB 0x0200
#define SENSOR_BIT_REPRINT 0x0002
#define SENSOR_BIT_EMAIL 0x0080
#define SENSOR_BIT_COPY 0x0040
#define SENSOR_BIT_MOREOPTIONS 0x0004
#define SENSOR_BIT_CANCEL 0x0100
#define SENSOR_BIT_POWERSAVE 0x2000
#define SENSOR_BIT_COPIESUP 0x0008
#define SENSOR_BIT_COPIESDOWN 0x0020
#define SENSOR_BIT_COLOURBW 0x0010
uint16_t sensorMaskMap[] =
{
0x0400, // Scan To button
0x0200, // Web (WWW) button
0x0002, // Reprint button
0x0080, // Email button
0x0040, // Copy button
0x0004, // More Options button
0x0100, // Cancel button
SENSOR_BIT_SCAN,
SENSOR_BIT_WEB,
SENSOR_BIT_REPRINT,
SENSOR_BIT_EMAIL,
SENSOR_BIT_COPY,
SENSOR_BIT_MOREOPTIONS,
SENSOR_BIT_CANCEL,
// Special buttons.
// These affect local machine settings, but we can still detect them being pressed.
0x2000, // Power Save button.
0x0008, // Copies Up button
0x0020, // Copies Down button
0x0010, // Color/BW Selection button.
SENSOR_BIT_POWERSAVE,
SENSOR_BIT_COPIESUP,
SENSOR_BIT_COPIESDOWN,
SENSOR_BIT_COLOURBW,
// Extra entries to make the array up to the 16 possible bits.
0x0000, // Unused
@ -238,6 +255,12 @@ static const SANE_Device **_pSaneDevList = 0;
/* option constraints */
static const SANE_Range rangeGammaTable = {0, 65535, 1};
static const SANE_Range rangeCopyCountTable = {0, 99, 1};
static SANE_String_Const modeSwitchList[] = {
COLOURBW_MODE_COLOUR,
COLOURBW_MODE_GREY,
NULL
};
#ifdef SUPPORT_2400_DPI
static const SANE_Int setResolutions[] = {6, 75, 150, 300, 600, 1200, 2400};
#else
@ -493,6 +516,26 @@ static void _InitOptions(TScanner *s)
pDesc->cap = SANE_CAP_SOFT_DETECT | SANE_CAP_HARD_SELECT | SANE_CAP_ADVANCED;
break;
case optSensorColourBWState:
pDesc->name = SANE_I18N("color-bw-state");
pDesc->title = SANE_I18N("Read color/BW button state");
pDesc->desc = SANE_I18N("Reads state of BW/colour panel setting");
pDesc->type = SANE_TYPE_STRING;
pDesc->constraint_type = SANE_CONSTRAINT_STRING_LIST;
pDesc->constraint.string_list = modeSwitchList;
pDesc->cap = SANE_CAP_SOFT_DETECT | SANE_CAP_SOFT_SELECT | SANE_CAP_ADVANCED;
break;
case optSensorCopyCount:
pDesc->name = SANE_I18N("copies-count");
pDesc->title = SANE_I18N("Read copy count value");
pDesc->desc = SANE_I18N("Reads state of copy count panel setting");
pDesc->type = SANE_TYPE_INT;
pDesc->constraint_type = SANE_CONSTRAINT_RANGE;
pDesc->constraint.range = &rangeCopyCountTable;
pDesc->cap = SANE_CAP_SOFT_DETECT | SANE_CAP_SOFT_SELECT | SANE_CAP_ADVANCED;
break;
#if 0
case optGroupMisc:
pDesc->title = SANE_I18N("Miscellaneous");
@ -856,8 +899,8 @@ sane_control_option (SANE_Handle h, SANE_Int n, SANE_Action Action,
case optSensorPowerSave:
case optSensorCopiesUp:
case optSensorCopiesDown:
case optSensorColourBW:
{
case optSensorColourBW:
{
HP5400_DBG (DBG_MSG, "Reading sensor state\n");
uint16_t sensorMap;
@ -879,7 +922,53 @@ sane_control_option (SANE_Handle h, SANE_Int n, SANE_Action Action,
*(SANE_Word *) pVal = (s->sensorMap & mask)? 1:0;
s->sensorMap &= ~mask;
break;
}
}
case optSensorCopyCount:
{
HP5400_DBG (DBG_MSG, "Reading copy count\n");
TPanelInfo panelInfo;
if (GetPanelInfo(&s->HWParams, &panelInfo) != 0)
{
HP5400_DBG (DBG_ERR,
"sane_control_option: SANE_ACTION_SET_VALUE could not retrieve panel info\n");
return SANE_STATUS_IO_ERROR;
}
HP5400_DBG (DBG_MSG, "Copy count setting=%u\n", panelInfo.copycount);
*(SANE_Word *) pVal = panelInfo.copycount;
break;
}
case optSensorColourBWState:
{
HP5400_DBG (DBG_MSG, "Reading BW/Colour setting\n");
TPanelInfo panelInfo;
if (GetPanelInfo(&s->HWParams, &panelInfo) != 0)
{
HP5400_DBG (DBG_ERR,
"sane_control_option: SANE_ACTION_SET_VALUE could not retrieve panel info\n");
return SANE_STATUS_IO_ERROR;
}
HP5400_DBG (DBG_MSG, "BW/Colour setting=%u\n", panelInfo.bwcolour);
// Just for safety:
if (panelInfo.bwcolour < 1)
{
panelInfo.bwcolour = 1;
}
else if (panelInfo.bwcolour > 2)
{
panelInfo.bwcolour = 2;
}
(void)strcpy((SANE_String)pVal, modeSwitchList[panelInfo.bwcolour - 1]);
break;
}
#if 0
/* Get options of type SANE_Bool */
@ -986,6 +1075,70 @@ sane_control_option (SANE_Handle h, SANE_Int n, SANE_Action Action,
HP5400_DBG (DBG_MSG, "Writing gamma table\n");
memcpy (s->aValues[n].wa, pVal, s->aOptions[n].size);
break;
case optSensorColourBWState:
{
SANE_String bwColour = (SANE_String)pVal;
SANE_Word bwColourValue;
if (strcmp(bwColour, COLOURBW_MODE_COLOUR) == 0)
{
bwColourValue = 1;
}
else if (strcmp(bwColour, COLOURBW_MODE_GREY) == 0)
{
bwColourValue = 2;
}
else
{
HP5400_DBG (DBG_ERR,
"sane_control_option: SANE_ACTION_SET_VALUE invalid colour/bw mode\n");
return SANE_STATUS_INVAL;
}
HP5400_DBG (DBG_MSG, "Setting BW/Colour state=%d\n", bwColourValue);
/*
* Now write it with the other panel settings back to the scanner.
*
*/
if (SetColourBW(&s->HWParams, bwColourValue) != 0)
{
HP5400_DBG (DBG_ERR,
"sane_control_option: SANE_ACTION_SET_VALUE could not set colour/BW mode\n");
return SANE_STATUS_IO_ERROR;
}
break;
}
case optSensorCopyCount:
{
SANE_Word copyCount = *(SANE_Word *) pVal;
if (copyCount < 0)
{
copyCount = 0;
}
else if (copyCount > 99)
{
copyCount = 99;
}
HP5400_DBG (DBG_MSG, "Setting Copy Count=%d\n", copyCount);
/*
* Now write it with the other panel settings back to the scanner.
*
*/
if (SetCopyCount(&s->HWParams, copyCount) != 0)
{
HP5400_DBG (DBG_ERR,
"sane_control_option: SANE_ACTION_SET_VALUE could not set copy count\n");
return SANE_STATUS_IO_ERROR;
}
break;
}
/*
case optLamp:
fVal = *(SANE_Bool *)pVal;