splash: de-confuse mixed VCL and UNO reference counting.

Change-Id: I1c8ded2e5c5e8072111d3e1480ba7086db135810
diff --git a/desktop/source/splash/splash.cxx b/desktop/source/splash/splash.cxx
index cb1ed36..cb1630a 100644
--- a/desktop/source/splash/splash.cxx
+++ b/desktop/source/splash/splash.cxx
@@ -46,16 +46,31 @@ using namespace ::com::sun::star::uno;

namespace {

class SplashScreen;

class SplashScreenWindow : public IntroWindow
{
public:
    SplashScreen *pSpl;
    ScopedVclPtr<VirtualDevice> _vdev;
            SplashScreenWindow(SplashScreen *);
    virtual ~SplashScreenWindow() { disposeOnce(); }
    virtual void dispose() SAL_OVERRIDE;
    // workwindow
    virtual void Paint( const Rectangle& ) SAL_OVERRIDE;
};

class  SplashScreen
    : public ::cppu::WeakImplHelper3< XStatusIndicator, XInitialization, XServiceInfo >
    , public IntroWindow
{
    friend SplashScreenWindow;
private:
    enum BitmapMode { BM_FULLSCREEN, BM_DEFAULTMODE };

    VclPtr<SplashScreenWindow> pWindow;

    DECL_LINK( AppEventListenerHdl, VclWindowEvent * );
    virtual ~SplashScreen();
    virtual void dispose() SAL_OVERRIDE;
    void loadConfig();
    void updateStatus();
    void SetScreenBitmap(BitmapEx &rBitmap);
@@ -63,7 +78,6 @@ private:

    static osl::Mutex _aMutex;

    ScopedVclPtr<VirtualDevice> _vdev;
    BitmapEx        _aIntroBmp;
    Color           _cProgressFrameColor;
    Color           _cProgressBarColor;
@@ -112,15 +126,24 @@ public:
    virtual css::uno::Sequence<OUString> SAL_CALL getSupportedServiceNames()
        throw (css::uno::RuntimeException, std::exception) SAL_OVERRIDE
    { return desktop::splash::getSupportedServiceNames(); }

    // workwindow
    virtual void Paint( const Rectangle& ) SAL_OVERRIDE;

};

SplashScreen::SplashScreen()
SplashScreenWindow::SplashScreenWindow(SplashScreen *pSplash)
    : IntroWindow()
    , _vdev(new VirtualDevice(*((IntroWindow*)this)))
    , pSpl( pSplash )
    , _vdev(new VirtualDevice(*this))
{
    _vdev->EnableRTL(IsRTLEnabled());
}

void SplashScreenWindow::dispose()
{
    pSpl = NULL;
    IntroWindow::dispose();
}

SplashScreen::SplashScreen()
    : pWindow( new SplashScreenWindow (this) )
    , _cProgressFrameColor(sal::static_int_cast< ColorData >(NOT_LOADED))
    , _cProgressBarColor(sal::static_int_cast< ColorData >(NOT_LOADED))
    , _cProgressTextColor(sal::static_int_cast< ColorData >(NOT_LOADED))
@@ -150,20 +173,14 @@ SplashScreen::SplashScreen()
    , _yoffset(18)
{
    loadConfig();
    _vdev->EnableRTL(IsRTLEnabled());
}

SplashScreen::~SplashScreen()
{
    disposeOnce();
}

void SplashScreen::dispose()
{
    Application::RemoveEventListener(
        LINK( this, SplashScreen, AppEventListenerHdl ) );
    Hide();
    IntroWindow::dispose();
    pWindow->Hide();
    pWindow.disposeAndClear();
}

void SAL_CALL SplashScreen::start(const OUString&, sal_Int32 nRange)
@@ -174,10 +191,10 @@ void SAL_CALL SplashScreen::start(const OUString&, sal_Int32 nRange)
        _bProgressEnd = false;
        SolarMutexGuard aSolarGuard;
        if ( _eBitmapMode == BM_FULLSCREEN )
            ShowFullScreenMode( true );
        Show();
        Paint(Rectangle());
        Flush();
            pWindow->ShowFullScreenMode( true );
        pWindow->Show();
        pWindow->Paint(Rectangle());
        pWindow->Flush();
    }
}

@@ -188,8 +205,8 @@ void SAL_CALL SplashScreen::end()
    if (_bVisible )
    {
        if ( _eBitmapMode == BM_FULLSCREEN )
            EndFullScreenMode();
        Hide();
            pWindow->EndFullScreenMode();
        pWindow->Hide();
    }
    _bProgressEnd = true;
}
@@ -201,8 +218,8 @@ void SAL_CALL SplashScreen::reset()
    if (_bVisible && !_bProgressEnd )
    {
        if ( _eBitmapMode == BM_FULLSCREEN )
            ShowFullScreenMode( true );
        Show();
            pWindow->ShowFullScreenMode( true );
        pWindow->Show();
        updateStatus();
    }
}
@@ -218,8 +235,8 @@ void SAL_CALL SplashScreen::setText(const OUString& rText)
        if (_bVisible && !_bProgressEnd)
        {
            if ( _eBitmapMode == BM_FULLSCREEN )
                ShowFullScreenMode( true );
            Show();
                pWindow->ShowFullScreenMode( true );
            pWindow->Show();
            updateStatus();
        }
    }
@@ -233,11 +250,13 @@ void SAL_CALL SplashScreen::setValue(sal_Int32 nValue)
    SolarMutexGuard aSolarGuard;
    if (_bVisible && !_bProgressEnd) {
        if ( _eBitmapMode == BM_FULLSCREEN )
            ShowFullScreenMode( true );
        Show();
        if (nValue >= _iMax) _iProgress = _iMax;
    else _iProgress = nValue;
    updateStatus();
            pWindow->ShowFullScreenMode( true );
        pWindow->Show();
        if (nValue >= _iMax)
            _iProgress = _iMax;
        else
            _iProgress = nValue;
        updateStatus();
    }
}

@@ -257,8 +276,8 @@ SplashScreen::initialize( const ::com::sun::star::uno::Sequence< ::com::sun::sta
        if ( _bShowLogo )
            SetScreenBitmap (_aIntroBmp);
        Size aSize = _aIntroBmp.GetSizePixel();
        SetOutputSizePixel( aSize );
        _vdev->SetOutputSizePixel( aSize );
        pWindow->SetOutputSizePixel( aSize );
        pWindow->_vdev->SetOutputSizePixel( aSize );
        _height = aSize.Height();
        _width = aSize.Width();
        if (_width > 500)
@@ -328,10 +347,12 @@ SplashScreen::initialize( const ::com::sun::star::uno::Sequence< ::com::sun::sta

void SplashScreen::updateStatus()
{
    if (!_bVisible || _bProgressEnd) return;
    if (!_bPaintProgress) _bPaintProgress = true;
    Paint(Rectangle());
    Flush();
    if (!_bVisible || _bProgressEnd)
        return;
    if (!_bPaintProgress)
        _bPaintProgress = true;
    pWindow->Paint(Rectangle());
    pWindow->Flush();
}

// internal private methods
@@ -342,7 +363,7 @@ IMPL_LINK( SplashScreen, AppEventListenerHdl, VclWindowEvent *, inEvent )
        switch ( inEvent->GetId() )
        {
            case VCLEVENT_WINDOW_SHOW:
                Paint( Rectangle() );
                pWindow->Paint( Rectangle() );
                break;
            default:
                break;
@@ -583,18 +604,19 @@ void SplashScreen::determineProgressRatioValues(
    }
}

void SplashScreen::Paint( const Rectangle&)
void SplashScreenWindow::Paint( const Rectangle&)
{
    if(!_bVisible) return;
    if (!pSpl || !pSpl->_bVisible)
        return;

    //native drawing
    // in case of native controls we need to draw directly to the window
    if( _bNativeProgress && IsNativeControlSupported( CTRL_INTROPROGRESS, PART_ENTIRE_CONTROL ) )
    if( pSpl->_bNativeProgress && IsNativeControlSupported( CTRL_INTROPROGRESS, PART_ENTIRE_CONTROL ) )
    {
        DrawBitmapEx( Point(), _aIntroBmp );
        DrawBitmapEx( Point(), pSpl->_aIntroBmp );

        ImplControlValue aValue( _iProgress * _barwidth / _iMax);
        Rectangle aDrawRect( Point(_tlx, _tly), Size( _barwidth, _barheight ) );
        ImplControlValue aValue( pSpl->_iProgress * pSpl->_barwidth / pSpl->_iMax);
        Rectangle aDrawRect( Point(pSpl->_tlx, pSpl->_tly), Size( pSpl->_barwidth, pSpl->_barheight ) );
        Rectangle aNativeControlRegion, aNativeContentRegion;

        if( GetNativeControlRegion( CTRL_INTROPROGRESS, PART_ENTIRE_CONTROL, aDrawRect,
@@ -602,39 +624,40 @@ void SplashScreen::Paint( const Rectangle&)
                                             aNativeControlRegion, aNativeContentRegion ) )
        {
              long nProgressHeight = aNativeControlRegion.GetHeight();
              aDrawRect.Top() -= (nProgressHeight - _barheight)/2;
              aDrawRect.Bottom() += (nProgressHeight - _barheight)/2;
              aDrawRect.Top() -= (nProgressHeight - pSpl->_barheight)/2;
              aDrawRect.Bottom() += (nProgressHeight - pSpl->_barheight)/2;
        }

        if( (DrawNativeControl( CTRL_INTROPROGRESS, PART_ENTIRE_CONTROL, aDrawRect,
                                            ControlState::ENABLED, aValue, _sProgressText )) )
                                ControlState::ENABLED, aValue, _sProgressText )) )
        {
            return;
        }
    }
    //non native drawing
    // draw bitmap
    if (_bPaintBitmap)
        _vdev->DrawBitmapEx( Point(), _aIntroBmp );

    if (_bPaintProgress) {
    // non native drawing
    // draw bitmap
    if (pSpl->_bPaintBitmap)
        _vdev->DrawBitmapEx( Point(), pSpl->_aIntroBmp );

    if (pSpl->_bPaintProgress) {
        // draw progress...
        long length = (_iProgress * _barwidth / _iMax) - (2 * _barspace);
        long length = (pSpl->_iProgress * pSpl->_barwidth / pSpl->_iMax) - (2 * pSpl->_barspace);
        if (length < 0) length = 0;

        // border
        _vdev->SetFillColor();
        _vdev->SetLineColor( _cProgressFrameColor );
        _vdev->DrawRect(Rectangle(_tlx, _tly, _tlx+_barwidth, _tly+_barheight));
        _vdev->SetFillColor( _cProgressBarColor );
        _vdev->SetLineColor( pSpl->_cProgressFrameColor );
        _vdev->DrawRect(Rectangle(pSpl->_tlx, pSpl->_tly, pSpl->_tlx+pSpl->_barwidth, pSpl->_tly+pSpl->_barheight));
        _vdev->SetFillColor( pSpl->_cProgressBarColor );
        _vdev->SetLineColor();
        _vdev->DrawRect(Rectangle(_tlx+_barspace, _tly+_barspace, _tlx+_barspace+length, _tly+_barheight-_barspace));
        _vdev->DrawRect(Rectangle(pSpl->_tlx+pSpl->_barspace, pSpl->_tly+pSpl->_barspace, pSpl->_tlx+pSpl->_barspace+length, pSpl->_tly+pSpl->_barheight-pSpl->_barspace));
        vcl::Font aFont;
        aFont.SetSize(Size(0, 12));
        aFont.SetAlign(ALIGN_BASELINE);
        _vdev->SetFont(aFont);
        _vdev->SetTextColor(_cProgressTextColor);
        _vdev->DrawText(Point(_tlx, _textBaseline), _sProgressText);
        _vdev->SetTextColor(pSpl->_cProgressTextColor);
        _vdev->DrawText(Point(pSpl->_tlx, pSpl->_textBaseline), pSpl->_sProgressText);
    }
    DrawOutDev(Point(), GetOutputSizePixel(), Point(), _vdev->GetOutputSizePixel(), *_vdev.get() );
}