xref: /trunk/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