1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2000, 2010 Oracle and/or its affiliates.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * This file is part of OpenOffice.org.
11 * OpenOffice.org is free software: you can redistribute it and/or modify
12 * it under the terms of the GNU Lesser General Public License version 3
13 * only, as published by the Free Software Foundation.
15 * OpenOffice.org is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU Lesser General Public License version 3 for more details
19 * (a copy is included in the LICENSE file that accompanied this code).
21 * You should have received a copy of the GNU Lesser General Public License
22 * version 3 along with OpenOffice.org. If not, see
23 * <http://www.openoffice.org/license.html>
24 * for a copy of the LGPLv3 License.
26 ************************************************************************/
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_extensions.hxx"
34 #if defined( WNT ) || defined (WIN)
35 #include <tools/svwin.h>
40 #include <vos/module.hxx>
41 #include <tools/stream.hxx>
42 #include <vcl/svapp.hxx>
43 #include <vcl/wrkwin.hxx>
44 #include <vcl/sysdata.hxx>
52 #define FIXTODOUBLE( nFix ) ((double)nFix.Whole+(double)nFix.Frac/65536.)
53 #define FIXTOLONG( nFix ) ((long)floor(FIXTODOUBLE(nFix)+0.5))
56 #define TWAIN_LIBNAME "TWAIN.DLL"
57 #define TWAIN_FUNCNAME "DSM_Entry"
59 #define TWAIN_LIBNAME "TWAIN_32.DLL"
60 #define TWAIN_FUNCNAME "DSM_Entry"
62 #define TWAIN_LIBNAME "twain"
63 #define TWAIN_FUNCNAME "DSM_ENTRY"
70 static ImpTwain
* pImpTwainInstance
= NULL
;
78 #define PTWAINMSG QMSG*
80 MRESULT EXPENTRY
TwainWndProc( HWND hWnd
, ULONG nMsg
, MPARAM nParam1
, MPARAM nParam2
)
82 return (MRESULT
) TRUE
;
88 #define PTWAINMSG MSG*
90 // -------------------------------------------------------------------------
92 LRESULT CALLBACK
TwainWndProc( HWND hWnd
,UINT nMsg
, WPARAM nPar1
, LPARAM nPar2
)
94 return DefWindowProc( hWnd
, nMsg
, nPar1
, nPar2
);
97 // -------------------------------------------------------------------------
99 LRESULT CALLBACK
TwainMsgProc( int nCode
, WPARAM wParam
, LPARAM lParam
)
101 MSG
* pMsg
= (MSG
*) lParam
;
104 ( pImpTwainInstance
->hTwainWnd
!= pMsg
->hwnd
) ||
105 !pImpTwainInstance
->ImplHandleMsg( (void*) lParam
) )
107 return CallNextHookEx( pImpTwainInstance
->hTwainHook
, nCode
, wParam
, lParam
);
111 pMsg
->message
= WM_USER
;
124 ImpTwain::ImpTwain( const Link
& rNotifyLink
) :
125 aNotifyLink ( rNotifyLink
),
132 pImpTwainInstance
= this;
135 aAppIdent
.Version
.MajorNum
= 1;
136 aAppIdent
.Version
.MinorNum
= 0;
137 aAppIdent
.Version
.Language
= TWLG_USA
;
138 aAppIdent
.Version
.Country
= TWCY_USA
;
139 aAppIdent
.ProtocolMajor
= TWON_PROTOCOLMAJOR
;
140 aAppIdent
.ProtocolMinor
= TWON_PROTOCOLMINOR
;
141 aAppIdent
.SupportedGroups
= DG_IMAGE
| DG_CONTROL
;
142 strcpy( aAppIdent
.Version
.Info
, "6.0" );
143 strcpy( aAppIdent
.Manufacturer
, "Sun Microsystems");
144 strcpy( aAppIdent
.ProductFamily
,"Office");
145 strcpy( aAppIdent
.ProductName
, "Office");
149 hAB
= Sysdepen::GethAB();
150 ImplFallback( TWAIN_EVENT_QUIT
);
151 // hTwainWnd = WinCreateWindow( HWND_DESKTOP, WC_FRAME, "dummy", 0, 0, 0, 0, 0, HWND_DESKTOP, HWND_BOTTOM, 0, 0, 0 );
155 HWND hParentWnd
= HWND_DESKTOP
;
156 WNDCLASS aWc
= { 0, &TwainWndProc
, 0, sizeof( WNDCLASS
), GetModuleHandle( NULL
),
157 NULL
, NULL
, NULL
, NULL
, "TwainClass" };
159 RegisterClass( &aWc
);
160 hTwainWnd
= CreateWindowEx( WS_EX_TOPMOST
, aWc
.lpszClassName
, "TWAIN", 0, 0, 0, 0, 0, hParentWnd
, NULL
, aWc
.hInstance
, 0 );
161 hTwainHook
= SetWindowsHookEx( WH_GETMESSAGE
, &TwainMsgProc
, NULL
, GetCurrentThreadId() );
166 // -----------------------------------------------------------------------------
168 ImpTwain::~ImpTwain()
172 // -----------------------------------------------------------------------------
174 void ImpTwain::Destroy()
176 ImplFallback( TWAIN_EVENT_NONE
);
177 Application::PostUserEvent( LINK( this, ImpTwain
, ImplDestroyHdl
), NULL
);
180 // -----------------------------------------------------------------------------
182 BOOL
ImpTwain::SelectSource()
184 TW_UINT16 nRet
= TWRC_FAILURE
;
189 ImplOpenSourceManager();
195 aIdent
.Id
= 0, aIdent
.ProductName
[ 0 ] = '\0';
196 aNotifyLink
.Call( (void*) TWAIN_EVENT_SCANNING
);
197 nRet
= PFUNC( &aAppIdent
, NULL
, DG_CONTROL
, DAT_IDENTITY
, MSG_USERSELECT
, &aIdent
);
200 ImplFallback( TWAIN_EVENT_QUIT
);
202 return( nRet
== TWRC_SUCCESS
|| nRet
== TWRC_CANCEL
);
205 // -----------------------------------------------------------------------------
207 BOOL
ImpTwain::InitXfer()
214 ImplOpenSourceManager();
221 bRet
= ImplEnableSource();
225 ImplFallback( TWAIN_EVENT_QUIT
);
230 // -----------------------------------------------------------------------------
232 Bitmap
ImpTwain::GetXferBitmap()
234 Bitmap
aRet( aBitmap
);
239 // -----------------------------------------------------------------------------
241 void ImpTwain::ImplOpenSourceManager()
245 pMod
= new NAMESPACE_VOS( OModule
)();
247 if( pMod
->load( TWAIN_LIBNAME
) )
251 if( ( ( pDSM
= (DSMENTRYPROC
) pMod
->getSymbol( TWAIN_FUNCNAME
) ) != NULL
) &&
252 ( PFUNC( &aAppIdent
, NULL
, DG_CONTROL
, DAT_PARENT
, MSG_OPENDSM
, &hTwainWnd
) == TWRC_SUCCESS
) )
265 // -----------------------------------------------------------------------------
267 void ImpTwain::ImplOpenSource()
271 if( ( PFUNC( &aAppIdent
, NULL
, DG_CONTROL
, DAT_IDENTITY
, MSG_GETDEFAULT
, &aSrcIdent
) == TWRC_SUCCESS
) &&
272 ( PFUNC( &aAppIdent
, NULL
, DG_CONTROL
, DAT_IDENTITY
, MSG_OPENDS
, &aSrcIdent
) == TWRC_SUCCESS
) )
276 // negotiate capabilities
280 TW_CAPABILITY aCap
= { CAP_XFERCOUNT
, TWON_ONEVALUE
, GlobalAlloc( GHND
, sizeof( TW_ONEVALUE
) ) };
281 TW_ONEVALUE
* pVal
= (TW_ONEVALUE
*) GlobalLock( aCap
.hContainer
);
283 pVal
->ItemType
= TWTY_INT16
, pVal
->Item
= 1;
284 GlobalUnlock( aCap
.hContainer
);
285 PFUNC( &aAppIdent
, &aSrcIdent
, DG_CONTROL
, DAT_CAPABILITY
, MSG_SET
, &aCap
);
286 GlobalFree( aCap
.hContainer
);
294 // -----------------------------------------------------------------------------
296 BOOL
ImpTwain::ImplEnableSource()
302 TW_USERINTERFACE aUI
= { TRUE
, TRUE
, hTwainWnd
};
304 aNotifyLink
.Call( (void*) TWAIN_EVENT_SCANNING
);
307 if( PFUNC( &aAppIdent
, &aSrcIdent
, DG_CONTROL
, DAT_USERINTERFACE
, MSG_ENABLEDS
, &aUI
) == TWRC_SUCCESS
)
316 // -----------------------------------------------------------------------------
318 BOOL
ImpTwain::ImplHandleMsg( void* pMsg
)
321 PTWAINMSG pMess
= (PTWAINMSG
) pMsg
;
322 TW_EVENT aEvt
= { pMess
, MSG_NULL
};
324 nRet
= PFUNC( &aAppIdent
, &aSrcIdent
, DG_CONTROL
, DAT_EVENT
, MSG_PROCESSEVENT
, &aEvt
);
326 if( aEvt
.TWMessage
!= MSG_NULL
)
328 switch( aEvt
.TWMessage
)
332 ULONG nEvent
= TWAIN_EVENT_QUIT
;
340 nEvent
= TWAIN_EVENT_XFER
;
343 ImplFallback( nEvent
);
348 ImplFallback( TWAIN_EVENT_QUIT
);
356 nRet
= TWRC_NOTDSEVENT
;
358 return( TWRC_DSEVENT
== nRet
);
361 // -----------------------------------------------------------------------------
363 void ImpTwain::ImplXfer()
369 long nWidth
= aInfo
.ImageWidth
;
370 long nHeight
= aInfo
.ImageLength
;
371 long nXRes
= FIXTOLONG( aInfo
.XResolution
);
372 long nYRes
= FIXTOLONG( aInfo
.YResolution
);
374 if( PFUNC( &aAppIdent
, &aSrcIdent
, DG_IMAGE
, DAT_IMAGEINFO
, MSG_GET
, &aInfo
) == TWRC_SUCCESS
)
376 nWidth
= aInfo
.ImageWidth
;
377 nHeight
= aInfo
.ImageLength
;
378 nXRes
= FIXTOLONG( aInfo
.XResolution
);
379 nYRes
= FIXTOLONG( aInfo
.YResolution
);
382 nWidth
= nHeight
= nXRes
= nYRes
= -1L;
384 switch( PFUNC( &aAppIdent
, &aSrcIdent
, DG_IMAGE
, DAT_IMAGENATIVEXFER
, MSG_GET
, &hDIB
) )
390 case( TWRC_XFERDONE
):
397 const ULONG nSize
= GlobalSize( (HGLOBAL
) hDIB
);
398 char* pBuf
= (char*) GlobalLock( (HGLOBAL
) hDIB
);
402 SvMemoryStream aMemStm
;
403 aMemStm
.SetBuffer( pBuf
, nSize
, FALSE
, nSize
);
404 aBitmap
.Read( aMemStm
, FALSE
);
405 GlobalUnlock( (HGLOBAL
) hDIB
);
408 GlobalFree( (HGLOBAL
) hDIB
);
411 // set resolution of bitmap if neccessary
412 if ( ( nXRes
!= -1 ) && ( nYRes
!= - 1 ) && ( nWidth
!= - 1 ) && ( nHeight
!= - 1 ) )
414 const MapMode
aMapMode( MAP_100TH_INCH
, Point(), Fraction( 100, nXRes
), Fraction( 100, nYRes
) );
415 aBitmap
.SetPrefMapMode( aMapMode
);
416 aBitmap
.SetPrefSize( Size( nWidth
, nHeight
) );
429 // -----------------------------------------------------------------------------
431 void ImpTwain::ImplFallback( ULONG nEvent
)
433 Application::PostUserEvent( LINK( this, ImpTwain
, ImplFallbackHdl
), (void*) nEvent
);
436 // -----------------------------------------------------------------------------
438 IMPL_LINK( ImpTwain
, ImplFallbackHdl
, void*, pData
)
440 const ULONG nEvent
= (ULONG
) pData
;
441 BOOL bFallback
= TRUE
;
448 TW_PENDINGXFERS aXfers
;
450 if( PFUNC( &aAppIdent
, &aSrcIdent
, DG_CONTROL
, DAT_PENDINGXFERS
, MSG_ENDXFER
, &aXfers
) == TWRC_SUCCESS
)
452 if( aXfers
.Count
!= 0 )
453 PFUNC( &aAppIdent
, &aSrcIdent
, DG_CONTROL
, DAT_PENDINGXFERS
, MSG_RESET
, &aXfers
);
462 TW_USERINTERFACE aUI
= { TRUE
, TRUE
, hTwainWnd
};
464 PFUNC( &aAppIdent
, &aSrcIdent
, DG_CONTROL
, DAT_USERINTERFACE
, MSG_DISABLEDS
, &aUI
);
471 PFUNC( &aAppIdent
, NULL
, DG_CONTROL
, DAT_IDENTITY
, MSG_CLOSEDS
, &aSrcIdent
);
478 PFUNC( &aAppIdent
, NULL
, DG_CONTROL
, DAT_PARENT
, MSG_CLOSEDSM
, &hTwainWnd
);
493 if( nEvent
!= TWAIN_EVENT_NONE
)
494 aNotifyLink
.Call( (void*) nEvent
);
502 ImplFallback( nEvent
);
507 // -----------------------------------------------------------------------------
509 IMPL_LINK( ImpTwain
, ImplDestroyHdl
, void*, p
)
514 WinDestroyWindow( hWndTwain
);
521 DestroyWindow( hTwainWnd
);
524 UnhookWindowsHookEx( hTwainHook
);
529 pImpTwainInstance
= NULL
;