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