Branch data Line data Source code
1 : : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : : /*************************************************************************
3 : : *
4 : : * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 : : *
6 : : * Copyright 2000, 2010 Oracle and/or its affiliates.
7 : : *
8 : : * OpenOffice.org - a multi-platform office productivity suite
9 : : *
10 : : * This file is part of OpenOffice.org.
11 : : *
12 : : * OpenOffice.org is free software: you can redistribute it and/or modify
13 : : * it under the terms of the GNU Lesser General Public License version 3
14 : : * only, as published by the Free Software Foundation.
15 : : *
16 : : * OpenOffice.org is distributed in the hope that it will be useful,
17 : : * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 : : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 : : * GNU Lesser General Public License version 3 for more details
20 : : * (a copy is included in the LICENSE file that accompanied this code).
21 : : *
22 : : * You should have received a copy of the GNU Lesser General Public License
23 : : * version 3 along with OpenOffice.org. If not, see
24 : : * <http://www.openoffice.org/license.html>
25 : : * for a copy of the LGPLv3 License.
26 : : *
27 : : ************************************************************************/
28 : :
29 : : #include <scanner.hxx>
30 : : #include <sanedlg.hxx>
31 : : #include <osl/thread.hxx>
32 : : #include <boost/shared_ptr.hpp>
33 : : #include <boost/shared_ptr.hpp>
34 : :
35 : : #if OSL_DEBUG_LEVEL > 1
36 : : #include <stdio.h>
37 : : #endif
38 : :
39 [ # # ][ # # ]: 0 : BitmapTransporter::BitmapTransporter()
40 : : {
41 : : #if OSL_DEBUG_LEVEL > 1
42 : : fprintf( stderr, "BitmapTransporter\n" );
43 : : #endif
44 : 0 : }
45 : :
46 [ # # ][ # # ]: 0 : BitmapTransporter::~BitmapTransporter()
47 : : {
48 : : #if OSL_DEBUG_LEVEL > 1
49 : : fprintf( stderr, "~BitmapTransporter\n" );
50 : : #endif
51 [ # # ]: 0 : }
52 : :
53 : : // -----------------------------------------------------------------------------
54 : :
55 : 0 : ANY SAL_CALL BitmapTransporter::queryInterface( const Type& rType ) throw( RuntimeException )
56 : : {
57 [ # # ]: 0 : const ANY aRet( cppu::queryInterface( rType, static_cast< AWT::XBitmap* >( this ) ) );
58 : :
59 [ # # ][ # # ]: 0 : return( aRet.hasValue() ? aRet : OWeakObject::queryInterface( rType ) );
60 : : }
61 : :
62 : : // -----------------------------------------------------------------------------
63 : :
64 : 0 : AWT::Size BitmapTransporter::getSize() throw()
65 : : {
66 [ # # ]: 0 : osl::MutexGuard aGuard( m_aProtector );
67 : 0 : int nPreviousPos = m_aStream.Tell();
68 : 0 : AWT::Size aRet;
69 : :
70 : : // ensure that there is at least a header
71 [ # # ]: 0 : m_aStream.Seek( STREAM_SEEK_TO_END );
72 : 0 : int nLen = m_aStream.Tell();
73 [ # # ]: 0 : if( nLen > 15 )
74 : : {
75 [ # # ]: 0 : m_aStream.Seek( 4 );
76 [ # # ][ # # ]: 0 : m_aStream >> aRet.Width >> aRet.Height;
77 : : }
78 : : else
79 : 0 : aRet.Width = aRet.Height = 0;
80 : :
81 [ # # ]: 0 : m_aStream.Seek( nPreviousPos );
82 : :
83 [ # # ]: 0 : return aRet;
84 : : }
85 : :
86 : : // -----------------------------------------------------------------------------
87 : :
88 : 0 : SEQ( sal_Int8 ) BitmapTransporter::getDIB() throw()
89 : : {
90 [ # # ]: 0 : osl::MutexGuard aGuard( m_aProtector );
91 : 0 : int nPreviousPos = m_aStream.Tell();
92 : :
93 : : // create return value
94 [ # # ]: 0 : m_aStream.Seek( STREAM_SEEK_TO_END );
95 : 0 : int nBytes = m_aStream.Tell();
96 [ # # ]: 0 : m_aStream.Seek( 0 );
97 : :
98 [ # # ]: 0 : SEQ( sal_Int8 ) aValue( nBytes );
99 [ # # ][ # # ]: 0 : m_aStream.Read( aValue.getArray(), nBytes );
100 [ # # ]: 0 : m_aStream.Seek( nPreviousPos );
101 : :
102 [ # # ]: 0 : return aValue;
103 : : }
104 : :
105 : : // --------------
106 : : // - SaneHolder -
107 : : // --------------
108 : :
109 [ # # ]: 0 : struct SaneHolder
110 : : {
111 : : Sane m_aSane;
112 : : REF( AWT::XBitmap ) m_xBitmap;
113 : : osl::Mutex m_aProtector;
114 : : ScanError m_nError;
115 : : bool m_bBusy;
116 : :
117 [ # # ]: 0 : SaneHolder() : m_nError(ScanError_ScanErrorNone), m_bBusy(false) {}
118 : : };
119 : :
120 : : namespace
121 : : {
122 : : typedef std::vector< boost::shared_ptr<SaneHolder> > sanevec;
123 : 16 : class allSanes
124 : : {
125 : : private:
126 : : int mnRefCount;
127 : : public:
128 : : sanevec m_aSanes;
129 : 16 : allSanes() : mnRefCount(0) {}
130 : : void acquire();
131 : : void release();
132 : : };
133 : :
134 : 130 : void allSanes::acquire()
135 : : {
136 : 130 : ++mnRefCount;
137 : 130 : }
138 : :
139 : 130 : void allSanes::release()
140 : : {
141 : : // was unused, now because of i99835: "Scanning interface not SANE API
142 : : // compliant" destroy all SaneHolder to get Sane Dtor called
143 : 130 : --mnRefCount;
144 [ + - ]: 130 : if (!mnRefCount)
145 : 130 : m_aSanes.clear();
146 : 130 : }
147 : :
148 : : struct theSaneProtector : public rtl::Static<osl::Mutex, theSaneProtector> {};
149 : : struct theSanes : public rtl::Static<allSanes, theSanes> {};
150 : : }
151 : :
152 : : // -----------------
153 : : // - ScannerThread -
154 : : // -----------------
155 : :
156 : : class ScannerThread : public osl::Thread
157 : : {
158 : : boost::shared_ptr<SaneHolder> m_pHolder;
159 : : REF( com::sun::star::lang::XEventListener ) m_xListener;
160 : : ScannerManager* m_pManager; // just for the disposing call
161 : :
162 : : public:
163 : : virtual void run();
164 [ # # ]: 0 : virtual void onTerminated() { delete this; }
165 : : public:
166 : : ScannerThread( boost::shared_ptr<SaneHolder> pHolder,
167 : : const REF( com::sun::star::lang::XEventListener )& listener,
168 : : ScannerManager* pManager );
169 : : virtual ~ScannerThread();
170 : : };
171 : :
172 : : // -----------------------------------------------------------------------------
173 : :
174 : 0 : ScannerThread::ScannerThread(
175 : : boost::shared_ptr<SaneHolder> pHolder,
176 : : const REF( com::sun::star::lang::XEventListener )& listener,
177 : : ScannerManager* pManager )
178 [ # # ]: 0 : : m_pHolder( pHolder ), m_xListener( listener ), m_pManager( pManager )
179 : : {
180 : : #if OSL_DEBUG_LEVEL > 1
181 : : fprintf( stderr, "ScannerThread\n" );
182 : : #endif
183 : 0 : }
184 : :
185 [ # # ]: 0 : ScannerThread::~ScannerThread()
186 : : {
187 : : #if OSL_DEBUG_LEVEL > 1
188 : : fprintf( stderr, "~ScannerThread\n" );
189 : : #endif
190 [ # # ]: 0 : }
191 : :
192 : 0 : void ScannerThread::run()
193 : : {
194 [ # # ]: 0 : osl::MutexGuard aGuard( m_pHolder->m_aProtector );
195 [ # # ]: 0 : BitmapTransporter* pTransporter = new BitmapTransporter;
196 [ # # ]: 0 : REF( XInterface ) aIf( static_cast< OWeakObject* >( pTransporter ) );
197 : :
198 [ # # ][ # # ]: 0 : m_pHolder->m_xBitmap = REF( AWT::XBitmap )( aIf, UNO_QUERY );
199 : :
200 : 0 : m_pHolder->m_bBusy = true;
201 [ # # ]: 0 : if( m_pHolder->m_aSane.IsOpen() )
202 : : {
203 [ # # ]: 0 : int nOption = m_pHolder->m_aSane.GetOptionByName( "preview" );
204 [ # # ]: 0 : if( nOption != -1 )
205 [ # # ]: 0 : m_pHolder->m_aSane.SetOptionValue( nOption, (sal_Bool)sal_False );
206 : :
207 : 0 : m_pHolder->m_nError =
208 [ # # ]: 0 : m_pHolder->m_aSane.Start( *pTransporter ) ?
209 [ # # ]: 0 : ScanError_ScanErrorNone : ScanError_ScanCanceled;
210 : : }
211 : : else
212 : 0 : m_pHolder->m_nError = ScanError_ScannerNotAvailable;
213 : :
214 : :
215 [ # # ]: 0 : REF( XInterface ) xXInterface( static_cast< OWeakObject* >( m_pManager ) );
216 [ # # ][ # # ]: 0 : m_xListener->disposing( com::sun::star::lang::EventObject(xXInterface) );
[ # # ][ # # ]
217 [ # # ]: 0 : m_pHolder->m_bBusy = false;
218 : 0 : }
219 : :
220 : : // ------------------
221 : : // - ScannerManager -
222 : : // ------------------
223 : :
224 : 130 : void ScannerManager::AcquireData()
225 : : {
226 [ + - ][ + - ]: 130 : osl::MutexGuard aGuard( theSaneProtector::get() );
227 [ + - ][ + - ]: 130 : theSanes::get().acquire();
228 : 130 : }
229 : :
230 : 130 : void ScannerManager::ReleaseData()
231 : : {
232 [ + - ][ + - ]: 130 : osl::MutexGuard aGuard( theSaneProtector::get() );
233 [ + - ][ + - ]: 130 : theSanes::get().release();
234 : 130 : }
235 : :
236 : : // -----------------------------------------------------------------------------
237 : :
238 : 0 : AWT::Size ScannerManager::getSize() throw()
239 : : {
240 : 0 : AWT::Size aRet;
241 : 0 : aRet.Width = aRet.Height = 0;
242 : 0 : return aRet;
243 : : }
244 : :
245 : : // -----------------------------------------------------------------------------
246 : :
247 : 0 : SEQ( sal_Int8 ) ScannerManager::getDIB() throw()
248 : : {
249 : 0 : return SEQ( sal_Int8 )();
250 : : }
251 : :
252 : : // -----------------------------------------------------------------------------
253 : :
254 : 0 : SEQ( ScannerContext ) ScannerManager::getAvailableScanners() throw()
255 : : {
256 [ # # ][ # # ]: 0 : osl::MutexGuard aGuard( theSaneProtector::get() );
257 [ # # ]: 0 : sanevec &rSanes = theSanes::get().m_aSanes;
258 : :
259 [ # # ]: 0 : if( rSanes.empty() )
260 : : {
261 [ # # ][ # # ]: 0 : boost::shared_ptr<SaneHolder> pSaneHolder(new SaneHolder);
[ # # ]
262 [ # # ]: 0 : if( Sane::IsSane() )
263 [ # # ][ # # ]: 0 : rSanes.push_back( pSaneHolder );
264 : : }
265 : :
266 [ # # ]: 0 : if( Sane::IsSane() )
267 : : {
268 [ # # ]: 0 : SEQ( ScannerContext ) aRet(1);
269 [ # # ]: 0 : aRet.getArray()[0].ScannerName = ::rtl::OUString("SANE");
270 [ # # ]: 0 : aRet.getArray()[0].InternalData = 0;
271 [ # # ][ # # ]: 0 : return aRet;
272 : : }
273 : :
274 [ # # ][ # # ]: 0 : return SEQ( ScannerContext )();
275 : : }
276 : :
277 : : // -----------------------------------------------------------------------------
278 : :
279 : 0 : sal_Bool ScannerManager::configureScannerAndScan( ScannerContext& scanner_context,
280 : : const REF( com::sun::star::lang::XEventListener )& listener ) throw( ScannerException )
281 : : {
282 : : bool bRet;
283 : : bool bScan;
284 : : {
285 [ # # ][ # # ]: 0 : osl::MutexGuard aGuard( theSaneProtector::get() );
286 [ # # ]: 0 : sanevec &rSanes = theSanes::get().m_aSanes;
287 : :
288 : : #if OSL_DEBUG_LEVEL > 1
289 : : fprintf( stderr, "ScannerManager::configureScanner\n" );
290 : : #endif
291 : :
292 [ # # ][ # # ]: 0 : if( scanner_context.InternalData < 0 || (sal_uLong)scanner_context.InternalData >= rSanes.size() )
[ # # ]
293 : : throw ScannerException(
294 : : ::rtl::OUString("Scanner does not exist"),
295 : : REF( XScannerManager )( this ),
296 : : ScanError_InvalidContext
297 [ # # ][ # # ]: 0 : );
298 : :
299 [ # # ]: 0 : boost::shared_ptr<SaneHolder> pHolder = rSanes[scanner_context.InternalData];
300 [ # # ]: 0 : if( pHolder->m_bBusy )
301 : : throw ScannerException(
302 : : ::rtl::OUString("Scanner is busy"),
303 : : REF( XScannerManager )( this ),
304 : : ScanError_ScanInProgress
305 [ # # ][ # # ]: 0 : );
306 : :
307 : 0 : pHolder->m_bBusy = true;
308 [ # # ]: 0 : SaneDlg aDlg( NULL, pHolder->m_aSane, listener.is() );
309 [ # # ]: 0 : bRet = aDlg.Execute();
310 [ # # ]: 0 : bScan = aDlg.getDoScan();
311 [ # # ][ # # ]: 0 : pHolder->m_bBusy = false;
[ # # ]
312 : : }
313 [ # # ]: 0 : if ( bScan )
314 : 0 : startScan( scanner_context, listener );
315 : :
316 : 0 : return bRet;
317 : : }
318 : :
319 : : // -----------------------------------------------------------------------------
320 : :
321 : 0 : void ScannerManager::startScan( const ScannerContext& scanner_context,
322 : : const REF( com::sun::star::lang::XEventListener )& listener ) throw( ScannerException )
323 : : {
324 [ # # ][ # # ]: 0 : osl::MutexGuard aGuard( theSaneProtector::get() );
325 [ # # ]: 0 : sanevec &rSanes = theSanes::get().m_aSanes;
326 : :
327 : : #if OSL_DEBUG_LEVEL > 1
328 : : fprintf( stderr, "ScannerManager::startScan\n" );
329 : : #endif
330 : :
331 [ # # ][ # # ]: 0 : if( scanner_context.InternalData < 0 || (sal_uLong)scanner_context.InternalData >= rSanes.size() )
[ # # ]
332 : : throw ScannerException(
333 : : ::rtl::OUString("Scanner does not exist"),
334 : : REF( XScannerManager )( this ),
335 : : ScanError_InvalidContext
336 [ # # ][ # # ]: 0 : );
337 [ # # ]: 0 : boost::shared_ptr<SaneHolder> pHolder = rSanes[scanner_context.InternalData];
338 [ # # ]: 0 : if( pHolder->m_bBusy )
339 : : throw ScannerException(
340 : : ::rtl::OUString("Scanner is busy"),
341 : : REF( XScannerManager )( this ),
342 : : ScanError_ScanInProgress
343 [ # # ][ # # ]: 0 : );
344 : 0 : pHolder->m_bBusy = true;
345 : :
346 [ # # ][ # # ]: 0 : ScannerThread* pThread = new ScannerThread( pHolder, listener, this );
[ # # ]
347 [ # # ][ # # ]: 0 : pThread->create();
[ # # ]
348 : 0 : }
349 : :
350 : : // -----------------------------------------------------------------------------
351 : :
352 : 0 : ScanError ScannerManager::getError( const ScannerContext& scanner_context ) throw( ScannerException )
353 : : {
354 [ # # ][ # # ]: 0 : osl::MutexGuard aGuard( theSaneProtector::get() );
355 [ # # ]: 0 : sanevec &rSanes = theSanes::get().m_aSanes;
356 : :
357 [ # # ][ # # ]: 0 : if( scanner_context.InternalData < 0 || (sal_uLong)scanner_context.InternalData >= rSanes.size() )
[ # # ]
358 : : throw ScannerException(
359 : : ::rtl::OUString("Scanner does not exist"),
360 : : REF( XScannerManager )( this ),
361 : : ScanError_InvalidContext
362 [ # # ][ # # ]: 0 : );
363 : :
364 [ # # ]: 0 : boost::shared_ptr<SaneHolder> pHolder = rSanes[scanner_context.InternalData];
365 : :
366 [ # # ][ # # ]: 0 : return pHolder->m_nError;
367 : : }
368 : :
369 : : // -----------------------------------------------------------------------------
370 : :
371 : 0 : REF( AWT::XBitmap ) ScannerManager::getBitmap( const ScannerContext& scanner_context ) throw( ScannerException )
372 : : {
373 [ # # ][ # # ]: 0 : osl::MutexGuard aGuard( theSaneProtector::get() );
374 [ # # ]: 0 : sanevec &rSanes = theSanes::get().m_aSanes;
375 : :
376 [ # # ][ # # ]: 0 : if( scanner_context.InternalData < 0 || (sal_uLong)scanner_context.InternalData >= rSanes.size() )
[ # # ]
377 : : throw ScannerException(
378 : : ::rtl::OUString("Scanner does not exist"),
379 : : REF( XScannerManager )( this ),
380 : : ScanError_InvalidContext
381 [ # # ][ # # ]: 0 : );
382 [ # # ]: 0 : boost::shared_ptr<SaneHolder> pHolder = rSanes[scanner_context.InternalData];
383 : :
384 [ # # ]: 0 : osl::MutexGuard aProtGuard( pHolder->m_aProtector );
385 : :
386 : 0 : REF( AWT::XBitmap ) xRet( pHolder->m_xBitmap );
387 [ # # ]: 0 : pHolder->m_xBitmap = REF( AWT::XBitmap )();
388 : :
389 [ # # ][ # # ]: 0 : return xRet;
[ # # ]
390 : : }
391 : :
392 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|