<commit_before>/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2008 by Sun Microsystems, Inc.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * $RCSfile: randrwrapper.cxx,v $
 *
 * $Revision: 1.5.10.1 $
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org 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 version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/

#ifdef USE_RANDR

#include <tools/prex.h>
#include <X11/extensions/Xrandr.h>
#include <tools/postx.h>

#include "osl/module.h"
#include "rtl/ustring.hxx"

namespace
{

# ifdef XRANDR_DLOPEN

class RandRWrapper
{
    oslModule m_pRandRLib;

    // function pointers
    Bool(*m_pXRRQueryExtension)(Display*,int*,int*);
    Status(*m_pXRRQueryVersion)(Display*,int*,int*);
    XRRScreenConfiguration*(*m_pXRRGetScreenInfo)(Display*,Drawable);
    void(*m_pXRRFreeScreenConfigInfo)(XRRScreenConfiguration*);
    void(*m_pXRRSelectInput)(Display*,XLIB_Window,int);
    int(*m_pXRRUpdateConfiguration)(XEvent*);
    XRRScreenSize*(*m_pXRRSizes)(Display*,int,int*);
    XRRScreenSize*(*m_pXRRConfigSizes)(XRRScreenConfiguration*,int*);
    SizeID(*m_pXRRConfigCurrentConfiguration)(XRRScreenConfiguration*,Rotation*);
    int(*m_pXRRRootToScreen)(Display*, XLIB_Window);

    bool m_bValid;

    void initFromModule();

    RandRWrapper(Display*);
    ~RandRWrapper();
public:
    static RandRWrapper& get(Display*);
    static void releaseWrapper();

    Bool XRRQueryExtension(Display* i_pDisp, int* o_event_base, int* o_error_base )
    {
        Bool bRet = False;
        if( m_bValid )
            bRet = m_pXRRQueryExtension( i_pDisp, o_event_base, o_error_base );
        return bRet;
    }
    Status XRRQueryVersion( Display* i_pDisp, int* o_major, int* o_minor )
    {
        return m_bValid ? m_pXRRQueryVersion( i_pDisp, o_major, o_minor ) : 0;
    }
    XRRScreenConfiguration* XRRGetScreenInfo( Display* i_pDisp, Drawable i_aDrawable )
    {
        return m_bValid ? m_pXRRGetScreenInfo( i_pDisp, i_aDrawable ) : NULL;
    }
    void XRRFreeScreenConfigInfo( XRRScreenConfiguration* i_pConfig )
    {
        if( m_bValid )
            m_pXRRFreeScreenConfigInfo( i_pConfig );
    }
    void XRRSelectInput( Display* i_pDisp, XLIB_Window i_window, int i_nMask )
    {
        if( m_bValid )
            m_pXRRSelectInput( i_pDisp, i_window, i_nMask );
    }
    int XRRUpdateConfiguration( XEvent* i_pEvent )
    {
        return m_bValid ? m_pXRRUpdateConfiguration( i_pEvent ) : 0;
    }
    XRRScreenSize* XRRSizes( Display* i_pDisp, int i_screen, int* o_nscreens )
    {
        return m_bValid ? m_pXRRSizes( i_pDisp, i_screen, o_nscreens ) : NULL;
    }
    XRRScreenSize* XRRConfigSizes( XRRScreenConfiguration* i_pConfig, int* o_nSizes )
    {
        return m_bValid ? m_pXRRConfigSizes( i_pConfig, o_nSizes ) : NULL;
    }
    SizeID XRRConfigCurrentConfiguration( XRRScreenConfiguration* i_pConfig, Rotation* o_pRot )
    {
        return m_bValid ? m_pXRRConfigCurrentConfiguration( i_pConfig, o_pRot ) : 0;
    }
    int XRRRootToScreen( Display *dpy, XLIB_Window root )
    {
        return m_bValid ? m_pXRRRootToScreen( dpy, root ) : -1;
    }
};

void RandRWrapper::initFromModule()
{
    m_pXRRQueryExtension = (Bool(*)(Display*,int*,int*))osl_getAsciiFunctionSymbol( m_pRandRLib, "XRRQueryExtension" );
    m_pXRRQueryVersion = (Status(*)(Display*,int*,int*))osl_getAsciiFunctionSymbol( m_pRandRLib, "XRRQueryVersion" );
    m_pXRRGetScreenInfo = (XRRScreenConfiguration*(*)(Display*,Drawable))osl_getAsciiFunctionSymbol( m_pRandRLib, "XRRGetScreenInfo" );
    m_pXRRFreeScreenConfigInfo = (void(*)(XRRScreenConfiguration*))osl_getAsciiFunctionSymbol( m_pRandRLib, "XRRFreeScreenConfigInfo" );
    m_pXRRSelectInput = (void(*)(Display*,XLIB_Window,int))osl_getAsciiFunctionSymbol( m_pRandRLib, "XRRSelectInput" );
    m_pXRRUpdateConfiguration = (int(*)(XEvent*))osl_getAsciiFunctionSymbol( m_pRandRLib, "XRRUpdateConfiguration" );
    m_pXRRSizes = (XRRScreenSize*(*)(Display*,int,int*))osl_getAsciiFunctionSymbol( m_pRandRLib, "XRRSizes" );
    m_pXRRConfigSizes = (XRRScreenSize*(*)(XRRScreenConfiguration*,int*))osl_getAsciiFunctionSymbol( m_pRandRLib, "XRRConfigSizes" );
    m_pXRRConfigCurrentConfiguration = (SizeID(*)(XRRScreenConfiguration*,Rotation*))osl_getAsciiFunctionSymbol( m_pRandRLib, "XRRConfigCurrentConfiguration" );
    m_pXRRRootToScreen = (int(*)(Display*,XLIB_Window))osl_getAsciiFunctionSymbol( m_pRandRLib, "XRRRootToScreen" );

    m_bValid = m_pXRRQueryExtension             &&
               m_pXRRQueryVersion               &&
               m_pXRRGetScreenInfo              &&
               m_pXRRFreeScreenConfigInfo       &&
               m_pXRRSelectInput                &&
               m_pXRRUpdateConfiguration        &&
               m_pXRRSizes                      &&
               m_pXRRConfigSizes                &&
               m_pXRRConfigCurrentConfiguration &&
               m_pXRRRootToScreen
               ;
}

RandRWrapper::RandRWrapper( Display* pDisplay ) :
        m_pRandRLib( NULL ),
        m_pXRRQueryExtension( NULL ),
        m_pXRRQueryVersion( NULL ),
        m_pXRRGetScreenInfo( NULL ),
        m_pXRRFreeScreenConfigInfo( NULL ),
        m_pXRRSelectInput( NULL ),
        m_pXRRUpdateConfiguration( NULL ),
        m_pXRRSizes( NULL ),
        m_pXRRConfigSizes( NULL ),
        m_pXRRConfigCurrentConfiguration( NULL ),
        m_pXRRRootToScreen( NULL ),
        m_bValid( false )
{
    // first try in process space (e.g. gtk links that ?)
    initFromModule();
    if( ! m_bValid )
    {
        rtl::OUString aLibName( RTL_CONSTASCII_USTRINGPARAM( "libXrandr.so.2" ) );
        m_pRandRLib = osl_loadModule( aLibName.pData, SAL_LOADMODULE_DEFAULT );
        initFromModule();
    }
    if( m_bValid )
    {
        int nEventBase = 0, nErrorBase = 0;
        if( ! m_pXRRQueryExtension( pDisplay, &nEventBase, &nErrorBase ) )
            m_bValid = false;
    }
}

RandRWrapper::~RandRWrapper()
{
    if( m_pRandRLib )
        osl_unloadModule( m_pRandRLib );
}

static RandRWrapper* pWrapper = NULL;

RandRWrapper& RandRWrapper::get( Display* i_pDisplay )
{
    if( ! pWrapper )
        pWrapper = new RandRWrapper( i_pDisplay );
    return *pWrapper;
}

void RandRWrapper::releaseWrapper()
{
    delete pWrapper;
    pWrapper = NULL;
}

# else

class RandRWrapper
{
    bool m_bValid;

    RandRWrapper(Display*);
public:
    static RandRWrapper& get(Display*);
    static void releaseWrapper();

    Bool XRRQueryExtension(Display* i_pDisp, int* o_event_base, int* o_error_base )
    {
        Bool bRet = False;
        if( m_bValid )
            bRet = ::XRRQueryExtension( i_pDisp, o_event_base, o_error_base );
        return bRet;
    }
    Status XRRQueryVersion( Display* i_pDisp, int* o_major, int* o_minor )
    {
        return m_bValid ? ::XRRQueryVersion( i_pDisp, o_major, o_minor ) : 0;
    }
    XRRScreenConfiguration* XRRGetScreenInfo( Display* i_pDisp, Drawable i_aDrawable )
    {
        return m_bValid ? ::XRRGetScreenInfo( i_pDisp, i_aDrawable ) : NULL;
    }
    void XRRFreeScreenConfigInfo( XRRScreenConfiguration* i_pConfig )
    {
        if( m_bValid )
            ::XRRFreeScreenConfigInfo( i_pConfig );
    }
    void XRRSelectInput( Display* i_pDisp, XLIB_Window i_window, int i_nMask )
    {
        if( m_bValid )
            ::XRRSelectInput( i_pDisp, i_window, i_nMask );
    }
    int XRRUpdateConfiguration( XEvent* i_pEvent )
    {
        return m_bValid ? ::XRRUpdateConfiguration( i_pEvent ) : 0;
    }
    XRRScreenSize* XRRSizes( Display* i_pDisp, int i_screen, int* o_nscreens )
    {
        return m_bValid ? ::XRRSizes( i_pDisp, i_screen, o_nscreens ) : NULL;
    }
    XRRScreenSize* XRRConfigSizes( XRRScreenConfiguration* i_pConfig, int* o_nSizes )
    {
        return m_bValid ? ::XRRConfigSizes( i_pConfig, o_nSizes ) : NULL;
    }
    SizeID XRRConfigCurrentConfiguration( XRRScreenConfiguration* i_pConfig, Rotation* o_pRot )
    {
        return m_bValid ? ::XRRConfigCurrentConfiguration( i_pConfig, o_pRot ) : 0;
    }
    int XRRRootToScreen( Display *dpy, XLIB_Window root )
    {
        return m_bValid ? ::XRRRootToScreen( dpy, root ) : -1;
    }
};

RandRWrapper::RandRWrapper( Display* pDisplay ) :
    m_bValid( true )
{
    int nEventBase = 0, nErrorBase = 0;
    if( !XRRQueryExtension( pDisplay, &nEventBase, &nErrorBase ) )
        m_bValid = false;
}

static RandRWrapper* pWrapper = NULL;

RandRWrapper& RandRWrapper::get( Display* i_pDisplay )
{
    if( ! pWrapper )
        pWrapper = new RandRWrapper( i_pDisplay );
    return *pWrapper;
}

void RandRWrapper::releaseWrapper()
{
    delete pWrapper;
    pWrapper = NULL;
}

#endif

} // namespace

#endif

#include "saldisp.hxx"
#include "salframe.h"

void SalDisplay::InitRandR( XLIB_Window aRoot ) const
{
    #ifdef USE_RANDR
    if( m_bUseRandRWrapper )
        RandRWrapper::get( GetDisplay() ).XRRSelectInput( GetDisplay(), aRoot, RRScreenChangeNotifyMask );
    #else
    (void)aRoot;
    #endif
}

void SalDisplay::DeInitRandR()
{
    #ifdef USE_RANDR
    if( m_bUseRandRWrapper )
        RandRWrapper::releaseWrapper();
#if OSL_DEBUG_LEVEL > 1
    fprintf( stderr, "SalDisplay::DeInitRandR()\n" );
#endif
    #endif
}

int SalDisplay::processRandREvent( XEvent* pEvent )
{
    int nRet = 0;
    #ifdef USE_RANDR
    XConfigureEvent* pCnfEvent=(XConfigureEvent*)pEvent;
    if( m_bUseRandRWrapper && pWrapper && pWrapper->XRRRootToScreen(GetDisplay(),pCnfEvent->window) != -1 )
    {
        nRet = pWrapper->XRRUpdateConfiguration( pEvent );
        if( nRet == 1 && pEvent->type != ConfigureNotify) // this should then be a XRRScreenChangeNotifyEvent
        {
            // update screens
            bool bNotify = false;
            for( size_t i = 0; i < m_aScreens.size(); i++ )
            {
                if( m_aScreens[i].m_bInit )
                {
                    XRRScreenConfiguration *pConfig = NULL;
                    XRRScreenSize *pSizes = NULL;
                    int nSizes = 0;
                    Rotation nRot = 0;
                    SizeID nId = 0;

                    pConfig = pWrapper->XRRGetScreenInfo( GetDisplay(), m_aScreens[i].m_aRoot );
                    nId = pWrapper->XRRConfigCurrentConfiguration( pConfig, &nRot );
                    pSizes = pWrapper->XRRConfigSizes( pConfig, &nSizes );
                    XRRScreenSize *pTargetSize = pSizes + nId;

                    bNotify = bNotify ||
                              m_aScreens[i].m_aSize.Width() != pTargetSize->width ||
                              m_aScreens[i].m_aSize.Height() != pTargetSize->height;

                    m_aScreens[i].m_aSize = Size( pTargetSize->width, pTargetSize->height );

                    pWrapper->XRRFreeScreenConfigInfo( pConfig );

                    #if OSL_DEBUG_LEVEL > 1
                    fprintf( stderr, "screen %d changed to size %dx%d\n", (int)i, (int)pTargetSize->width, (int)pTargetSize->height );
                    #endif
                }
            }
            if( bNotify && ! m_aFrames.empty() )
                m_aFrames.front()->CallCallback( SALEVENT_DISPLAYCHANGED, 0 );
        }
    }
    #else
    (void)pEvent;
    #endif
    return nRet;
}
<commit_msg>CWS-TOOLING: integrate CWS d2v02<commit_after>/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2008 by Sun Microsystems, Inc.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * $RCSfile: randrwrapper.cxx,v $
 *
 * $Revision: 1.5.10.1 $
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org 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 version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/

#ifdef USE_RANDR

#include <tools/prex.h>
#include <X11/extensions/Xrandr.h>
#include <tools/postx.h>

#include "osl/module.h"
#include "rtl/ustring.hxx"

namespace
{

# ifdef XRANDR_DLOPEN

class RandRWrapper
{
    oslModule m_pRandRLib;

    // function pointers
    Bool(*m_pXRRQueryExtension)(Display*,int*,int*);
    Status(*m_pXRRQueryVersion)(Display*,int*,int*);
    XRRScreenConfiguration*(*m_pXRRGetScreenInfo)(Display*,Drawable);
    void(*m_pXRRFreeScreenConfigInfo)(XRRScreenConfiguration*);
    void(*m_pXRRSelectInput)(Display*,XLIB_Window,int);
    int(*m_pXRRUpdateConfiguration)(XEvent*);
    XRRScreenSize*(*m_pXRRSizes)(Display*,int,int*);
    XRRScreenSize*(*m_pXRRConfigSizes)(XRRScreenConfiguration*,int*);
    SizeID(*m_pXRRConfigCurrentConfiguration)(XRRScreenConfiguration*,Rotation*);
    int(*m_pXRRRootToScreen)(Display*, XLIB_Window);

    bool m_bValid;

    void initFromModule();

    RandRWrapper(Display*);
    ~RandRWrapper();
public:
    static RandRWrapper& get(Display*);
    static void releaseWrapper();

    Bool XRRQueryExtension(Display* i_pDisp, int* o_event_base, int* o_error_base )
    {
        Bool bRet = False;
        if( m_bValid )
            bRet = m_pXRRQueryExtension( i_pDisp, o_event_base, o_error_base );
        return bRet;
    }
    Status XRRQueryVersion( Display* i_pDisp, int* o_major, int* o_minor )
    {
        return m_bValid ? m_pXRRQueryVersion( i_pDisp, o_major, o_minor ) : 0;
    }
    XRRScreenConfiguration* XRRGetScreenInfo( Display* i_pDisp, Drawable i_aDrawable )
    {
        return m_bValid ? m_pXRRGetScreenInfo( i_pDisp, i_aDrawable ) : NULL;
    }
    void XRRFreeScreenConfigInfo( XRRScreenConfiguration* i_pConfig )
    {
        if( m_bValid )
            m_pXRRFreeScreenConfigInfo( i_pConfig );
    }
    void XRRSelectInput( Display* i_pDisp, XLIB_Window i_window, int i_nMask )
    {
        if( m_bValid )
            m_pXRRSelectInput( i_pDisp, i_window, i_nMask );
    }
    int XRRUpdateConfiguration( XEvent* i_pEvent )
    {
        return m_bValid ? m_pXRRUpdateConfiguration( i_pEvent ) : 0;
    }
    XRRScreenSize* XRRSizes( Display* i_pDisp, int i_screen, int* o_nscreens )
    {
        return m_bValid ? m_pXRRSizes( i_pDisp, i_screen, o_nscreens ) : NULL;
    }
    XRRScreenSize* XRRConfigSizes( XRRScreenConfiguration* i_pConfig, int* o_nSizes )
    {
        return m_bValid ? m_pXRRConfigSizes( i_pConfig, o_nSizes ) : NULL;
    }
    SizeID XRRConfigCurrentConfiguration( XRRScreenConfiguration* i_pConfig, Rotation* o_pRot )
    {
        return m_bValid ? m_pXRRConfigCurrentConfiguration( i_pConfig, o_pRot ) : 0;
    }
    int XRRRootToScreen( Display *dpy, XLIB_Window root )
    {
        return m_bValid ? m_pXRRRootToScreen( dpy, root ) : -1;
    }
};

void RandRWrapper::initFromModule()
{
    m_pXRRQueryExtension = (Bool(*)(Display*,int*,int*))osl_getAsciiFunctionSymbol( m_pRandRLib, "XRRQueryExtension" );
    m_pXRRQueryVersion = (Status(*)(Display*,int*,int*))osl_getAsciiFunctionSymbol( m_pRandRLib, "XRRQueryVersion" );
    m_pXRRGetScreenInfo = (XRRScreenConfiguration*(*)(Display*,Drawable))osl_getAsciiFunctionSymbol( m_pRandRLib, "XRRGetScreenInfo" );
    m_pXRRFreeScreenConfigInfo = (void(*)(XRRScreenConfiguration*))osl_getAsciiFunctionSymbol( m_pRandRLib, "XRRFreeScreenConfigInfo" );
    m_pXRRSelectInput = (void(*)(Display*,XLIB_Window,int))osl_getAsciiFunctionSymbol( m_pRandRLib, "XRRSelectInput" );
    m_pXRRUpdateConfiguration = (int(*)(XEvent*))osl_getAsciiFunctionSymbol( m_pRandRLib, "XRRUpdateConfiguration" );
    m_pXRRSizes = (XRRScreenSize*(*)(Display*,int,int*))osl_getAsciiFunctionSymbol( m_pRandRLib, "XRRSizes" );
    m_pXRRConfigSizes = (XRRScreenSize*(*)(XRRScreenConfiguration*,int*))osl_getAsciiFunctionSymbol( m_pRandRLib, "XRRConfigSizes" );
    m_pXRRConfigCurrentConfiguration = (SizeID(*)(XRRScreenConfiguration*,Rotation*))osl_getAsciiFunctionSymbol( m_pRandRLib, "XRRConfigCurrentConfiguration" );
    m_pXRRRootToScreen = (int(*)(Display*,XLIB_Window))osl_getAsciiFunctionSymbol( m_pRandRLib, "XRRRootToScreen" );

    m_bValid = m_pXRRQueryExtension             &&
               m_pXRRQueryVersion               &&
               m_pXRRGetScreenInfo              &&
               m_pXRRFreeScreenConfigInfo       &&
               m_pXRRSelectInput                &&
               m_pXRRUpdateConfiguration        &&
               m_pXRRSizes                      &&
               m_pXRRConfigSizes                &&
               m_pXRRConfigCurrentConfiguration &&
               m_pXRRRootToScreen
               ;
}

RandRWrapper::RandRWrapper( Display* pDisplay ) :
        m_pRandRLib( NULL ),
        m_pXRRQueryExtension( NULL ),
        m_pXRRQueryVersion( NULL ),
        m_pXRRGetScreenInfo( NULL ),
        m_pXRRFreeScreenConfigInfo( NULL ),
        m_pXRRSelectInput( NULL ),
        m_pXRRUpdateConfiguration( NULL ),
        m_pXRRSizes( NULL ),
        m_pXRRConfigSizes( NULL ),
        m_pXRRConfigCurrentConfiguration( NULL ),
        m_pXRRRootToScreen( NULL ),
        m_bValid( false )
{
    // first try in process space (e.g. gtk links that ?)
    initFromModule();
    if( ! m_bValid )
    {
        rtl::OUString aLibName( RTL_CONSTASCII_USTRINGPARAM( "libXrandr.so.2" ) );
        // load and resolve dependencies immediately
        // rationale: there are older distributions where libXrandr.so.2 is not linked
        // with libXext.so, resulting in a missing symbol and terminating the office
        // obviously they expected libXext to be linked in global symbolspace (that is
        // linked by the application), which is not the case with us (because we want
        // to be able to run in headless mode even without an installed X11 library)
        m_pRandRLib = osl_loadModule( aLibName.pData, SAL_LOADMODULE_DEFAULT | SAL_LOADMODULE_NOW );
        initFromModule();
    }
    if( m_bValid )
    {
        int nEventBase = 0, nErrorBase = 0;
        if( ! m_pXRRQueryExtension( pDisplay, &nEventBase, &nErrorBase ) )
            m_bValid = false;
    }
}

RandRWrapper::~RandRWrapper()
{
    if( m_pRandRLib )
        osl_unloadModule( m_pRandRLib );
}

static RandRWrapper* pWrapper = NULL;

RandRWrapper& RandRWrapper::get( Display* i_pDisplay )
{
    if( ! pWrapper )
        pWrapper = new RandRWrapper( i_pDisplay );
    return *pWrapper;
}

void RandRWrapper::releaseWrapper()
{
    delete pWrapper;
    pWrapper = NULL;
}

# else

class RandRWrapper
{
    bool m_bValid;

    RandRWrapper(Display*);
public:
    static RandRWrapper& get(Display*);
    static void releaseWrapper();

    Bool XRRQueryExtension(Display* i_pDisp, int* o_event_base, int* o_error_base )
    {
        Bool bRet = False;
        if( m_bValid )
            bRet = ::XRRQueryExtension( i_pDisp, o_event_base, o_error_base );
        return bRet;
    }
    Status XRRQueryVersion( Display* i_pDisp, int* o_major, int* o_minor )
    {
        return m_bValid ? ::XRRQueryVersion( i_pDisp, o_major, o_minor ) : 0;
    }
    XRRScreenConfiguration* XRRGetScreenInfo( Display* i_pDisp, Drawable i_aDrawable )
    {
        return m_bValid ? ::XRRGetScreenInfo( i_pDisp, i_aDrawable ) : NULL;
    }
    void XRRFreeScreenConfigInfo( XRRScreenConfiguration* i_pConfig )
    {
        if( m_bValid )
            ::XRRFreeScreenConfigInfo( i_pConfig );
    }
    void XRRSelectInput( Display* i_pDisp, XLIB_Window i_window, int i_nMask )
    {
        if( m_bValid )
            ::XRRSelectInput( i_pDisp, i_window, i_nMask );
    }
    int XRRUpdateConfiguration( XEvent* i_pEvent )
    {
        return m_bValid ? ::XRRUpdateConfiguration( i_pEvent ) : 0;
    }
    XRRScreenSize* XRRSizes( Display* i_pDisp, int i_screen, int* o_nscreens )
    {
        return m_bValid ? ::XRRSizes( i_pDisp, i_screen, o_nscreens ) : NULL;
    }
    XRRScreenSize* XRRConfigSizes( XRRScreenConfiguration* i_pConfig, int* o_nSizes )
    {
        return m_bValid ? ::XRRConfigSizes( i_pConfig, o_nSizes ) : NULL;
    }
    SizeID XRRConfigCurrentConfiguration( XRRScreenConfiguration* i_pConfig, Rotation* o_pRot )
    {
        return m_bValid ? ::XRRConfigCurrentConfiguration( i_pConfig, o_pRot ) : 0;
    }
    int XRRRootToScreen( Display *dpy, XLIB_Window root )
    {
        return m_bValid ? ::XRRRootToScreen( dpy, root ) : -1;
    }
};

RandRWrapper::RandRWrapper( Display* pDisplay ) :
    m_bValid( true )
{
    int nEventBase = 0, nErrorBase = 0;
    if( !XRRQueryExtension( pDisplay, &nEventBase, &nErrorBase ) )
        m_bValid = false;
}

static RandRWrapper* pWrapper = NULL;

RandRWrapper& RandRWrapper::get( Display* i_pDisplay )
{
    if( ! pWrapper )
        pWrapper = new RandRWrapper( i_pDisplay );
    return *pWrapper;
}

void RandRWrapper::releaseWrapper()
{
    delete pWrapper;
    pWrapper = NULL;
}

#endif

} // namespace

#endif

#include "saldisp.hxx"
#include "salframe.h"

void SalDisplay::InitRandR( XLIB_Window aRoot ) const
{
    #ifdef USE_RANDR
    if( m_bUseRandRWrapper )
        RandRWrapper::get( GetDisplay() ).XRRSelectInput( GetDisplay(), aRoot, RRScreenChangeNotifyMask );
    #else
    (void)aRoot;
    #endif
}

void SalDisplay::DeInitRandR()
{
    #ifdef USE_RANDR
    if( m_bUseRandRWrapper )
        RandRWrapper::releaseWrapper();
#if OSL_DEBUG_LEVEL > 1
    fprintf( stderr, "SalDisplay::DeInitRandR()\n" );
#endif
    #endif
}

int SalDisplay::processRandREvent( XEvent* pEvent )
{
    int nRet = 0;
    #ifdef USE_RANDR
    XConfigureEvent* pCnfEvent=(XConfigureEvent*)pEvent;
    if( m_bUseRandRWrapper && pWrapper && pWrapper->XRRRootToScreen(GetDisplay(),pCnfEvent->window) != -1 )
    {
        nRet = pWrapper->XRRUpdateConfiguration( pEvent );
        if( nRet == 1 && pEvent->type != ConfigureNotify) // this should then be a XRRScreenChangeNotifyEvent
        {
            // update screens
            bool bNotify = false;
            for( size_t i = 0; i < m_aScreens.size(); i++ )
            {
                if( m_aScreens[i].m_bInit )
                {
                    XRRScreenConfiguration *pConfig = NULL;
                    XRRScreenSize *pSizes = NULL;
                    int nSizes = 0;
                    Rotation nRot = 0;
                    SizeID nId = 0;

                    pConfig = pWrapper->XRRGetScreenInfo( GetDisplay(), m_aScreens[i].m_aRoot );
                    nId = pWrapper->XRRConfigCurrentConfiguration( pConfig, &nRot );
                    pSizes = pWrapper->XRRConfigSizes( pConfig, &nSizes );
                    XRRScreenSize *pTargetSize = pSizes + nId;

                    bNotify = bNotify ||
                              m_aScreens[i].m_aSize.Width() != pTargetSize->width ||
                              m_aScreens[i].m_aSize.Height() != pTargetSize->height;

                    m_aScreens[i].m_aSize = Size( pTargetSize->width, pTargetSize->height );

                    pWrapper->XRRFreeScreenConfigInfo( pConfig );

                    #if OSL_DEBUG_LEVEL > 1
                    fprintf( stderr, "screen %d changed to size %dx%d\n", (int)i, (int)pTargetSize->width, (int)pTargetSize->height );
                    #endif
                }
            }
            if( bNotify && ! m_aFrames.empty() )
                m_aFrames.front()->CallCallback( SALEVENT_DISPLAYCHANGED, 0 );
        }
    }
    #else
    (void)pEvent;
    #endif
    return nRet;
}
<|endoftext|>


<commit_before>Bool_t ConfigPhiLeading(
 AliRsnMiniAnalysisTask *task,
 Bool_t isMC = kFALSE,
 Bool_t isPP = kFALSE,
 Double_t nSigmaPart1TPC = -1,
 Double_t nSigmaPart2TPC = -1,
 Double_t nSigmaPart1TOF = -1,
 Double_t nSigmaPart2TOF = -1
 )
{

    // -- Values ------------------------------------------------------------------------------------
    /* invariant mass   */ Int_t imID = task->CreateValue(AliRsnMiniValue::kInvMass, kFALSE);
    /* transv. momentum */ Int_t ptID = task->CreateValue(AliRsnMiniValue::kPt, kFALSE);
    /* angel to leading */ Int_t alID = task->CreateValue(AliRsnMiniValue::kAngleLeading, kFALSE);
    /* pt of leading    */ Int_t ptlID = task->CreateValue(AliRsnMiniValue::kLeadingPt, kFALSE);
    /* multiplicity     */ Int_t multID = task->CreateValue(AliRsnMiniValue::kMult,kFALSE);

            AliRsnCutSet           *cutsPair;
			Int_t                  Strcut = 2011;
			Int_t                  customQualityCutsID = AliRsnCutSetDaughterParticle::kDisableCustom;
			AliRsnCutSetDaughterParticle::ERsnDaughterCutSet cutKaCandidate=AliRsnCutSetDaughterParticle::kTPCTOFpidphipp2015;
  // set daughter cuts
  AliRsnCutSetDaughterParticle* cutSetK;
  AliRsnCutTrackQuality* trkQualityCut= new AliRsnCutTrackQuality("myQualityCut");
  if(!trkQualityCut) return kFALSE;

    cutSetK=new AliRsnCutSetDaughterParticle(Form("cutK%i_%2.1fsigma",cutKaCandidate, nSigmaPart1TPC),trkQualityCut,cutKaCandidate,AliPID::kKaon,nSigmaPart1TPC,nSigmaPart1TOF);

  Int_t iTrackCutK  = task->AddTrackCuts(cutSetK);

    // Cuts
/*
    TString scheme;
    AliRsnCutSet *cutSetKaon = new AliRsnCutSet("kaonCutSet", AliRsnTarget::kDaughter);

    AliRsnCutTrackQuality *trkQualityCut = new AliRsnCutTrackQuality("trackQualityCut");
    trkQualityCut->SetDefaults2011(kTRUE, kTRUE);
AliRsnCutSetDaughterParticle::ERsnDaughterCutSet cutKaCandidate=AliRsnCutSetDaughterParticle::kTPCpidTOFveto3s
    cutSetK=new AliRsnCutSetDaughterParticle(Form("cutK%i_%2.1fsigma",cutKaCandidate, nsigmaK),trkQualityCut,cutKaCandidate,AliPID::kKaon,nSigmaPart1TPC,nSigmaPart1TOF);

    cutSetKaon->AddCut(trkQualityCut);
    if (!scheme.IsNull())
        scheme += "&";
    scheme += trkQualityCut->GetName();

    if (nSigmaPart1 >= 0)
    {
        AliRsnCutPIDNSigma *cutKTPC = new AliRsnCutPIDNSigma("cutNSigmaTPCK", AliPID::kKaon, AliRsnCutPIDNSigma::kTPC);
        cutKTPC->SinglePIDRange(nSigmaPart1);
        cutSetKaon->AddCut(cutKTPC);
        if (!scheme.IsNull())
            scheme += "&";
        scheme += cutKTPC->GetName();
    }
    cutSetKaon->SetCutScheme(scheme.Data());

    Int_t iTrackCutK = task->AddTrackCuts(cutSetKaon);
*/
    // Defining output objects
    const Int_t dims = 6;
    Int_t useIM[dims] = {1, 1, 1, 1, isMC, isMC};
    TString name[dims] = {"Unlike", "Mixing", "LikePP", "LikeMM", "True", "Mother"};
    TString comp[dims] = {"PAIR", "MIX", "PAIR", "PAIR", "TRUE", "MOTHER"};
    TString output[dims] = {"SPARSE", "SPARSE", "SPARSE", "SPARSE", "SPARSE", "SPARSE"};
    Char_t charge1[dims] = {'+', '+', '+', '-', '+', '+'};
    Char_t charge2[dims] = {'-', '-', '+', '-', '-', '-'};
    Int_t pdgCode[dims] = {333, 333, 333, 333, 333, 333};
    Double_t motherMass[dims] = {1.019461, 1.019461, 1.019461, 1.019461, 1.019461, 1.019461};

    for (Int_t i = 0; i < dims; i++)
    {
        if (!useIM[i])
            continue;
        AliRsnMiniOutput *out = task->CreateOutput(name[i].Data(), output[i].Data(), comp[i].Data());
        out->SetCutID(0, iTrackCutK);
        out->SetCutID(1, iTrackCutK);
        out->SetDaughter(0, AliRsnDaughter::kKaon);
        out->SetDaughter(1, AliRsnDaughter::kKaon);
        out->SetCharge(0, charge1[i]);
        out->SetCharge(1, charge2[i]);
        out->SetMotherPDG(pdgCode[i]);
        out->SetMotherMass(motherMass[i]);

        out->AddAxis(imID, 215, 0.985, 1.2);
        out->AddAxis(ptID, 40, 0., 20.);
        if(!isPP ) out->AddAxis(multID,100,0.,100.);
        else out->AddAxis(multID, 10, 0., 100.);

        out->AddAxis(alID, 36, -0.5 * TMath::Pi(), 1.5 * TMath::Pi());
        out->AddAxis(ptlID, 40, 0., 20.);

    }
    return kTRUE;
}

<commit_msg>TPC TOF upgrade<commit_after>Bool_t ConfigPhiLeading(
 AliRsnMiniAnalysisTask *task,
 Bool_t isMC = kFALSE,
 Bool_t isPP = kFALSE,
 Double_t nSigmaPart1TPC = -1,
 Double_t nSigmaPart2TPC = -1,
 Double_t nSigmaPart1TOF = -1,
 Double_t nSigmaPart2TOF = -1
 )
{
    // -- Values ------------------------------------------------------------------------------------
    /* invariant mass   */ Int_t imID = task->CreateValue(AliRsnMiniValue::kInvMass, kFALSE);
    /* transv. momentum */ Int_t ptID = task->CreateValue(AliRsnMiniValue::kPt, kFALSE);
    /* angel to leading */ Int_t alID = task->CreateValue(AliRsnMiniValue::kAngleLeading, kFALSE);
    /* pt of leading    */ Int_t ptlID = task->CreateValue(AliRsnMiniValue::kLeadingPt, kFALSE);
    /* multiplicity     */ Int_t multID = task->CreateValue(AliRsnMiniValue::kMult,kFALSE);

            AliRsnCutSet           *cutsPair;
			Int_t                  Strcut = 2011;
			Int_t                  customQualityCutsID = AliRsnCutSetDaughterParticle::kDisableCustom;
			AliRsnCutSetDaughterParticle::ERsnDaughterCutSet cutKaCandidate=AliRsnCutSetDaughterParticle::kTPCTOFpidphipp2015;
  // set daughter cuts
  AliRsnCutSetDaughterParticle* cutSetK;
  AliRsnCutTrackQuality* trkQualityCut= new AliRsnCutTrackQuality("myQualityCut");
  if(!trkQualityCut) return kFALSE;

    cutSetK=new AliRsnCutSetDaughterParticle(Form("cutK%i_%2.1fsigma",cutKaCandidate, nSigmaPart1TPC),trkQualityCut,cutKaCandidate,AliPID::kKaon,nSigmaPart1TPC,nSigmaPart1TOF);

  Int_t iTrackCutK  = task->AddTrackCuts(cutSetK);

    // Cuts
/*
    TString scheme;
    AliRsnCutSet *cutSetKaon = new AliRsnCutSet("kaonCutSet", AliRsnTarget::kDaughter);

    AliRsnCutTrackQuality *trkQualityCut = new AliRsnCutTrackQuality("trackQualityCut");
    trkQualityCut->SetDefaults2011(kTRUE, kTRUE);
AliRsnCutSetDaughterParticle::ERsnDaughterCutSet cutKaCandidate=AliRsnCutSetDaughterParticle::kTPCpidTOFveto3s
    cutSetK=new AliRsnCutSetDaughterParticle(Form("cutK%i_%2.1fsigma",cutKaCandidate, nsigmaK),trkQualityCut,cutKaCandidate,AliPID::kKaon,nSigmaPart1TPC,nSigmaPart1TOF);

    cutSetKaon->AddCut(trkQualityCut);
    if (!scheme.IsNull())
        scheme += "&";
    scheme += trkQualityCut->GetName();

    if (nSigmaPart1 >= 0)
    {
        AliRsnCutPIDNSigma *cutKTPC = new AliRsnCutPIDNSigma("cutNSigmaTPCK", AliPID::kKaon, AliRsnCutPIDNSigma::kTPC);
        cutKTPC->SinglePIDRange(nSigmaPart1);
        cutSetKaon->AddCut(cutKTPC);
        if (!scheme.IsNull())
            scheme += "&";
        scheme += cutKTPC->GetName();
    }
    cutSetKaon->SetCutScheme(scheme.Data());

    Int_t iTrackCutK = task->AddTrackCuts(cutSetKaon);
*/
    // Defining output objects
    const Int_t dims = 6;
    Int_t useIM[dims] = {1, 1, 1, 1, isMC, isMC};
    TString name[dims] = {"Unlike", "Mixing", "LikePP", "LikeMM", "True", "Mother"};
    TString comp[dims] = {"PAIR", "MIX", "PAIR", "PAIR", "TRUE", "MOTHER"};
    TString output[dims] = {"SPARSE", "SPARSE", "SPARSE", "SPARSE", "SPARSE", "SPARSE"};
    Char_t charge1[dims] = {'+', '+', '+', '-', '+', '+'};
    Char_t charge2[dims] = {'-', '-', '+', '-', '-', '-'};
    Int_t pdgCode[dims] = {333, 333, 333, 333, 333, 333};
    Double_t motherMass[dims] = {1.019461, 1.019461, 1.019461, 1.019461, 1.019461, 1.019461};

    for (Int_t i = 0; i < dims; i++)
    {
        if (!useIM[i])
            continue;
        AliRsnMiniOutput *out = task->CreateOutput(name[i].Data(), output[i].Data(), comp[i].Data());
        out->SetCutID(0, iTrackCutK);
        out->SetCutID(1, iTrackCutK);
        out->SetDaughter(0, AliRsnDaughter::kKaon);
        out->SetDaughter(1, AliRsnDaughter::kKaon);
        out->SetCharge(0, charge1[i]);
        out->SetCharge(1, charge2[i]);
        out->SetMotherPDG(pdgCode[i]);
        out->SetMotherMass(motherMass[i]);

        out->AddAxis(imID, 215, 0.985, 1.2);
        out->AddAxis(ptID, 40, 0., 20.);
        if(!isPP ) out->AddAxis(multID,100,0.,100.);
        else out->AddAxis(multID, 10, 0., 100.);

        out->AddAxis(alID, 36, -0.5 * TMath::Pi(), 1.5 * TMath::Pi());
        out->AddAxis(ptlID, 40, 0., 20.);

    }
    return kTRUE;
}

<|endoftext|>


<commit_before>#include "SimpleAmqpClient.h"
#include <gtest/gtest.h>

using namespace AmqpClient;

TEST(connect_success, connect)
{
  Channel::ptr_t channel = Channel::Create("localhost");
}

TEST(connect_bad_host, connect)
{
  EXPECT_THROW(Channel::ptr_t channel = Channel::Create("HostDoesntExist"), std::runtime_error);
}

TEST(connect_bad_auth, connect)
{
  EXPECT_THROW(Channel::ptr_t channel = Channel::Create("localhost", 5672, "baduser", "badpass"), AmqpResponseServerException);
}

TEST(connect_bad_frame_size, connect)
{
  // AMQP Spec says we have a minimum frame size of 4096
  EXPECT_THROW(Channel::ptr_t channel = Channel::Create("localhost", 5672, "guest", "guest", "/", 400), AmqpResponseServerException);
}

TEST(connect_bad_vhost, connect)
{
  EXPECT_THROW(Channel::ptr_t channel = Channel::Create("localhost", 5672, "guest", "guest", "nonexitant_vhost"), AmqpResponseServerException);
}<commit_msg>Made test_connect cases expect correct exceptions<commit_after>#include "SimpleAmqpClient.h"
#include <gtest/gtest.h>

using namespace AmqpClient;

TEST(connect_success, connect)
{
  Channel::ptr_t channel = Channel::Create("localhost");
}

TEST(connect_bad_host, connect)
{
  EXPECT_THROW(Channel::ptr_t channel = Channel::Create("HostDoesntExist"), std::runtime_error);
}

TEST(connect_bad_auth, connect)
{
  EXPECT_THROW(Channel::ptr_t channel = Channel::Create("localhost", 5672, "baduser", "badpass"), AmqpResponseLibraryException);
}

TEST(connect_bad_frame_size, connect)
{
  // AMQP Spec says we have a minimum frame size of 4096
  EXPECT_THROW(Channel::ptr_t channel = Channel::Create("localhost", 5672, "guest", "guest", "/", 400), AmqpResponseLibraryException);
}

TEST(connect_bad_vhost, connect)
{
  EXPECT_THROW(Channel::ptr_t channel = Channel::Create("localhost", 5672, "guest", "guest", "nonexitant_vhost"), AmqpResponseLibraryException);
}<|endoftext|>


<commit_before>#include "output_compressed.hpp"
#include "inspect.hpp"
#include "ast.hpp"
#include "context.hpp"
#include "to_string.hpp"
#include "util.hpp"
#include <cmath>
#include <iomanip>

namespace Sass {
  using namespace std;

  Output_Compressed::Output_Compressed(Context* ctx) : buffer(""), rendered_imports(""), ctx(ctx) { }
  Output_Compressed::~Output_Compressed() { }

  inline void Output_Compressed::fallback_impl(AST_Node* n)
  {
    Inspect i(ctx);
    n->perform(&i);
    buffer += i.get_buffer();
  }

  void Output_Compressed::operator()(Import* imp)
  {
    Inspect insp(ctx);
    imp->perform(&insp);
    rendered_imports += insp.get_buffer();
  }

  void Output_Compressed::operator()(Block* b)
  {
    if (!b->is_root()) return;
    for (size_t i = 0, L = b->length(); i < L; ++i) {
      (*b)[i]->perform(this);
    }
  }

  void Output_Compressed::operator()(Ruleset* r)
  {
    Selector* s     = r->selector();
    Block*    b     = r->block();

    // Filter out rulesets that aren't printable (process its children though)
    if (!Util::isPrintable(r)) {
      for (size_t i = 0, L = b->length(); i < L; ++i) {
        Statement* stm = (*b)[i];
        if (dynamic_cast<Has_Block*>(stm)) {
          stm->perform(this);
        }
      }
      return;
    }

    if (b->has_non_hoistable()) {
      s->perform(this);
      append_singleline_part_to_buffer("{");
      for (size_t i = 0, L = b->length(); i < L; ++i) {
        Statement* stm = (*b)[i];
        if (!stm->is_hoistable()) {
          stm->perform(this);
        }
      }
      size_t l = buffer.length();
      buffer.erase(l-1);
      append_singleline_part_to_buffer("}");
    }

    if (b->has_hoistable()) {
      for (size_t i = 0, L = b->length(); i < L; ++i) {
        Statement* stm = (*b)[i];
        if (stm->is_hoistable()) {
          stm->perform(this);
        }
      }
    }
  }

  void Output_Compressed::operator()(Media_Block* m)
  {
    List*  q     = m->media_queries();
    Block* b     = m->block();

    // Filter out media blocks that aren't printable (process its children though)
    if (!Util::isPrintable(m)) {
      for (size_t i = 0, L = b->length(); i < L; ++i) {
        Statement* stm = (*b)[i];
        if (dynamic_cast<Has_Block*>(stm)) {
          stm->perform(this);
        }
      }
      return;
    }

    ctx->source_map.add_mapping(m);
    append_singleline_part_to_buffer("@media ");
    q->perform(this);
    append_singleline_part_to_buffer("{");

    Selector* e = m->selector();
    if (e && b->has_non_hoistable()) {
      // JMA - hoisted, output the non-hoistable in a nested block, followed by the hoistable
      e->perform(this);
      append_singleline_part_to_buffer("{");

      for (size_t i = 0, L = b->length(); i < L; ++i) {
        Statement* stm = (*b)[i];
        if (!stm->is_hoistable()) {
          stm->perform(this);
        }
      }

      append_singleline_part_to_buffer("}");

      for (size_t i = 0, L = b->length(); i < L; ++i) {
        Statement* stm = (*b)[i];
        if (stm->is_hoistable()) {
          stm->perform(this);
        }
      }
    }
    else {
      // JMA - not hoisted, just output in order
      for (size_t i = 0, L = b->length(); i < L; ++i) {
        Statement* stm = (*b)[i];
        if (!stm->is_hoistable()) {
          stm->perform(this);
        }
      }
    }

    append_singleline_part_to_buffer("}");
  }

  void Output_Compressed::operator()(At_Rule* a)
  {
    string      kwd   = a->keyword();
    Selector*   s     = a->selector();
    Expression* v     = a->value();
    Block*      b     = a->block();

    append_singleline_part_to_buffer(kwd);
    if (s) {
      append_singleline_part_to_buffer(" ");
      s->perform(this);
    }
    else if (v) {
      append_singleline_part_to_buffer(" ");
      v->perform(this);
    }

    if (!b) {
      append_singleline_part_to_buffer(";");
      return;
    }

    append_singleline_part_to_buffer("{");
    for (size_t i = 0, L = b->length(); i < L; ++i) {
      Statement* stm = (*b)[i];
      if (!stm->is_hoistable()) {
        stm->perform(this);
      }
    }

    for (size_t i = 0, L = b->length(); i < L; ++i) {
      Statement* stm = (*b)[i];
      if (stm->is_hoistable()) {
        stm->perform(this);
      }
    }

    append_singleline_part_to_buffer("}");
  }

  void Output_Compressed::operator()(Declaration* d)
  {
    bool bPrintExpression = true;
    // Check print conditions
    if (d->value()->concrete_type() == Expression::NULL_VAL) {
      bPrintExpression = false;
    }
    if (d->value()->concrete_type() == Expression::STRING) {
      String_Constant* valConst = static_cast<String_Constant*>(d->value());
      string val(valConst->value());
      if (val.empty()) {
        bPrintExpression = false;
      }
    }
    // Print if OK
    if(bPrintExpression) {
      if (ctx) ctx->source_map.add_mapping(d->property());
      d->property()->perform(this);
      append_singleline_part_to_buffer(":");
      if (ctx) ctx->source_map.add_mapping(d->value());
      d->value()->perform(this);
      if (d->is_important()) append_singleline_part_to_buffer("!important");
      append_singleline_part_to_buffer(";");
    }
  }

  void Output_Compressed::operator()(Comment* c)
  {
    To_String to_string;
    string txt = c->text()->perform(&to_string);
    if(txt[2] != '!') {
      return;
    }
    else {
      Inspect i(ctx);
      c->perform(&i);
      buffer += i.get_buffer();
    }
  }

  void Output_Compressed::operator()(List* list)
  {
    string sep(list->separator() == List::SPACE ? " " : ",");
    if (list->empty()) return;
    Expression* first = (*list)[0];
    bool first_invisible = first->is_invisible();
    if (!first_invisible) first->perform(this);
    for (size_t i = 1, L = list->length(); i < L; ++i) {
      Expression* next = (*list)[i];
      bool next_invisible = next->is_invisible();
      if (i == 1 && !first_invisible && !next_invisible) append_singleline_part_to_buffer(sep);
      else if (!next_invisible)                          append_singleline_part_to_buffer(sep);
      next->perform(this);
    }
  }

  // helper function for serializing colors
  template <size_t range>
  static double cap_channel(double c) {
    if      (c > range) return range;
    else if (c < 0)     return 0;
    else                return c;
  }

  void Output_Compressed::operator()(Color* c)
  {
    stringstream ss;
    double r = round(cap_channel<0xff>(c->r()));
    double g = round(cap_channel<0xff>(c->g()));
    double b = round(cap_channel<0xff>(c->b()));
    double a = cap_channel<1>   (c->a());

    // retain the originally specified color definition if unchanged
    if (!c->disp().empty()) {
      ss << c->disp();
    }
    else if (a >= 1) {
      // see if it's a named color
      int numval = r * 0x10000;
      numval += g * 0x100;
      numval += b;
      if (ctx && ctx->colors_to_names.count(numval)) {
        ss << ctx->colors_to_names[numval];
      }
      else {
        // otherwise output the hex triplet
        ss << '#' << setw(2) << setfill('0');
        ss << hex << setw(2) << static_cast<unsigned long>(r);
        ss << hex << setw(2) << static_cast<unsigned long>(g);
        ss << hex << setw(2) << static_cast<unsigned long>(b);
      }
    }
    else {
      ss << "rgba(";
      ss << static_cast<unsigned long>(r) << ",";
      ss << static_cast<unsigned long>(g) << ",";
      ss << static_cast<unsigned long>(b) << ",";
      ss << a << ')';
    }
    append_singleline_part_to_buffer(ss.str());
  }

  void Output_Compressed::operator()(Media_Query_Expression* mqe)
  {
    if (mqe->is_interpolated()) {
      mqe->feature()->perform(this);
    }
    else {
      append_singleline_part_to_buffer("(");
      mqe->feature()->perform(this);
      if (mqe->value()) {
        append_singleline_part_to_buffer(":");
        mqe->value()->perform(this);
      }
      append_singleline_part_to_buffer(")");
    }
  }

  void Output_Compressed::operator()(Null* n)
  {
    // noop
  }

  void Output_Compressed::operator()(Argument* a)
  {
    if (!a->name().empty()) {
      append_singleline_part_to_buffer(a->name());
      append_singleline_part_to_buffer(":");
    }
    a->value()->perform(this);
    if (a->is_rest_argument()) {
      append_singleline_part_to_buffer("...");
    }
  }

  void Output_Compressed::operator()(Arguments* a)
  {
    append_singleline_part_to_buffer("(");
    if (!a->empty()) {
      (*a)[0]->perform(this);
      for (size_t i = 1, L = a->length(); i < L; ++i) {
        append_singleline_part_to_buffer(",");
        (*a)[i]->perform(this);
      }
    }
    append_singleline_part_to_buffer(")");
  }

  void Output_Compressed::operator()(Complex_Selector* c)
  {
    Compound_Selector*           head = c->head();
    Complex_Selector*            tail = c->tail();
    Complex_Selector::Combinator comb = c->combinator();
    if (head && head->is_empty_reference() && tail)
    {
      tail->perform(this);
      return;
    }
    if (head && !head->is_empty_reference()) head->perform(this);
    switch (comb) {
      case Complex_Selector::ANCESTOR_OF:
        if (tail) append_singleline_part_to_buffer(" ");
        break;
      case Complex_Selector::PARENT_OF:
        append_singleline_part_to_buffer(">");
        break;
      case Complex_Selector::PRECEDES:
        // Apparently need to preserve spaces around this combinator?
        if (head && !head->is_empty_reference()) append_singleline_part_to_buffer(" ");
        append_singleline_part_to_buffer("~");
        if (tail) append_singleline_part_to_buffer(" ");
        break;
      case Complex_Selector::ADJACENT_TO:
        append_singleline_part_to_buffer("+");
        break;
    }
    if (tail) tail->perform(this);
  }

  void Output_Compressed::operator()(Selector_List* g)
  {
    if (g->empty()) return;
    (*g)[0]->perform(this);
    for (size_t i = 1, L = g->length(); i < L; ++i) {
      append_singleline_part_to_buffer(",");
      (*g)[i]->perform(this);
    }
  }

  void Output_Compressed::append_singleline_part_to_buffer(const string& text)
  {
    buffer += text;
    if (ctx) ctx->source_map.update_column(text);
  }

}
<commit_msg>Fixes an edge case when buffer is empty<commit_after>#include "output_compressed.hpp"
#include "inspect.hpp"
#include "ast.hpp"
#include "context.hpp"
#include "to_string.hpp"
#include "util.hpp"
#include <cmath>
#include <iomanip>

namespace Sass {
  using namespace std;

  Output_Compressed::Output_Compressed(Context* ctx) : buffer(""), rendered_imports(""), ctx(ctx) { }
  Output_Compressed::~Output_Compressed() { }

  inline void Output_Compressed::fallback_impl(AST_Node* n)
  {
    Inspect i(ctx);
    n->perform(&i);
    buffer += i.get_buffer();
  }

  void Output_Compressed::operator()(Import* imp)
  {
    Inspect insp(ctx);
    imp->perform(&insp);
    rendered_imports += insp.get_buffer();
  }

  void Output_Compressed::operator()(Block* b)
  {
    if (!b->is_root()) return;
    for (size_t i = 0, L = b->length(); i < L; ++i) {
      (*b)[i]->perform(this);
    }
  }

  void Output_Compressed::operator()(Ruleset* r)
  {
    Selector* s     = r->selector();
    Block*    b     = r->block();

    // Filter out rulesets that aren't printable (process its children though)
    if (!Util::isPrintable(r)) {
      for (size_t i = 0, L = b->length(); i < L; ++i) {
        Statement* stm = (*b)[i];
        if (dynamic_cast<Has_Block*>(stm)) {
          stm->perform(this);
        }
      }
      return;
    }

    if (b->has_non_hoistable()) {
      s->perform(this);
      append_singleline_part_to_buffer("{");
      for (size_t i = 0, L = b->length(); i < L; ++i) {
        Statement* stm = (*b)[i];
        if (!stm->is_hoistable()) {
          stm->perform(this);
        }
      }
      size_t l = buffer.length();
      if (l > 0 && buffer.at(l - 1) == ';') buffer.erase(l - 1);
      append_singleline_part_to_buffer("}");
    }

    if (b->has_hoistable()) {
      for (size_t i = 0, L = b->length(); i < L; ++i) {
        Statement* stm = (*b)[i];
        if (stm->is_hoistable()) {
          stm->perform(this);
        }
      }
    }
  }

  void Output_Compressed::operator()(Media_Block* m)
  {
    List*  q     = m->media_queries();
    Block* b     = m->block();

    // Filter out media blocks that aren't printable (process its children though)
    if (!Util::isPrintable(m)) {
      for (size_t i = 0, L = b->length(); i < L; ++i) {
        Statement* stm = (*b)[i];
        if (dynamic_cast<Has_Block*>(stm)) {
          stm->perform(this);
        }
      }
      return;
    }

    ctx->source_map.add_mapping(m);
    append_singleline_part_to_buffer("@media ");
    q->perform(this);
    append_singleline_part_to_buffer("{");

    Selector* e = m->selector();
    if (e && b->has_non_hoistable()) {
      // JMA - hoisted, output the non-hoistable in a nested block, followed by the hoistable
      e->perform(this);
      append_singleline_part_to_buffer("{");

      for (size_t i = 0, L = b->length(); i < L; ++i) {
        Statement* stm = (*b)[i];
        if (!stm->is_hoistable()) {
          stm->perform(this);
        }
      }

      append_singleline_part_to_buffer("}");

      for (size_t i = 0, L = b->length(); i < L; ++i) {
        Statement* stm = (*b)[i];
        if (stm->is_hoistable()) {
          stm->perform(this);
        }
      }
    }
    else {
      // JMA - not hoisted, just output in order
      for (size_t i = 0, L = b->length(); i < L; ++i) {
        Statement* stm = (*b)[i];
        if (!stm->is_hoistable()) {
          stm->perform(this);
        }
      }
    }

    append_singleline_part_to_buffer("}");
  }

  void Output_Compressed::operator()(At_Rule* a)
  {
    string      kwd   = a->keyword();
    Selector*   s     = a->selector();
    Expression* v     = a->value();
    Block*      b     = a->block();

    append_singleline_part_to_buffer(kwd);
    if (s) {
      append_singleline_part_to_buffer(" ");
      s->perform(this);
    }
    else if (v) {
      append_singleline_part_to_buffer(" ");
      v->perform(this);
    }

    if (!b) {
      append_singleline_part_to_buffer(";");
      return;
    }

    append_singleline_part_to_buffer("{");
    for (size_t i = 0, L = b->length(); i < L; ++i) {
      Statement* stm = (*b)[i];
      if (!stm->is_hoistable()) {
        stm->perform(this);
      }
    }

    for (size_t i = 0, L = b->length(); i < L; ++i) {
      Statement* stm = (*b)[i];
      if (stm->is_hoistable()) {
        stm->perform(this);
      }
    }

    append_singleline_part_to_buffer("}");
  }

  void Output_Compressed::operator()(Declaration* d)
  {
    bool bPrintExpression = true;
    // Check print conditions
    if (d->value()->concrete_type() == Expression::NULL_VAL) {
      bPrintExpression = false;
    }
    if (d->value()->concrete_type() == Expression::STRING) {
      String_Constant* valConst = static_cast<String_Constant*>(d->value());
      string val(valConst->value());
      if (val.empty()) {
        bPrintExpression = false;
      }
    }
    // Print if OK
    if(bPrintExpression) {
      if (ctx) ctx->source_map.add_mapping(d->property());
      d->property()->perform(this);
      append_singleline_part_to_buffer(":");
      if (ctx) ctx->source_map.add_mapping(d->value());
      d->value()->perform(this);
      if (d->is_important()) append_singleline_part_to_buffer("!important");
      append_singleline_part_to_buffer(";");
    }
  }

  void Output_Compressed::operator()(Comment* c)
  {
    To_String to_string;
    string txt = c->text()->perform(&to_string);
    if(txt[2] != '!') {
      return;
    }
    else {
      Inspect i(ctx);
      c->perform(&i);
      buffer += i.get_buffer();
    }
  }

  void Output_Compressed::operator()(List* list)
  {
    string sep(list->separator() == List::SPACE ? " " : ",");
    if (list->empty()) return;
    Expression* first = (*list)[0];
    bool first_invisible = first->is_invisible();
    if (!first_invisible) first->perform(this);
    for (size_t i = 1, L = list->length(); i < L; ++i) {
      Expression* next = (*list)[i];
      bool next_invisible = next->is_invisible();
      if (i == 1 && !first_invisible && !next_invisible) append_singleline_part_to_buffer(sep);
      else if (!next_invisible)                          append_singleline_part_to_buffer(sep);
      next->perform(this);
    }
  }

  // helper function for serializing colors
  template <size_t range>
  static double cap_channel(double c) {
    if      (c > range) return range;
    else if (c < 0)     return 0;
    else                return c;
  }

  void Output_Compressed::operator()(Color* c)
  {
    stringstream ss;
    double r = round(cap_channel<0xff>(c->r()));
    double g = round(cap_channel<0xff>(c->g()));
    double b = round(cap_channel<0xff>(c->b()));
    double a = cap_channel<1>   (c->a());

    // retain the originally specified color definition if unchanged
    if (!c->disp().empty()) {
      ss << c->disp();
    }
    else if (a >= 1) {
      // see if it's a named color
      int numval = r * 0x10000;
      numval += g * 0x100;
      numval += b;
      if (ctx && ctx->colors_to_names.count(numval)) {
        ss << ctx->colors_to_names[numval];
      }
      else {
        // otherwise output the hex triplet
        ss << '#' << setw(2) << setfill('0');
        ss << hex << setw(2) << static_cast<unsigned long>(r);
        ss << hex << setw(2) << static_cast<unsigned long>(g);
        ss << hex << setw(2) << static_cast<unsigned long>(b);
      }
    }
    else {
      ss << "rgba(";
      ss << static_cast<unsigned long>(r) << ",";
      ss << static_cast<unsigned long>(g) << ",";
      ss << static_cast<unsigned long>(b) << ",";
      ss << a << ')';
    }
    append_singleline_part_to_buffer(ss.str());
  }

  void Output_Compressed::operator()(Media_Query_Expression* mqe)
  {
    if (mqe->is_interpolated()) {
      mqe->feature()->perform(this);
    }
    else {
      append_singleline_part_to_buffer("(");
      mqe->feature()->perform(this);
      if (mqe->value()) {
        append_singleline_part_to_buffer(":");
        mqe->value()->perform(this);
      }
      append_singleline_part_to_buffer(")");
    }
  }

  void Output_Compressed::operator()(Null* n)
  {
    // noop
  }

  void Output_Compressed::operator()(Argument* a)
  {
    if (!a->name().empty()) {
      append_singleline_part_to_buffer(a->name());
      append_singleline_part_to_buffer(":");
    }
    a->value()->perform(this);
    if (a->is_rest_argument()) {
      append_singleline_part_to_buffer("...");
    }
  }

  void Output_Compressed::operator()(Arguments* a)
  {
    append_singleline_part_to_buffer("(");
    if (!a->empty()) {
      (*a)[0]->perform(this);
      for (size_t i = 1, L = a->length(); i < L; ++i) {
        append_singleline_part_to_buffer(",");
        (*a)[i]->perform(this);
      }
    }
    append_singleline_part_to_buffer(")");
  }

  void Output_Compressed::operator()(Complex_Selector* c)
  {
    Compound_Selector*           head = c->head();
    Complex_Selector*            tail = c->tail();
    Complex_Selector::Combinator comb = c->combinator();
    if (head && head->is_empty_reference() && tail)
    {
      tail->perform(this);
      return;
    }
    if (head && !head->is_empty_reference()) head->perform(this);
    switch (comb) {
      case Complex_Selector::ANCESTOR_OF:
        if (tail) append_singleline_part_to_buffer(" ");
        break;
      case Complex_Selector::PARENT_OF:
        append_singleline_part_to_buffer(">");
        break;
      case Complex_Selector::PRECEDES:
        // Apparently need to preserve spaces around this combinator?
        if (head && !head->is_empty_reference()) append_singleline_part_to_buffer(" ");
        append_singleline_part_to_buffer("~");
        if (tail) append_singleline_part_to_buffer(" ");
        break;
      case Complex_Selector::ADJACENT_TO:
        append_singleline_part_to_buffer("+");
        break;
    }
    if (tail) tail->perform(this);
  }

  void Output_Compressed::operator()(Selector_List* g)
  {
    if (g->empty()) return;
    (*g)[0]->perform(this);
    for (size_t i = 1, L = g->length(); i < L; ++i) {
      append_singleline_part_to_buffer(",");
      (*g)[i]->perform(this);
    }
  }

  void Output_Compressed::append_singleline_part_to_buffer(const string& text)
  {
    buffer += text;
    if (ctx) ctx->source_map.update_column(text);
  }

}
<|endoftext|>


<commit_before>// Copyright 2015-2019 Elviss Strazdins. All rights reserved.

#ifndef OUZEL_CORE_ENGINE_HPP
#define OUZEL_CORE_ENGINE_HPP

#include <atomic>
#include <chrono>
#include <condition_variable>
#include <functional>
#include <mutex>
#include <thread>
#include <vector>
#include "core/Application.hpp"
#include "core/Timer.hpp"
#include "core/Window.hpp"
#include "graphics/Renderer.hpp"
#include "audio/Audio.hpp"
#include "events/EventDispatcher.hpp"
#include "input/InputManager.hpp"
#include "scene/Scene.hpp"
#include "scene/SceneManager.hpp"
#include "storage/FileSystem.hpp"
#include "assets/Bundle.hpp"
#include "assets/Cache.hpp"
#include "assets/Loader.hpp"
#include "localization/Localization.hpp"
#include "network/Network.hpp"
#include "utils/Ini.hpp"
#include "utils/Log.hpp"
#include "utils/Thread.hpp"

namespace ouzel
{
    std::unique_ptr<Application> main(const std::vector<std::string>& args);

    const std::string SHADER_TEXTURE = "shaderTexture";
    const std::string SHADER_COLOR = "shaderColor";

    const std::string BLEND_NO_BLEND = "blendNoBlend";
    const std::string BLEND_ADD = "blendAdd";
    const std::string BLEND_MULTIPLY = "blendMultiply";
    const std::string BLEND_ALPHA = "blendAlpha";
    const std::string BLEND_SCREEN = "blendScreen";

    const std::string TEXTURE_WHITE_PIXEL = "textureWhitePixel";

    class Engine
    {
    public:
        Engine();
        virtual ~Engine();

        Engine(const Engine&) = delete;
        Engine& operator=(const Engine&) = delete;

        Engine(Engine&&) = delete;
        Engine& operator=(Engine&&) = delete;

        void init();

        inline auto& getArgs() const noexcept { return args; }

        inline Log log(Log::Level level = Log::Level::Info) const { return logger.log(level); }
        inline Logger& getLogger() { return logger; }
        inline const Logger& getLogger() const { return logger; }

        inline storage::FileSystem& getFileSystem() { return fileSystem; }
        inline const storage::FileSystem& getFileSystem() const { return fileSystem; }

        inline EventDispatcher& getEventDispatcher() { return eventDispatcher; }
        inline const EventDispatcher& getEventDispatcher() const { return eventDispatcher; }

        inline assets::Cache& getCache() { return cache; }
        inline const assets::Cache& getCache() const { return cache; }

        inline auto getWindow() const { return window.get(); }

        inline auto getRenderer() const noexcept { return renderer.get(); }
        inline auto getAudio() const noexcept { return audio.get(); }

        inline scene::SceneManager& getSceneManager() { return sceneManager; }
        inline const scene::SceneManager& getSceneManager() const { return sceneManager; }

        inline auto getInputManager() const noexcept { return inputManager.get(); }

        inline Localization& getLocalization() { return localization; }
        inline const Localization& getLocalization() const { return localization; }

        inline network::Network& getNetwork() { return network; }
        inline const network::Network& getNetwork() const { return network; }

        inline auto& getDefaultSettings() const noexcept { return defaultSettings; }
        inline auto& getUserSettings() const noexcept { return userSettings; }

        void start();
        void pause();
        void resume();
        void exit();

        inline bool isPaused() const noexcept { return paused; }
        inline bool isActive() const noexcept { return active; }

        void update();

        void executeOnMainThread(const std::function<void()>& func);

        virtual void openURL(const std::string& url);

        inline bool isScreenSaverEnabled() const noexcept { return screenSaverEnabled; }
        virtual void setScreenSaverEnabled(bool newScreenSaverEnabled);

        inline bool isOneUpdatePerFrame() const noexcept { return oneUpdatePerFrame; }
        inline void setOneUpdatePerFrame(bool value) { oneUpdatePerFrame = value; }

    protected:
        class Command final
        {
        public:
            enum class Type
            {
                Execute,
                OpenUrl,
                SetScreensaverEnabled
            };

            std::function<void()> func;
            std::string url;
            bool enabled = false;
        };

        virtual void engineMain();
        virtual void runOnMainThread(const std::function<void()>& func) = 0;

        Logger logger;
        storage::FileSystem fileSystem;
        EventDispatcher eventDispatcher;
        std::unique_ptr<Window> window;
        std::unique_ptr<graphics::Renderer> renderer;
        std::unique_ptr<audio::Audio> audio;
        std::unique_ptr<input::InputManager> inputManager;
        Localization localization;
        assets::Cache cache;
        assets::Bundle assetBundle;
        scene::SceneManager sceneManager;
        network::Network network;

        ini::Data defaultSettings;
        ini::Data userSettings;

#if !defined(__EMSCRIPTEN__)
        Thread updateThread;
        std::mutex updateMutex;
        std::condition_variable updateCondition;
#endif
        std::chrono::steady_clock::time_point previousUpdateTime;

        std::atomic_bool active{false};
        std::atomic_bool paused{false};
        std::atomic_bool oneUpdatePerFrame{false};

        std::atomic_bool screenSaverEnabled{true};
        std::vector<std::string> args;
    };

    extern Engine* engine;
}

#endif // OUZEL_CORE_ENGINE_HPP
<commit_msg>Use auto for return types of engine's getters<commit_after>// Copyright 2015-2019 Elviss Strazdins. All rights reserved.

#ifndef OUZEL_CORE_ENGINE_HPP
#define OUZEL_CORE_ENGINE_HPP

#include <atomic>
#include <chrono>
#include <condition_variable>
#include <functional>
#include <mutex>
#include <thread>
#include <vector>
#include "core/Application.hpp"
#include "core/Timer.hpp"
#include "core/Window.hpp"
#include "graphics/Renderer.hpp"
#include "audio/Audio.hpp"
#include "events/EventDispatcher.hpp"
#include "input/InputManager.hpp"
#include "scene/Scene.hpp"
#include "scene/SceneManager.hpp"
#include "storage/FileSystem.hpp"
#include "assets/Bundle.hpp"
#include "assets/Cache.hpp"
#include "assets/Loader.hpp"
#include "localization/Localization.hpp"
#include "network/Network.hpp"
#include "utils/Ini.hpp"
#include "utils/Log.hpp"
#include "utils/Thread.hpp"

namespace ouzel
{
    std::unique_ptr<Application> main(const std::vector<std::string>& args);

    const std::string SHADER_TEXTURE = "shaderTexture";
    const std::string SHADER_COLOR = "shaderColor";

    const std::string BLEND_NO_BLEND = "blendNoBlend";
    const std::string BLEND_ADD = "blendAdd";
    const std::string BLEND_MULTIPLY = "blendMultiply";
    const std::string BLEND_ALPHA = "blendAlpha";
    const std::string BLEND_SCREEN = "blendScreen";

    const std::string TEXTURE_WHITE_PIXEL = "textureWhitePixel";

    class Engine
    {
    public:
        Engine();
        virtual ~Engine();

        Engine(const Engine&) = delete;
        Engine& operator=(const Engine&) = delete;

        Engine(Engine&&) = delete;
        Engine& operator=(Engine&&) = delete;

        void init();

        inline auto& getArgs() const noexcept { return args; }

        inline Log log(Log::Level level = Log::Level::Info) const { return logger.log(level); }
        inline auto& getLogger() { return logger; }
        inline auto& getLogger() const { return logger; }

        inline auto& getFileSystem() { return fileSystem; }
        inline const auto& getFileSystem() const { return fileSystem; }

        inline auto& getEventDispatcher() { return eventDispatcher; }
        inline const auto& getEventDispatcher() const { return eventDispatcher; }

        inline auto& getCache() { return cache; }
        inline const auto& getCache() const { return cache; }

        inline auto getWindow() const { return window.get(); }

        inline auto getRenderer() const noexcept { return renderer.get(); }
        inline auto getAudio() const noexcept { return audio.get(); }

        inline auto& getSceneManager() { return sceneManager; }
        inline const auto& getSceneManager() const { return sceneManager; }

        inline auto getInputManager() const noexcept { return inputManager.get(); }

        inline auto& getLocalization() { return localization; }
        inline const auto& getLocalization() const { return localization; }

        inline auto& getNetwork() { return network; }
        inline const auto& getNetwork() const { return network; }

        inline auto& getDefaultSettings() const noexcept { return defaultSettings; }
        inline auto& getUserSettings() const noexcept { return userSettings; }

        void start();
        void pause();
        void resume();
        void exit();

        inline bool isPaused() const noexcept { return paused; }
        inline bool isActive() const noexcept { return active; }

        void update();

        void executeOnMainThread(const std::function<void()>& func);

        virtual void openURL(const std::string& url);

        inline bool isScreenSaverEnabled() const noexcept { return screenSaverEnabled; }
        virtual void setScreenSaverEnabled(bool newScreenSaverEnabled);

        inline bool isOneUpdatePerFrame() const noexcept { return oneUpdatePerFrame; }
        inline void setOneUpdatePerFrame(bool value) { oneUpdatePerFrame = value; }

    protected:
        class Command final
        {
        public:
            enum class Type
            {
                Execute,
                OpenUrl,
                SetScreensaverEnabled
            };

            std::function<void()> func;
            std::string url;
            bool enabled = false;
        };

        virtual void engineMain();
        virtual void runOnMainThread(const std::function<void()>& func) = 0;

        Logger logger;
        storage::FileSystem fileSystem;
        EventDispatcher eventDispatcher;
        std::unique_ptr<Window> window;
        std::unique_ptr<graphics::Renderer> renderer;
        std::unique_ptr<audio::Audio> audio;
        std::unique_ptr<input::InputManager> inputManager;
        Localization localization;
        assets::Cache cache;
        assets::Bundle assetBundle;
        scene::SceneManager sceneManager;
        network::Network network;

        ini::Data defaultSettings;
        ini::Data userSettings;

#if !defined(__EMSCRIPTEN__)
        Thread updateThread;
        std::mutex updateMutex;
        std::condition_variable updateCondition;
#endif
        std::chrono::steady_clock::time_point previousUpdateTime;

        std::atomic_bool active{false};
        std::atomic_bool paused{false};
        std::atomic_bool oneUpdatePerFrame{false};

        std::atomic_bool screenSaverEnabled{true};
        std::vector<std::string> args;
    };

    extern Engine* engine;
}

#endif // OUZEL_CORE_ENGINE_HPP
<|endoftext|>


<commit_before>/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2000, 2010 Oracle and/or its affiliates.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org 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 version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/

#include "precompiled_sfx2.hxx"

#include "preextstl.h"
#include <cppunit/TestAssert.h>
#include <cppunit/TestFixture.h>
#include <cppunit/extensions/HelperMacros.h>
#include <cppunit/plugin/TestPlugIn.h>
#include "postextstl.h"

#include <rtl/ustrbuf.hxx>

#include <com/sun/star/util/DateTime.hpp>
#include <com/sun/star/util/Date.hpp>
#include <com/sun/star/util/Duration.hpp>

#include <sfx2/Metadatable.hxx>
#include <sfx2/XmlIdRegistry.hxx>

using namespace ::com::sun::star;

namespace {

class MetadatableTest
    : public ::CppUnit::TestFixture
{
public:
    virtual void setUp();
    virtual void tearDown();

    void test();

    CPPUNIT_TEST_SUITE(MetadatableTest);
    CPPUNIT_TEST(test);
    CPPUNIT_TEST_SUITE_END();

private:
};

void MetadatableTest::setUp()
{
}

void MetadatableTest::tearDown()
{
}

class MockMetadatable
    : public ::sfx2::Metadatable
{
private:
    ::sfx2::IXmlIdRegistry & m_rRegistry;

public:
    MockMetadatable(::sfx2::IXmlIdRegistry & i_rReg,
            bool const i_isInClip = false)
        : m_rRegistry(i_rReg)
        , m_bInClipboard(i_isInClip), m_bInUndo(false), m_bInContent(true) {}
    bool m_bInClipboard;
    bool m_bInUndo;
    bool m_bInContent;
    virtual bool IsInClipboard() const { return m_bInClipboard; }
    virtual bool IsInUndo() const { return m_bInUndo; }
    virtual bool IsInContent() const { return m_bInContent; }
    virtual ::sfx2::IXmlIdRegistry& GetRegistry() { return m_rRegistry; }
    virtual ::com::sun::star::uno::Reference<
        ::com::sun::star::rdf::XMetadatable > MakeUnoObject() { return 0; }
};

static bool operator==(beans::StringPair p1, beans::StringPair p2)
{
    return p1.First == p2.First && p1.Second == p2.Second;
}

void MetadatableTest::test()
{
    OSL_TRACE("SwMetadatable test(): start\n");
    ::std::auto_ptr< ::sfx2::IXmlIdRegistry > const pReg(
        ::sfx2::createXmlIdRegistry(false) );
    ::std::auto_ptr< ::sfx2::IXmlIdRegistry > const pRegClip(
        ::sfx2::createXmlIdRegistry(true) );

    MockMetadatable m1(*pReg);
    MockMetadatable m2(*pReg);
    MockMetadatable m3(*pReg);
    MockMetadatable m4(*pReg);
    MockMetadatable m5(*pReg);
    ::rtl::OUString empty;
    ::rtl::OUString content( RTL_CONSTASCII_USTRINGPARAM("content.xml") );
    ::rtl::OUString styles( RTL_CONSTASCII_USTRINGPARAM("styles.xml") );
    ::rtl::OUString sid1( RTL_CONSTASCII_USTRINGPARAM("id1") );
    ::rtl::OUString sid2( RTL_CONSTASCII_USTRINGPARAM("id2") );
    ::rtl::OUString sid3( RTL_CONSTASCII_USTRINGPARAM("id3") );
    ::rtl::OUString sid4( RTL_CONSTASCII_USTRINGPARAM("id4") );
    beans::StringPair id1(content, sid1);
    beans::StringPair id2(content, sid2);
    beans::StringPair id3(content, sid3);
    beans::StringPair id4(styles,  sid4);
    beans::StringPair id3e(empty,  sid3);
    beans::StringPair id4e(empty,  sid4);
    m1.SetMetadataReference(id1);
    CPPUNIT_ASSERT_MESSAGE("set failed", m1.GetMetadataReference() == id1);
    try {
        m2.SetMetadataReference(id1);
        CPPUNIT_ASSERT_MESSAGE("set duplicate succeeded", false);
    } catch (lang::IllegalArgumentException) { }
    m1.SetMetadataReference(id1);
    CPPUNIT_ASSERT_MESSAGE("set failed (existing)",
            m1.GetMetadataReference() == id1);
    m1.EnsureMetadataReference();
    CPPUNIT_ASSERT_MESSAGE("ensure failed (existing)",
            m1.GetMetadataReference() == id1);

    m2.EnsureMetadataReference();
    beans::StringPair m2id(m2.GetMetadataReference());
    CPPUNIT_ASSERT_MESSAGE("ensure failed", m2id.Second.getLength());
    m2.EnsureMetadataReference();
    CPPUNIT_ASSERT_MESSAGE("ensure failed (idempotent)",
            m2.GetMetadataReference() == m2id);

    m1.m_bInUndo = true;
    CPPUNIT_ASSERT_MESSAGE("move to undo failed",
            !m1.GetMetadataReference().Second.getLength());

    m1.m_bInUndo = false;
    CPPUNIT_ASSERT_MESSAGE("move from undo failed",
            m1.GetMetadataReference() == id1);

    m1.m_bInUndo = true;
    try {
        m2.SetMetadataReference(id1); // steal!
    } catch (lang::IllegalArgumentException &) {
        CPPUNIT_FAIL("set duplicate to undo failed");
    }
    m1.m_bInUndo = false;
    CPPUNIT_ASSERT_MESSAGE("move from undo: duplicate",
            !m1.GetMetadataReference().Second.getLength());

    m3.RegisterAsCopyOf(m2);
    CPPUNIT_ASSERT_MESSAGE("copy: source", m2.GetMetadataReference() == id1);
    CPPUNIT_ASSERT_MESSAGE("copy: duplicate",
            !m3.GetMetadataReference().Second.getLength());
    m4.RegisterAsCopyOf(m3);
    CPPUNIT_ASSERT_MESSAGE("copy: source", m2.GetMetadataReference() == id1);
    CPPUNIT_ASSERT_MESSAGE("copy: duplicate",
            !m3.GetMetadataReference().Second.getLength());
    CPPUNIT_ASSERT_MESSAGE("copy: duplicate",
            !m4.GetMetadataReference().Second.getLength());
    m2.m_bInUndo = true;
    CPPUNIT_ASSERT_MESSAGE("duplicate to undo",
            m3.GetMetadataReference() == id1);
    CPPUNIT_ASSERT_MESSAGE("duplicate to undo",
            !m2.GetMetadataReference().Second.getLength());
    m2.m_bInUndo = false;
    CPPUNIT_ASSERT_MESSAGE("duplicate from undo",
            m2.GetMetadataReference() == id1);
    CPPUNIT_ASSERT_MESSAGE("duplicate from undo",
            !m3.GetMetadataReference().Second.getLength());

    m4.EnsureMetadataReference(); // new!
    beans::StringPair m4id(m4.GetMetadataReference());
    CPPUNIT_ASSERT_MESSAGE("ensure on duplicate",
            m4id.Second.getLength() && !(m4id == id1));

    MockMetadatable mc1(*pRegClip, true); // in clipboard
    MockMetadatable mc2(*pRegClip, true);
    MockMetadatable mc3(*pRegClip, true);
    MockMetadatable mc4(*pRegClip, true);
    MockMetadatable m2p(*pReg);
    MockMetadatable m3p(*pReg);

    mc1.SetMetadataReference(id2);
    CPPUNIT_ASSERT_MESSAGE("set failed", mc1.GetMetadataReference() == id2);
    try {
        mc2.SetMetadataReference(id2);
        CPPUNIT_FAIL("set duplicate succeeded");
    } catch (lang::IllegalArgumentException) { }
    mc1.SetMetadataReference(id2);
    CPPUNIT_ASSERT_MESSAGE("set failed (existing)",
            mc1.GetMetadataReference() == id2);
    mc1.EnsureMetadataReference();
    CPPUNIT_ASSERT_MESSAGE("ensure failed (existing)",
            mc1.GetMetadataReference() == id2);
    mc2.EnsureMetadataReference();
    beans::StringPair mc2id(mc2.GetMetadataReference());
    CPPUNIT_ASSERT_MESSAGE("ensure failed", mc2id.Second.getLength());
    mc2.EnsureMetadataReference();
    CPPUNIT_ASSERT_MESSAGE("ensure failed (idempotent)",
            mc2.GetMetadataReference() == mc2id);
    mc2.RemoveMetadataReference();
    CPPUNIT_ASSERT_MESSAGE("remove failed",
            !mc2.GetMetadataReference().Second.getLength());

    // set up mc2 as copy of m2 and mc3 as copy of m3
    mc3.RegisterAsCopyOf(m3);
    CPPUNIT_ASSERT_MESSAGE("copy to clipboard (latent)",
            !mc3.GetMetadataReference().Second.getLength() );
    mc2.RegisterAsCopyOf(m2);
    CPPUNIT_ASSERT_MESSAGE("copy to clipboard (non-latent)",
            mc2.GetMetadataReference() == id1);
    // paste mc2 to m2p and mc3 to m3p
    m2p.RegisterAsCopyOf(mc2);
    CPPUNIT_ASSERT_MESSAGE("paste from clipboard (non-latent)",
            !m2p.GetMetadataReference().Second.getLength() );
    m3p.RegisterAsCopyOf(mc3);
    CPPUNIT_ASSERT_MESSAGE("paste from clipboard (latent)",
            !m3p.GetMetadataReference().Second.getLength() );
    // delete m2, m2p, m3
    m2.RemoveMetadataReference();
    CPPUNIT_ASSERT_MESSAGE("remove failed",
            !m2.GetMetadataReference().Second.getLength());
    CPPUNIT_ASSERT_MESSAGE("paste-remove (non-latent)",
            m2p.GetMetadataReference() == id1);
    m2p.RemoveMetadataReference();
    CPPUNIT_ASSERT_MESSAGE("remove failed",
            !m2p.GetMetadataReference().Second.getLength());
    CPPUNIT_ASSERT_MESSAGE("paste-remove2 (non-latent)",
            m3.GetMetadataReference() == id1);
    m3.RemoveMetadataReference();
    CPPUNIT_ASSERT_MESSAGE("remove failed",
            !m3.GetMetadataReference().Second.getLength());
    CPPUNIT_ASSERT_MESSAGE("paste-remove (latent)",
            m3p.GetMetadataReference() == id1);
    // delete mc2
    mc2.SetMetadataReference(beans::StringPair());
    CPPUNIT_ASSERT_MESSAGE("in clipboard becomes non-latent",
            !mc3.GetMetadataReference().Second.getLength() );
    // paste mc2
    m2p.RegisterAsCopyOf(mc2);
    CPPUNIT_ASSERT_MESSAGE("remove-paste",
            !m2p.GetMetadataReference().Second.getLength());
    CPPUNIT_ASSERT_MESSAGE("remove-paste (stolen)",
            m3p.GetMetadataReference() == id1);

    // auto-detect stream
    m5.SetMetadataReference(id3e);
    CPPUNIT_ASSERT_MESSAGE("auto-detect (content)",
            m5.GetMetadataReference() == id3);
    m5.m_bInContent = false;
    m5.SetMetadataReference(id4e);
    CPPUNIT_ASSERT_MESSAGE("auto-detect (styles)",
            m5.GetMetadataReference() == id4);

    OSL_TRACE("sfx2::Metadatable test(): finished\n");
}

CPPUNIT_TEST_SUITE_REGISTRATION(MetadatableTest);

}

CPPUNIT_PLUGIN_IMPLEMENT();

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
<commit_msg>Removing the ext_std masterpiece<commit_after>/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2000, 2010 Oracle and/or its affiliates.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org 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 version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/

#include "precompiled_sfx2.hxx"

#include <cppunit/TestAssert.h>
#include <cppunit/TestFixture.h>
#include <cppunit/extensions/HelperMacros.h>
#include <cppunit/plugin/TestPlugIn.h>

#include <rtl/ustrbuf.hxx>

#include <com/sun/star/util/DateTime.hpp>
#include <com/sun/star/util/Date.hpp>
#include <com/sun/star/util/Duration.hpp>

#include <sfx2/Metadatable.hxx>
#include <sfx2/XmlIdRegistry.hxx>

using namespace ::com::sun::star;

namespace {

class MetadatableTest
    : public ::CppUnit::TestFixture
{
public:
    virtual void setUp();
    virtual void tearDown();

    void test();

    CPPUNIT_TEST_SUITE(MetadatableTest);
    CPPUNIT_TEST(test);
    CPPUNIT_TEST_SUITE_END();

private:
};

void MetadatableTest::setUp()
{
}

void MetadatableTest::tearDown()
{
}

class MockMetadatable
    : public ::sfx2::Metadatable
{
private:
    ::sfx2::IXmlIdRegistry & m_rRegistry;

public:
    MockMetadatable(::sfx2::IXmlIdRegistry & i_rReg,
            bool const i_isInClip = false)
        : m_rRegistry(i_rReg)
        , m_bInClipboard(i_isInClip), m_bInUndo(false), m_bInContent(true) {}
    bool m_bInClipboard;
    bool m_bInUndo;
    bool m_bInContent;
    virtual bool IsInClipboard() const { return m_bInClipboard; }
    virtual bool IsInUndo() const { return m_bInUndo; }
    virtual bool IsInContent() const { return m_bInContent; }
    virtual ::sfx2::IXmlIdRegistry& GetRegistry() { return m_rRegistry; }
    virtual ::com::sun::star::uno::Reference<
        ::com::sun::star::rdf::XMetadatable > MakeUnoObject() { return 0; }
};

static bool operator==(beans::StringPair p1, beans::StringPair p2)
{
    return p1.First == p2.First && p1.Second == p2.Second;
}

void MetadatableTest::test()
{
    OSL_TRACE("SwMetadatable test(): start\n");
    ::std::auto_ptr< ::sfx2::IXmlIdRegistry > const pReg(
        ::sfx2::createXmlIdRegistry(false) );
    ::std::auto_ptr< ::sfx2::IXmlIdRegistry > const pRegClip(
        ::sfx2::createXmlIdRegistry(true) );

    MockMetadatable m1(*pReg);
    MockMetadatable m2(*pReg);
    MockMetadatable m3(*pReg);
    MockMetadatable m4(*pReg);
    MockMetadatable m5(*pReg);
    ::rtl::OUString empty;
    ::rtl::OUString content( RTL_CONSTASCII_USTRINGPARAM("content.xml") );
    ::rtl::OUString styles( RTL_CONSTASCII_USTRINGPARAM("styles.xml") );
    ::rtl::OUString sid1( RTL_CONSTASCII_USTRINGPARAM("id1") );
    ::rtl::OUString sid2( RTL_CONSTASCII_USTRINGPARAM("id2") );
    ::rtl::OUString sid3( RTL_CONSTASCII_USTRINGPARAM("id3") );
    ::rtl::OUString sid4( RTL_CONSTASCII_USTRINGPARAM("id4") );
    beans::StringPair id1(content, sid1);
    beans::StringPair id2(content, sid2);
    beans::StringPair id3(content, sid3);
    beans::StringPair id4(styles,  sid4);
    beans::StringPair id3e(empty,  sid3);
    beans::StringPair id4e(empty,  sid4);
    m1.SetMetadataReference(id1);
    CPPUNIT_ASSERT_MESSAGE("set failed", m1.GetMetadataReference() == id1);
    try {
        m2.SetMetadataReference(id1);
        CPPUNIT_ASSERT_MESSAGE("set duplicate succeeded", false);
    } catch (lang::IllegalArgumentException) { }
    m1.SetMetadataReference(id1);
    CPPUNIT_ASSERT_MESSAGE("set failed (existing)",
            m1.GetMetadataReference() == id1);
    m1.EnsureMetadataReference();
    CPPUNIT_ASSERT_MESSAGE("ensure failed (existing)",
            m1.GetMetadataReference() == id1);

    m2.EnsureMetadataReference();
    beans::StringPair m2id(m2.GetMetadataReference());
    CPPUNIT_ASSERT_MESSAGE("ensure failed", m2id.Second.getLength());
    m2.EnsureMetadataReference();
    CPPUNIT_ASSERT_MESSAGE("ensure failed (idempotent)",
            m2.GetMetadataReference() == m2id);

    m1.m_bInUndo = true;
    CPPUNIT_ASSERT_MESSAGE("move to undo failed",
            !m1.GetMetadataReference().Second.getLength());

    m1.m_bInUndo = false;
    CPPUNIT_ASSERT_MESSAGE("move from undo failed",
            m1.GetMetadataReference() == id1);

    m1.m_bInUndo = true;
    try {
        m2.SetMetadataReference(id1); // steal!
    } catch (lang::IllegalArgumentException &) {
        CPPUNIT_FAIL("set duplicate to undo failed");
    }
    m1.m_bInUndo = false;
    CPPUNIT_ASSERT_MESSAGE("move from undo: duplicate",
            !m1.GetMetadataReference().Second.getLength());

    m3.RegisterAsCopyOf(m2);
    CPPUNIT_ASSERT_MESSAGE("copy: source", m2.GetMetadataReference() == id1);
    CPPUNIT_ASSERT_MESSAGE("copy: duplicate",
            !m3.GetMetadataReference().Second.getLength());
    m4.RegisterAsCopyOf(m3);
    CPPUNIT_ASSERT_MESSAGE("copy: source", m2.GetMetadataReference() == id1);
    CPPUNIT_ASSERT_MESSAGE("copy: duplicate",
            !m3.GetMetadataReference().Second.getLength());
    CPPUNIT_ASSERT_MESSAGE("copy: duplicate",
            !m4.GetMetadataReference().Second.getLength());
    m2.m_bInUndo = true;
    CPPUNIT_ASSERT_MESSAGE("duplicate to undo",
            m3.GetMetadataReference() == id1);
    CPPUNIT_ASSERT_MESSAGE("duplicate to undo",
            !m2.GetMetadataReference().Second.getLength());
    m2.m_bInUndo = false;
    CPPUNIT_ASSERT_MESSAGE("duplicate from undo",
            m2.GetMetadataReference() == id1);
    CPPUNIT_ASSERT_MESSAGE("duplicate from undo",
            !m3.GetMetadataReference().Second.getLength());

    m4.EnsureMetadataReference(); // new!
    beans::StringPair m4id(m4.GetMetadataReference());
    CPPUNIT_ASSERT_MESSAGE("ensure on duplicate",
            m4id.Second.getLength() && !(m4id == id1));

    MockMetadatable mc1(*pRegClip, true); // in clipboard
    MockMetadatable mc2(*pRegClip, true);
    MockMetadatable mc3(*pRegClip, true);
    MockMetadatable mc4(*pRegClip, true);
    MockMetadatable m2p(*pReg);
    MockMetadatable m3p(*pReg);

    mc1.SetMetadataReference(id2);
    CPPUNIT_ASSERT_MESSAGE("set failed", mc1.GetMetadataReference() == id2);
    try {
        mc2.SetMetadataReference(id2);
        CPPUNIT_FAIL("set duplicate succeeded");
    } catch (lang::IllegalArgumentException) { }
    mc1.SetMetadataReference(id2);
    CPPUNIT_ASSERT_MESSAGE("set failed (existing)",
            mc1.GetMetadataReference() == id2);
    mc1.EnsureMetadataReference();
    CPPUNIT_ASSERT_MESSAGE("ensure failed (existing)",
            mc1.GetMetadataReference() == id2);
    mc2.EnsureMetadataReference();
    beans::StringPair mc2id(mc2.GetMetadataReference());
    CPPUNIT_ASSERT_MESSAGE("ensure failed", mc2id.Second.getLength());
    mc2.EnsureMetadataReference();
    CPPUNIT_ASSERT_MESSAGE("ensure failed (idempotent)",
            mc2.GetMetadataReference() == mc2id);
    mc2.RemoveMetadataReference();
    CPPUNIT_ASSERT_MESSAGE("remove failed",
            !mc2.GetMetadataReference().Second.getLength());

    // set up mc2 as copy of m2 and mc3 as copy of m3
    mc3.RegisterAsCopyOf(m3);
    CPPUNIT_ASSERT_MESSAGE("copy to clipboard (latent)",
            !mc3.GetMetadataReference().Second.getLength() );
    mc2.RegisterAsCopyOf(m2);
    CPPUNIT_ASSERT_MESSAGE("copy to clipboard (non-latent)",
            mc2.GetMetadataReference() == id1);
    // paste mc2 to m2p and mc3 to m3p
    m2p.RegisterAsCopyOf(mc2);
    CPPUNIT_ASSERT_MESSAGE("paste from clipboard (non-latent)",
            !m2p.GetMetadataReference().Second.getLength() );
    m3p.RegisterAsCopyOf(mc3);
    CPPUNIT_ASSERT_MESSAGE("paste from clipboard (latent)",
            !m3p.GetMetadataReference().Second.getLength() );
    // delete m2, m2p, m3
    m2.RemoveMetadataReference();
    CPPUNIT_ASSERT_MESSAGE("remove failed",
            !m2.GetMetadataReference().Second.getLength());
    CPPUNIT_ASSERT_MESSAGE("paste-remove (non-latent)",
            m2p.GetMetadataReference() == id1);
    m2p.RemoveMetadataReference();
    CPPUNIT_ASSERT_MESSAGE("remove failed",
            !m2p.GetMetadataReference().Second.getLength());
    CPPUNIT_ASSERT_MESSAGE("paste-remove2 (non-latent)",
            m3.GetMetadataReference() == id1);
    m3.RemoveMetadataReference();
    CPPUNIT_ASSERT_MESSAGE("remove failed",
            !m3.GetMetadataReference().Second.getLength());
    CPPUNIT_ASSERT_MESSAGE("paste-remove (latent)",
            m3p.GetMetadataReference() == id1);
    // delete mc2
    mc2.SetMetadataReference(beans::StringPair());
    CPPUNIT_ASSERT_MESSAGE("in clipboard becomes non-latent",
            !mc3.GetMetadataReference().Second.getLength() );
    // paste mc2
    m2p.RegisterAsCopyOf(mc2);
    CPPUNIT_ASSERT_MESSAGE("remove-paste",
            !m2p.GetMetadataReference().Second.getLength());
    CPPUNIT_ASSERT_MESSAGE("remove-paste (stolen)",
            m3p.GetMetadataReference() == id1);

    // auto-detect stream
    m5.SetMetadataReference(id3e);
    CPPUNIT_ASSERT_MESSAGE("auto-detect (content)",
            m5.GetMetadataReference() == id3);
    m5.m_bInContent = false;
    m5.SetMetadataReference(id4e);
    CPPUNIT_ASSERT_MESSAGE("auto-detect (styles)",
            m5.GetMetadataReference() == id4);

    OSL_TRACE("sfx2::Metadatable test(): finished\n");
}

CPPUNIT_TEST_SUITE_REGISTRATION(MetadatableTest);

}

CPPUNIT_PLUGIN_IMPLEMENT();

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
<|endoftext|>