<commit_before>/*************************************************************************
 *
 *  $RCSfile: basicmigration.hxx,v $
 *
 *  $Revision: 1.2 $
 *
 *  last change: $Author: rt $ $Date: 2005-01-27 14:26:43 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (the "License"); You may not use this file
 *  except in compliance with the License. You may obtain a copy of the
 *  License at http://www.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

#ifndef _DESKTOP_BASICMIGRATION_HXX_
#define _DESKTOP_BASICMIGRATION_HXX_

#ifndef _COM_SUN_STAR_LANG_XSERVICEINFO_HPP_
#include <com/sun/star/lang/XServiceInfo.hpp>
#endif
#ifndef _COM_SUN_STAR_LANG_XINITIALIZATION_HPP_
#include <com/sun/star/lang/XInitialization.hpp>
#endif
#ifndef _COM_SUN_STAR_TASK_XJOB_HPP_
#include <com/sun/star/task/XJob.hpp>
#endif
#ifndef _COM_SUN_STAR_UNO_XCOMPONENTCONTEXT_HPP_
#include <com/sun/star/uno/XComponentContext.hpp>
#endif

#ifndef _CPPUHELPER_IMPLBASE3_HXX_
#include <cppuhelper/implbase3.hxx>
#endif
#ifndef _OSL_MUTEX_HXX_
#include <osl/mutex.hxx>
#endif
#ifndef _OSL_FILE_HXX_
#include <osl/file.hxx>
#endif

#include <vector>
#include <memory>

class INetURLObject;

//.........................................................................
namespace migration
{
//.........................................................................

    ::rtl::OUString SAL_CALL BasicMigration_getImplementationName();
    ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL BasicMigration_getSupportedServiceNames();
    ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > SAL_CALL BasicMigration_create(
        ::com::sun::star::uno::Reference< ::com::sun::star::uno::XComponentContext > const & xContext )
        SAL_THROW( (::com::sun::star::uno::Exception) );

    // =============================================================================
    // class BasicMigration
    // =============================================================================

    typedef ::std::vector< ::rtl::OUString > TStringVector;
    typedef ::std::auto_ptr< TStringVector > TStringVectorPtr;

    typedef ::cppu::WeakImplHelper3<
        ::com::sun::star::lang::XServiceInfo,
        ::com::sun::star::lang::XInitialization,
        ::com::sun::star::task::XJob > BasicMigration_BASE;

    class BasicMigration : public BasicMigration_BASE
    {
    private:
        ::osl::Mutex            m_aMutex;
        ::rtl::OUString         m_sSourceDir;

        TStringVectorPtr        getFiles( const ::rtl::OUString& rBaseURL ) const;
        ::osl::FileBase::RC     checkAndCreateDirectory( INetURLObject& rDirURL );
        void                    copyFiles();

    public:
        BasicMigration();
        virtual ~BasicMigration();

        // XServiceInfo
        virtual ::rtl::OUString SAL_CALL getImplementationName()
            throw (::com::sun::star::uno::RuntimeException);
        virtual sal_Bool SAL_CALL supportsService( const ::rtl::OUString& rServiceName )
            throw (::com::sun::star::uno::RuntimeException);
        virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL getSupportedServiceNames()
            throw (::com::sun::star::uno::RuntimeException);

        // XInitialization
        virtual void SAL_CALL initialize( const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any >& aArguments )
            throw (::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException);

        // XJob
        virtual ::com::sun::star::uno::Any SAL_CALL execute(
            const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::NamedValue >& Arguments )
            throw (::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::Exception,
                ::com::sun::star::uno::RuntimeException);
    };

//.........................................................................
}   // namespace migration
//.........................................................................

#endif // _DESKTOP_BASICMIGRATION_HXX_
<commit_msg>INTEGRATION: CWS lo5 (1.2.88); FILE MERGED 2005/04/28 11:24:45 tbe 1.2.88.1: #i48275# migration of auto correction files<commit_after>/*************************************************************************
 *
 *  $RCSfile: basicmigration.hxx,v $
 *
 *  $Revision: 1.3 $
 *
 *  last change: $Author: rt $ $Date: 2005-05-13 08:10:05 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (the "License"); You may not use this file
 *  except in compliance with the License. You may obtain a copy of the
 *  License at http://www.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

#ifndef _DESKTOP_BASICMIGRATION_HXX_
#define _DESKTOP_BASICMIGRATION_HXX_

#ifndef _DESKTOP_MISC_HXX_
#include "misc.hxx"
#endif

#ifndef _COM_SUN_STAR_LANG_XSERVICEINFO_HPP_
#include <com/sun/star/lang/XServiceInfo.hpp>
#endif
#ifndef _COM_SUN_STAR_LANG_XINITIALIZATION_HPP_
#include <com/sun/star/lang/XInitialization.hpp>
#endif
#ifndef _COM_SUN_STAR_TASK_XJOB_HPP_
#include <com/sun/star/task/XJob.hpp>
#endif
#ifndef _COM_SUN_STAR_UNO_XCOMPONENTCONTEXT_HPP_
#include <com/sun/star/uno/XComponentContext.hpp>
#endif

#ifndef _CPPUHELPER_IMPLBASE3_HXX_
#include <cppuhelper/implbase3.hxx>
#endif
#ifndef _OSL_MUTEX_HXX_
#include <osl/mutex.hxx>
#endif
#ifndef _OSL_FILE_HXX_
#include <osl/file.hxx>
#endif

class INetURLObject;

//.........................................................................
namespace migration
{
//.........................................................................

    ::rtl::OUString SAL_CALL BasicMigration_getImplementationName();
    ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL BasicMigration_getSupportedServiceNames();
    ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > SAL_CALL BasicMigration_create(
        ::com::sun::star::uno::Reference< ::com::sun::star::uno::XComponentContext > const & xContext )
        SAL_THROW( (::com::sun::star::uno::Exception) );

    // =============================================================================
    // class BasicMigration
    // =============================================================================

    typedef ::cppu::WeakImplHelper3<
        ::com::sun::star::lang::XServiceInfo,
        ::com::sun::star::lang::XInitialization,
        ::com::sun::star::task::XJob > BasicMigration_BASE;

    class BasicMigration : public BasicMigration_BASE
    {
    private:
        ::osl::Mutex            m_aMutex;
        ::rtl::OUString         m_sSourceDir;

        TStringVectorPtr        getFiles( const ::rtl::OUString& rBaseURL ) const;
        ::osl::FileBase::RC     checkAndCreateDirectory( INetURLObject& rDirURL );
        void                    copyFiles();

    public:
        BasicMigration();
        virtual ~BasicMigration();

        // XServiceInfo
        virtual ::rtl::OUString SAL_CALL getImplementationName()
            throw (::com::sun::star::uno::RuntimeException);
        virtual sal_Bool SAL_CALL supportsService( const ::rtl::OUString& rServiceName )
            throw (::com::sun::star::uno::RuntimeException);
        virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL getSupportedServiceNames()
            throw (::com::sun::star::uno::RuntimeException);

        // XInitialization
        virtual void SAL_CALL initialize( const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any >& aArguments )
            throw (::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException);

        // XJob
        virtual ::com::sun::star::uno::Any SAL_CALL execute(
            const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::NamedValue >& Arguments )
            throw (::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::Exception,
                ::com::sun::star::uno::RuntimeException);
    };

//.........................................................................
}   // namespace migration
//.........................................................................

#endif // _DESKTOP_BASICMIGRATION_HXX_
<|endoftext|>


<commit_before>//
// Copyright (C) 2007-2016 SIPez LLC.  All rights reserved.
//
// Copyright (C) 2007 SIPfoundry Inc.
// Licensed by SIPfoundry under the LGPL license.
//
// $$
///////////////////////////////////////////////////////////////////////////////

// Author: Alexander Chemeris <Alexander DOT Chemeris AT SIPez DOT com>

// SYSTEM INCLUDES
#include <assert.h>

// APPLICATION INCLUDES
#include <mp/MpAudioOutputConnection.h>
#include <mp/MpOutputDeviceDriver.h>
#include <mp/MpDspUtils.h>
#include <os/OsLock.h>
#include <os/OsDefs.h>    // for min macro
#include <os/OsSysLog.h>

//#define RTL_ENABLED
//#define RTL_AUDIO_ENABLED

#ifdef RTL_ENABLED
#include <rtl_macro.h>
#else
#define RTL_BLOCK(x)
#define RTL_EVENT(x,y)
#endif

// EXTERNAL FUNCTIONS
// EXTERNAL VARIABLES
// CONSTANTS
// STATIC VARIABLE INITIALIZATIONS
// PRIVATE CLASSES
// DEFINES
#define DEBUG_PRINT
#undef  DEBUG_PRINT

// MACROS
#ifdef DEBUG_PRINT // [
#  define debugPrintf    printf
#else  // DEBUG_PRINT ][
static void debugPrintf(...) {}
#endif // DEBUG_PRINT ]

/* //////////////////////////// PUBLIC //////////////////////////////////// */

/* ============================ CREATORS ================================== */

MpAudioOutputConnection::MpAudioOutputConnection(MpOutputDeviceHandle deviceId,
                                                 MpOutputDeviceDriver *deviceDriver)
: UtlInt(deviceId)
, mMutex(OsMutexBase::Q_PRIORITY)
, mUseCount(0)
, mpDeviceDriver(deviceDriver)
, mCurrentFrameTime(0)
, mMixerBufferLength(0)
, mpMixerBuffer(NULL)
, mMixerBufferBegin(0)
, readyForDataCallbackNotf((intptr_t)this, readyForDataCallback)
, mpFlowgraphTicker(NULL)
{
   assert(mpDeviceDriver != NULL);
};

MpAudioOutputConnection::~MpAudioOutputConnection()
{
}

/* ============================ MANIPULATORS ============================== */

OsStatus MpAudioOutputConnection::enableDevice(unsigned samplesPerFrame,
                                               unsigned samplesPerSec,
                                               MpFrameTime currentFrameTime,
                                               MpFrameTime mixerBufferLength)
{
   OsStatus result = OS_FAILED;
   OsLock lock(mMutex);

   assert(samplesPerFrame > 0);
   assert(samplesPerSec > 0);

   if (mpDeviceDriver->isEnabled())
   {
      OsSysLog::add(FAC_MP, PRI_DEBUG,
              "MpAudioOutputConnection::enableDevice() device (%s id: %d) already enabled status: %d",
              mpDeviceDriver->getDeviceName().data(),
              getValue(),
              OS_INVALID_STATE);
      return(OS_INVALID_STATE);
   }

   // Mixer buffer length can't be zero.
   if (mixerBufferLength == 0)
   {
      return OS_NOT_SUPPORTED;
   }

   // Set current frame time for this connection.
   mCurrentFrameTime = currentFrameTime;

   // Calculate number of samples in mixer buffer.
   // I.e. convert from milliseconds to samples and round to frame boundary.
   // Note: this calculation may overflow (e.g. 10000msec*44100Hz > 4294967296smp).
   unsigned bufferSamples = mixerBufferLength*samplesPerSec/1000;
   bufferSamples = ((bufferSamples + samplesPerFrame - 1) / samplesPerFrame)
                 * samplesPerFrame;

   // Initialize mixer buffer. All mixer buffer related variables will be set here.
   if (initMixerBuffer(bufferSamples) != OS_SUCCESS)
   {
      return result;
   }

   // Enable device driver
   result = mpDeviceDriver->enableDevice(samplesPerFrame,
                                         samplesPerSec,
                                         mCurrentFrameTime,
                                         readyForDataCallbackNotf);

   return result;
}

OsStatus MpAudioOutputConnection::disableDevice()
{
   OsStatus result = OS_FAILED;
   OsLock lock(mMutex);

   // Disable device and set result code.
   result = mpDeviceDriver->disableDevice();

   // Free mixer buffer if device was set to disabled state.
   if (!mpDeviceDriver->isEnabled())
   {
      // Do not check return code, as it is not critical if it fails.
      freeMixerBuffer();
   }

   return result;
}

OsStatus MpAudioOutputConnection::enableFlowgraphTicker(OsNotification *pFlowgraphTicker)
{
   OsStatus result = OS_SUCCESS;
   OsLock lock(mMutex);

   assert(mpFlowgraphTicker == NULL);

   // Set flowgraph ticker
   mpFlowgraphTicker = pFlowgraphTicker;

   return result;
}

OsStatus MpAudioOutputConnection::disableFlowgraphTicker()
{
   OsStatus result = OS_SUCCESS;
   OsLock lock(mMutex);

   assert(mpFlowgraphTicker != NULL);

   // Clear flowgraph ticker notification
   mpFlowgraphTicker = NULL;

   return result;
}

OsStatus MpAudioOutputConnection::pushFrameBeginning(unsigned int numSamples,
                                                     const MpAudioSample* samples,
                                                     MpFrameTime &frameTime)
{
   OsStatus result = OS_SUCCESS;
   RTL_BLOCK("MpAudioOutputConnection::pushFrame");

   assert(numSamples > 0);

   // From now we access internal data. Take lock.
   OsLock lock(mMutex);

   RTL_EVENT("MpAudioOutputConnection::pushFrame_frameTime", frameTime);
   RTL_EVENT("MpAudioOutputConnection::pushFrame_currentTime", mCurrentFrameTime);
   RTL_EVENT("MpAudioOutputConnection::pushFrame", this->getValue());

   // Do nothing if no audio was pushed. Mixer buffer will be filled with
   // silence or data from other sources.
   if (samples != NULL)
   {
      // Mix frame to the very beginning of the mixer buffer.
      result = mixFrame(mMixerBufferBegin, samples, numSamples);
   }

   frameTime = mCurrentFrameTime;

   return result;
};

OsStatus MpAudioOutputConnection::pushFrame(unsigned int numSamples,
                                            const MpAudioSample* samples,
                                            MpFrameTime frameTime)
{
   OsStatus result = OS_SUCCESS;
   RTL_EVENT("MpAudioOutputConnection::pushFrame", -1);

   assert(numSamples > 0);

   // From now we access internal data. Take lock.
   OsLock lock(mMutex);

   RTL_EVENT("MpAudioOutputConnection::pushFrame_frameTime", frameTime);
   RTL_EVENT("MpAudioOutputConnection::pushFrame_currentTime", mCurrentFrameTime);
   RTL_EVENT("MpAudioOutputConnection::pushFrame", this->getValue());

   // Check for late frame. Check for early frame is done inside mixFrame().
   if (MpDspUtils::compareSerials(frameTime, mCurrentFrameTime) < 0)
   {
      OsSysLog::add(FAC_MP, PRI_WARNING,
                    "MpAudioOutputConnection::pushFrame()"
                    " OS_INVALID_STATE frameTime=%d, currentTime=%d\n",
                    frameTime, mCurrentFrameTime);
      result = OS_INVALID_STATE;
      RTL_EVENT("MpAudioOutputConnection::pushFrame", result);
      return result;
   }

   if(mpDeviceDriver->isEnabled())
   {
       // Convert frameTime to offset in mixer buffer.
       // Note: frameTime >= mCurrentFrameTime.
       unsigned mixerBufferOffsetFrames =
                (frameTime-mCurrentFrameTime) / mpDeviceDriver->getFramePeriod();
       unsigned mixerBufferOffsetSamples =
                mixerBufferOffsetFrames * mpDeviceDriver->getSamplesPerFrame();

       // Don't touch mix buffer if no audio was pushed. Mixer buffer will be filled
       // with silence or data from other sources.
       if (samples != NULL)
       {
          // Mix this data with other sources.
          result = mixFrame(mixerBufferOffsetSamples, samples, numSamples);
          if(result != OS_SUCCESS)
          {
              OsSysLog::add(FAC_MP, PRI_WARNING,
                            "MpAudioOutputConnection::pushFrame mixFrame(%d, %p, %d) returned: %d"
                            " frameTime=%d, currentTime=%d\n",
                            (int)mixerBufferOffsetSamples, samples, numSamples, result,
                            frameTime, mCurrentFrameTime);
          }
       }
       else
       {
          // Just check for late frame.
          result = isLateToMix(mixerBufferOffsetSamples, numSamples);
       }
   }
   else
   {
       result = OS_INVALID_STATE;
   }

   RTL_EVENT("MpAudioOutputConnection::pushFrame", result);
   return result;
};

/* ============================ ACCESSORS ================================= */

MpFrameTime MpAudioOutputConnection::getCurrentFrameTime() const
{
   OsLock lock(mMutex);
   return mCurrentFrameTime;
}

/* ============================ INQUIRY =================================== */

/* //////////////////////////// PROTECTED ///////////////////////////////// */

OsStatus MpAudioOutputConnection::initMixerBuffer(unsigned mixerBufferLength)
{
   // We cannot allocate buffer of zero length.
   if (mixerBufferLength == 0)
   {
      return OS_FAILED;
   }

   // Deallocate mixer buffer if it is allocated.
   // Do not check return value. Nothing fatal may happen inside.
   freeMixerBuffer();

   // Initialize variables.
   mMixerBufferLength = mixerBufferLength;
   mpMixerBuffer = new MpAudioSample[mMixerBufferLength];
   mMixerBufferBegin = 0;

   // Clear buffer data.
   memset(mpMixerBuffer, 0, mMixerBufferLength*sizeof(MpAudioSample));

   return OS_SUCCESS;
}

OsStatus MpAudioOutputConnection::freeMixerBuffer()
{
   mMixerBufferLength = 0;
   if (mpMixerBuffer != NULL)
   {
      delete[] mpMixerBuffer;
      mpMixerBuffer = NULL;
   }
   mMixerBufferBegin = 0;

   return OS_SUCCESS;
}

OsStatus MpAudioOutputConnection::mixFrame(unsigned frameOffset,
                                           const MpAudioSample* samples,
                                           unsigned numSamples)
{
   assert(numSamples > 0);
   assert(samples != NULL);

   // Check for late frame.
   if (isLateToMix(frameOffset, numSamples) == OS_LIMIT_REACHED)
   {
      OsSysLog::add(FAC_MP, PRI_WARNING,
                  "MpAudioOutputConnection::mixFrame()"
                  " OS_LIMIT_REACHED offset=%d, samples=%d, bufferLength=%d\n",
                  frameOffset, numSamples, mMixerBufferLength);
      return OS_LIMIT_REACHED;
   }

   // Calculate frame start as if buffer is linear
   unsigned frameBegin = mMixerBufferBegin+frameOffset;
   // and wrap it because it is circular actually.
   if (frameBegin >= mMixerBufferLength)
   {
      frameBegin -= mMixerBufferLength;
   }

   // Calculate size of first chunk to mix.
   unsigned firstChunkSize = sipx_min(numSamples, mMixerBufferLength-frameBegin);

   // Counter variables for next two loops
   unsigned srcIndex, dstIndex;

   // from frame begin to buffer wrap
   for (srcIndex=0, dstIndex=frameBegin;
        srcIndex<firstChunkSize;
        srcIndex++, dstIndex++)
   {
      mpMixerBuffer[dstIndex] += samples[srcIndex];
   }

   // from buffer wrap to frame end
   for (dstIndex=0;
        srcIndex<numSamples;
        srcIndex++, dstIndex++)
   {
      mpMixerBuffer[dstIndex] += samples[srcIndex];
   }

   return OS_SUCCESS;
}

OsStatus MpAudioOutputConnection::advanceMixerBuffer(unsigned numSamples)
{
   // If buffer could be copied in one pass
   if(numSamples <= 0)
   {
      OsSysLog::add(FAC_MP, PRI_ERR, "MpAudioOutputConnection::advanceMixerBuffer invoked with: %d samples\n", numSamples);
      assert(numSamples > 0);
   }
   else if(numSamples > mMixerBufferLength)
   {
      OsSysLog::add(FAC_MP, PRI_ERR, "MpAudioOutputConnection::advanceMixerBuffer invoked with numSamples: %d > mMixerBufferLength: %d\n",
             numSamples, mMixerBufferLength);
      assert(numSamples <= mMixerBufferLength);
   }
   else if (mMixerBufferBegin+numSamples <= mMixerBufferLength)
   {
      memset(&mpMixerBuffer[mMixerBufferBegin],
             0,
             numSamples*sizeof(MpAudioSample));
      mMixerBufferBegin += numSamples;
      mMixerBufferBegin %= mMixerBufferLength;
   }
   else
   {
      unsigned firstChunkSize = mMixerBufferLength-mMixerBufferBegin;
      memset(&mpMixerBuffer[mMixerBufferBegin],
             0,
             firstChunkSize*sizeof(MpAudioSample));
      memset(&mpMixerBuffer[0],
             0,
             (numSamples-firstChunkSize)*sizeof(MpAudioSample));

      mMixerBufferBegin = numSamples - firstChunkSize;
   }

   return OS_SUCCESS;
}

void MpAudioOutputConnection::readyForDataCallback(const intptr_t userData,
                                                   const intptr_t eventData)
{
   OsStatus result;
   MpAudioOutputConnection *pConnection = (MpAudioOutputConnection*)userData;
   RTL_BLOCK("MpAudioOutputConnection::tickerCallBack");

   if (pConnection->mMutex.acquire(OsTime(5)) == OS_SUCCESS)
   {
      // Push data to device driver and forget.
      result = pConnection->mpDeviceDriver->pushFrame(
                     pConnection->mpDeviceDriver->getSamplesPerFrame(),
                     pConnection->mpMixerBuffer+pConnection->mMixerBufferBegin,
                     pConnection->mCurrentFrameTime);
      debugPrintf("MpAudioOutputConnection::readyForDataCallback()"
                  " frame=%d, pushFrame result=%d\n",
                  pConnection->mCurrentFrameTime, result);
//      assert(result == OS_SUCCESS);

      // Advance mixer buffer and frame time.
      pConnection->advanceMixerBuffer(pConnection->mpDeviceDriver->getSamplesPerFrame());
      pConnection->mCurrentFrameTime +=
                           pConnection->mpDeviceDriver->getSamplesPerFrame() * 1000
                           / pConnection->mpDeviceDriver->getSamplesPerSec();
      RTL_EVENT("MpAudioOutputConnection::tickerCallBack_currentFrameTime",
                pConnection->mCurrentFrameTime);

      pConnection->mMutex.release();
   }

   // Signal frame processing interval start if requested.
   if (pConnection->mpFlowgraphTicker)
   {
      pConnection->mpFlowgraphTicker->signal(0);
   }
}

/* //////////////////////////// PRIVATE /////////////////////////////////// */

/* ============================ FUNCTIONS ================================= */

<commit_msg>Added compile time conditional logging for output device ticker method invocation and mutex aquisition.<commit_after>//
// Copyright (C) 2007-2016 SIPez LLC.  All rights reserved.
//
// Copyright (C) 2007 SIPfoundry Inc.
// Licensed by SIPfoundry under the LGPL license.
//
// $$
///////////////////////////////////////////////////////////////////////////////

// Author: Alexander Chemeris <Alexander DOT Chemeris AT SIPez DOT com>

// SYSTEM INCLUDES
#include <assert.h>

// APPLICATION INCLUDES
#include <mp/MpAudioOutputConnection.h>
#include <mp/MpOutputDeviceDriver.h>
#include <mp/MpDspUtils.h>
#include <os/OsLock.h>
#include <os/OsDefs.h>    // for min macro
#include <os/OsSysLog.h>

// milliseconds
//#define LOG_HEART_BEAT_PERIOD 100

//#define RTL_ENABLED
//#define RTL_AUDIO_ENABLED

#ifdef RTL_ENABLED
#include <rtl_macro.h>
#else
#define RTL_BLOCK(x)
#define RTL_EVENT(x,y)
#endif

// EXTERNAL FUNCTIONS
// EXTERNAL VARIABLES
// CONSTANTS
// STATIC VARIABLE INITIALIZATIONS
// PRIVATE CLASSES
// DEFINES
// MACROS

/* //////////////////////////// PUBLIC //////////////////////////////////// */

/* ============================ CREATORS ================================== */

MpAudioOutputConnection::MpAudioOutputConnection(MpOutputDeviceHandle deviceId,
                                                 MpOutputDeviceDriver *deviceDriver)
: UtlInt(deviceId)
, mMutex(OsMutexBase::Q_PRIORITY)
, mUseCount(0)
, mpDeviceDriver(deviceDriver)
, mCurrentFrameTime(0)
, mMixerBufferLength(0)
, mpMixerBuffer(NULL)
, mMixerBufferBegin(0)
, readyForDataCallbackNotf((intptr_t)this, readyForDataCallback)
, mpFlowgraphTicker(NULL)
{
   assert(mpDeviceDriver != NULL);
};

MpAudioOutputConnection::~MpAudioOutputConnection()
{
}

/* ============================ MANIPULATORS ============================== */

OsStatus MpAudioOutputConnection::enableDevice(unsigned samplesPerFrame,
                                               unsigned samplesPerSec,
                                               MpFrameTime currentFrameTime,
                                               MpFrameTime mixerBufferLength)
{
   OsStatus result = OS_FAILED;
   OsLock lock(mMutex);

   assert(samplesPerFrame > 0);
   assert(samplesPerSec > 0);

   if (mpDeviceDriver->isEnabled())
   {
      OsSysLog::add(FAC_MP, PRI_DEBUG,
              "MpAudioOutputConnection::enableDevice() device (%s id: %d) already enabled status: %d",
              mpDeviceDriver->getDeviceName().data(),
              getValue(),
              OS_INVALID_STATE);
      return(OS_INVALID_STATE);
   }

   // Mixer buffer length can't be zero.
   if (mixerBufferLength == 0)
   {
      return OS_NOT_SUPPORTED;
   }

   // Set current frame time for this connection.
   mCurrentFrameTime = currentFrameTime;

   // Calculate number of samples in mixer buffer.
   // I.e. convert from milliseconds to samples and round to frame boundary.
   // Note: this calculation may overflow (e.g. 10000msec*44100Hz > 4294967296smp).
   unsigned bufferSamples = mixerBufferLength*samplesPerSec/1000;
   bufferSamples = ((bufferSamples + samplesPerFrame - 1) / samplesPerFrame)
                 * samplesPerFrame;

   // Initialize mixer buffer. All mixer buffer related variables will be set here.
   if (initMixerBuffer(bufferSamples) != OS_SUCCESS)
   {
      return result;
   }

   // Enable device driver
   result = mpDeviceDriver->enableDevice(samplesPerFrame,
                                         samplesPerSec,
                                         mCurrentFrameTime,
                                         readyForDataCallbackNotf);

   return result;
}

OsStatus MpAudioOutputConnection::disableDevice()
{
   OsStatus result = OS_FAILED;
   OsLock lock(mMutex);

   // Disable device and set result code.
   result = mpDeviceDriver->disableDevice();

   // Free mixer buffer if device was set to disabled state.
   if (!mpDeviceDriver->isEnabled())
   {
      // Do not check return code, as it is not critical if it fails.
      freeMixerBuffer();
   }

   return result;
}

OsStatus MpAudioOutputConnection::enableFlowgraphTicker(OsNotification *pFlowgraphTicker)
{
   OsStatus result = OS_SUCCESS;
   OsLock lock(mMutex);

   assert(mpFlowgraphTicker == NULL);

   // Set flowgraph ticker
   mpFlowgraphTicker = pFlowgraphTicker;

   return result;
}

OsStatus MpAudioOutputConnection::disableFlowgraphTicker()
{
   OsStatus result = OS_SUCCESS;
   OsLock lock(mMutex);

   assert(mpFlowgraphTicker != NULL);

   // Clear flowgraph ticker notification
   mpFlowgraphTicker = NULL;

   return result;
}

OsStatus MpAudioOutputConnection::pushFrameBeginning(unsigned int numSamples,
                                                     const MpAudioSample* samples,
                                                     MpFrameTime &frameTime)
{
   OsStatus result = OS_SUCCESS;
   RTL_BLOCK("MpAudioOutputConnection::pushFrame");

   assert(numSamples > 0);

   // From now we access internal data. Take lock.
   OsLock lock(mMutex);

   RTL_EVENT("MpAudioOutputConnection::pushFrame_frameTime", frameTime);
   RTL_EVENT("MpAudioOutputConnection::pushFrame_currentTime", mCurrentFrameTime);
   RTL_EVENT("MpAudioOutputConnection::pushFrame", this->getValue());

   // Do nothing if no audio was pushed. Mixer buffer will be filled with
   // silence or data from other sources.
   if (samples != NULL)
   {
      // Mix frame to the very beginning of the mixer buffer.
      result = mixFrame(mMixerBufferBegin, samples, numSamples);
   }

   frameTime = mCurrentFrameTime;

   return result;
};

OsStatus MpAudioOutputConnection::pushFrame(unsigned int numSamples,
                                            const MpAudioSample* samples,
                                            MpFrameTime frameTime)
{
   OsStatus result = OS_SUCCESS;
   RTL_EVENT("MpAudioOutputConnection::pushFrame", -1);

   assert(numSamples > 0);

   // From now we access internal data. Take lock.
   OsLock lock(mMutex);

   RTL_EVENT("MpAudioOutputConnection::pushFrame_frameTime", frameTime);
   RTL_EVENT("MpAudioOutputConnection::pushFrame_currentTime", mCurrentFrameTime);
   RTL_EVENT("MpAudioOutputConnection::pushFrame", this->getValue());

   // Check for late frame. Check for early frame is done inside mixFrame().
   if (MpDspUtils::compareSerials(frameTime, mCurrentFrameTime) < 0)
   {
      OsSysLog::add(FAC_MP, PRI_WARNING,
                    "MpAudioOutputConnection::pushFrame()"
                    " OS_INVALID_STATE frameTime=%d, currentTime=%d\n",
                    frameTime, mCurrentFrameTime);
      result = OS_INVALID_STATE;
      RTL_EVENT("MpAudioOutputConnection::pushFrame", result);
      return result;
   }

   if(mpDeviceDriver->isEnabled())
   {
       // Convert frameTime to offset in mixer buffer.
       // Note: frameTime >= mCurrentFrameTime.
       unsigned mixerBufferOffsetFrames =
                (frameTime-mCurrentFrameTime) / mpDeviceDriver->getFramePeriod();
       unsigned mixerBufferOffsetSamples =
                mixerBufferOffsetFrames * mpDeviceDriver->getSamplesPerFrame();

       // Don't touch mix buffer if no audio was pushed. Mixer buffer will be filled
       // with silence or data from other sources.
       if (samples != NULL)
       {
          // Mix this data with other sources.
          result = mixFrame(mixerBufferOffsetSamples, samples, numSamples);
          if(result != OS_SUCCESS)
          {
              OsSysLog::add(FAC_MP, PRI_WARNING,
                            "MpAudioOutputConnection::pushFrame mixFrame(%d, %p, %d) returned: %d"
                            " frameTime=%d, currentTime=%d\n",
                            (int)mixerBufferOffsetSamples, samples, numSamples, result,
                            frameTime, mCurrentFrameTime);
          }
       }
       else
       {
          // Just check for late frame.
          result = isLateToMix(mixerBufferOffsetSamples, numSamples);
       }
   }
   else
   {
       result = OS_INVALID_STATE;
   }

   RTL_EVENT("MpAudioOutputConnection::pushFrame", result);
   return result;
};

/* ============================ ACCESSORS ================================= */

MpFrameTime MpAudioOutputConnection::getCurrentFrameTime() const
{
   OsLock lock(mMutex);
   return mCurrentFrameTime;
}

/* ============================ INQUIRY =================================== */

/* //////////////////////////// PROTECTED ///////////////////////////////// */

OsStatus MpAudioOutputConnection::initMixerBuffer(unsigned mixerBufferLength)
{
   // We cannot allocate buffer of zero length.
   if (mixerBufferLength == 0)
   {
      return OS_FAILED;
   }

   // Deallocate mixer buffer if it is allocated.
   // Do not check return value. Nothing fatal may happen inside.
   freeMixerBuffer();

   // Initialize variables.
   mMixerBufferLength = mixerBufferLength;
   mpMixerBuffer = new MpAudioSample[mMixerBufferLength];
   mMixerBufferBegin = 0;

   // Clear buffer data.
   memset(mpMixerBuffer, 0, mMixerBufferLength*sizeof(MpAudioSample));

   return OS_SUCCESS;
}

OsStatus MpAudioOutputConnection::freeMixerBuffer()
{
   mMixerBufferLength = 0;
   if (mpMixerBuffer != NULL)
   {
      delete[] mpMixerBuffer;
      mpMixerBuffer = NULL;
   }
   mMixerBufferBegin = 0;

   return OS_SUCCESS;
}

OsStatus MpAudioOutputConnection::mixFrame(unsigned frameOffset,
                                           const MpAudioSample* samples,
                                           unsigned numSamples)
{
   assert(numSamples > 0);
   assert(samples != NULL);

   // Check for late frame.
   if (isLateToMix(frameOffset, numSamples) == OS_LIMIT_REACHED)
   {
      OsSysLog::add(FAC_MP, PRI_WARNING,
                  "MpAudioOutputConnection::mixFrame()"
                  " OS_LIMIT_REACHED offset=%d, samples=%d, bufferLength=%d\n",
                  frameOffset, numSamples, mMixerBufferLength);
      return OS_LIMIT_REACHED;
   }

   // Calculate frame start as if buffer is linear
   unsigned frameBegin = mMixerBufferBegin+frameOffset;
   // and wrap it because it is circular actually.
   if (frameBegin >= mMixerBufferLength)
   {
      frameBegin -= mMixerBufferLength;
   }

   // Calculate size of first chunk to mix.
   unsigned firstChunkSize = sipx_min(numSamples, mMixerBufferLength-frameBegin);

   // Counter variables for next two loops
   unsigned srcIndex, dstIndex;

   // from frame begin to buffer wrap
   for (srcIndex=0, dstIndex=frameBegin;
        srcIndex<firstChunkSize;
        srcIndex++, dstIndex++)
   {
      mpMixerBuffer[dstIndex] += samples[srcIndex];
   }

   // from buffer wrap to frame end
   for (dstIndex=0;
        srcIndex<numSamples;
        srcIndex++, dstIndex++)
   {
      mpMixerBuffer[dstIndex] += samples[srcIndex];
   }

   return OS_SUCCESS;
}

OsStatus MpAudioOutputConnection::advanceMixerBuffer(unsigned numSamples)
{
   // If buffer could be copied in one pass
   if(numSamples <= 0)
   {
      OsSysLog::add(FAC_MP, PRI_ERR, "MpAudioOutputConnection::advanceMixerBuffer invoked with: %d samples\n", numSamples);
      assert(numSamples > 0);
   }
   else if(numSamples > mMixerBufferLength)
   {
      OsSysLog::add(FAC_MP, PRI_ERR, "MpAudioOutputConnection::advanceMixerBuffer invoked with numSamples: %d > mMixerBufferLength: %d\n",
             numSamples, mMixerBufferLength);
      assert(numSamples <= mMixerBufferLength);
   }
   else if (mMixerBufferBegin+numSamples <= mMixerBufferLength)
   {
      memset(&mpMixerBuffer[mMixerBufferBegin],
             0,
             numSamples*sizeof(MpAudioSample));
      mMixerBufferBegin += numSamples;
      mMixerBufferBegin %= mMixerBufferLength;
   }
   else
   {
      unsigned firstChunkSize = mMixerBufferLength-mMixerBufferBegin;
      memset(&mpMixerBuffer[mMixerBufferBegin],
             0,
             firstChunkSize*sizeof(MpAudioSample));
      memset(&mpMixerBuffer[0],
             0,
             (numSamples-firstChunkSize)*sizeof(MpAudioSample));

      mMixerBufferBegin = numSamples - firstChunkSize;
   }

   return OS_SUCCESS;
}

void MpAudioOutputConnection::readyForDataCallback(const intptr_t userData,
                                                   const intptr_t eventData)
{
   OsStatus result;
   MpAudioOutputConnection *pConnection = (MpAudioOutputConnection*)userData;
   RTL_BLOCK("MpAudioOutputConnection::tickerCallBack");

#ifdef LOG_HEART_BEAT_PERIOD
   if(pConnection->mCurrentFrameTime % LOG_HEART_BEAT_PERIOD == 0)
   {
       OsSysLog::add(FAC_MP, PRI_DEBUG,
                     "MpAudioOutputConnection::readyForDataCallback aquiring mutex frame time: %d",
                     pConnection->mCurrentFrameTime);

   }
#endif

   if (pConnection->mMutex.acquire(OsTime(5)) == OS_SUCCESS)
   {
      // Push data to device driver and forget.
      result = pConnection->mpDeviceDriver->pushFrame(
                     pConnection->mpDeviceDriver->getSamplesPerFrame(),
                     pConnection->mpMixerBuffer+pConnection->mMixerBufferBegin,
                     pConnection->mCurrentFrameTime);
#ifdef LOG_HEART_BEAT_PERIOD
      if(pConnection->mCurrentFrameTime % LOG_HEART_BEAT_PERIOD == 0)
      {
         OsSysLog::add(FAC_MP, PRI_DEBUG,
                      "MpAudioOutputConnection::readyForDataCallback()"
                      " frame=%d, pushFrame result=%d\n",
                      pConnection->mCurrentFrameTime, result);
      }
#else
      SIPX_UNUSED(result);
#endif
//      assert(result == OS_SUCCESS);

      // Advance mixer buffer and frame time.
      pConnection->advanceMixerBuffer(pConnection->mpDeviceDriver->getSamplesPerFrame());
      pConnection->mCurrentFrameTime +=
                           pConnection->mpDeviceDriver->getSamplesPerFrame() * 1000
                           / pConnection->mpDeviceDriver->getSamplesPerSec();
      RTL_EVENT("MpAudioOutputConnection::tickerCallBack_currentFrameTime",
                pConnection->mCurrentFrameTime);

      pConnection->mMutex.release();
   }

   // Signal frame processing interval start if requested.
   if (pConnection->mpFlowgraphTicker)
   {
      pConnection->mpFlowgraphTicker->signal(0);
   }
}

/* //////////////////////////// PRIVATE /////////////////////////////////// */

/* ============================ FUNCTIONS ================================= */

<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: SlideSorterViewShell.hxx,v $
 *
 *  $Revision: 1.10 $
 *
 *  last change: $Author: kz $ $Date: 2006-12-12 17:37:39 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

#ifndef SD_SLIDESORTER_SLIDE_SORTER_VIEW_SHELL_HXX
#define SD_SLIDESORTER_SLIDE_SORTER_VIEW_SHELL_HXX

#include "ViewShell.hxx"
#include "SlideSorterViewShell.hxx"
#include "glob.hxx"
#ifndef _SFX_SHELL_HXX
#include <sfx2/shell.hxx>
#endif
#ifndef _VIEWFAC_HXX
#include <sfx2/viewfac.hxx>
#endif

class ScrollBarBox;
class TabBar;
class Window;

namespace sd { namespace slidesorter { namespace model {
class SlideSorterModel;
} } }

namespace sd { namespace slidesorter { namespace view {
class SlideSorterView;
} } }

namespace sd { namespace slidesorter { namespace controller {
class Listener;
class SlideSorterController;
class SlotManager;
} } }

namespace sd { namespace slidesorter {

class SlideSorterViewShell
    : public ViewShell
{
    friend class controller::SlotManager;
public:
    TYPEINFO();
    SFX_DECL_INTERFACE(SD_IF_SDSLIDESORTERVIEWSHELL)

    enum TabBarEntry
    {
        TBE_SWITCH = 0,
        TBE_SLIDES = 1,
        TBE_MASTER_PAGES = 2
    };

    static SfxShell* CreateInstance (
        sal_Int32 nId,
        SfxShell* pParent,
        void* pUserData,
        ViewShellBase& rBase);

    SlideSorterViewShell (
        SfxViewFrame* pFrame,
        ViewShellBase& rViewShellBase,
        ::Window* pParentWindow,
        FrameView* pFrameView);

    virtual ~SlideSorterViewShell (void);

    /** Late initialization that has to be called after a new instance has
        completed its construction.
    */
    virtual void Init (bool bIsMainViewShell);

    /** Return a slide sorter that is currently displayed in one of the
        panes that belong to the given ViewShellBase object.
        When there is only one slide sorter visible then that one is
        returned.  When two (or more) are visible then the one in the center
        pane is returned.  When no slidesorter is visible then NULL is
        returned.
    */
    static SlideSorterViewShell* GetSlideSorter (ViewShellBase& rBase);

    virtual void GetFocus (void);
    virtual void LoseFocus (void);
    virtual SdPage* GetActualPage (void);

    /// inherited from sd::ViewShell
    virtual SdPage* getCurrentPage() const;

    void ExecCtrl (SfxRequest& rRequest);
    virtual void GetCtrlState (SfxItemSet &rSet);
    virtual void FuSupport (SfxRequest& rRequest);
    virtual void FuTemporary (SfxRequest& rRequest);
    virtual void GetStatusBarState (SfxItemSet& rSet);
    virtual void FuPermanent (SfxRequest& rRequest);
    void GetAttrState (SfxItemSet& rSet);
    void ExecStatusBar (SfxRequest& rRequest);
    virtual void Command (const CommandEvent& rEvent, ::sd::Window* pWindow);
    virtual void GetMenuState (SfxItemSet &rSet);

    virtual void ReadFrameViewData (FrameView* pView);
    virtual void WriteFrameViewData (void);

    /** Set the zoom factor.  The given value is clipped against an upper
        bound.
        @param nZoom
            An integer percent value, i.e. nZoom/100 is the actual zoom
            factor.
        */
    virtual void SetZoom (long int nZoom);
    virtual void SetZoomRect (const Rectangle& rZoomRect);

    /** This is a callback method used by the active window to delegate its
        Paint() call to.  This view shell itself delegates it to the view.
    */
    virtual void Paint(const Rectangle& rRect, ::sd::Window* pWin);

    /** Place and size the controls and windows.  You may want to call this
        method when something has changed that for instance affects the
        visibility state of the scroll bars.
    */
    virtual void ArrangeGUIElements (void);

    /** Return the control of the vertical scroll bar.
    */
    ScrollBar* GetVerticalScrollBar (void) const;

    /** Return the control of the horizontal scroll bar.
    */
    ScrollBar* GetHorizontalScrollBar (void) const;

    /** Return the scroll bar filler that paints the little square that is
        enclosed by the two scroll bars.
    */
    ScrollBarBox* GetScrollBarFiller (void) const;

    /** Set the tab bar to the given mode.
        @param eEntry
            When TBE_SWITCH is given, then switch between the two tabs.
    */
    TabBarEntry SwitchTabBar (TabBarEntry eEntry);

    controller::SlideSorterController& GetSlideSorterController (void);

    //===== Drag and Drop =====================================================

    virtual void StartDrag (
        const Point& rDragPt,
        ::Window* pWindow );
    virtual void DragFinished (
        sal_Int8 nDropAction);
    virtual sal_Int8 AcceptDrop (
        const AcceptDropEvent& rEvt,
        DropTargetHelper& rTargetHelper,
        ::sd::Window* pTargetWindow = NULL,
        USHORT nPage = SDRPAGE_NOTFOUND,
        USHORT nLayer = SDRPAGE_NOTFOUND );
    virtual sal_Int8 ExecuteDrop (
        const ExecuteDropEvent& rEvt,
        DropTargetHelper& rTargetHelper,
        ::sd::Window* pTargetWindow = NULL,
        USHORT nPage = SDRPAGE_NOTFOUND,
        USHORT nLayer = SDRPAGE_NOTFOUND);

    /** Return the selected pages by putting them into the given container.
        The container does not have to be empty.  It is not cleared.
    */
    void GetSelectedPages (::std::vector<SdPage*>& pPageContainer);

    /** Add a listener that is called when the selection of the slide sorter
        changes.
        @param rListener
            When this method is called multiple times for the same listener
            the second and all following calls are ignored.  Each listener
            is added only once.
    */
    void AddSelectionChangeListener (const Link& rListener);

    /** Remove a listener that was called when the selection of the slide
        sorter changes.
        @param rListener
            It is save to pass a listener that was not added are has been
            removed previously.  Such calls are ignored.
    */
    void RemoveSelectionChangeListener (const Link& rListener);

    virtual ::std::auto_ptr<DrawSubController> CreateSubController (void);

    /** Create an accessible object representing the specified window.
        @param pWindow
            The returned object makes the document displayed in this window
            accessible.
        @return
            Returns an <type>AccessibleSlideSorterView</type> object.
   */
    virtual ::com::sun::star::uno::Reference<
        ::com::sun::star::accessibility::XAccessible>
        CreateAccessibleDocumentView (::sd::Window* pWindow);

protected:
    ::std::auto_ptr<controller::SlideSorterController> mpSlideSorterController;
    ::std::auto_ptr<model::SlideSorterModel> mpSlideSorterModel;
    ::std::auto_ptr<view::SlideSorterView> mpSlideSorterView;

    virtual SvBorder GetBorder (bool bOuterResize);

    /** This virtual method makes it possible to create a specialization of
        the slide sorter view shell that works with its own implementation
        of model, view, and controller.  The default implementation simply
        calls the CreateModel(), CreateView(), and CreateController()
        methods in this order.
    */
    virtual void CreateModelViewController (void);

    /** Create the model for the view shell.  When called from the default
        implementation of CreateModelViewController() then neither view nor
        controller do exist.  Test their pointers when in doubt.
    */
    virtual model::SlideSorterModel* CreateModel (void);

    /** Create the view for the view shell.  When called from the default
        implementation of CreateModelViewController() then the model but not
        the controller does exist.  Test their pointers when in doubt.
    */
    virtual view::SlideSorterView* CreateView (void);

    /** Create the controller for the view shell.  When called from the default
        implementation of CreateModelViewController() then both the view and
        the controller do exist.  Test their pointers when in doubt.
    */
    virtual controller::SlideSorterController* CreateController (void);

    /** This method is overloaded to handle a missing tool bar correctly.
        This is the case when the slide sorter is not the main view shell.
    */
    virtual SfxUndoManager* ImpGetUndoManager (void) const;

private:
    ::std::auto_ptr<TabBar> mpTabBar;

    /** Set this flag to <TRUE/> to force a layout before the next paint.
    */
    bool mbLayoutPending;

    /** Create the controls for the slide sorter.  This are the tab bar
       for switching the edit mode, the scroll bar, and the actual
       slide sorter view window.
       This method is usually called exactly one time from the
       constructor.
    */
    void SetupControls (::Window* pParentWindow);

    /** This method is usually called exactly one time from the
        constructor.
    */
    void SetupListeners (void);

    /** Release the listeners that have been installed in SetupListeners().
    */
    void ReleaseListeners (void);

    /** This method overwrites the one from our base class:  We do our own
        scroll bar and the base class call is thus unnecessary.  It simply
        calls UpdateScrollBars(false).
    */
    virtual void UpdateScrollBars (void);
};

} } // end of namespace ::sd::slidesorter

#endif
<commit_msg>INTEGRATION: CWS components1 (1.10.38); FILE MERGED 2007/01/29 17:25:34 af 1.10.38.1: #i68075# New RelocateToParentWindow() method.<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: SlideSorterViewShell.hxx,v $
 *
 *  $Revision: 1.11 $
 *
 *  last change: $Author: rt $ $Date: 2007-04-03 16:06:39 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

#ifndef SD_SLIDESORTER_SLIDE_SORTER_VIEW_SHELL_HXX
#define SD_SLIDESORTER_SLIDE_SORTER_VIEW_SHELL_HXX

#include "ViewShell.hxx"
#include "SlideSorterViewShell.hxx"
#include "glob.hxx"
#ifndef _SFX_SHELL_HXX
#include <sfx2/shell.hxx>
#endif
#ifndef _VIEWFAC_HXX
#include <sfx2/viewfac.hxx>
#endif

class ScrollBarBox;
class TabBar;
class Window;

namespace sd { namespace slidesorter { namespace model {
class SlideSorterModel;
} } }

namespace sd { namespace slidesorter { namespace view {
class SlideSorterView;
} } }

namespace sd { namespace slidesorter { namespace controller {
class Listener;
class SlideSorterController;
class SlotManager;
} } }

namespace sd { namespace slidesorter {

class SlideSorterViewShell
    : public ViewShell
{
    friend class controller::SlotManager;
public:
    TYPEINFO();
    SFX_DECL_INTERFACE(SD_IF_SDSLIDESORTERVIEWSHELL)

    enum TabBarEntry
    {
        TBE_SWITCH = 0,
        TBE_SLIDES = 1,
        TBE_MASTER_PAGES = 2
    };

    static SfxShell* CreateInstance (
        sal_Int32 nId,
        SfxShell* pParent,
        void* pUserData,
        ViewShellBase& rBase);

    SlideSorterViewShell (
        SfxViewFrame* pFrame,
        ViewShellBase& rViewShellBase,
        ::Window* pParentWindow,
        FrameView* pFrameView);

    virtual ~SlideSorterViewShell (void);

    /** Late initialization that has to be called after a new instance has
        completed its construction.
    */
    virtual void Init (bool bIsMainViewShell);

    /** Return a slide sorter that is currently displayed in one of the
        panes that belong to the given ViewShellBase object.
        When there is only one slide sorter visible then that one is
        returned.  When two (or more) are visible then the one in the center
        pane is returned.  When no slidesorter is visible then NULL is
        returned.
    */
    static SlideSorterViewShell* GetSlideSorter (ViewShellBase& rBase);

    virtual void GetFocus (void);
    virtual void LoseFocus (void);
    virtual SdPage* GetActualPage (void);

    /// inherited from sd::ViewShell
    virtual SdPage* getCurrentPage() const;

    void ExecCtrl (SfxRequest& rRequest);
    virtual void GetCtrlState (SfxItemSet &rSet);
    virtual void FuSupport (SfxRequest& rRequest);
    virtual void FuTemporary (SfxRequest& rRequest);
    virtual void GetStatusBarState (SfxItemSet& rSet);
    virtual void FuPermanent (SfxRequest& rRequest);
    void GetAttrState (SfxItemSet& rSet);
    void ExecStatusBar (SfxRequest& rRequest);
    virtual void Command (const CommandEvent& rEvent, ::sd::Window* pWindow);
    virtual void GetMenuState (SfxItemSet &rSet);

    virtual void ReadFrameViewData (FrameView* pView);
    virtual void WriteFrameViewData (void);

    /** Set the zoom factor.  The given value is clipped against an upper
        bound.
        @param nZoom
            An integer percent value, i.e. nZoom/100 is the actual zoom
            factor.
        */
    virtual void SetZoom (long int nZoom);
    virtual void SetZoomRect (const Rectangle& rZoomRect);

    /** This is a callback method used by the active window to delegate its
        Paint() call to.  This view shell itself delegates it to the view.
    */
    virtual void Paint(const Rectangle& rRect, ::sd::Window* pWin);

    /** Place and size the controls and windows.  You may want to call this
        method when something has changed that for instance affects the
        visibility state of the scroll bars.
    */
    virtual void ArrangeGUIElements (void);

    /** Return the control of the vertical scroll bar.
    */
    ScrollBar* GetVerticalScrollBar (void) const;

    /** Return the control of the horizontal scroll bar.
    */
    ScrollBar* GetHorizontalScrollBar (void) const;

    /** Return the scroll bar filler that paints the little square that is
        enclosed by the two scroll bars.
    */
    ScrollBarBox* GetScrollBarFiller (void) const;

    /** Set the tab bar to the given mode.
        @param eEntry
            When TBE_SWITCH is given, then switch between the two tabs.
    */
    TabBarEntry SwitchTabBar (TabBarEntry eEntry);

    controller::SlideSorterController& GetSlideSorterController (void);

    //===== Drag and Drop =====================================================

    virtual void StartDrag (
        const Point& rDragPt,
        ::Window* pWindow );
    virtual void DragFinished (
        sal_Int8 nDropAction);
    virtual sal_Int8 AcceptDrop (
        const AcceptDropEvent& rEvt,
        DropTargetHelper& rTargetHelper,
        ::sd::Window* pTargetWindow = NULL,
        USHORT nPage = SDRPAGE_NOTFOUND,
        USHORT nLayer = SDRPAGE_NOTFOUND );
    virtual sal_Int8 ExecuteDrop (
        const ExecuteDropEvent& rEvt,
        DropTargetHelper& rTargetHelper,
        ::sd::Window* pTargetWindow = NULL,
        USHORT nPage = SDRPAGE_NOTFOUND,
        USHORT nLayer = SDRPAGE_NOTFOUND);

    /** Return the selected pages by putting them into the given container.
        The container does not have to be empty.  It is not cleared.
    */
    void GetSelectedPages (::std::vector<SdPage*>& pPageContainer);

    /** Add a listener that is called when the selection of the slide sorter
        changes.
        @param rListener
            When this method is called multiple times for the same listener
            the second and all following calls are ignored.  Each listener
            is added only once.
    */
    void AddSelectionChangeListener (const Link& rListener);

    /** Remove a listener that was called when the selection of the slide
        sorter changes.
        @param rListener
            It is save to pass a listener that was not added are has been
            removed previously.  Such calls are ignored.
    */
    void RemoveSelectionChangeListener (const Link& rListener);

    virtual ::std::auto_ptr<DrawSubController> CreateSubController (void);

    /** Create an accessible object representing the specified window.
        @param pWindow
            The returned object makes the document displayed in this window
            accessible.
        @return
            Returns an <type>AccessibleSlideSorterView</type> object.
   */
    virtual ::com::sun::star::uno::Reference<
        ::com::sun::star::accessibility::XAccessible>
        CreateAccessibleDocumentView (::sd::Window* pWindow);

    /** Try to relocate all toplevel window elements to the given parent
        window.
    */
    virtual bool RelocateToParentWindow (::Window* pParentWindow);

protected:
    ::std::auto_ptr<controller::SlideSorterController> mpSlideSorterController;
    ::std::auto_ptr<model::SlideSorterModel> mpSlideSorterModel;
    ::std::auto_ptr<view::SlideSorterView> mpSlideSorterView;

    virtual SvBorder GetBorder (bool bOuterResize);

    /** This virtual method makes it possible to create a specialization of
        the slide sorter view shell that works with its own implementation
        of model, view, and controller.  The default implementation simply
        calls the CreateModel(), CreateView(), and CreateController()
        methods in this order.
    */
    virtual void CreateModelViewController (void);

    /** Create the model for the view shell.  When called from the default
        implementation of CreateModelViewController() then neither view nor
        controller do exist.  Test their pointers when in doubt.
    */
    virtual model::SlideSorterModel* CreateModel (void);

    /** Create the view for the view shell.  When called from the default
        implementation of CreateModelViewController() then the model but not
        the controller does exist.  Test their pointers when in doubt.
    */
    virtual view::SlideSorterView* CreateView (void);

    /** Create the controller for the view shell.  When called from the default
        implementation of CreateModelViewController() then both the view and
        the controller do exist.  Test their pointers when in doubt.
    */
    virtual controller::SlideSorterController* CreateController (void);

    /** This method is overloaded to handle a missing tool bar correctly.
        This is the case when the slide sorter is not the main view shell.
    */
    virtual SfxUndoManager* ImpGetUndoManager (void) const;

private:
    ::std::auto_ptr<TabBar> mpTabBar;

    /** Set this flag to <TRUE/> to force a layout before the next paint.
    */
    bool mbLayoutPending;

    /** Create the controls for the slide sorter.  This are the tab bar
       for switching the edit mode, the scroll bar, and the actual
       slide sorter view window.
       This method is usually called exactly one time from the
       constructor.
    */
    void SetupControls (::Window* pParentWindow);

    /** This method is usually called exactly one time from the
        constructor.
    */
    void SetupListeners (void);

    /** Release the listeners that have been installed in SetupListeners().
    */
    void ReleaseListeners (void);

    /** This method overwrites the one from our base class:  We do our own
        scroll bar and the base class call is thus unnecessary.  It simply
        calls UpdateScrollBars(false).
    */
    virtual void UpdateScrollBars (void);
};

} } // end of namespace ::sd::slidesorter

#endif
<|endoftext|>


<commit_before>/*
   For more information, please see: http://software.sci.utah.edu

   The MIT License

   Copyright (c) 2008 Scientific Computing and Imaging Institute,
   University of Utah.

   Permission is hereby granted, free of charge, to any person obtaining a
   copy of this software and associated documentation files (the "Software"),
   to deal in the Software without restriction, including without limitation
   the rights to use, copy, modify, merge, publish, distribute, sublicense,
   and/or sell copies of the Software, and to permit persons to whom the
   Software is furnished to do so, subject to the following conditions:

   The above copyright notice and this permission notice shall be included
   in all copies or substantial portions of the Software.

   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
   FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
   THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
   LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
   DEALINGS IN THE SOFTWARE.
*/

/**
  \file    SystemInfo.cpp
  \author  Jens Krueger
           SCI Institute
           University of Utah
  \date    July 2008
*/

#include "SystemInfo.h"

#include "StdDefines.h"
#ifdef _WIN32
  #include <windows.h>
#else
  #ifdef TUVOK_OS_APPLE
    #include <sys/sysctl.h>
  #else
    #include <cstdio>
    #include <iostream>
    #include <sstream>
    #include <sys/resource.h>
    #include <sys/sysinfo.h>
    #include <sys/time.h>
    #include "IO/KeyValueFileParser.h"
  #endif
#endif

SystemInfo::SystemInfo(UINT64 iDefaultCPUMemSize, UINT64 iDefaultGPUMemSize) :
  m_iProgrammBitWith(sizeof(void*)*8),
  m_iUseMaxCPUMem(iDefaultCPUMemSize),
  m_iUseMaxGPUMem(iDefaultGPUMemSize),
  m_iCPUMemSize(iDefaultCPUMemSize),
  m_iGPUMemSize(iDefaultGPUMemSize),
  m_bIsCPUSizeComputed(false),
  m_bIsGPUSizeComputed(false),
  m_bIsNumberOfCPUsComputed(false),
  m_bIsDirectX10Capable(false)
{
  UINT32 iNumberOfCPUs = ComputeNumCPUs();
  if (iNumberOfCPUs > 0) {
    m_iNumberOfCPUs = iNumberOfCPUs;
    m_bIsNumberOfCPUsComputed = true;
  }

  UINT64 iCPUMemSize = ComputeCPUMemSize();
  if (iCPUMemSize > 0) {
    m_iCPUMemSize = iCPUMemSize;
    m_bIsCPUSizeComputed = true;
  }

  UINT64 iGPUMemSize = ComputeGPUMemory();  // also sets m_bIsDirectX10Capable
  if (iGPUMemSize > 0) {
    m_iGPUMemSize = iGPUMemSize;
    m_bIsGPUSizeComputed = true;
  }
}

UINT32 SystemInfo::ComputeNumCPUs() {
  #ifdef _WIN32
    SYSTEM_INFO siSysInfo;
    GetSystemInfo(&siSysInfo);
    return siSysInfo.dwNumberOfProcessors;
  #else
    #ifdef TUVOK_OS_APPLE
      return 0;
    #else
      return 0;
    #endif
  #endif
}

#ifdef __linux__

#ifndef NDEBUG
#   define DBG(str) do { std::cerr << str << std::endl; } while(0)
#else
#   define DBG(str) /* nothing */
#endif
static unsigned long lnx_mem_sysinfo() {
  struct sysinfo si;
  if(sysinfo(&si) < 0) {
    perror("sysinfo");
    return 0;
  }
  return si.totalram;
}

static UINT64 lnx_mem_rlimit() {
    struct rlimit limit;
    // RLIMIT_MEMLOCK returns 32768 (that's *bytes*) on my 6gb-RAM system, so
    // that number is worthless to us.
    // RLIMIT_DATA isn't great, because it gets the entire data segment size
    // allowable, not just the heap size ...
    if(getrlimit(RLIMIT_DATA, &limit) != 0) {
        perror("getrlimit");
        return 0;
    }
    // Frequently the information given by getrlimit(2) is essentially
    // worthless, because it assumes we don't care about swapping.
    if(limit.rlim_cur == RLIM_INFINITY || limit.rlim_max == RLIM_INFINITY) {
        DBG("getrlimit gave useless info...");
        return 0;
    }
    return limit.rlim_max;
}

static UINT64 lnx_mem_proc() {
  KeyValueFileParser meminfo("/proc/meminfo");

  if(!meminfo.FileReadable()) {
    DBG("could not open proc memory filesystem");
    return 0;
  }

  KeyValPair *mem_total = meminfo.GetData("MemTotal");
  if(mem_total == NULL) {
    DBG("proc mem fs did not have a `MemTotal' entry.");
    return 0;
  }
  std::istringstream mem_strm(mem_total->strValue);
  UINT64 mem;
  mem_strm >> mem;
  return mem * 1024;
}

static UINT64 lnx_mem() {
  UINT64 m;
  if((m = lnx_mem_proc()) == 0) {
    DBG("proc failed, falling back to rlimit");
    if((m = lnx_mem_rlimit()) == 0) {
      DBG("rlimit failed, falling back to sysinfo");
      if((m = lnx_mem_sysinfo()) == 0) {
        DBG("all memory lookups failed; pretending you have 1Gb of memory.");
        return 1024*1024*1024;
      }
    }
  }
  return m;
}
#endif

UINT64 SystemInfo::ComputeCPUMemSize() {
  #ifdef _WIN32
    MEMORYSTATUSEX statex;
    statex.dwLength = sizeof (statex);
    GlobalMemoryStatusEx (&statex);
    return statex.ullTotalPhys;
  #else
    #ifdef TUVOK_OS_APPLE
      UINT64 phys = 0;
      int mib[2] = { CTL_HW, HW_PHYSMEM };
      size_t len = sizeof(phys);
      if (sysctl(mib, 2, &phys, &len, NULL, 0) != 0) return 0;
      return phys;
    #elif defined(__linux__)
      return static_cast<UINT64>(lnx_mem());
    #else
      std::cerr << "Unknown system, can't lookup max memory.  "
                << "Using a hard setting of 10 gb." << std::endl;
      return 1024*1024*1024*10;
    #endif
  #endif
}

#if defined(_WIN32) && defined(USE_DIRECTX)
  #define INITGUID
  #include <string.h>
  #include <stdio.h>
  #include <assert.h>
  #include <d3d9.h>
  #include <multimon.h>

  #pragma comment( lib, "d3d9.lib" )

  HRESULT GetVideoMemoryViaDirectDraw( HMONITOR hMonitor, DWORD* pdwAvailableVidMem );
  HRESULT GetVideoMemoryViaDXGI( HMONITOR hMonitor, SIZE_T* pDedicatedVideoMemory, SIZE_T* pDedicatedSystemMemory, SIZE_T* pSharedSystemMemory );

  #ifndef SAFE_RELEASE
    #define SAFE_RELEASE(p)      { if (p) { (p)->Release(); (p)=NULL; } }
  #endif

  typedef IDirect3D9* ( WINAPI* LPDIRECT3DCREATE9 )( UINT  );
  LPDIRECT3DCREATE9 pDirect3DCreate9;

  UINT64 SystemInfo::ComputeGPUMemory( )
  {
    HINSTANCE hD3D9 = LoadLibrary( L"d3d9.dll" );
    if (!hD3D9) return 0;
    pDirect3DCreate9 = ( LPDIRECT3DCREATE9 )GetProcAddress( hD3D9, "Direct3DCreate9" );

    if (!pDirect3DCreate9) {
      FreeLibrary( hD3D9 );
      return 0;
    }

    IDirect3D9* pD3D9 = NULL;
    pD3D9 = pDirect3DCreate9( D3D_SDK_VERSION );
    if( pD3D9 )
    {
        UINT dwAdapterCount = pD3D9->GetAdapterCount();
        if (dwAdapterCount > 0) {
            UINT iAdapter = 0;

            HMONITOR hMonitor = pD3D9->GetAdapterMonitor( iAdapter );

            SIZE_T DedicatedVideoMemory;
            SIZE_T DedicatedSystemMemory;
            SIZE_T SharedSystemMemory;
            if( SUCCEEDED( GetVideoMemoryViaDXGI( hMonitor, &DedicatedVideoMemory, &DedicatedSystemMemory, &SharedSystemMemory ) ) )
            {
              m_bIsDirectX10Capable = true;
              SAFE_RELEASE( pD3D9 );
              return UINT64(DedicatedVideoMemory);
            } else {
              DWORD dwAvailableVidMem;
              if( SUCCEEDED( GetVideoMemoryViaDirectDraw( hMonitor, &dwAvailableVidMem ) ) ) {
                SAFE_RELEASE( pD3D9 );
                FreeLibrary( hD3D9 );
                return UINT64(DedicatedVideoMemory);
              } else {
                SAFE_RELEASE( pD3D9 );
                FreeLibrary( hD3D9 );
                return 0;
              }
            }
        }

        SAFE_RELEASE( pD3D9 );
        FreeLibrary( hD3D9 );
        return 0;
    }
    else
    {
        FreeLibrary( hD3D9 );
        return 0;
    }
  }

#else
  UINT64 SystemInfo::ComputeGPUMemory( )
  {
    #ifdef TUVOK_OS_APPLE
      return 0;
    #else // Linux
      return 0;
    #endif
  }
#endif
<commit_msg>Fix the include, and thus the build.<commit_after>/*
   For more information, please see: http://software.sci.utah.edu

   The MIT License

   Copyright (c) 2008 Scientific Computing and Imaging Institute,
   University of Utah.

   Permission is hereby granted, free of charge, to any person obtaining a
   copy of this software and associated documentation files (the "Software"),
   to deal in the Software without restriction, including without limitation
   the rights to use, copy, modify, merge, publish, distribute, sublicense,
   and/or sell copies of the Software, and to permit persons to whom the
   Software is furnished to do so, subject to the following conditions:

   The above copyright notice and this permission notice shall be included
   in all copies or substantial portions of the Software.

   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
   FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
   THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
   LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
   DEALINGS IN THE SOFTWARE.
*/

/**
  \file    SystemInfo.cpp
  \author  Jens Krueger
           SCI Institute
           University of Utah
  \date    July 2008
*/

#include "SystemInfo.h"

#include "StdTuvokDefines.h"
#ifdef _WIN32
  #include <windows.h>
#else
  #ifdef TUVOK_OS_APPLE
    #include <sys/sysctl.h>
  #else
    #include <cstdio>
    #include <iostream>
    #include <sstream>
    #include <sys/resource.h>
    #include <sys/sysinfo.h>
    #include <sys/time.h>
    #include "IO/KeyValueFileParser.h"
  #endif
#endif

SystemInfo::SystemInfo(UINT64 iDefaultCPUMemSize, UINT64 iDefaultGPUMemSize) :
  m_iProgrammBitWith(sizeof(void*)*8),
  m_iUseMaxCPUMem(iDefaultCPUMemSize),
  m_iUseMaxGPUMem(iDefaultGPUMemSize),
  m_iCPUMemSize(iDefaultCPUMemSize),
  m_iGPUMemSize(iDefaultGPUMemSize),
  m_bIsCPUSizeComputed(false),
  m_bIsGPUSizeComputed(false),
  m_bIsNumberOfCPUsComputed(false),
  m_bIsDirectX10Capable(false)
{
  UINT32 iNumberOfCPUs = ComputeNumCPUs();
  if (iNumberOfCPUs > 0) {
    m_iNumberOfCPUs = iNumberOfCPUs;
    m_bIsNumberOfCPUsComputed = true;
  }

  UINT64 iCPUMemSize = ComputeCPUMemSize();
  if (iCPUMemSize > 0) {
    m_iCPUMemSize = iCPUMemSize;
    m_bIsCPUSizeComputed = true;
  }

  UINT64 iGPUMemSize = ComputeGPUMemory();  // also sets m_bIsDirectX10Capable
  if (iGPUMemSize > 0) {
    m_iGPUMemSize = iGPUMemSize;
    m_bIsGPUSizeComputed = true;
  }
}

UINT32 SystemInfo::ComputeNumCPUs() {
  #ifdef _WIN32
    SYSTEM_INFO siSysInfo;
    GetSystemInfo(&siSysInfo);
    return siSysInfo.dwNumberOfProcessors;
  #else
    #ifdef TUVOK_OS_APPLE
      return 0;
    #else
      return 0;
    #endif
  #endif
}

#ifdef __linux__

#ifndef NDEBUG
#   define DBG(str) do { std::cerr << str << std::endl; } while(0)
#else
#   define DBG(str) /* nothing */
#endif
static unsigned long lnx_mem_sysinfo() {
  struct sysinfo si;
  if(sysinfo(&si) < 0) {
    perror("sysinfo");
    return 0;
  }
  return si.totalram;
}

static UINT64 lnx_mem_rlimit() {
    struct rlimit limit;
    // RLIMIT_MEMLOCK returns 32768 (that's *bytes*) on my 6gb-RAM system, so
    // that number is worthless to us.
    // RLIMIT_DATA isn't great, because it gets the entire data segment size
    // allowable, not just the heap size ...
    if(getrlimit(RLIMIT_DATA, &limit) != 0) {
        perror("getrlimit");
        return 0;
    }
    // Frequently the information given by getrlimit(2) is essentially
    // worthless, because it assumes we don't care about swapping.
    if(limit.rlim_cur == RLIM_INFINITY || limit.rlim_max == RLIM_INFINITY) {
        DBG("getrlimit gave useless info...");
        return 0;
    }
    return limit.rlim_max;
}

static UINT64 lnx_mem_proc() {
  KeyValueFileParser meminfo("/proc/meminfo");

  if(!meminfo.FileReadable()) {
    DBG("could not open proc memory filesystem");
    return 0;
  }

  KeyValPair *mem_total = meminfo.GetData("MemTotal");
  if(mem_total == NULL) {
    DBG("proc mem fs did not have a `MemTotal' entry.");
    return 0;
  }
  std::istringstream mem_strm(mem_total->strValue);
  UINT64 mem;
  mem_strm >> mem;
  return mem * 1024;
}

static UINT64 lnx_mem() {
  UINT64 m;
  if((m = lnx_mem_proc()) == 0) {
    DBG("proc failed, falling back to rlimit");
    if((m = lnx_mem_rlimit()) == 0) {
      DBG("rlimit failed, falling back to sysinfo");
      if((m = lnx_mem_sysinfo()) == 0) {
        DBG("all memory lookups failed; pretending you have 1Gb of memory.");
        return 1024*1024*1024;
      }
    }
  }
  return m;
}
#endif

UINT64 SystemInfo::ComputeCPUMemSize() {
  #ifdef _WIN32
    MEMORYSTATUSEX statex;
    statex.dwLength = sizeof (statex);
    GlobalMemoryStatusEx (&statex);
    return statex.ullTotalPhys;
  #else
    #ifdef TUVOK_OS_APPLE
      UINT64 phys = 0;
      int mib[2] = { CTL_HW, HW_PHYSMEM };
      size_t len = sizeof(phys);
      if (sysctl(mib, 2, &phys, &len, NULL, 0) != 0) return 0;
      return phys;
    #elif defined(__linux__)
      return static_cast<UINT64>(lnx_mem());
    #else
      std::cerr << "Unknown system, can't lookup max memory.  "
                << "Using a hard setting of 10 gb." << std::endl;
      return 1024*1024*1024*10;
    #endif
  #endif
}

#if defined(_WIN32) && defined(USE_DIRECTX)
  #define INITGUID
  #include <string.h>
  #include <stdio.h>
  #include <assert.h>
  #include <d3d9.h>
  #include <multimon.h>

  #pragma comment( lib, "d3d9.lib" )

  HRESULT GetVideoMemoryViaDirectDraw( HMONITOR hMonitor, DWORD* pdwAvailableVidMem );
  HRESULT GetVideoMemoryViaDXGI( HMONITOR hMonitor, SIZE_T* pDedicatedVideoMemory, SIZE_T* pDedicatedSystemMemory, SIZE_T* pSharedSystemMemory );

  #ifndef SAFE_RELEASE
    #define SAFE_RELEASE(p)      { if (p) { (p)->Release(); (p)=NULL; } }
  #endif

  typedef IDirect3D9* ( WINAPI* LPDIRECT3DCREATE9 )( UINT  );
  LPDIRECT3DCREATE9 pDirect3DCreate9;

  UINT64 SystemInfo::ComputeGPUMemory( )
  {
    HINSTANCE hD3D9 = LoadLibrary( L"d3d9.dll" );
    if (!hD3D9) return 0;
    pDirect3DCreate9 = ( LPDIRECT3DCREATE9 )GetProcAddress( hD3D9, "Direct3DCreate9" );

    if (!pDirect3DCreate9) {
      FreeLibrary( hD3D9 );
      return 0;
    }

    IDirect3D9* pD3D9 = NULL;
    pD3D9 = pDirect3DCreate9( D3D_SDK_VERSION );
    if( pD3D9 )
    {
        UINT dwAdapterCount = pD3D9->GetAdapterCount();
        if (dwAdapterCount > 0) {
            UINT iAdapter = 0;

            HMONITOR hMonitor = pD3D9->GetAdapterMonitor( iAdapter );

            SIZE_T DedicatedVideoMemory;
            SIZE_T DedicatedSystemMemory;
            SIZE_T SharedSystemMemory;
            if( SUCCEEDED( GetVideoMemoryViaDXGI( hMonitor, &DedicatedVideoMemory, &DedicatedSystemMemory, &SharedSystemMemory ) ) )
            {
              m_bIsDirectX10Capable = true;
              SAFE_RELEASE( pD3D9 );
              return UINT64(DedicatedVideoMemory);
            } else {
              DWORD dwAvailableVidMem;
              if( SUCCEEDED( GetVideoMemoryViaDirectDraw( hMonitor, &dwAvailableVidMem ) ) ) {
                SAFE_RELEASE( pD3D9 );
                FreeLibrary( hD3D9 );
                return UINT64(DedicatedVideoMemory);
              } else {
                SAFE_RELEASE( pD3D9 );
                FreeLibrary( hD3D9 );
                return 0;
              }
            }
        }

        SAFE_RELEASE( pD3D9 );
        FreeLibrary( hD3D9 );
        return 0;
    }
    else
    {
        FreeLibrary( hD3D9 );
        return 0;
    }
  }

#else
  UINT64 SystemInfo::ComputeGPUMemory( )
  {
    #ifdef TUVOK_OS_APPLE
      return 0;
    #else // Linux
      return 0;
    #endif
  }
#endif
<|endoftext|>


<commit_before>#include "bvs/bvs.h"
#include "bvs/traits.h"
#include "control.h"
#include "loader.h"

#ifdef BVS_LOG_SYSTEM
#include "logsystem.h"
#endif

BVS::BVS::BVS(int argc, char** argv, std::function<void()>shutdownHandler)
	: config{"bvs", argc, argv},
	shutdownHandler(shutdownHandler),
	info(Info{config, 0, {}, {}}),
#ifdef BVS_LOG_SYSTEM
	logSystem{LogSystem::connectToLogSystem()},
	logger{"BVS"},
#endif
	loader{new Loader{info}},
	control{new Control{loader->modules, *this, info}},
	moduleStack{}
{
#ifdef BVS_LOG_SYSTEM
	logSystem->updateSettings(config);
	logSystem->updateLoggerLevels(config);
#endif
}

BVS::BVS::~BVS()
{
	delete control;
	delete loader;
}

BVS::BVS& BVS::BVS::loadModules()
{
	// get module list from config
	std::vector<std::string> moduleList;
	config.getValue("BVS.modules", moduleList);
	std::string poolName;

	// check length
	if (moduleList.size()==0)
	{
		LOG(1, "No modules specified, nothing to load!");
		return *this;
	}

	// load all selected modules
	bool asThread;
	for (auto& it : moduleList)
	{
		asThread = false;
		poolName.clear();

		// check for thread selection ('+' prefix) and system settings
		if (it[0]=='+')
		{
			it.erase(0, 1);
			if (it[0]=='[')
			{
				LOG(0, "Cannot start module in thread AND pool!");
				exit(1);
			}
			asThread = true;
		}

		if (it[0]=='[')
		{
			size_t pos = it.find_first_of(']');
			poolName = it.substr(1, pos-1);
			it.erase(0, pos+1);
		}

		loadModule(it , asThread, poolName);
	}

	return *this;
}

BVS::BVS& BVS::BVS::loadModule(const std::string& moduleTraits, bool asThread, std::string poolName)
{
	std::string id;
	std::string library;
	std::string configuration;
	std::string options;

	// adapt to module thread/pools settings
	bool moduleThreads = config.getValue<bool>("BVS.moduleThreads", bvs_module_threads);
	bool forceModuleThreads = config.getValue<bool>("BVS.forceModuleThreads", bvs_module_force_threads);
	bool modulePools = config.getValue<bool>("BVS.modulePools", bvs_module_pools);

	if (forceModuleThreads) asThread = true;
	if (!moduleThreads) asThread = false;
	if (!modulePools) poolName.clear();

	// separate id, library, configuration and options
	size_t separator = moduleTraits.find_first_of(".()");
	if (separator==std::string::npos) id = moduleTraits;
	else if (moduleTraits.at(separator)=='.')
	{
		id = moduleTraits.substr(0, separator);
		options = moduleTraits.substr(separator+1, std::string::npos);
	}
	else if (moduleTraits.at(separator)=='(')
	{
		size_t dot = moduleTraits.find_first_of('.');
		size_t rp = moduleTraits.find_first_of(')');
		id = moduleTraits.substr(0, separator);
		library = moduleTraits.substr(separator+1, rp-separator-1);
		options = moduleTraits.substr(rp+2<moduleTraits.size()?rp+2:rp+1, std::string::npos);
		if (dot<rp)
		{
			library = moduleTraits.substr(separator+1, dot-separator-1);
			configuration = moduleTraits.substr(dot+1, rp-dot-1);
		}
	}
	if (library.empty()) library = id;
	if (configuration.empty()) configuration = id;

	// load
	loader->load(id, library, configuration, options, asThread, poolName);
	control->startModule(id);
	moduleStack.push(id);

	return *this;
}

BVS::BVS& BVS::BVS::unloadModules()
{
	while (!moduleStack.empty())
	{
		if(loader->modules.find(moduleStack.top())!=loader->modules.end())
		{
			unloadModule(moduleStack.top());
		}
		moduleStack.pop();
	}

	return *this;
}

BVS::BVS& BVS::BVS::unloadModule(const std::string& id)
{
	SystemFlag state = control->queryActiveFlag();
	if (state!=SystemFlag::QUIT)
	{
		control->sendCommand(SystemFlag::PAUSE);
		control->waitUntilInactive(id);
	}

	control->purgeData(id);
	control->quitModule(id);
	loader->unload(id);

	if (state!=SystemFlag::QUIT) control->sendCommand(state);

	return *this;
}

BVS::BVS& BVS::BVS::loadConfigFile(const std::string& configFile)
{
	config.loadConfigFile(configFile);
#ifdef BVS_LOG_SYSTEM
	logSystem->updateSettings(config);
	logSystem->updateLoggerLevels(config);
#endif

	return *this;
}

BVS::BVS& BVS::BVS::setLogSystemVerbosity(const unsigned short verbosity)
{
#ifdef BVS_LOG_SYSTEM
	if (logSystem) logSystem->setSystemVerbosity(verbosity);
#else
	(void) verbosity;
#endif

	return *this;
}

BVS::BVS& BVS::BVS::enableLogFile(const std::string& file, bool append)
{
#ifdef BVS_LOG_SYSTEM
	if (logSystem) logSystem->enableLogFile(file, append);
#else
	(void) file;
	(void) append;
#endif

	return *this;
}

BVS::BVS& BVS::BVS::disableLogFile()
{
#ifdef BVS_LOG_SYSTEM
	if (logSystem) logSystem->disableLogFile();
#endif

	return *this;
}

BVS::BVS& BVS::BVS::enableLogConsole(const std::ostream& out)
{
#ifdef BVS_LOG_SYSTEM
	if (logSystem) logSystem->enableLogConsole(out);
#else
	(void) out;
#endif

	return *this;
}

BVS::BVS& BVS::BVS::disableLogConsole()
{
#ifdef BVS_LOG_SYSTEM
	if (logSystem) logSystem->disableLogConsole();
#endif

	return *this;
}

BVS::BVS& BVS::BVS::connectAllModules()
{
	loader->connectAllModules();

	return *this;
}

BVS::BVS& BVS::BVS::connectModule(const std::string id)
{
	loader->connectModule(id, config.getValue<bool>("BVS.connectorTypeMatching", bvs_connector_type_matching));

	return *this;
}

BVS::BVS& BVS::BVS::start(bool forkMasterController)
{
	control->masterController(forkMasterController);

	return *this;
}

BVS::BVS& BVS::BVS::run()
{
	control->sendCommand(SystemFlag::RUN);

	return *this;
}

BVS::BVS& BVS::BVS::step()
{
	control->sendCommand(SystemFlag::STEP);

	return *this;
}

BVS::BVS& BVS::BVS::pause()
{
	control->sendCommand(SystemFlag::PAUSE);

	return *this;
}

BVS::BVS& BVS::BVS::hotSwap(const std::string& id)
{
#ifdef BVS_MODULE_HOTSWAP
	if (control->modules.find(id)!=control->modules.end())
	{
		SystemFlag state = control->queryActiveFlag();
		control->sendCommand(SystemFlag::PAUSE);
		control->waitUntilInactive(id);

		loader->hotSwapModule(id);
		control->sendCommand(state);
	}
	else
	{
		LOG(0, "'" << id << "' not found!");
	}
#else //BVS_MODULE_HOTSWAP
	LOG(0, "ERROR: HotSwap disabled, could not hotswap: '" << id << "'!");
#endif //BVS_MODULE_HOTSWAP

	return *this;
}

BVS::BVS& BVS::BVS::quit()
{
	control->sendCommand(SystemFlag::QUIT);
	unloadModules();

	return *this;
}
<commit_msg>bvs: always wait for running instances<commit_after>#include "bvs/bvs.h"
#include "bvs/traits.h"
#include "control.h"
#include "loader.h"

#ifdef BVS_LOG_SYSTEM
#include "logsystem.h"
#endif

BVS::BVS::BVS(int argc, char** argv, std::function<void()>shutdownHandler)
	: config{"bvs", argc, argv},
	shutdownHandler(shutdownHandler),
	info(Info{config, 0, {}, {}}),
#ifdef BVS_LOG_SYSTEM
	logSystem{LogSystem::connectToLogSystem()},
	logger{"BVS"},
#endif
	loader{new Loader{info}},
	control{new Control{loader->modules, *this, info}},
	moduleStack{}
{
#ifdef BVS_LOG_SYSTEM
	logSystem->updateSettings(config);
	logSystem->updateLoggerLevels(config);
#endif
}

BVS::BVS::~BVS()
{
	delete control;
	delete loader;
}

BVS::BVS& BVS::BVS::loadModules()
{
	// get module list from config
	std::vector<std::string> moduleList;
	config.getValue("BVS.modules", moduleList);
	std::string poolName;

	// check length
	if (moduleList.size()==0)
	{
		LOG(1, "No modules specified, nothing to load!");
		return *this;
	}

	// load all selected modules
	bool asThread;
	for (auto& it : moduleList)
	{
		asThread = false;
		poolName.clear();

		// check for thread selection ('+' prefix) and system settings
		if (it[0]=='+')
		{
			it.erase(0, 1);
			if (it[0]=='[')
			{
				LOG(0, "Cannot start module in thread AND pool!");
				exit(1);
			}
			asThread = true;
		}

		if (it[0]=='[')
		{
			size_t pos = it.find_first_of(']');
			poolName = it.substr(1, pos-1);
			it.erase(0, pos+1);
		}

		loadModule(it , asThread, poolName);
	}

	return *this;
}

BVS::BVS& BVS::BVS::loadModule(const std::string& moduleTraits, bool asThread, std::string poolName)
{
	std::string id;
	std::string library;
	std::string configuration;
	std::string options;

	// adapt to module thread/pools settings
	bool moduleThreads = config.getValue<bool>("BVS.moduleThreads", bvs_module_threads);
	bool forceModuleThreads = config.getValue<bool>("BVS.forceModuleThreads", bvs_module_force_threads);
	bool modulePools = config.getValue<bool>("BVS.modulePools", bvs_module_pools);

	if (forceModuleThreads) asThread = true;
	if (!moduleThreads) asThread = false;
	if (!modulePools) poolName.clear();

	// separate id, library, configuration and options
	size_t separator = moduleTraits.find_first_of(".()");
	if (separator==std::string::npos) id = moduleTraits;
	else if (moduleTraits.at(separator)=='.')
	{
		id = moduleTraits.substr(0, separator);
		options = moduleTraits.substr(separator+1, std::string::npos);
	}
	else if (moduleTraits.at(separator)=='(')
	{
		size_t dot = moduleTraits.find_first_of('.');
		size_t rp = moduleTraits.find_first_of(')');
		id = moduleTraits.substr(0, separator);
		library = moduleTraits.substr(separator+1, rp-separator-1);
		options = moduleTraits.substr(rp+2<moduleTraits.size()?rp+2:rp+1, std::string::npos);
		if (dot<rp)
		{
			library = moduleTraits.substr(separator+1, dot-separator-1);
			configuration = moduleTraits.substr(dot+1, rp-dot-1);
		}
	}
	if (library.empty()) library = id;
	if (configuration.empty()) configuration = id;

	// load
	loader->load(id, library, configuration, options, asThread, poolName);
	control->startModule(id);
	moduleStack.push(id);

	return *this;
}

BVS::BVS& BVS::BVS::unloadModules()
{
	while (!moduleStack.empty())
	{
		if(loader->modules.find(moduleStack.top())!=loader->modules.end())
		{
			unloadModule(moduleStack.top());
		}
		moduleStack.pop();
	}

	return *this;
}

BVS::BVS& BVS::BVS::unloadModule(const std::string& id)
{
	SystemFlag state = control->queryActiveFlag();
	if (state!=SystemFlag::QUIT) control->sendCommand(SystemFlag::PAUSE);

	control->waitUntilInactive(id);
	control->purgeData(id);
	control->quitModule(id);
	loader->unload(id);

	if (state!=SystemFlag::QUIT) control->sendCommand(state);

	return *this;
}

BVS::BVS& BVS::BVS::loadConfigFile(const std::string& configFile)
{
	config.loadConfigFile(configFile);
#ifdef BVS_LOG_SYSTEM
	logSystem->updateSettings(config);
	logSystem->updateLoggerLevels(config);
#endif

	return *this;
}

BVS::BVS& BVS::BVS::setLogSystemVerbosity(const unsigned short verbosity)
{
#ifdef BVS_LOG_SYSTEM
	if (logSystem) logSystem->setSystemVerbosity(verbosity);
#else
	(void) verbosity;
#endif

	return *this;
}

BVS::BVS& BVS::BVS::enableLogFile(const std::string& file, bool append)
{
#ifdef BVS_LOG_SYSTEM
	if (logSystem) logSystem->enableLogFile(file, append);
#else
	(void) file;
	(void) append;
#endif

	return *this;
}

BVS::BVS& BVS::BVS::disableLogFile()
{
#ifdef BVS_LOG_SYSTEM
	if (logSystem) logSystem->disableLogFile();
#endif

	return *this;
}

BVS::BVS& BVS::BVS::enableLogConsole(const std::ostream& out)
{
#ifdef BVS_LOG_SYSTEM
	if (logSystem) logSystem->enableLogConsole(out);
#else
	(void) out;
#endif

	return *this;
}

BVS::BVS& BVS::BVS::disableLogConsole()
{
#ifdef BVS_LOG_SYSTEM
	if (logSystem) logSystem->disableLogConsole();
#endif

	return *this;
}

BVS::BVS& BVS::BVS::connectAllModules()
{
	loader->connectAllModules();

	return *this;
}

BVS::BVS& BVS::BVS::connectModule(const std::string id)
{
	loader->connectModule(id, config.getValue<bool>("BVS.connectorTypeMatching", bvs_connector_type_matching));

	return *this;
}

BVS::BVS& BVS::BVS::start(bool forkMasterController)
{
	control->masterController(forkMasterController);

	return *this;
}

BVS::BVS& BVS::BVS::run()
{
	control->sendCommand(SystemFlag::RUN);

	return *this;
}

BVS::BVS& BVS::BVS::step()
{
	control->sendCommand(SystemFlag::STEP);

	return *this;
}

BVS::BVS& BVS::BVS::pause()
{
	control->sendCommand(SystemFlag::PAUSE);

	return *this;
}

BVS::BVS& BVS::BVS::hotSwap(const std::string& id)
{
#ifdef BVS_MODULE_HOTSWAP
	if (control->modules.find(id)!=control->modules.end())
	{
		SystemFlag state = control->queryActiveFlag();
		control->sendCommand(SystemFlag::PAUSE);
		control->waitUntilInactive(id);

		loader->hotSwapModule(id);
		control->sendCommand(state);
	}
	else
	{
		LOG(0, "'" << id << "' not found!");
	}
#else //BVS_MODULE_HOTSWAP
	LOG(0, "ERROR: HotSwap disabled, could not hotswap: '" << id << "'!");
#endif //BVS_MODULE_HOTSWAP

	return *this;
}

BVS::BVS& BVS::BVS::quit()
{
	control->sendCommand(SystemFlag::QUIT);
	unloadModules();

	return *this;
}
<|endoftext|>


<commit_before>#define MYSQLPP_NOT_HEADER
#include "platform.h"

#include "field_names.h"

#include "result2.hh"

void FieldNames::init(const ResUse *res) {
  int num = res->num_fields();
  reserve(num);
  for (int i = 0; i < num; i++) {
		std::string p(res->fields()[i].name); str_to_lwr(p);   push_back(p);
  }

}

<commit_msg>- #include filename fix - Code style improvements<commit_after>#define MYSQLPP_NOT_HEADER
#include "platform.h"

#include "field_names.h"

#include "result.h"

void FieldNames::init(const ResUse *res)
{
  int num = res->num_fields();
  reserve(num);
  for (int i = 0; i < num; i++) {
		std::string p(res->fields()[i].name);
		str_to_lwr(p);
		push_back(p);
  }
}

<|endoftext|>