This is a merge request to solve a problem that became visible by this merge request from Ivan Lyugaev:
https://gitlab.winehq.org/wine/wine/-/merge_requests/9184#note_121010
When used with a HP Officejet Pro 8600 N911a, it is no longer possible to choose a scan resolution other than 75 DPI.
The reason is that the code always set the "source" option after the "resolution" option, and setting the "source" option resets the resolution on that scanner to 75 DPI, even if it is not changed. Sane services are implemented in hplip. On Debian:
``` apt source hplip sed -n '560,563p' hplip-3.22.10+dfsg0/scan/sane/ledm.c i = session->adf_resolutionList[0] + 1; while(i--) session->resolutionList[i] = session->adf_resolutionList[i]; } ps->currentResolution = session->resolutionList[1]; ```
This new commit changes two things:
1. The order in which parameters are set in sane is changed. A parameter called "source" is set earlier than all other parameters. 2. If a parameter derived from a combobox of named options is not changed, it is not set in sane to the same value again.
This seems to solve the problem on the HP Officejet Pro 8600 N911a, but other sane backends might have more dependencies that might still need to be addressed.
-- v5: dlls/sane.ds: Fix setting resolution in user interface
From: Bernd Herd codeberg@herdsoft.com
--- dlls/sane.ds/ui.c | 46 +++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 43 insertions(+), 3 deletions(-)
diff --git a/dlls/sane.ds/ui.c b/dlls/sane.ds/ui.c index 0e32e274d9c..6c36735719b 100644 --- a/dlls/sane.ds/ui.c +++ b/dlls/sane.ds/ui.c @@ -798,6 +798,8 @@ static INT_PTR InitializeDialog(HWND hwnd) int optcount; HWND control; int i; + int o; + int *opt_order=NULL;
rc = sane_option_get_value( 0, &optcount ); if (rc != TWCC_SUCCESS) @@ -808,16 +810,48 @@ static INT_PTR InitializeDialog(HWND hwnd) else gOptCount = optcount;
- for ( i = 1; i < optcount; i++) + /* Determine the order in which options shall be set in sane */ + opt_order = (int *) malloc((optcount+1) * sizeof(int)); + if (!opt_order) + { + ERR("Out of memory allocation opt_order\n"); + return FALSE; + } + + for ( o = 0; o < optcount; o++) + { + opt_order[o] = o; + } + + for ( o = 1; o < optcount; o++) { struct option_descriptor opt; + opt.optno = opt_order[o]; + SANE_CALL( option_get_descriptor, &opt ); + + if (!strcmp(opt.name, "source")) + { + /* Source (adf, flatbed) must be set before resolution + * so process it first */ + memmove(opt_order+2, + opt_order+1, + (o-1) * sizeof(int)); + opt_order[1] = opt.optno; + } + } + + for ( o = 1; o < optcount; o++) + { + struct option_descriptor opt; + + opt.optno = + i = opt_order[o];
control = GetDlgItem(hwnd,i+ID_BASE);
if (!control) continue;
- opt.optno = i; SANE_CALL( option_get_descriptor, &opt );
TRACE("%i %s %i %i\n",i,debugstr_w(opt.title),opt.type,opt.constraint_type); @@ -829,6 +863,9 @@ static INT_PTR InitializeDialog(HWND hwnd) { CHAR buffer[255]; WCHAR *p; + char oldvalue[256]; + + sane_option_get_value(opt.optno, oldvalue);
for (p = opt.constraint.strings; *p; p += lstrlenW(p) + 1) SendMessageW( control,CB_ADDSTRING,0, (LPARAM)p ); @@ -841,7 +878,8 @@ static INT_PTR InitializeDialog(HWND hwnd) WideCharToMultiByte(CP_UTF8, 0, p, -1, param, sizeof(param), NULL, NULL); if (!strcmp(param, buffer)) { - sane_option_set_value(opt.optno, buffer, NULL); + if (strcmp(param, oldvalue)) + sane_option_set_value(opt.optno, buffer, NULL); break; } } @@ -965,6 +1003,8 @@ static INT_PTR InitializeDialog(HWND hwnd) } }
+ free(opt_order); + return TRUE; }
This merge request was approved by Esme Povirk.