Fix the computation of the trackbar's size.
[wine/wine-kai.git] / dlls / twain / dsm_ctrl.c
blob3c55ea5fb1a81e10345965a05e9e046695d98e10
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>
25 #define NONAMELESSUNION
26 #define NONAMELESSSTRUCT
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 /* DG_CONTROL/DAT_IDENTITY/MSG_CLOSEDS */
35 TW_UINT16 TWAIN_CloseDS (pTW_IDENTITY pOrigin, TW_MEMREF pData)
37 #ifndef HAVE_SANE
38 DSM_twCC = TWCC_NODS;
39 return TWRC_FAILURE;
40 #else
41 TW_UINT16 twRC = TWRC_SUCCESS;
42 pTW_IDENTITY pIdentity = (pTW_IDENTITY) pData;
43 activeDS *currentDS = NULL, *prevDS = NULL;
45 TRACE ("DG_CONTROL/DAT_IDENTITY/MSG_CLOSEDS\n");
47 for (currentDS = activeSources; currentDS; currentDS = currentDS->next)
49 if (currentDS->identity.Id == pIdentity->Id)
50 break;
51 prevDS = currentDS;
53 if (currentDS)
55 /* Only valid to close a data source if it is in state 4 */
56 if (currentDS->currentState == 4)
58 sane_close (currentDS->deviceHandle);
59 /* remove the data source from active data source list */
60 if (prevDS)
61 prevDS->next = currentDS->next;
62 else
63 activeSources = currentDS->next;
64 HeapFree (GetProcessHeap(), 0, currentDS);
65 twRC = TWRC_SUCCESS;
66 DSM_twCC = TWCC_SUCCESS;
68 else
70 twRC = TWRC_FAILURE;
71 DSM_twCC = TWCC_SEQERROR;
74 else
76 twRC = TWRC_FAILURE;
77 DSM_twCC = TWCC_NODS;
80 return twRC;
81 #endif
84 /* DG_CONTROL/DAT_IDENTITY/MSG_GETDEFAULT */
85 TW_UINT16 TWAIN_IdentityGetDefault (pTW_IDENTITY pOrigin, TW_MEMREF pData)
87 #ifndef HAVE_SANE
88 DSM_twCC = TWCC_NODS;
89 return TWRC_FAILURE;
90 #else
91 TW_UINT16 twRC = TWRC_SUCCESS;
92 pTW_IDENTITY pSourceIdentity = (pTW_IDENTITY) pData;
94 TRACE("DG_CONTROL/DAT_IDENTITY/MSG_GETDEFAULT\n");
96 if (!device_list)
98 if ((sane_get_devices (&device_list, SANE_FALSE) != SANE_STATUS_GOOD))
100 DSM_twCC = TWCC_NODS;
101 return TWRC_FAILURE;
105 /* FIXME: the default device is not necessarily the first device. *
106 * Users should be able to choose the default device */
107 if (device_list && device_list[0])
109 pSourceIdentity->Id = DSM_sourceId ++;
110 strcpy (pSourceIdentity->ProductName, device_list[0]->name);
111 strcpy (pSourceIdentity->Manufacturer, device_list[0]->vendor);
112 strcpy (pSourceIdentity->ProductFamily, device_list[0]->model);
113 pSourceIdentity->ProtocolMajor = TWON_PROTOCOLMAJOR;
114 pSourceIdentity->ProtocolMinor = TWON_PROTOCOLMINOR;
116 twRC = TWRC_SUCCESS;
117 DSM_twCC = TWCC_SUCCESS;
119 else
121 twRC = TWRC_FAILURE;
122 DSM_twCC = TWCC_NODS;
125 return twRC;
126 #endif
129 /* DG_CONTROL/DAT_IDENTITY/MSG_GETFIRST */
130 TW_UINT16 TWAIN_IdentityGetFirst (pTW_IDENTITY pOrigin, TW_MEMREF pData)
132 #ifndef HAVE_SANE
133 DSM_twCC = TWCC_NODS;
134 return TWRC_FAILURE;
135 #else
136 TW_UINT16 twRC = TWRC_SUCCESS;
137 pTW_IDENTITY pSourceIdentity;/* = (pTW_IDENTITY) pData;*/
138 SANE_Status status;
140 TRACE ("DG_CONTROL/DAT_IDENTITY/MSG_GETFIRST\n");
142 status = sane_get_devices (&device_list, SANE_FALSE);
143 if (status == SANE_STATUS_GOOD)
145 if (device_list[0])
147 pSourceIdentity->Id = DSM_sourceId ++;
148 strcpy (pSourceIdentity->ProductName, device_list[0]->name);
149 strcpy (pSourceIdentity->Manufacturer, device_list[0]->vendor);
150 strcpy (pSourceIdentity->ProductFamily, device_list[0]->model);
151 pSourceIdentity->ProtocolMajor = TWON_PROTOCOLMAJOR;
152 pSourceIdentity->ProtocolMinor = TWON_PROTOCOLMINOR;
154 DSM_currentDevice = 1;
155 twRC = TWRC_SUCCESS;
156 DSM_twCC = TWCC_SUCCESS;
158 else if (status == SANE_STATUS_NO_MEM)
160 twRC = TWRC_FAILURE;
161 DSM_twCC = TWCC_LOWMEMORY;
163 else
165 WARN("sane_get_devices() failed: %s\n", sane_strstatus (status));
166 twRC = TWRC_FAILURE;
167 DSM_twCC = TWCC_NODS;
170 return twRC;
171 #endif
174 /* DG_CONTROL/DAT_IDENTITY/MSG_GETNEXT */
175 TW_UINT16 TWAIN_IdentityGetNext (pTW_IDENTITY pOrigin, TW_MEMREF pData)
177 #ifndef HAVE_SANE
178 DSM_twCC = TWCC_SUCCESS;
179 return TWRC_ENDOFLIST;
180 #else
181 TW_UINT16 twRC = TWRC_SUCCESS;
182 pTW_IDENTITY pSourceIdentity = (pTW_IDENTITY) pData;
184 TRACE("DG_CONTROL/DAT_IDENTITY/MSG_GETNEXT\n");
186 if (device_list && device_list[DSM_currentDevice])
188 pSourceIdentity->Id = DSM_sourceId ++;
189 strcpy (pSourceIdentity->ProductName, device_list[DSM_currentDevice]->name);
190 strcpy (pSourceIdentity->Manufacturer, device_list[DSM_currentDevice]->vendor);
191 strcpy (pSourceIdentity->ProductFamily, device_list[DSM_currentDevice]->model);
192 pSourceIdentity->ProtocolMajor = TWON_PROTOCOLMAJOR;
193 pSourceIdentity->ProtocolMinor = TWON_PROTOCOLMINOR;
194 DSM_currentDevice ++;
196 twRC = TWRC_SUCCESS;
197 DSM_twCC = TWCC_SUCCESS;
199 else
201 DSM_twCC = TWCC_SUCCESS;
202 twRC = TWRC_ENDOFLIST;
205 return twRC;
206 #endif
209 /* DG_CONTROL/DAT_IDENTITY/MSG_OPENDS */
210 TW_UINT16 TWAIN_OpenDS (pTW_IDENTITY pOrigin, TW_MEMREF pData)
212 #ifndef HAVE_SANE
213 DSM_twCC = TWCC_NODS;
214 return TWRC_FAILURE;
215 #else
216 TW_UINT16 twRC = TWRC_SUCCESS, i = 0;
217 pTW_IDENTITY pIdentity = (pTW_IDENTITY) pData;
218 activeDS *newSource;
219 SANE_Status status;
221 TRACE("DG_CONTROL/DAT_IDENTITY/MSG_OPENDS\n");
223 if (DSM_currentState != 3)
225 DSM_twCC = TWCC_SEQERROR;
226 return TWRC_FAILURE;
229 if (!device_list &&
230 (sane_get_devices (&device_list, SANE_FALSE) != SANE_STATUS_GOOD))
232 DSM_twCC = TWCC_NODS;
233 return TWRC_FAILURE;
236 if (pIdentity->ProductName[0] != '\0')
238 /* Make sure the source to be open exists in the device list */
239 for (i = 0; device_list[i]; i ++)
241 if (strcmp (device_list[i]->name, pIdentity->ProductName) == 0)
242 break;
246 if (device_list[i])
248 /* the source is found in the device list */
249 newSource = HeapAlloc (GetProcessHeap(), 0, sizeof (activeDS));
250 if (newSource)
252 status = sane_open(device_list[i]->name,&newSource->deviceHandle);
253 if (status == SANE_STATUS_GOOD)
255 /* Assign name and id for the opened data source */
256 strcpy (pIdentity->ProductName, device_list[i]->name);
257 pIdentity->Id = DSM_sourceId ++;
258 /* add the data source to an internal active source list */
259 newSource->next = activeSources;
260 newSource->identity.Id = pIdentity->Id;
261 strcpy (newSource->identity.ProductName, pIdentity->ProductName);
262 newSource->currentState = 4; /*transition into state 4*/
263 newSource->twCC = TWCC_SUCCESS;
264 activeSources = newSource;
265 twRC = TWRC_SUCCESS;
266 DSM_twCC = TWCC_SUCCESS;
268 else
270 twRC = TWRC_FAILURE;
271 DSM_twCC = TWCC_OPERATIONERROR;
274 else
276 twRC = TWRC_FAILURE;
277 DSM_twCC = TWCC_LOWMEMORY;
280 else
282 twRC = TWRC_FAILURE;
283 DSM_twCC = TWCC_NODS;
286 return twRC;
287 #endif
290 /* DG_CONTROL/DAT_IDENTITY/MSG_USERSELECT */
291 TW_UINT16 TWAIN_UserSelect (pTW_IDENTITY pOrigin, TW_MEMREF pData)
293 #ifndef HAVE_SANE
294 return TWRC_SUCCESS;
295 #else
296 TW_UINT16 twRC = TWRC_SUCCESS;
298 TRACE("DG_CONTROL/DAT_IDENTITY/MSG_USERSELECT\n");
300 /* FIXME: we should replace xscanimage with our own User Select UI */
301 system("xscanimage");
303 DSM_twCC = TWCC_SUCCESS;
304 return twRC;
305 #endif
308 /* DG_CONTROL/DAT_PARENT/MSG_CLOSEDSM */
309 TW_UINT16 TWAIN_CloseDSM (pTW_IDENTITY pOrigin, TW_MEMREF pData)
311 #ifndef HAVE_SANE
312 return TWRC_FAILURE;
313 #else
314 TW_UINT16 twRC = TWRC_SUCCESS;
315 activeDS *currentDS = activeSources, *nextDS;
317 TRACE("DG_CONTROL/DAT_PARENT/MSG_CLOSEDSM\n");
319 if (DSM_currentState == 3)
321 sane_exit ();
322 DSM_initialized = FALSE;
323 DSM_parentHWND = 0;
324 DSM_currentState = 2;
326 /* If there are data sources still open, close them now. */
327 while (currentDS != NULL)
329 nextDS = currentDS->next;
330 sane_close (currentDS->deviceHandle);
331 HeapFree (GetProcessHeap(), 0, currentDS);
332 currentDS = nextDS;
334 activeSources = NULL;
335 DSM_twCC = TWCC_SUCCESS;
336 twRC = TWRC_SUCCESS;
338 else
340 DSM_twCC = TWCC_SEQERROR;
341 twRC = TWRC_FAILURE;
344 return twRC;
345 #endif
348 /* DG_CONTROL/DAT_PARENT/MSG_OPENDSM */
349 TW_UINT16 TWAIN_OpenDSM (pTW_IDENTITY pOrigin, TW_MEMREF pData)
351 #ifndef HAVE_SANE
352 return TWRC_FAILURE;
353 #else
354 TW_UINT16 twRC = TWRC_SUCCESS;
355 SANE_Status status;
356 SANE_Int version_code;
358 TRACE("DG_CONTROL/DAT_PARENT/MSG_OPENDSM\n");
360 if (DSM_currentState == 2)
362 if (!DSM_initialized)
364 DSM_initialized = TRUE;
365 status = sane_init (&version_code, NULL);
366 device_list = NULL;
367 DSM_currentDevice = 0;
368 DSM_sourceId = 0;
370 DSM_parentHWND = *(TW_HANDLE*)pData;
371 DSM_currentState = 3; /* transition to state 3 */
372 DSM_twCC = TWCC_SUCCESS;
373 twRC = TWRC_SUCCESS;
375 else
377 /* operation invoked in invalid state */
378 DSM_twCC = TWCC_SEQERROR;
379 twRC = TWRC_FAILURE;
382 return twRC;
383 #endif
386 /* DG_CONTROL/DAT_STATUS/MSG_GET */
387 TW_UINT16 TWAIN_GetDSMStatus (pTW_IDENTITY pOrigin, TW_MEMREF pData)
389 pTW_STATUS pSourceStatus = (pTW_STATUS) pData;
391 TRACE ("DG_CONTROL/DAT_STATUS/MSG_GET\n");
393 pSourceStatus->ConditionCode = DSM_twCC;
394 DSM_twCC = TWCC_SUCCESS; /* clear the condition code */
396 return TWRC_SUCCESS;