Added function table to GDI objects for better encapsulation.
[wine.git] / dlls / twain / dsm_ctrl.c
blob8ca51720580e5db01f118778fffbf539c8c7eb3d
1 /*
2 * TWAIN32 Source Manager
4 * Copyright 2000 Corel Corporation
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 #include "config.h"
23 #include <stdlib.h>
24 #include "winbase.h"
25 #include "twain.h"
26 #include "twain_i.h"
27 #include "wine/debug.h"
29 WINE_DEFAULT_DEBUG_CHANNEL(twain);
31 /* DG_CONTROL/DAT_IDENTITY/MSG_CLOSEDS */
32 TW_UINT16 TWAIN_CloseDS (pTW_IDENTITY pOrigin, TW_MEMREF pData)
34 #ifndef HAVE_SANE
35 DSM_twCC = TWCC_NODS;
36 return TWRC_FAILURE;
37 #else
38 TW_UINT16 twRC = TWRC_SUCCESS;
39 pTW_IDENTITY pIdentity = (pTW_IDENTITY) pData;
40 activeDS *currentDS = NULL, *prevDS = NULL;
42 TRACE ("DG_CONTROL/DAT_IDENTITY/MSG_CLOSEDS\n");
44 for (currentDS = activeSources; currentDS; currentDS = currentDS->next)
46 if (currentDS->identity.Id == pIdentity->Id)
47 break;
48 prevDS = currentDS;
50 if (currentDS)
52 /* Only valid to close a data source if it is in state 4 */
53 if (currentDS->currentState == 4)
55 sane_close (currentDS->deviceHandle);
56 /* remove the data source from active data source list */
57 if (prevDS)
58 prevDS->next = currentDS->next;
59 else
60 activeSources = currentDS->next;
61 HeapFree (GetProcessHeap(), 0, currentDS);
62 twRC = TWRC_SUCCESS;
63 DSM_twCC = TWCC_SUCCESS;
65 else
67 twRC = TWRC_FAILURE;
68 DSM_twCC = TWCC_SEQERROR;
71 else
73 twRC = TWRC_FAILURE;
74 DSM_twCC = TWCC_NODS;
77 return twRC;
78 #endif
81 /* DG_CONTROL/DAT_IDENTITY/MSG_GETDEFAULT */
82 TW_UINT16 TWAIN_IdentityGetDefault (pTW_IDENTITY pOrigin, TW_MEMREF pData)
84 #ifndef HAVE_SANE
85 DSM_twCC = TWCC_NODS;
86 return TWRC_FAILURE;
87 #else
88 TW_UINT16 twRC = TWRC_SUCCESS;
89 pTW_IDENTITY pSourceIdentity = (pTW_IDENTITY) pData;
91 TRACE("DG_CONTROL/DAT_IDENTITY/MSG_GETDEFAULT\n");
93 if (!device_list)
95 if ((sane_get_devices (&device_list, SANE_FALSE) != SANE_STATUS_GOOD))
97 DSM_twCC = TWCC_NODS;
98 return TWRC_FAILURE;
102 /* FIXME: the default device is not necessarily the first device. *
103 * Users should be able to choose the default device */
104 if (device_list && device_list[0])
106 pSourceIdentity->Id = DSM_sourceId ++;
107 strcpy (pSourceIdentity->ProductName, device_list[0]->name);
108 strcpy (pSourceIdentity->Manufacturer, device_list[0]->vendor);
109 strcpy (pSourceIdentity->ProductFamily, device_list[0]->model);
110 pSourceIdentity->ProtocolMajor = TWON_PROTOCOLMAJOR;
111 pSourceIdentity->ProtocolMinor = TWON_PROTOCOLMINOR;
113 twRC = TWRC_SUCCESS;
114 DSM_twCC = TWCC_SUCCESS;
116 else
118 twRC = TWRC_FAILURE;
119 DSM_twCC = TWCC_NODS;
122 return twRC;
123 #endif
126 /* DG_CONTROL/DAT_IDENTITY/MSG_GETFIRST */
127 TW_UINT16 TWAIN_IdentityGetFirst (pTW_IDENTITY pOrigin, TW_MEMREF pData)
129 #ifndef HAVE_SANE
130 DSM_twCC = TWCC_NODS;
131 return TWRC_FAILURE;
132 #else
133 TW_UINT16 twRC = TWRC_SUCCESS;
134 pTW_IDENTITY pSourceIdentity;/* = (pTW_IDENTITY) pData;*/
135 SANE_Status status;
137 TRACE ("DG_CONTROL/DAT_IDENTITY/MSG_GETFIRST\n");
139 status = sane_get_devices (&device_list, SANE_FALSE);
140 if (status == SANE_STATUS_GOOD)
142 if (device_list[0])
144 pSourceIdentity->Id = DSM_sourceId ++;
145 strcpy (pSourceIdentity->ProductName, device_list[0]->name);
146 strcpy (pSourceIdentity->Manufacturer, device_list[0]->vendor);
147 strcpy (pSourceIdentity->ProductFamily, device_list[0]->model);
148 pSourceIdentity->ProtocolMajor = TWON_PROTOCOLMAJOR;
149 pSourceIdentity->ProtocolMinor = TWON_PROTOCOLMINOR;
151 DSM_currentDevice = 1;
152 twRC = TWRC_SUCCESS;
153 DSM_twCC = TWCC_SUCCESS;
155 else if (status == SANE_STATUS_NO_MEM)
157 twRC = TWRC_FAILURE;
158 DSM_twCC = TWCC_LOWMEMORY;
160 else
162 WARN("sane_get_devices() failed: %s\n", sane_strstatus (status));
163 twRC = TWRC_FAILURE;
164 DSM_twCC = TWCC_NODS;
167 return twRC;
168 #endif
171 /* DG_CONTROL/DAT_IDENTITY/MSG_GETNEXT */
172 TW_UINT16 TWAIN_IdentityGetNext (pTW_IDENTITY pOrigin, TW_MEMREF pData)
174 #ifndef HAVE_SANE
175 DSM_twCC = TWCC_SUCCESS;
176 return TWRC_ENDOFLIST;
177 #else
178 TW_UINT16 twRC = TWRC_SUCCESS;
179 pTW_IDENTITY pSourceIdentity = (pTW_IDENTITY) pData;
181 TRACE("DG_CONTROL/DAT_IDENTITY/MSG_GETNEXT\n");
183 if (device_list && device_list[DSM_currentDevice])
185 pSourceIdentity->Id = DSM_sourceId ++;
186 strcpy (pSourceIdentity->ProductName, device_list[DSM_currentDevice]->name);
187 strcpy (pSourceIdentity->Manufacturer, device_list[DSM_currentDevice]->vendor);
188 strcpy (pSourceIdentity->ProductFamily, device_list[DSM_currentDevice]->model);
189 pSourceIdentity->ProtocolMajor = TWON_PROTOCOLMAJOR;
190 pSourceIdentity->ProtocolMinor = TWON_PROTOCOLMINOR;
191 DSM_currentDevice ++;
193 twRC = TWRC_SUCCESS;
194 DSM_twCC = TWCC_SUCCESS;
196 else
198 DSM_twCC = TWCC_SUCCESS;
199 twRC = TWRC_ENDOFLIST;
202 return twRC;
203 #endif
206 /* DG_CONTROL/DAT_IDENTITY/MSG_OPENDS */
207 TW_UINT16 TWAIN_OpenDS (pTW_IDENTITY pOrigin, TW_MEMREF pData)
209 #ifndef HAVE_SANE
210 DSM_twCC = TWCC_NODS;
211 return TWRC_FAILURE;
212 #else
213 TW_UINT16 twRC = TWRC_SUCCESS, i = 0;
214 pTW_IDENTITY pIdentity = (pTW_IDENTITY) pData;
215 activeDS *newSource;
216 SANE_Status status;
218 TRACE("DG_CONTROL/DAT_IDENTITY/MSG_OPENDS\n");
220 if (DSM_currentState != 3)
222 DSM_twCC = TWCC_SEQERROR;
223 return TWRC_FAILURE;
226 if (!device_list &&
227 (sane_get_devices (&device_list, SANE_FALSE) != SANE_STATUS_GOOD))
229 DSM_twCC = TWCC_NODS;
230 return TWRC_FAILURE;
233 if (pIdentity->ProductName[0] != '\0')
235 /* Make sure the source to be open exists in the device list */
236 for (i = 0; device_list[i]; i ++)
238 if (strcmp (device_list[i]->name, pIdentity->ProductName) == 0)
239 break;
243 if (device_list[i])
245 /* the source is found in the device list */
246 newSource = HeapAlloc (GetProcessHeap(), 0, sizeof (activeDS));
247 if (newSource)
249 status = sane_open(device_list[i]->name,&newSource->deviceHandle);
250 if (status == SANE_STATUS_GOOD)
252 /* Assign name and id for the opened data source */
253 strcpy (pIdentity->ProductName, device_list[i]->name);
254 pIdentity->Id = DSM_sourceId ++;
255 /* add the data source to an internal active source list */
256 newSource->next = activeSources;
257 newSource->identity.Id = pIdentity->Id;
258 strcpy (newSource->identity.ProductName, pIdentity->ProductName);
259 newSource->currentState = 4; /*transition into state 4*/
260 newSource->twCC = TWCC_SUCCESS;
261 activeSources = newSource;
262 twRC = TWRC_SUCCESS;
263 DSM_twCC = TWCC_SUCCESS;
265 else
267 twRC = TWRC_FAILURE;
268 DSM_twCC = TWCC_OPERATIONERROR;
271 else
273 twRC = TWRC_FAILURE;
274 DSM_twCC = TWCC_LOWMEMORY;
277 else
279 twRC = TWRC_FAILURE;
280 DSM_twCC = TWCC_NODS;
283 return twRC;
284 #endif
287 /* DG_CONTROL/DAT_IDENTITY/MSG_USERSELECT */
288 TW_UINT16 TWAIN_UserSelect (pTW_IDENTITY pOrigin, TW_MEMREF pData)
290 #ifndef HAVE_SANE
291 return TWRC_SUCCESS;
292 #else
293 TW_UINT16 twRC = TWRC_SUCCESS;
295 TRACE("DG_CONTROL/DAT_IDENTITY/MSG_USERSELECT\n");
297 /* FIXME: we should replace xscanimage with our own User Select UI */
298 system("xscanimage");
300 DSM_twCC = TWCC_SUCCESS;
301 return twRC;
302 #endif
305 /* DG_CONTROL/DAT_PARENT/MSG_CLOSEDSM */
306 TW_UINT16 TWAIN_CloseDSM (pTW_IDENTITY pOrigin, TW_MEMREF pData)
308 #ifndef HAVE_SANE
309 return TWRC_FAILURE;
310 #else
311 TW_UINT16 twRC = TWRC_SUCCESS;
312 activeDS *currentDS = activeSources, *nextDS;
314 TRACE("DG_CONTROL/DAT_PARENT/MSG_CLOSEDSM\n");
316 if (DSM_currentState == 3)
318 sane_exit ();
319 DSM_initialized = FALSE;
320 DSM_parentHWND = 0;
321 DSM_currentState = 2;
323 /* If there are data sources still open, close them now. */
324 while (currentDS != NULL)
326 nextDS = currentDS->next;
327 sane_close (currentDS->deviceHandle);
328 HeapFree (GetProcessHeap(), 0, currentDS);
329 currentDS = nextDS;
331 activeSources = NULL;
332 DSM_twCC = TWCC_SUCCESS;
333 twRC = TWRC_SUCCESS;
335 else
337 DSM_twCC = TWCC_SEQERROR;
338 twRC = TWRC_FAILURE;
341 return twRC;
342 #endif
345 /* DG_CONTROL/DAT_PARENT/MSG_OPENDSM */
346 TW_UINT16 TWAIN_OpenDSM (pTW_IDENTITY pOrigin, TW_MEMREF pData)
348 #ifndef HAVE_SANE
349 return TWRC_FAILURE;
350 #else
351 TW_UINT16 twRC = TWRC_SUCCESS;
352 SANE_Status status;
353 SANE_Int version_code;
355 TRACE("DG_CONTROL/DAT_PARENT/MSG_OPENDSM\n");
357 if (DSM_currentState == 2)
359 if (!DSM_initialized)
361 DSM_initialized = TRUE;
362 status = sane_init (&version_code, NULL);
363 device_list = NULL;
364 DSM_currentDevice = 0;
365 DSM_sourceId = 0;
367 DSM_parentHWND = *(HWND*)pData;
368 DSM_currentState = 3; /* transition to state 3 */
369 DSM_twCC = TWCC_SUCCESS;
370 twRC = TWRC_SUCCESS;
372 else
374 /* operation invoked in invalid state */
375 DSM_twCC = TWCC_SEQERROR;
376 twRC = TWRC_FAILURE;
379 return twRC;
380 #endif
383 /* DG_CONTROL/DAT_STATUS/MSG_GET */
384 TW_UINT16 TWAIN_GetDSMStatus (pTW_IDENTITY pOrigin, TW_MEMREF pData)
386 pTW_STATUS pSourceStatus = (pTW_STATUS) pData;
388 TRACE ("DG_CONTROL/DAT_STATUS/MSG_GET\n");
390 pSourceStatus->ConditionCode = DSM_twCC;
391 DSM_twCC = TWCC_SUCCESS; /* clear the condition code */
393 return TWRC_SUCCESS;