xref: /reactos/dll/win32/twain_32/twain32_main.c (revision d5399189)
1 /*
2  * TWAIN32 functions
3  *
4  * Copyright 2000 Shi Quan He <shiquan@cyberdude.com>
5  * Copyright 2006 Marcus Meissner
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with this library; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
20  */
21 
22 #include "config.h"
23 
24 #include <stdarg.h>
25 
26 #include "windef.h"
27 #include "winbase.h"
28 #include "twain.h"
29 #include "twain_i.h"
30 #include "wine/debug.h"
31 
32 WINE_DEFAULT_DEBUG_CHANNEL(twain);
33 
34 extern HINSTANCE DSM_hinstance;
35 
36 BOOL WINAPI DllMain (HINSTANCE hinstance, DWORD reason, LPVOID reserved)
37 {
38     TRACE("%p,%x,%p\n", hinstance, reason, reserved);
39 
40     switch (reason)
41     {
42         case DLL_PROCESS_ATTACH:
43             DisableThreadLibraryCalls(hinstance);
44             DSM_hinstance = hinstance;
45             break;
46         case DLL_PROCESS_DETACH:
47             break;
48     }
49     return TRUE;
50 }
51 
52 /* A helper function that looks up a destination identity in the active
53    source list */
54 static activeDS *TWAIN_LookupSource (const TW_IDENTITY *pDest)
55 {
56     activeDS *pSource;
57 
58     for (pSource = activeSources; pSource; pSource = pSource->next)
59         if (pSource->identity.Id == pDest->Id)
60             break;
61     return pSource;
62 }
63 
64 static TW_UINT16 TWAIN_SourceManagerHandler (
65            pTW_IDENTITY pOrigin,
66            TW_UINT16   DAT,
67            TW_UINT16   MSG,
68            TW_MEMREF   pData)
69 {
70     TW_UINT16 twRC = TWRC_SUCCESS;
71 
72     switch (DAT)
73     {
74         case DAT_IDENTITY:
75             switch (MSG)
76             {
77                 case MSG_CLOSEDS:
78                     twRC = TWAIN_CloseDS (pOrigin, pData);
79                     break;
80 
81                 case MSG_GETDEFAULT:
82                     twRC = TWAIN_IdentityGetDefault (pOrigin, pData);
83                     break;
84 
85                 case MSG_GETFIRST:
86                     twRC = TWAIN_IdentityGetFirst (pOrigin, pData);
87                     break;
88 
89                 case MSG_GETNEXT:
90                     twRC = TWAIN_IdentityGetNext (pOrigin, pData);
91                     break;
92 
93                 case MSG_OPENDS:
94                     twRC = TWAIN_OpenDS (pOrigin, pData);
95                     break;
96 
97                 case MSG_USERSELECT:
98                     twRC = TWAIN_UserSelect (pOrigin, pData);
99                     break;
100 
101                 default:
102                     /* Unrecognized operation triplet */
103                     twRC = TWRC_FAILURE;
104                     DSM_twCC = TWCC_BADPROTOCOL;
105                     WARN("unrecognized operation triplet\n");
106                     break;
107             }
108             break;
109 
110         case DAT_PARENT:
111             switch (MSG)
112             {
113                 case MSG_CLOSEDSM:
114                     twRC = TWAIN_CloseDSM (pOrigin, pData);
115                     break;
116 
117                 case MSG_OPENDSM:
118                     twRC = TWAIN_OpenDSM (pOrigin, pData);
119                     break;
120 
121                 default:
122                     /* Unrecognized operation triplet */
123                     twRC = TWRC_FAILURE;
124                     DSM_twCC = TWCC_BADPROTOCOL;
125                     WARN("unrecognized operation triplet\n");
126             }
127             break;
128 
129         case DAT_STATUS:
130             if (MSG == MSG_GET) {
131                 twRC = TWAIN_GetDSMStatus (pOrigin, pData);
132             } else {
133                 twRC = TWRC_FAILURE;
134                 DSM_twCC = TWCC_BADPROTOCOL;
135                 WARN("unrecognized operation triplet\n");
136             }
137             break;
138 
139         default:
140             twRC = TWRC_FAILURE;
141             DSM_twCC = TWCC_BADPROTOCOL;
142             WARN("unrecognized operation triplet\n");
143             break;
144     }
145 
146     return twRC;
147 }
148 
149 
150 /* Main entry point for the TWAIN library */
151 TW_UINT16 WINAPI
152 DSM_Entry (pTW_IDENTITY pOrigin,
153            pTW_IDENTITY pDest,
154            TW_UINT32    DG,
155            TW_UINT16    DAT,
156            TW_UINT16    MSG,
157            TW_MEMREF    pData)
158 {
159     TW_UINT16 twRC = TWRC_SUCCESS;  /* Return Code */
160 
161     TRACE("(DG=%d DAT=%d MSG=%d)\n", DG, DAT, MSG);
162 
163     if (DG == DG_CONTROL && DAT == DAT_NULL)
164     {
165         activeDS *pSource = TWAIN_LookupSource (pOrigin);
166         if (!pSource)
167         {
168             ERR("No source associated with pSource %p\n", pDest);
169             DSM_twCC = TWCC_BADPROTOCOL;
170             return TWRC_FAILURE;
171         }
172 
173         return TWAIN_ControlNull (pOrigin, pDest, pSource, MSG, pData);
174     }
175 
176     if (pDest)
177     {
178         activeDS *pSource = TWAIN_LookupSource (pDest);
179 	/* This operation's destination is a source */
180 
181         if (!pSource) {
182 	    ERR("No source associated with pDest %p\n", pDest);
183 	    DSM_twCC = TWCC_BADDEST;
184 	    return TWRC_FAILURE;
185 	}
186 
187         if (DG == DG_CONTROL && DAT == DAT_EVENT && MSG == MSG_PROCESSEVENT)
188         {
189             twRC = TWAIN_ProcessEvent(pOrigin, pSource, pData);
190             if (twRC == TWRC_DSEVENT)
191                 return twRC;
192         }
193 
194         if (DG == DG_CONTROL && DAT == DAT_USERINTERFACE &&
195             (MSG == MSG_ENABLEDS || MSG == MSG_ENABLEDSUIONLY) &&
196             pData != NULL)
197         {
198             pSource->ui_window = ((TW_USERINTERFACE*)pData)->hParent;
199         }
200 
201 	DSM_twCC = TWCC_SUCCESS;
202         TRACE("Forwarding %d/%d/%d/%p to DS.\n", DG, DAT, MSG, pData);
203 	twRC = pSource->dsEntry(pOrigin, DG, DAT, MSG, pData);
204 	TRACE("return value is %d\n", twRC);
205 	return twRC;
206     }
207     switch (DG)
208     {
209         case DG_CONTROL:
210             twRC = TWAIN_SourceManagerHandler (pOrigin, DAT, MSG, pData);
211             break;
212         default:
213             FIXME("The DSM does not handle DG %d\n", DG);
214             DSM_twCC = TWCC_BADPROTOCOL;
215             twRC = TWRC_FAILURE;
216     }
217     return twRC;
218 }
219