LCOV - code coverage report
Current view: top level - extensions/source/scanner - scanunx.cxx (source / functions) Hit Total Coverage
Test: commit 0e63ca4fde4e446f346e35849c756a30ca294aab Lines: 18 137 13.1 %
Date: 2014-04-11 Functions: 6 26 23.1 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.10