1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: twain.cxx,v $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_extensions.hxx"
37 #if defined( WNT ) || defined (WIN)
38 #include <tools/svwin.h>
43 #include <vos/module.hxx>
44 #include <tools/stream.hxx>
45 #include <vcl/svapp.hxx>
46 #include <vcl/wrkwin.hxx>
47 #include <vcl/sysdata.hxx>
55 #define FIXTODOUBLE( nFix ) ((double)nFix.Whole+(double)nFix.Frac/65536.)
56 #define FIXTOLONG( nFix ) ((long)floor(FIXTODOUBLE(nFix)+0.5))
59 #define TWAIN_LIBNAME "TWAIN.DLL"
60 #define TWAIN_FUNCNAME "DSM_Entry"
62 #define TWAIN_LIBNAME "TWAIN_32.DLL"
63 #define TWAIN_FUNCNAME "DSM_Entry"
65 #define TWAIN_LIBNAME "twain"
66 #define TWAIN_FUNCNAME "DSM_ENTRY"
73 static ImpTwain
* pImpTwainInstance
= NULL
;
81 #define PTWAINMSG QMSG*
83 MRESULT EXPENTRY
TwainWndProc( HWND hWnd
, ULONG nMsg
, MPARAM nParam1
, MPARAM nParam2
)
85 return (MRESULT
) TRUE
;
91 #define PTWAINMSG MSG*
93 // -------------------------------------------------------------------------
95 LRESULT CALLBACK
TwainWndProc( HWND hWnd
,UINT nMsg
, WPARAM nPar1
, LPARAM nPar2
)
97 return DefWindowProc( hWnd
, nMsg
, nPar1
, nPar2
);
100 // -------------------------------------------------------------------------
102 LRESULT CALLBACK
TwainMsgProc( int nCode
, WPARAM wParam
, LPARAM lParam
)
104 MSG
* pMsg
= (MSG
*) lParam
;
107 ( pImpTwainInstance
->hTwainWnd
!= pMsg
->hwnd
) ||
108 !pImpTwainInstance
->ImplHandleMsg( (void*) lParam
) )
110 return CallNextHookEx( pImpTwainInstance
->hTwainHook
, nCode
, wParam
, lParam
);
114 pMsg
->message
= WM_USER
;
127 ImpTwain::ImpTwain( const Link
& rNotifyLink
) :
128 aNotifyLink ( rNotifyLink
),
135 pImpTwainInstance
= this;
138 aAppIdent
.Version
.MajorNum
= 1;
139 aAppIdent
.Version
.MinorNum
= 0;
140 aAppIdent
.Version
.Language
= TWLG_USA
;
141 aAppIdent
.Version
.Country
= TWCY_USA
;
142 aAppIdent
.ProtocolMajor
= TWON_PROTOCOLMAJOR
;
143 aAppIdent
.ProtocolMinor
= TWON_PROTOCOLMINOR
;
144 aAppIdent
.SupportedGroups
= DG_IMAGE
| DG_CONTROL
;
145 strcpy( aAppIdent
.Version
.Info
, "6.0" );
146 strcpy( aAppIdent
.Manufacturer
, "Sun Microsystems");
147 strcpy( aAppIdent
.ProductFamily
,"Office");
148 strcpy( aAppIdent
.ProductName
, "Office");
152 hAB
= Sysdepen::GethAB();
153 ImplFallback( TWAIN_EVENT_QUIT
);
154 // hTwainWnd = WinCreateWindow( HWND_DESKTOP, WC_FRAME, "dummy", 0, 0, 0, 0, 0, HWND_DESKTOP, HWND_BOTTOM, 0, 0, 0 );
158 HWND hParentWnd
= HWND_DESKTOP
;
159 WNDCLASS aWc
= { 0, &TwainWndProc
, 0, sizeof( WNDCLASS
), GetModuleHandle( NULL
),
160 NULL
, NULL
, NULL
, NULL
, "TwainClass" };
162 RegisterClass( &aWc
);
163 hTwainWnd
= CreateWindowEx( WS_EX_TOPMOST
, aWc
.lpszClassName
, "TWAIN", 0, 0, 0, 0, 0, hParentWnd
, NULL
, aWc
.hInstance
, 0 );
164 hTwainHook
= SetWindowsHookEx( WH_GETMESSAGE
, &TwainMsgProc
, NULL
, GetCurrentThreadId() );
169 // -----------------------------------------------------------------------------
171 ImpTwain::~ImpTwain()
175 // -----------------------------------------------------------------------------
177 void ImpTwain::Destroy()
179 ImplFallback( TWAIN_EVENT_NONE
);
180 Application::PostUserEvent( LINK( this, ImpTwain
, ImplDestroyHdl
), NULL
);
183 // -----------------------------------------------------------------------------
185 BOOL
ImpTwain::SelectSource()
187 TW_UINT16 nRet
= TWRC_FAILURE
;
192 ImplOpenSourceManager();
198 aIdent
.Id
= 0, aIdent
.ProductName
[ 0 ] = '\0';
199 aNotifyLink
.Call( (void*) TWAIN_EVENT_SCANNING
);
200 nRet
= PFUNC( &aAppIdent
, NULL
, DG_CONTROL
, DAT_IDENTITY
, MSG_USERSELECT
, &aIdent
);
203 ImplFallback( TWAIN_EVENT_QUIT
);
205 return( nRet
== TWRC_SUCCESS
|| nRet
== TWRC_CANCEL
);
208 // -----------------------------------------------------------------------------
210 BOOL
ImpTwain::InitXfer()
217 ImplOpenSourceManager();
224 bRet
= ImplEnableSource();
228 ImplFallback( TWAIN_EVENT_QUIT
);
233 // -----------------------------------------------------------------------------
235 Bitmap
ImpTwain::GetXferBitmap()
237 Bitmap
aRet( aBitmap
);
242 // -----------------------------------------------------------------------------
244 void ImpTwain::ImplOpenSourceManager()
248 pMod
= new NAMESPACE_VOS( OModule
)();
250 if( pMod
->load( TWAIN_LIBNAME
) )
254 if( ( ( pDSM
= (DSMENTRYPROC
) pMod
->getSymbol( TWAIN_FUNCNAME
) ) != NULL
) &&
255 ( PFUNC( &aAppIdent
, NULL
, DG_CONTROL
, DAT_PARENT
, MSG_OPENDSM
, &hTwainWnd
) == TWRC_SUCCESS
) )
268 // -----------------------------------------------------------------------------
270 void ImpTwain::ImplOpenSource()
274 if( ( PFUNC( &aAppIdent
, NULL
, DG_CONTROL
, DAT_IDENTITY
, MSG_GETDEFAULT
, &aSrcIdent
) == TWRC_SUCCESS
) &&
275 ( PFUNC( &aAppIdent
, NULL
, DG_CONTROL
, DAT_IDENTITY
, MSG_OPENDS
, &aSrcIdent
) == TWRC_SUCCESS
) )
279 // negotiate capabilities
283 TW_CAPABILITY aCap
= { CAP_XFERCOUNT
, TWON_ONEVALUE
, GlobalAlloc( GHND
, sizeof( TW_ONEVALUE
) ) };
284 TW_ONEVALUE
* pVal
= (TW_ONEVALUE
*) GlobalLock( aCap
.hContainer
);
286 pVal
->ItemType
= TWTY_INT16
, pVal
->Item
= 1;
287 GlobalUnlock( aCap
.hContainer
);
288 PFUNC( &aAppIdent
, &aSrcIdent
, DG_CONTROL
, DAT_CAPABILITY
, MSG_SET
, &aCap
);
289 GlobalFree( aCap
.hContainer
);
297 // -----------------------------------------------------------------------------
299 BOOL
ImpTwain::ImplEnableSource()
305 TW_USERINTERFACE aUI
= { TRUE
, TRUE
, hTwainWnd
};
307 aNotifyLink
.Call( (void*) TWAIN_EVENT_SCANNING
);
310 if( PFUNC( &aAppIdent
, &aSrcIdent
, DG_CONTROL
, DAT_USERINTERFACE
, MSG_ENABLEDS
, &aUI
) == TWRC_SUCCESS
)
319 // -----------------------------------------------------------------------------
321 BOOL
ImpTwain::ImplHandleMsg( void* pMsg
)
324 PTWAINMSG pMess
= (PTWAINMSG
) pMsg
;
325 TW_EVENT aEvt
= { pMess
, MSG_NULL
};
327 nRet
= PFUNC( &aAppIdent
, &aSrcIdent
, DG_CONTROL
, DAT_EVENT
, MSG_PROCESSEVENT
, &aEvt
);
329 if( aEvt
.TWMessage
!= MSG_NULL
)
331 switch( aEvt
.TWMessage
)
335 ULONG nEvent
= TWAIN_EVENT_QUIT
;
343 nEvent
= TWAIN_EVENT_XFER
;
346 ImplFallback( nEvent
);
351 ImplFallback( TWAIN_EVENT_QUIT
);
359 nRet
= TWRC_NOTDSEVENT
;
361 return( TWRC_DSEVENT
== nRet
);
364 // -----------------------------------------------------------------------------
366 void ImpTwain::ImplXfer()
372 long nWidth
= aInfo
.ImageWidth
;
373 long nHeight
= aInfo
.ImageLength
;
374 long nXRes
= FIXTOLONG( aInfo
.XResolution
);
375 long nYRes
= FIXTOLONG( aInfo
.YResolution
);
377 if( PFUNC( &aAppIdent
, &aSrcIdent
, DG_IMAGE
, DAT_IMAGEINFO
, MSG_GET
, &aInfo
) == TWRC_SUCCESS
)
379 nWidth
= aInfo
.ImageWidth
;
380 nHeight
= aInfo
.ImageLength
;
381 nXRes
= FIXTOLONG( aInfo
.XResolution
);
382 nYRes
= FIXTOLONG( aInfo
.YResolution
);
385 nWidth
= nHeight
= nXRes
= nYRes
= -1L;
387 switch( PFUNC( &aAppIdent
, &aSrcIdent
, DG_IMAGE
, DAT_IMAGENATIVEXFER
, MSG_GET
, &hDIB
) )
393 case( TWRC_XFERDONE
):
400 const ULONG nSize
= GlobalSize( (HGLOBAL
) hDIB
);
401 char* pBuf
= (char*) GlobalLock( (HGLOBAL
) hDIB
);
405 SvMemoryStream aMemStm
;
406 aMemStm
.SetBuffer( pBuf
, nSize
, FALSE
, nSize
);
407 aBitmap
.Read( aMemStm
, FALSE
);
408 GlobalUnlock( (HGLOBAL
) hDIB
);
411 GlobalFree( (HGLOBAL
) hDIB
);
414 // set resolution of bitmap if neccessary
415 if ( ( nXRes
!= -1 ) && ( nYRes
!= - 1 ) && ( nWidth
!= - 1 ) && ( nHeight
!= - 1 ) )
417 const MapMode
aMapMode( MAP_100TH_INCH
, Point(), Fraction( 100, nXRes
), Fraction( 100, nYRes
) );
418 aBitmap
.SetPrefMapMode( aMapMode
);
419 aBitmap
.SetPrefSize( Size( nWidth
, nHeight
) );
432 // -----------------------------------------------------------------------------
434 void ImpTwain::ImplFallback( ULONG nEvent
)
436 Application::PostUserEvent( LINK( this, ImpTwain
, ImplFallbackHdl
), (void*) nEvent
);
439 // -----------------------------------------------------------------------------
441 IMPL_LINK( ImpTwain
, ImplFallbackHdl
, void*, pData
)
443 const ULONG nEvent
= (ULONG
) pData
;
444 BOOL bFallback
= TRUE
;
451 TW_PENDINGXFERS aXfers
;
453 if( PFUNC( &aAppIdent
, &aSrcIdent
, DG_CONTROL
, DAT_PENDINGXFERS
, MSG_ENDXFER
, &aXfers
) == TWRC_SUCCESS
)
455 if( aXfers
.Count
!= 0 )
456 PFUNC( &aAppIdent
, &aSrcIdent
, DG_CONTROL
, DAT_PENDINGXFERS
, MSG_RESET
, &aXfers
);
465 TW_USERINTERFACE aUI
= { TRUE
, TRUE
, hTwainWnd
};
467 PFUNC( &aAppIdent
, &aSrcIdent
, DG_CONTROL
, DAT_USERINTERFACE
, MSG_DISABLEDS
, &aUI
);
474 PFUNC( &aAppIdent
, NULL
, DG_CONTROL
, DAT_IDENTITY
, MSG_CLOSEDS
, &aSrcIdent
);
481 PFUNC( &aAppIdent
, NULL
, DG_CONTROL
, DAT_PARENT
, MSG_CLOSEDSM
, &hTwainWnd
);
496 if( nEvent
!= TWAIN_EVENT_NONE
)
497 aNotifyLink
.Call( (void*) nEvent
);
505 ImplFallback( nEvent
);
510 // -----------------------------------------------------------------------------
512 IMPL_LINK( ImpTwain
, ImplDestroyHdl
, void*, p
)
517 WinDestroyWindow( hWndTwain
);
524 DestroyWindow( hTwainWnd
);
527 UnhookWindowsHookEx( hTwainHook
);
532 pImpTwainInstance
= NULL
;