016680b96eb8a81f4d5e1f1d1dc5ba10a9075e45
[reactos.git] / dll / win32 / twain_32 / twain32_main.c
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 }