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