quartz: Fix support for files with multiple odml indexes.
[wine/wine64.git] / dlls / gphoto2.ds / ds_ctrl.c
blob9644f8a18673c9d5dbdb6ca8c9625c1a97f20a3d
1 /*
2 * Copyright 2000 Corel Corporation
3 * Copyright 2006 Marcus Meissner
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.
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.
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
20 #include "config.h"
22 #ifdef HAVE_UNISTD_H
23 # include <unistd.h>
24 #endif
25 #include <stdlib.h>
26 #include <stdio.h>
27 #include "twain.h"
28 #include "gphoto2_i.h"
29 #include "wine/debug.h"
31 WINE_DEFAULT_DEBUG_CHANNEL(twain);
33 static void
34 load_filesystem(const char *folder) {
35 #ifdef HAVE_GPHOTO2
36 int i, count, ret;
37 CameraList *list;
39 ret = gp_list_new (&list);
40 if (ret < GP_OK)
41 return;
42 ret = gp_camera_folder_list_files (activeDS.camera, folder, list, activeDS.context);
43 if (ret < GP_OK) {
44 gp_list_free (list);
45 return;
47 count = gp_list_count (list);
48 if (count < GP_OK) {
49 gp_list_free (list);
50 return;
52 for (i = 0; i < count; i++) {
53 const char *name;
54 struct gphoto2_file *gpfile;
56 ret = gp_list_get_name (list, i, &name);
57 if (ret < GP_OK)
58 continue;
59 gpfile = malloc(sizeof(struct gphoto2_file));
60 if (!gpfile)
61 continue;
62 TRACE("adding %s/%s\n", folder, name);
63 gpfile->folder = strdup(folder);
64 gpfile->filename = strdup(name);
65 gpfile->download = FALSE;
66 list_add_tail( &activeDS.files, &gpfile->entry );
68 gp_list_reset (list);
70 ret = gp_camera_folder_list_folders (activeDS.camera, folder, list, activeDS.context);
71 if (ret < GP_OK) {
72 FIXME("list_folders failed\n");
73 gp_list_free (list);
74 return;
76 count = gp_list_count (list);
77 if (count < GP_OK) {
78 FIXME("list_folders failed\n");
79 gp_list_free (list);
80 return;
82 for (i = 0; i < count; i++) {
83 const char *name;
84 char *newfolder;
85 ret = gp_list_get_name (list, i, &name);
86 if (ret < GP_OK)
87 continue;
88 TRACE("recursing into %s\n", name);
89 newfolder = malloc(strlen(folder)+1+strlen(name)+1);
90 if (!strcmp(folder,"/"))
91 sprintf (newfolder, "/%s", name);
92 else
93 sprintf (newfolder, "%s/%s", folder, name);
94 load_filesystem (newfolder); /* recurse ... happily */
96 gp_list_free (list);
97 #endif
100 /* DG_CONTROL/DAT_CAPABILITY/MSG_GET */
101 TW_UINT16 GPHOTO2_CapabilityGet (pTW_IDENTITY pOrigin, TW_MEMREF pData)
103 pTW_CAPABILITY pCapability = (pTW_CAPABILITY) pData;
105 TRACE("DG_CONTROL/DAT_CAPABILITY/MSG_GET\n");
106 if (activeDS.currentState < 4 || activeDS.currentState > 7) {
107 activeDS.twCC = TWCC_SEQERROR;
108 return TWRC_FAILURE;
110 activeDS.twCC = GPHOTO2_SaneCapability (pCapability, MSG_GET);
111 return (activeDS.twCC == TWCC_SUCCESS)?TWRC_SUCCESS:TWRC_FAILURE;
114 /* DG_CONTROL/DAT_CAPABILITY/MSG_GETCURRENT */
115 TW_UINT16 GPHOTO2_CapabilityGetCurrent (pTW_IDENTITY pOrigin, TW_MEMREF pData)
117 pTW_CAPABILITY pCapability = (pTW_CAPABILITY) pData;
119 TRACE("DG_CONTROL/DAT_CAPABILITY/MSG_GETCURRENT\n");
121 if (activeDS.currentState < 4 || activeDS.currentState > 7) {
122 activeDS.twCC = TWCC_SEQERROR;
123 return TWRC_FAILURE;
125 activeDS.twCC = GPHOTO2_SaneCapability (pCapability, MSG_GETCURRENT);
126 return (activeDS.twCC == TWCC_SUCCESS)?TWRC_SUCCESS:TWRC_FAILURE;
129 /* DG_CONTROL/DAT_CAPABILITY/MSG_GETDEFAULT */
130 TW_UINT16 GPHOTO2_CapabilityGetDefault (pTW_IDENTITY pOrigin, TW_MEMREF pData)
132 pTW_CAPABILITY pCapability = (pTW_CAPABILITY) pData;
134 TRACE("DG_CONTROL/DAT_CAPABILITY/MSG_GETDEFAULT\n");
135 if (activeDS.currentState < 4 || activeDS.currentState > 7) {
136 activeDS.twCC = TWCC_SEQERROR;
137 return TWRC_FAILURE;
139 activeDS.twCC = GPHOTO2_SaneCapability (pCapability, MSG_GETDEFAULT);
140 return (activeDS.twCC == TWCC_SUCCESS)?TWRC_SUCCESS:TWRC_FAILURE;
143 /* DG_CONTROL/DAT_CAPABILITY/MSG_QUERYSUPPORT */
144 TW_UINT16 GPHOTO2_CapabilityQuerySupport (pTW_IDENTITY pOrigin,
145 TW_MEMREF pData)
147 FIXME ("stub!\n");
149 return TWRC_FAILURE;
152 /* DG_CONTROL/DAT_CAPABILITY/MSG_RESET */
153 TW_UINT16 GPHOTO2_CapabilityReset (pTW_IDENTITY pOrigin,
154 TW_MEMREF pData)
156 pTW_CAPABILITY pCapability = (pTW_CAPABILITY) pData;
158 TRACE("DG_CONTROL/DAT_CAPABILITY/MSG_RESET\n");
160 if (activeDS.currentState < 4 || activeDS.currentState > 7) {
161 activeDS.twCC = TWCC_SEQERROR;
162 return TWRC_FAILURE;
164 activeDS.twCC = GPHOTO2_SaneCapability (pCapability, MSG_RESET);
165 return (activeDS.twCC == TWCC_SUCCESS)?TWRC_SUCCESS:TWRC_FAILURE;
168 /* DG_CONTROL/DAT_CAPABILITY/MSG_SET */
169 TW_UINT16 GPHOTO2_CapabilitySet (pTW_IDENTITY pOrigin,
170 TW_MEMREF pData)
172 pTW_CAPABILITY pCapability = (pTW_CAPABILITY) pData;
174 TRACE ("DG_CONTROL/DAT_CAPABILITY/MSG_SET\n");
176 if (activeDS.currentState != 4) {
177 activeDS.twCC = TWCC_SEQERROR;
178 return TWRC_FAILURE;
180 activeDS.twCC = GPHOTO2_SaneCapability (pCapability, MSG_SET);
181 return (activeDS.twCC == TWCC_SUCCESS)?TWRC_SUCCESS:TWRC_FAILURE;
184 /* DG_CONTROL/DAT_CUSTOMDSDATA/MSG_GET */
185 TW_UINT16 GPHOTO2_CustomDSDataGet (pTW_IDENTITY pOrigin,
186 TW_MEMREF pData)
188 FIXME ("stub!\n");
190 return TWRC_FAILURE;
193 /* DG_CONTROL/DAT_CUSTOMDSDATA/MSG_SET */
194 TW_UINT16 GPHOTO2_CustomDSDataSet (pTW_IDENTITY pOrigin,
195 TW_MEMREF pData)
197 FIXME ("stub!\n");
199 return TWRC_FAILURE;
202 /* DG_CONTROL/DAT_FILESYSTEM/MSG_AUTOMATICCAPTUREDIRECTORY */
203 TW_UINT16 GPHOTO2_AutomaticCaptureDirectory (pTW_IDENTITY pOrigin,
205 TW_MEMREF pData)
207 FIXME ("stub!\n");
209 return TWRC_FAILURE;
212 /* DG_CONTROL/DAT_FILESYSTEM/MSG_CHANGEDIRECTORY */
213 TW_UINT16 GPHOTO2_ChangeDirectory (pTW_IDENTITY pOrigin,
214 TW_MEMREF pData)
216 FIXME ("stub!\n");
218 return TWRC_FAILURE;
221 /* DG_CONTROL/DAT_FILESYSTEM/MSG_COPY */
222 TW_UINT16 GPHOTO2_FileSystemCopy (pTW_IDENTITY pOrigin,
223 TW_MEMREF pData)
225 FIXME ("stub!\n");
227 return TWRC_FAILURE;
230 /* DG_CONTROL/DAT_FILESYSTEM/MSG_CREATEDIRECTORY */
231 TW_UINT16 GPHOTO2_CreateDirectory (pTW_IDENTITY pOrigin,
232 TW_MEMREF pData)
234 FIXME ("stub!\n");
236 return TWRC_FAILURE;
239 /* DG_CONTROL/DAT_FILESYSTEM/MSG_DELETE */
240 TW_UINT16 GPHOTO2_FileSystemDelete (pTW_IDENTITY pOrigin,
241 TW_MEMREF pData)
243 FIXME ("stub!\n");
245 return TWRC_FAILURE;
248 /* DG_CONTROL/DAT_FILESYSTEM/MSG_FORMATMEDIA */
249 TW_UINT16 GPHOTO2_FormatMedia (pTW_IDENTITY pOrigin,
250 TW_MEMREF pData)
252 FIXME ("stub!\n");
254 return TWRC_FAILURE;
257 /* DG_CONTROL/DAT_FILESYSTEM/MSG_GETCLOSE */
258 TW_UINT16 GPHOTO2_FileSystemGetClose (pTW_IDENTITY pOrigin,
259 TW_MEMREF pData)
261 FIXME ("stub!\n");
263 return TWRC_FAILURE;
266 /* DG_CONTROL/DAT_FILESYSTEM/MSG_GETFIRSTFILE */
267 TW_UINT16 GPHOTO2_FileSystemGetFirstFile (pTW_IDENTITY pOrigin,
269 TW_MEMREF pData)
271 FIXME ("stub!\n");
273 return TWRC_FAILURE;
276 /* DG_CONTROL/DAT_FILESYSTEM/MSG_GETINFO */
277 TW_UINT16 GPHOTO2_FileSystemGetInfo (pTW_IDENTITY pOrigin,
278 TW_MEMREF pData)
280 FIXME ("stub!\n");
282 return TWRC_FAILURE;
285 /* DG_CONTROL/DAT_FILESYSTEM/MSG_GETNEXTFILE */
286 TW_UINT16 GPHOTO2_FileSystemGetNextFile (pTW_IDENTITY pOrigin,
288 TW_MEMREF pData)
290 FIXME ("stub!\n");
292 return TWRC_FAILURE;
295 /* DG_CONTROL/DAT_FILESYSTEM/MSG_RENAME */
296 TW_UINT16 GPHOTO2_FileSystemRename (pTW_IDENTITY pOrigin,
297 TW_MEMREF pData)
299 FIXME ("stub!\n");
301 return TWRC_FAILURE;
304 /* DG_CONTROL/DAT_EVENT/MSG_PROCESSEVENT */
305 TW_UINT16 GPHOTO2_ProcessEvent (pTW_IDENTITY pOrigin,
306 TW_MEMREF pData)
308 TW_UINT16 twRC = TWRC_SUCCESS;
309 pTW_EVENT pEvent = (pTW_EVENT) pData;
311 TRACE("DG_CONTROL/DAT_EVENT/MSG_PROCESSEVENT\n");
313 if (activeDS.currentState < 5 || activeDS.currentState > 7) {
314 activeDS.twCC = TWCC_SEQERROR;
315 return TWRC_FAILURE;
318 if (activeDS.pendingEvent.TWMessage != MSG_NULL) {
319 pEvent->TWMessage = activeDS.pendingEvent.TWMessage;
320 activeDS.pendingEvent.TWMessage = MSG_NULL;
321 twRC = TWRC_SUCCESS;
322 } else {
323 pEvent->TWMessage = MSG_NULL; /* no message to the application */
324 twRC = TWRC_NOTDSEVENT;
326 activeDS.twCC = TWCC_SUCCESS;
327 return twRC;
330 /* DG_CONTROL/DAT_PASSTHRU/MSG_PASSTHRU */
331 TW_UINT16 GPHOTO2_PassThrough (pTW_IDENTITY pOrigin,
332 TW_MEMREF pData)
334 FIXME ("stub!\n");
336 return TWRC_FAILURE;
339 /* DG_CONTROL/DAT_PENDINGXFERS/MSG_ENDXFER */
340 TW_UINT16 GPHOTO2_PendingXfersEndXfer (pTW_IDENTITY pOrigin,
341 TW_MEMREF pData)
343 TW_UINT32 count;
344 pTW_PENDINGXFERS pPendingXfers = (pTW_PENDINGXFERS) pData;
345 struct gphoto2_file *file;
347 TRACE("DG_CONTROL/DAT_PENDINGXFERS/MSG_ENDXFER\n");
349 if (activeDS.currentState != 6 && activeDS.currentState != 7) {
350 activeDS.twCC = TWCC_SEQERROR;
351 return TWRC_FAILURE;
353 count = 0;
354 LIST_FOR_EACH_ENTRY( file, &activeDS.files, struct gphoto2_file, entry ) {
355 if (file->download)
356 count++;
358 TRACE("count = %ld\n", count);
359 pPendingXfers->Count = count;
360 if (pPendingXfers->Count != 0) {
361 activeDS.currentState = 6;
362 } else {
363 activeDS.currentState = 5;
364 /* Notify the application that it can close the data source */
365 activeDS.pendingEvent.TWMessage = MSG_CLOSEDSREQ;
366 /* close any Transferring dialog */
367 TransferringDialogBox(activeDS.progressWnd,-1);
368 activeDS.progressWnd = 0;
370 activeDS.twCC = TWCC_SUCCESS;
371 return TWRC_SUCCESS;
374 /* DG_CONTROL/DAT_PENDINGXFERS/MSG_GET */
375 TW_UINT16 GPHOTO2_PendingXfersGet (pTW_IDENTITY pOrigin,
376 TW_MEMREF pData)
378 TW_UINT32 count;
379 pTW_PENDINGXFERS pPendingXfers = (pTW_PENDINGXFERS) pData;
380 struct gphoto2_file *file;
382 TRACE("DG_CONTROL/DAT_PENDINGXFERS/MSG_GET\n");
384 if (activeDS.currentState < 4 || activeDS.currentState > 7) {
385 activeDS.twCC = TWCC_SEQERROR;
386 return TWRC_FAILURE;
389 count = 0;
390 LIST_FOR_EACH_ENTRY( file, &activeDS.files, struct gphoto2_file, entry ) {
391 if (file->download)
392 count++;
394 TRACE("count = %ld\n", count);
395 pPendingXfers->Count = count;
396 activeDS.twCC = TWCC_SUCCESS;
397 return TWRC_SUCCESS;
400 /* DG_CONTROL/DAT_PENDINGXFERS/MSG_RESET */
401 TW_UINT16 GPHOTO2_PendingXfersReset (pTW_IDENTITY pOrigin,
402 TW_MEMREF pData)
404 pTW_PENDINGXFERS pPendingXfers = (pTW_PENDINGXFERS) pData;
406 TRACE("DG_CONTROL/DAT_PENDINGXFERS/MSG_RESET\n");
408 if (activeDS.currentState != 6) {
409 activeDS.twCC = TWCC_SEQERROR;
410 return TWRC_FAILURE;
412 pPendingXfers->Count = 0;
413 activeDS.currentState = 5;
414 activeDS.twCC = TWCC_SUCCESS;
415 return TWRC_SUCCESS;
418 /* DG_CONTROL/DAT_PENDINGXFERS/MSG_STOPFEEDER */
419 TW_UINT16 GPHOTO2_PendingXfersStopFeeder (pTW_IDENTITY pOrigin,
420 TW_MEMREF pData)
422 FIXME ("stub!\n");
424 return TWRC_FAILURE;
427 /* DG_CONTROL/DAT_SETUPFILEXFER/MSG_GET */
428 TW_UINT16 GPHOTO2_SetupFileXferGet (pTW_IDENTITY pOrigin,
429 TW_MEMREF pData)
431 FIXME ("stub!\n");
433 return TWRC_FAILURE;
436 /* DG_CONTROL/DAT_SETUPXFER/MSG_GETDEFAULT */
437 TW_UINT16 GPHOTO2_SetupFileXferGetDefault (pTW_IDENTITY pOrigin,
438 TW_MEMREF pData)
440 FIXME ("stub!\n");
442 return TWRC_FAILURE;
446 /* DG_CONTROL/DAT_SETUPFILEXFER/MSG_RESET */
447 TW_UINT16 GPHOTO2_SetupFileXferReset (pTW_IDENTITY pOrigin,
448 TW_MEMREF pData)
450 FIXME ("stub!\n");
452 return TWRC_FAILURE;
455 /* DG_CONTROL/DAT_SETUPFILEXFER/MSG_SET */
456 TW_UINT16 GPHOTO2_SetupFileXferSet (pTW_IDENTITY pOrigin,
457 TW_MEMREF pData)
459 FIXME ("stub!\n");
461 return TWRC_FAILURE;
464 /* DG_CONTROL/DAT_SETUPFILEXFER2/MSG_GET */
465 TW_UINT16 GPHOTO2_SetupFileXfer2Get (pTW_IDENTITY pOrigin,
466 TW_MEMREF pData)
468 FIXME ("stub!\n");
470 return TWRC_FAILURE;
473 /* DG_CONTROL/DAT_SETUPFILEXFER2/MSG_GETDEFAULT */
474 TW_UINT16 GPHOTO2_SetupFileXfer2GetDefault (pTW_IDENTITY pOrigin,
475 TW_MEMREF pData)
477 FIXME ("stub!\n");
479 return TWRC_FAILURE;
482 /* DG_CONTROL/DAT_SETUPFILEXFER2/MSG_RESET */
483 TW_UINT16 GPHOTO2_SetupFileXfer2Reset (pTW_IDENTITY pOrigin,
484 TW_MEMREF pData)
486 FIXME ("stub!\n");
488 return TWRC_FAILURE;
491 /* DG_CONTROL/DAT_SETUPFILEXFER2/MSG_SET */
492 TW_UINT16 GPHOTO2_SetupFileXfer2Set (pTW_IDENTITY pOrigin,
493 TW_MEMREF pData)
495 FIXME ("stub!\n");
497 return TWRC_FAILURE;
500 /* DG_CONTROL/DAT_SETUPMEMXFER/MSG_GET */
501 TW_UINT16 GPHOTO2_SetupMemXferGet (pTW_IDENTITY pOrigin,
502 TW_MEMREF pData)
504 pTW_SETUPMEMXFER pSetupMemXfer = (pTW_SETUPMEMXFER)pData;
506 TRACE("DG_CONTROL/DAT_SETUPMEMXFER/MSG_GET\n");
507 /* Guessing */
508 pSetupMemXfer->MinBufSize = 20000;
509 pSetupMemXfer->MaxBufSize = 80000;
510 pSetupMemXfer->Preferred = 40000;
511 return TWRC_SUCCESS;
514 /* DG_CONTROL/DAT_STATUS/MSG_GET */
515 TW_UINT16 GPHOTO2_GetDSStatus (pTW_IDENTITY pOrigin,
516 TW_MEMREF pData)
518 pTW_STATUS pSourceStatus = (pTW_STATUS) pData;
520 TRACE ("DG_CONTROL/DAT_STATUS/MSG_GET\n");
521 pSourceStatus->ConditionCode = activeDS.twCC;
522 /* Reset the condition code */
523 activeDS.twCC = TWCC_SUCCESS;
524 return TWRC_SUCCESS;
527 /* DG_CONTROL/DAT_USERINTERFACE/MSG_DISABLEDS */
528 TW_UINT16 GPHOTO2_DisableDSUserInterface (pTW_IDENTITY pOrigin,
529 TW_MEMREF pData)
531 TRACE ("DG_CONTROL/DAT_USERINTERFACE/MSG_DISABLEDS\n");
533 if (activeDS.currentState != 5) {
534 activeDS.twCC = TWCC_SEQERROR;
535 return TWRC_FAILURE;
537 activeDS.currentState = 4;
538 activeDS.twCC = TWCC_SUCCESS;
539 return TWRC_SUCCESS;
542 /* DG_CONTROL/DAT_USERINTERFACE/MSG_ENABLEDS */
543 TW_UINT16 GPHOTO2_EnableDSUserInterface (pTW_IDENTITY pOrigin,
544 TW_MEMREF pData)
546 pTW_USERINTERFACE pUserInterface = (pTW_USERINTERFACE) pData;
548 load_filesystem("/");
550 TRACE ("DG_CONTROL/DAT_USERINTERFACE/MSG_ENABLEDS\n");
551 if (activeDS.currentState != 4) {
552 FIXME("Sequence error %d\n", activeDS.currentState);
553 activeDS.twCC = TWCC_SEQERROR;
554 return TWRC_FAILURE;
556 activeDS.hwndOwner = pUserInterface->hParent;
557 if (pUserInterface->ShowUI)
559 BOOL rc;
560 activeDS.currentState = 5; /* Transitions to state 5 */
561 rc = DoCameraUI();
562 if (!rc) {
563 activeDS.pendingEvent.TWMessage = MSG_CLOSEDSREQ;
564 } else {
565 /* FIXME: The GUI should have marked the files to download... */
566 activeDS.pendingEvent.TWMessage = MSG_XFERREADY;
567 activeDS.currentState = 6; /* Transitions to state 6 directly */
569 } else {
570 /* no UI will be displayed, so source is ready to transfer data */
571 activeDS.pendingEvent.TWMessage = MSG_XFERREADY;
572 activeDS.currentState = 6; /* Transitions to state 6 directly */
574 activeDS.hwndOwner = pUserInterface->hParent;
575 activeDS.twCC = TWCC_SUCCESS;
576 return TWRC_SUCCESS;
579 /* DG_CONTROL/DAT_USERINTERFACE/MSG_ENABLEDSUIONLY */
580 TW_UINT16 GPHOTO2_EnableDSUIOnly (pTW_IDENTITY pOrigin,
581 TW_MEMREF pData)
583 TRACE("DG_CONTROL/DAT_USERINTERFACE/MSG_ENABLEDSUIONLY\n");
585 if (activeDS.currentState != 4) {
586 activeDS.twCC = TWCC_SEQERROR;
587 return TWRC_FAILURE;
589 /* FIXME: we should replace xscanimage with our own UI */
590 FIXME ("not implemented!\n");
591 activeDS.currentState = 5;
592 activeDS.twCC = TWCC_SUCCESS;
593 return TWRC_SUCCESS;
596 /* DG_CONTROL/DAT_XFERGROUP/MSG_GET */
597 TW_UINT16 GPHOTO2_XferGroupGet (pTW_IDENTITY pOrigin,
598 TW_MEMREF pData)
600 FIXME ("stub!\n");
601 return TWRC_FAILURE;
604 /* DG_CONTROL/DAT_XFERGROUP/MSG_SET */
605 TW_UINT16 GPHOTO2_XferGroupSet (pTW_IDENTITY pOrigin,
606 TW_MEMREF pData)
608 FIXME ("stub!\n");
609 return TWRC_FAILURE;