From: Bernd Herd codeberg@herdsoft.com
This allows combining the capability negotiation with the application program with the user interface. --- dlls/sane.ds/sane_i.h | 1 + dlls/sane.ds/sane_main.c | 3 + dlls/sane.ds/ui.c | 265 +++++++++++++++++++-------------------- 3 files changed, 135 insertions(+), 134 deletions(-)
diff --git a/dlls/sane.ds/sane_i.h b/dlls/sane.ds/sane_i.h index e35ed77c935..e98d96340f7 100644 --- a/dlls/sane.ds/sane_i.h +++ b/dlls/sane.ds/sane_i.h @@ -59,6 +59,7 @@ extern struct tagActiveDS activeDS; extern TW_UINT16 SANE_SaneCapability (pTW_CAPABILITY pCapability, TW_UINT16 action); extern TW_UINT16 SANE_SaneSetDefaults (void); extern void SANE_Notify (TW_UINT16 message); +extern void SANE_LoadOptions(void);
/* Implementation of operation triplets * From Application to Source (Control Information) */ diff --git a/dlls/sane.ds/sane_main.c b/dlls/sane.ds/sane_main.c index 360509e2bf6..45d936f38d4 100644 --- a/dlls/sane.ds/sane_main.c +++ b/dlls/sane.ds/sane_main.c @@ -80,6 +80,9 @@ static TW_UINT16 SANE_OpenDS( pTW_IDENTITY pOrigin, pTW_IDENTITY self) activeDS.currentState = 4; activeDS.identity.Id = self->Id; activeDS.appIdentity = *pOrigin; + + SANE_LoadOptions(); + return TWRC_SUCCESS; } SANE_CALL( close_ds, NULL ); diff --git a/dlls/sane.ds/ui.c b/dlls/sane.ds/ui.c index 51c7f54eea9..a74aa3914a7 100644 --- a/dlls/sane.ds/ui.c +++ b/dlls/sane.ds/ui.c @@ -539,12 +539,6 @@ BOOL DoScannerUI(void) len = lstrlenA(activeDS.identity.Manufacturer) + lstrlenA(activeDS.identity.ProductName) + 2; szCaption = malloc(len *sizeof(WCHAR)); - - snprintf(reg_path, MAX_PATH, "Software\ScannersSettings\%s\%s_%s", - activeDS.identity.Manufacturer, - activeDS.identity.ProductFamily, - activeDS.identity.ProductName); - MultiByteToWideChar(CP_ACP,0,activeDS.identity.Manufacturer,-1, szCaption,len); szCaption[lstrlenA(activeDS.identity.Manufacturer)] = ' '; @@ -592,37 +586,6 @@ static BOOL save_to_reg( DWORD reg_type, CHAR* name, const BYTE* value, DWORD si return res == ERROR_SUCCESS; }
-static BOOL load_from_reg( int opt_type, CHAR* name, void* value ) -{ - HKEY h_key; - DWORD flag, size; - LSTATUS res; - - if (RegOpenKeyExA( HKEY_CURRENT_USER, reg_path, 0, KEY_ALL_ACCESS, &h_key )) return FALSE; - - switch( opt_type ) - { - case TYPE_INT: - case TYPE_FIXED: - case TYPE_BOOL: - flag = RRF_RT_REG_DWORD; - size = sizeof(DWORD); - break; - case TYPE_STRING: - flag = RRF_RT_REG_SZ; - size = OPTION_VALUE_MAX; - break; - default: - RegCloseKey( h_key ); - ERR( "Unknown type: %d\n", opt_type ); - return FALSE; - } - - res = RegGetValueA( h_key, NULL, name, flag, NULL, value, &size ); - RegCloseKey( h_key ); - return res == ERROR_SUCCESS; -} - static BOOL get_option(struct option_descriptor* opt, ScannerOption* option) { lstrcpynA(option->name, opt->name, OPTION_NAME_MAX); @@ -792,66 +755,41 @@ static BOOL UpdateSaneScrollOption(const struct option_descriptor *opt, DWORD po return result; }
+ +/* @brief Set Dialog control values to SANE values + * + * Set the values of controls in the Scanner GUI property sheet dialog + * to those selected in the SANE parameter space. + * Set Combobox options to the list of possible values. + * + * @param hwnd Property sheet Dialog window. + * + * @return Return value for dialog function WM_INITDIALOG. Always TRUE. + */ static INT_PTR InitializeDialog(HWND hwnd) { TW_UINT16 rc; int optcount; HWND control; int i; - int o; - int *opt_order=NULL;
rc = sane_option_get_value( 0, &optcount ); if (rc != TWCC_SUCCESS) { ERR("Unable to read number of options\n"); - optcount = gOptCount; - } - else - gOptCount = optcount; - - /* Determine the order in which options shall be set in sane */ - opt_order = 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++) + for ( i = 1; i < optcount; i++) { 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); @@ -863,39 +801,19 @@ 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 ); - - if (load_from_reg(opt.type, opt.name, buffer)) - { - for (p = opt.constraint.strings; *p; p += lstrlenW(p) + 1) - { - CHAR param[256]; - WideCharToMultiByte(CP_UTF8, 0, p, -1, param, sizeof(param), NULL, NULL); - if (!strcmp(param, buffer)) - { - if (strcmp(param, oldvalue)) - sane_option_set_value(opt.optno, buffer, NULL); - break; - } - } - if (!*p) ERR("%s=%s is incorrect. The default value is set!", opt.name, buffer); - } - sane_option_get_value( i, buffer ); SendMessageA(control,CB_SELECTSTRING,0,(LPARAM)buffer); } else if (opt.type == TYPE_BOOL) { BOOL b; - - if (load_from_reg(opt.type, opt.name, &b)) sane_option_set_value( i, &b, NULL ); sane_option_get_value( i, &b ); - SendMessageA(control,BM_SETCHECK, b ? BST_CHECKED : BST_UNCHECKED,0); + if (b) + SendMessageA(control,BM_SETCHECK,BST_CHECKED,0); + } else if (opt.type == TYPE_INT && opt.constraint_type == CONSTRAINT_WORD_LIST) { @@ -907,20 +825,6 @@ static INT_PTR InitializeDialog(HWND hwnd) sprintf(buffer, "%d", opt.constraint.word_list[j]); SendMessageA(control, CB_ADDSTRING, 0, (LPARAM)buffer); } - - if (load_from_reg(opt.type, opt.name, &val)) - { - for (j=1; j<=count; j++) - { - if (opt.constraint.word_list[j] == val) - { - sane_option_set_value( i, &val, NULL ); - break; - } - } - if (j > count) ERR("%s=%d is incorrect. The default value is set!\n", opt.name, val); - } - sane_option_get_value( i, &val ); sprintf(buffer, "%d", val); SendMessageA(control,CB_SELECTSTRING,0,(LPARAM)buffer); @@ -940,12 +844,6 @@ static INT_PTR InitializeDialog(HWND hwnd)
SendMessageA(control,SBM_SETRANGE,min,max);
- if (load_from_reg(opt.type, opt.name, &si)) - { - if (si >= min && si <= max) sane_option_set_value( i, &si, NULL); - else ERR("%s=%d is out of range [%d..%d]. The default value is used!\n", opt.name, si, min, max); - } - sane_option_get_value( i, &si ); if (opt.constraint.range.quant) si = si / opt.constraint.range.quant; @@ -955,7 +853,7 @@ static INT_PTR InitializeDialog(HWND hwnd) } else if (opt.type == TYPE_FIXED) { - int pos, min, max, *sf, val; + int pos, min, max, *sf;
if (opt.constraint.range.quant) { @@ -970,19 +868,6 @@ static INT_PTR InitializeDialog(HWND hwnd)
SendMessageA(control,SBM_SETRANGE,min,max);
- if (load_from_reg(opt.type, opt.name, &val)) - { - if (val >= min && val <= max) - { - int valSet; - if (opt.constraint.range.quant) - valSet = val * opt.constraint.range.quant; - else - valSet = MulDiv(val, 65536, 100); - sane_option_set_value(i, &valSet, NULL); - } - else ERR("%s = %d is out of range [%d..%d]. The default value is used!\n", opt.name, val, min, max); - }
sf = calloc( opt.size, sizeof(int) ); sane_option_get_value( i, sf ); @@ -1003,8 +888,6 @@ static INT_PTR InitializeDialog(HWND hwnd) } }
- free(opt_order); - return TRUE; }
@@ -1201,3 +1084,117 @@ HWND ScanningDialogBox(HWND dialog, LONG progress)
return dialog; } + + +/** @brief Load all current settings from registry to sane + * + * Called when opening a data source. + * Loads all SANE options from the registry and sets them + * in the SANE parameter space for later negotiation + * with the CAP_xxx machanism and display in the UI. + */ +void +SANE_LoadOptions(void) +{ + TW_UINT16 rc; + int optcount; + int o; + int *opt_order=NULL; + + HKEY h_key; + DWORD size; + + int ivalue; + char svalue[OPTION_VALUE_MAX+1]; + + snprintf(reg_path, MAX_PATH, "Software\ScannersSettings\%s\%s_%s", + activeDS.identity.Manufacturer, + activeDS.identity.ProductFamily, + activeDS.identity.ProductName); + + rc = sane_option_get_value( 0, &optcount ); + if (rc != TWCC_SUCCESS) + { + ERR("SANE_LoadOptions: Unable to read number of options\n"); + return; + } + gOptCount = optcount; + + if (RegOpenKeyExA( HKEY_CURRENT_USER, reg_path, 0, KEY_ALL_ACCESS, &h_key)==ERROR_SUCCESS) + { + /* Determine the order in which options shall be set in sane */ + opt_order = malloc((optcount+1) * sizeof(int)); + if (!opt_order) + { + ERR("Out of memory allocation opt_order\n"); + return; + } + + 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 = opt_order[o]; + + SANE_CALL( option_get_descriptor, &opt ); + + TRACE("%i %s %i %i\n",opt.optno,debugstr_w(opt.title),opt.type,opt.constraint_type); + + switch( opt.type ) + { + case TYPE_INT: + case TYPE_BOOL: + size = sizeof(ivalue); + if (RegGetValueA( h_key, NULL, opt.name, RRF_RT_REG_DWORD, NULL, &ivalue, &size)==ERROR_SUCCESS) + { + sane_option_set_value( opt.optno, &ivalue, NULL ); + } + break; + case TYPE_FIXED: + size = sizeof(ivalue); + if (RegGetValueA( h_key, NULL, opt.name, RRF_RT_REG_DWORD, NULL, &ivalue, &size)==ERROR_SUCCESS) + { + int valSet; + if (opt.constraint.range.quant) + valSet = ivalue * opt.constraint.range.quant; + else + valSet = MulDiv(ivalue, 65536, 100); + sane_option_set_value( opt.optno, &valSet, NULL); + } + break; + case TYPE_STRING: + size = OPTION_VALUE_MAX; + if (RegGetValueA( h_key, NULL, opt.name, RRF_RT_REG_SZ, NULL, svalue, &size)==ERROR_SUCCESS) + { + sane_option_set_value( opt.optno, svalue, NULL ); + } + break; + default: ; + } + } + free(opt_order); + + RegCloseKey( h_key ); + } +}