[TWAIN_32] Sync with Wine Staging 4.18. CORE-16441
[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 <stdarg.h>
23
24 #include "windef.h"
25 #include "winbase.h"
26 #include "twain.h"
27 #include "twain_i.h"
28 #include "wine/debug.h"
29
30 WINE_DEFAULT_DEBUG_CHANNEL(twain);
31
32 extern HINSTANCE DSM_hinstance;
33
34 BOOL WINAPI DllMain (HINSTANCE hinstance, DWORD reason, LPVOID reserved)
35 {
36 TRACE("%p,%x,%p\n", hinstance, reason, reserved);
37
38 switch (reason)
39 {
40 case DLL_PROCESS_ATTACH:
41 DisableThreadLibraryCalls(hinstance);
42 DSM_hinstance = hinstance;
43 break;
44 case DLL_PROCESS_DETACH:
45 break;
46 }
47 return TRUE;
48 }
49
50 /* A helper function that looks up a destination identity in the active
51 source list */
52 static activeDS *TWAIN_LookupSource (const TW_IDENTITY *pDest)
53 {
54 activeDS *pSource;
55
56 for (pSource = activeSources; pSource; pSource = pSource->next)
57 if (pSource->identity.Id == pDest->Id)
58 break;
59 return pSource;
60 }
61
62 static TW_UINT16 TWAIN_SourceManagerHandler (
63 pTW_IDENTITY pOrigin,
64 TW_UINT16 DAT,
65 TW_UINT16 MSG,
66 TW_MEMREF pData)
67 {
68 TW_UINT16 twRC = TWRC_SUCCESS;
69
70 switch (DAT)
71 {
72 case DAT_IDENTITY:
73 switch (MSG)
74 {
75 case MSG_CLOSEDS:
76 twRC = TWAIN_CloseDS (pOrigin, pData);
77 break;
78
79 case MSG_GETDEFAULT:
80 twRC = TWAIN_IdentityGetDefault (pOrigin, pData);
81 break;
82
83 case MSG_GETFIRST:
84 twRC = TWAIN_IdentityGetFirst (pOrigin, pData);
85 break;
86
87 case MSG_GETNEXT:
88 twRC = TWAIN_IdentityGetNext (pOrigin, pData);
89 break;
90
91 case MSG_OPENDS:
92 twRC = TWAIN_OpenDS (pOrigin, pData);
93 break;
94
95 case MSG_USERSELECT:
96 twRC = TWAIN_UserSelect (pOrigin, pData);
97 break;
98
99 default:
100 /* Unrecognized operation triplet */
101 twRC = TWRC_FAILURE;
102 DSM_twCC = TWCC_BADPROTOCOL;
103 WARN("unrecognized operation triplet\n");
104 break;
105 }
106 break;
107
108 case DAT_PARENT:
109 switch (MSG)
110 {
111 case MSG_CLOSEDSM:
112 twRC = TWAIN_CloseDSM (pOrigin, pData);
113 break;
114
115 case MSG_OPENDSM:
116 twRC = TWAIN_OpenDSM (pOrigin, pData);
117 break;
118
119 default:
120 /* Unrecognized operation triplet */
121 twRC = TWRC_FAILURE;
122 DSM_twCC = TWCC_BADPROTOCOL;
123 WARN("unrecognized operation triplet\n");
124 }
125 break;
126
127 case DAT_STATUS:
128 if (MSG == MSG_GET) {
129 twRC = TWAIN_GetDSMStatus (pOrigin, pData);
130 } else {
131 twRC = TWRC_FAILURE;
132 DSM_twCC = TWCC_BADPROTOCOL;
133 WARN("unrecognized operation triplet\n");
134 }
135 break;
136
137 default:
138 twRC = TWRC_FAILURE;
139 DSM_twCC = TWCC_BADPROTOCOL;
140 WARN("unrecognized operation triplet\n");
141 break;
142 }
143
144 return twRC;
145 }
146
147
148 /* Main entry point for the TWAIN library */
149 TW_UINT16 WINAPI
150 DSM_Entry (pTW_IDENTITY pOrigin,
151 pTW_IDENTITY pDest,
152 TW_UINT32 DG,
153 TW_UINT16 DAT,
154 TW_UINT16 MSG,
155 TW_MEMREF pData)
156 {
157 TW_UINT16 twRC = TWRC_SUCCESS; /* Return Code */
158
159 TRACE("(DG=%d DAT=%d MSG=%d)\n", DG, DAT, MSG);
160
161 if (DG == DG_CONTROL && DAT == DAT_NULL)
162 {
163 activeDS *pSource = TWAIN_LookupSource (pOrigin);
164 if (!pSource)
165 {
166 ERR("No source associated with pSource %p\n", pDest);
167 DSM_twCC = TWCC_BADPROTOCOL;
168 return TWRC_FAILURE;
169 }
170
171 return TWAIN_ControlNull (pOrigin, pDest, pSource, MSG, pData);
172 }
173
174 if (pDest)
175 {
176 activeDS *pSource = TWAIN_LookupSource (pDest);
177 /* This operation's destination is a source */
178
179 if (!pSource) {
180 ERR("No source associated with pDest %p\n", pDest);
181 DSM_twCC = TWCC_BADDEST;
182 return TWRC_FAILURE;
183 }
184
185 if (DG == DG_CONTROL && DAT == DAT_EVENT && MSG == MSG_PROCESSEVENT)
186 {
187 twRC = TWAIN_ProcessEvent(pOrigin, pSource, pData);
188 if (twRC == TWRC_DSEVENT)
189 return twRC;
190 }
191
192 if (DG == DG_CONTROL && DAT == DAT_USERINTERFACE &&
193 (MSG == MSG_ENABLEDS || MSG == MSG_ENABLEDSUIONLY) &&
194 pData != NULL)
195 {
196 pSource->ui_window = ((TW_USERINTERFACE*)pData)->hParent;
197 }
198
199 DSM_twCC = TWCC_SUCCESS;
200 TRACE("Forwarding %d/%d/%d/%p to DS.\n", DG, DAT, MSG, pData);
201 twRC = pSource->dsEntry(pOrigin, DG, DAT, MSG, pData);
202 TRACE("return value is %d\n", twRC);
203 return twRC;
204 }
205 switch (DG)
206 {
207 case DG_CONTROL:
208 twRC = TWAIN_SourceManagerHandler (pOrigin, DAT, MSG, pData);
209 break;
210 default:
211 FIXME("The DSM does not handle DG %d\n", DG);
212 DSM_twCC = TWCC_BADPROTOCOL;
213 twRC = TWRC_FAILURE;
214 }
215 return twRC;
216 }