Authors: Rob Shearman <rob@codeweavers.com>, Mike Hearn <mh@codeweavers.com>
[wine] / dlls / twain / twain32_main.c
1 /*
2  * TWAIN32 functions
3  *
4  * Copyright 2000 Shi Quan He <shiquan@cyberdude.com>
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19  */
20
21 #include "config.h"
22
23 #include <stdarg.h>
24
25 #include "windef.h"
26 #include "winbase.h"
27 #include "twain.h"
28 #include "twain_i.h"
29 #include "wine/debug.h"
30
31 WINE_DEFAULT_DEBUG_CHANNEL(twain);
32
33 BOOL WINAPI DllMain (HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
34 {
35     TRACE("%p,%lx,%p\n", hinstDLL, fdwReason, lpvReserved);
36
37     switch (fdwReason)
38     {
39         case DLL_PROCESS_ATTACH:
40             DisableThreadLibraryCalls(hinstDLL);
41             DSM_currentState = 2;
42             break;
43
44         case DLL_PROCESS_DETACH:
45             DSM_currentState = 1;
46             break;
47     }
48
49     return TRUE;
50 }
51
52 TW_UINT16 TWAIN_SourceManagerHandler (
53            pTW_IDENTITY pOrigin,
54            TW_UINT16   DAT,
55            TW_UINT16   MSG,
56            TW_MEMREF   pData)
57 {
58     TW_UINT16 twRC = TWRC_SUCCESS;
59
60     switch (DAT)
61     {
62         case DAT_IDENTITY:
63             switch (MSG)
64             {
65                 case MSG_CLOSEDS:
66                     twRC = TWAIN_CloseDS (pOrigin, pData);
67                     break;
68
69                 case MSG_GETDEFAULT:
70                     twRC = TWAIN_IdentityGetDefault (pOrigin, pData);
71                     break;
72
73                 case MSG_GETFIRST:
74                     twRC = TWAIN_IdentityGetFirst (pOrigin, pData);
75                     break;
76
77                 case MSG_GETNEXT:
78                     twRC = TWAIN_IdentityGetNext (pOrigin, pData);
79                     break;
80
81                 case MSG_OPENDS:
82                     twRC = TWAIN_OpenDS (pOrigin, pData);
83                     break;
84
85                 case MSG_USERSELECT:
86                     twRC = TWAIN_UserSelect (pOrigin, pData);
87                     break;
88
89                 default:
90                     /* Unrecognized operation triplet */
91                     twRC = TWRC_FAILURE;
92                     DSM_twCC = TWCC_BADPROTOCOL;
93                     WARN("unrecognized operation triplet\n");
94                     break;
95             }
96             break;
97
98         case DAT_PARENT:
99             switch (MSG)
100             {
101                 case MSG_CLOSEDSM:
102                     twRC = TWAIN_CloseDSM (pOrigin, pData);
103                     break;
104
105                 case MSG_OPENDSM:
106                     twRC = TWAIN_OpenDSM (pOrigin, pData);
107                     break;
108
109                 default:
110                     /* Unrecognized operation triplet */
111                     twRC = TWRC_FAILURE;
112                     DSM_twCC = TWCC_BADPROTOCOL;
113                     WARN("unrecognized operation triplet\n");
114             }
115             break;
116
117         case DAT_STATUS:
118             if (MSG == MSG_GET)
119             {
120                 twRC = TWAIN_GetDSMStatus (pOrigin, pData);
121             }
122             else
123             {
124                 twRC = TWRC_FAILURE;
125                 DSM_twCC = TWCC_BADPROTOCOL;
126                 WARN("unrecognized operation triplet\n");
127             }
128             break;
129
130         default:
131             twRC = TWRC_FAILURE;
132             DSM_twCC = TWCC_BADPROTOCOL;
133             WARN("unrecognized operation triplet\n");
134             break;
135     }
136
137     return twRC;
138 }
139
140 TW_UINT16 TWAIN_SourceControlHandler (
141            pTW_IDENTITY pOrigin,
142            pTW_IDENTITY pDest,
143            TW_UINT16    DAT,
144            TW_UINT16    MSG,
145            TW_MEMREF    pData)
146 {
147     TW_UINT16 twRC = TWRC_SUCCESS;
148
149     switch (DAT)
150     {
151         case DAT_CAPABILITY:
152             switch (MSG)
153             {
154                 case MSG_GET:
155                     twRC = TWAIN_CapabilityGet (pOrigin, pDest, pData);
156                     break;
157                 case MSG_GETCURRENT:
158                     twRC = TWAIN_CapabilityGetCurrent (pOrigin, pDest, pData);
159                     break;
160                 case MSG_GETDEFAULT:
161                     twRC = TWAIN_CapabilityGetDefault (pOrigin, pDest, pData);
162                     break;
163                 case MSG_QUERYSUPPORT:
164                     twRC = TWAIN_CapabilityQuerySupport (pOrigin, pDest, pData);
165                     break;
166                 case MSG_RESET:
167                     twRC = TWAIN_CapabilityReset (pOrigin, pDest, pData);
168                     break;
169                 case MSG_SET:
170                     twRC = TWAIN_CapabilitySet (pOrigin, pDest, pData);
171                     break;
172                 default:
173                     twRC = TWRC_FAILURE;
174                     WARN("unrecognized opertion triplet\n");
175             }
176             break;
177
178         case DAT_CUSTOMDSDATA:
179             switch (MSG)
180             {
181                 case MSG_GET:
182                     twRC = TWAIN_CustomDSDataGet (pOrigin, pDest, pData);
183                     break;
184                 case MSG_SET:
185                     twRC = TWAIN_CustomDSDataSet (pOrigin, pDest, pData);
186                     break;
187                 default:
188                     break;
189             }
190             break;
191
192         case DAT_FILESYSTEM:
193             switch (MSG)
194             {
195                 /*case MSG_AUTOMATICCAPTUREDIRECTORY:
196                     twRC = TWAIN_AutomaticCaptureDirectory
197                                (pOrigin, pDest, pData);
198                     break;*/
199                 case MSG_CHANGEDIRECTORY:
200                     twRC = TWAIN_ChangeDirectory (pOrigin, pDest, pData);
201                     break;
202                 /*case MSG_COPY:
203                     twRC = TWAIN_FileSystemCopy (pOrigin, pDest, pData);
204                     break;*/
205                 case MSG_CREATEDIRECTORY:
206                     twRC = TWAIN_CreateDirectory (pOrigin, pDest, pData);
207                     break;
208                 case MSG_DELETE:
209                     twRC = TWAIN_FileSystemDelete (pOrigin, pDest, pData);
210                     break;
211                 case MSG_FORMATMEDIA:
212                     twRC = TWAIN_FormatMedia (pOrigin, pDest, pData);
213                     break;
214                 case MSG_GETCLOSE:
215                     twRC = TWAIN_FileSystemGetClose (pOrigin, pDest, pData);
216                     break;
217                 case MSG_GETFIRSTFILE:
218                     twRC = TWAIN_FileSystemGetFirstFile
219                                (pOrigin, pDest, pData);
220                     break;
221                 case MSG_GETINFO:
222                     twRC = TWAIN_FileSystemGetInfo (pOrigin, pDest, pData);
223                     break;
224                 case MSG_GETNEXTFILE:
225                     twRC = TWAIN_FileSystemGetNextFile
226                                (pOrigin, pDest, pData);
227                     break;
228                 case MSG_RENAME:
229                     twRC = TWAIN_FileSystemRename (pOrigin, pDest, pData);
230                     break;
231                 default:
232                     twRC = TWRC_FAILURE;
233                     break;
234             }
235             break;
236
237         case DAT_EVENT:
238             if (MSG == MSG_PROCESSEVENT)
239                 twRC = TWAIN_ProcessEvent (pOrigin, pDest, pData);
240             else
241                 twRC = TWRC_FAILURE;
242             break;
243
244         case DAT_PASSTHRU:
245             if (MSG == MSG_PASSTHRU)
246                 twRC = TWAIN_PassThrough (pOrigin, pDest, pData);
247             else
248                 twRC = TWRC_FAILURE;
249             break;
250
251         case DAT_PENDINGXFERS:
252             switch (MSG)
253             {
254                 case MSG_ENDXFER:
255                     twRC = TWAIN_PendingXfersEndXfer (pOrigin, pDest, pData);
256                     break;
257                 case MSG_GET:
258                     twRC = TWAIN_PendingXfersGet (pOrigin, pDest, pData);
259                     break;
260                 case MSG_RESET:
261                     twRC = TWAIN_PendingXfersReset (pOrigin, pDest, pData);
262                     break;
263                 /*case MSG_STOPFEEDER:
264                     twRC = TWAIN_PendingXfersStopFeeder
265                                (pOrigin, pDest, pData);
266                     break;*/
267                 default:
268                     twRC = TWRC_FAILURE;
269             }
270             break;
271
272         case DAT_SETUPFILEXFER:
273             switch (MSG)
274             {
275                 case MSG_GET:
276                     twRC = TWAIN_SetupFileXferGet (pOrigin, pDest, pData);
277                     break;
278                 case MSG_GETDEFAULT:
279                     twRC = TWAIN_SetupFileXferGetDefault
280                                (pOrigin, pDest, pData);
281                     break;
282                 case MSG_RESET:
283                     twRC = TWAIN_SetupFileXferReset (pOrigin, pDest, pData);
284                     break;
285                 case MSG_SET:
286                     twRC = TWAIN_SetupFileXferSet (pOrigin, pDest, pData);
287                     break;
288                 default:
289                     twRC = TWRC_FAILURE;
290                     break;
291             }
292             break;
293
294         /*case DAT_SETUPFILEXFER2:
295             switch (MSG)
296             {
297                 case MSG_GET:
298                     twRC = TWAIN_SetupFileXfer2Get (pOrigin, pDest, pData);
299                     break;
300                 case MSG_GETDEFAULT:
301                     twRC = TWAIN_SetupFileXfer2GetDefault
302                                (pOrigin, pDest, pData);
303                     break;
304                 case MSG_RESET:
305                     twRC = TWAIN_SetupFileXfer2Reset (pOrigin, pDest, pData);
306                     break;
307                 case MSG_SET:
308                     twRC = TWAIN_SetupFileXfer2Set (pOrigin, pDest, pData);
309                     break;
310             }
311             break;*/
312         case DAT_SETUPMEMXFER:
313             if (MSG == MSG_GET)
314                 twRC = TWAIN_SetupMemXferGet (pOrigin, pDest, pData);
315             else
316                 twRC = TWRC_FAILURE;
317             break;
318
319         case DAT_STATUS:
320             if (MSG == MSG_GET)
321                 twRC = TWAIN_GetDSStatus (pOrigin, pDest, pData);
322             else
323                 twRC = TWRC_FAILURE;
324             break;
325
326         case DAT_USERINTERFACE:
327             switch (MSG)
328             {
329                 case MSG_DISABLEDS:
330                     twRC = TWAIN_DisableDSUserInterface
331                                (pOrigin, pDest, pData);
332                     break;
333                 case MSG_ENABLEDS:
334                     twRC = TWAIN_EnableDSUserInterface
335                                (pOrigin, pDest, pData);
336                     break;
337                 case MSG_ENABLEDSUIONLY:
338                     twRC = TWAIN_EnableDSUIOnly (pOrigin, pDest, pData);
339                     break;
340                 default:
341                     twRC = TWRC_FAILURE;
342                     break;
343             }
344             break;
345
346         case DAT_XFERGROUP:
347             switch (MSG)
348             {
349                 case MSG_GET:
350                     twRC = TWAIN_XferGroupGet (pOrigin, pDest, pData);
351                     break;
352                 case MSG_SET:
353                     twRC = TWAIN_XferGroupSet (pOrigin, pDest, pData);
354                     break;
355                 default:
356                     twRC = TWRC_FAILURE;
357                     break;
358             }
359             break;
360
361         default:
362             twRC = TWRC_FAILURE;
363             break;
364     }
365
366     return twRC;
367 }
368
369 TW_UINT16 TWAIN_ControlGroupHandler (
370            pTW_IDENTITY pOrigin,
371            pTW_IDENTITY pDest,
372            TW_UINT16    DAT,
373            TW_UINT16    MSG,
374            TW_MEMREF    pData)
375 {
376     TW_UINT16 twRC = TWRC_SUCCESS;
377
378     if (pDest)
379     {
380         /* This operation's destination is a source */
381         twRC = TWAIN_SourceControlHandler (pOrigin, pDest, DAT, MSG, pData);
382     }
383     else
384     {
385         /* This operation's destination is the Source Manager */
386         twRC = TWAIN_SourceManagerHandler (pOrigin, DAT, MSG, pData);
387     }
388
389     return twRC;
390 }
391
392 TW_UINT16 TWAIN_ImageGroupHandler (
393            pTW_IDENTITY pOrigin,
394            pTW_IDENTITY pDest,
395            TW_UINT16    DAT,
396            TW_UINT16    MSG,
397            TW_MEMREF    pData)
398 {
399     TW_UINT16 twRC = TWRC_SUCCESS;
400
401     if (pDest == NULL)
402     {
403         DSM_twCC = TWCC_BADDEST;
404         return TWRC_FAILURE;
405     }
406
407     switch (DAT)
408     {
409         case DAT_CIECOLOR:
410             if (MSG == MSG_GET)
411                 twRC = TWAIN_CIEColorGet (pOrigin, pDest, pData);
412             else
413                 twRC = TWRC_FAILURE;
414             break;
415
416         case DAT_EXTIMAGEINFO:
417             if (MSG == MSG_GET)
418                 twRC = TWAIN_ExtImageInfoGet (pOrigin, pDest, pData);
419             else
420                 twRC = TWRC_FAILURE;
421             break;
422
423         case DAT_GRAYRESPONSE:
424             switch (MSG)
425             {
426                 case MSG_RESET:
427                     twRC = TWAIN_GrayResponseReset (pOrigin, pDest, pData);
428                     break;
429                 case MSG_SET:
430                     twRC = TWAIN_GrayResponseSet (pOrigin, pDest, pData);
431                     break;
432                 default:
433                     twRC = TWRC_FAILURE;
434                     DSM_twCC = TWCC_BADPROTOCOL;
435                     WARN("unrecognized operation triplet\n");
436                     break;
437             }
438             break;
439         case DAT_IMAGEFILEXFER:
440             if (MSG == MSG_GET)
441                 twRC = TWAIN_ImageFileXferGet (pOrigin, pDest, pData);
442             else
443                 twRC = TWRC_FAILURE;
444             break;
445
446         case DAT_IMAGEINFO:
447             if (MSG == MSG_GET)
448                 twRC = TWAIN_ImageInfoGet (pOrigin, pDest, pData);
449             else
450                 twRC = TWRC_FAILURE;
451             break;
452
453         case DAT_IMAGELAYOUT:
454             switch (MSG)
455             {
456                 case MSG_GET:
457                     twRC = TWAIN_ImageLayoutGet (pOrigin, pDest, pData);
458                     break;
459                 case MSG_GETDEFAULT:
460                     twRC = TWAIN_ImageLayoutGetDefault (pOrigin, pDest, pData);
461                     break;
462                 case MSG_RESET:
463                     twRC = TWAIN_ImageLayoutReset (pOrigin, pDest, pData);
464                     break;
465                 case MSG_SET:
466                     twRC = TWAIN_ImageLayoutSet (pOrigin, pDest, pData);
467                     break;
468                 default:
469                     twRC = TWRC_FAILURE;
470                     DSM_twCC = TWCC_BADPROTOCOL;
471                     WARN("unrecognized operation triplet\n");
472                     break;
473             }
474             break;
475
476         case DAT_IMAGEMEMXFER:
477             if (MSG == MSG_GET)
478                 twRC = TWAIN_ImageMemXferGet (pOrigin, pDest, pData);
479             else
480                 twRC = TWRC_FAILURE;
481             break;
482
483         case DAT_IMAGENATIVEXFER:
484             if (MSG == MSG_GET)
485                 twRC = TWAIN_ImageNativeXferGet (pOrigin, pDest, pData);
486             else
487                 twRC = TWRC_FAILURE;
488             break;
489
490         case DAT_JPEGCOMPRESSION:
491             switch (MSG)
492             {
493                 case MSG_GET:
494                     twRC = TWAIN_JPEGCompressionGet (pOrigin, pDest, pData);
495                     break;
496                 case MSG_GETDEFAULT:
497                     twRC = TWAIN_JPEGCompressionGetDefault
498                                (pOrigin, pDest, pData);
499                     break;
500                 case MSG_RESET:
501                     twRC = TWAIN_JPEGCompressionReset (pOrigin, pDest, pData);
502                     break;
503                 case MSG_SET:
504                     twRC = TWAIN_JPEGCompressionSet (pOrigin, pDest, pData);
505                     break;
506                 default:
507                     twRC = TWRC_FAILURE;
508                     DSM_twCC = TWCC_BADPROTOCOL;
509                     WARN("unrecognized operation triplet\n");
510                     break;
511             }
512             break;
513
514         case DAT_PALETTE8:
515             switch (MSG)
516             {
517                 case MSG_GET:
518                     twRC = TWAIN_Palette8Get (pOrigin, pDest, pData);
519                     break;
520                 case MSG_GETDEFAULT:
521                     twRC = TWAIN_Palette8GetDefault (pOrigin, pDest, pData);
522                     break;
523                 case MSG_RESET:
524                     twRC = TWAIN_Palette8Reset (pOrigin, pDest, pData);
525                     break;
526                 case MSG_SET:
527                     twRC = TWAIN_Palette8Set (pOrigin, pDest, pData);
528                     break;
529                 default:
530                     twRC = TWRC_FAILURE;
531                     DSM_twCC = TWCC_BADPROTOCOL;
532                     WARN("unrecognized operation triplet\n");
533             }
534             break;
535
536         case DAT_RGBRESPONSE:
537             switch (MSG)
538             {
539                 case MSG_RESET:
540                     twRC = TWAIN_RGBResponseReset (pOrigin, pDest, pData);
541                     break;
542                 case MSG_SET:
543                     twRC = TWAIN_RGBResponseSet (pOrigin, pDest, pData);
544                     break;
545                 default:
546                     twRC = TWRC_FAILURE;
547                     DSM_twCC = TWCC_BADPROTOCOL;
548                     WARN("unrecognized operation triplet\n");
549                     break;
550             }
551             break;
552
553         default:
554             twRC = TWRC_FAILURE;
555             DSM_twCC = TWCC_BADPROTOCOL;
556             WARN("unrecognized operation triplet\n");
557     }
558     return twRC;
559 }
560
561 TW_UINT16 TWAIN_AudioGroupHandler (
562            pTW_IDENTITY pOrigin,
563            pTW_IDENTITY pDest,
564            TW_UINT16    DAT,
565            TW_UINT16    MSG,
566            TW_MEMREF    pData)
567 {
568     TW_UINT16 twRC = TWRC_FAILURE;
569
570     switch (DAT)
571     {
572         case DAT_AUDIOFILEXFER:
573             if (MSG == MSG_GET)
574                 twRC = TWAIN_AudioFileXferGet (pOrigin, pDest, pData);
575             break;
576
577         case DAT_AUDIOINFO:
578             if (MSG == MSG_GET)
579                 twRC = TWAIN_AudioInfoGet (pOrigin, pDest, pData);
580             break;
581
582         case DAT_AUDIONATIVEXFER:
583             if (MSG == MSG_GET)
584                 twRC = TWAIN_AudioNativeXferGet (pOrigin, pDest, pData);
585             break;
586
587         default:
588             DSM_twCC = TWCC_BADPROTOCOL;
589             twRC = TWRC_FAILURE;
590             break;
591     }
592
593     return twRC;
594 }
595
596 /* Main entry point for the TWAIN library */
597 TW_UINT16 WINAPI
598 DSM_Entry (pTW_IDENTITY pOrigin,
599            pTW_IDENTITY pDest,
600            TW_UINT32    DG,
601            TW_UINT16    DAT,
602            TW_UINT16    MSG,
603            TW_MEMREF    pData)
604 {
605     TW_UINT16 twRC = TWRC_SUCCESS;  /* Return Code */
606
607     TRACE("(DG=%ld DAT=%d MSG=%d)\n", DG, DAT, MSG);
608
609     switch (DG)
610     {
611         case DG_CONTROL:
612             twRC = TWAIN_ControlGroupHandler (pOrigin,pDest,DAT,MSG,pData);
613             break;
614         case DG_IMAGE:
615             twRC = TWAIN_ImageGroupHandler (pOrigin,pDest,DAT,MSG,pData);
616             break;
617         case DG_AUDIO:
618             twRC = TWAIN_AudioGroupHandler (pOrigin,pDest,DAT,MSG,pData);
619             break;
620         default:
621             DSM_twCC = TWCC_BADPROTOCOL;
622             twRC = TWRC_FAILURE;
623     }
624
625     return twRC;
626 }
627
628 /* A helper function that looks up a destination identity in the active
629    source list */
630 activeDS *TWAIN_LookupSource (pTW_IDENTITY pDest)
631 {
632     activeDS *pSource;
633
634     for (pSource = activeSources; pSource; pSource = pSource->next)
635         if (pSource->identity.Id == pDest->Id)
636             break;
637
638     return pSource;
639 }