From ad38bc6ecb80ddeb562841b33258dd53659b1da6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Frings-F=C3=BCrst?= Date: Mon, 24 Aug 2020 18:44:51 +0200 Subject: New upstream version 1.0.31 --- backend/hp5400_sane.c | 543 ++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 439 insertions(+), 104 deletions(-) (limited to 'backend/hp5400_sane.c') diff --git a/backend/hp5400_sane.c b/backend/hp5400_sane.c index e5fdf43..b6fa6da 100644 --- a/backend/hp5400_sane.c +++ b/backend/hp5400_sane.c @@ -1,4 +1,5 @@ /* sane - Scanner Access Now Easy. + Copyright (C) 2020 Ralph Little Copyright (C) 2003 Martijn van Oosterhout Copyright (C) 2003 Thomas Soumarmon @@ -71,28 +72,6 @@ #include "hp5400.h" -/* includes for data transfer methods */ -#include "hp5400.h" - -#ifdef STANDALONE -#include "hp5400_scanner.h" -#endif - -#if defined(LINUX_USB_SUPPORT) - #include "hp5400_linux.c" -#endif -#if defined(USCANNER_SUPPORT) - #include "hp5400_uscanner.c" -#endif -#if defined(LIBUSB_SUPPORT) - #include "hp5400_libusb.c" -#endif -#if defined(LIBIEEE1284_SUPPORT) - #include "hp5400_ieee1284.c" -#endif - - - /* other definitions */ #ifndef min #define min(A,B) (((A)<(B)) ? (A) : (B)) @@ -115,30 +94,91 @@ typedef enum { optCount = 0, + optDPI, + optGroupGeometry, optTLX, optTLY, optBRX, optBRY, - optDPI, - optGroupImage, + optGroupEnhancement, optGammaTableRed, /* Gamma Tables */ optGammaTableGreen, optGammaTableBlue, - optLast, /* Disable the offset code */ + optGroupSensors, - optGroupMisc, - optOffsetX, optOffsetY + optSensorScanTo, + optSensorWeb, + optSensorReprint, + optSensorEmail, + optSensorCopy, + optSensorMoreOptions, + optSensorCancel, + optSensorPowerSave, + optSensorCopiesUp, + optSensorCopiesDown, + optSensorColourBW, + optSensorColourBWState, + optSensorCopyCount, -/* put temporarily disabled options here after optLast */ -/* - optLamp, -*/ + // Unsupported as yet. + //optGroupMisc, + //optLamp, + //optCalibrate, + optLast, /* Disable the offset code */ } EOptionIndex; +/* + * Array mapping (optSensor* - optGroupSensors - 1) to the bit mask of the + * corresponding sensor bit that we get from the scanner. + * All sensor bits are reported as a complete 16-bit word with individual bits set + * to indicate that the sensor has been activated. + * They seem to be latched so that they are picked up on next query and a number + * 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[] = +{ + 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. + 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 + 0x0000, // Unused + 0x0000, // Unused + 0x0000, // Unused + 0x0000 // Unused +}; + typedef union { SANE_Word w; @@ -165,6 +205,8 @@ typedef struct int fScanning; /* TRUE if actively scanning */ int fCanceled; + + uint16_t sensorMap; /* Contains the current unreported sensor bits. */ } TScanner; @@ -191,18 +233,19 @@ 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[] = { + SANE_VALUE_SCAN_MODE_COLOR, + SANE_VALUE_SCAN_MODE_GRAY, + NULL +}; #ifdef SUPPORT_2400_DPI static const SANE_Int setResolutions[] = {6, 75, 150, 300, 600, 1200, 2400}; #else static const SANE_Int setResolutions[] = {5, 75, 150, 300, 600, 1200}; #endif -static const SANE_Range rangeXmm = {0, 220, 1}; -static const SANE_Range rangeYmm = {0, 300, 1}; -static const SANE_Range rangeXoffset = {0, 20, 1}; -static const SANE_Range rangeYoffset = {0, 70, 1}; -static const SANE_Int offsetX = 5; -static const SANE_Int offsetY = 52; - +static const SANE_Range rangeXmm = {0, 216, 1}; +static const SANE_Range rangeYmm = {0, 297, 1}; static void _InitOptions(TScanner *s) { @@ -248,8 +291,22 @@ static void _InitOptions(TScanner *s) pVal->w = (SANE_Word)optLast; break; + case optDPI: + pDesc->name = SANE_NAME_SCAN_RESOLUTION; + pDesc->title = SANE_TITLE_SCAN_RESOLUTION; + pDesc->desc = SANE_DESC_SCAN_RESOLUTION; + pDesc->unit = SANE_UNIT_DPI; + pDesc->constraint_type = SANE_CONSTRAINT_WORD_LIST; + pDesc->constraint.word_list = setResolutions; + pDesc->cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT; + pVal->w = setResolutions[1]; + break; + + //--------------------------------- case optGroupGeometry: - pDesc->title = "Geometry"; + pDesc->name = SANE_NAME_GEOMETRY; + pDesc->title = SANE_TITLE_GEOMETRY; + pDesc->desc = SANE_DESC_GEOMETRY; pDesc->type = SANE_TYPE_GROUP; pDesc->size = 0; break; @@ -262,7 +319,7 @@ static void _InitOptions(TScanner *s) pDesc->constraint_type = SANE_CONSTRAINT_RANGE; pDesc->constraint.range = &rangeXmm; pDesc->cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT; - pVal->w = rangeXmm.min + offsetX; + pVal->w = rangeXmm.min; break; case optTLY: @@ -273,7 +330,7 @@ static void _InitOptions(TScanner *s) pDesc->constraint_type = SANE_CONSTRAINT_RANGE; pDesc->constraint.range = &rangeYmm; pDesc->cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT; - pVal->w = rangeYmm.min + offsetY; + pVal->w = rangeYmm.min; break; case optBRX: @@ -284,7 +341,7 @@ static void _InitOptions(TScanner *s) pDesc->constraint_type = SANE_CONSTRAINT_RANGE; pDesc->constraint.range = &rangeXmm; pDesc->cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT; - pVal->w = rangeXmm.max + offsetX; + pVal->w = rangeXmm.max; break; case optBRY: @@ -295,22 +352,14 @@ static void _InitOptions(TScanner *s) pDesc->constraint_type = SANE_CONSTRAINT_RANGE; pDesc->constraint.range = &rangeYmm; pDesc->cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT; - pVal->w = rangeYmm.max + offsetY; - break; - - case optDPI: - pDesc->name = SANE_NAME_SCAN_RESOLUTION; - pDesc->title = SANE_TITLE_SCAN_RESOLUTION; - pDesc->desc = SANE_DESC_SCAN_RESOLUTION; - pDesc->unit = SANE_UNIT_DPI; - pDesc->constraint_type = SANE_CONSTRAINT_WORD_LIST; - pDesc->constraint.word_list = setResolutions; - pDesc->cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT; - pVal->w = setResolutions[1]; + pVal->w = rangeYmm.max; break; - case optGroupImage: - pDesc->title = SANE_I18N("Image"); + //--------------------------------- + case optGroupEnhancement: + pDesc->name = SANE_NAME_ENHANCEMENT; + pDesc->title = SANE_TITLE_ENHANCEMENT; + pDesc->desc = SANE_DESC_ENHANCEMENT; pDesc->type = SANE_TYPE_GROUP; pDesc->size = 0; break; @@ -348,34 +397,130 @@ static void _InitOptions(TScanner *s) pVal->wa = s->aGammaTableB; break; - case optGroupMisc: - pDesc->title = SANE_I18N("Miscellaneous"); + //--------------------------------- + case optGroupSensors: + pDesc->name = SANE_NAME_SENSORS; + pDesc->title = SANE_TITLE_SENSORS; pDesc->type = SANE_TYPE_GROUP; + pDesc->desc = SANE_DESC_SENSORS; pDesc->size = 0; break; - case optOffsetX: - pDesc->title = SANE_I18N("offset X"); - pDesc->desc = SANE_I18N("Hardware internal X position of the scanning area."); - pDesc->unit = SANE_UNIT_MM; - pDesc->constraint_type = SANE_CONSTRAINT_RANGE; - pDesc->constraint.range = &rangeXoffset; - pDesc->cap = SANE_CAP_SOFT_SELECT; - pVal->w = offsetX; + case optSensorScanTo: + pDesc->name = SANE_NAME_SCAN; + pDesc->title = SANE_TITLE_SCAN; + pDesc->desc = SANE_DESC_SCAN; + pDesc->type = SANE_TYPE_BOOL; + pDesc->cap = SANE_CAP_SOFT_DETECT | SANE_CAP_HARD_SELECT | SANE_CAP_ADVANCED; break; - case optOffsetY: - pDesc->title = SANE_I18N("offset Y"); - pDesc->desc = SANE_I18N("Hardware internal Y position of the scanning area."); - pDesc->unit = SANE_UNIT_MM; - pDesc->constraint_type = SANE_CONSTRAINT_RANGE; - pDesc->constraint.range = &rangeYoffset; - pDesc->cap = SANE_CAP_SOFT_SELECT; - pVal->w = offsetY; + case optSensorWeb: + pDesc->name = SANE_I18N("web"); + pDesc->title = SANE_I18N("Share-To-Web button"); + pDesc->desc = SANE_I18N("Scan an image and send it on the web"); + pDesc->type = SANE_TYPE_BOOL; + pDesc->cap = SANE_CAP_SOFT_DETECT | SANE_CAP_HARD_SELECT | SANE_CAP_ADVANCED; + break; + + case optSensorReprint: + pDesc->name = SANE_I18N("reprint"); + pDesc->title = SANE_I18N("Reprint Photos button"); + pDesc->desc = SANE_I18N("Button for reprinting photos"); + pDesc->type = SANE_TYPE_BOOL; + pDesc->cap = SANE_CAP_SOFT_DETECT | SANE_CAP_HARD_SELECT | SANE_CAP_ADVANCED; + break; + + case optSensorEmail: + pDesc->name = SANE_NAME_EMAIL; + pDesc->title = SANE_TITLE_EMAIL; + pDesc->desc = SANE_DESC_EMAIL; + pDesc->type = SANE_TYPE_BOOL; + pDesc->cap = SANE_CAP_SOFT_DETECT | SANE_CAP_HARD_SELECT | SANE_CAP_ADVANCED; + break; + + case optSensorCopy: + pDesc->name = SANE_NAME_COPY; + pDesc->title = SANE_TITLE_COPY; + pDesc->desc = SANE_DESC_COPY; + pDesc->type = SANE_TYPE_BOOL; + pDesc->cap = SANE_CAP_SOFT_DETECT | SANE_CAP_HARD_SELECT | SANE_CAP_ADVANCED; + break; + + case optSensorMoreOptions: + pDesc->name = SANE_I18N("more-options"); + pDesc->title = SANE_I18N("More Options button"); + pDesc->desc = SANE_I18N("Button for additional options/configuration"); + pDesc->type = SANE_TYPE_BOOL; + pDesc->cap = SANE_CAP_SOFT_DETECT | SANE_CAP_HARD_SELECT | SANE_CAP_ADVANCED; + break; + + case optSensorCancel: + pDesc->name = SANE_NAME_CANCEL; + pDesc->title = SANE_TITLE_CANCEL; + pDesc->desc = SANE_DESC_CANCEL; + pDesc->type = SANE_TYPE_BOOL; + pDesc->cap = SANE_CAP_SOFT_DETECT | SANE_CAP_HARD_SELECT | SANE_CAP_ADVANCED; + break; + + case optSensorPowerSave: + pDesc->name = SANE_I18N("power-save"); + pDesc->title = SANE_I18N("Power Save button"); + pDesc->desc = SANE_I18N("Puts the scanner in an energy-conservation mode"); + pDesc->type = SANE_TYPE_BOOL; + pDesc->cap = SANE_CAP_SOFT_DETECT | SANE_CAP_HARD_SELECT | SANE_CAP_ADVANCED; + break; + + case optSensorCopiesUp: + pDesc->name = SANE_I18N("copies-up"); + pDesc->title = SANE_I18N("Increase Copies button"); + pDesc->desc = SANE_I18N("Increase the number of copies"); + pDesc->type = SANE_TYPE_BOOL; + pDesc->cap = SANE_CAP_SOFT_DETECT | SANE_CAP_HARD_SELECT | SANE_CAP_ADVANCED; + break; + + case optSensorCopiesDown: + pDesc->name = SANE_I18N("copies-down"); + pDesc->title = SANE_I18N("Decrease Copies button"); + pDesc->desc = SANE_I18N("Decrease the number of copies"); + pDesc->type = SANE_TYPE_BOOL; + pDesc->cap = SANE_CAP_SOFT_DETECT | SANE_CAP_HARD_SELECT | SANE_CAP_ADVANCED; break; + case optSensorColourBW: + pDesc->name = SANE_I18N("color-bw"); + pDesc->title = SANE_I18N("Select color/BW button"); + pDesc->desc = SANE_I18N("Alternates between color and black/white scanning"); + pDesc->type = SANE_TYPE_BOOL; + 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"); + pDesc->type = SANE_TYPE_GROUP; + pDesc->size = 0; + break; + case optLamp: pDesc->name = "lamp"; pDesc->title = SANE_I18N("Lamp status"); @@ -385,8 +530,7 @@ static void _InitOptions(TScanner *s) /* switch the lamp on when starting for first the time */ pVal->w = SANE_TRUE; break; -#endif -#if 0 + case optCalibrate: pDesc->name = "calibrate"; pDesc->title = SANE_I18N("Calibrate"); @@ -467,7 +611,7 @@ sane_init (SANE_Int * piVersion, SANE_Auth_Callback pfnAuth) SANE_String_Const proper_str; int nline = 0; - /* prevent compiler from complaing about unused parameters */ + /* prevent compiler from complaining about unused parameters */ pfnAuth = pfnAuth; strcpy(usb_devfile, "/dev/usb/scanner0"); @@ -531,7 +675,6 @@ sane_init (SANE_Int * piVersion, SANE_Auth_Callback pfnAuth) *piVersion = SANE_VERSION_CODE (SANE_CURRENT_MAJOR, V_MINOR, BUILD); } - return SANE_STATUS_GOOD; } @@ -694,7 +837,7 @@ sane_control_option (SANE_Handle h, SANE_Int n, SANE_Action Action, /* Get options of type SANE_Word */ case optBRX: case optTLX: - *(SANE_Word *) pVal = s->aValues[n].w; /* Not needed anymore - s->aValues[optOffsetX].w; */ + *(SANE_Word *) pVal = s->aValues[n].w; HP5400_DBG (DBG_MSG, "sane_control_option: SANE_ACTION_GET_VALUE %d = %d\n", n, *(SANE_Word *) pVal); @@ -702,14 +845,12 @@ sane_control_option (SANE_Handle h, SANE_Int n, SANE_Action Action, case optBRY: case optTLY: - *(SANE_Word *) pVal = s->aValues[n].w; /* Not needed anymore - - s->aValues[optOffsetY].w; */ + *(SANE_Word *) pVal = s->aValues[n].w; HP5400_DBG (DBG_MSG, "sane_control_option: SANE_ACTION_GET_VALUE %d = %d\n", n, *(SANE_Word *) pVal); break; - case optOffsetX: - case optOffsetY: case optCount: case optDPI: HP5400_DBG (DBG_MSG, @@ -726,14 +867,94 @@ sane_control_option (SANE_Handle h, SANE_Int n, SANE_Action Action, memcpy (pVal, s->aValues[n].wa, s->aOptions[n].size); break; + case optSensorScanTo: + case optSensorWeb: + case optSensorReprint: + case optSensorEmail: + case optSensorCopy: + case optSensorMoreOptions: + case optSensorCancel: + case optSensorPowerSave: + case optSensorCopiesUp: + case optSensorCopiesDown: + case optSensorColourBW: + { + HP5400_DBG (DBG_MSG, "Reading sensor state\n"); + + uint16_t sensorMap; + if (GetSensors(&s->HWParams, &sensorMap) != 0) + { + HP5400_DBG (DBG_ERR, + "sane_control_option: SANE_ACTION_SET_VALUE could not retrieve sensors\n"); + return SANE_STATUS_IO_ERROR; + + } + + HP5400_DBG (DBG_MSG, "Sensor state=%x\n", sensorMap); + + // Add read flags to what we already have so that we can report them when requested. + s->sensorMap |= sensorMap; + + // Look up the mask based on the option number. + uint16_t mask = sensorMaskMap[n - optGroupSensors - 1]; + *(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 */ case optLamp: GetLamp (&s->HWParams, &fLampIsOn); *(SANE_Bool *) pVal = fLampIsOn; break; -#endif -#if 0 + case optCalibrate: /* although this option has nothing to read, it's added here to avoid a warning when running scanimage --help */ @@ -761,26 +982,70 @@ sane_control_option (SANE_Handle h, SANE_Int n, SANE_Action Action, case optBRX: case optTLX: - info |= SANE_INFO_RELOAD_PARAMS; - s->ScanParams.iLines = 0; /* Forget actual image settings */ - s->aValues[n].w = *(SANE_Word *) pVal; /* Not needed anymore - + s->aValues[optOffsetX].w; */ - break; - - case optBRY: - case optTLY: - info |= SANE_INFO_RELOAD_PARAMS; - s->ScanParams.iLines = 0; /* Forget actual image settings */ - s->aValues[n].w = *(SANE_Word *) pVal; /* Not needed anymore - + s->aValues[optOffsetY].w; */ - break; - case optDPI: - info |= SANE_INFO_RELOAD_PARAMS; - s->ScanParams.iLines = 0; /* Forget actual image settings */ -#ifdef SUPPORT_2400_DPI - (s->aValues[n].w) = *(SANE_Word *) pVal; -#else - (s->aValues[n].w) = min (1200, *(SANE_Word *) pVal); -#endif - break; + { + // Check against legal values. + SANE_Word value = *(SANE_Word *) pVal; + if ((value < s->aOptions[n].constraint.range->min) || + (value > s->aOptions[n].constraint.range->max)) + { + HP5400_DBG (DBG_ERR, + "sane_control_option: SANE_ACTION_SET_VALUE out of range X value\n"); + return SANE_STATUS_INVAL; + } + + info |= SANE_INFO_RELOAD_PARAMS; + s->ScanParams.iLines = 0; /* Forget actual image settings */ + s->aValues[n].w = value; + break; + } + + case optBRY: + case optTLY: + { + // Check against legal values. + SANE_Word value = *(SANE_Word *) pVal; + if ((value < s->aOptions[n].constraint.range->min) || + (value > s->aOptions[n].constraint.range->max)) + { + HP5400_DBG (DBG_ERR, + "sane_control_option: SANE_ACTION_SET_VALUE out of range Y value\n"); + return SANE_STATUS_INVAL; + } + + info |= SANE_INFO_RELOAD_PARAMS; + s->ScanParams.iLines = 0; /* Forget actual image settings */ + s->aValues[n].w = value; + break; + } + + case optDPI: + { + // Check against legal values. + SANE_Word dpiValue = *(SANE_Word *) pVal; + + // First check too large. + SANE_Word maxRes = setResolutions[setResolutions[0]]; + if (dpiValue > maxRes) + { + dpiValue = maxRes; + } + else // Check smaller values: if not exact match, pick next higher available. + { + for (SANE_Int resIdx = 1; resIdx <= setResolutions[0]; resIdx++) + { + if (dpiValue <= setResolutions[resIdx]) + { + dpiValue = setResolutions[resIdx]; + break; + } + } + } + + info |= SANE_INFO_RELOAD_PARAMS; + s->ScanParams.iLines = 0; /* Forget actual image settings */ + (s->aValues[n].w) = dpiValue; + break; + } case optGammaTableRed: case optGammaTableGreen: @@ -788,6 +1053,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, SANE_VALUE_SCAN_MODE_COLOR) == 0) + { + bwColourValue = 1; + } + else if (strcmp(bwColour, SANE_VALUE_SCAN_MODE_GRAY) == 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; @@ -924,6 +1253,7 @@ sane_start (SANE_Handle h) s->ScanParams.iLinesRead = 0; s->fScanning = TRUE; + s->fCanceled = FALSE; return SANE_STATUS_GOOD; } @@ -944,6 +1274,11 @@ sane_read (SANE_Handle h, SANE_Byte * buf, SANE_Int maxlen, SANE_Int * len) /* nothing has been read for the moment */ *len = 0; + if (!s->fScanning || s->fCanceled) + { + HP5400_DBG (DBG_MSG, "sane_read: we're not scanning.\n"); + return SANE_STATUS_EOF; + } /* if we read all the lines return EOF */ -- cgit v1.2.3