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
28 #include "gphoto2_i.h"
29 #include "wine/debug.h"
31 WINE_DEFAULT_DEBUG_CHANNEL(twain);
34 load_filesystem(const char *folder) {
39 ret = gp_list_new (&list);
42 ret = gp_camera_folder_list_files (activeDS.camera, folder, list, activeDS.context);
47 count = gp_list_count (list);
52 for (i = 0; i < count; i++) {
54 struct gphoto2_file *gpfile;
56 ret = gp_list_get_name (list, i, &name);
59 gpfile = malloc(sizeof(struct gphoto2_file));
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 );
70 ret = gp_camera_folder_list_folders (activeDS.camera, folder, list, activeDS.context);
72 FIXME("list_folders failed\n");
76 count = gp_list_count (list);
78 FIXME("list_folders failed\n");
82 for (i = 0; i < count; i++) {
85 ret = gp_list_get_name (list, i, &name);
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);
93 sprintf (newfolder, "%s/%s", folder, name);
94 load_filesystem (newfolder); /* recurse ... happily */
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;
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;
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;
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,
152 /* DG_CONTROL/DAT_CAPABILITY/MSG_RESET */
153 TW_UINT16 GPHOTO2_CapabilityReset (pTW_IDENTITY pOrigin,
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;
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,
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;
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,
193 /* DG_CONTROL/DAT_CUSTOMDSDATA/MSG_SET */
194 TW_UINT16 GPHOTO2_CustomDSDataSet (pTW_IDENTITY pOrigin,
202 /* DG_CONTROL/DAT_FILESYSTEM/MSG_AUTOMATICCAPTUREDIRECTORY */
203 TW_UINT16 GPHOTO2_AutomaticCaptureDirectory (pTW_IDENTITY pOrigin,
212 /* DG_CONTROL/DAT_FILESYSTEM/MSG_CHANGEDIRECTORY */
213 TW_UINT16 GPHOTO2_ChangeDirectory (pTW_IDENTITY pOrigin,
221 /* DG_CONTROL/DAT_FILESYSTEM/MSG_COPY */
222 TW_UINT16 GPHOTO2_FileSystemCopy (pTW_IDENTITY pOrigin,
230 /* DG_CONTROL/DAT_FILESYSTEM/MSG_CREATEDIRECTORY */
231 TW_UINT16 GPHOTO2_CreateDirectory (pTW_IDENTITY pOrigin,
239 /* DG_CONTROL/DAT_FILESYSTEM/MSG_DELETE */
240 TW_UINT16 GPHOTO2_FileSystemDelete (pTW_IDENTITY pOrigin,
248 /* DG_CONTROL/DAT_FILESYSTEM/MSG_FORMATMEDIA */
249 TW_UINT16 GPHOTO2_FormatMedia (pTW_IDENTITY pOrigin,
257 /* DG_CONTROL/DAT_FILESYSTEM/MSG_GETCLOSE */
258 TW_UINT16 GPHOTO2_FileSystemGetClose (pTW_IDENTITY pOrigin,
266 /* DG_CONTROL/DAT_FILESYSTEM/MSG_GETFIRSTFILE */
267 TW_UINT16 GPHOTO2_FileSystemGetFirstFile (pTW_IDENTITY pOrigin,
276 /* DG_CONTROL/DAT_FILESYSTEM/MSG_GETINFO */
277 TW_UINT16 GPHOTO2_FileSystemGetInfo (pTW_IDENTITY pOrigin,
285 /* DG_CONTROL/DAT_FILESYSTEM/MSG_GETNEXTFILE */
286 TW_UINT16 GPHOTO2_FileSystemGetNextFile (pTW_IDENTITY pOrigin,
295 /* DG_CONTROL/DAT_FILESYSTEM/MSG_RENAME */
296 TW_UINT16 GPHOTO2_FileSystemRename (pTW_IDENTITY pOrigin,
304 /* DG_CONTROL/DAT_EVENT/MSG_PROCESSEVENT */
305 TW_UINT16 GPHOTO2_ProcessEvent (pTW_IDENTITY pOrigin,
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;
318 if (activeDS.pendingEvent.TWMessage != MSG_NULL) {
319 pEvent->TWMessage = activeDS.pendingEvent.TWMessage;
320 activeDS.pendingEvent.TWMessage = MSG_NULL;
323 pEvent->TWMessage = MSG_NULL; /* no message to the application */
324 twRC = TWRC_NOTDSEVENT;
326 activeDS.twCC = TWCC_SUCCESS;
330 /* DG_CONTROL/DAT_PASSTHRU/MSG_PASSTHRU */
331 TW_UINT16 GPHOTO2_PassThrough (pTW_IDENTITY pOrigin,
339 /* DG_CONTROL/DAT_PENDINGXFERS/MSG_ENDXFER */
340 TW_UINT16 GPHOTO2_PendingXfersEndXfer (pTW_IDENTITY pOrigin,
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;
354 LIST_FOR_EACH_ENTRY( file, &activeDS.files, struct gphoto2_file, entry ) {
358 TRACE("count = %ld\n", count);
359 pPendingXfers->Count = count;
360 if (pPendingXfers->Count != 0) {
361 activeDS.currentState = 6;
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;
374 /* DG_CONTROL/DAT_PENDINGXFERS/MSG_GET */
375 TW_UINT16 GPHOTO2_PendingXfersGet (pTW_IDENTITY pOrigin,
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;
390 LIST_FOR_EACH_ENTRY( file, &activeDS.files, struct gphoto2_file, entry ) {
394 TRACE("count = %ld\n", count);
395 pPendingXfers->Count = count;
396 activeDS.twCC = TWCC_SUCCESS;
400 /* DG_CONTROL/DAT_PENDINGXFERS/MSG_RESET */
401 TW_UINT16 GPHOTO2_PendingXfersReset (pTW_IDENTITY pOrigin,
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;
412 pPendingXfers->Count = 0;
413 activeDS.currentState = 5;
414 activeDS.twCC = TWCC_SUCCESS;
418 /* DG_CONTROL/DAT_PENDINGXFERS/MSG_STOPFEEDER */
419 TW_UINT16 GPHOTO2_PendingXfersStopFeeder (pTW_IDENTITY pOrigin,
427 /* DG_CONTROL/DAT_SETUPFILEXFER/MSG_GET */
428 TW_UINT16 GPHOTO2_SetupFileXferGet (pTW_IDENTITY pOrigin,
436 /* DG_CONTROL/DAT_SETUPXFER/MSG_GETDEFAULT */
437 TW_UINT16 GPHOTO2_SetupFileXferGetDefault (pTW_IDENTITY pOrigin,
446 /* DG_CONTROL/DAT_SETUPFILEXFER/MSG_RESET */
447 TW_UINT16 GPHOTO2_SetupFileXferReset (pTW_IDENTITY pOrigin,
455 /* DG_CONTROL/DAT_SETUPFILEXFER/MSG_SET */
456 TW_UINT16 GPHOTO2_SetupFileXferSet (pTW_IDENTITY pOrigin,
464 /* DG_CONTROL/DAT_SETUPFILEXFER2/MSG_GET */
465 TW_UINT16 GPHOTO2_SetupFileXfer2Get (pTW_IDENTITY pOrigin,
473 /* DG_CONTROL/DAT_SETUPFILEXFER2/MSG_GETDEFAULT */
474 TW_UINT16 GPHOTO2_SetupFileXfer2GetDefault (pTW_IDENTITY pOrigin,
482 /* DG_CONTROL/DAT_SETUPFILEXFER2/MSG_RESET */
483 TW_UINT16 GPHOTO2_SetupFileXfer2Reset (pTW_IDENTITY pOrigin,
491 /* DG_CONTROL/DAT_SETUPFILEXFER2/MSG_SET */
492 TW_UINT16 GPHOTO2_SetupFileXfer2Set (pTW_IDENTITY pOrigin,
500 /* DG_CONTROL/DAT_SETUPMEMXFER/MSG_GET */
501 TW_UINT16 GPHOTO2_SetupMemXferGet (pTW_IDENTITY pOrigin,
504 pTW_SETUPMEMXFER pSetupMemXfer = (pTW_SETUPMEMXFER)pData;
506 TRACE("DG_CONTROL/DAT_SETUPMEMXFER/MSG_GET\n");
508 pSetupMemXfer->MinBufSize = 20000;
509 pSetupMemXfer->MaxBufSize = 80000;
510 pSetupMemXfer->Preferred = 40000;
514 /* DG_CONTROL/DAT_STATUS/MSG_GET */
515 TW_UINT16 GPHOTO2_GetDSStatus (pTW_IDENTITY pOrigin,
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;
527 /* DG_CONTROL/DAT_USERINTERFACE/MSG_DISABLEDS */
528 TW_UINT16 GPHOTO2_DisableDSUserInterface (pTW_IDENTITY pOrigin,
531 TRACE ("DG_CONTROL/DAT_USERINTERFACE/MSG_DISABLEDS\n");
533 if (activeDS.currentState != 5) {
534 activeDS.twCC = TWCC_SEQERROR;
537 activeDS.currentState = 4;
538 activeDS.twCC = TWCC_SUCCESS;
542 /* DG_CONTROL/DAT_USERINTERFACE/MSG_ENABLEDS */
543 TW_UINT16 GPHOTO2_EnableDSUserInterface (pTW_IDENTITY pOrigin,
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;
556 activeDS.hwndOwner = pUserInterface->hParent;
557 if (pUserInterface->ShowUI)
560 activeDS.currentState = 5; /* Transitions to state 5 */
563 activeDS.pendingEvent.TWMessage = MSG_CLOSEDSREQ;
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 */
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;
579 /* DG_CONTROL/DAT_USERINTERFACE/MSG_ENABLEDSUIONLY */
580 TW_UINT16 GPHOTO2_EnableDSUIOnly (pTW_IDENTITY pOrigin,
583 TRACE("DG_CONTROL/DAT_USERINTERFACE/MSG_ENABLEDSUIONLY\n");
585 if (activeDS.currentState != 4) {
586 activeDS.twCC = TWCC_SEQERROR;
589 /* FIXME: we should replace xscanimage with our own UI */
590 FIXME ("not implemented!\n");
591 activeDS.currentState = 5;
592 activeDS.twCC = TWCC_SUCCESS;
596 /* DG_CONTROL/DAT_XFERGROUP/MSG_GET */
597 TW_UINT16 GPHOTO2_XferGroupGet (pTW_IDENTITY pOrigin,
604 /* DG_CONTROL/DAT_XFERGROUP/MSG_SET */
605 TW_UINT16 GPHOTO2_XferGroupSet (pTW_IDENTITY pOrigin,