user32: Don't wait for other threads to process WM_NCDESTROY.
[wine.git] / dlls / twain_32 / twain32_main.c
blob016680b96eb8a81f4d5e1f1d1dc5ba10a9075e45
1 /*
2 * TWAIN32 functions
4 * Copyright 2000 Shi Quan He <shiquan@cyberdude.com>
5 * Copyright 2006 Marcus Meissner
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.
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.
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
22 #include "config.h"
24 #include <stdarg.h>
26 #include "windef.h"
27 #include "winbase.h"
28 #include "twain.h"
29 #include "twain_i.h"
30 #include "wine/debug.h"
32 WINE_DEFAULT_DEBUG_CHANNEL(twain);
34 extern HINSTANCE DSM_hinstance;
36 BOOL WINAPI DllMain (HINSTANCE hinstance, DWORD reason, LPVOID reserved)
38 TRACE("%p,%x,%p\n", hinstance, reason, reserved);
40 switch (reason)
42 case DLL_PROCESS_ATTACH:
43 DisableThreadLibraryCalls(hinstance);
44 DSM_hinstance = hinstance;
45 break;
46 case DLL_PROCESS_DETACH:
47 break;
49 return TRUE;
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)
56 activeDS *pSource;
58 for (pSource = activeSources; pSource; pSource = pSource->next)
59 if (pSource->identity.Id == pDest->Id)
60 break;
61 return pSource;
64 static TW_UINT16 TWAIN_SourceManagerHandler (
65 pTW_IDENTITY pOrigin,
66 TW_UINT16 DAT,
67 TW_UINT16 MSG,
68 TW_MEMREF pData)
70 TW_UINT16 twRC = TWRC_SUCCESS;
72 switch (DAT)
74 case DAT_IDENTITY:
75 switch (MSG)
77 case MSG_CLOSEDS:
78 twRC = TWAIN_CloseDS (pOrigin, pData);
79 break;
81 case MSG_GETDEFAULT:
82 twRC = TWAIN_IdentityGetDefault (pOrigin, pData);
83 break;
85 case MSG_GETFIRST:
86 twRC = TWAIN_IdentityGetFirst (pOrigin, pData);
87 break;
89 case MSG_GETNEXT:
90 twRC = TWAIN_IdentityGetNext (pOrigin, pData);
91 break;
93 case MSG_OPENDS:
94 twRC = TWAIN_OpenDS (pOrigin, pData);
95 break;
97 case MSG_USERSELECT:
98 twRC = TWAIN_UserSelect (pOrigin, pData);
99 break;
101 default:
102 /* Unrecognized operation triplet */
103 twRC = TWRC_FAILURE;
104 DSM_twCC = TWCC_BADPROTOCOL;
105 WARN("unrecognized operation triplet\n");
106 break;
108 break;
110 case DAT_PARENT:
111 switch (MSG)
113 case MSG_CLOSEDSM:
114 twRC = TWAIN_CloseDSM (pOrigin, pData);
115 break;
117 case MSG_OPENDSM:
118 twRC = TWAIN_OpenDSM (pOrigin, pData);
119 break;
121 default:
122 /* Unrecognized operation triplet */
123 twRC = TWRC_FAILURE;
124 DSM_twCC = TWCC_BADPROTOCOL;
125 WARN("unrecognized operation triplet\n");
127 break;
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");
137 break;
139 default:
140 twRC = TWRC_FAILURE;
141 DSM_twCC = TWCC_BADPROTOCOL;
142 WARN("unrecognized operation triplet\n");
143 break;
146 return twRC;
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)
159 TW_UINT16 twRC = TWRC_SUCCESS; /* Return Code */
161 TRACE("(DG=%d DAT=%d MSG=%d)\n", DG, DAT, MSG);
163 if (DG == DG_CONTROL && DAT == DAT_NULL)
165 activeDS *pSource = TWAIN_LookupSource (pOrigin);
166 if (!pSource)
168 ERR("No source associated with pSource %p\n", pDest);
169 DSM_twCC = TWCC_BADPROTOCOL;
170 return TWRC_FAILURE;
173 return TWAIN_ControlNull (pOrigin, pDest, pSource, MSG, pData);
176 if (pDest)
178 activeDS *pSource = TWAIN_LookupSource (pDest);
179 /* This operation's destination is a source */
181 if (!pSource) {
182 ERR("No source associated with pDest %p\n", pDest);
183 DSM_twCC = TWCC_BADDEST;
184 return TWRC_FAILURE;
187 if (DG == DG_CONTROL && DAT == DAT_EVENT && MSG == MSG_PROCESSEVENT)
189 twRC = TWAIN_ProcessEvent(pOrigin, pSource, pData);
190 if (twRC == TWRC_DSEVENT)
191 return twRC;
194 if (DG == DG_CONTROL && DAT == DAT_USERINTERFACE &&
195 (MSG == MSG_ENABLEDS || MSG == MSG_ENABLEDSUIONLY) &&
196 pData != NULL)
198 pSource->ui_window = ((TW_USERINTERFACE*)pData)->hParent;
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;
207 switch (DG)
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;
217 return twRC;