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_head( &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
,