msvcrt: NULL terminate program arguments list in __getmainargs.
[wine] / dlls / gphoto2.ds / capability.c
1 /*
2  * Copyright 2000 Corel Corporation
3  * Copyright 2006 Marcus Meissner
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public
7  * License as published by the Free Software Foundation; either
8  * version 2.1 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public
16  * License along with this library; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
18  */
19
20 #define NONAMELESSUNION
21 #define NONAMELESSSTRUCT
22
23 #include "config.h"
24
25 #include <stdarg.h>
26
27 #include "gphoto2_i.h"
28 #include "wine/debug.h"
29
30 WINE_DEFAULT_DEBUG_CHANNEL(twain);
31
32 static TW_UINT16 GPHOTO2_ICAPXferMech (pTW_CAPABILITY,TW_UINT16);
33 static TW_UINT16 GPHOTO2_ICAPPixelType (pTW_CAPABILITY,TW_UINT16);
34 static TW_UINT16 GPHOTO2_ICAPPixelFlavor (pTW_CAPABILITY,TW_UINT16);
35 static TW_UINT16 GPHOTO2_ICAPBitDepth (pTW_CAPABILITY,TW_UINT16);
36 static TW_UINT16 GPHOTO2_ICAPUnits (pTW_CAPABILITY,TW_UINT16);
37
38 TW_UINT16 GPHOTO2_SaneCapability (pTW_CAPABILITY pCapability, TW_UINT16 action)
39 {
40     TW_UINT16 twCC = TWCC_SUCCESS;
41
42     TRACE("capability=%d action=%d\n", pCapability->Cap, action);
43
44     switch (pCapability->Cap)
45     {
46         case CAP_DEVICEEVENT:
47         case CAP_ALARMS:
48         case CAP_ALARMVOLUME:
49         case ACAP_AUDIOFILEFORMAT:
50         case ACAP_XFERMECH:
51         case ICAP_AUTOMATICBORDERDETECTION:
52         case ICAP_AUTOMATICDESKEW:
53         case ICAP_AUTODISCARDBLANKPAGES:
54         case ICAP_AUTOMATICROTATE:
55         case ICAP_FLIPROTATION:
56         case CAP_AUTOMATICCAPTURE:
57         case CAP_TIMEBEFOREFIRSTCAPTURE:
58         case CAP_TIMEBETWEENCAPTURES:
59         case CAP_AUTOSCAN:
60         case CAP_CLEARBUFFERS:
61         case CAP_MAXBATCHBUFFERS:
62         case ICAP_BARCODEDETECTIONENABLED:
63         case ICAP_SUPPORTEDBARCODETYPES:
64         case ICAP_BARCODEMAXSEARCHPRIORITIES:
65         case ICAP_BARCODESEARCHPRIORITIES:
66         case ICAP_BARCODESEARCHMODE:
67         case ICAP_BARCODEMAXRETRIES:
68         case ICAP_BARCODETIMEOUT:
69         case CAP_EXTENDEDCAPS:
70         case CAP_SUPPORTEDCAPS:
71         case ICAP_FILTER:
72         case ICAP_GAMMA:
73         case ICAP_PLANARCHUNKY:
74         case ICAP_BITORDERCODES:
75         case ICAP_CCITTKFACTOR:
76         case ICAP_JPEGPIXELTYPE:
77         /*case ICAP_JPEGQUALITY:*/
78         case ICAP_PIXELFLAVORCODES:
79         case ICAP_TIMEFILL:
80         case CAP_DEVICEONLINE:
81         case CAP_DEVICETIMEDATE:
82         case CAP_SERIALNUMBER:
83         case ICAP_EXPOSURETIME:
84         case ICAP_FLASHUSED2:
85         case ICAP_IMAGEFILTER:
86         case ICAP_LAMPSTATE:
87         case ICAP_LIGHTPATH:
88         case ICAP_NOISEFILTER:
89         case ICAP_OVERSCAN:
90         case ICAP_PHYSICALHEIGHT:
91         case ICAP_PHYSICALWIDTH:
92         case ICAP_ZOOMFACTOR:
93         case CAP_PRINTER:
94         case CAP_PRINTERENABLED:
95         case CAP_PRINTERINDEX:
96         case CAP_PRINTERMODE:
97         case CAP_PRINTERSTRING:
98         case CAP_PRINTERSUFFIX:
99         case CAP_AUTHOR:
100         case CAP_CAPTION:
101         case CAP_TIMEDATE:
102         case ICAP_AUTOBRIGHT:
103         case ICAP_BRIGHTNESS:
104         case ICAP_CONTRAST:
105         case ICAP_HIGHLIGHT:
106         case ICAP_ORIENTATION:
107         case ICAP_ROTATION:
108         case ICAP_SHADOW:
109         case ICAP_XSCALING:
110         case ICAP_YSCALING:
111         case ICAP_BITDEPTHREDUCTION:
112         case ICAP_BITORDER:
113         case ICAP_CUSTHALFTONE:
114         case ICAP_HALFTONES:
115         case ICAP_THRESHOLD:
116         case CAP_LANGUAGE:
117         case ICAP_FRAMES:
118         case ICAP_MAXFRAMES:
119         case ICAP_SUPPORTEDSIZES:
120         case CAP_AUTOFEED:
121         case CAP_CLEARPAGE:
122         case CAP_FEEDERALIGNMENT:
123         case CAP_FEEDERENABLED:
124         case CAP_FEEDERLOADED:
125         case CAP_FEEDERORDER:
126         case CAP_FEEDPAGE:
127         case CAP_PAPERBINDING:
128         case CAP_PAPERDETECTABLE:
129         case CAP_REACQUIREALLOWED:
130         case CAP_REWINDPAGE:
131         case ICAP_PATCHCODEDETECTIONENABLED:
132         case ICAP_SUPPORTEDPATCHCODETYPES:
133         case ICAP_PATCHCODEMAXSEARCHPRIORITIES:
134         case ICAP_PATCHCODESEARCHPRIORITIES:
135         case ICAP_PATCHCODESEARCHMODE:
136         case ICAP_PATCHCODEMAXRETRIES:
137         case ICAP_PATCHCODETIMEOUT:
138         case CAP_BATTERYMINUTES:
139         case CAP_BATTERYPERCENTAGE:
140         case CAP_POWERDOWNTIME:
141         case CAP_POWERSUPPLY:
142         case ICAP_XNATIVERESOLUTION:
143         case ICAP_XRESOLUTION:
144         case ICAP_YNATIVERESOLUTION:
145         case ICAP_YRESOLUTION:
146             twCC = TWCC_CAPUNSUPPORTED;
147             break;
148         case CAP_XFERCOUNT:
149             /* This is a required capability that every source need to
150                support but we haven't implemented yet. */
151             twCC = TWCC_SUCCESS;
152             break;
153         /*case ICAP_COMPRESSION:*/
154         case ICAP_IMAGEFILEFORMAT:
155         case ICAP_TILES:
156             twCC = TWCC_CAPUNSUPPORTED;
157             break;
158         case ICAP_XFERMECH:
159             twCC = GPHOTO2_ICAPXferMech (pCapability, action);
160             break;
161         case ICAP_PIXELTYPE:
162             twCC = GPHOTO2_ICAPPixelType (pCapability, action);
163             break;
164         case ICAP_PIXELFLAVOR:
165             twCC = GPHOTO2_ICAPPixelFlavor (pCapability, action);
166             break;
167         case ICAP_BITDEPTH:
168             twCC = GPHOTO2_ICAPBitDepth (pCapability, action);
169             break;
170         case ICAP_UNITS:
171             twCC = GPHOTO2_ICAPUnits (pCapability, action);
172             break;
173         case ICAP_UNDEFINEDIMAGESIZE:
174         case CAP_CAMERAPREVIEWUI:
175         case CAP_ENABLEDSUIONLY:
176         case CAP_INDICATORS:
177         case CAP_UICONTROLLABLE:
178             twCC = TWCC_CAPUNSUPPORTED;
179             break;
180
181         case ICAP_COMPRESSION:
182             twCC = TWCC_SUCCESS;
183             break;
184         default:
185             twCC = TWRC_FAILURE;
186             break;
187     }
188     return twCC;
189 }
190
191 static TW_BOOL GPHOTO2_OneValueSet32 (pTW_CAPABILITY pCapability, TW_UINT32 value)
192 {
193     pCapability->hContainer = GlobalAlloc (0, sizeof(TW_ONEVALUE));
194
195     TRACE("-> %d\n", value);
196
197     if (pCapability->hContainer)
198     {
199         pTW_ONEVALUE pVal = GlobalLock (pCapability->hContainer);
200         pVal->ItemType = TWTY_UINT32;
201         pVal->Item = value;
202         GlobalUnlock (pCapability->hContainer);
203         pCapability->ConType = TWON_ONEVALUE;
204         return TRUE;
205     }
206     else
207         return FALSE;
208 }
209
210 static TW_BOOL GPHOTO2_OneValueSet16 (pTW_CAPABILITY pCapability, TW_UINT16 value)
211 {
212     pCapability->hContainer = GlobalAlloc (0, sizeof(TW_ONEVALUE));
213
214     TRACE("-> %d\n", value);
215
216     if (pCapability->hContainer)
217     {
218         pTW_ONEVALUE pVal = GlobalLock (pCapability->hContainer);
219         pVal->ItemType = TWTY_UINT16;
220         pVal->Item = value;
221         GlobalUnlock (pCapability->hContainer);
222         pCapability->ConType = TWON_ONEVALUE;
223         return TRUE;
224     }
225     else
226         return FALSE;
227 }
228
229 static TW_BOOL GPHOTO2_EnumSet16 (pTW_CAPABILITY pCapability, int nrofvalues,
230                                   const TW_UINT16 *values, int current, int def)
231 {
232     pTW_ENUMERATION pVal;
233     pCapability->hContainer = GlobalAlloc (0, sizeof(TW_ENUMERATION) + nrofvalues * sizeof(TW_UINT16));
234
235     if (!pCapability->hContainer)
236         return FALSE;
237
238     pVal = GlobalLock (pCapability->hContainer);
239     pVal->ItemType = TWTY_UINT16;
240     pVal->NumItems = nrofvalues;
241     memcpy(pVal->ItemList, values, sizeof(TW_UINT16)*nrofvalues);
242     pVal->CurrentIndex = current;
243     pVal->DefaultIndex = def;
244     pCapability->ConType = TWON_ENUMERATION;
245     GlobalUnlock (pCapability->hContainer);
246     return TRUE;
247 }
248
249 static TW_BOOL GPHOTO2_EnumGet16 (pTW_CAPABILITY pCapability, int *nrofvalues, TW_UINT16 **values)
250 {
251     pTW_ENUMERATION pVal = GlobalLock (pCapability->hContainer);
252
253     if (!pVal)
254         return FALSE;
255     *nrofvalues = pVal->NumItems;
256     *values = HeapAlloc( GetProcessHeap(), 0, sizeof(TW_UINT16)*pVal->NumItems);
257     memcpy (*values, pVal->ItemList, sizeof(TW_UINT16)*(*nrofvalues));
258     FIXME("Current Index %d, Default Index %d\n", pVal->CurrentIndex, pVal->DefaultIndex);
259     GlobalUnlock (pCapability->hContainer);
260     return TRUE;
261 }
262
263 static TW_BOOL GPHOTO2_OneValueGet32 (pTW_CAPABILITY pCapability, TW_UINT32 *pValue)
264 {
265     pTW_ONEVALUE pVal = GlobalLock (pCapability->hContainer);
266
267     if (pVal)
268     {
269         *pValue = pVal->Item;
270         GlobalUnlock (pCapability->hContainer);
271         return TRUE;
272     }
273     else
274         return FALSE;
275 }
276
277 static TW_BOOL GPHOTO2_OneValueGet16 (pTW_CAPABILITY pCapability, TW_UINT16 *pValue)
278 {
279     pTW_ONEVALUE pVal = GlobalLock (pCapability->hContainer);
280
281     if (pVal)
282     {
283         *pValue = pVal->Item;
284         GlobalUnlock (pCapability->hContainer);
285         return TRUE;
286     }
287     else
288         return FALSE;
289 }
290
291 /* ICAP_XFERMECH */
292 static TW_UINT16 GPHOTO2_ICAPXferMech (pTW_CAPABILITY pCapability, TW_UINT16 action)
293 {
294     TRACE("ICAP_XFERMECH, action %d\n", action);
295
296     switch (action)
297     {
298         case MSG_GET:
299             if (!GPHOTO2_OneValueSet32 (pCapability, activeDS.capXferMech))
300                 return TWCC_LOWMEMORY;
301             return TWCC_SUCCESS;
302         case MSG_SET:
303             if (pCapability->ConType == TWON_ONEVALUE)
304             {
305                 TW_UINT32 xfermechtemp = 0;
306
307                 if (!GPHOTO2_OneValueGet32 (pCapability, &xfermechtemp))
308                     return TWCC_LOWMEMORY;
309                 activeDS.capXferMech = xfermechtemp;
310                 TRACE("xfermech is %d\n", xfermechtemp);
311                 return TWCC_SUCCESS;
312             }
313             else if (pCapability->ConType == TWON_ENUMERATION)
314             {
315
316             }
317             FIXME("GET FAILED\n");
318             break;
319         case MSG_GETCURRENT:
320             if (!GPHOTO2_OneValueSet32 (pCapability, activeDS.capXferMech))
321                 return TWCC_LOWMEMORY;
322             break;
323         case MSG_GETDEFAULT:
324             if (!GPHOTO2_OneValueSet32 (pCapability, TWSX_NATIVE))
325                 return TWCC_LOWMEMORY;
326             break;
327         case MSG_RESET:
328             activeDS.capXferMech = TWSX_NATIVE;
329             break;
330     }
331     return TWCC_SUCCESS;
332 }
333
334 /* ICAP_PIXELTYPE */
335 static TW_UINT16 GPHOTO2_ICAPPixelType (pTW_CAPABILITY pCapability, TW_UINT16 action)
336 {
337     TRACE("Action %d\n", action);
338
339     switch (action)
340     {
341         case MSG_GET:
342             if ((pCapability->ConType == TWON_DONTCARE16) ||
343                 (pCapability->ConType == TWON_ONEVALUE)
344             ) {
345                 if (!GPHOTO2_OneValueSet16 (pCapability, activeDS.pixeltype))
346                     return TWCC_LOWMEMORY;
347                 return TWCC_SUCCESS;
348             }
349             FIXME("Unknown container type %x in MSG_GET\n", pCapability->ConType);
350             return TWCC_CAPBADOPERATION;
351         case MSG_SET:
352             if (pCapability->ConType == TWON_ONEVALUE)
353             {
354                 TW_UINT16 pixeltype = 0;
355
356                 if (!GPHOTO2_OneValueGet16 (pCapability, &pixeltype))
357                     return TWCC_LOWMEMORY;
358                 activeDS.pixeltype = pixeltype;
359                 FIXME("pixeltype changed to %d!\n", pixeltype);
360                 return TWCC_SUCCESS;
361             }
362             FIXME("set not done\n");
363             if (pCapability->ConType == TWON_ENUMERATION) {
364                 TW_UINT16       *values = NULL;
365                 int i, nrofvalues = 0;
366                 
367                 if (!GPHOTO2_EnumGet16 (pCapability, &nrofvalues, &values))
368                     return TWCC_LOWMEMORY;
369                 for (i=0;i<nrofvalues;i++)
370                     FIXME("SET PixelType %d:%d\n", i, values[i]);
371                 HeapFree (GetProcessHeap(), 0, values);
372             }
373             break;
374         case MSG_GETCURRENT:
375             if (!GPHOTO2_OneValueSet16 (pCapability, activeDS.pixeltype)) {
376                 FIXME("Failed one value set in GETCURRENT, contype %d!\n", pCapability->ConType);
377                 return TWCC_LOWMEMORY;
378             }
379             break;
380         case MSG_GETDEFAULT:
381             if (!GPHOTO2_OneValueSet16 (pCapability, TWPT_RGB)) {
382                 FIXME("Failed onevalue set in GETDEFAULT!\n");
383                 return TWCC_LOWMEMORY;
384             }
385             break;
386         case MSG_RESET:
387             activeDS.pixeltype = TWPT_RGB;
388             break;
389     }
390     return TWCC_SUCCESS;
391 }
392
393 /* ICAP_PIXELFLAVOR */
394 static TW_UINT16 GPHOTO2_ICAPPixelFlavor (pTW_CAPABILITY pCapability, TW_UINT16 action)
395 {
396     TRACE("Action %d\n", action);
397
398     switch (action)
399     {
400         case MSG_GET:
401             if ((pCapability->ConType == TWON_DONTCARE16)       ||
402                 (pCapability->ConType == TWON_ONEVALUE)
403             ) {
404                 if (!GPHOTO2_OneValueSet16 (pCapability, TWPF_CHOCOLATE))
405                     return TWCC_LOWMEMORY;
406                 return TWCC_SUCCESS;
407             }
408             if (!pCapability->ConType) {
409                 TW_UINT16 arr[2];
410                 arr[0] = TWPF_CHOCOLATE;
411                 arr[1] = TWPF_VANILLA;
412
413                 if (!GPHOTO2_EnumSet16 (pCapability, 2, arr, 1, 1))
414                     return TWCC_LOWMEMORY;
415                 return TWCC_SUCCESS;
416             }
417             FIXME("MSG_GET container type %x unhandled\n", pCapability->ConType);
418             return TWCC_BADVALUE;
419         case MSG_SET:
420             if (pCapability->ConType == TWON_ONEVALUE)
421             {
422                 TW_UINT16 pixelflavor = 0;
423
424                 if (!GPHOTO2_OneValueGet16 (pCapability, &pixelflavor))
425                     return TWCC_LOWMEMORY;
426                 activeDS.pixelflavor = pixelflavor;
427                 FIXME("pixelflavor is %d\n", pixelflavor);
428             }
429             break;
430         case MSG_GETCURRENT:
431             if (!GPHOTO2_OneValueSet16 (pCapability, activeDS.pixelflavor))
432                 return TWCC_LOWMEMORY;
433             break;
434         case MSG_GETDEFAULT:
435             if (!GPHOTO2_OneValueSet16 (pCapability, TWPF_CHOCOLATE))
436                 return TWCC_LOWMEMORY;
437             break;
438         case MSG_RESET:
439             break;
440     }
441     return TWCC_SUCCESS;
442 }
443
444 /* ICAP_BITDEPTH */
445 static TW_UINT16 GPHOTO2_ICAPBitDepth (pTW_CAPABILITY pCapability, TW_UINT16 action)
446 {
447     TRACE("Action %d\n", action);
448
449     switch (action)
450     {
451         case MSG_GET:
452             if ((pCapability->ConType == TWON_DONTCARE16) ||
453                 (pCapability->ConType == TWON_ONEVALUE)
454             ) {
455                 if (!GPHOTO2_OneValueSet16 (pCapability, 24))
456                     return TWCC_LOWMEMORY;
457                 return TWCC_SUCCESS;
458             }
459             FIXME("MSG_GET container type %x unhandled\n", pCapability->ConType);
460             return TWCC_SUCCESS;
461         case MSG_SET:
462             if (pCapability->ConType == TWON_ONEVALUE) {
463                 TW_UINT16 bitdepth = 0;
464
465                 if (!GPHOTO2_OneValueGet16 (pCapability, &bitdepth))
466                     return TWCC_LOWMEMORY;
467                 if (bitdepth != 24)
468                     return TWCC_BADVALUE;
469                 return TWCC_SUCCESS;
470             }
471             if (pCapability->ConType == TWON_ENUMERATION)
472             {
473                 int i, nrofvalues = 0;
474                 TW_UINT16 *values = NULL;
475
476                 if (!GPHOTO2_EnumGet16 (pCapability, &nrofvalues, &values))
477                     return TWCC_LOWMEMORY;
478                 for (i=0;i<nrofvalues;i++)
479                     FIXME("SET: enum element %d = %d\n", i, values[i]);
480                 HeapFree (GetProcessHeap(), 0, values);
481                 return TWCC_SUCCESS;
482             }
483             FIXME("Unhandled container type %d in MSG_SET\n", pCapability->ConType);
484             break;
485         case MSG_GETCURRENT:
486             if (!GPHOTO2_OneValueSet16 (pCapability, 24))
487                 return TWCC_LOWMEMORY;
488             break;
489         case MSG_GETDEFAULT:
490             if (!GPHOTO2_OneValueSet16 (pCapability, 24))
491                 return TWCC_LOWMEMORY;
492             break;
493         case MSG_RESET:
494             break;
495     }
496     return TWCC_SUCCESS;
497 }
498
499 /* ICAP_UNITS */
500 static TW_UINT16 GPHOTO2_ICAPUnits (pTW_CAPABILITY pCapability, TW_UINT16 action)
501 {
502     TRACE("Action %d\n", action);
503
504     switch (action)
505     {
506         case MSG_GET:
507             if ((pCapability->ConType == TWON_DONTCARE16) ||
508                 (pCapability->ConType == TWON_ONEVALUE)
509             ) {
510                 if (!GPHOTO2_OneValueSet16 (pCapability, TWUN_PIXELS))
511                     return TWCC_LOWMEMORY;
512                 return TWCC_SUCCESS;
513             }
514             FIXME("MSG_GET container type %x unhandled\n", pCapability->ConType);
515             return TWCC_SUCCESS;
516         case MSG_SET:
517             if (pCapability->ConType == TWON_ONEVALUE) {
518                 TW_UINT16 units = 0;
519
520                 if (!GPHOTO2_OneValueGet16 (pCapability, &units))
521                     return TWCC_LOWMEMORY;
522                 FIXME("SET to type %d, stub.\n", units);
523                 return TWCC_SUCCESS;
524             }
525             if (pCapability->ConType == TWON_ENUMERATION)
526             {
527                 int i, nrofvalues = 0;
528                 TW_UINT16 *values = NULL;
529
530                 if (!GPHOTO2_EnumGet16 (pCapability, &nrofvalues, &values))
531                     return TWCC_LOWMEMORY;
532                 for (i=0;i<nrofvalues;i++)
533                     FIXME("SET: enum element %d = %d\n", i, values[i]);
534                 HeapFree (GetProcessHeap(), 0, values);
535                 return TWCC_SUCCESS;
536             }
537             FIXME("Unhandled container type %d in MSG_SET\n", pCapability->ConType);
538             break;
539         case MSG_GETCURRENT:
540             if (!GPHOTO2_OneValueSet16 (pCapability, TWUN_INCHES))
541                 return TWCC_LOWMEMORY;
542             break;
543         case MSG_GETDEFAULT:
544             if (!GPHOTO2_OneValueSet16 (pCapability, TWUN_PIXELS))
545                 return TWCC_LOWMEMORY;
546             break;
547         case MSG_RESET:
548             break;
549     }
550     return TWCC_SUCCESS;
551 }