2010-10-12 15:57:08 +02:00
|
|
|
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
re-base on ALv2 code. Includes (at least) relevant parts of:
linecap: Reintegrating finished LineCap feature
Patch contributed by Regina Henschel
http://svn.apache.org/viewvc?view=revision&revision=1232507
Patches contributed by Sven Jacobi
impress212: #i81610# fixed animation export
http://svn.apache.org/viewvc?view=revision&revision=1167620
impress212: drawinglayer gbuild environment changes
http://svn.apache.org/viewvc?view=revision&revision=1167627
http://svn.apache.org/viewvc?view=revision&revision=1167628
impress212: DffPropSet -> minor code improvements, removing table
http://svn.apache.org/viewvc?view=revision&revision=1167634
impress212: #158494# fixed excel import (text rotation)
http://svn.apache.org/viewvc?view=revision&revision=1167638
Patches contributed by Armin Le Grand
Svg: Reintegrated Svg replacement from /branches/alg/svgreplavement
http://svn.apache.org/viewvc?view=revision&revision=1220836
#118728# changed indentifying definitions for Svg file detection
http://svn.apache.org/viewvc?view=revision&revision=1229961
#118838# LineGeometry creation for complicated cases optimized to
create single Polygons
http://svn.apache.org/viewvc?view=revision&revision=1236232
#119176# corrected file type detection for SVG for svg files
without xml header
http://svn.apache.org/viewvc?view=revision&revision=1309445
#118728# Extended Svg file detection
http://svn.apache.org/viewvc?view=revision&revision=1230531
#118529# solve break converters and convert commands for OLEs and images
http://svn.apache.org/viewvc?view=revision&revision=1186168
svg: added WaE changes from branch svgreplacement to trunc
http://svn.apache.org/viewvc?view=revision&revision=1222974
svg: corrected missing member initialization
http://svn.apache.org/viewvc?view=revision&revision=1226134
fix for #118525#: Using primitives for chart sub-geometry visualisation
http://svn.apache.org/viewvc?view=revision&revision=1226879
#118898# Adapted ImpGraphic::ImplGetBitmap to correctly convert
metafiles to bitmapEx ...
http://svn.apache.org/viewvc?view=revision&revision=1293316
fix for #118525#: removed no longer used variable maOriginalMapMode, one
more exception eliminated
http://svn.apache.org/viewvc?view=revision&revision=1227097
#16758# Added buffering to the VDev usages of the VclProcessor2D derivates...
http://svn.apache.org/viewvc?view=revision&revision=1229521
#116758# Secured VDev buffer device to Vcl deinit
http://svn.apache.org/viewvc?view=revision&revision=1230574
#116758# added remembering allocated VDevs for VDevBuffer to be able to also
delete these when vcl goes down; it should never happen, but You never know
http://svn.apache.org/viewvc?view=revision&revision=1230927
#118730# Changed SvgClipPathNode to use MaskPrimitive2D for primitive
representation instead of TransparencePrimitive2D
http://svn.apache.org/viewvc?view=revision&revision=1231198
#118822# secured 3D geometry creation (slices) by subdividing the 2D
source polyPolygon early
http://svn.apache.org/viewvc?view=revision&revision=1234749
#118829# enhanced Svg gradient quality, obstacles avoided
http://svn.apache.org/viewvc?view=revision&revision=1235361
#118834# Unified usage of TextBreakupHelper as single tooling class
for i18n text primitive breakup
http://svn.apache.org/viewvc?view=revision&revision=1236110
#118853# added square pixel size limit to conversion of
TransparencePrimitive2D to Metafile action
http://svn.apache.org/viewvc?view=revision&revision=1237656
#118824# coreccted mirroring and boundrect when the graphicmanager
is used for bitmap output
http://svn.apache.org/viewvc?view=revision&revision=1240097
#115092# Corrected VclProcessor2D::RenderPolygonStrokePrimitive2D for
various optimization scenarios
http://svn.apache.org/viewvc?view=revision&revision=1241434
#118783# Corrected errors in ID strings, corrected Svg line/fill export,
corrected polygon close state
http://svn.apache.org/viewvc?view=revision&revision=1232006
#118796# corrected null-pointer usage in SVG text exporter
http://svn.apache.org/viewvc?view=revision&revision=1240262
#118729# Use GraphicStreamUrl and GraphicUrl to allow multi image
import with linked graphics, too
http://svn.apache.org/viewvc?view=revision&revision=1229962
#118898# corrected error in GDIMetaFile::GetBoundRect in handling
MetaFloatTransparentAction
http://svn.apache.org/viewvc?view=revision&revision=1293349
#118855# Corrected handling of possibly created empty clipRegions
after PolyPolygon clipping
http://svn.apache.org/viewvc?view=revision&revision=1237725
#115962# Better (but not yet optimal, see comments in task) handling
of MetaFloatTransparentAction in PDF export
http://svn.apache.org/viewvc?view=revision&revision=1241078
IP clearance: #118466# This patch removes librsvg, libcroco, libgsf, ...
http://svn.apache.org/viewvc?view=revision&revision=1200879
118779# Added svg content streaming in/out to ImpGraphic stream operators
http://svn.apache.org/viewvc?view=revision&revision=1231908
linecap: correctons for WaE and mac drawing
http://svn.apache.org/viewvc?view=revision&revision=1232793
svg: uses current system Dpi for Svg replacement image creation
http://svn.apache.org/viewvc?view=revision&revision=1233948
Patches contributed by Mathias Bauer (and others)
gnumake4 work variously
http://svn.apache.org/viewvc?view=revision&revision=1394326
http://svn.apache.org/viewvc?view=revision&revision=1396797
http://svn.apache.org/viewvc?view=revision&revision=1397315
http://svn.apache.org/viewvc?view=revision&revision=1394326
Remove duplicate header includes.
cws mba34issues01: #i117720#: convert assertion into warning
http://svn.apache.org/viewvc?view=revision&revision=1172352
118485 - Styles for OLEs are not saved. Submitted by Armin Le Grand.
http://svn.apache.org/viewvc?view=revision&revision=1182166
cws mba34issues01: #i117714#: remove assertion
http://svn.apache.org/viewvc?view=revision&revision=1172357
Patch contributed by Jurgen Schmidt
add some additional checks to ensure proper reading operations
http://svn.apache.org/viewvc?view=revision&revision=1209022
mostly prefer our stream / bounds checking work.
Patches contributed by Herbert Duerr
#i118816# add clarifying comment regarding Font::*Color*() methods
http://svn.apache.org/viewvc?view=revision&revision=1233833
extend macro->string handling for empty strings
http://svn.apache.org/viewvc?view=revision&revision=1175801
avoid magic constants for SALCOLOR_NONE
http://svn.apache.org/viewvc?view=revision&revision=1177543
initialize slant properly in ImplFontMetricData constructor (author=iorsh)
http://svn.apache.org/viewvc?view=revision&revision=1177551
#i118675# make check for extension updates more stable
http://svn.apache.org/viewvc?view=revision&revision=1214797
#a118617# remove VBasicEventListener.dll binary
There are no known users depending on its CLSID
http://svn.apache.org/viewvc?view=revision&revision=1203697
Patches contributed by Ariel Constenla-Haile
Fix build breaker on Linux/gcc
http://svn.apache.org/viewvc?view=revision&revision=1221104
Fix crash when trying to instantiate css.graphic.GraphicRasterizer_RSVG
http://svn.apache.org/viewvc?view=revision&revision=1215559
Patches contributed by Oliver-Rainer Wittmann
sw34bf06: #i117962# - method <SwFlyFrm::IsPaint(..)> - consider
instances of <SwFlyDrawObj>
http://svn.apache.org/viewvc?view=revision&revision=1172120
sw34bf06: #i117783# - Writer's implementation of XPagePrintable -
apply print settings to new printing routines
http://svn.apache.org/viewvc?view=revision&revision=1172115
gnumake4 work variously from Hans-Joachim Lankenau
http://svn.apache.org/viewvc?view=revision&revision=1397315
http://svn.apache.org/viewvc?view=revision&revision=1396797
http://svn.apache.org/viewvc?view=revision&revision=1396782
http://svn.apache.org/viewvc?view=revision&revision=1394707
plus some amount of re-splitting of legacy headers.
Patch contributed by Pavel Janik
WaE: Remove unused variables.
http://svn.apache.org/viewvc?view=revision&revision=1230697
Patches contributed by Takashi Ono
mingwport35: i#117795: MinGW port fix for vcl2gnumake
http://svn.apache.org/viewvc?view=revision&revision=1172091
mingwport35: i#117795: MinGW port fix for vcl2gnumake
http://svn.apache.org/viewvc?view=revision&revision=1172091
Patch contributed by Christian Lippka
impress212: #i98044# re enable Text menu for outline and title shapes
http://svn.apache.org/viewvc?view=revision&revision=1167639
Patch contributed by Andre Fischer
118674: Made category B code optional and disabled by default.
http://svn.apache.org/viewvc?view=revision&revision=1215131
118881: Ignore empty paragraphs after bullets.
http://svn.apache.org/viewvc?view=revision&revision=1296205
Patches contributed by Philipp Lohmann
ooo340fixes: #i117780# use rtl allocator
http://svn.apache.org/viewvc?view=revision&revision=1172087
ooo34gsl02: #i117807# fix an off by one error (index actually
inside the pfb section header)
http://svn.apache.org/viewvc?view=revision&revision=1167576
various cleanups, related compilation fixes, warning cleanups, re-working
of obsolete stl template pieces to use boost instead, changed string
classes, re-adapt KDE about data, about dialog, fixing warnings,
and other fixes & improvements.
Disable svg import / render for about/ branding code-paths for now.
Restore full icon theme set.
Remove OS/2 conditionals and sources.
Remove conflicting gtk/full-screen monitors support.
Retain existing svg rasterizer files - temporarily disabled.
Standardize stringificaiton and fixup dllpostfix issues.
Rename SvgGradientHelper::== to equalTo to avoid overloading issues.
Use the flat GdiPlus API for LineCaps calls.
2012-10-09 12:22:23 +01:00
|
|
|
/*
|
|
|
|
* This file is part of the LibreOffice project.
|
|
|
|
*
|
|
|
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
|
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
|
|
|
*
|
|
|
|
* This file incorporates work covered by the following license notice:
|
|
|
|
*
|
|
|
|
* Licensed to the Apache Software Foundation (ASF) under one or more
|
|
|
|
* contributor license agreements. See the NOTICE file distributed
|
|
|
|
* with this work for additional information regarding copyright
|
|
|
|
* ownership. The ASF licenses this file to you under the Apache
|
|
|
|
* License, Version 2.0 (the "License"); you may not use this file
|
|
|
|
* except in compliance with the License. You may obtain a copy of
|
|
|
|
* the License at http://www.apache.org/licenses/LICENSE-2.0 .
|
|
|
|
*/
|
2000-09-18 15:18:56 +00:00
|
|
|
|
2003-04-08 14:40:31 +00:00
|
|
|
#include <com/sun/star/uno/Any.hxx>
|
|
|
|
#include <com/sun/star/uno/Reference.hxx>
|
|
|
|
#include <com/sun/star/util/XCloseable.hpp>
|
|
|
|
#include <com/sun/star/util/XCloseBroadcaster.hpp>
|
|
|
|
#include <com/sun/star/util/XCloseListener.hpp>
|
|
|
|
#include <com/sun/star/frame/XFrame.hpp>
|
2012-12-14 12:58:00 +02:00
|
|
|
#include <com/sun/star/frame/Desktop.hpp>
|
2003-04-08 14:40:31 +00:00
|
|
|
#include <com/sun/star/beans/XPropertySet.hpp>
|
|
|
|
#include <cppuhelper/implbase1.hxx>
|
|
|
|
#include <comphelper/processfactory.hxx>
|
|
|
|
|
2011-03-28 16:35:28 +01:00
|
|
|
#include <prewin.h>
|
2011-03-26 00:10:06 +01:00
|
|
|
#include <windows.h>
|
2011-03-28 16:35:28 +01:00
|
|
|
#include <postwin.h>
|
2000-09-18 15:18:56 +00:00
|
|
|
#include <math.h>
|
|
|
|
#include <tools/stream.hxx>
|
2012-07-01 01:06:04 +02:00
|
|
|
#include <tools/helpers.hxx>
|
2010-10-16 03:15:49 -05:00
|
|
|
#include <osl/mutex.hxx>
|
2010-10-16 04:30:41 -05:00
|
|
|
#include <osl/module.hxx>
|
2000-09-18 15:18:56 +00:00
|
|
|
#include <vcl/svapp.hxx>
|
|
|
|
#include <vcl/wrkwin.hxx>
|
|
|
|
#include <vcl/sysdata.hxx>
|
|
|
|
#include "scanner.hxx"
|
2008-01-14 14:04:05 +00:00
|
|
|
|
2012-12-27 14:09:50 +02:00
|
|
|
#if defined _MSC_VER
|
2008-01-14 14:04:05 +00:00
|
|
|
#pragma warning (push,1)
|
|
|
|
#pragma warning (disable:4668)
|
2012-04-16 16:24:59 +02:00
|
|
|
#endif
|
2000-09-18 15:18:56 +00:00
|
|
|
#include "twain/twain.h"
|
2012-12-27 14:09:50 +02:00
|
|
|
#if defined _MSC_VER
|
2008-01-14 14:04:05 +00:00
|
|
|
#pragma warning (pop)
|
2012-04-16 16:24:59 +02:00
|
|
|
#endif
|
2000-09-18 15:18:56 +00:00
|
|
|
|
2003-04-08 14:40:31 +00:00
|
|
|
using namespace ::com::sun::star;
|
|
|
|
|
2000-09-18 15:18:56 +00:00
|
|
|
#define TWAIN_EVENT_NONE 0x00000000UL
|
|
|
|
#define TWAIN_EVENT_QUIT 0x00000001UL
|
|
|
|
#define TWAIN_EVENT_SCANNING 0x00000002UL
|
|
|
|
#define TWAIN_EVENT_XFER 0x00000004UL
|
|
|
|
|
|
|
|
#define PFUNC (*pDSM)
|
|
|
|
#define PTWAINMSG MSG*
|
|
|
|
#define FIXTODOUBLE( nFix ) ((double)nFix.Whole+(double)nFix.Frac/65536.)
|
|
|
|
#define FIXTOLONG( nFix ) ((long)floor(FIXTODOUBLE(nFix)+0.5))
|
|
|
|
|
2010-06-25 13:15:03 +02:00
|
|
|
#if defined WNT
|
2000-09-18 15:18:56 +00:00
|
|
|
#define TWAIN_LIBNAME "TWAIN_32.DLL"
|
|
|
|
#define TWAIN_FUNCNAME "DSM_Entry"
|
|
|
|
#endif
|
|
|
|
|
|
|
|
enum TwainState
|
|
|
|
{
|
|
|
|
TWAIN_STATE_NONE = 0,
|
|
|
|
TWAIN_STATE_SCANNING = 1,
|
|
|
|
TWAIN_STATE_DONE = 2,
|
|
|
|
TWAIN_STATE_CANCELED = 3
|
|
|
|
};
|
|
|
|
|
2005-11-11 10:05:48 +00:00
|
|
|
class ImpTwain : public ::cppu::WeakImplHelper1< util::XCloseListener >
|
2003-04-08 14:40:31 +00:00
|
|
|
{
|
2005-11-11 10:05:48 +00:00
|
|
|
friend LRESULT CALLBACK TwainMsgProc( int nCode, WPARAM wParam, LPARAM lParam );
|
|
|
|
|
|
|
|
uno::Reference< uno::XInterface > mxSelfRef;
|
|
|
|
uno::Reference< scanner::XScannerManager > mxMgr;
|
|
|
|
ScannerManager& mrMgr;
|
|
|
|
TW_IDENTITY aAppIdent;
|
|
|
|
TW_IDENTITY aSrcIdent;
|
|
|
|
Link aNotifyLink;
|
|
|
|
DSMENTRYPROC pDSM;
|
2010-10-16 04:30:41 -05:00
|
|
|
osl::Module* pMod;
|
2005-11-11 10:05:48 +00:00
|
|
|
ULONG nCurState;
|
|
|
|
HWND hTwainWnd;
|
|
|
|
HHOOK hTwainHook;
|
|
|
|
bool mbCloseFrameOnExit;
|
|
|
|
|
|
|
|
bool ImplHandleMsg( void* pMsg );
|
|
|
|
void ImplCreate();
|
|
|
|
void ImplOpenSourceManager();
|
|
|
|
void ImplOpenSource();
|
|
|
|
bool ImplEnableSource();
|
|
|
|
void ImplXfer();
|
|
|
|
void ImplFallback( ULONG nEvent );
|
|
|
|
void ImplSendCloseEvent();
|
|
|
|
void ImplDeregisterCloseListener();
|
|
|
|
void ImplRegisterCloseListener();
|
|
|
|
uno::Reference< frame::XFrame > ImplGetActiveFrame();
|
|
|
|
uno::Reference< util::XCloseBroadcaster > ImplGetActiveFrameCloseBroadcaster();
|
|
|
|
|
|
|
|
DECL_LINK( ImplFallbackHdl, void* );
|
|
|
|
DECL_LINK( ImplDestroyHdl, void* );
|
2000-09-18 15:18:56 +00:00
|
|
|
|
2005-11-11 10:05:48 +00:00
|
|
|
// from util::XCloseListener
|
|
|
|
virtual void SAL_CALL queryClosing( const lang::EventObject& Source, sal_Bool GetsOwnership ) throw (util::CloseVetoException, uno::RuntimeException);
|
|
|
|
virtual void SAL_CALL notifyClosing( const lang::EventObject& Source ) throw (uno::RuntimeException);
|
2000-09-18 15:18:56 +00:00
|
|
|
|
2005-11-11 10:05:48 +00:00
|
|
|
// from lang::XEventListener
|
|
|
|
virtual void SAL_CALL disposing( const lang::EventObject& Source ) throw (uno::RuntimeException);
|
2000-09-18 15:18:56 +00:00
|
|
|
|
|
|
|
public:
|
|
|
|
|
2005-11-11 10:05:48 +00:00
|
|
|
ImpTwain( ScannerManager& rMgr, const Link& rNotifyLink );
|
|
|
|
~ImpTwain();
|
2000-09-18 15:18:56 +00:00
|
|
|
|
2005-11-11 10:05:48 +00:00
|
|
|
void Destroy();
|
2003-04-08 14:40:31 +00:00
|
|
|
|
2005-11-11 10:05:48 +00:00
|
|
|
bool SelectSource();
|
|
|
|
bool InitXfer();
|
2000-09-18 15:18:56 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
static ImpTwain* pImpTwainInstance = NULL;
|
|
|
|
|
|
|
|
LRESULT CALLBACK TwainWndProc( HWND hWnd,UINT nMsg, WPARAM nPar1, LPARAM nPar2 )
|
|
|
|
{
|
|
|
|
return DefWindowProc( hWnd, nMsg, nPar1, nPar2 );
|
|
|
|
}
|
|
|
|
|
|
|
|
LRESULT CALLBACK TwainMsgProc( int nCode, WPARAM wParam, LPARAM lParam )
|
|
|
|
{
|
|
|
|
MSG* pMsg = (MSG*) lParam;
|
|
|
|
|
2005-11-11 10:05:48 +00:00
|
|
|
if( ( nCode < 0 ) || ( pImpTwainInstance->hTwainWnd != pMsg->hwnd ) || !pImpTwainInstance->ImplHandleMsg( (void*) lParam ) )
|
2000-09-18 15:18:56 +00:00
|
|
|
{
|
|
|
|
return CallNextHookEx( pImpTwainInstance->hTwainHook, nCode, wParam, lParam );
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
pMsg->message = WM_USER;
|
|
|
|
pMsg->lParam = 0;
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2005-11-11 10:05:48 +00:00
|
|
|
// #107835# hold reference to ScannerManager, to prevent premature death
|
|
|
|
ImpTwain::ImpTwain( ScannerManager& rMgr, const Link& rNotifyLink ) :
|
|
|
|
mxMgr( uno::Reference< scanner::XScannerManager >( static_cast< OWeakObject* >( &rMgr ), uno::UNO_QUERY) ),
|
2012-02-15 14:35:19 +00:00
|
|
|
mrMgr( rMgr ),
|
2005-11-11 10:05:48 +00:00
|
|
|
aNotifyLink( rNotifyLink ),
|
|
|
|
pDSM( NULL ),
|
|
|
|
pMod( NULL ),
|
2012-02-15 14:35:19 +00:00
|
|
|
nCurState( 1 ),
|
2005-11-11 10:05:48 +00:00
|
|
|
hTwainWnd( 0 ),
|
|
|
|
hTwainHook( 0 ),
|
|
|
|
mbCloseFrameOnExit( false )
|
2000-09-18 15:18:56 +00:00
|
|
|
{
|
2003-04-08 14:40:31 +00:00
|
|
|
// setup TWAIN window
|
2000-09-18 15:18:56 +00:00
|
|
|
pImpTwainInstance = this;
|
|
|
|
|
|
|
|
aAppIdent.Id = 0;
|
|
|
|
aAppIdent.Version.MajorNum = 1;
|
|
|
|
aAppIdent.Version.MinorNum = 0;
|
|
|
|
aAppIdent.Version.Language = TWLG_USA;
|
|
|
|
aAppIdent.Version.Country = TWCY_USA;
|
|
|
|
aAppIdent.ProtocolMajor = TWON_PROTOCOLMAJOR;
|
|
|
|
aAppIdent.ProtocolMinor = TWON_PROTOCOLMINOR;
|
|
|
|
aAppIdent.SupportedGroups = DG_IMAGE | DG_CONTROL;
|
2005-11-11 10:05:48 +00:00
|
|
|
strncpy( aAppIdent.Version.Info, "8.0", 32 );
|
2003-04-08 14:40:31 +00:00
|
|
|
aAppIdent.Version.Info[32] = aAppIdent.Version.Info[33] = 0;
|
|
|
|
strncpy( aAppIdent.Manufacturer, "Sun Microsystems", 32 );
|
|
|
|
aAppIdent.Manufacturer[32] = aAppIdent.Manufacturer[33] = 0;
|
|
|
|
strncpy( aAppIdent.ProductFamily,"Office", 32 );
|
|
|
|
aAppIdent.ProductFamily[32] = aAppIdent.ProductFamily[33] = 0;
|
|
|
|
strncpy( aAppIdent.ProductName, "Office", 32 );
|
|
|
|
aAppIdent.ProductName[32] = aAppIdent.ProductName[33] = 0;
|
2000-09-18 15:18:56 +00:00
|
|
|
|
2005-11-11 10:05:48 +00:00
|
|
|
WNDCLASS aWc = { 0, &TwainWndProc, 0, sizeof( WNDCLASS ), GetModuleHandle( NULL ), NULL, NULL, NULL, NULL, "TwainClass" };
|
2000-09-18 15:18:56 +00:00
|
|
|
RegisterClass( &aWc );
|
2005-11-11 10:05:48 +00:00
|
|
|
|
|
|
|
hTwainWnd = CreateWindowEx( WS_EX_TOPMOST, aWc.lpszClassName, "TWAIN", 0, 0, 0, 0, 0, HWND_DESKTOP, NULL, aWc.hInstance, 0 );
|
2000-09-18 15:18:56 +00:00
|
|
|
hTwainHook = SetWindowsHookEx( WH_GETMESSAGE, &TwainMsgProc, NULL, GetCurrentThreadId() );
|
2003-04-08 14:40:31 +00:00
|
|
|
|
2010-11-25 21:22:04 +02:00
|
|
|
// block destruction until ImplDestroyHdl is called
|
2005-11-11 10:05:48 +00:00
|
|
|
mxSelfRef = static_cast< ::cppu::OWeakObject* >( this );
|
2000-09-18 15:18:56 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
ImpTwain::~ImpTwain()
|
|
|
|
{
|
2003-04-08 14:40:31 +00:00
|
|
|
// are we responsible for application shutdown?
|
|
|
|
if( mbCloseFrameOnExit )
|
|
|
|
ImplSendCloseEvent();
|
2000-09-18 15:18:56 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void ImpTwain::Destroy()
|
|
|
|
{
|
|
|
|
ImplFallback( TWAIN_EVENT_NONE );
|
|
|
|
Application::PostUserEvent( LINK( this, ImpTwain, ImplDestroyHdl ), NULL );
|
|
|
|
}
|
|
|
|
|
2005-11-11 10:05:48 +00:00
|
|
|
bool ImpTwain::SelectSource()
|
2000-09-18 15:18:56 +00:00
|
|
|
{
|
|
|
|
TW_UINT16 nRet = TWRC_FAILURE;
|
|
|
|
|
|
|
|
ImplOpenSourceManager();
|
|
|
|
|
|
|
|
if( 3 == nCurState )
|
|
|
|
{
|
|
|
|
TW_IDENTITY aIdent;
|
|
|
|
|
|
|
|
aIdent.Id = 0, aIdent.ProductName[ 0 ] = '\0';
|
|
|
|
aNotifyLink.Call( (void*) TWAIN_EVENT_SCANNING );
|
|
|
|
nRet = PFUNC( &aAppIdent, NULL, DG_CONTROL, DAT_IDENTITY, MSG_USERSELECT, &aIdent );
|
|
|
|
}
|
|
|
|
|
|
|
|
ImplFallback( TWAIN_EVENT_QUIT );
|
|
|
|
|
2002-07-04 14:22:46 +00:00
|
|
|
return( TWRC_SUCCESS == nRet );
|
2000-09-18 15:18:56 +00:00
|
|
|
}
|
|
|
|
|
2005-11-11 10:05:48 +00:00
|
|
|
bool ImpTwain::InitXfer()
|
2000-09-18 15:18:56 +00:00
|
|
|
{
|
2005-11-11 10:05:48 +00:00
|
|
|
bool bRet = false;
|
2000-09-18 15:18:56 +00:00
|
|
|
|
|
|
|
ImplOpenSourceManager();
|
|
|
|
|
|
|
|
if( 3 == nCurState )
|
|
|
|
{
|
|
|
|
ImplOpenSource();
|
|
|
|
|
|
|
|
if( 4 == nCurState )
|
|
|
|
bRet = ImplEnableSource();
|
|
|
|
}
|
|
|
|
|
|
|
|
if( !bRet )
|
|
|
|
ImplFallback( TWAIN_EVENT_QUIT );
|
|
|
|
|
|
|
|
return bRet;
|
|
|
|
}
|
|
|
|
|
|
|
|
void ImpTwain::ImplOpenSourceManager()
|
|
|
|
{
|
|
|
|
if( 1 == nCurState )
|
|
|
|
{
|
2013-04-07 12:06:47 +02:00
|
|
|
pMod = new ::osl::Module( OUString() );
|
2000-09-18 15:18:56 +00:00
|
|
|
|
2013-04-07 12:06:47 +02:00
|
|
|
if( pMod->load( OUString( TWAIN_LIBNAME ) ) )
|
2000-09-18 15:18:56 +00:00
|
|
|
{
|
|
|
|
nCurState = 2;
|
|
|
|
|
2012-06-02 12:27:08 -05:00
|
|
|
if( ( ( pDSM = (DSMENTRYPROC) pMod->getSymbol( String( TWAIN_FUNCNAME ) ) ) != NULL ) &&
|
2000-09-18 15:18:56 +00:00
|
|
|
( PFUNC( &aAppIdent, NULL, DG_CONTROL, DAT_PARENT, MSG_OPENDSM, &hTwainWnd ) == TWRC_SUCCESS ) )
|
|
|
|
{
|
|
|
|
nCurState = 3;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
delete pMod;
|
|
|
|
pMod = NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void ImpTwain::ImplOpenSource()
|
|
|
|
{
|
|
|
|
if( 3 == nCurState )
|
|
|
|
{
|
|
|
|
if( ( PFUNC( &aAppIdent, NULL, DG_CONTROL, DAT_IDENTITY, MSG_GETDEFAULT, &aSrcIdent ) == TWRC_SUCCESS ) &&
|
|
|
|
( PFUNC( &aAppIdent, NULL, DG_CONTROL, DAT_IDENTITY, MSG_OPENDS, &aSrcIdent ) == TWRC_SUCCESS ) )
|
|
|
|
{
|
|
|
|
TW_CAPABILITY aCap = { CAP_XFERCOUNT, TWON_ONEVALUE, GlobalAlloc( GHND, sizeof( TW_ONEVALUE ) ) };
|
|
|
|
TW_ONEVALUE* pVal = (TW_ONEVALUE*) GlobalLock( aCap.hContainer );
|
|
|
|
|
|
|
|
pVal->ItemType = TWTY_INT16, pVal->Item = 1;
|
|
|
|
GlobalUnlock( aCap.hContainer );
|
|
|
|
PFUNC( &aAppIdent, &aSrcIdent, DG_CONTROL, DAT_CAPABILITY, MSG_SET, &aCap );
|
|
|
|
GlobalFree( aCap.hContainer );
|
|
|
|
nCurState = 4;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2005-11-11 10:05:48 +00:00
|
|
|
bool ImpTwain::ImplEnableSource()
|
2000-09-18 15:18:56 +00:00
|
|
|
{
|
2005-11-11 10:05:48 +00:00
|
|
|
bool bRet = false;
|
2000-09-18 15:18:56 +00:00
|
|
|
|
|
|
|
if( 4 == nCurState )
|
|
|
|
{
|
2005-11-11 10:05:48 +00:00
|
|
|
TW_USERINTERFACE aUI = { true, true, hTwainWnd };
|
2000-09-18 15:18:56 +00:00
|
|
|
|
|
|
|
aNotifyLink.Call( (void*) TWAIN_EVENT_SCANNING );
|
|
|
|
nCurState = 5;
|
|
|
|
|
2010-11-25 21:22:04 +02:00
|
|
|
// register as vetoable close listener, to prevent application to die under us
|
2003-04-08 14:40:31 +00:00
|
|
|
ImplRegisterCloseListener();
|
|
|
|
|
2000-09-18 15:18:56 +00:00
|
|
|
if( PFUNC( &aAppIdent, &aSrcIdent, DG_CONTROL, DAT_USERINTERFACE, MSG_ENABLEDS, &aUI ) == TWRC_SUCCESS )
|
2003-04-08 14:40:31 +00:00
|
|
|
{
|
2005-11-11 10:05:48 +00:00
|
|
|
bRet = true;
|
2003-04-08 14:40:31 +00:00
|
|
|
}
|
2000-09-18 15:18:56 +00:00
|
|
|
else
|
2003-04-08 14:40:31 +00:00
|
|
|
{
|
2000-09-18 15:18:56 +00:00
|
|
|
nCurState = 4;
|
2003-04-08 14:40:31 +00:00
|
|
|
|
2010-11-25 21:22:04 +02:00
|
|
|
// deregister as vetoable close listener, dialog failed
|
2003-04-08 14:40:31 +00:00
|
|
|
ImplDeregisterCloseListener();
|
|
|
|
}
|
2000-09-18 15:18:56 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return bRet;
|
|
|
|
}
|
|
|
|
|
2005-11-11 10:05:48 +00:00
|
|
|
bool ImpTwain::ImplHandleMsg( void* pMsg )
|
2000-09-18 15:18:56 +00:00
|
|
|
{
|
|
|
|
TW_UINT16 nRet;
|
|
|
|
PTWAINMSG pMess = (PTWAINMSG) pMsg;
|
|
|
|
TW_EVENT aEvt = { pMess, MSG_NULL };
|
|
|
|
|
|
|
|
nRet = PFUNC( &aAppIdent, &aSrcIdent, DG_CONTROL, DAT_EVENT, MSG_PROCESSEVENT, &aEvt );
|
|
|
|
|
|
|
|
if( aEvt.TWMessage != MSG_NULL )
|
|
|
|
{
|
|
|
|
switch( aEvt.TWMessage )
|
|
|
|
{
|
|
|
|
case MSG_XFERREADY:
|
|
|
|
{
|
|
|
|
ULONG nEvent = TWAIN_EVENT_QUIT;
|
|
|
|
|
|
|
|
if( 5 == nCurState )
|
|
|
|
{
|
|
|
|
nCurState = 6;
|
|
|
|
ImplXfer();
|
|
|
|
|
2005-11-11 10:05:48 +00:00
|
|
|
if( mrMgr.GetData() )
|
2000-09-18 15:18:56 +00:00
|
|
|
nEvent = TWAIN_EVENT_XFER;
|
|
|
|
}
|
|
|
|
|
|
|
|
ImplFallback( nEvent );
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case MSG_CLOSEDSREQ:
|
|
|
|
ImplFallback( TWAIN_EVENT_QUIT );
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
nRet = TWRC_NOTDSEVENT;
|
|
|
|
|
|
|
|
return( TWRC_DSEVENT == nRet );
|
|
|
|
}
|
|
|
|
|
|
|
|
void ImpTwain::ImplXfer()
|
|
|
|
{
|
|
|
|
if( nCurState == 6 )
|
|
|
|
{
|
|
|
|
TW_IMAGEINFO aInfo;
|
|
|
|
TW_UINT32 hDIB = 0;
|
|
|
|
long nWidth, nHeight, nXRes, nYRes;
|
|
|
|
|
|
|
|
if( PFUNC( &aAppIdent, &aSrcIdent, DG_IMAGE, DAT_IMAGEINFO, MSG_GET, &aInfo ) == TWRC_SUCCESS )
|
|
|
|
{
|
|
|
|
nWidth = aInfo.ImageWidth;
|
|
|
|
nHeight = aInfo.ImageLength;
|
|
|
|
nXRes = FIXTOLONG( aInfo.XResolution );
|
|
|
|
nYRes = FIXTOLONG( aInfo.YResolution );
|
|
|
|
}
|
|
|
|
else
|
|
|
|
nWidth = nHeight = nXRes = nYRes = -1L;
|
|
|
|
|
|
|
|
switch( PFUNC( &aAppIdent, &aSrcIdent, DG_IMAGE, DAT_IMAGENATIVEXFER, MSG_GET, &hDIB ) )
|
|
|
|
{
|
|
|
|
case( TWRC_CANCEL ):
|
|
|
|
nCurState = 7;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case( TWRC_XFERDONE ):
|
|
|
|
{
|
2005-11-11 10:05:48 +00:00
|
|
|
if( hDIB )
|
2000-09-18 15:18:56 +00:00
|
|
|
{
|
|
|
|
if( ( nXRes != -1 ) && ( nYRes != - 1 ) && ( nWidth != - 1 ) && ( nHeight != - 1 ) )
|
|
|
|
{
|
|
|
|
// set resolution of bitmap
|
|
|
|
BITMAPINFOHEADER* pBIH = (BITMAPINFOHEADER*) GlobalLock( (HGLOBAL) hDIB );
|
|
|
|
static const double fFactor = 100.0 / 2.54;
|
|
|
|
|
|
|
|
pBIH->biXPelsPerMeter = FRound( fFactor * nXRes );
|
|
|
|
pBIH->biYPelsPerMeter = FRound( fFactor * nYRes );
|
|
|
|
|
|
|
|
GlobalUnlock( (HGLOBAL) hDIB );
|
|
|
|
}
|
|
|
|
|
2005-11-11 10:05:48 +00:00
|
|
|
mrMgr.SetData( (void*)(long) hDIB );
|
2000-09-18 15:18:56 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
GlobalFree( (HGLOBAL) hDIB );
|
|
|
|
|
|
|
|
nCurState = 7;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void ImpTwain::ImplFallback( ULONG nEvent )
|
|
|
|
{
|
|
|
|
Application::PostUserEvent( LINK( this, ImpTwain, ImplFallbackHdl ), (void*) nEvent );
|
|
|
|
}
|
|
|
|
|
|
|
|
IMPL_LINK( ImpTwain, ImplFallbackHdl, void*, pData )
|
|
|
|
{
|
|
|
|
const ULONG nEvent = (ULONG) pData;
|
2005-11-11 10:05:48 +00:00
|
|
|
bool bFallback = true;
|
2000-09-18 15:18:56 +00:00
|
|
|
|
|
|
|
switch( nCurState )
|
|
|
|
{
|
|
|
|
case( 7 ):
|
|
|
|
case( 6 ):
|
|
|
|
{
|
|
|
|
TW_PENDINGXFERS aXfers;
|
|
|
|
|
|
|
|
if( PFUNC( &aAppIdent, &aSrcIdent, DG_CONTROL, DAT_PENDINGXFERS, MSG_ENDXFER, &aXfers ) == TWRC_SUCCESS )
|
|
|
|
{
|
|
|
|
if( aXfers.Count != 0 )
|
|
|
|
PFUNC( &aAppIdent, &aSrcIdent, DG_CONTROL, DAT_PENDINGXFERS, MSG_RESET, &aXfers );
|
|
|
|
}
|
|
|
|
|
|
|
|
nCurState = 5;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case( 5 ):
|
|
|
|
{
|
2005-11-11 10:05:48 +00:00
|
|
|
TW_USERINTERFACE aUI = { true, true, hTwainWnd };
|
2000-09-18 15:18:56 +00:00
|
|
|
|
|
|
|
PFUNC( &aAppIdent, &aSrcIdent, DG_CONTROL, DAT_USERINTERFACE, MSG_DISABLEDS, &aUI );
|
|
|
|
nCurState = 4;
|
2003-04-08 14:40:31 +00:00
|
|
|
|
2010-11-25 21:22:04 +02:00
|
|
|
// deregister as vetoable close listener
|
2003-04-08 14:40:31 +00:00
|
|
|
ImplDeregisterCloseListener();
|
2000-09-18 15:18:56 +00:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case( 4 ):
|
|
|
|
{
|
|
|
|
PFUNC( &aAppIdent, NULL, DG_CONTROL, DAT_IDENTITY, MSG_CLOSEDS, &aSrcIdent );
|
|
|
|
nCurState = 3;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case( 3 ):
|
|
|
|
{
|
|
|
|
PFUNC( &aAppIdent, NULL, DG_CONTROL, DAT_PARENT, MSG_CLOSEDSM, &hTwainWnd );
|
|
|
|
nCurState = 2;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case( 2 ):
|
|
|
|
{
|
|
|
|
delete pMod;
|
|
|
|
pMod = NULL;
|
|
|
|
nCurState = 1;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
{
|
|
|
|
if( nEvent != TWAIN_EVENT_NONE )
|
|
|
|
aNotifyLink.Call( (void*) nEvent );
|
|
|
|
|
2005-11-11 10:05:48 +00:00
|
|
|
bFallback = false;
|
2000-09-18 15:18:56 +00:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
if( bFallback )
|
|
|
|
ImplFallback( nEvent );
|
|
|
|
|
|
|
|
return 0L;
|
|
|
|
}
|
|
|
|
|
2008-01-14 14:04:05 +00:00
|
|
|
IMPL_LINK( ImpTwain, ImplDestroyHdl, void*, /*p*/ )
|
2000-09-18 15:18:56 +00:00
|
|
|
{
|
|
|
|
if( hTwainWnd )
|
|
|
|
DestroyWindow( hTwainWnd );
|
|
|
|
|
|
|
|
if( hTwainHook )
|
|
|
|
UnhookWindowsHookEx( hTwainHook );
|
|
|
|
|
2010-11-25 21:22:04 +02:00
|
|
|
// permit destruction of ourselves (normally, refcount
|
2003-04-08 14:40:31 +00:00
|
|
|
// should drop to zero exactly here)
|
|
|
|
mxSelfRef = NULL;
|
2000-09-18 15:18:56 +00:00
|
|
|
pImpTwainInstance = NULL;
|
|
|
|
|
|
|
|
return 0L;
|
|
|
|
}
|
|
|
|
|
2003-04-08 14:40:31 +00:00
|
|
|
uno::Reference< frame::XFrame > ImpTwain::ImplGetActiveFrame()
|
|
|
|
{
|
|
|
|
try
|
|
|
|
{
|
2012-12-14 12:58:00 +02:00
|
|
|
// query desktop instance
|
|
|
|
uno::Reference< frame::XDesktop2 > xDesktop = frame::Desktop::create( ::comphelper::getProcessComponentContext() );
|
2003-04-08 14:40:31 +00:00
|
|
|
|
2012-12-14 12:58:00 +02:00
|
|
|
uno::Reference< frame::XFrame > xActiveFrame = xDesktop->getActiveFrame();
|
2003-04-08 14:40:31 +00:00
|
|
|
|
2012-12-14 12:58:00 +02:00
|
|
|
if( xActiveFrame.is() )
|
|
|
|
{
|
|
|
|
return xActiveFrame;
|
2003-04-08 14:40:31 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
catch( const uno::Exception& )
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2011-03-01 17:55:09 +01:00
|
|
|
OSL_FAIL("ImpTwain::ImplGetActiveFrame: Could not determine active frame!");
|
2003-04-08 14:40:31 +00:00
|
|
|
return uno::Reference< frame::XFrame >();
|
|
|
|
}
|
|
|
|
|
|
|
|
uno::Reference< util::XCloseBroadcaster > ImpTwain::ImplGetActiveFrameCloseBroadcaster()
|
|
|
|
{
|
|
|
|
try
|
|
|
|
{
|
|
|
|
return uno::Reference< util::XCloseBroadcaster >( ImplGetActiveFrame(), uno::UNO_QUERY );
|
|
|
|
}
|
|
|
|
catch( const uno::Exception& )
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2011-03-01 17:55:09 +01:00
|
|
|
OSL_FAIL("ImpTwain::ImplGetActiveFrameCloseBroadcaster: Could determine close broadcaster on active frame!");
|
2003-04-08 14:40:31 +00:00
|
|
|
return uno::Reference< util::XCloseBroadcaster >();
|
|
|
|
}
|
|
|
|
|
|
|
|
void ImpTwain::ImplRegisterCloseListener()
|
|
|
|
{
|
|
|
|
try
|
|
|
|
{
|
2005-11-11 10:05:48 +00:00
|
|
|
uno::Reference< util::XCloseBroadcaster > xCloseBroadcaster( ImplGetActiveFrameCloseBroadcaster() );
|
2003-04-08 14:40:31 +00:00
|
|
|
|
|
|
|
if( xCloseBroadcaster.is() )
|
|
|
|
{
|
|
|
|
xCloseBroadcaster->addCloseListener(this);
|
|
|
|
return; // successfully registered as a close listener
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// interface unknown. don't register, then
|
2011-03-01 17:55:09 +01:00
|
|
|
OSL_FAIL("ImpTwain::ImplRegisterCloseListener: XFrame has no XCloseBroadcaster!");
|
2003-04-08 14:40:31 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
catch( const uno::Exception& )
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2011-03-01 17:55:09 +01:00
|
|
|
OSL_FAIL("ImpTwain::ImplRegisterCloseListener: Could not register as close listener!");
|
2003-04-08 14:40:31 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void ImpTwain::ImplDeregisterCloseListener()
|
|
|
|
{
|
|
|
|
try
|
|
|
|
{
|
|
|
|
uno::Reference< util::XCloseBroadcaster > xCloseBroadcaster(
|
|
|
|
ImplGetActiveFrameCloseBroadcaster() );
|
|
|
|
|
|
|
|
if( xCloseBroadcaster.is() )
|
|
|
|
{
|
|
|
|
xCloseBroadcaster->removeCloseListener(this);
|
|
|
|
return; // successfully deregistered as a close listener
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// interface unknown. don't deregister, then
|
2011-03-01 17:55:09 +01:00
|
|
|
OSL_FAIL("ImpTwain::ImplDeregisterCloseListener: XFrame has no XCloseBroadcaster!");
|
2003-04-08 14:40:31 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
catch( const uno::Exception& )
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2011-03-01 17:55:09 +01:00
|
|
|
OSL_FAIL("ImpTwain::ImplDeregisterCloseListener: Could not deregister as close listener!");
|
2003-04-08 14:40:31 +00:00
|
|
|
}
|
|
|
|
|
2008-01-14 14:04:05 +00:00
|
|
|
void SAL_CALL ImpTwain::queryClosing( const lang::EventObject& /*Source*/, sal_Bool GetsOwnership ) throw (util::CloseVetoException, uno::RuntimeException)
|
2003-04-08 14:40:31 +00:00
|
|
|
{
|
|
|
|
// shall we re-send the close query later on?
|
|
|
|
mbCloseFrameOnExit = GetsOwnership;
|
|
|
|
|
|
|
|
// the sole purpose of this listener is to forbid closing of the listened-at frame
|
|
|
|
throw util::CloseVetoException();
|
|
|
|
}
|
|
|
|
|
2008-01-14 14:04:05 +00:00
|
|
|
void SAL_CALL ImpTwain::notifyClosing( const lang::EventObject& /*Source*/ ) throw (uno::RuntimeException)
|
2003-04-08 14:40:31 +00:00
|
|
|
{
|
|
|
|
// should not happen
|
2011-03-01 17:55:09 +01:00
|
|
|
OSL_FAIL("ImpTwain::notifyClosing called, but we vetoed the closing before!");
|
2003-04-08 14:40:31 +00:00
|
|
|
}
|
|
|
|
|
2008-01-14 14:04:05 +00:00
|
|
|
void SAL_CALL ImpTwain::disposing( const lang::EventObject& /*Source*/ ) throw (uno::RuntimeException)
|
2003-04-08 14:40:31 +00:00
|
|
|
{
|
|
|
|
// we're not holding any references to the frame, thus noop
|
|
|
|
}
|
|
|
|
|
|
|
|
void ImpTwain::ImplSendCloseEvent()
|
|
|
|
{
|
|
|
|
try
|
|
|
|
{
|
|
|
|
uno::Reference< util::XCloseable > xCloseable( ImplGetActiveFrame(), uno::UNO_QUERY );
|
|
|
|
|
|
|
|
if( xCloseable.is() )
|
|
|
|
xCloseable->close( true );
|
|
|
|
}
|
|
|
|
catch( const uno::Exception& )
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2011-03-01 17:55:09 +01:00
|
|
|
OSL_FAIL("ImpTwain::ImplSendCloseEvent: Could not send required close broadcast!");
|
2003-04-08 14:40:31 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2000-09-18 15:18:56 +00:00
|
|
|
class Twain
|
|
|
|
{
|
2005-11-11 10:05:48 +00:00
|
|
|
uno::Reference< lang::XEventListener > mxListener;
|
|
|
|
uno::Reference< scanner::XScannerManager > mxMgr;
|
|
|
|
const ScannerManager* mpCurMgr;
|
|
|
|
ImpTwain* mpImpTwain;
|
|
|
|
TwainState meState;
|
2000-09-18 15:18:56 +00:00
|
|
|
|
2005-11-11 10:05:48 +00:00
|
|
|
DECL_LINK( ImpNotifyHdl, ImpTwain* );
|
2000-09-18 15:18:56 +00:00
|
|
|
|
|
|
|
public:
|
|
|
|
|
2005-11-11 10:05:48 +00:00
|
|
|
Twain();
|
|
|
|
~Twain();
|
2000-09-18 15:18:56 +00:00
|
|
|
|
2005-11-11 10:05:48 +00:00
|
|
|
bool SelectSource( ScannerManager& rMgr );
|
|
|
|
bool PerformTransfer( ScannerManager& rMgr, const uno::Reference< lang::XEventListener >& rxListener );
|
2000-09-18 15:18:56 +00:00
|
|
|
|
2005-11-11 10:05:48 +00:00
|
|
|
TwainState GetState() const { return meState; }
|
2000-09-18 15:18:56 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
Twain::Twain() :
|
2005-11-11 10:05:48 +00:00
|
|
|
mpCurMgr( NULL ),
|
|
|
|
mpImpTwain( NULL ),
|
|
|
|
meState( TWAIN_STATE_NONE )
|
2000-09-18 15:18:56 +00:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
Twain::~Twain()
|
|
|
|
{
|
|
|
|
if( mpImpTwain )
|
|
|
|
mpImpTwain->Destroy();
|
|
|
|
}
|
|
|
|
|
2005-11-11 10:05:48 +00:00
|
|
|
bool Twain::SelectSource( ScannerManager& rMgr )
|
2000-09-18 15:18:56 +00:00
|
|
|
{
|
2005-11-11 10:05:48 +00:00
|
|
|
bool bRet;
|
2000-09-18 15:18:56 +00:00
|
|
|
|
2005-11-11 10:05:48 +00:00
|
|
|
if( !mpImpTwain )
|
2000-09-18 15:18:56 +00:00
|
|
|
{
|
2010-11-25 21:22:04 +02:00
|
|
|
// hold reference to ScannerManager, to prevent premature death
|
2005-11-11 10:05:48 +00:00
|
|
|
mxMgr = uno::Reference< scanner::XScannerManager >( static_cast< OWeakObject* >( const_cast< ScannerManager* >( mpCurMgr = &rMgr ) ),
|
|
|
|
uno::UNO_QUERY ),
|
|
|
|
|
2000-09-18 15:18:56 +00:00
|
|
|
meState = TWAIN_STATE_NONE;
|
2005-11-11 10:05:48 +00:00
|
|
|
mpImpTwain = new ImpTwain( rMgr, LINK( this, Twain, ImpNotifyHdl ) );
|
2000-09-18 15:18:56 +00:00
|
|
|
bRet = mpImpTwain->SelectSource();
|
|
|
|
}
|
|
|
|
else
|
2005-11-11 10:05:48 +00:00
|
|
|
bRet = false;
|
2000-09-18 15:18:56 +00:00
|
|
|
|
|
|
|
return bRet;
|
|
|
|
}
|
|
|
|
|
2005-11-11 10:05:48 +00:00
|
|
|
bool Twain::PerformTransfer( ScannerManager& rMgr, const uno::Reference< lang::XEventListener >& rxListener )
|
2000-09-18 15:18:56 +00:00
|
|
|
{
|
2005-11-11 10:05:48 +00:00
|
|
|
bool bRet;
|
2000-09-18 15:18:56 +00:00
|
|
|
|
2005-11-11 10:05:48 +00:00
|
|
|
if( !mpImpTwain )
|
2000-09-18 15:18:56 +00:00
|
|
|
{
|
2010-11-25 21:22:04 +02:00
|
|
|
// hold reference to ScannerManager, to prevent premature death
|
2005-11-11 10:05:48 +00:00
|
|
|
mxMgr = uno::Reference< scanner::XScannerManager >( static_cast< OWeakObject* >( const_cast< ScannerManager* >( mpCurMgr = &rMgr ) ),
|
|
|
|
uno::UNO_QUERY ),
|
|
|
|
|
2000-09-18 15:18:56 +00:00
|
|
|
mxListener = rxListener;
|
|
|
|
meState = TWAIN_STATE_NONE;
|
2005-11-11 10:05:48 +00:00
|
|
|
mpImpTwain = new ImpTwain( rMgr, LINK( this, Twain, ImpNotifyHdl ) );
|
2000-09-18 15:18:56 +00:00
|
|
|
bRet = mpImpTwain->InitXfer();
|
|
|
|
}
|
|
|
|
else
|
2005-11-11 10:05:48 +00:00
|
|
|
bRet = false;
|
2000-09-18 15:18:56 +00:00
|
|
|
|
|
|
|
return bRet;
|
|
|
|
}
|
|
|
|
|
|
|
|
IMPL_LINK( Twain, ImpNotifyHdl, ImpTwain*, nEvent )
|
|
|
|
{
|
|
|
|
switch( (ULONG)(void*) nEvent )
|
|
|
|
{
|
|
|
|
case( TWAIN_EVENT_SCANNING ):
|
|
|
|
meState = TWAIN_STATE_SCANNING;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case( TWAIN_EVENT_QUIT ):
|
|
|
|
{
|
|
|
|
if( meState != TWAIN_STATE_DONE )
|
|
|
|
meState = TWAIN_STATE_CANCELED;
|
|
|
|
|
2002-11-05 11:02:56 +00:00
|
|
|
if( mpImpTwain )
|
|
|
|
{
|
|
|
|
mpImpTwain->Destroy();
|
|
|
|
mpImpTwain = NULL;
|
2005-11-11 10:05:48 +00:00
|
|
|
mpCurMgr = NULL;
|
2002-11-05 11:02:56 +00:00
|
|
|
}
|
2000-09-18 15:18:56 +00:00
|
|
|
|
2005-11-11 10:05:48 +00:00
|
|
|
if( mxListener.is() )
|
|
|
|
mxListener->disposing( lang::EventObject( mxMgr ) );
|
2000-09-18 15:18:56 +00:00
|
|
|
|
2005-11-11 10:05:48 +00:00
|
|
|
mxListener = NULL;
|
2000-09-18 15:18:56 +00:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case( TWAIN_EVENT_XFER ):
|
|
|
|
{
|
2005-11-11 10:05:48 +00:00
|
|
|
if( mpImpTwain )
|
2000-09-18 15:18:56 +00:00
|
|
|
{
|
2005-11-11 10:05:48 +00:00
|
|
|
meState = ( mpCurMgr->GetData() ? TWAIN_STATE_DONE : TWAIN_STATE_CANCELED );
|
2000-09-18 15:18:56 +00:00
|
|
|
|
|
|
|
mpImpTwain->Destroy();
|
|
|
|
mpImpTwain = NULL;
|
2005-11-11 10:05:48 +00:00
|
|
|
mpCurMgr = NULL;
|
2000-09-18 15:18:56 +00:00
|
|
|
|
2005-11-11 10:05:48 +00:00
|
|
|
if( mxListener.is() )
|
|
|
|
mxListener->disposing( lang::EventObject( mxMgr ) );
|
2000-09-18 15:18:56 +00:00
|
|
|
}
|
|
|
|
|
2005-11-11 10:05:48 +00:00
|
|
|
mxListener = NULL;
|
2000-09-18 15:18:56 +00:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0L;
|
|
|
|
}
|
|
|
|
|
|
|
|
static Twain aTwain;
|
|
|
|
|
2010-09-30 16:45:24 +01:00
|
|
|
void ScannerManager::AcquireData()
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
void ScannerManager::ReleaseData()
|
2000-09-18 15:18:56 +00:00
|
|
|
{
|
|
|
|
if( mpData )
|
|
|
|
{
|
|
|
|
GlobalFree( (HGLOBAL)(long) mpData );
|
|
|
|
mpData = NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-04-01 22:08:52 +02:00
|
|
|
awt::Size ScannerManager::getSize() throw()
|
2000-09-18 15:18:56 +00:00
|
|
|
{
|
2013-04-01 22:08:52 +02:00
|
|
|
awt::Size aRet;
|
2000-09-18 15:18:56 +00:00
|
|
|
HGLOBAL hDIB = (HGLOBAL)(long) mpData;
|
|
|
|
|
|
|
|
if( hDIB )
|
|
|
|
{
|
|
|
|
BITMAPINFOHEADER* pBIH = (BITMAPINFOHEADER*) GlobalLock( hDIB );
|
|
|
|
|
|
|
|
if( pBIH )
|
|
|
|
{
|
|
|
|
aRet.Width = pBIH->biWidth;
|
|
|
|
aRet.Height = pBIH->biHeight;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
aRet.Width = aRet.Height = 0;
|
|
|
|
|
|
|
|
GlobalUnlock( hDIB );
|
|
|
|
}
|
|
|
|
else
|
|
|
|
aRet.Width = aRet.Height = 0;
|
|
|
|
|
|
|
|
return aRet;
|
|
|
|
}
|
|
|
|
|
2013-04-01 22:08:52 +02:00
|
|
|
uno::Sequence< sal_Int8 > ScannerManager::getDIB() throw()
|
2000-09-18 15:18:56 +00:00
|
|
|
{
|
2013-04-01 22:08:52 +02:00
|
|
|
uno::Sequence< sal_Int8 > aRet;
|
2000-09-18 15:18:56 +00:00
|
|
|
|
|
|
|
if( mpData )
|
|
|
|
{
|
|
|
|
HGLOBAL hDIB = (HGLOBAL)(long) mpData;
|
|
|
|
const sal_uInt32 nDIBSize = GlobalSize( hDIB );
|
|
|
|
BITMAPINFOHEADER* pBIH = (BITMAPINFOHEADER*) GlobalLock( hDIB );
|
|
|
|
|
|
|
|
if( pBIH )
|
|
|
|
{
|
|
|
|
sal_uInt32 nColEntries;
|
|
|
|
|
|
|
|
switch( pBIH->biBitCount )
|
|
|
|
{
|
|
|
|
case( 1 ):
|
|
|
|
case( 4 ):
|
|
|
|
case( 8 ):
|
|
|
|
nColEntries = pBIH->biClrUsed ? pBIH->biClrUsed : ( 1 << pBIH->biBitCount );
|
|
|
|
break;
|
|
|
|
|
|
|
|
case( 24 ):
|
|
|
|
nColEntries = pBIH->biClrUsed ? pBIH->biClrUsed : 0;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case( 16 ):
|
|
|
|
case( 32 ):
|
|
|
|
{
|
|
|
|
nColEntries = pBIH->biClrUsed;
|
|
|
|
|
|
|
|
if( pBIH->biCompression == BI_BITFIELDS )
|
|
|
|
nColEntries += 3;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
nColEntries = 0;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2013-04-01 22:08:52 +02:00
|
|
|
aRet = uno::Sequence< sal_Int8 >( sizeof( BITMAPFILEHEADER ) + nDIBSize );
|
2000-09-18 15:18:56 +00:00
|
|
|
|
|
|
|
sal_Int8* pBuf = aRet.getArray();
|
|
|
|
SvMemoryStream* pMemStm = new SvMemoryStream( (char*) pBuf, sizeof( BITMAPFILEHEADER ), STREAM_WRITE );
|
|
|
|
|
|
|
|
*pMemStm << 'B' << 'M' << (sal_uInt32) 0 << (sal_uInt32) 0;
|
|
|
|
*pMemStm << (sal_uInt32) ( sizeof( BITMAPFILEHEADER ) + pBIH->biSize + ( nColEntries * sizeof( RGBQUAD ) ) );
|
|
|
|
|
|
|
|
delete pMemStm;
|
2004-01-06 11:41:04 +00:00
|
|
|
memcpy( pBuf + sizeof( BITMAPFILEHEADER ), pBIH, nDIBSize );
|
2000-09-18 15:18:56 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
GlobalUnlock( hDIB );
|
2010-09-30 16:45:24 +01:00
|
|
|
ReleaseData();
|
2000-09-18 15:18:56 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return aRet;
|
|
|
|
}
|
|
|
|
|
2013-04-01 22:08:52 +02:00
|
|
|
uno::Sequence< ScannerContext > SAL_CALL ScannerManager::getAvailableScanners() throw()
|
2000-09-18 15:18:56 +00:00
|
|
|
{
|
2010-10-16 03:15:49 -05:00
|
|
|
osl::MutexGuard aGuard( maProtector );
|
2013-04-01 22:08:52 +02:00
|
|
|
uno::Sequence< ScannerContext > aRet( 1 );
|
2000-09-18 15:18:56 +00:00
|
|
|
|
2013-04-07 12:06:47 +02:00
|
|
|
aRet.getArray()[0].ScannerName = OUString( "TWAIN" );
|
2000-09-18 15:18:56 +00:00
|
|
|
aRet.getArray()[0].InternalData = 0;
|
|
|
|
|
|
|
|
return aRet;
|
|
|
|
}
|
|
|
|
|
2011-10-20 21:25:46 +02:00
|
|
|
sal_Bool SAL_CALL ScannerManager::configureScannerAndScan( ScannerContext& rContext, const uno::Reference< lang::XEventListener >& )
|
2005-11-11 10:05:48 +00:00
|
|
|
throw( ScannerException )
|
2000-09-18 15:18:56 +00:00
|
|
|
{
|
2010-10-16 03:15:49 -05:00
|
|
|
osl::MutexGuard aGuard( maProtector );
|
2005-11-11 10:05:48 +00:00
|
|
|
uno::Reference< XScannerManager > xThis( this );
|
2000-09-18 15:18:56 +00:00
|
|
|
|
2013-04-07 12:06:47 +02:00
|
|
|
if( rContext.InternalData != 0 || rContext.ScannerName != OUString( "TWAIN" ) )
|
|
|
|
throw ScannerException( OUString( "Scanner does not exist" ), xThis, ScanError_InvalidContext );
|
2000-09-18 15:18:56 +00:00
|
|
|
|
2010-09-30 16:45:24 +01:00
|
|
|
ReleaseData();
|
2000-09-18 15:18:56 +00:00
|
|
|
|
2005-11-11 10:05:48 +00:00
|
|
|
return aTwain.SelectSource( *this );
|
2000-09-18 15:18:56 +00:00
|
|
|
}
|
|
|
|
|
2005-11-11 10:05:48 +00:00
|
|
|
void SAL_CALL ScannerManager::startScan( const ScannerContext& rContext, const uno::Reference< lang::XEventListener >& rxListener )
|
|
|
|
throw( ScannerException )
|
2000-09-18 15:18:56 +00:00
|
|
|
{
|
2010-10-16 03:15:49 -05:00
|
|
|
osl::MutexGuard aGuard( maProtector );
|
2005-11-11 10:05:48 +00:00
|
|
|
uno::Reference< XScannerManager > xThis( this );
|
2000-09-18 15:18:56 +00:00
|
|
|
|
2013-04-07 12:06:47 +02:00
|
|
|
if( rContext.InternalData != 0 || rContext.ScannerName != OUString( "TWAIN" ) )
|
|
|
|
throw ScannerException( OUString( "Scanner does not exist" ), xThis, ScanError_InvalidContext );
|
2000-09-18 15:18:56 +00:00
|
|
|
|
2010-09-30 16:45:24 +01:00
|
|
|
ReleaseData();
|
2005-11-11 10:05:48 +00:00
|
|
|
aTwain.PerformTransfer( *this, rxListener );
|
2000-09-18 15:18:56 +00:00
|
|
|
}
|
|
|
|
|
2005-11-11 10:05:48 +00:00
|
|
|
ScanError SAL_CALL ScannerManager::getError( const ScannerContext& rContext )
|
|
|
|
throw( ScannerException )
|
2000-09-18 15:18:56 +00:00
|
|
|
{
|
2010-10-16 03:15:49 -05:00
|
|
|
osl::MutexGuard aGuard( maProtector );
|
2005-11-11 10:05:48 +00:00
|
|
|
uno::Reference< XScannerManager > xThis( this );
|
2000-09-18 15:18:56 +00:00
|
|
|
|
2013-04-07 12:06:47 +02:00
|
|
|
if( rContext.InternalData != 0 || rContext.ScannerName != OUString( "TWAIN" ) )
|
|
|
|
throw ScannerException( OUString( "Scanner does not exist" ), xThis, ScanError_InvalidContext );
|
2000-09-18 15:18:56 +00:00
|
|
|
|
2005-11-11 10:05:48 +00:00
|
|
|
return( ( aTwain.GetState() == TWAIN_STATE_CANCELED ) ? ScanError_ScanCanceled : ScanError_ScanErrorNone );
|
2000-09-18 15:18:56 +00:00
|
|
|
}
|
|
|
|
|
2008-01-14 14:04:05 +00:00
|
|
|
uno::Reference< awt::XBitmap > SAL_CALL ScannerManager::getBitmap( const ScannerContext& /*rContext*/ )
|
2005-11-11 10:05:48 +00:00
|
|
|
throw( ScannerException )
|
2000-09-18 15:18:56 +00:00
|
|
|
{
|
2010-10-16 03:15:49 -05:00
|
|
|
osl::MutexGuard aGuard( maProtector );
|
2005-11-11 10:05:48 +00:00
|
|
|
return uno::Reference< awt::XBitmap >( this );
|
2000-09-18 15:18:56 +00:00
|
|
|
}
|
2010-10-12 15:57:08 +02:00
|
|
|
|
|
|
|
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|