Release 1.5.29.
[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 "sane_i.h"
23 #include "wine/debug.h"
24
25 #ifdef SONAME_LIBSANE
26 static SANE_Status sane_find_option(SANE_Handle h, const char *option_name,
27         const SANE_Option_Descriptor **opt_p, int *optno, SANE_Value_Type type)
28 {
29     SANE_Status rc;
30     SANE_Int optcount;
31     const SANE_Option_Descriptor *opt;
32     int i;
33
34     /* Debian, in 32_net_backend_standard_fix.dpatch,
35      *  forces a frontend (that's us) to reload options
36      *  manually by invoking get_option_descriptor. */
37     opt = psane_get_option_descriptor(h, 0);
38     if (! opt)
39         return SANE_STATUS_EOF;
40
41     rc = psane_control_option(h, 0, SANE_ACTION_GET_VALUE, &optcount, NULL);
42     if (rc != SANE_STATUS_GOOD)
43         return rc;
44
45     for (i = 1; i < optcount; i++)
46     {
47         opt = psane_get_option_descriptor(h, i);
48         if (opt && (opt->name && strcmp(opt->name, option_name) == 0) &&
49                opt->type == type)
50         {
51             *opt_p = opt;
52             *optno = i;
53             return SANE_STATUS_GOOD;
54         }
55     }
56     return SANE_STATUS_EOF;
57 }
58
59 SANE_Status sane_option_get_int(SANE_Handle h, const char *option_name, SANE_Int *val)
60 {
61     SANE_Status rc;
62     int optno;
63     const SANE_Option_Descriptor *opt;
64
65     rc = sane_find_option(h, option_name, &opt, &optno, SANE_TYPE_INT);
66     if (rc != SANE_STATUS_GOOD)
67         return rc;
68
69     return psane_control_option(h, optno, SANE_ACTION_GET_VALUE, val, NULL);
70 }
71
72 SANE_Status sane_option_set_int(SANE_Handle h, const char *option_name, SANE_Int val, SANE_Int *status)
73 {
74     SANE_Status rc;
75     int optno;
76     const SANE_Option_Descriptor *opt;
77
78     rc = sane_find_option(h, option_name, &opt, &optno, SANE_TYPE_INT);
79     if (rc != SANE_STATUS_GOOD)
80         return rc;
81
82     return psane_control_option(h, optno, SANE_ACTION_SET_VALUE, (void *) &val, status);
83 }
84
85 SANE_Status sane_option_get_bool(SANE_Handle h, const char *option_name, SANE_Bool *val, SANE_Int *status)
86 {
87     SANE_Status rc;
88     int optno;
89     const SANE_Option_Descriptor *opt;
90
91     rc = sane_find_option(h, option_name, &opt, &optno, SANE_TYPE_BOOL);
92     if (rc != SANE_STATUS_GOOD)
93         return rc;
94
95     return psane_control_option(h, optno, SANE_ACTION_GET_VALUE, (void *) val, status);
96 }
97
98 SANE_Status sane_option_set_bool(SANE_Handle h, const char *option_name, SANE_Bool val, SANE_Int *status)
99 {
100     SANE_Status rc;
101     int optno;
102     const SANE_Option_Descriptor *opt;
103
104     rc = sane_find_option(h, option_name, &opt, &optno, SANE_TYPE_BOOL);
105     if (rc != SANE_STATUS_GOOD)
106         return rc;
107
108     return psane_control_option(h, optno, SANE_ACTION_SET_VALUE, (void *) &val, status);
109 }
110
111 SANE_Status sane_option_set_fixed(SANE_Handle h, const char *option_name, SANE_Fixed val, SANE_Int *status)
112 {
113     SANE_Status rc;
114     int optno;
115     const SANE_Option_Descriptor *opt;
116
117     rc = sane_find_option(h, option_name, &opt, &optno, SANE_TYPE_FIXED);
118     if (rc != SANE_STATUS_GOOD)
119         return rc;
120
121     return psane_control_option(h, optno, SANE_ACTION_SET_VALUE, (void *) &val, status);
122 }
123
124 SANE_Status sane_option_get_str(SANE_Handle h, const char *option_name, SANE_String val, size_t len, SANE_Int *status)
125 {
126     SANE_Status rc;
127     int optno;
128     const SANE_Option_Descriptor *opt;
129
130     rc = sane_find_option(h, option_name, &opt, &optno, SANE_TYPE_STRING);
131     if (rc != SANE_STATUS_GOOD)
132         return rc;
133
134     if (opt->size < len)
135         return psane_control_option(h, optno, SANE_ACTION_GET_VALUE, (void *) val, status);
136     else
137         return SANE_STATUS_NO_MEM;
138 }
139
140 /* Important:  SANE has the side effect of overwriting val with the returned value */
141 SANE_Status sane_option_set_str(SANE_Handle h, const char *option_name, SANE_String val, SANE_Int *status)
142 {
143     SANE_Status rc;
144     int optno;
145     const SANE_Option_Descriptor *opt;
146
147     rc = sane_find_option(h, option_name, &opt, &optno, SANE_TYPE_STRING);
148     if (rc != SANE_STATUS_GOOD)
149         return rc;
150
151     return psane_control_option(h, optno, SANE_ACTION_SET_VALUE, (void *) val, status);
152 }
153
154 SANE_Status sane_option_probe_resolution(SANE_Handle h, const char *option_name, SANE_Int *minval, SANE_Int *maxval, SANE_Int *quant)
155 {
156     SANE_Status rc;
157     int optno;
158     const SANE_Option_Descriptor *opt;
159
160     rc = sane_find_option(h, option_name, &opt, &optno, SANE_TYPE_INT);
161     if (rc != SANE_STATUS_GOOD)
162         return rc;
163
164     if (opt->constraint_type != SANE_CONSTRAINT_RANGE)
165         return SANE_STATUS_UNSUPPORTED;
166
167     *minval = opt->constraint.range->min;
168     *maxval = opt->constraint.range->max;
169     *quant = opt->constraint.range->quant;
170
171     return rc;
172 }
173
174 SANE_Status sane_option_probe_mode(SANE_Handle h, SANE_String_Const **choices, char *current, int current_size)
175 {
176     SANE_Status rc;
177     int optno;
178     const SANE_Option_Descriptor *opt;
179     rc = sane_find_option(h, "mode", &opt, &optno, SANE_TYPE_STRING);
180     if (rc != SANE_STATUS_GOOD)
181         return rc;
182
183     if (choices && opt->constraint_type == SANE_CONSTRAINT_STRING_LIST)
184         *choices = (SANE_String_Const *) opt->constraint.string_list;
185
186     if (opt->size < current_size)
187         return psane_control_option(h, optno, SANE_ACTION_GET_VALUE, current, NULL);
188     else
189         return SANE_STATUS_NO_MEM;
190
191 }
192
193 SANE_Status sane_option_probe_scan_area(SANE_Handle h, const char *option_name, SANE_Fixed *val,
194                                         SANE_Unit *unit, SANE_Fixed *min, SANE_Fixed *max, SANE_Fixed *quant)
195 {
196     SANE_Status rc;
197     int optno;
198     const SANE_Option_Descriptor *opt;
199
200     rc = sane_find_option(h, option_name, &opt, &optno, SANE_TYPE_FIXED);
201     if (rc != SANE_STATUS_GOOD)
202         return rc;
203
204     if (unit)
205         *unit = opt->unit;
206     if (min)
207         *min = opt->constraint.range->min;
208     if (max)
209         *max = opt->constraint.range->max;
210     if (quant)
211         *quant = opt->constraint.range->quant;
212
213     if (val)
214         rc = psane_control_option(h, optno, SANE_ACTION_GET_VALUE, val, NULL);
215
216     return rc;
217 }
218
219 TW_UINT16 sane_status_to_twcc(SANE_Status rc)
220 {
221     switch (rc)
222     {
223         case SANE_STATUS_GOOD:
224             return TWCC_SUCCESS;
225         case SANE_STATUS_UNSUPPORTED:
226             return TWCC_CAPUNSUPPORTED;
227         case SANE_STATUS_JAMMED:
228             return TWCC_PAPERJAM;
229         case SANE_STATUS_NO_MEM:
230             return TWCC_LOWMEMORY;
231         case SANE_STATUS_ACCESS_DENIED:
232             return TWCC_DENIED;
233
234         case SANE_STATUS_IO_ERROR:
235         case SANE_STATUS_NO_DOCS:
236         case SANE_STATUS_COVER_OPEN:
237         case SANE_STATUS_EOF:
238         case SANE_STATUS_INVAL:
239         case SANE_STATUS_CANCELLED:
240         case SANE_STATUS_DEVICE_BUSY:
241         default:
242             return TWCC_BUMMER;
243     }
244 }
245 static void convert_double_fix32(double d, TW_FIX32 *fix32)
246 {
247     TW_INT32 value = (TW_INT32) (d * 65536.0 + 0.5);
248     fix32->Whole = value >> 16;
249     fix32->Frac = value & 0x0000ffffL;
250 }
251
252 BOOL convert_sane_res_to_twain(double sane_res, SANE_Unit unit, TW_FIX32 *twain_res, TW_UINT16 twtype)
253 {
254     if (unit != SANE_UNIT_MM)
255         return FALSE;
256
257     if (twtype != TWUN_INCHES)
258         return FALSE;
259
260     convert_double_fix32((sane_res / 10.0) / 2.54, twain_res);
261
262     return TRUE;
263 }
264 #endif