setupapi/tests: Add tests to show that SetupIterateCabinet handles callback exception...
[wine] / dlls / sane.ds / options.c
1 /*
2  * Copyright 2009 Jeremy White <jwhite@codeweavers.com> for CodeWeavers
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2.1 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with this library; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
17  */
18
19 #include "config.h"
20
21 #include <stdlib.h>
22 #include "twain.h"
23 #include "sane_i.h"
24 #include "wine/debug.h"
25
26 #ifdef SONAME_LIBSANE
27 static SANE_Status sane_find_option(SANE_Handle h, const char *option_name,
28         const SANE_Option_Descriptor **opt_p, int *optno, SANE_Value_Type type)
29 {
30     SANE_Status rc;
31     SANE_Int optcount;
32     const SANE_Option_Descriptor *opt;
33     int i;
34
35     /* Debian, in 32_net_backend_standard_fix.dpatch,
36      *  forces a frontend (that's us) to reload options
37      *  manually by invoking get_option_descriptor. */
38     opt = psane_get_option_descriptor(h, 0);
39     if (! opt)
40         return SANE_STATUS_EOF;
41
42     rc = psane_control_option(h, 0, SANE_ACTION_GET_VALUE, &optcount, NULL);
43     if (rc != SANE_STATUS_GOOD)
44         return rc;
45
46     for (i = 1; i < optcount; i++)
47     {
48         opt = psane_get_option_descriptor(h, i);
49         if (opt && (opt->name && strcmp(opt->name, option_name) == 0) &&
50                opt->type == type)
51         {
52             *opt_p = opt;
53             *optno = i;
54             return SANE_STATUS_GOOD;
55         }
56     }
57     return SANE_STATUS_EOF;
58 }
59
60 SANE_Status sane_option_get_int(SANE_Handle h, const char *option_name, SANE_Int *val)
61 {
62     SANE_Status rc;
63     int optno;
64     const SANE_Option_Descriptor *opt;
65
66     rc = sane_find_option(h, option_name, &opt, &optno, SANE_TYPE_INT);
67     if (rc != SANE_STATUS_GOOD)
68         return rc;
69
70     return psane_control_option(h, optno, SANE_ACTION_GET_VALUE, val, NULL);
71 }
72
73 SANE_Status sane_option_set_int(SANE_Handle h, const char *option_name, SANE_Int val, SANE_Int *status)
74 {
75     SANE_Status rc;
76     int optno;
77     const SANE_Option_Descriptor *opt;
78
79     rc = sane_find_option(h, option_name, &opt, &optno, SANE_TYPE_INT);
80     if (rc != SANE_STATUS_GOOD)
81         return rc;
82
83     return psane_control_option(h, optno, SANE_ACTION_SET_VALUE, (void *) &val, status);
84 }
85
86 SANE_Status sane_option_get_bool(SANE_Handle h, const char *option_name, SANE_Bool *val, SANE_Int *status)
87 {
88     SANE_Status rc;
89     int optno;
90     const SANE_Option_Descriptor *opt;
91
92     rc = sane_find_option(h, option_name, &opt, &optno, SANE_TYPE_BOOL);
93     if (rc != SANE_STATUS_GOOD)
94         return rc;
95
96     return psane_control_option(h, optno, SANE_ACTION_GET_VALUE, (void *) val, status);
97 }
98
99 SANE_Status sane_option_set_bool(SANE_Handle h, const char *option_name, SANE_Bool val, SANE_Int *status)
100 {
101     SANE_Status rc;
102     int optno;
103     const SANE_Option_Descriptor *opt;
104
105     rc = sane_find_option(h, option_name, &opt, &optno, SANE_TYPE_BOOL);
106     if (rc != SANE_STATUS_GOOD)
107         return rc;
108
109     return psane_control_option(h, optno, SANE_ACTION_SET_VALUE, (void *) &val, status);
110 }
111
112 SANE_Status sane_option_set_fixed(SANE_Handle h, const char *option_name, SANE_Fixed val, SANE_Int *status)
113 {
114     SANE_Status rc;
115     int optno;
116     const SANE_Option_Descriptor *opt;
117
118     rc = sane_find_option(h, option_name, &opt, &optno, SANE_TYPE_FIXED);
119     if (rc != SANE_STATUS_GOOD)
120         return rc;
121
122     return psane_control_option(h, optno, SANE_ACTION_SET_VALUE, (void *) &val, status);
123 }
124
125 SANE_Status sane_option_get_str(SANE_Handle h, const char *option_name, SANE_String val, size_t len, SANE_Int *status)
126 {
127     SANE_Status rc;
128     int optno;
129     const SANE_Option_Descriptor *opt;
130
131     rc = sane_find_option(h, option_name, &opt, &optno, SANE_TYPE_STRING);
132     if (rc != SANE_STATUS_GOOD)
133         return rc;
134
135     if (opt->size < len)
136         return psane_control_option(h, optno, SANE_ACTION_GET_VALUE, (void *) val, status);
137     else
138         return SANE_STATUS_NO_MEM;
139 }
140
141 /* Important:  SANE has the side effect of overwriting val with the returned value */
142 SANE_Status sane_option_set_str(SANE_Handle h, const char *option_name, SANE_String val, SANE_Int *status)
143 {
144     SANE_Status rc;
145     int optno;
146     const SANE_Option_Descriptor *opt;
147
148     rc = sane_find_option(h, option_name, &opt, &optno, SANE_TYPE_STRING);
149     if (rc != SANE_STATUS_GOOD)
150         return rc;
151
152     return psane_control_option(h, optno, SANE_ACTION_SET_VALUE, (void *) val, status);
153 }
154
155 SANE_Status sane_option_probe_resolution(SANE_Handle h, const char *option_name, SANE_Int *minval, SANE_Int *maxval, SANE_Int *quant)
156 {
157     SANE_Status rc;
158     int optno;
159     const SANE_Option_Descriptor *opt;
160
161     rc = sane_find_option(h, option_name, &opt, &optno, SANE_TYPE_INT);
162     if (rc != SANE_STATUS_GOOD)
163         return rc;
164
165     if (opt->constraint_type != SANE_CONSTRAINT_RANGE)
166         return SANE_STATUS_UNSUPPORTED;
167
168     *minval = opt->constraint.range->min;
169     *maxval = opt->constraint.range->max;
170     *quant = opt->constraint.range->quant;
171
172     return rc;
173 }
174
175 SANE_Status sane_option_probe_mode(SANE_Handle h, SANE_String_Const **choices, char *current, int current_size)
176 {
177     SANE_Status rc;
178     int optno;
179     const SANE_Option_Descriptor *opt;
180     rc = sane_find_option(h, "mode", &opt, &optno, SANE_TYPE_STRING);
181     if (rc != SANE_STATUS_GOOD)
182         return rc;
183
184     if (choices && opt->constraint_type == SANE_CONSTRAINT_STRING_LIST)
185         *choices = (SANE_String_Const *) opt->constraint.string_list;
186
187     if (opt->size < current_size)
188         return psane_control_option(h, optno, SANE_ACTION_GET_VALUE, current, NULL);
189     else
190         return SANE_STATUS_NO_MEM;
191
192 }
193
194 SANE_Status sane_option_probe_scan_area(SANE_Handle h, const char *option_name, SANE_Fixed *val,
195                                         SANE_Unit *unit, SANE_Fixed *min, SANE_Fixed *max, SANE_Fixed *quant)
196 {
197     SANE_Status rc;
198     int optno;
199     const SANE_Option_Descriptor *opt;
200
201     rc = sane_find_option(h, option_name, &opt, &optno, SANE_TYPE_FIXED);
202     if (rc != SANE_STATUS_GOOD)
203         return rc;
204
205     if (unit)
206         *unit = opt->unit;
207     if (min)
208         *min = opt->constraint.range->min;
209     if (max)
210         *max = opt->constraint.range->max;
211     if (quant)
212         *quant = opt->constraint.range->quant;
213
214     if (val)
215         rc = psane_control_option(h, optno, SANE_ACTION_GET_VALUE, val, NULL);
216
217     return rc;
218 }
219
220 TW_UINT16 sane_status_to_twcc(SANE_Status rc)
221 {
222     switch (rc)
223     {
224         case SANE_STATUS_GOOD:
225             return TWCC_SUCCESS;
226         case SANE_STATUS_UNSUPPORTED:
227             return TWCC_CAPUNSUPPORTED;
228         case SANE_STATUS_JAMMED:
229             return TWCC_PAPERJAM;
230         case SANE_STATUS_NO_MEM:
231             return TWCC_LOWMEMORY;
232         case SANE_STATUS_ACCESS_DENIED:
233             return TWCC_DENIED;
234
235         case SANE_STATUS_IO_ERROR:
236         case SANE_STATUS_NO_DOCS:
237         case SANE_STATUS_COVER_OPEN:
238         case SANE_STATUS_EOF:
239         case SANE_STATUS_INVAL:
240         case SANE_STATUS_CANCELLED:
241         case SANE_STATUS_DEVICE_BUSY:
242         default:
243             return TWCC_BUMMER;
244     }
245 }
246 static void convert_double_fix32(double d, TW_FIX32 *fix32)
247 {
248     TW_INT32 value = (TW_INT32) (d * 65536.0 + 0.5);
249     fix32->Whole = value >> 16;
250     fix32->Frac = value & 0x0000ffffL;
251 }
252
253 BOOL convert_sane_res_to_twain(double sane_res, SANE_Unit unit, TW_FIX32 *twain_res, TW_UINT16 twtype)
254 {
255     double d;
256
257     if (unit != SANE_UNIT_MM)
258         return FALSE;
259
260     if (twtype != TWUN_INCHES)
261         return FALSE;
262
263     d = (sane_res / 10.0) / 2.54;
264     convert_double_fix32((sane_res / 10.0) / 2.54, twain_res);
265
266     return TRUE;
267 }
268 #endif