LCOV - code coverage report
Current view: top level - extensions/source/scanner - scanunx.cxx (source / functions) Hit Total Coverage
Test: commit 10e77ab3ff6f4314137acd6e2702a6e5c1ce1fae Lines: 19 139 13.7 %
Date: 2014-11-03 Functions: 8 28 28.6 %
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          22 :     class allSanes
     114             :     {
     115             :     private:
     116             :         int mnRefCount;
     117             :     public:
     118             :         sanevec m_aSanes;
     119          22 :         allSanes() : mnRefCount(0) {}
     120             :         void acquire();
     121             :         void release();
     122             :     };
     123             : 
     124         198 :     void allSanes::acquire()
     125             :     {
     126         198 :         ++mnRefCount;
     127         198 :     }
     128             : 
     129         198 :     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         198 :         --mnRefCount;
     134         198 :         if (!mnRefCount)
     135         198 :             m_aSanes.clear();
     136         198 :     }
     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_setThreadName("ScannerThread");
     185             : 
     186           0 :     osl::MutexGuard         aGuard( m_pHolder->m_aProtector );
     187           0 :     BitmapTransporter*  pTransporter = new BitmapTransporter;
     188           0 :     Reference< XInterface >   aIf( static_cast< OWeakObject* >( pTransporter ) );
     189             : 
     190           0 :     m_pHolder->m_xBitmap = Reference< css::awt::XBitmap >( aIf, UNO_QUERY );
     191             : 
     192           0 :     m_pHolder->m_bBusy = true;
     193           0 :     if( m_pHolder->m_aSane.IsOpen() )
     194             :     {
     195           0 :         int nOption = m_pHolder->m_aSane.GetOptionByName( "preview" );
     196           0 :         if( nOption != -1 )
     197           0 :             m_pHolder->m_aSane.SetOptionValue( nOption, false );
     198             : 
     199           0 :         m_pHolder->m_nError =
     200           0 :             m_pHolder->m_aSane.Start( *pTransporter ) ?
     201           0 :             ScanError_ScanErrorNone : ScanError_ScanCanceled;
     202             :     }
     203             :     else
     204           0 :         m_pHolder->m_nError = ScanError_ScannerNotAvailable;
     205             : 
     206             : 
     207           0 :     Reference< XInterface > xXInterface( static_cast< OWeakObject* >( m_pManager ) );
     208           0 :     m_xListener->disposing( com::sun::star::lang::EventObject(xXInterface) );
     209           0 :     m_pHolder->m_bBusy = false;
     210           0 : }
     211             : 
     212             : 
     213             : // - ScannerManager -
     214             : 
     215             : 
     216         198 : void ScannerManager::AcquireData()
     217             : {
     218         198 :     osl::MutexGuard aGuard( theSaneProtector::get() );
     219         198 :     theSanes::get().acquire();
     220         198 : }
     221             : 
     222         198 : void ScannerManager::ReleaseData()
     223             : {
     224         198 :     osl::MutexGuard aGuard( theSaneProtector::get() );
     225         198 :     theSanes::get().release();
     226         198 : }
     227             : 
     228             : 
     229             : 
     230           0 : css::awt::Size ScannerManager::getSize() throw(std::exception)
     231             : {
     232           0 :     css::awt::Size aRet;
     233           0 :     aRet.Width = aRet.Height = 0;
     234           0 :     return aRet;
     235             : }
     236             : 
     237             : 
     238             : 
     239           0 : Sequence< sal_Int8 > ScannerManager::getDIB() throw(std::exception)
     240             : {
     241           0 :     return Sequence< sal_Int8 >();
     242             : }
     243             : 
     244             : 
     245             : 
     246           0 : Sequence< ScannerContext > ScannerManager::getAvailableScanners() throw(std::exception)
     247             : {
     248           0 :     osl::MutexGuard aGuard( theSaneProtector::get() );
     249           0 :     sanevec &rSanes = theSanes::get().m_aSanes;
     250             : 
     251           0 :     if( rSanes.empty() )
     252             :     {
     253           0 :         boost::shared_ptr<SaneHolder> pSaneHolder(new SaneHolder);
     254           0 :         if( Sane::IsSane() )
     255           0 :             rSanes.push_back( pSaneHolder );
     256             :     }
     257             : 
     258           0 :     if( Sane::IsSane() )
     259             :     {
     260           0 :         Sequence< ScannerContext > aRet(1);
     261           0 :         aRet[0].ScannerName      = "SANE";
     262           0 :         aRet[0].InternalData     = 0;
     263           0 :         return aRet;
     264             :     }
     265             : 
     266           0 :     return Sequence< ScannerContext >();
     267             : }
     268             : 
     269             : 
     270             : 
     271           0 : sal_Bool ScannerManager::configureScannerAndScan( ScannerContext& scanner_context,
     272             :                                                   const Reference< com::sun::star::lang::XEventListener >& listener )
     273             :     throw (ScannerException, RuntimeException, std::exception)
     274             : {
     275             :     bool bRet;
     276             :     bool bScan;
     277             :     {
     278           0 :         osl::MutexGuard aGuard( theSaneProtector::get() );
     279           0 :         sanevec &rSanes = theSanes::get().m_aSanes;
     280             : 
     281             : #if OSL_DEBUG_LEVEL > 1
     282             :         fprintf( stderr, "ScannerManager::configureScanner\n" );
     283             : #endif
     284             : 
     285           0 :         if( scanner_context.InternalData < 0 || (sal_uLong)scanner_context.InternalData >= rSanes.size() )
     286             :             throw ScannerException(
     287             :                 "Scanner does not exist",
     288             :                 Reference< XScannerManager >( this ),
     289             :                 ScanError_InvalidContext
     290           0 :             );
     291             : 
     292           0 :         boost::shared_ptr<SaneHolder> pHolder = rSanes[scanner_context.InternalData];
     293           0 :         if( pHolder->m_bBusy )
     294             :             throw ScannerException(
     295             :                 "Scanner is busy",
     296             :                 Reference< XScannerManager >( this ),
     297             :                 ScanError_ScanInProgress
     298           0 :             );
     299             : 
     300           0 :         pHolder->m_bBusy = true;
     301           0 :         SaneDlg aDlg( NULL, pHolder->m_aSane, listener.is() );
     302           0 :         bRet = aDlg.Execute();
     303           0 :         bScan = aDlg.getDoScan();
     304           0 :         pHolder->m_bBusy = false;
     305             :     }
     306           0 :     if ( bScan )
     307           0 :         startScan( scanner_context, listener );
     308             : 
     309           0 :     return bRet;
     310             : }
     311             : 
     312             : 
     313             : 
     314           0 : void ScannerManager::startScan( const ScannerContext& scanner_context,
     315             :                                 const Reference< com::sun::star::lang::XEventListener >& listener ) throw( ScannerException, std::exception )
     316             : {
     317           0 :     osl::MutexGuard aGuard( theSaneProtector::get() );
     318           0 :     sanevec &rSanes = theSanes::get().m_aSanes;
     319             : 
     320             : #if OSL_DEBUG_LEVEL > 1
     321             :     fprintf( stderr, "ScannerManager::startScan\n" );
     322             : #endif
     323             : 
     324           0 :     if( scanner_context.InternalData < 0 || (sal_uLong)scanner_context.InternalData >= rSanes.size() )
     325             :         throw ScannerException(
     326             :             "Scanner does not exist",
     327             :             Reference< XScannerManager >( this ),
     328             :             ScanError_InvalidContext
     329           0 :             );
     330           0 :     boost::shared_ptr<SaneHolder> pHolder = rSanes[scanner_context.InternalData];
     331           0 :     if( pHolder->m_bBusy )
     332             :         throw ScannerException(
     333             :             "Scanner is busy",
     334             :             Reference< XScannerManager >( this ),
     335             :             ScanError_ScanInProgress
     336           0 :             );
     337           0 :     pHolder->m_bBusy = true;
     338             : 
     339           0 :     ScannerThread* pThread = new ScannerThread( pHolder, listener, this );
     340           0 :     pThread->create();
     341           0 : }
     342             : 
     343             : 
     344             : 
     345           0 : ScanError ScannerManager::getError( const ScannerContext& scanner_context ) throw( ScannerException, std::exception )
     346             : {
     347           0 :     osl::MutexGuard aGuard( theSaneProtector::get() );
     348           0 :     sanevec &rSanes = theSanes::get().m_aSanes;
     349             : 
     350           0 :     if( scanner_context.InternalData < 0 || (sal_uLong)scanner_context.InternalData >= rSanes.size() )
     351             :         throw ScannerException(
     352             :             "Scanner does not exist",
     353             :             Reference< XScannerManager >( this ),
     354             :             ScanError_InvalidContext
     355           0 :             );
     356             : 
     357           0 :     boost::shared_ptr<SaneHolder> pHolder = rSanes[scanner_context.InternalData];
     358             : 
     359           0 :     return pHolder->m_nError;
     360             : }
     361             : 
     362             : 
     363             : 
     364           0 : Reference< css::awt::XBitmap > ScannerManager::getBitmap( const ScannerContext& scanner_context ) throw( ScannerException, std::exception )
     365             : {
     366           0 :     osl::MutexGuard aGuard( theSaneProtector::get() );
     367           0 :     sanevec &rSanes = theSanes::get().m_aSanes;
     368             : 
     369           0 :     if( scanner_context.InternalData < 0 || (sal_uLong)scanner_context.InternalData >= rSanes.size() )
     370             :         throw ScannerException(
     371             :             "Scanner does not exist",
     372             :             Reference< XScannerManager >( this ),
     373             :             ScanError_InvalidContext
     374           0 :             );
     375           0 :     boost::shared_ptr<SaneHolder> pHolder = rSanes[scanner_context.InternalData];
     376             : 
     377           0 :     osl::MutexGuard aProtGuard( pHolder->m_aProtector );
     378             : 
     379           0 :     Reference< css::awt::XBitmap > xRet( pHolder->m_xBitmap );
     380           0 :     pHolder->m_xBitmap = Reference< css::awt::XBitmap >();
     381             : 
     382           0 :     return xRet;
     383          66 : }
     384             : 
     385             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10