From 9cf95e76ef7a89f4d93506ad561f3a9629b4b62b Mon Sep 17 00:00:00 2001 From: Ilia Docin Date: Fri, 21 Jun 2024 21:23:45 +0300 Subject: [PATCH] sane.ds: Improve color mode and paper source detection. --- dlls/sane.ds/capability.c | 156 ++++++++++++++++++++++++-------------- dlls/sane.ds/options.c | 39 ++++++---- dlls/sane.ds/sane_i.h | 2 +- 3 files changed, 127 insertions(+), 70 deletions(-) diff --git a/dlls/sane.ds/capability.c b/dlls/sane.ds/capability.c index 555575c45a4..bbe518c8513 100644 --- a/dlls/sane.ds/capability.c +++ b/dlls/sane.ds/capability.c @@ -277,47 +277,32 @@ static TW_UINT16 SANE_CAPXferCount (pTW_CAPABILITY pCapability, TW_UINT16 action return twCC; } -static TW_UINT16 set_color_mode(TW_UINT32 pixeltype) +static TW_UINT16 set_option_value(const char* option_name, char* option_value) { - TW_UINT16 twCC = TWCC_BADCAP; + TW_UINT16 twCC = TWCC_BADVALUE; BOOL reload = FALSE; - int i; - const char * const * modes; - /* most of the values are taken from https://gitlab.gnome.org/GNOME/simple-scan/-/blob/master/src/scanner.vala */ - static const char * const gray[] = {"Gray", "Grayscale", "True Gray", "8-bit Grayscale", "Grayscale - 256 Levels", "gray", - 0}; - static const char * const rgb[] = {"Color", "24bit Color[Fast]", "24bit Color", - "24 bit Color", "Color - 16 Million Colors", 0}; - static const char * const bw[] = {"Lineart", "LineArt", "Black & White", "Binary", "Thresholded", "1-bit Black & White", - "Black and White - Line Art", "Black and White - Halftone", "Monochrome", 0}; - switch (pixeltype) + if (*option_value) { - case TWPT_GRAY: - modes = gray; - break; - case TWPT_RGB: - modes = rgb; - break; - case TWPT_BW: - modes = bw; - break; - default: - ERR("Unsupported pixeltype %lu\n", pixeltype); - return TWCC_BADVALUE; - break; - } - TRACE("Setting pixeltype to %lu\n", pixeltype); - for(i=0; modes[i]; ++i) - { - twCC = sane_option_set_str("mode", (char*)modes[i], &reload); + twCC = sane_option_set_str(option_name, option_value, &reload); if (twCC == TWCC_SUCCESS) { if (reload) get_sane_params(&activeDS.frame_params); - break; } } return twCC; } +static TW_UINT16 find_value_pos(const char* value, const char* values, TW_UINT16 buf_len, TW_UINT16 buf_count) +{ + TW_UINT16 index; + for (index=0; index 0; switch (action) { @@ -958,16 +999,16 @@ static TW_UINT16 SANE_CAPFeederEnabled (pTW_CAPABILITY pCapability, TW_UINT16 ac case MSG_SET: twCC = msg_set(pCapability, &val); - if (twCC == TWCC_SUCCESS) + if ((twCC == TWCC_SUCCESS) && (val < buf_count)) { - strcpy(source, "ADF"); - twCC = sane_option_set_str("source", source, NULL); + output = paper_sources + val * buf_len; + TRACE("Setting paper source to %lu: %s\n", val, output); + twCC = set_option_value("source", output); if (twCC != TWCC_SUCCESS) - { - strcpy(source, "Auto"); - twCC = sane_option_set_str("source", source, NULL); - } + ERR("Unable to set paper source to %lu: %s\n", val, output); } + else + twCC = TWCC_BADVALUE; break; case MSG_GETDEFAULT: @@ -975,9 +1016,14 @@ static TW_UINT16 SANE_CAPFeederEnabled (pTW_CAPABILITY pCapability, TW_UINT16 ac break; case MSG_RESET: - strcpy(source, "Auto"); - if (sane_option_set_str("source", source, NULL) == TWCC_SUCCESS) - enabled = TRUE; + val = *(paper_sources + buf_len) ? 1 : 0; // set to Auto/ADF if it's supported + output = paper_sources + val * buf_len; + TRACE("Resetting paper source to %lu: %s\n", val, output); + twCC = set_option_value("source", output); + if (twCC != TWCC_SUCCESS) + ERR("Unable to reset paper source to %lu: %s\n", val, output); + else + enabled = val > 0; /* .. fall through intentional .. */ case MSG_GETCURRENT: diff --git a/dlls/sane.ds/options.c b/dlls/sane.ds/options.c index eb6a308b844..a4c4507360f 100644 --- a/dlls/sane.ds/options.c +++ b/dlls/sane.ds/options.c @@ -115,30 +115,41 @@ TW_UINT16 sane_option_probe_resolution(const char *option_name, struct option_de return sane_find_option(option_name, TYPE_INT, opt); } -TW_UINT16 sane_option_probe_mode(TW_UINT16 *current, TW_UINT32 *choices, int *count) +static TW_UINT32 sane_categorize_value(const WCHAR* value, const WCHAR* const* filter[], char* categories, int buf_len) +{ + TW_UINT32 i, j; + for(i=0; filter[i]; ++i) + { + if (!*categories) + { + for(j=0; filter[i][j]; ++j) + { + if (!wcscmp(value, filter[i][j])) + { + wcstombs(categories, value, buf_len); + return i; + } + } + } + categories += buf_len; + } + return 0; +} + +TW_UINT16 sane_option_probe_str(const char* option_name, const WCHAR* const* filter[], char* opt_values, int buf_len) { WCHAR *p; - char buffer[256]; struct option_descriptor opt; - TW_UINT16 rc = sane_find_option("mode", TYPE_STRING, &opt); + TW_UINT16 rc = sane_find_option(option_name, TYPE_STRING, &opt); if (rc != TWCC_SUCCESS) return rc; - if (opt.size > sizeof(buffer)) return TWCC_BADVALUE; - rc = sane_option_get_value( opt.optno, buffer ); - if (rc != TWCC_SUCCESS) return rc; + if (opt.size > buf_len) return TWCC_BADVALUE; - if (!strcmp( buffer, "Lineart" )) *current = TWPT_BW; - else if (!strcmp( buffer, "Color" )) *current = TWPT_RGB; - else if (!strncmp( buffer, "Gray", 4 )) *current = TWPT_GRAY; - - *count = 0; if (opt.constraint_type == CONSTRAINT_STRING_LIST) { for (p = opt.constraint.strings; *p; p += lstrlenW(p) + 1) { - if (!wcscmp( p, L"Lineart" )) choices[(*count)++] = TWPT_BW; - else if (!wcscmp( p, L"Color" )) choices[(*count)++] = TWPT_RGB; - else if (!wcsncmp( p, L"Gray", 4 )) choices[(*count)++] = TWPT_GRAY; + sane_categorize_value(p, filter, opt_values, buf_len); } } return rc; diff --git a/dlls/sane.ds/sane_i.h b/dlls/sane.ds/sane_i.h index 47c5d69c82e..e35ed77c935 100644 --- a/dlls/sane.ds/sane_i.h +++ b/dlls/sane.ds/sane_i.h @@ -201,7 +201,7 @@ TW_UINT16 sane_option_set_int( const char *option_name, int val, BOOL *reload ); TW_UINT16 sane_option_get_str( const char *option_name, char *val, int len ); TW_UINT16 sane_option_set_str( const char *option_name, char *val, BOOL *reload ); TW_UINT16 sane_option_probe_resolution( const char *option_name, struct option_descriptor *opt ); -TW_UINT16 sane_option_probe_mode(TW_UINT16 *current, TW_UINT32 *choices, int *count); +TW_UINT16 sane_option_probe_str( const char* option_name, const WCHAR* const* filter[], char* opt_vals, int buf_len ); TW_UINT16 sane_option_get_bool( const char *option_name, BOOL *val ); TW_UINT16 sane_option_set_bool( const char *option_name, BOOL val ); TW_UINT16 sane_option_get_scan_area( int *tlx, int *tly, int *brx, int *bry );