update dev300-m58
[ooovba.git] / extensions / source / scanner / scanunx.cxx
blob4169069aef60db1a5230b5123032a5a9d47f4958
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: scanunx.cxx,v $
10 * $Revision: 1.10 $
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
39 #include <stdio.h>
40 #endif
42 BitmapTransporter::BitmapTransporter()
44 #if OSL_DEBUG_LEVEL > 1
45 fprintf( stderr, "BitmapTransporter\n" );
46 #endif
49 BitmapTransporter::~BitmapTransporter()
51 #if OSL_DEBUG_LEVEL > 1
52 fprintf( stderr, "~BitmapTransporter\n" );
53 #endif
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();
71 AWT::Size aRet;
73 // ensure that there is at least a header
74 m_aStream.Seek( STREAM_SEEK_TO_END );
75 int nLen = m_aStream.Tell();
76 if( nLen > 15 )
78 m_aStream.Seek( 4 );
79 m_aStream >> aRet.Width >> aRet.Height;
81 else
82 aRet.Width = aRet.Height = 0;
84 m_aStream.Seek( nPreviousPos );
86 return aRet;
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();
99 m_aStream.Seek( 0 );
101 SEQ( sal_Int8 ) aValue( nBytes );
102 m_aStream.Read( aValue.getArray(), nBytes );
103 m_aStream.Seek( nPreviousPos );
105 return aValue;
108 // --------------
109 // - SaneHolder -
110 // --------------
112 struct SaneHolder
114 Sane m_aSane;
115 REF( AWT::XBitmap ) m_xBitmap;
116 vos::OMutex m_aProtector;
117 ScanError m_nError;
118 bool m_bBusy;
121 DECLARE_LIST( SaneHolderList, SaneHolder* )
123 static SaneHolderList allSanes;
124 static vos::OMutex aSaneProtector;
126 // -----------------
127 // - ScannerThread -
128 // -----------------
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
136 public:
137 virtual void run();
138 virtual void onTerminated() { delete this; }
139 public:
140 ScannerThread( SaneHolder* pHolder,
141 const REF( com::sun::star::lang::XEventListener )& listener,
142 ScannerManager* pManager );
143 virtual ~ScannerThread();
146 // -----------------------------------------------------------------------------
148 ScannerThread::ScannerThread(
149 SaneHolder* pHolder,
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" );
156 #endif
159 ScannerThread::~ScannerThread()
161 #if OSL_DEBUG_LEVEL > 1
162 fprintf( stderr, "~ScannerThread\n" );
163 #endif
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" );
178 if( nOption != -1 )
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;
185 else
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
202 int i;
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()
214 AWT::Size aRet;
215 aRet.Width = aRet.Height = 0;
216 return aRet;
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;
237 if( Sane::IsSane() )
238 allSanes.Insert( pSaneHolder );
239 else
240 delete pSaneHolder;
243 if( Sane::IsSane() )
245 SEQ( ScannerContext ) aRet(1);
246 aRet.getArray()[0].ScannerName = ::rtl::OUString::createFromAscii( "SANE" );
247 aRet.getArray()[0].InternalData = 0;
248 return aRet;
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" );
262 #endif
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;
284 return bRet;
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" );
296 #endif
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 );
314 pThread->create();
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 )();
354 return xRet;