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: scanunx.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"
33 #include <scanner.hxx>
34 #include <sanedlg.hxx>
35 #include <vos/thread.hxx>
36 #include <tools/list.hxx>
38 #if OSL_DEBUG_LEVEL > 1
42 BitmapTransporter::BitmapTransporter()
44 #if OSL_DEBUG_LEVEL > 1
45 fprintf( stderr
, "BitmapTransporter\n" );
49 BitmapTransporter::~BitmapTransporter()
51 #if OSL_DEBUG_LEVEL > 1
52 fprintf( stderr
, "~BitmapTransporter\n" );
56 // -----------------------------------------------------------------------------
58 ANY SAL_CALL
BitmapTransporter::queryInterface( const Type
& rType
) throw( RuntimeException
)
60 const ANY
aRet( cppu::queryInterface( rType
, static_cast< AWT::XBitmap
* >( this ) ) );
62 return( aRet
.hasValue() ? aRet
: OWeakObject::queryInterface( rType
) );
65 // -----------------------------------------------------------------------------
67 AWT::Size
BitmapTransporter::getSize() throw()
69 vos::OGuard
aGuard( m_aProtector
);
70 int nPreviousPos
= m_aStream
.Tell();
73 // ensure that there is at least a header
74 m_aStream
.Seek( STREAM_SEEK_TO_END
);
75 int nLen
= m_aStream
.Tell();
79 m_aStream
>> aRet
.Width
>> aRet
.Height
;
82 aRet
.Width
= aRet
.Height
= 0;
84 m_aStream
.Seek( nPreviousPos
);
89 // -----------------------------------------------------------------------------
91 SEQ( sal_Int8
) BitmapTransporter::getDIB() throw()
93 vos::OGuard
aGuard( m_aProtector
);
94 int nPreviousPos
= m_aStream
.Tell();
96 // create return value
97 m_aStream
.Seek( STREAM_SEEK_TO_END
);
98 int nBytes
= m_aStream
.Tell();
101 SEQ( sal_Int8
) aValue( nBytes
);
102 m_aStream
.Read( aValue
.getArray(), nBytes
);
103 m_aStream
.Seek( nPreviousPos
);
115 REF( AWT::XBitmap
) m_xBitmap
;
116 vos::OMutex m_aProtector
;
121 DECLARE_LIST( SaneHolderList
, SaneHolder
* )
123 static SaneHolderList allSanes
;
124 static vos::OMutex aSaneProtector
;
130 class ScannerThread
: public vos::OThread
132 SaneHolder
* m_pHolder
;
133 REF( com::sun::star::lang::XEventListener
) m_xListener
;
134 ScannerManager
* m_pManager
; // just for the disposing call
138 virtual void onTerminated() { delete this; }
140 ScannerThread( SaneHolder
* pHolder
,
141 const REF( com::sun::star::lang::XEventListener
)& listener
,
142 ScannerManager
* pManager
);
143 virtual ~ScannerThread();
146 // -----------------------------------------------------------------------------
148 ScannerThread::ScannerThread(
150 const REF( com::sun::star::lang::XEventListener
)& listener
,
151 ScannerManager
* pManager
)
152 : m_pHolder( pHolder
), m_xListener( listener
), m_pManager( pManager
)
154 #if OSL_DEBUG_LEVEL > 1
155 fprintf( stderr
, "ScannerThread\n" );
159 ScannerThread::~ScannerThread()
161 #if OSL_DEBUG_LEVEL > 1
162 fprintf( stderr
, "~ScannerThread\n" );
166 void ScannerThread::run()
168 vos::OGuard
aGuard( m_pHolder
->m_aProtector
);
169 BitmapTransporter
* pTransporter
= new BitmapTransporter
;
170 REF( XInterface
) aIf( static_cast< OWeakObject
* >( pTransporter
) );
172 m_pHolder
->m_xBitmap
= REF( AWT::XBitmap
)( aIf
, UNO_QUERY
);
174 m_pHolder
->m_bBusy
= true;
175 if( m_pHolder
->m_aSane
.IsOpen() )
177 int nOption
= m_pHolder
->m_aSane
.GetOptionByName( "preview" );
179 m_pHolder
->m_aSane
.SetOptionValue( nOption
, (BOOL
)FALSE
);
181 m_pHolder
->m_nError
=
182 m_pHolder
->m_aSane
.Start( *pTransporter
) ?
183 ScanError_ScanErrorNone
: ScanError_ScanCanceled
;
186 m_pHolder
->m_nError
= ScanError_ScannerNotAvailable
;
189 REF( XInterface
) xXInterface( static_cast< OWeakObject
* >( m_pManager
) );
190 m_xListener
->disposing( com::sun::star::lang::EventObject(xXInterface
) );
191 m_pHolder
->m_bBusy
= false;
194 // ------------------
195 // - ScannerManager -
196 // ------------------
198 void ScannerManager::DestroyData()
200 // was unused, now because of i99835: "Scanning interface not SANE API compliant"
201 // delete all SaneHolder to get Sane Dtor called
203 for ( i
= allSanes
.Count(); i
> 0; i
-- )
205 SaneHolder
*pSaneHolder
= allSanes
.GetObject(i
-1);
206 if ( pSaneHolder
) delete pSaneHolder
;
210 // -----------------------------------------------------------------------------
212 AWT::Size
ScannerManager::getSize() throw()
215 aRet
.Width
= aRet
.Height
= 0;
219 // -----------------------------------------------------------------------------
221 SEQ( sal_Int8
) ScannerManager::getDIB() throw()
223 return SEQ( sal_Int8
)();
226 // -----------------------------------------------------------------------------
228 SEQ( ScannerContext
) ScannerManager::getAvailableScanners() throw()
230 vos::OGuard
aGuard( aSaneProtector
);
232 if( ! allSanes
.Count() )
234 SaneHolder
* pSaneHolder
= new SaneHolder
;
235 pSaneHolder
->m_nError
= ScanError_ScanErrorNone
;
236 pSaneHolder
->m_bBusy
= false;
238 allSanes
.Insert( pSaneHolder
);
245 SEQ( ScannerContext
) aRet(1);
246 aRet
.getArray()[0].ScannerName
= ::rtl::OUString::createFromAscii( "SANE" );
247 aRet
.getArray()[0].InternalData
= 0;
251 return SEQ( ScannerContext
)();
254 // -----------------------------------------------------------------------------
256 BOOL
ScannerManager::configureScanner( ScannerContext
& scanner_context
) throw( ScannerException
)
258 vos::OGuard
aGuard( aSaneProtector
);
260 #if OSL_DEBUG_LEVEL > 1
261 fprintf( stderr
, "ScannerManager::configureScanner\n" );
264 if( scanner_context
.InternalData
< 0 || (ULONG
)scanner_context
.InternalData
>= allSanes
.Count() )
265 throw ScannerException(
266 ::rtl::OUString::createFromAscii( "Scanner does not exist" ),
267 REF( XScannerManager
)( this ),
268 ScanError_InvalidContext
271 SaneHolder
* pHolder
= allSanes
.GetObject( scanner_context
.InternalData
);
272 if( pHolder
->m_bBusy
)
273 throw ScannerException(
274 ::rtl::OUString::createFromAscii( "Scanner is busy" ),
275 REF( XScannerManager
)( this ),
276 ScanError_ScanInProgress
279 pHolder
->m_bBusy
= true;
280 SaneDlg
aDlg( NULL
, pHolder
->m_aSane
);
281 BOOL bRet
= (BOOL
)aDlg
.Execute();
282 pHolder
->m_bBusy
= false;
287 // -----------------------------------------------------------------------------
289 void ScannerManager::startScan( const ScannerContext
& scanner_context
,
290 const REF( com::sun::star::lang::XEventListener
)& listener
) throw( ScannerException
)
292 vos::OGuard
aGuard( aSaneProtector
);
294 #if OSL_DEBUG_LEVEL > 1
295 fprintf( stderr
, "ScannerManager::startScan\n" );
298 if( scanner_context
.InternalData
< 0 || (ULONG
)scanner_context
.InternalData
>= allSanes
.Count() )
299 throw ScannerException(
300 ::rtl::OUString::createFromAscii( "Scanner does not exist" ),
301 REF( XScannerManager
)( this ),
302 ScanError_InvalidContext
304 SaneHolder
* pHolder
= allSanes
.GetObject( scanner_context
.InternalData
);
305 if( pHolder
->m_bBusy
)
306 throw ScannerException(
307 ::rtl::OUString::createFromAscii( "Scanner is busy" ),
308 REF( XScannerManager
)( this ),
309 ScanError_ScanInProgress
311 pHolder
->m_bBusy
= true;
313 ScannerThread
* pThread
= new ScannerThread( pHolder
, listener
, this );
317 // -----------------------------------------------------------------------------
319 ScanError
ScannerManager::getError( const ScannerContext
& scanner_context
) throw( ScannerException
)
321 vos::OGuard
aGuard( aSaneProtector
);
323 if( scanner_context
.InternalData
< 0 || (ULONG
)scanner_context
.InternalData
>= allSanes
.Count() )
324 throw ScannerException(
325 ::rtl::OUString::createFromAscii( "Scanner does not exist" ),
326 REF( XScannerManager
)( this ),
327 ScanError_InvalidContext
330 SaneHolder
* pHolder
= allSanes
.GetObject( scanner_context
.InternalData
);
332 return pHolder
->m_nError
;
335 // -----------------------------------------------------------------------------
337 REF( AWT::XBitmap
) ScannerManager::getBitmap( const ScannerContext
& scanner_context
) throw( ScannerException
)
339 vos::OGuard
aGuard( aSaneProtector
);
341 if( scanner_context
.InternalData
< 0 || (ULONG
)scanner_context
.InternalData
>= allSanes
.Count() )
342 throw ScannerException(
343 ::rtl::OUString::createFromAscii( "Scanner does not exist" ),
344 REF( XScannerManager
)( this ),
345 ScanError_InvalidContext
347 SaneHolder
* pHolder
= allSanes
.GetObject( scanner_context
.InternalData
);
349 vos::OGuard
aProtGuard( pHolder
->m_aProtector
);
351 REF( AWT::XBitmap
) xRet( pHolder
->m_xBitmap
);
352 pHolder
->m_xBitmap
= REF( AWT::XBitmap
)();