xref: /AOO41X/main/extensions/source/scanner/twain.cxx (revision cdf0e10c4e3984b49a9502b011690b615761d4a3)
1*cdf0e10cSrcweir /*************************************************************************
2*cdf0e10cSrcweir  *
3*cdf0e10cSrcweir  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4*cdf0e10cSrcweir  *
5*cdf0e10cSrcweir  * Copyright 2000, 2010 Oracle and/or its affiliates.
6*cdf0e10cSrcweir  *
7*cdf0e10cSrcweir  * OpenOffice.org - a multi-platform office productivity suite
8*cdf0e10cSrcweir  *
9*cdf0e10cSrcweir  * This file is part of OpenOffice.org.
10*cdf0e10cSrcweir  *
11*cdf0e10cSrcweir  * OpenOffice.org is free software: you can redistribute it and/or modify
12*cdf0e10cSrcweir  * it under the terms of the GNU Lesser General Public License version 3
13*cdf0e10cSrcweir  * only, as published by the Free Software Foundation.
14*cdf0e10cSrcweir  *
15*cdf0e10cSrcweir  * OpenOffice.org is distributed in the hope that it will be useful,
16*cdf0e10cSrcweir  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17*cdf0e10cSrcweir  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18*cdf0e10cSrcweir  * GNU Lesser General Public License version 3 for more details
19*cdf0e10cSrcweir  * (a copy is included in the LICENSE file that accompanied this code).
20*cdf0e10cSrcweir  *
21*cdf0e10cSrcweir  * You should have received a copy of the GNU Lesser General Public License
22*cdf0e10cSrcweir  * version 3 along with OpenOffice.org.  If not, see
23*cdf0e10cSrcweir  * <http://www.openoffice.org/license.html>
24*cdf0e10cSrcweir  * for a copy of the LGPLv3 License.
25*cdf0e10cSrcweir  *
26*cdf0e10cSrcweir  ************************************************************************/
27*cdf0e10cSrcweir 
28*cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
29*cdf0e10cSrcweir #include "precompiled_extensions.hxx"
30*cdf0e10cSrcweir 
31*cdf0e10cSrcweir #include <string.h>
32*cdf0e10cSrcweir #include <math.h>
33*cdf0e10cSrcweir 
34*cdf0e10cSrcweir #if defined( WNT )
35*cdf0e10cSrcweir #include <tools/svwin.h>
36*cdf0e10cSrcweir #endif
37*cdf0e10cSrcweir #ifdef OS2
38*cdf0e10cSrcweir #include <svpm.h>
39*cdf0e10cSrcweir #endif // OS2
40*cdf0e10cSrcweir #include <vos/module.hxx>
41*cdf0e10cSrcweir #include <tools/stream.hxx>
42*cdf0e10cSrcweir #include <vcl/svapp.hxx>
43*cdf0e10cSrcweir #include <vcl/wrkwin.hxx>
44*cdf0e10cSrcweir #include <vcl/sysdata.hxx>
45*cdf0e10cSrcweir #include "twain.hxx"
46*cdf0e10cSrcweir 
47*cdf0e10cSrcweir // -----------
48*cdf0e10cSrcweir // - Defines -
49*cdf0e10cSrcweir // -----------
50*cdf0e10cSrcweir 
51*cdf0e10cSrcweir #define PFUNC						(*pDSM)
52*cdf0e10cSrcweir #define FIXTODOUBLE( nFix ) 		((double)nFix.Whole+(double)nFix.Frac/65536.)
53*cdf0e10cSrcweir #define FIXTOLONG( nFix )			((long)floor(FIXTODOUBLE(nFix)+0.5))
54*cdf0e10cSrcweir 
55*cdf0e10cSrcweir #if defined WNT
56*cdf0e10cSrcweir #define TWAIN_LIBNAME				"TWAIN_32.DLL"
57*cdf0e10cSrcweir #define TWAIN_FUNCNAME				"DSM_Entry"
58*cdf0e10cSrcweir #elif defined OS2
59*cdf0e10cSrcweir #define TWAIN_LIBNAME				"twain"
60*cdf0e10cSrcweir #define TWAIN_FUNCNAME				"DSM_ENTRY"
61*cdf0e10cSrcweir #endif
62*cdf0e10cSrcweir 
63*cdf0e10cSrcweir // -----------
64*cdf0e10cSrcweir // - Statics -
65*cdf0e10cSrcweir // -----------
66*cdf0e10cSrcweir 
67*cdf0e10cSrcweir static ImpTwain* pImpTwainInstance = NULL;
68*cdf0e10cSrcweir 
69*cdf0e10cSrcweir // ---------
70*cdf0e10cSrcweir // - Procs -
71*cdf0e10cSrcweir // ---------
72*cdf0e10cSrcweir 
73*cdf0e10cSrcweir #ifdef OS2
74*cdf0e10cSrcweir 
75*cdf0e10cSrcweir 	#define PTWAINMSG QMSG*
76*cdf0e10cSrcweir 
77*cdf0e10cSrcweir 	MRESULT EXPENTRY TwainWndProc( HWND hWnd, ULONG nMsg, MPARAM nParam1, MPARAM nParam2 )
78*cdf0e10cSrcweir 	{
79*cdf0e10cSrcweir 		return (MRESULT) TRUE;
80*cdf0e10cSrcweir 	}
81*cdf0e10cSrcweir 
82*cdf0e10cSrcweir 
83*cdf0e10cSrcweir #else // OS2
84*cdf0e10cSrcweir 
85*cdf0e10cSrcweir 	#define PTWAINMSG MSG*
86*cdf0e10cSrcweir 
87*cdf0e10cSrcweir 	// -------------------------------------------------------------------------
88*cdf0e10cSrcweir 
89*cdf0e10cSrcweir 	LRESULT CALLBACK TwainWndProc( HWND hWnd,UINT nMsg, WPARAM nPar1, LPARAM nPar2 )
90*cdf0e10cSrcweir 	{
91*cdf0e10cSrcweir 		return DefWindowProc( hWnd, nMsg, nPar1, nPar2 );
92*cdf0e10cSrcweir 	}
93*cdf0e10cSrcweir 
94*cdf0e10cSrcweir 	// -------------------------------------------------------------------------
95*cdf0e10cSrcweir 
96*cdf0e10cSrcweir 	LRESULT CALLBACK TwainMsgProc( int nCode, WPARAM wParam, LPARAM lParam )
97*cdf0e10cSrcweir 	{
98*cdf0e10cSrcweir 		MSG* pMsg = (MSG*) lParam;
99*cdf0e10cSrcweir 
100*cdf0e10cSrcweir 		if( ( nCode < 0 ) ||
101*cdf0e10cSrcweir 			( pImpTwainInstance->hTwainWnd != pMsg->hwnd ) ||
102*cdf0e10cSrcweir 			!pImpTwainInstance->ImplHandleMsg( (void*) lParam ) )
103*cdf0e10cSrcweir 		{
104*cdf0e10cSrcweir 			return CallNextHookEx( pImpTwainInstance->hTwainHook, nCode, wParam, lParam );
105*cdf0e10cSrcweir 		}
106*cdf0e10cSrcweir 		else
107*cdf0e10cSrcweir 		{
108*cdf0e10cSrcweir 			pMsg->message = WM_USER;
109*cdf0e10cSrcweir 			pMsg->lParam = 0;
110*cdf0e10cSrcweir 
111*cdf0e10cSrcweir 			return 0;
112*cdf0e10cSrcweir 		}
113*cdf0e10cSrcweir 	}
114*cdf0e10cSrcweir 
115*cdf0e10cSrcweir #endif // OS2
116*cdf0e10cSrcweir 
117*cdf0e10cSrcweir // ------------
118*cdf0e10cSrcweir // - ImpTwain -
119*cdf0e10cSrcweir // ------------
120*cdf0e10cSrcweir 
121*cdf0e10cSrcweir ImpTwain::ImpTwain( const Link& rNotifyLink ) :
122*cdf0e10cSrcweir 			aNotifyLink ( rNotifyLink ),
123*cdf0e10cSrcweir 			pDSM		( NULL ),
124*cdf0e10cSrcweir 			pMod		( NULL ),
125*cdf0e10cSrcweir 			hTwainWnd	( 0 ),
126*cdf0e10cSrcweir 			hTwainHook	( 0 ),
127*cdf0e10cSrcweir 			nCurState	( 1 )
128*cdf0e10cSrcweir {
129*cdf0e10cSrcweir 	pImpTwainInstance = this;
130*cdf0e10cSrcweir 
131*cdf0e10cSrcweir 	aAppIdent.Id = 0;
132*cdf0e10cSrcweir 	aAppIdent.Version.MajorNum = 1;
133*cdf0e10cSrcweir 	aAppIdent.Version.MinorNum = 0;
134*cdf0e10cSrcweir 	aAppIdent.Version.Language = TWLG_USA;
135*cdf0e10cSrcweir 	aAppIdent.Version.Country = TWCY_USA;
136*cdf0e10cSrcweir 	aAppIdent.ProtocolMajor = TWON_PROTOCOLMAJOR;
137*cdf0e10cSrcweir 	aAppIdent.ProtocolMinor = TWON_PROTOCOLMINOR;
138*cdf0e10cSrcweir 	aAppIdent.SupportedGroups =	DG_IMAGE | DG_CONTROL;
139*cdf0e10cSrcweir 	strcpy( aAppIdent.Version.Info, "6.0" );
140*cdf0e10cSrcweir 	strcpy( aAppIdent.Manufacturer, "Sun Microsystems");
141*cdf0e10cSrcweir 	strcpy( aAppIdent.ProductFamily,"Office");
142*cdf0e10cSrcweir 	strcpy( aAppIdent.ProductName, "Office");
143*cdf0e10cSrcweir 
144*cdf0e10cSrcweir #ifdef OS2
145*cdf0e10cSrcweir 
146*cdf0e10cSrcweir 	hAB = Sysdepen::GethAB();
147*cdf0e10cSrcweir 	ImplFallback( TWAIN_EVENT_QUIT );
148*cdf0e10cSrcweir 	// hTwainWnd = WinCreateWindow( HWND_DESKTOP, WC_FRAME, "dummy", 0, 0, 0, 0, 0, HWND_DESKTOP, HWND_BOTTOM, 0, 0, 0 );
149*cdf0e10cSrcweir 
150*cdf0e10cSrcweir #else
151*cdf0e10cSrcweir 
152*cdf0e10cSrcweir 	HWND		hParentWnd = HWND_DESKTOP;
153*cdf0e10cSrcweir 	WNDCLASS	aWc = { 0, &TwainWndProc, 0, sizeof( WNDCLASS ), GetModuleHandle( NULL ),
154*cdf0e10cSrcweir 						NULL, NULL, NULL, NULL, "TwainClass" };
155*cdf0e10cSrcweir 
156*cdf0e10cSrcweir 	RegisterClass( &aWc );
157*cdf0e10cSrcweir 	hTwainWnd = CreateWindowEx( WS_EX_TOPMOST, aWc.lpszClassName, "TWAIN", 0, 0, 0, 0, 0, hParentWnd, NULL, aWc.hInstance, 0 );
158*cdf0e10cSrcweir 	hTwainHook = SetWindowsHookEx( WH_GETMESSAGE, &TwainMsgProc, NULL, GetCurrentThreadId() );
159*cdf0e10cSrcweir 
160*cdf0e10cSrcweir #endif
161*cdf0e10cSrcweir }
162*cdf0e10cSrcweir 
163*cdf0e10cSrcweir // -----------------------------------------------------------------------------
164*cdf0e10cSrcweir 
165*cdf0e10cSrcweir ImpTwain::~ImpTwain()
166*cdf0e10cSrcweir {
167*cdf0e10cSrcweir }
168*cdf0e10cSrcweir 
169*cdf0e10cSrcweir // -----------------------------------------------------------------------------
170*cdf0e10cSrcweir 
171*cdf0e10cSrcweir void ImpTwain::Destroy()
172*cdf0e10cSrcweir {
173*cdf0e10cSrcweir 	ImplFallback( TWAIN_EVENT_NONE );
174*cdf0e10cSrcweir 	Application::PostUserEvent( LINK( this, ImpTwain, ImplDestroyHdl ), NULL );
175*cdf0e10cSrcweir }
176*cdf0e10cSrcweir 
177*cdf0e10cSrcweir // -----------------------------------------------------------------------------
178*cdf0e10cSrcweir 
179*cdf0e10cSrcweir sal_Bool ImpTwain::SelectSource()
180*cdf0e10cSrcweir {
181*cdf0e10cSrcweir 	TW_UINT16 nRet = TWRC_FAILURE;
182*cdf0e10cSrcweir 
183*cdf0e10cSrcweir 	if( !!aBitmap )
184*cdf0e10cSrcweir 		aBitmap = Bitmap();
185*cdf0e10cSrcweir 
186*cdf0e10cSrcweir 	ImplOpenSourceManager();
187*cdf0e10cSrcweir 
188*cdf0e10cSrcweir 	if( 3 == nCurState )
189*cdf0e10cSrcweir 	{
190*cdf0e10cSrcweir 		TW_IDENTITY aIdent;
191*cdf0e10cSrcweir 
192*cdf0e10cSrcweir 		aIdent.Id = 0, aIdent.ProductName[ 0 ] = '\0';
193*cdf0e10cSrcweir 		aNotifyLink.Call( (void*) TWAIN_EVENT_SCANNING );
194*cdf0e10cSrcweir 		nRet = PFUNC( &aAppIdent, NULL, DG_CONTROL, DAT_IDENTITY, MSG_USERSELECT, &aIdent );
195*cdf0e10cSrcweir 	}
196*cdf0e10cSrcweir 
197*cdf0e10cSrcweir 	ImplFallback( TWAIN_EVENT_QUIT );
198*cdf0e10cSrcweir 
199*cdf0e10cSrcweir 	return( nRet == TWRC_SUCCESS || nRet == TWRC_CANCEL );
200*cdf0e10cSrcweir }
201*cdf0e10cSrcweir 
202*cdf0e10cSrcweir // -----------------------------------------------------------------------------
203*cdf0e10cSrcweir 
204*cdf0e10cSrcweir sal_Bool ImpTwain::InitXfer()
205*cdf0e10cSrcweir {
206*cdf0e10cSrcweir 	sal_Bool bRet = sal_False;
207*cdf0e10cSrcweir 
208*cdf0e10cSrcweir 	if( !!aBitmap )
209*cdf0e10cSrcweir 		aBitmap = Bitmap();
210*cdf0e10cSrcweir 
211*cdf0e10cSrcweir 	ImplOpenSourceManager();
212*cdf0e10cSrcweir 
213*cdf0e10cSrcweir 	if( 3 == nCurState )
214*cdf0e10cSrcweir 	{
215*cdf0e10cSrcweir 		ImplOpenSource();
216*cdf0e10cSrcweir 
217*cdf0e10cSrcweir 		if( 4 == nCurState )
218*cdf0e10cSrcweir 			bRet = ImplEnableSource();
219*cdf0e10cSrcweir 	}
220*cdf0e10cSrcweir 
221*cdf0e10cSrcweir 	if( !bRet )
222*cdf0e10cSrcweir 		ImplFallback( TWAIN_EVENT_QUIT );
223*cdf0e10cSrcweir 
224*cdf0e10cSrcweir 	return bRet;
225*cdf0e10cSrcweir }
226*cdf0e10cSrcweir 
227*cdf0e10cSrcweir // -----------------------------------------------------------------------------
228*cdf0e10cSrcweir 
229*cdf0e10cSrcweir Bitmap ImpTwain::GetXferBitmap()
230*cdf0e10cSrcweir {
231*cdf0e10cSrcweir 	Bitmap aRet( aBitmap );
232*cdf0e10cSrcweir 	aBitmap = Bitmap();
233*cdf0e10cSrcweir 	return aRet;
234*cdf0e10cSrcweir }
235*cdf0e10cSrcweir 
236*cdf0e10cSrcweir // -----------------------------------------------------------------------------
237*cdf0e10cSrcweir 
238*cdf0e10cSrcweir void ImpTwain::ImplOpenSourceManager()
239*cdf0e10cSrcweir {
240*cdf0e10cSrcweir 	if( 1 == nCurState )
241*cdf0e10cSrcweir 	{
242*cdf0e10cSrcweir 		pMod = new vos:: OModule ();
243*cdf0e10cSrcweir 
244*cdf0e10cSrcweir 		if( pMod->load( TWAIN_LIBNAME ) )
245*cdf0e10cSrcweir 		{
246*cdf0e10cSrcweir 			nCurState = 2;
247*cdf0e10cSrcweir 
248*cdf0e10cSrcweir 			if( ( ( pDSM = (DSMENTRYPROC) pMod->getSymbol( TWAIN_FUNCNAME ) ) != NULL ) &&
249*cdf0e10cSrcweir 				( PFUNC( &aAppIdent, NULL, DG_CONTROL, DAT_PARENT, MSG_OPENDSM, &hTwainWnd ) == TWRC_SUCCESS ) )
250*cdf0e10cSrcweir 			{
251*cdf0e10cSrcweir 				nCurState = 3;
252*cdf0e10cSrcweir 			}
253*cdf0e10cSrcweir 		}
254*cdf0e10cSrcweir 		else
255*cdf0e10cSrcweir 		{
256*cdf0e10cSrcweir 			delete pMod;
257*cdf0e10cSrcweir 			pMod = NULL;
258*cdf0e10cSrcweir 		}
259*cdf0e10cSrcweir 	}
260*cdf0e10cSrcweir }
261*cdf0e10cSrcweir 
262*cdf0e10cSrcweir // -----------------------------------------------------------------------------
263*cdf0e10cSrcweir 
264*cdf0e10cSrcweir void ImpTwain::ImplOpenSource()
265*cdf0e10cSrcweir {
266*cdf0e10cSrcweir 	if( 3 == nCurState )
267*cdf0e10cSrcweir 	{
268*cdf0e10cSrcweir 		if( ( PFUNC( &aAppIdent, NULL, DG_CONTROL, DAT_IDENTITY, MSG_GETDEFAULT, &aSrcIdent ) == TWRC_SUCCESS ) &&
269*cdf0e10cSrcweir 			( PFUNC( &aAppIdent, NULL, DG_CONTROL, DAT_IDENTITY, MSG_OPENDS, &aSrcIdent ) == TWRC_SUCCESS ) )
270*cdf0e10cSrcweir 		{
271*cdf0e10cSrcweir #ifdef OS2
272*cdf0e10cSrcweir 
273*cdf0e10cSrcweir 			// negotiate capabilities
274*cdf0e10cSrcweir 
275*cdf0e10cSrcweir #else
276*cdf0e10cSrcweir 
277*cdf0e10cSrcweir 			TW_CAPABILITY	aCap = { CAP_XFERCOUNT, TWON_ONEVALUE, GlobalAlloc( GHND, sizeof( TW_ONEVALUE ) ) };
278*cdf0e10cSrcweir 			TW_ONEVALUE*	pVal = (TW_ONEVALUE*) GlobalLock( aCap.hContainer );
279*cdf0e10cSrcweir 
280*cdf0e10cSrcweir 			pVal->ItemType = TWTY_INT16, pVal->Item = 1;
281*cdf0e10cSrcweir 			GlobalUnlock( aCap.hContainer );
282*cdf0e10cSrcweir 			PFUNC( &aAppIdent, &aSrcIdent, DG_CONTROL, DAT_CAPABILITY, MSG_SET, &aCap );
283*cdf0e10cSrcweir 			GlobalFree( aCap.hContainer );
284*cdf0e10cSrcweir #endif
285*cdf0e10cSrcweir 
286*cdf0e10cSrcweir 			nCurState = 4;
287*cdf0e10cSrcweir 		}
288*cdf0e10cSrcweir 	}
289*cdf0e10cSrcweir }
290*cdf0e10cSrcweir 
291*cdf0e10cSrcweir // -----------------------------------------------------------------------------
292*cdf0e10cSrcweir 
293*cdf0e10cSrcweir BOOL ImpTwain::ImplEnableSource()
294*cdf0e10cSrcweir {
295*cdf0e10cSrcweir 	BOOL bRet = FALSE;
296*cdf0e10cSrcweir 
297*cdf0e10cSrcweir 	if( 4 == nCurState )
298*cdf0e10cSrcweir 	{
299*cdf0e10cSrcweir 		TW_USERINTERFACE aUI = { TRUE, TRUE, hTwainWnd };
300*cdf0e10cSrcweir 
301*cdf0e10cSrcweir 		aNotifyLink.Call( (void*) TWAIN_EVENT_SCANNING );
302*cdf0e10cSrcweir 		nCurState = 5;
303*cdf0e10cSrcweir 
304*cdf0e10cSrcweir 		if( PFUNC( &aAppIdent, &aSrcIdent, DG_CONTROL, DAT_USERINTERFACE, MSG_ENABLEDS, &aUI ) == TWRC_SUCCESS )
305*cdf0e10cSrcweir 			bRet = TRUE;
306*cdf0e10cSrcweir 		else
307*cdf0e10cSrcweir 			nCurState = 4;
308*cdf0e10cSrcweir 	}
309*cdf0e10cSrcweir 
310*cdf0e10cSrcweir 	return bRet;
311*cdf0e10cSrcweir }
312*cdf0e10cSrcweir 
313*cdf0e10cSrcweir // -----------------------------------------------------------------------------
314*cdf0e10cSrcweir 
315*cdf0e10cSrcweir BOOL ImpTwain::ImplHandleMsg( void* pMsg )
316*cdf0e10cSrcweir {
317*cdf0e10cSrcweir 	TW_UINT16	nRet;
318*cdf0e10cSrcweir 	PTWAINMSG	pMess = (PTWAINMSG) pMsg;
319*cdf0e10cSrcweir 	TW_EVENT	aEvt = { pMess, MSG_NULL };
320*cdf0e10cSrcweir 
321*cdf0e10cSrcweir 	nRet = PFUNC( &aAppIdent, &aSrcIdent, DG_CONTROL, DAT_EVENT, MSG_PROCESSEVENT, &aEvt );
322*cdf0e10cSrcweir 
323*cdf0e10cSrcweir 	if( aEvt.TWMessage != MSG_NULL )
324*cdf0e10cSrcweir 	{
325*cdf0e10cSrcweir 		switch( aEvt.TWMessage )
326*cdf0e10cSrcweir 		{
327*cdf0e10cSrcweir 			case MSG_XFERREADY:
328*cdf0e10cSrcweir 			{
329*cdf0e10cSrcweir 				ULONG nEvent = TWAIN_EVENT_QUIT;
330*cdf0e10cSrcweir 
331*cdf0e10cSrcweir 				if( 5 == nCurState )
332*cdf0e10cSrcweir 				{
333*cdf0e10cSrcweir 					nCurState = 6;
334*cdf0e10cSrcweir 					ImplXfer();
335*cdf0e10cSrcweir 
336*cdf0e10cSrcweir 					if( !!aBitmap )
337*cdf0e10cSrcweir 						nEvent = TWAIN_EVENT_XFER;
338*cdf0e10cSrcweir 				}
339*cdf0e10cSrcweir 
340*cdf0e10cSrcweir 				ImplFallback( nEvent );
341*cdf0e10cSrcweir 			}
342*cdf0e10cSrcweir 			break;
343*cdf0e10cSrcweir 
344*cdf0e10cSrcweir 			case MSG_CLOSEDSREQ:
345*cdf0e10cSrcweir 				ImplFallback( TWAIN_EVENT_QUIT );
346*cdf0e10cSrcweir 			break;
347*cdf0e10cSrcweir 
348*cdf0e10cSrcweir 			default:
349*cdf0e10cSrcweir 			break;
350*cdf0e10cSrcweir 		}
351*cdf0e10cSrcweir 	}
352*cdf0e10cSrcweir 	else
353*cdf0e10cSrcweir 		nRet = TWRC_NOTDSEVENT;
354*cdf0e10cSrcweir 
355*cdf0e10cSrcweir 	return( TWRC_DSEVENT == nRet );
356*cdf0e10cSrcweir }
357*cdf0e10cSrcweir 
358*cdf0e10cSrcweir // -----------------------------------------------------------------------------
359*cdf0e10cSrcweir 
360*cdf0e10cSrcweir void ImpTwain::ImplXfer()
361*cdf0e10cSrcweir {
362*cdf0e10cSrcweir 	if( nCurState == 6 )
363*cdf0e10cSrcweir 	{
364*cdf0e10cSrcweir 		TW_IMAGEINFO	aInfo;
365*cdf0e10cSrcweir 		TW_UINT32		hDIB = 0;
366*cdf0e10cSrcweir 		long			nWidth = aInfo.ImageWidth;
367*cdf0e10cSrcweir 		long			nHeight = aInfo.ImageLength;
368*cdf0e10cSrcweir 		long			nXRes = FIXTOLONG( aInfo.XResolution );
369*cdf0e10cSrcweir 		long			nYRes = FIXTOLONG( aInfo.YResolution );
370*cdf0e10cSrcweir 
371*cdf0e10cSrcweir 		if( PFUNC( &aAppIdent, &aSrcIdent, DG_IMAGE, DAT_IMAGEINFO, MSG_GET, &aInfo ) == TWRC_SUCCESS )
372*cdf0e10cSrcweir 		{
373*cdf0e10cSrcweir 			nWidth = aInfo.ImageWidth;
374*cdf0e10cSrcweir 			nHeight = aInfo.ImageLength;
375*cdf0e10cSrcweir 			nXRes = FIXTOLONG( aInfo.XResolution );
376*cdf0e10cSrcweir 			nYRes = FIXTOLONG( aInfo.YResolution );
377*cdf0e10cSrcweir 		}
378*cdf0e10cSrcweir 		else
379*cdf0e10cSrcweir 			nWidth = nHeight = nXRes = nYRes = -1L;
380*cdf0e10cSrcweir 
381*cdf0e10cSrcweir 		switch( PFUNC( &aAppIdent, &aSrcIdent, DG_IMAGE, DAT_IMAGENATIVEXFER, MSG_GET, &hDIB ) )
382*cdf0e10cSrcweir 		{
383*cdf0e10cSrcweir 			case( TWRC_CANCEL ):
384*cdf0e10cSrcweir 				nCurState = 7;
385*cdf0e10cSrcweir 			break;
386*cdf0e10cSrcweir 
387*cdf0e10cSrcweir 			case( TWRC_XFERDONE ):
388*cdf0e10cSrcweir 			{
389*cdf0e10cSrcweir #ifdef OS2
390*cdf0e10cSrcweir 
391*cdf0e10cSrcweir 				// get OS/2-Bitmap
392*cdf0e10cSrcweir 
393*cdf0e10cSrcweir #else // OS2
394*cdf0e10cSrcweir 				const ULONG nSize = GlobalSize( (HGLOBAL) hDIB );
395*cdf0e10cSrcweir 				char*		pBuf = (char*) GlobalLock( (HGLOBAL) hDIB );
396*cdf0e10cSrcweir 
397*cdf0e10cSrcweir 				if( pBuf )
398*cdf0e10cSrcweir 				{
399*cdf0e10cSrcweir 					SvMemoryStream aMemStm;
400*cdf0e10cSrcweir 					aMemStm.SetBuffer( pBuf, nSize, FALSE, nSize );
401*cdf0e10cSrcweir 					aBitmap.Read( aMemStm, FALSE );
402*cdf0e10cSrcweir 					GlobalUnlock( (HGLOBAL) hDIB );
403*cdf0e10cSrcweir 				}
404*cdf0e10cSrcweir 
405*cdf0e10cSrcweir 				GlobalFree( (HGLOBAL) hDIB );
406*cdf0e10cSrcweir #endif // OS2
407*cdf0e10cSrcweir 
408*cdf0e10cSrcweir 				// set resolution of bitmap if neccessary
409*cdf0e10cSrcweir 				if ( ( nXRes != -1 ) && ( nYRes != - 1 ) && ( nWidth != - 1 ) && ( nHeight != - 1 ) )
410*cdf0e10cSrcweir 				{
411*cdf0e10cSrcweir 					const MapMode aMapMode( MAP_100TH_INCH, Point(), Fraction( 100, nXRes ), Fraction( 100, nYRes ) );
412*cdf0e10cSrcweir 					aBitmap.SetPrefMapMode( aMapMode );
413*cdf0e10cSrcweir 					aBitmap.SetPrefSize( Size( nWidth, nHeight ) );
414*cdf0e10cSrcweir 				}
415*cdf0e10cSrcweir 
416*cdf0e10cSrcweir 				nCurState = 7;
417*cdf0e10cSrcweir 			}
418*cdf0e10cSrcweir 			break;
419*cdf0e10cSrcweir 
420*cdf0e10cSrcweir 			default:
421*cdf0e10cSrcweir 			break;
422*cdf0e10cSrcweir 		}
423*cdf0e10cSrcweir 	}
424*cdf0e10cSrcweir }
425*cdf0e10cSrcweir 
426*cdf0e10cSrcweir // -----------------------------------------------------------------------------
427*cdf0e10cSrcweir 
428*cdf0e10cSrcweir void ImpTwain::ImplFallback( ULONG nEvent )
429*cdf0e10cSrcweir {
430*cdf0e10cSrcweir 	Application::PostUserEvent( LINK( this, ImpTwain, ImplFallbackHdl ), (void*) nEvent );
431*cdf0e10cSrcweir }
432*cdf0e10cSrcweir 
433*cdf0e10cSrcweir // -----------------------------------------------------------------------------
434*cdf0e10cSrcweir 
435*cdf0e10cSrcweir IMPL_LINK( ImpTwain, ImplFallbackHdl, void*, pData )
436*cdf0e10cSrcweir {
437*cdf0e10cSrcweir 	const ULONG	nEvent = (ULONG) pData;
438*cdf0e10cSrcweir 	sal_Bool		bFallback = sal_True;
439*cdf0e10cSrcweir 
440*cdf0e10cSrcweir 	switch( nCurState )
441*cdf0e10cSrcweir 	{
442*cdf0e10cSrcweir 		case( 7 ):
443*cdf0e10cSrcweir 		case( 6 ):
444*cdf0e10cSrcweir 		{
445*cdf0e10cSrcweir 			TW_PENDINGXFERS aXfers;
446*cdf0e10cSrcweir 
447*cdf0e10cSrcweir 			if( PFUNC( &aAppIdent, &aSrcIdent, DG_CONTROL, DAT_PENDINGXFERS, MSG_ENDXFER, &aXfers ) == TWRC_SUCCESS )
448*cdf0e10cSrcweir 			{
449*cdf0e10cSrcweir 				if( aXfers.Count != 0 )
450*cdf0e10cSrcweir 					PFUNC( &aAppIdent, &aSrcIdent, DG_CONTROL, DAT_PENDINGXFERS, MSG_RESET, &aXfers );
451*cdf0e10cSrcweir 			}
452*cdf0e10cSrcweir 
453*cdf0e10cSrcweir 			nCurState = 5;
454*cdf0e10cSrcweir 		}
455*cdf0e10cSrcweir 		break;
456*cdf0e10cSrcweir 
457*cdf0e10cSrcweir 		case( 5 ):
458*cdf0e10cSrcweir 		{
459*cdf0e10cSrcweir 			TW_USERINTERFACE aUI = { TRUE, TRUE, hTwainWnd };
460*cdf0e10cSrcweir 
461*cdf0e10cSrcweir 			PFUNC( &aAppIdent, &aSrcIdent, DG_CONTROL, DAT_USERINTERFACE, MSG_DISABLEDS, &aUI );
462*cdf0e10cSrcweir 			nCurState = 4;
463*cdf0e10cSrcweir 		}
464*cdf0e10cSrcweir 		break;
465*cdf0e10cSrcweir 
466*cdf0e10cSrcweir 		case( 4 ):
467*cdf0e10cSrcweir 		{
468*cdf0e10cSrcweir 			PFUNC( &aAppIdent, NULL, DG_CONTROL, DAT_IDENTITY, MSG_CLOSEDS, &aSrcIdent );
469*cdf0e10cSrcweir 			nCurState = 3;
470*cdf0e10cSrcweir 		}
471*cdf0e10cSrcweir 		break;
472*cdf0e10cSrcweir 
473*cdf0e10cSrcweir 		case( 3 ):
474*cdf0e10cSrcweir 		{
475*cdf0e10cSrcweir 			PFUNC( &aAppIdent, NULL, DG_CONTROL, DAT_PARENT, MSG_CLOSEDSM, &hTwainWnd );
476*cdf0e10cSrcweir 			nCurState = 2;
477*cdf0e10cSrcweir 		}
478*cdf0e10cSrcweir 		break;
479*cdf0e10cSrcweir 
480*cdf0e10cSrcweir 		case( 2 ):
481*cdf0e10cSrcweir 		{
482*cdf0e10cSrcweir 			delete pMod;
483*cdf0e10cSrcweir 			pMod = NULL;
484*cdf0e10cSrcweir 			nCurState = 1;
485*cdf0e10cSrcweir 		}
486*cdf0e10cSrcweir 		break;
487*cdf0e10cSrcweir 
488*cdf0e10cSrcweir 		default:
489*cdf0e10cSrcweir 		{
490*cdf0e10cSrcweir 			if( nEvent != TWAIN_EVENT_NONE )
491*cdf0e10cSrcweir 				aNotifyLink.Call( (void*) nEvent );
492*cdf0e10cSrcweir 
493*cdf0e10cSrcweir 			bFallback = sal_False;
494*cdf0e10cSrcweir 		}
495*cdf0e10cSrcweir 		break;
496*cdf0e10cSrcweir 	}
497*cdf0e10cSrcweir 
498*cdf0e10cSrcweir 	if( bFallback )
499*cdf0e10cSrcweir 		ImplFallback( nEvent );
500*cdf0e10cSrcweir 
501*cdf0e10cSrcweir 	return 0L;
502*cdf0e10cSrcweir }
503*cdf0e10cSrcweir 
504*cdf0e10cSrcweir // -----------------------------------------------------------------------------
505*cdf0e10cSrcweir 
506*cdf0e10cSrcweir IMPL_LINK( ImpTwain, ImplDestroyHdl, void*, p )
507*cdf0e10cSrcweir {
508*cdf0e10cSrcweir #ifdef OS2
509*cdf0e10cSrcweir 
510*cdf0e10cSrcweir 	if( hWndTwain )
511*cdf0e10cSrcweir 		WinDestroyWindow( hWndTwain );
512*cdf0e10cSrcweir 
513*cdf0e10cSrcweir 	// unset hook
514*cdf0e10cSrcweir 
515*cdf0e10cSrcweir #else
516*cdf0e10cSrcweir 
517*cdf0e10cSrcweir 	if( hTwainWnd )
518*cdf0e10cSrcweir 		DestroyWindow( hTwainWnd );
519*cdf0e10cSrcweir 
520*cdf0e10cSrcweir 	if( hTwainHook )
521*cdf0e10cSrcweir 		UnhookWindowsHookEx( hTwainHook );
522*cdf0e10cSrcweir 
523*cdf0e10cSrcweir #endif
524*cdf0e10cSrcweir 
525*cdf0e10cSrcweir 	delete this;
526*cdf0e10cSrcweir 	pImpTwainInstance = NULL;
527*cdf0e10cSrcweir 
528*cdf0e10cSrcweir 	return 0L;
529*cdf0e10cSrcweir }
530