sane.ds: Add suport for CAP_AUTOFEED, make batch scans the default.
diff --git a/dlls/sane.ds/capability.c b/dlls/sane.ds/capability.c
index 4faab59..7a37399 100644
--- a/dlls/sane.ds/capability.c
+++ b/dlls/sane.ds/capability.c
@@ -166,6 +166,7 @@
{
TW_ARRAY *a;
static const UINT16 supported_caps[] = { CAP_SUPPORTEDCAPS, CAP_XFERCOUNT, CAP_UICONTROLLABLE,
+ CAP_AUTOFEED,
ICAP_XFERMECH, ICAP_PIXELTYPE, ICAP_UNITS, ICAP_BITDEPTH, ICAP_COMPRESSION, ICAP_PIXELFLAVOR,
ICAP_XRESOLUTION, ICAP_YRESOLUTION, ICAP_PHYSICALHEIGHT, ICAP_PHYSICALWIDTH };
@@ -815,6 +816,72 @@
return twCC;
}
+/* CAP_AUTOFEED */
+static TW_UINT16 SANE_CAPAutofeed (pTW_CAPABILITY pCapability, TW_UINT16 action)
+{
+ TW_UINT16 twCC = TWCC_BADCAP;
+#ifdef SONAME_LIBSANE
+ TW_UINT32 val;
+ SANE_Bool autofeed;
+ SANE_Status status;
+
+ TRACE("CAP_AUTOFEED\n");
+
+ if (sane_option_get_bool(activeDS.deviceHandle, "batch-scan", &autofeed, NULL) != SANE_STATUS_GOOD)
+ return TWCC_BADCAP;
+
+ switch (action)
+ {
+ case MSG_QUERYSUPPORT:
+ twCC = set_onevalue(pCapability, TWTY_INT32,
+ TWQC_GET | TWQC_SET | TWQC_GETDEFAULT | TWQC_GETCURRENT | TWQC_RESET );
+ break;
+
+ case MSG_GET:
+ twCC = set_onevalue(pCapability, TWTY_BOOL, autofeed);
+ break;
+
+ case MSG_SET:
+ twCC = msg_set(pCapability, &val);
+ if (twCC == TWCC_SUCCESS)
+ {
+ if (val)
+ autofeed = SANE_TRUE;
+ else
+ autofeed = SANE_FALSE;
+
+ status = sane_option_set_bool(activeDS.deviceHandle, "batch-scan", autofeed, NULL);
+ if (status != SANE_STATUS_GOOD)
+ {
+ ERR("Error %s: Could not set batch-scan to %d\n", psane_strstatus(status), autofeed);
+ return sane_status_to_twcc(status);
+ }
+ }
+ break;
+
+ case MSG_GETDEFAULT:
+ twCC = set_onevalue(pCapability, TWTY_BOOL, SANE_TRUE);
+ break;
+
+ case MSG_RESET:
+ autofeed = SANE_TRUE;
+ status = sane_option_set_bool(activeDS.deviceHandle, "batch-scan", autofeed, NULL);
+ if (status != SANE_STATUS_GOOD)
+ {
+ ERR("Error %s: Could not reset batch-scan to SANE_TRUE\n", psane_strstatus(status));
+ return sane_status_to_twcc(status);
+ }
+ /* .. fall through intentional .. */
+
+ case MSG_GETCURRENT:
+ twCC = set_onevalue(pCapability, TWTY_BOOL, autofeed);
+ break;
+ }
+#endif
+ return twCC;
+}
+
+
TW_UINT16 SANE_SaneCapability (pTW_CAPABILITY pCapability, TW_UINT16 action)
{
@@ -839,6 +906,10 @@
twCC = SANE_CAPUiControllable (pCapability, action);
break;
+ case CAP_AUTOFEED:
+ twCC = SANE_CAPAutofeed (pCapability, action);
+ break;
+
case ICAP_PIXELTYPE:
twCC = SANE_ICAPPixelType (pCapability, action);
break;
@@ -891,3 +962,17 @@
return twCC;
}
+
+TW_UINT16 SANE_SaneSetDefaults (void)
+{
+ TW_CAPABILITY cap;
+
+ memset(&cap, 0, sizeof(cap));
+ cap.Cap = CAP_AUTOFEED;
+ cap.ConType = TWON_DONTCARE16;
+
+ if (SANE_SaneCapability(&cap, MSG_RESET) == TWCC_SUCCESS)
+ GlobalFree(cap.hContainer);
+
+ return TWCC_SUCCESS;
+}
diff --git a/dlls/sane.ds/options.c b/dlls/sane.ds/options.c
index 4793883..1997abc 100644
--- a/dlls/sane.ds/options.c
+++ b/dlls/sane.ds/options.c
@@ -85,6 +85,33 @@
return psane_control_option(h, optno, SANE_ACTION_SET_VALUE, (void *) &val, status);
}
+SANE_Status sane_option_get_bool(SANE_Handle h, const char *option_name, SANE_Bool *val, SANE_Int *status)
+{
+ SANE_Status rc;
+ int optno;
+ const SANE_Option_Descriptor *opt;
+
+ rc = sane_find_option(h, option_name, &opt, &optno, SANE_TYPE_BOOL);
+ if (rc != SANE_STATUS_GOOD)
+ return rc;
+
+ return psane_control_option(h, optno, SANE_ACTION_GET_VALUE, (void *) val, status);
+}
+
+SANE_Status sane_option_set_bool(SANE_Handle h, const char *option_name, SANE_Bool val, SANE_Int *status)
+{
+ SANE_Status rc;
+ int optno;
+ const SANE_Option_Descriptor *opt;
+
+ rc = sane_find_option(h, option_name, &opt, &optno, SANE_TYPE_BOOL);
+ if (rc != SANE_STATUS_GOOD)
+ return rc;
+
+ return psane_control_option(h, optno, SANE_ACTION_SET_VALUE, (void *) &val, status);
+}
+
+
/* Important: SANE has the side effect of of overwriting val with the returned value */
SANE_Status sane_option_set_str(SANE_Handle h, const char *option_name, SANE_String val, SANE_Int *status)
{
diff --git a/dlls/sane.ds/sane_i.h b/dlls/sane.ds/sane_i.h
index 18fd8bb..81c9a9e 100644
--- a/dlls/sane.ds/sane_i.h
+++ b/dlls/sane.ds/sane_i.h
@@ -85,6 +85,7 @@
/* Helper functions */
extern TW_UINT16 SANE_SaneCapability (pTW_CAPABILITY pCapability, TW_UINT16 action);
+extern TW_UINT16 SANE_SaneSetDefaults (void);
/* Implementation of operation triplets
* From Application to Source (Control Information) */
@@ -228,6 +229,8 @@
SANE_Status sane_option_probe_mode(SANE_Handle h, SANE_String_Const **choices, char *current, int current_size);
SANE_Status sane_option_probe_scan_area(SANE_Handle h, const char *option_name, SANE_Fixed *val,
SANE_Unit *unit, SANE_Fixed *min, SANE_Fixed *max, SANE_Fixed *quant);
+SANE_Status sane_option_get_bool(SANE_Handle h, const char *option_name, SANE_Bool *val, SANE_Int *status);
+SANE_Status sane_option_set_bool(SANE_Handle h, const char *option_name, SANE_Bool val, SANE_Int *status);
#endif
diff --git a/dlls/sane.ds/sane_main.c b/dlls/sane.ds/sane_main.c
index 49a7cb3..d8ba9b5 100644
--- a/dlls/sane.ds/sane_main.c
+++ b/dlls/sane.ds/sane_main.c
@@ -661,11 +661,16 @@
}
status = psane_open(sane_devlist[i]->name,&activeDS.deviceHandle);
if (status == SANE_STATUS_GOOD) {
- activeDS.currentState = 4;
- activeDS.twCC = TWRC_SUCCESS;
- return TWRC_SUCCESS;
+ activeDS.twCC = SANE_SaneSetDefaults();
+ if (activeDS.twCC == TWCC_SUCCESS) {
+ activeDS.currentState = 4;
+ return TWRC_SUCCESS;
+ }
+ else
+ psane_close(activeDS.deviceHandle);
}
- ERR("sane_open(%s): %s\n", sane_devlist[i]->name, psane_strstatus (status));
+ else
+ ERR("sane_open(%s): %s\n", sane_devlist[i]->name, psane_strstatus (status));
return TWRC_FAILURE;
}
#endif
diff --git a/dlls/twain_32/tests/dsm.c b/dlls/twain_32/tests/dsm.c
index 46d0c5a..c4744f9 100644
--- a/dlls/twain_32/tests/dsm.c
+++ b/dlls/twain_32/tests/dsm.c
@@ -578,6 +578,12 @@
if (capabilities[ICAP_YRESOLUTION])
test_resolution(appid, source, ICAP_YRESOLUTION,
TWQC_GET | TWQC_SET | TWQC_GETDEFAULT | TWQC_GETCURRENT | TWQC_RESET);
+
+ /* Optional capabilities */
+ if (capabilities[CAP_AUTOFEED])
+ test_onevalue_cap(appid, source, CAP_AUTOFEED, TWTY_BOOL,
+ TWQC_GET | TWQC_SET | TWQC_GETDEFAULT | TWQC_GETCURRENT | TWQC_RESET);
+
}
}