1
2
3 /*max@home*/
4 #ifdef __cplusplus
5 extern "C" {
6 #endif
7
8 #ifdef NOTE
9 ConvertOneValue2Enum() potrebbe essere fonte di errore se
10 DCItemSize[one_value.ItemType] >
11 DCItemSize[TW_INT8] e si utilizzano i bit piu significativi di one_value
12 .Item
13 ConvertEnumeration2Range() potrebbe restituire valori di StepSize non
14 appropriati se enumeration.ItemType e TW_FIX32 potrebbe
15 restituire valori MinValue non corretti se DCItemSize[xxx.ItemType] >
16 DCItemSize[TW_INT8] e si utilizzano i bit piu significativi di xxx.Item
17 ConvertEnum2OneValue ritorna(ovviamente) solo il valore corrente
18 #endif
19
20 #include <assert.h>
21 #include <string.h>
22
23 #include "ttwain_capability.h"
24 #include "ttwain_conversion.h"
25 #include "ttwain_error.h"
26 #include "ttwain_state.h"
27
28 #include "ttwain_global_def.h"
29
30 /*---------------------------------------------------------------------------*/
31 static const size_t DCItemSize[13] = {
32 sizeof(TW_INT8), sizeof(TW_INT16), sizeof(TW_INT32), sizeof(TW_UINT8),
33 sizeof(TW_UINT16), sizeof(TW_UINT32), sizeof(TW_BOOL), sizeof(TW_FIX32),
34 sizeof(TW_FRAME), sizeof(TW_STR32), sizeof(TW_STR64), sizeof(TW_STR128),
35 sizeof(TW_STR255),
36 }; /* see twain.h */
37
38 /*---------------------------------------------------------------------------*/
39 #define TWON_TWON(TYPE1, TYPE2) (((TYPE1) << 8) | (TYPE2))
40 /*---------------------------------------------------------------------------*/
41 static int ConvertOneValue2Range(TW_ONEVALUE one_value, TW_RANGE *range);
42 static int ConvertEnumeration2Range(TW_ENUMERATION enumeration,
43 TW_RANGE *range);
44 static int ConvertOneValue2Enum(TW_ONEVALUE one_value, TW_ENUMERATION *tw_enum);
45 static int ConvertEnum2OneValue(TW_ENUMERATION tw_enum, TW_ONEVALUE *one_value);
46 static int ConvertEnum2Array(TW_ENUMERATION tw_enum, TW_ARRAY *array);
47
48 static TUINT32 GetContainerSize(int nFormat, unsigned twty, TW_UINT32 nItems);
49 static int TTWAIN_GetCapability(TW_INT16 msgType, TW_UINT16 cap_id,
50 TW_UINT16 conType, void *data,
51 TUINT32 *cont_size);
52 /*------------------------------------------------------------------------*/
TTWAIN_GetCap(TW_UINT16 cap_id,TW_UINT16 conType,void * data,TUINT32 * cont_size)53 int TTWAIN_GetCap(TW_UINT16 cap_id, TW_UINT16 conType, void *data,
54 TUINT32 *cont_size) {
55 return TTWAIN_GetCapability(MSG_GET, cap_id, conType, data, cont_size);
56 }
57 /*------------------------------------------------------------------------*/
TTWAIN_GetCapCurrent(TW_UINT16 cap_id,TW_UINT16 conType,void * data,TUINT32 * cont_size)58 int TTWAIN_GetCapCurrent(TW_UINT16 cap_id, TW_UINT16 conType, void *data,
59 TUINT32 *cont_size) {
60 return TTWAIN_GetCapability(MSG_GETCURRENT, cap_id, conType, data, cont_size);
61 }
62 /*------------------------------------------------------------------------*/
TTWAIN_GetCapQuery(TW_UINT16 cap_id,TW_UINT16 * pattern)63 int TTWAIN_GetCapQuery(TW_UINT16 cap_id, TW_UINT16 *pattern) {
64 int rc;
65 /* GCC9 during compilation shows that this code possible call
66 * TTWAIN_GetCapability() with case TWON_TWON(TWON_RANGE, TWON_RANGE)
67 * whitch cause stack corruption, so make 'data' big enough to store
68 * TW_ONEVALUE. */
69 TW_ONEVALUE data[1 + (sizeof(TW_RANGE) / sizeof(TW_ONEVALUE))];
70 rc = TTWAIN_GetCapability(MSG_QUERYSUPPORT, cap_id, TWON_ONEVALUE, &data, 0);
71 if (!rc) return FALSE;
72 *pattern = (TW_UINT16)data[0].Item;
73 return TRUE;
74 }
75 /*------------------------------------------------------------------------*/
TTWAIN_GetCapability(TW_INT16 msgType,TW_UINT16 cap_id,TW_UINT16 conType,void * data,TUINT32 * cont_size)76 static int TTWAIN_GetCapability(TW_INT16 msgType, TW_UINT16 cap_id,
77 TW_UINT16 conType, void *data,
78 TUINT32 *cont_size) {
79 TW_CAPABILITY cap;
80 void *pv;
81 TW_ENUMERATION *my_enum;
82 TW_ARRAY *my_array;
83 TW_ONEVALUE *my_one;
84 TW_RANGE *my_range;
85 TUINT32 size = 0;
86
87 if (!data && !cont_size) return FALSE;
88
89 if (TTWAIN_GetState() < TWAIN_SOURCE_OPEN) {
90 TTWAIN_ErrorBox("Attempt to get capability value below State 4.");
91 return FALSE;
92 }
93 /* Fill in capability structure */
94 cap.Cap = cap_id; /* capability id */
95 cap.ConType =
96 TWON_DONTCARE16; /* favorite type of container (should be ignored...) */
97 cap.hContainer = NULL;
98
99 if (TTWAIN_DS(DG_CONTROL, DAT_CAPABILITY, msgType, (TW_MEMREF)&cap) !=
100 TWRC_SUCCESS)
101 return FALSE;
102
103 if (!cap.hContainer) return FALSE;
104
105 if (msgType == MSG_QUERYSUPPORT) {
106 }
107
108 pv = GLOBAL_LOCK(cap.hContainer);
109 my_enum = (TW_ENUMERATION *)pv;
110 my_array = (TW_ARRAY *)pv;
111 my_one = (TW_ONEVALUE *)pv;
112 my_range = (TW_RANGE *)pv;
113
114 if (cont_size) {
115 switch (TWON_TWON(cap.ConType, conType)) {
116 case TWON_TWON(TWON_ENUMERATION, TWON_ENUMERATION):
117 *cont_size = GetContainerSize(TWON_ENUMERATION, my_enum->ItemType,
118 my_enum->NumItems);
119 break;
120 case TWON_TWON(TWON_ONEVALUE, TWON_ENUMERATION):
121 *cont_size = GetContainerSize(TWON_ENUMERATION, my_one->ItemType, 1);
122 break;
123 case TWON_TWON(TWON_ARRAY, TWON_ARRAY):
124 *cont_size =
125 GetContainerSize(TWON_ARRAY, my_array->ItemType, my_array->NumItems);
126 break;
127 case TWON_TWON(TWON_ONEVALUE, TWON_ONEVALUE):
128 *cont_size = GetContainerSize(TWON_ONEVALUE, my_one->ItemType, 1);
129 break;
130 case TWON_TWON(TWON_ENUMERATION, TWON_ARRAY):
131 *cont_size =
132 GetContainerSize(TWON_ARRAY, my_enum->ItemType, my_enum->NumItems);
133 break;
134 default:
135 /* tmsg_error("Unable to convert type %d to %d (cap 0x%x)\n",
136 * cap.ConType, conType,cap_id);*/
137 assert(0);
138 GLOBAL_UNLOCK(cap.hContainer);
139 GLOBAL_FREE(cap.hContainer);
140 return FALSE;
141 }
142 GLOBAL_UNLOCK(cap.hContainer);
143 GLOBAL_FREE(cap.hContainer);
144 return TRUE;
145 }
146
147 switch (TWON_TWON(cap.ConType, conType)) {
148 case TWON_TWON(TWON_ENUMERATION, TWON_ENUMERATION):
149 size = GetContainerSize(cap.ConType, my_enum->ItemType, my_enum->NumItems);
150 memcpy(data, my_enum, size);
151 break;
152 case TWON_TWON(TWON_ENUMERATION, TWON_RANGE):
153 ConvertEnumeration2Range(*my_enum, (TW_RANGE *)data);
154 break;
155 case TWON_TWON(TWON_ENUMERATION, TWON_ONEVALUE):
156 ConvertEnum2OneValue(*my_enum, (TW_ONEVALUE *)data);
157 break;
158 case TWON_TWON(TWON_ARRAY, TWON_ARRAY):
159 size =
160 GetContainerSize(cap.ConType, my_array->ItemType, my_array->NumItems);
161 memcpy(data, my_array, size);
162 break;
163 case TWON_TWON(TWON_ONEVALUE, TWON_ONEVALUE):
164 memcpy(data, my_one, sizeof(TW_ONEVALUE));
165 break;
166 case TWON_TWON(TWON_ONEVALUE, TWON_RANGE):
167 ConvertOneValue2Range(*my_one, (TW_RANGE *)data);
168 break;
169 case TWON_TWON(TWON_ONEVALUE, TWON_ENUMERATION):
170 ConvertOneValue2Enum(*my_one, (TW_ENUMERATION *)data);
171 break;
172 case TWON_TWON(TWON_RANGE, TWON_RANGE):
173 memcpy(data, my_range, sizeof(TW_RANGE));
174 break;
175 case TWON_TWON(TWON_ENUMERATION, TWON_ARRAY):
176 ConvertEnum2Array(*my_enum, (TW_ARRAY *)data);
177 break;
178 default:
179 assert(0);
180 GLOBAL_UNLOCK(cap.hContainer);
181 GLOBAL_FREE(cap.hContainer);
182 return FALSE;
183 }
184 GLOBAL_UNLOCK(cap.hContainer);
185 GLOBAL_FREE(cap.hContainer);
186 return TRUE;
187 }
188 /*---------------------------------------------------------------------------*/
189 /*---------------------------------------------------------------------------*/
190 /*---------------------------------------------------------------------------*/
191
192 /*---------------------------------------------------------------------------*/
ConvertOneValue2Range(TW_ONEVALUE one_value,TW_RANGE * range)193 static int ConvertOneValue2Range(TW_ONEVALUE one_value, TW_RANGE *range) {
194 range->ItemType = one_value.ItemType;
195 range->MinValue = one_value.Item;
196 range->MaxValue = one_value.Item;
197 range->StepSize = 0;
198 range->DefaultValue = one_value.Item;
199 range->CurrentValue = one_value.Item;
200 return TRUE;
201 }
202 /*---------------------------------------------------------------------------*/
ConvertEnumeration2Range(TW_ENUMERATION enumeration,TW_RANGE * range)203 static int ConvertEnumeration2Range(TW_ENUMERATION enumeration,
204 TW_RANGE *range) {
205 range->ItemType = enumeration.ItemType;
206 range->MinValue = enumeration.ItemList[0];
207 range->MaxValue = enumeration.ItemList[enumeration.NumItems - 1];
208 range->StepSize = (range->MaxValue - range->MinValue) / enumeration.NumItems;
209 if (range->MaxValue < range->MinValue) {
210 range->MaxValue = range->MinValue;
211 range->StepSize = 0;
212 }
213 range->DefaultValue = enumeration.ItemList[enumeration.DefaultIndex];
214 range->CurrentValue = enumeration.ItemList[enumeration.CurrentIndex];
215 return TRUE;
216 }
217 /*---------------------------------------------------------------------------*/
ConvertOneValue2Enum(TW_ONEVALUE one_value,TW_ENUMERATION * tw_enum)218 static int ConvertOneValue2Enum(TW_ONEVALUE one_value,
219 TW_ENUMERATION *tw_enum) {
220 tw_enum->ItemType = one_value.ItemType;
221 tw_enum->NumItems = 1;
222 tw_enum->CurrentIndex = 0; /* Current value is in ItemList[CurrentIndex] */
223 tw_enum->DefaultIndex = 0; /* Powerup value is in ItemList[DefaultIndex] */
224 tw_enum->ItemList[0] = (TW_UINT8)one_value.Item;
225 return TRUE;
226 }
227 /*---------------------------------------------------------------------------*/
ConvertEnum2OneValue(TW_ENUMERATION tw_enum,TW_ONEVALUE * one_value)228 static int ConvertEnum2OneValue(TW_ENUMERATION tw_enum,
229 TW_ONEVALUE *one_value) {
230 unsigned char *base;
231 TW_UINT32 ofs;
232 TW_UINT32 itemSize;
233
234 itemSize = DCItemSize[tw_enum.ItemType];
235 base = tw_enum.ItemList;
236 ofs = tw_enum.CurrentIndex * itemSize;
237
238 one_value->ItemType = tw_enum.ItemType;
239 one_value->Item = 0;
240 memcpy(&(one_value->Item), &(base[ofs]), itemSize);
241 return TRUE;
242 }
243 /*---------------------------------------------------------------------------*/
ConvertEnum2Array(TW_ENUMERATION tw_enum,TW_ARRAY * array)244 static int ConvertEnum2Array(TW_ENUMERATION tw_enum, TW_ARRAY *array) {
245 TW_UINT32 itemSize;
246 TW_UINT32 listSize;
247
248 itemSize = DCItemSize[tw_enum.ItemType];
249 listSize = itemSize * tw_enum.NumItems;
250 array->ItemType = tw_enum.ItemType;
251 array->NumItems = tw_enum.NumItems;
252 memcpy(&(array->ItemList), &(tw_enum.ItemList), listSize);
253 return TRUE;
254 }
255 /*---------------------------------------------------------------------------*/
256 /*---------------------------------------------------------------------------*/
257 /*---------------------------------------------------------------------------*/
258 /* SET CAP */
259 /*---------------------------------------------------------------------------*/
TTWAIN_SetCap(TW_UINT16 cap_id,TW_UINT16 conType,TW_UINT16 itemType,TW_UINT32 * value)260 int TTWAIN_SetCap(TW_UINT16 cap_id, TW_UINT16 conType, TW_UINT16 itemType,
261 TW_UINT32 *value) {
262 int rc = FALSE;
263 TUINT32 size;
264 TW_CAPABILITY *capability = 0;
265 TW_HANDLE capabilityH = 0;
266 TW_ONEVALUE *container = 0;
267 TW_HANDLE containerH = 0;
268
269 size = GetContainerSize(conType, itemType, 1);
270 containerH = GLOBAL_ALLOC(GMEM_FIXED, size);
271 if (!containerH) goto done;
272 container = (TW_ONEVALUE *)GLOBAL_LOCK(containerH);
273
274 container->ItemType = itemType;
275 container->Item = *value;
276 capabilityH = GLOBAL_ALLOC(GMEM_FIXED, sizeof(TW_CAPABILITY));
277 if (!capabilityH) {
278 GLOBAL_UNLOCK(containerH);
279 GLOBAL_FREE(containerH);
280 containerH = NULL;
281 goto done;
282 }
283
284 capability = (TW_CAPABILITY *)GLOBAL_LOCK(capabilityH);
285 capability->ConType = conType;
286 capability->hContainer = containerH;
287
288 if (TTWAIN_GetState() < TWAIN_SOURCE_OPEN) {
289 /*TTWAIN_ErrorBox("Setting capability in State < 4.");*/
290 TTWAIN_OpenSourceManager(0); /* Bring up to state 4 */
291 /*goto done;*/
292 }
293
294 capability->Cap = cap_id; /* capability id */
295
296 rc = (TTWAIN_DS(DG_CONTROL, DAT_CAPABILITY, MSG_SET, (TW_MEMREF)capability) ==
297 TWRC_SUCCESS);
298
299 done:
300 if (containerH) {
301 GLOBAL_UNLOCK(containerH);
302 GLOBAL_FREE(containerH);
303 }
304
305 if (capabilityH) {
306 GLOBAL_UNLOCK(capabilityH);
307 GLOBAL_FREE(capabilityH);
308 }
309 return rc;
310 }
311 /*---------------------------------------------------------------------------*/
GetContainerSize(int nFormat,unsigned twty,TW_UINT32 nItems)312 static TUINT32 GetContainerSize(int nFormat, unsigned twty, TW_UINT32 nItems) {
313 TUINT32 size;
314 switch (nFormat) {
315 case TWON_ONEVALUE:
316 size = sizeof(TW_ONEVALUE);
317 if (DCItemSize[twty] > sizeof(TW_UINT32)) {
318 size += DCItemSize[twty] - sizeof(TW_UINT32);
319 }
320 break;
321 case TWON_RANGE:
322 size = sizeof(TW_RANGE);
323 break;
324 case TWON_ENUMERATION:
325 size =
326 sizeof(TW_ENUMERATION) + DCItemSize[twty] * nItems - sizeof(TW_UINT8);
327 break;
328 case TWON_ARRAY:
329 size = sizeof(TW_ARRAY) + DCItemSize[twty] * nItems - sizeof(TW_UINT8);
330 break;
331 default:
332 size = 0;
333 break;
334 } /* switch */
335 return size;
336 }
337 /*---------------------------------------------------------------------------*/
338
339 #ifdef __cplusplus
340 }
341 #endif
342