sane.ds: Use Twain types and status codes in option helpers.

Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Alexandre Julliard 2021-10-25 17:32:04 +02:00
parent ee280d8cc3
commit b263ff26b9
5 changed files with 295 additions and 425 deletions

View File

@ -310,21 +310,20 @@ static BOOL sane_mode_to_pixeltype(SANE_String_Const mode, TW_UINT16 *pixeltype)
/* ICAP_PIXELTYPE */
static TW_UINT16 SANE_ICAPPixelType (pTW_CAPABILITY pCapability, TW_UINT16 action)
{
TW_UINT16 twCC = TWCC_BADCAP;
TW_UINT16 twCC;
TW_UINT32 possible_values[3];
int possible_value_count;
TW_UINT32 val;
SANE_Status rc;
SANE_Int status;
SANE_String_Const *choices;
BOOL reload = FALSE;
const char * const *choices;
char current_mode[64];
TW_UINT16 current_pixeltype = TWPT_BW;
SANE_Char mode[64];
TRACE("ICAP_PIXELTYPE\n");
rc = sane_option_probe_mode(&choices, current_mode, sizeof(current_mode));
if (rc != SANE_STATUS_GOOD)
twCC = sane_option_probe_mode(&choices, current_mode, sizeof(current_mode));
if (twCC != TWCC_SUCCESS)
{
ERR("Unable to retrieve mode from sane, ICAP_PIXELTYPE unsupported\n");
return twCC;
@ -366,17 +365,14 @@ static TW_UINT16 SANE_ICAPPixelType (pTW_CAPABILITY pCapability, TW_UINT16 actio
if (! pixeltype_to_sane_mode(val, mode, sizeof(mode)))
return TWCC_BADVALUE;
status = 0;
rc = sane_option_set_str("mode", mode, &status);
twCC = sane_option_set_str("mode", mode, &reload);
/* Some SANE devices use 'Grayscale' instead of the standard 'Gray' */
if (rc == SANE_STATUS_INVAL && strcmp(mode, SANE_VALUE_SCAN_MODE_GRAY) == 0)
if (twCC != TWCC_SUCCESS && strcmp(mode, SANE_VALUE_SCAN_MODE_GRAY) == 0)
{
strcpy(mode, "Grayscale");
rc = sane_option_set_str("mode", mode, &status);
twCC = sane_option_set_str("mode", mode, &reload);
}
if (rc != SANE_STATUS_GOOD)
return sane_status_to_twcc(rc);
if (status & SANE_INFO_RELOAD_PARAMS)
if (reload)
sane_get_parameters (activeDS.deviceHandle, &activeDS.sane_param);
}
break;
@ -390,18 +386,15 @@ static TW_UINT16 SANE_ICAPPixelType (pTW_CAPABILITY pCapability, TW_UINT16 actio
if (! pixeltype_to_sane_mode(current_pixeltype, mode, sizeof(mode)))
return TWCC_BADVALUE;
status = 0;
rc = sane_option_set_str("mode", mode, &status);
twCC = sane_option_set_str("mode", mode, &reload);
/* Some SANE devices use 'Grayscale' instead of the standard 'Gray' */
if (rc == SANE_STATUS_INVAL && strcmp(mode, SANE_VALUE_SCAN_MODE_GRAY) == 0)
if (twCC != TWCC_SUCCESS && strcmp(mode, SANE_VALUE_SCAN_MODE_GRAY) == 0)
{
strcpy(mode, "Grayscale");
rc = sane_option_set_str("mode", mode, &status);
twCC = sane_option_set_str("mode", mode, &reload);
}
if (rc != SANE_STATUS_GOOD)
return sane_status_to_twcc(rc);
if (status & SANE_INFO_RELOAD_PARAMS)
sane_get_parameters (activeDS.deviceHandle, &activeDS.sane_param);
if (twCC != TWCC_SUCCESS) break;
if (reload) sane_get_parameters (activeDS.deviceHandle, &activeDS.sane_param);
/* .. fall through intentional .. */
@ -558,12 +551,10 @@ static TW_UINT16 SANE_ICAPResolution (pTW_CAPABILITY pCapability, TW_UINT16 acti
{
TW_UINT16 twCC = TWCC_BADCAP;
TW_UINT32 val;
SANE_Int current_resolution;
int current_resolution;
TW_FIX32 *default_res;
const char *best_option_name;
SANE_Int minval, maxval, quantval;
SANE_Status sane_rc;
SANE_Int set_status;
int minval, maxval, quantval;
TRACE("ICAP_%cRESOLUTION\n", cap == ICAP_XRESOLUTION ? 'X' : 'Y');
@ -578,10 +569,10 @@ static TW_UINT16 SANE_ICAPResolution (pTW_CAPABILITY pCapability, TW_UINT16 acti
best_option_name = "y-resolution";
default_res = &activeDS.defaultYResolution;
}
if (sane_option_get_int(best_option_name, &current_resolution) != SANE_STATUS_GOOD)
if (sane_option_get_int(best_option_name, &current_resolution) != TWCC_SUCCESS)
{
best_option_name = "resolution";
if (sane_option_get_int(best_option_name, &current_resolution) != SANE_STATUS_GOOD)
if (sane_option_get_int(best_option_name, &current_resolution) != TWCC_SUCCESS)
return TWCC_BADCAP;
}
@ -610,10 +601,8 @@ static TW_UINT16 SANE_ICAPResolution (pTW_CAPABILITY pCapability, TW_UINT16 acti
break;
case MSG_GET:
sane_rc = sane_option_probe_resolution(best_option_name, &minval, &maxval, &quantval);
if (sane_rc != SANE_STATUS_GOOD)
twCC = TWCC_BADCAP;
else
twCC = sane_option_probe_resolution(best_option_name, &minval, &maxval, &quantval);
if (twCC == TWCC_SUCCESS)
twCC = msg_get_range(pCapability, TWTY_FIX32,
minval, maxval, quantval == 0 ? 1 : quantval, default_res->Whole, current_resolution);
break;
@ -623,15 +612,10 @@ static TW_UINT16 SANE_ICAPResolution (pTW_CAPABILITY pCapability, TW_UINT16 acti
if (twCC == TWCC_SUCCESS)
{
TW_FIX32 f32;
BOOL reload = FALSE;
memcpy(&f32, &val, sizeof(f32));
sane_rc = sane_option_set_int(best_option_name, f32.Whole, &set_status);
if (sane_rc != SANE_STATUS_GOOD)
{
FIXME("Status of %d not expected or handled\n", sane_rc);
twCC = TWCC_BADCAP;
}
else if (set_status == SANE_INFO_INEXACT)
twCC = TWCC_CHECKSTATUS;
twCC = sane_option_set_int(best_option_name, f32.Whole, &reload);
if (reload) twCC = TWCC_CHECKSTATUS;
}
break;
@ -640,9 +624,8 @@ static TW_UINT16 SANE_ICAPResolution (pTW_CAPABILITY pCapability, TW_UINT16 acti
break;
case MSG_RESET:
sane_rc = sane_option_set_int(best_option_name, default_res->Whole, NULL);
if (sane_rc != SANE_STATUS_GOOD)
return TWCC_BADCAP;
twCC = sane_option_set_int(best_option_name, default_res->Whole, NULL);
if (twCC != TWCC_SUCCESS) return twCC;
/* .. fall through intentional .. */
@ -656,24 +639,21 @@ static TW_UINT16 SANE_ICAPResolution (pTW_CAPABILITY pCapability, TW_UINT16 acti
/* ICAP_PHYSICALHEIGHT, ICAP_PHYSICALWIDTH */
static TW_UINT16 SANE_ICAPPhysical (pTW_CAPABILITY pCapability, TW_UINT16 action, TW_UINT16 cap)
{
TW_UINT16 twCC = TWCC_BADCAP;
TW_UINT16 twCC;
TW_FIX32 res;
char option_name[64];
SANE_Fixed lower, upper;
SANE_Unit lowerunit, upperunit;
SANE_Status status;
TRACE("ICAP_PHYSICAL%s\n", cap == ICAP_PHYSICALHEIGHT? "HEIGHT" : "WIDTH");
sprintf(option_name, "tl-%c", cap == ICAP_PHYSICALHEIGHT ? 'y' : 'x');
status = sane_option_probe_scan_area(option_name, NULL, &lowerunit, &lower, NULL, NULL);
if (status != SANE_STATUS_GOOD)
return sane_status_to_twcc(status);
twCC = sane_option_probe_scan_area(option_name, NULL, &lowerunit, &lower, NULL, NULL);
if (twCC != TWCC_SUCCESS) return twCC;
sprintf(option_name, "br-%c", cap == ICAP_PHYSICALHEIGHT ? 'y' : 'x');
status = sane_option_probe_scan_area(option_name, NULL, &upperunit, NULL, &upper, NULL);
if (status != SANE_STATUS_GOOD)
return sane_status_to_twcc(status);
twCC = sane_option_probe_scan_area(option_name, NULL, &upperunit, NULL, &upper, NULL);
if (twCC != TWCC_SUCCESS) return twCC;
if (upperunit != lowerunit)
return TWCC_BADCAP;
@ -746,28 +726,23 @@ static TW_UINT16 SANE_ICAPPixelFlavor (pTW_CAPABILITY pCapability, TW_UINT16 act
static TW_UINT16 get_width_height(double *width, double *height, BOOL max)
{
SANE_Status status;
TW_UINT16 rc;
SANE_Fixed tlx_current, tlx_min, tlx_max;
SANE_Fixed tly_current, tly_min, tly_max;
SANE_Fixed brx_current, brx_min, brx_max;
SANE_Fixed bry_current, bry_min, bry_max;
status = sane_option_probe_scan_area("tl-x", &tlx_current, NULL, &tlx_min, &tlx_max, NULL);
if (status != SANE_STATUS_GOOD)
return sane_status_to_twcc(status);
rc = sane_option_probe_scan_area("tl-x", &tlx_current, NULL, &tlx_min, &tlx_max, NULL);
if (rc != TWCC_SUCCESS) return rc;
status = sane_option_probe_scan_area("tl-y", &tly_current, NULL, &tly_min, &tly_max, NULL);
if (status != SANE_STATUS_GOOD)
return sane_status_to_twcc(status);
rc = sane_option_probe_scan_area("tl-y", &tly_current, NULL, &tly_min, &tly_max, NULL);
if (rc != TWCC_SUCCESS) return rc;
status = sane_option_probe_scan_area("br-x", &brx_current, NULL, &brx_min, &brx_max, NULL);
if (status != SANE_STATUS_GOOD)
return sane_status_to_twcc(status);
rc = sane_option_probe_scan_area("br-x", &brx_current, NULL, &brx_min, &brx_max, NULL);
if (rc != TWCC_SUCCESS) return rc;
status = sane_option_probe_scan_area("br-y", &bry_current, NULL, &bry_min, &bry_max, NULL);
if (status != SANE_STATUS_GOOD)
return sane_status_to_twcc(status);
rc = sane_option_probe_scan_area("br-y", &bry_current, NULL, &bry_min, &bry_max, NULL);
if (rc != TWCC_SUCCESS) return rc;
if (max)
*width = SANE_UNFIX(brx_max) - SANE_UNFIX(tlx_min);
@ -784,11 +759,7 @@ static TW_UINT16 get_width_height(double *width, double *height, BOOL max)
static TW_UINT16 set_one_coord(const char *name, double coord)
{
SANE_Status status;
status = sane_option_set_fixed(name, SANE_FIX(coord), NULL);
if (status != SANE_STATUS_GOOD)
return sane_status_to_twcc(status);
return TWCC_SUCCESS;
return sane_option_set_fixed(name, coord * 65536, NULL);
}
static TW_UINT16 set_width_height(double width, double height)
@ -967,11 +938,10 @@ static TW_UINT16 SANE_CAPAutofeed (pTW_CAPABILITY pCapability, TW_UINT16 action)
TW_UINT16 twCC = TWCC_BADCAP;
TW_UINT32 val;
SANE_Bool autofeed;
SANE_Status status;
TRACE("CAP_AUTOFEED\n");
if (sane_option_get_bool("batch-scan", &autofeed, NULL) != SANE_STATUS_GOOD)
if (sane_option_get_bool("batch-scan", &autofeed) != TWCC_SUCCESS)
return TWCC_BADCAP;
switch (action)
@ -994,12 +964,7 @@ static TW_UINT16 SANE_CAPAutofeed (pTW_CAPABILITY pCapability, TW_UINT16 action)
else
autofeed = SANE_FALSE;
status = sane_option_set_bool("batch-scan", autofeed, NULL);
if (status != SANE_STATUS_GOOD)
{
ERR("Error %s: Could not set batch-scan to %d\n", sane_strstatus(status), autofeed);
return sane_status_to_twcc(status);
}
twCC = sane_option_set_bool("batch-scan", autofeed);
}
break;
@ -1009,12 +974,8 @@ static TW_UINT16 SANE_CAPAutofeed (pTW_CAPABILITY pCapability, TW_UINT16 action)
case MSG_RESET:
autofeed = SANE_TRUE;
status = sane_option_set_bool("batch-scan", autofeed, NULL);
if (status != SANE_STATUS_GOOD)
{
ERR("Error %s: Could not reset batch-scan to SANE_TRUE\n", sane_strstatus(status));
return sane_status_to_twcc(status);
}
twCC = sane_option_set_bool("batch-scan", autofeed);
if (twCC != TWCC_SUCCESS) break;
/* .. fall through intentional .. */
case MSG_GETCURRENT:
@ -1030,12 +991,11 @@ static TW_UINT16 SANE_CAPFeederEnabled (pTW_CAPABILITY pCapability, TW_UINT16 ac
TW_UINT16 twCC = TWCC_BADCAP;
TW_UINT32 val;
TW_BOOL enabled;
SANE_Status status;
SANE_Char source[64];
TRACE("CAP_FEEDERENABLED\n");
if (sane_option_get_str(SANE_NAME_SCAN_SOURCE, source, sizeof(source), NULL) != SANE_STATUS_GOOD)
if (sane_option_get_str(SANE_NAME_SCAN_SOURCE, source, sizeof(source)) != TWCC_SUCCESS)
return TWCC_BADCAP;
if (strcmp(source, "Auto") == 0 || strcmp(source, "ADF") == 0)
@ -1059,16 +1019,11 @@ static TW_UINT16 SANE_CAPFeederEnabled (pTW_CAPABILITY pCapability, TW_UINT16 ac
if (twCC == TWCC_SUCCESS)
{
strcpy(source, "ADF");
status = sane_option_set_str(SANE_NAME_SCAN_SOURCE, source, NULL);
if (status != SANE_STATUS_GOOD)
twCC = sane_option_set_str(SANE_NAME_SCAN_SOURCE, source, NULL);
if (twCC != TWCC_SUCCESS)
{
strcpy(source, "Auto");
status = sane_option_set_str(SANE_NAME_SCAN_SOURCE, source, NULL);
}
if (status != SANE_STATUS_GOOD)
{
ERR("Error %s: Could not set source to either ADF or Auto\n", sane_strstatus(status));
return sane_status_to_twcc(status);
twCC = sane_option_set_str(SANE_NAME_SCAN_SOURCE, source, NULL);
}
}
break;
@ -1079,7 +1034,7 @@ static TW_UINT16 SANE_CAPFeederEnabled (pTW_CAPABILITY pCapability, TW_UINT16 ac
case MSG_RESET:
strcpy(source, "Auto");
if (sane_option_set_str(SANE_NAME_SCAN_SOURCE, source, NULL) == SANE_STATUS_GOOD)
if (sane_option_set_str(SANE_NAME_SCAN_SOURCE, source, NULL) == TWCC_SUCCESS)
enabled = TRUE;
/* .. fall through intentional .. */

View File

@ -35,7 +35,7 @@ TW_UINT16 SANE_ImageInfoGet (pTW_IDENTITY pOrigin,
TW_UINT16 twRC = TWRC_SUCCESS;
pTW_IMAGEINFO pImageInfo = (pTW_IMAGEINFO) pData;
SANE_Status status;
SANE_Int resolution;
int resolution;
TRACE("DG_IMAGE/DAT_IMAGEINFO/MSG_GET\n");
@ -62,7 +62,7 @@ TW_UINT16 SANE_ImageInfoGet (pTW_IDENTITY pOrigin,
activeDS.sane_param_valid = TRUE;
}
if (sane_option_get_int("resolution", &resolution) == SANE_STATUS_GOOD)
if (sane_option_get_int("resolution", &resolution) == TWCC_SUCCESS)
pImageInfo->XResolution.Whole = pImageInfo->YResolution.Whole = resolution;
else
pImageInfo->XResolution.Whole = pImageInfo->YResolution.Whole = -1;
@ -117,23 +117,23 @@ TW_UINT16 SANE_ImageLayoutGet (pTW_IDENTITY pOrigin,
SANE_Fixed tly_current;
SANE_Fixed brx_current;
SANE_Fixed bry_current;
SANE_Status status;
TW_UINT16 rc;
TRACE("DG_IMAGE/DAT_IMAGELAYOUT/MSG_GET\n");
status = sane_option_probe_scan_area("tl-x", &tlx_current, NULL, NULL, NULL, NULL);
if (status == SANE_STATUS_GOOD)
status = sane_option_probe_scan_area("tl-y", &tly_current, NULL, NULL, NULL, NULL);
rc = sane_option_probe_scan_area("tl-x", &tlx_current, NULL, NULL, NULL, NULL);
if (rc == TWCC_SUCCESS)
rc = sane_option_probe_scan_area("tl-y", &tly_current, NULL, NULL, NULL, NULL);
if (status == SANE_STATUS_GOOD)
status = sane_option_probe_scan_area("br-x", &brx_current, NULL, NULL, NULL, NULL);
if (rc == TWCC_SUCCESS)
rc = sane_option_probe_scan_area("br-x", &brx_current, NULL, NULL, NULL, NULL);
if (status == SANE_STATUS_GOOD)
status = sane_option_probe_scan_area("br-y", &bry_current, NULL, NULL, NULL, NULL);
if (rc == TWCC_SUCCESS)
rc = sane_option_probe_scan_area("br-y", &bry_current, NULL, NULL, NULL, NULL);
if (status != SANE_STATUS_GOOD)
if (rc != TWCC_SUCCESS)
{
activeDS.twCC = sane_status_to_twcc(status);
activeDS.twCC = rc;
return TWRC_FAILURE;
}
@ -170,17 +170,13 @@ TW_UINT16 SANE_ImageLayoutReset (pTW_IDENTITY pOrigin,
static TW_UINT16 set_one_imagecoord(const char *option_name, TW_FIX32 val, BOOL *changed)
{
double d = val.Whole + ((double) val.Frac / 65536.0);
int set_status = 0;
SANE_Status status;
status = sane_option_set_fixed(option_name, SANE_FIX((d * 254) / 10), &set_status);
if (status != SANE_STATUS_GOOD)
int v = val.Whole * 65536 + val.Frac;
TW_UINT16 rc = sane_option_set_fixed(option_name, MulDiv( v, 254, 10 ), changed);
if (rc != TWCC_SUCCESS)
{
activeDS.twCC = sane_status_to_twcc(status);
activeDS.twCC = rc;
return TWRC_FAILURE;
}
if (set_status & SANE_INFO_INEXACT)
*changed = TRUE;
return TWRC_SUCCESS;
}

View File

@ -22,200 +22,7 @@
#include "sane_i.h"
#include "wine/debug.h"
static SANE_Status sane_find_option(const char *option_name,
const SANE_Option_Descriptor **opt_p, int *optno, SANE_Value_Type type)
{
SANE_Status rc;
SANE_Int optcount;
const SANE_Option_Descriptor *opt;
int i;
/* Debian, in 32_net_backend_standard_fix.dpatch,
* forces a frontend (that's us) to reload options
* manually by invoking get_option_descriptor. */
opt = sane_get_option_descriptor(activeDS.deviceHandle, 0);
if (! opt)
return SANE_STATUS_EOF;
rc = sane_control_option(activeDS.deviceHandle, 0, SANE_ACTION_GET_VALUE, &optcount, NULL);
if (rc != SANE_STATUS_GOOD)
return rc;
for (i = 1; i < optcount; i++)
{
opt = sane_get_option_descriptor(activeDS.deviceHandle, i);
if (opt && (opt->name && strcmp(opt->name, option_name) == 0) &&
opt->type == type)
{
*opt_p = opt;
*optno = i;
return SANE_STATUS_GOOD;
}
}
return SANE_STATUS_EOF;
}
SANE_Status sane_option_get_int(const char *option_name, SANE_Int *val)
{
SANE_Status rc;
int optno;
const SANE_Option_Descriptor *opt;
rc = sane_find_option(option_name, &opt, &optno, SANE_TYPE_INT);
if (rc != SANE_STATUS_GOOD)
return rc;
return sane_control_option(activeDS.deviceHandle, optno, SANE_ACTION_GET_VALUE, val, NULL);
}
SANE_Status sane_option_set_int(const char *option_name, SANE_Int val, SANE_Int *status)
{
SANE_Status rc;
int optno;
const SANE_Option_Descriptor *opt;
rc = sane_find_option(option_name, &opt, &optno, SANE_TYPE_INT);
if (rc != SANE_STATUS_GOOD)
return rc;
return sane_control_option(activeDS.deviceHandle, optno, SANE_ACTION_SET_VALUE, (void *) &val, status);
}
SANE_Status sane_option_get_bool(const char *option_name, SANE_Bool *val, SANE_Int *status)
{
SANE_Status rc;
int optno;
const SANE_Option_Descriptor *opt;
rc = sane_find_option(option_name, &opt, &optno, SANE_TYPE_BOOL);
if (rc != SANE_STATUS_GOOD)
return rc;
return sane_control_option(activeDS.deviceHandle, optno, SANE_ACTION_GET_VALUE, (void *) val, status);
}
SANE_Status sane_option_set_bool(const char *option_name, SANE_Bool val, SANE_Int *status)
{
SANE_Status rc;
int optno;
const SANE_Option_Descriptor *opt;
rc = sane_find_option(option_name, &opt, &optno, SANE_TYPE_BOOL);
if (rc != SANE_STATUS_GOOD)
return rc;
return sane_control_option(activeDS.deviceHandle, optno, SANE_ACTION_SET_VALUE, (void *) &val, status);
}
SANE_Status sane_option_set_fixed(const char *option_name, SANE_Fixed val, SANE_Int *status)
{
SANE_Status rc;
int optno;
const SANE_Option_Descriptor *opt;
rc = sane_find_option(option_name, &opt, &optno, SANE_TYPE_FIXED);
if (rc != SANE_STATUS_GOOD)
return rc;
return sane_control_option(activeDS.deviceHandle, optno, SANE_ACTION_SET_VALUE, (void *) &val, status);
}
SANE_Status sane_option_get_str(const char *option_name, SANE_String val, size_t len, SANE_Int *status)
{
SANE_Status rc;
int optno;
const SANE_Option_Descriptor *opt;
rc = sane_find_option(option_name, &opt, &optno, SANE_TYPE_STRING);
if (rc != SANE_STATUS_GOOD)
return rc;
if (opt->size < len)
return sane_control_option(activeDS.deviceHandle, optno, SANE_ACTION_GET_VALUE, (void *) val, status);
else
return SANE_STATUS_NO_MEM;
}
/* Important: SANE has the side effect of overwriting val with the returned value */
SANE_Status sane_option_set_str(const char *option_name, SANE_String val, SANE_Int *status)
{
SANE_Status rc;
int optno;
const SANE_Option_Descriptor *opt;
rc = sane_find_option(option_name, &opt, &optno, SANE_TYPE_STRING);
if (rc != SANE_STATUS_GOOD)
return rc;
return sane_control_option(activeDS.deviceHandle, optno, SANE_ACTION_SET_VALUE, (void *) val, status);
}
SANE_Status sane_option_probe_resolution(const char *option_name, SANE_Int *minval, SANE_Int *maxval, SANE_Int *quant)
{
SANE_Status rc;
int optno;
const SANE_Option_Descriptor *opt;
rc = sane_find_option(option_name, &opt, &optno, SANE_TYPE_INT);
if (rc != SANE_STATUS_GOOD)
return rc;
if (opt->constraint_type != SANE_CONSTRAINT_RANGE)
return SANE_STATUS_UNSUPPORTED;
*minval = opt->constraint.range->min;
*maxval = opt->constraint.range->max;
*quant = opt->constraint.range->quant;
return rc;
}
SANE_Status sane_option_probe_mode(SANE_String_Const **choices, char *current, int current_size)
{
SANE_Status rc;
int optno;
const SANE_Option_Descriptor *opt;
rc = sane_find_option("mode", &opt, &optno, SANE_TYPE_STRING);
if (rc != SANE_STATUS_GOOD)
return rc;
if (choices && opt->constraint_type == SANE_CONSTRAINT_STRING_LIST)
*choices = (SANE_String_Const *) opt->constraint.string_list;
if (opt->size < current_size)
return sane_control_option(activeDS.deviceHandle, optno, SANE_ACTION_GET_VALUE, current, NULL);
else
return SANE_STATUS_NO_MEM;
}
SANE_Status sane_option_probe_scan_area(const char *option_name, SANE_Fixed *val,
SANE_Unit *unit, SANE_Fixed *min, SANE_Fixed *max, SANE_Fixed *quant)
{
SANE_Status rc;
int optno;
const SANE_Option_Descriptor *opt;
rc = sane_find_option(option_name, &opt, &optno, SANE_TYPE_FIXED);
if (rc != SANE_STATUS_GOOD)
return rc;
if (unit)
*unit = opt->unit;
if (min)
*min = opt->constraint.range->min;
if (max)
*max = opt->constraint.range->max;
if (quant)
*quant = opt->constraint.range->quant;
if (val)
rc = sane_control_option(activeDS.deviceHandle, optno, SANE_ACTION_GET_VALUE, val, NULL);
return rc;
}
TW_UINT16 sane_status_to_twcc(SANE_Status rc)
static TW_UINT16 sane_status_to_twcc(SANE_Status rc)
{
switch (rc)
{
@ -241,6 +48,188 @@ TW_UINT16 sane_status_to_twcc(SANE_Status rc)
return TWCC_BUMMER;
}
}
TW_UINT16 sane_option_get_value( int optno, void *val )
{
return sane_status_to_twcc( sane_control_option( activeDS.deviceHandle, optno,
SANE_ACTION_GET_VALUE, val, NULL ));
}
TW_UINT16 sane_option_set_value( int optno, void *val, BOOL *reload )
{
int status = 0;
TW_UINT16 rc = sane_status_to_twcc( sane_control_option( activeDS.deviceHandle, optno,
SANE_ACTION_SET_VALUE, val, &status ));
if (rc == TWCC_SUCCESS && reload)
*reload = (status & (SANE_INFO_RELOAD_OPTIONS | SANE_INFO_RELOAD_PARAMS | SANE_INFO_INEXACT)) != 0;
return rc;
}
static TW_UINT16 sane_find_option(const char *option_name,
const SANE_Option_Descriptor **opt_p, int *optno, SANE_Value_Type type)
{
TW_UINT16 rc;
int optcount;
const SANE_Option_Descriptor *opt;
int i;
/* Debian, in 32_net_backend_standard_fix.dpatch,
* forces a frontend (that's us) to reload options
* manually by invoking get_option_descriptor. */
opt = sane_get_option_descriptor(activeDS.deviceHandle, 0);
if (! opt)
return TWCC_BUMMER;
rc = sane_option_get_value( 0, &optcount );
if (rc != TWCC_SUCCESS) return rc;
for (i = 1; i < optcount; i++)
{
opt = sane_get_option_descriptor(activeDS.deviceHandle, i);
if (opt && (opt->name && strcmp(opt->name, option_name) == 0) &&
opt->type == type)
{
*opt_p = opt;
*optno = i;
return TWCC_SUCCESS;
}
}
return TWCC_CAPUNSUPPORTED;
}
TW_UINT16 sane_option_get_int(const char *option_name, int *val)
{
int optno;
const SANE_Option_Descriptor *opt;
TW_UINT16 rc = sane_find_option(option_name, &opt, &optno, SANE_TYPE_INT);
if (rc == TWCC_SUCCESS) rc = sane_option_get_value( optno, val );
return rc;
}
TW_UINT16 sane_option_set_int(const char *option_name, int val, BOOL *needs_reload )
{
int optno;
const SANE_Option_Descriptor *opt;
TW_UINT16 rc = sane_find_option(option_name, &opt, &optno, SANE_TYPE_INT);
if (rc == TWCC_SUCCESS) rc = sane_option_set_value( optno, &val, needs_reload );
return rc;
}
TW_UINT16 sane_option_get_bool(const char *option_name, int *val)
{
int optno;
const SANE_Option_Descriptor *opt;
TW_UINT16 rc = sane_find_option(option_name, &opt, &optno, SANE_TYPE_BOOL);
if (rc == TWCC_SUCCESS) rc = sane_option_get_value( optno, val );
return rc;
}
TW_UINT16 sane_option_set_bool(const char *option_name, int val )
{
int optno;
const SANE_Option_Descriptor *opt;
TW_UINT16 rc = sane_find_option(option_name, &opt, &optno, SANE_TYPE_BOOL);
if (rc == TWCC_SUCCESS) rc = sane_option_set_value( optno, &val, NULL );
return rc;
}
TW_UINT16 sane_option_set_fixed(const char *option_name, int val, BOOL *needs_reload )
{
int optno;
const SANE_Option_Descriptor *opt;
TW_UINT16 rc = sane_find_option(option_name, &opt, &optno, SANE_TYPE_FIXED);
if (rc == TWCC_SUCCESS) rc = sane_option_set_value( optno, &val, needs_reload );
return rc;
}
TW_UINT16 sane_option_get_str(const char *option_name, char *val, int len)
{
int optno;
const SANE_Option_Descriptor *opt;
TW_UINT16 rc = sane_find_option(option_name, &opt, &optno, SANE_TYPE_STRING);
if (rc == TWCC_SUCCESS)
{
if (opt->size < len)
rc = sane_option_get_value( optno, val );
else
rc = TWCC_BADVALUE;
}
return rc;
}
/* Important: SANE has the side effect of overwriting val with the returned value */
TW_UINT16 sane_option_set_str(const char *option_name, char *val, BOOL *needs_reload)
{
int optno;
const SANE_Option_Descriptor *opt;
TW_UINT16 rc = sane_find_option(option_name, &opt, &optno, SANE_TYPE_STRING);
if (rc == TWCC_SUCCESS) rc = sane_option_set_value( optno, &val, needs_reload );
return rc;
}
TW_UINT16 sane_option_probe_resolution(const char *option_name, int *minval, int *maxval, int *quant)
{
int optno;
const SANE_Option_Descriptor *opt;
TW_UINT16 rc = sane_find_option(option_name, &opt, &optno, SANE_TYPE_INT);
if (rc != TWCC_SUCCESS) return rc;
if (opt->constraint_type != SANE_CONSTRAINT_RANGE) return TWCC_CAPUNSUPPORTED;
*minval = opt->constraint.range->min;
*maxval = opt->constraint.range->max;
*quant = opt->constraint.range->quant;
return rc;
}
TW_UINT16 sane_option_probe_mode(const char * const **choices, char *current, int current_size)
{
int optno;
const SANE_Option_Descriptor *opt;
TW_UINT16 rc = sane_find_option("mode", &opt, &optno, SANE_TYPE_STRING);
if (rc != TWCC_SUCCESS) return rc;
if (choices && opt->constraint_type == SANE_CONSTRAINT_STRING_LIST)
*choices = opt->constraint.string_list;
if (opt->size < current_size)
return sane_option_get_value( optno, current );
else
return TWCC_BADVALUE;
}
TW_UINT16 sane_option_probe_scan_area(const char *option_name, SANE_Fixed *val,
SANE_Unit *unit, SANE_Fixed *min, SANE_Fixed *max, SANE_Fixed *quant)
{
int optno;
const SANE_Option_Descriptor *opt;
TW_UINT16 rc = sane_find_option(option_name, &opt, &optno, SANE_TYPE_FIXED);
if (rc != TWCC_SUCCESS) return rc;
if (unit)
*unit = opt->unit;
if (min)
*min = opt->constraint.range->min;
if (max)
*max = opt->constraint.range->max;
if (quant)
*quant = opt->constraint.range->quant;
if (val)
rc = sane_option_get_value( optno, val );
return rc;
}
static void convert_double_fix32(double d, TW_FIX32 *fix32)
{
TW_INT32 value = (TW_INT32) (d * 65536.0 + 0.5);

View File

@ -206,18 +206,19 @@ BOOL DoScannerUI(void) DECLSPEC_HIDDEN;
HWND ScanningDialogBox(HWND dialog, LONG progress) DECLSPEC_HIDDEN;
/* Option functions */
SANE_Status sane_option_get_int(const char *option_name, SANE_Int *val) DECLSPEC_HIDDEN;
SANE_Status sane_option_set_int(const char *option_name, SANE_Int val, SANE_Int *status) DECLSPEC_HIDDEN;
SANE_Status sane_option_get_str(const char *option_name, SANE_String val, size_t len, SANE_Int *status) DECLSPEC_HIDDEN;
SANE_Status sane_option_set_str(const char *option_name, SANE_String val, SANE_Int *status) DECLSPEC_HIDDEN;
SANE_Status sane_option_probe_resolution(const char *option_name, SANE_Int *minval, SANE_Int *maxval, SANE_Int *quant) DECLSPEC_HIDDEN;
SANE_Status sane_option_probe_mode(SANE_String_Const **choices, char *current, int current_size) DECLSPEC_HIDDEN;
SANE_Status sane_option_probe_scan_area(const char *option_name, SANE_Fixed *val,
SANE_Unit *unit, SANE_Fixed *min, SANE_Fixed *max, SANE_Fixed *quant) DECLSPEC_HIDDEN;
SANE_Status sane_option_get_bool(const char *option_name, SANE_Bool *val, SANE_Int *status) DECLSPEC_HIDDEN;
SANE_Status sane_option_set_bool(const char *option_name, SANE_Bool val, SANE_Int *status) DECLSPEC_HIDDEN;
SANE_Status sane_option_set_fixed(const char *option_name, SANE_Fixed val, SANE_Int *status) DECLSPEC_HIDDEN;
TW_UINT16 sane_status_to_twcc(SANE_Status rc) DECLSPEC_HIDDEN;
TW_UINT16 sane_option_get_value( int optno, void *val ) DECLSPEC_HIDDEN;
TW_UINT16 sane_option_set_value( int optno, void *val, BOOL *reload ) DECLSPEC_HIDDEN;
TW_UINT16 sane_option_get_int( const char *option_name, int *val ) DECLSPEC_HIDDEN;
TW_UINT16 sane_option_set_int( const char *option_name, int val, BOOL *reload ) DECLSPEC_HIDDEN;
TW_UINT16 sane_option_get_str( const char *option_name, char *val, int len ) DECLSPEC_HIDDEN;
TW_UINT16 sane_option_set_str( const char *option_name, char *val, BOOL *reload ) DECLSPEC_HIDDEN;
TW_UINT16 sane_option_probe_resolution( const char *option_name, int *minval, int *maxval, int *quant) DECLSPEC_HIDDEN;
TW_UINT16 sane_option_probe_mode(const char * const **choices, char *current, int current_size) DECLSPEC_HIDDEN;
TW_UINT16 sane_option_probe_scan_area(const char *option_name, SANE_Fixed *val,
SANE_Unit *unit, SANE_Fixed *min, SANE_Fixed *max, SANE_Fixed *quant) DECLSPEC_HIDDEN;
TW_UINT16 sane_option_get_bool( const char *option_name, BOOL *val ) DECLSPEC_HIDDEN;
TW_UINT16 sane_option_set_bool( const char *option_name, BOOL val ) DECLSPEC_HIDDEN;
TW_UINT16 sane_option_set_fixed( const char *option_name, int val, BOOL *reload ) DECLSPEC_HIDDEN;
BOOL convert_sane_res_to_twain(double sane_res, SANE_Unit unit, TW_FIX32 *twain_res, TW_UINT16 twtype) DECLSPEC_HIDDEN;
#endif

View File

@ -169,11 +169,9 @@ static int create_item(HDC hdc, const SANE_Option_Descriptor *opt,
}
else if (opt->type == SANE_TYPE_INT)
{
SANE_Int i;
sane_control_option(activeDS.deviceHandle, id-ID_BASE,
SANE_ACTION_GET_VALUE, &i,NULL);
int i;
sane_option_get_value( id - ID_BASE, &i );
sprintf(buffer,"%i",i);
if (opt->constraint_type == SANE_CONSTRAINT_NONE)
@ -207,8 +205,7 @@ static int create_item(HDC hdc, const SANE_Option_Descriptor *opt,
i = HeapAlloc(GetProcessHeap(),0,opt->size*sizeof(SANE_Word));
sane_control_option(activeDS.deviceHandle, id-ID_BASE,
SANE_ACTION_GET_VALUE, i, NULL);
sane_option_get_value( id - ID_BASE, i );
dd = SANE_UNFIX(*i);
sprintf(buffer,"%f",dd);
@ -251,8 +248,7 @@ static int create_item(HDC hdc, const SANE_Option_Descriptor *opt,
}
leading_len += create_leading_static(hdc, opt->title, &lead_static, y,
id+ID_STATIC_BASE);
sane_control_option(activeDS.deviceHandle, id-ID_BASE,
SANE_ACTION_GET_VALUE, buffer,NULL);
sane_option_get_value( id - ID_BASE, buffer );
title = buffer;
local_len += MultiByteToWideChar(CP_ACP,0,title,-1,NULL,0);
@ -366,7 +362,7 @@ static int create_item(HDC hdc, const SANE_Option_Descriptor *opt,
static LPDLGTEMPLATEW create_options_page(HDC hdc, int *from_index,
SANE_Int optcount, BOOL split_tabs)
int optcount, BOOL split_tabs)
{
int i;
INT y = 2;
@ -518,8 +514,8 @@ BOOL DoScannerUI(void)
int page_count= 0;
PROPSHEETHEADERW psh;
int index = 1;
SANE_Status rc;
SANE_Int optcount;
TW_UINT16 rc;
int optcount;
UINT psrc;
LPWSTR szCaption;
DWORD len;
@ -527,9 +523,8 @@ BOOL DoScannerUI(void)
hdc = GetDC(0);
memset(psp,0,sizeof(psp));
rc = sane_control_option(activeDS.deviceHandle, 0, SANE_ACTION_GET_VALUE,
&optcount, NULL);
if (rc != SANE_STATUS_GOOD)
rc = sane_option_get_value( 0, &optcount );
if (rc != TWCC_SUCCESS)
{
ERR("Unable to read number of options\n");
return FALSE;
@ -647,21 +642,18 @@ static void UpdateRelevantEdit(HWND hwnd, const SANE_Option_Descriptor *opt,
static BOOL UpdateSaneScrollOption(
const SANE_Option_Descriptor *opt, int index, DWORD position)
{
SANE_Status rc = SANE_STATUS_GOOD;
SANE_Int result = 0;
BOOL result = FALSE;
if (opt->type == SANE_TYPE_INT)
{
SANE_Int si;
int si;
if (opt->constraint.range->quant)
si = position * opt->constraint.range->quant;
else
si = position;
rc = sane_control_option (activeDS.deviceHandle,index,
SANE_ACTION_SET_VALUE, &si, &result);
sane_option_set_value( index, &si, &result );
}
else if (opt->type == SANE_TYPE_FIXED)
{
@ -679,85 +671,23 @@ static BOOL UpdateSaneScrollOption(
*sf = SANE_FIX(dd);
rc = sane_control_option (activeDS.deviceHandle,index,
SANE_ACTION_SET_VALUE, sf, &result);
sane_option_set_value( index, sf, &result );
HeapFree(GetProcessHeap(),0,sf);
}
if(rc == SANE_STATUS_GOOD)
{
if (result & SANE_INFO_RELOAD_OPTIONS ||
result & SANE_INFO_RELOAD_PARAMS || result & SANE_INFO_INEXACT)
return TRUE;
}
return FALSE;
}
static BOOL UpdateSaneBoolOption(int index, BOOL position)
{
SANE_Status rc = SANE_STATUS_GOOD;
SANE_Int result = 0;
SANE_Bool si;
si = position;
rc = sane_control_option (activeDS.deviceHandle,index,
SANE_ACTION_SET_VALUE, &si, &result);
if(rc == SANE_STATUS_GOOD)
{
if (result & SANE_INFO_RELOAD_OPTIONS ||
result & SANE_INFO_RELOAD_PARAMS || result & SANE_INFO_INEXACT)
return TRUE;
}
return FALSE;
}
static BOOL UpdateSaneIntOption(int index, SANE_Int value)
{
SANE_Status rc = SANE_STATUS_GOOD;
SANE_Int result = 0;
rc = sane_control_option (activeDS.deviceHandle,index,
SANE_ACTION_SET_VALUE, &value, &result);
if(rc == SANE_STATUS_GOOD)
{
if (result & SANE_INFO_RELOAD_OPTIONS ||
result & SANE_INFO_RELOAD_PARAMS || result & SANE_INFO_INEXACT)
return TRUE;
}
return FALSE;
}
static BOOL UpdateSaneStringOption(int index, SANE_String value)
{
SANE_Status rc = SANE_STATUS_GOOD;
SANE_Int result = 0;
rc = sane_control_option (activeDS.deviceHandle,index,
SANE_ACTION_SET_VALUE, value, &result);
if(rc == SANE_STATUS_GOOD)
{
if (result & SANE_INFO_RELOAD_OPTIONS ||
result & SANE_INFO_RELOAD_PARAMS || result & SANE_INFO_INEXACT)
return TRUE;
}
return FALSE;
return result;
}
static INT_PTR InitializeDialog(HWND hwnd)
{
SANE_Status rc;
SANE_Int optcount;
TW_UINT16 rc;
int optcount;
HWND control;
int i;
rc = sane_control_option(activeDS.deviceHandle, 0, SANE_ACTION_GET_VALUE,
&optcount, NULL);
if (rc != SANE_STATUS_GOOD)
rc = sane_option_get_value( 0, &optcount );
if (rc != TWCC_SUCCESS)
{
ERR("Unable to read number of options\n");
return FALSE;
@ -794,14 +724,13 @@ static INT_PTR InitializeDialog(HWND hwnd)
(LPARAM)opt->constraint.string_list[j]);
j++;
}
sane_control_option(activeDS.deviceHandle, i, SANE_ACTION_GET_VALUE, buffer,NULL);
sane_option_get_value( i, buffer );
SendMessageA(control,CB_SELECTSTRING,0,(LPARAM)buffer);
}
else if (opt->type == SANE_TYPE_BOOL)
{
SANE_Bool b;
sane_control_option(activeDS.deviceHandle, i,
SANE_ACTION_GET_VALUE, &b, NULL);
BOOL b;
sane_option_get_value( i, &b );
if (b)
SendMessageA(control,BM_SETCHECK,BST_CHECKED,0);
@ -811,13 +740,13 @@ static INT_PTR InitializeDialog(HWND hwnd)
{
int j, count = opt->constraint.word_list[0];
CHAR buffer[16];
SANE_Int val;
int val;
for (j=1; j<=count; j++)
{
sprintf(buffer, "%d", opt->constraint.word_list[j]);
SendMessageA(control, CB_ADDSTRING, 0, (LPARAM)buffer);
}
sane_control_option(activeDS.deviceHandle, i, SANE_ACTION_GET_VALUE, &val, NULL);
sane_option_get_value( i, &val );
sprintf(buffer, "%d", val);
SendMessageA(control,CB_SELECTSTRING,0,(LPARAM)buffer);
}
@ -825,7 +754,7 @@ static INT_PTR InitializeDialog(HWND hwnd)
{
if (opt->type == SANE_TYPE_INT)
{
SANE_Int si;
int si;
int min,max;
min = (SANE_Int)opt->constraint.range->min /
@ -838,8 +767,7 @@ static INT_PTR InitializeDialog(HWND hwnd)
SendMessageA(control,SBM_SETRANGE,min,max);
sane_control_option(activeDS.deviceHandle, i,
SANE_ACTION_GET_VALUE, &si,NULL);
sane_option_get_value( i, &si );
if (opt->constraint.range->quant)
si = si / opt->constraint.range->quant;
@ -874,8 +802,7 @@ static INT_PTR InitializeDialog(HWND hwnd)
sf = HeapAlloc(GetProcessHeap(),0,opt->size*sizeof(SANE_Word));
sane_control_option(activeDS.deviceHandle, i,
SANE_ACTION_GET_VALUE, sf,NULL);
sane_option_get_value( i, sf );
dd = SANE_UNFIX(*sf);
HeapFree(GetProcessHeap(),0,sf);
@ -960,6 +887,7 @@ static void ButtonClicked(HWND hwnd, INT id, HWND control)
{
int index;
const SANE_Option_Descriptor *opt;
BOOL changed = FALSE;
index = id - ID_BASE;
if (index < 0)
@ -973,8 +901,8 @@ static void ButtonClicked(HWND hwnd, INT id, HWND control)
if (opt->type == SANE_TYPE_BOOL)
{
BOOL r = SendMessageW(control,BM_GETCHECK,0,0)==BST_CHECKED;
if (UpdateSaneBoolOption(index, r))
InitializeDialog(hwnd);
sane_option_set_value( index, &r, &changed );
if (changed) InitializeDialog(hwnd);
}
}
@ -985,6 +913,7 @@ static void ComboChanged(HWND hwnd, INT id, HWND control)
int len;
const SANE_Option_Descriptor *opt;
SANE_String value;
BOOL changed = FALSE;
index = id - ID_BASE;
if (index < 0)
@ -1004,14 +933,14 @@ static void ComboChanged(HWND hwnd, INT id, HWND control)
if (opt->type == SANE_TYPE_STRING)
{
if (UpdateSaneStringOption(index, value))
InitializeDialog(hwnd);
sane_option_set_value( index, value, &changed );
}
else if (opt->type == SANE_TYPE_INT)
{
if (UpdateSaneIntOption(index, atoi(value)))
InitializeDialog(hwnd);
int val = atoi( value );
sane_option_set_value( index, &val, &changed );
}
if (changed) InitializeDialog(hwnd);
}