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