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

#ifndef OSL_MODULE_H
#include <osl/module.h>
#endif
#ifndef OSL_PROCESS_H
#include <osl/process.h>
#endif
#ifndef RTL_STRING_HXX
#include <rtl/ustrbuf.hxx>
#endif

#include <svunx.h>
#include <prex.h>
#include <X11/Xatom.h>
#include <postx.h>

#include <salinst.hxx>
#include <saldata.hxx>

#include <cstdio>
#include <unistd.h>

using namespace rtl;

typedef SalInstance*(*salFactoryProc)( oslModule pModule);

static oslModule pCloseModule = NULL;

#define DESKTOP_NONE 0
#define DESKTOP_UNKNOWN 1
#define DESKTOP_GNOME 2
#define DESKTOP_KDE 3
#define DESKTOP_CDE 4

static const char * desktop_strings[5] = { "none", "unknown", "GNOME", "KDE", "CDE" };

static SalInstance* tryInstance( const OUString& rModuleBase )
{
    SalInstance* pInst = NULL;

    OUStringBuffer aModName( 128 );
    aModName.appendAscii( SAL_DLLPREFIX"vclplug_" );
    aModName.append( rModuleBase );
    aModName.append( (sal_Int32)SUPD );
    aModName.appendAscii( SAL_DLLPOSTFIX );
    aModName.appendAscii( SAL_DLLEXTENSION );
    OUString aModule = aModName.makeStringAndClear();

    oslModule aMod = osl_loadModule( aModule.pData, SAL_LOADMODULE_DEFAULT );
    if( aMod )
    {
        OUString aSym( RTL_CONSTASCII_USTRINGPARAM( "create_SalInstance" ) );
        salFactoryProc aProc = (salFactoryProc)osl_getSymbol( aMod, aSym.pData );
        if( aProc )
        {
            pInst = aProc( aMod );
#if OSL_DEBUG_LEVEL > 1
            fprintf( stderr, "sal plugin %s produced instance %p\n",
                     OUStringToOString( aModule, RTL_TEXTENCODING_ASCII_US ).getStr(),
                     pInst );
#endif
            if( pInst )
            {
                pCloseModule = aMod;
                GetSalData()->m_pPlugin = aMod;
            }
            else
                osl_unloadModule( aMod );
        }
        else
        {
#if OSL_DEBUG_LEVEL > 1
            fprintf( stderr, "could not load symbol %s from shared object %s\n",
                     OUStringToOString( aSym, RTL_TEXTENCODING_ASCII_US ).getStr(),
                     OUStringToOString( aModule, RTL_TEXTENCODING_ASCII_US ).getStr() );
#endif
            osl_unloadModule( aMod );
        }
    }
#if OSL_DEBUG_LEVEL > 1
    else
        fprintf( stderr, "could not load shared object %s\n",
                 OUStringToOString( aModule, RTL_TEXTENCODING_ASCII_US ).getStr() );
#endif

    return pInst;
}

static bool is_gnome_desktop( Display* pDisplay )
{
    bool ret = false;

    // warning: these checks are coincidental, GNOME does not
    // explicitly advertise itself

    if ( NULL != getenv( "GNOME_DESKTOP_SESSION_ID" ) )
        ret = true;

    if( ! ret )
    {
        Atom nAtom1 = XInternAtom( pDisplay, "GNOME_SM_PROXY", True );
        Atom nAtom2 = XInternAtom( pDisplay, "NAUTILUS_DESKTOP_WINDOW_ID", True );
        if( nAtom1 || nAtom2 )
        {
            int nProperties = 0;
            Atom* pProperties = XListProperties( pDisplay, DefaultRootWindow( pDisplay ), &nProperties );
            if( pProperties && nProperties )
            {
                for( int i = 0; i < nProperties; i++ )
                    if( pProperties[ i ] == nAtom1 ||
                        pProperties[ i ] == nAtom2 )
                {
                    ret = true;
                }
                XFree( pProperties );
            }
        }
    }

    if( ! ret )
    {
        Atom nUTFAtom       = XInternAtom( pDisplay, "UTF8_STRING", True );
        Atom nNetWMNameAtom = XInternAtom( pDisplay, "_NET_WM_NAME", True );
        if( nUTFAtom && nNetWMNameAtom )
        {
            // another, more expensive check: search for a gnome-panel
            XLIB_Window aRoot, aParent, *pChildren = NULL;
            unsigned int nChildren = 0;
            XQueryTree( pDisplay, DefaultRootWindow( pDisplay ),
                        &aRoot, &aParent, &pChildren, &nChildren );
            if( pChildren && nChildren )
            {
                for( unsigned int i = 0; i < nChildren && ! ret; i++ )
                {
                    Atom nType = None;
                    int nFormat = 0;
                    unsigned long nItems = 0, nBytes = 0;
                    unsigned char* pProp = NULL;
                    XGetWindowProperty( pDisplay,
                                        pChildren[i],
                                        nNetWMNameAtom,
                                        0, 8,
                                        False,
                                        nUTFAtom,
                                        &nType,
                                        &nFormat,
                                        &nItems,
                                        &nBytes,
                                        &pProp );
                    if( pProp && nType == nUTFAtom )
                    {
                        OString aWMName( (sal_Char*)pProp );
                        if( aWMName.equalsIgnoreAsciiCase( "gnome-panel" ) )
                            ret = true;
                    }
                    if( pProp )
                        XFree( pProp );
                }
                XFree( pChildren );
            }
        }
    }

    return ret;
}

static bool bWasXError = false;

static inline bool WasXError()
{
    bool bRet = bWasXError;
    bWasXError = false;
    return bRet;
}

extern "C"
{
    static int autodect_error_handler( Display*, XErrorEvent* )
    {
        bWasXError = true;
        return 0;
    }

    typedef int(* XErrorHandler)(Display*,XErrorEvent*);
}

static OUString getNetWMName( Display* pDisplay )
{
    OUString aRet;

    Atom nWmCheck   = XInternAtom( pDisplay, "_NET_SUPPORTING_WM_CHECK", True );
    Atom nWmName    = XInternAtom( pDisplay, "_NET_WM_NAME", True );
    if( nWmName && nWmCheck )
    {
        XLIB_Window         aCheckWin   = None;
        Atom                aRealType   = None;
        int                 nFormat     = 8;
        unsigned long       nItems      = 0;
        unsigned long       nBytesLeft  = 0;
        unsigned char*  pProperty   = NULL;
        XGetWindowProperty( pDisplay,
                            DefaultRootWindow( pDisplay ),
                            nWmCheck,
                            0, 1,
                            False,
                            XA_WINDOW,
                            &aRealType,
                            &nFormat,
                            &nItems,
                            &nBytesLeft,
                            &pProperty );
        if( aRealType == XA_WINDOW && nFormat == 32 && nItems != 0 )
            aCheckWin = *(XLIB_Window*)pProperty;
        if( pProperty )
        {
            XFree( pProperty );
            pProperty = NULL;
        }

        // see if that window really exists and has the check property set
        if( aCheckWin != None )
        {
            // clear error flag
            WasXError();
            // get the property
            XGetWindowProperty( pDisplay,
                                aCheckWin,
                                nWmCheck,
                                0, 1,
                                False,
                                XA_WINDOW,
                                &aRealType,
                                &nFormat,
                                &nItems,
                                &nBytesLeft,
                                &pProperty );
            if( ! WasXError() && aRealType == XA_WINDOW && nFormat == 32 && nItems != 0 && pProperty )
            {
                if( aCheckWin == *(XLIB_Window*)pProperty )
                {
                    XFree( pProperty );
                    pProperty = NULL;
                    XGetWindowProperty( pDisplay,
                                        aCheckWin,
                                        nWmName,
                                        0, 256,
                                        False,
                                        AnyPropertyType,
                                        &aRealType,
                                        &nFormat,
                                        &nItems,
                                        &nBytesLeft,
                                        &pProperty );
                    if( !WasXError() && nItems != 0 && pProperty && *pProperty )
                    {
                        if( aRealType == XA_STRING ) // some WM's use this although the should use UTF8_STRING
                        {
                            aRet = rtl::OStringToOUString( rtl::OString( (sal_Char*)pProperty ), RTL_TEXTENCODING_ISO_8859_1 );
                        }
                        else
                            aRet = rtl::OStringToOUString( rtl::OString( (sal_Char*)pProperty ), RTL_TEXTENCODING_UTF8 );
                    }
                }
            }
            if( pProperty )
            {
                XFree( pProperty );
                pProperty = NULL;
            }
        }
    }
    return aRet;
}

static bool is_kde_desktop( Display* pDisplay )
{
    if ( NULL != getenv( "KDE_FULL_SESSION" ) )
        return true;

    // check for kwin
    rtl::OUString aWM = getNetWMName( pDisplay );
    if( aWM.equalsIgnoreAsciiCaseAscii( "KWin" ) )
        return true;

    return false;
}

static bool is_cde_desktop( Display* pDisplay )
{
    void* pLibrary = NULL;

    Atom nDtAtom = XInternAtom( pDisplay, "_DT_WM_READY", True );
    OUString aPathName( RTL_CONSTASCII_USTRINGPARAM( "file:///usr/dt/lib/libDtSvc.so" ) );
    if( nDtAtom && ( pLibrary = osl_loadModule( aPathName.pData, SAL_LOADMODULE_DEFAULT ) ) )
    {
        osl_unloadModule( (oslModule*)pLibrary );
        return true;
    }

    return false;
}

static const char * get_desktop_environment()
{
    static const char *pRet = NULL;
    static const char *pOverride = getenv( "OOO_FORCE_DESKTOP" );

    if ( pOverride && *pOverride )
    {
        OString aOver( pOverride );

        if ( aOver.equalsIgnoreAsciiCase( "cde" ) )
            pRet = desktop_strings[DESKTOP_CDE];
        if ( aOver.equalsIgnoreAsciiCase( "kde" ) )
            pRet = desktop_strings[DESKTOP_KDE];
        if ( aOver.equalsIgnoreAsciiCase( "gnome" ) )
            pRet = desktop_strings[DESKTOP_GNOME];
        if ( aOver.equalsIgnoreAsciiCase( "none" ) )
            pRet = desktop_strings[DESKTOP_UNKNOWN];
    }

    if ( NULL == pRet )
    {
        // get display to connect to
        const char* pDisplayStr = getenv( "DISPLAY" );
        int nParams = osl_getCommandArgCount();
        OUString aParam;
        OString aBParm;
        for( int i = 0; i < nParams-1; i++ )
        {
            osl_getCommandArg( i, &aParam.pData );
            if( aParam.equalsAscii( "-display" ) || aParam.equalsAscii( "--display" ) )
            {
                osl_getCommandArg( i+1, &aParam.pData );
                aBParm = OUStringToOString( aParam, osl_getThreadTextEncoding() );
                pDisplayStr = aBParm.getStr();
                break;
            }
        }

        // no server at all
        if( ! pDisplayStr || !*pDisplayStr )
            pRet = desktop_strings[DESKTOP_NONE];
        else
        {
            Display* pDisplay = XOpenDisplay( pDisplayStr );
            if( pDisplay )
            {
                XErrorHandler pOldHdl = XSetErrorHandler( autodect_error_handler );

                if ( is_kde_desktop( pDisplay ) )
                    pRet = desktop_strings[DESKTOP_KDE];
                else if ( is_gnome_desktop( pDisplay ) )
                    pRet = desktop_strings[DESKTOP_GNOME];
                else if ( is_cde_desktop( pDisplay ) )
                    pRet = desktop_strings[DESKTOP_CDE];
                else
                    pRet = desktop_strings[DESKTOP_UNKNOWN];

                // set the default handler again
                XSetErrorHandler( pOldHdl );

                XCloseDisplay( pDisplay );
            }
        }
    }

    return pRet;
}

static const char* autodetect_plugin()
{
    const char * desktop = get_desktop_environment();
    const char * pRet = NULL;

    // no server at all: dummy plugin
    if ( desktop == desktop_strings[DESKTOP_NONE] )
        pRet = "dummy";
    else if ( desktop == desktop_strings[DESKTOP_GNOME] )
        pRet = "gtk";
    else if( desktop == desktop_strings[DESKTOP_KDE] )
        pRet = "kde";
    else
        pRet = "gen";

#if OSL_DEBUG_LEVEL > 1
    fprintf( stderr, "plugin autodetection: %s\n", pRet );
#endif

    return pRet;
}

SalInstance *CreateSalInstance()
{
    SalInstance*    pInst = NULL;

    static const char* pUsePlugin = getenv( "SAL_USE_VCLPLUGIN" );

    if( !(pUsePlugin && *pUsePlugin) )
        pUsePlugin = autodetect_plugin();

    if( pUsePlugin && *pUsePlugin )
        pInst = tryInstance( OUString::createFromAscii( pUsePlugin ) );

    // fallback to gen
    if( ! pInst )
        pInst = tryInstance( OUString( RTL_CONSTASCII_USTRINGPARAM( "gen" ) ) );

    if( ! pInst )
    {
        fprintf( stderr, "no suitable windowing system found, exiting.\n" );
        _exit( 1 );
    }

    // acquire SolarMutex
    pInst->AcquireYieldMutex( 1 );

    return pInst;
}

void DestroySalInstance( SalInstance *pInst )
{
    // release SolarMutex
    pInst->ReleaseYieldMutex();

    delete pInst;
    if( pCloseModule )
        osl_unloadModule( pCloseModule );
}

void InitSalData()
{
}

void DeInitSalData()
{
}

void InitSalMain()
{
}

void DeInitSalMain()
{
}

void SalAbort( const XubString& rErrorText )
{
    if( !rErrorText.Len() )
        fprintf( stderr, "Application Error" );
    else
        fprintf( stderr, ByteString( rErrorText, gsl_getSystemTextEncoding() ).GetBuffer() );
    abort();
}

const OUString& SalGetDesktopEnvironment()
{
    static OUString aRet = OStringToOUString(OString(get_desktop_environment()), RTL_TEXTENCODING_ASCII_US);
    return aRet;
}
<commit_msg>#i54458#, #i10000#: Correct my last changes<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: salplug.cxx,v $
 *
 *  $Revision: 1.18 $
 *
 *  last change: $Author: rt $ $Date: 2005-10-27 07:59:29 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

#ifndef OSL_MODULE_H
#include <osl/module.h>
#endif
#ifndef OSL_PROCESS_H
#include <osl/process.h>
#endif
#ifndef RTL_STRING_HXX
#include <rtl/ustrbuf.hxx>
#endif

#include <svunx.h>
#include <prex.h>
#include <X11/Xatom.h>
#include <postx.h>

#include <salinst.hxx>
#include <saldata.hxx>

#include <cstdio>
#include <unistd.h>

using namespace rtl;

typedef SalInstance*(*salFactoryProc)( oslModule pModule);

static oslModule pCloseModule = NULL;

#define DESKTOP_NONE 0
#define DESKTOP_UNKNOWN 1
#define DESKTOP_GNOME 2
#define DESKTOP_KDE 3
#define DESKTOP_CDE 4

static const char * desktop_strings[5] = { "none", "unknown", "GNOME", "KDE", "CDE" };

static SalInstance* tryInstance( const OUString& rModuleBase )
{
    SalInstance* pInst = NULL;

    OUStringBuffer aModName( 128 );
    aModName.appendAscii( SAL_DLLPREFIX"vclplug_" );
    aModName.append( rModuleBase );
    aModName.append( (sal_Int32)SUPD );
    aModName.appendAscii( SAL_DLLPOSTFIX );
    aModName.appendAscii( SAL_DLLEXTENSION );
    OUString aModule = aModName.makeStringAndClear();

    oslModule aMod = osl_loadModule( aModule.pData, SAL_LOADMODULE_DEFAULT );
    if( aMod )
    {
        OUString aSym( RTL_CONSTASCII_USTRINGPARAM( "create_SalInstance" ) );
        salFactoryProc aProc = (salFactoryProc)osl_getSymbol( aMod, aSym.pData );
        if( aProc )
        {
            pInst = aProc( aMod );
#if OSL_DEBUG_LEVEL > 1
            fprintf( stderr, "sal plugin %s produced instance %p\n",
                     OUStringToOString( aModule, RTL_TEXTENCODING_ASCII_US ).getStr(),
                     pInst );
#endif
            if( pInst )
            {
                pCloseModule = aMod;
                GetSalData()->m_pPlugin = aMod;
            }
            else
                osl_unloadModule( aMod );
        }
        else
        {
#if OSL_DEBUG_LEVEL > 1
            fprintf( stderr, "could not load symbol %s from shared object %s\n",
                     OUStringToOString( aSym, RTL_TEXTENCODING_ASCII_US ).getStr(),
                     OUStringToOString( aModule, RTL_TEXTENCODING_ASCII_US ).getStr() );
#endif
            osl_unloadModule( aMod );
        }
    }
#if OSL_DEBUG_LEVEL > 1
    else
        fprintf( stderr, "could not load shared object %s\n",
                 OUStringToOString( aModule, RTL_TEXTENCODING_ASCII_US ).getStr() );
#endif

    return pInst;
}

static bool is_gnome_desktop( Display* pDisplay )
{
    bool ret = false;

    // warning: these checks are coincidental, GNOME does not
    // explicitly advertise itself

    if ( NULL != getenv( "GNOME_DESKTOP_SESSION_ID" ) )
        ret = true;

    if( ! ret )
    {
        Atom nAtom1 = XInternAtom( pDisplay, "GNOME_SM_PROXY", True );
        Atom nAtom2 = XInternAtom( pDisplay, "NAUTILUS_DESKTOP_WINDOW_ID", True );
        if( nAtom1 || nAtom2 )
        {
            int nProperties = 0;
            Atom* pProperties = XListProperties( pDisplay, DefaultRootWindow( pDisplay ), &nProperties );
            if( pProperties && nProperties )
            {
                for( int i = 0; i < nProperties; i++ )
                    if( pProperties[ i ] == nAtom1 ||
                        pProperties[ i ] == nAtom2 )
                {
                    ret = true;
                }
                XFree( pProperties );
            }
        }
    }

    if( ! ret )
    {
        Atom nUTFAtom       = XInternAtom( pDisplay, "UTF8_STRING", True );
        Atom nNetWMNameAtom = XInternAtom( pDisplay, "_NET_WM_NAME", True );
        if( nUTFAtom && nNetWMNameAtom )
        {
            // another, more expensive check: search for a gnome-panel
            XLIB_Window aRoot, aParent, *pChildren = NULL;
            unsigned int nChildren = 0;
            XQueryTree( pDisplay, DefaultRootWindow( pDisplay ),
                        &aRoot, &aParent, &pChildren, &nChildren );
            if( pChildren && nChildren )
            {
                for( unsigned int i = 0; i < nChildren && ! ret; i++ )
                {
                    Atom nType = None;
                    int nFormat = 0;
                    unsigned long nItems = 0, nBytes = 0;
                    unsigned char* pProp = NULL;
                    XGetWindowProperty( pDisplay,
                                        pChildren[i],
                                        nNetWMNameAtom,
                                        0, 8,
                                        False,
                                        nUTFAtom,
                                        &nType,
                                        &nFormat,
                                        &nItems,
                                        &nBytes,
                                        &pProp );
                    if( pProp && nType == nUTFAtom )
                    {
                        OString aWMName( (sal_Char*)pProp );
                        if( aWMName.equalsIgnoreAsciiCase( "gnome-panel" ) )
                            ret = true;
                    }
                    if( pProp )
                        XFree( pProp );
                }
                XFree( pChildren );
            }
        }
    }

    return ret;
}

static bool bWasXError = false;

static inline bool WasXError()
{
    bool bRet = bWasXError;
    bWasXError = false;
    return bRet;
}

extern "C"
{
    static int autodect_error_handler( Display*, XErrorEvent* )
    {
        bWasXError = true;
        return 0;
    }

    typedef int(* XErrorHandler)(Display*,XErrorEvent*);
}

static OUString getNetWMName( Display* pDisplay )
{
    OUString aRet;

    Atom nWmCheck   = XInternAtom( pDisplay, "_NET_SUPPORTING_WM_CHECK", True );
    Atom nWmName    = XInternAtom( pDisplay, "_NET_WM_NAME", True );
    if( nWmName && nWmCheck )
    {
        XLIB_Window         aCheckWin   = None;
        Atom                aRealType   = None;
        int                 nFormat     = 8;
        unsigned long       nItems      = 0;
        unsigned long       nBytesLeft  = 0;
        unsigned char*  pProperty   = NULL;
        XGetWindowProperty( pDisplay,
                            DefaultRootWindow( pDisplay ),
                            nWmCheck,
                            0, 1,
                            False,
                            XA_WINDOW,
                            &aRealType,
                            &nFormat,
                            &nItems,
                            &nBytesLeft,
                            &pProperty );
        if( aRealType == XA_WINDOW && nFormat == 32 && nItems != 0 )
            aCheckWin = *(XLIB_Window*)pProperty;
        if( pProperty )
        {
            XFree( pProperty );
            pProperty = NULL;
        }

        // see if that window really exists and has the check property set
        if( aCheckWin != None )
        {
            // clear error flag
            WasXError();
            // get the property
            XGetWindowProperty( pDisplay,
                                aCheckWin,
                                nWmCheck,
                                0, 1,
                                False,
                                XA_WINDOW,
                                &aRealType,
                                &nFormat,
                                &nItems,
                                &nBytesLeft,
                                &pProperty );
            if( ! WasXError() && aRealType == XA_WINDOW && nFormat == 32 && nItems != 0 && pProperty )
            {
                if( aCheckWin == *(XLIB_Window*)pProperty )
                {
                    XFree( pProperty );
                    pProperty = NULL;
                    XGetWindowProperty( pDisplay,
                                        aCheckWin,
                                        nWmName,
                                        0, 256,
                                        False,
                                        AnyPropertyType,
                                        &aRealType,
                                        &nFormat,
                                        &nItems,
                                        &nBytesLeft,
                                        &pProperty );
                    if( !WasXError() && nItems != 0 && pProperty && *pProperty )
                    {
                        if( aRealType == XA_STRING ) // some WM's use this although the should use UTF8_STRING
                        {
                            aRet = rtl::OStringToOUString( rtl::OString( (sal_Char*)pProperty ), RTL_TEXTENCODING_ISO_8859_1 );
                        }
                        else
                            aRet = rtl::OStringToOUString( rtl::OString( (sal_Char*)pProperty ), RTL_TEXTENCODING_UTF8 );
                    }
                }
            }
            if( pProperty )
            {
                XFree( pProperty );
                pProperty = NULL;
            }
        }
    }
    return aRet;
}

static bool is_kde_desktop( Display* pDisplay )
{
    if ( NULL != getenv( "KDE_FULL_SESSION" ) )
        return true;

    // check for kwin
    rtl::OUString aWM = getNetWMName( pDisplay );
    if( aWM.equalsIgnoreAsciiCaseAscii( "KWin" ) )
        return true;

    return false;
}

static bool is_cde_desktop( Display* pDisplay )
{
    void* pLibrary = NULL;

    Atom nDtAtom = XInternAtom( pDisplay, "_DT_WM_READY", True );
    OUString aPathName( RTL_CONSTASCII_USTRINGPARAM( "file:///usr/dt/lib/libDtSvc.so" ) );
    if( nDtAtom && ( pLibrary = osl_loadModule( aPathName.pData, SAL_LOADMODULE_DEFAULT ) ) )
    {
        osl_unloadModule( (oslModule)pLibrary );
        return true;
    }

    return false;
}

static const char * get_desktop_environment()
{
    static const char *pRet = NULL;
    static const char *pOverride = getenv( "OOO_FORCE_DESKTOP" );

    if ( pOverride && *pOverride )
    {
        OString aOver( pOverride );

        if ( aOver.equalsIgnoreAsciiCase( "cde" ) )
            pRet = desktop_strings[DESKTOP_CDE];
        if ( aOver.equalsIgnoreAsciiCase( "kde" ) )
            pRet = desktop_strings[DESKTOP_KDE];
        if ( aOver.equalsIgnoreAsciiCase( "gnome" ) )
            pRet = desktop_strings[DESKTOP_GNOME];
        if ( aOver.equalsIgnoreAsciiCase( "none" ) )
            pRet = desktop_strings[DESKTOP_UNKNOWN];
    }

    if ( NULL == pRet )
    {
        // get display to connect to
        const char* pDisplayStr = getenv( "DISPLAY" );
        int nParams = osl_getCommandArgCount();
        OUString aParam;
        OString aBParm;
        for( int i = 0; i < nParams-1; i++ )
        {
            osl_getCommandArg( i, &aParam.pData );
            if( aParam.equalsAscii( "-display" ) || aParam.equalsAscii( "--display" ) )
            {
                osl_getCommandArg( i+1, &aParam.pData );
                aBParm = OUStringToOString( aParam, osl_getThreadTextEncoding() );
                pDisplayStr = aBParm.getStr();
                break;
            }
        }

        // no server at all
        if( ! pDisplayStr || !*pDisplayStr )
            pRet = desktop_strings[DESKTOP_NONE];
        else
        {
            Display* pDisplay = XOpenDisplay( pDisplayStr );
            if( pDisplay )
            {
                XErrorHandler pOldHdl = XSetErrorHandler( autodect_error_handler );

                if ( is_kde_desktop( pDisplay ) )
                    pRet = desktop_strings[DESKTOP_KDE];
                else if ( is_gnome_desktop( pDisplay ) )
                    pRet = desktop_strings[DESKTOP_GNOME];
                else if ( is_cde_desktop( pDisplay ) )
                    pRet = desktop_strings[DESKTOP_CDE];
                else
                    pRet = desktop_strings[DESKTOP_UNKNOWN];

                // set the default handler again
                XSetErrorHandler( pOldHdl );

                XCloseDisplay( pDisplay );
            }
        }
    }

    return pRet;
}

static const char* autodetect_plugin()
{
    const char * desktop = get_desktop_environment();
    const char * pRet = NULL;

    // no server at all: dummy plugin
    if ( desktop == desktop_strings[DESKTOP_NONE] )
        pRet = "dummy";
    else if ( desktop == desktop_strings[DESKTOP_GNOME] )
        pRet = "gtk";
    else if( desktop == desktop_strings[DESKTOP_KDE] )
        pRet = "kde";
    else
        pRet = "gen";

#if OSL_DEBUG_LEVEL > 1
    fprintf( stderr, "plugin autodetection: %s\n", pRet );
#endif

    return pRet;
}

SalInstance *CreateSalInstance()
{
    SalInstance*    pInst = NULL;

    static const char* pUsePlugin = getenv( "SAL_USE_VCLPLUGIN" );

    if( !(pUsePlugin && *pUsePlugin) )
        pUsePlugin = autodetect_plugin();

    if( pUsePlugin && *pUsePlugin )
        pInst = tryInstance( OUString::createFromAscii( pUsePlugin ) );

    // fallback to gen
    if( ! pInst )
        pInst = tryInstance( OUString( RTL_CONSTASCII_USTRINGPARAM( "gen" ) ) );

    if( ! pInst )
    {
        fprintf( stderr, "no suitable windowing system found, exiting.\n" );
        _exit( 1 );
    }

    // acquire SolarMutex
    pInst->AcquireYieldMutex( 1 );

    return pInst;
}

void DestroySalInstance( SalInstance *pInst )
{
    // release SolarMutex
    pInst->ReleaseYieldMutex();

    delete pInst;
    if( pCloseModule )
        osl_unloadModule( pCloseModule );
}

void InitSalData()
{
}

void DeInitSalData()
{
}

void InitSalMain()
{
}

void DeInitSalMain()
{
}

void SalAbort( const XubString& rErrorText )
{
    if( !rErrorText.Len() )
        fprintf( stderr, "Application Error" );
    else
        fprintf( stderr, ByteString( rErrorText, gsl_getSystemTextEncoding() ).GetBuffer() );
    abort();
}

const OUString& SalGetDesktopEnvironment()
{
    static OUString aRet = OStringToOUString(OString(get_desktop_environment()), RTL_TEXTENCODING_ASCII_US);
    return aRet;
}
<|endoftext|>


<commit_before>// This file is part of the HörTech Open Master Hearing Aid (openMHA)
// Copyright © 2007 2009 2010 2013 2014 2015 2018 2019 2020 HörTech gGmbH
//
// openMHA is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, version 3 of the License.
//
// openMHA 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 Affero General Public License, version 3 for more details.
//
// You should have received a copy of the GNU Affero General Public License,
// version 3 along with openMHA.  If not, see <http://www.gnu.org/licenses/>.

#include "mha_plugin.hh"
#include "mha_signal.hh"
#include "mha_events.h"
#include "mha_defs.h"
#include "mha_filter.hh"

namespace mconv {
    /**\internal
     * class implements plugin for partitioned convolution.
     * A matrix of impulse responses, filtering n input channels to m output
     * channels, is supported.
     */
    class MConv :  public MHAPlugin::plugin_t<MHAFilter::partitioned_convolution_t>
    {
    public:
        /** Plugin constructor.
         * @param iac handle and function pointers for algorithm communication
         * @param chainname Name of processing chain
         * @param algoname The name by which the chain refers to this algorithm */
        MConv(const algo_comm_t & iac,
              const std::string & chainname,
              const std::string & algoname);
        /** Prepare this plugin for processing.
         * @param mhaconfig Configuration for this plugin (Input/Output parameter)
         * Sample rate, fragment size, number of channels are detailed here. */
        void prepare(mhaconfig_t & mhaconfig);
        void release();
        mha_wave_t* process(mha_wave_t*);
    private:
        /** Update is needed only once, since this plugin allows only
         * change of irs after prepare(). */
        void update();
        /**  This function updates the irs without allowing a change
         * of its size after prepare(). */
        void update_irs();
        /** Number of output channels to produce */
        MHAParser::int_t nchannels_out;
        /** Vector of input channel indices.
         * Each element in this vector identifies the input channel to
         * which to apply the corresponding impulse response in irs. */
        MHAParser::vint_t inch;
        /** Vector of output channel indices.
         * Each element in this vector identifies the output channel to
         * which the result of filtering with the corresponding impulse
         * response in irs is mixed. */
        MHAParser::vint_t outch;
        /** Impulse responses, one per row.  For each row, the
         * corresponding element of inch identifies the source channel,
         * and the corresponding element of outch identifies the target
         * channel. */
        MHAParser::mfloat_t irs;

        /** Number of input channels, set during prepare. */
        unsigned int nchannels_in;

        /** Fragsize, set during prepare, is used as the partition length in the
         * partitioned convolution */
        unsigned int fragsize;

        MHAEvents::patchbay_t<MConv> patchbay;
    };

    MConv::MConv(const algo_comm_t & iac,
                 const std::string & chainname,
                 const std::string & algoname)
        : MHAPlugin::plugin_t<MHAFilter::partitioned_convolution_t>
        ("FFT based FIR filter using partitioned convolution\n"
         "  This plugin filters its input channels using partitioned fast\n"
         "convolution. The variables in this plugin define a sparse matrix of\n"
         "impulse responses. The number of elements in the vectors inch and\n"
         "outch and the number of rows in irs have to be equal.\n", iac),
        nchannels_out("Number of output channels to produce", "1", "[0,["),
        inch("Vector of input channel indices.\n"
             "  Each element in this vector identifies the input channel to\n"
             "which to apply the corresponding impulse response in irs.",
             "[0]", "[0,["),
        outch("Vector of output channel indices.\n"
              "  Each element in this vector identifies the output channel to\n"
              "which the result of filtering with the corresponding impulse\n"
              "response in irs is mixed.", "[0]", "[0,["),
        irs("Impulse responses, one per row.  For each row, the corresponding\n"
            "element of inch identifies the source channel, and the\n"
            "corresponding element of outch identifies the target channel.",
            "[[1]]"),
        nchannels_in(0),
        fragsize(0)
    {
        insert_item("nchannels_out", &nchannels_out);
        insert_item("inch", &inch);
        insert_item("outch", &outch);
        insert_item("irs", &irs);

        patchbay.connect(&irs.writeaccess, this, &MConv::update_irs);
    }

    void MConv::prepare(mhaconfig_t & mhaconfig)
    {
        if (mhaconfig.domain != MHA_WAVEFORM)
            throw MHA_ErrorMsg("Plugin supports waveform processing only.");
        nchannels_in = mhaconfig.channels;
        mhaconfig.channels = nchannels_out.data;
        fragsize = mhaconfig.fragsize;
        update();
        inch.setlock(true);
        outch.setlock(true);
        nchannels_out.setlock(true);
    }

    void MConv::release()
    {
        nchannels_out.setlock(false);
        inch.setlock(false);
        outch.setlock(false);
    }

    void MConv::update()
    {
        if (irs.data.size() != inch.data.size()
            || irs.data.size() != outch.data.size())
            throw MHA_Error(__FILE__, __LINE__,
                            "Sizes of irs (%zu), inch (%zu), and outch (%zu) do not match",
                            irs.data.size(), inch.data.size(), outch.data.size());

        MHAFilter::transfer_function_t tf;
        MHAFilter::transfer_matrix_t tm;
        for (size_t index = 0; index < irs.data.size(); ++index) {
            if (inch.data[index] < 0 || inch.data[index] >= (int)nchannels_in)
                throw MHA_Error(__FILE__,__LINE__,
                                "Source channel index inch[%d]=%d is out of range",
                                int(index), inch.data[index]);
            tf.source_channel_index = inch.data[index];
            if (outch.data[index] < 0 || outch.data[index] >= nchannels_out.data)
                throw MHA_Error(__FILE__,__LINE__,
                                "Target channel index outch[%d]=%d is out of range",
                                int(index), outch.data[index]);
            tf.target_channel_index = outch.data[index];
            tf.impulse_response = irs.data[index];
            tm.push_back(tf);
        }

        if (is_prepared())
            push_config(new MHAFilter::partitioned_convolution_t(fragsize,
                                                             nchannels_in,
                                                             nchannels_out.data,
                                                             tm));
    }

    void MConv::update_irs()
    {
        if (!is_prepared())
            return;
        if (irs.data.size() != inch.data.size()
            || irs.data.size() != outch.data.size())
            throw MHA_Error(__FILE__, __LINE__,
                            "Sizes of irs (%zu), inch (%zu), and outch (%zu) do not match",
                            irs.data.size(), inch.data.size(), outch.data.size());

        MHAFilter::transfer_function_t tf;
        MHAFilter::transfer_matrix_t tm;
        for (size_t index = 0; index < irs.data.size(); ++index) {
            tf.source_channel_index = inch.data[index];
            tf.target_channel_index = outch.data[index];
            tf.impulse_response = irs.data[index];
            tm.push_back(tf);
        }

        push_config(new MHAFilter::partitioned_convolution_t(fragsize,
                                                             nchannels_in,
                                                             nchannels_out.data,
                                                             tm));
    }

    mha_wave_t* MConv::process(mha_wave_t * s_in)
    {
        poll_config();
        mha_wave_t * s_out = cfg->process(s_in);
        return s_out;
    }
}

MHAPLUGIN_CALLBACKS(mconv,mconv::MConv, wave, wave)
MHAPLUGIN_DOCUMENTATION(mconv,
                        "filter",
                        "The plugin {\\em mconv} performs partitioned convolution, using a"
                        " sparse matrix of impulse responses.\n\n"
                        " The partition size used for the partitioned convolution is equal to"
                        " fragsize, the number of samples per channel in one block of audio. "
                        " The impulse responses are separated into partitions, and each partition"
                        " is applied with the appropriate delay. Each partition is applied using the"
                        "overlap-save method. The FFT length used is 2*fragsize."
                        "For efficiency reasons, fragsize should be a power of two.\n\n"
                        " Partitioned convolution is used to reduce the"
                        " overall algorithmic delay of the convolution with a long impulse response."
                        " The overall computational cost of using partitioned convolution is higher"
                        " when compared to convolving the complete impulse response in a single overlap-save"
                        " operation, because longer FFTs are more efficient.\n\n"
                        " This implementation discards impulse response partitions where the coefficients are all zero."
                        )

// Local Variables:
// compile-command: "make"
// c-basic-offset: 4
// indent-tabs-mode: nil
// coding: utf-8-unix
// End:
<commit_msg>Remove questionable statements about partitioned convolution<commit_after>// This file is part of the HörTech Open Master Hearing Aid (openMHA)
// Copyright © 2007 2009 2010 2013 2014 2015 2018 2019 2020 HörTech gGmbH
//
// openMHA is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, version 3 of the License.
//
// openMHA 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 Affero General Public License, version 3 for more details.
//
// You should have received a copy of the GNU Affero General Public License,
// version 3 along with openMHA.  If not, see <http://www.gnu.org/licenses/>.

#include "mha_plugin.hh"
#include "mha_signal.hh"
#include "mha_events.h"
#include "mha_defs.h"
#include "mha_filter.hh"

namespace mconv {
    /**\internal
     * class implements plugin for partitioned convolution.
     * A matrix of impulse responses, filtering n input channels to m output
     * channels, is supported.
     */
    class MConv :  public MHAPlugin::plugin_t<MHAFilter::partitioned_convolution_t>
    {
    public:
        /** Plugin constructor.
         * @param iac handle and function pointers for algorithm communication
         * @param chainname Name of processing chain
         * @param algoname The name by which the chain refers to this algorithm */
        MConv(const algo_comm_t & iac,
              const std::string & chainname,
              const std::string & algoname);
        /** Prepare this plugin for processing.
         * @param mhaconfig Configuration for this plugin (Input/Output parameter)
         * Sample rate, fragment size, number of channels are detailed here. */
        void prepare(mhaconfig_t & mhaconfig);
        void release();
        mha_wave_t* process(mha_wave_t*);
    private:
        /** Update is needed only once, since this plugin allows only
         * change of irs after prepare(). */
        void update();
        /**  This function updates the irs without allowing a change
         * of its size after prepare(). */
        void update_irs();
        /** Number of output channels to produce */
        MHAParser::int_t nchannels_out;
        /** Vector of input channel indices.
         * Each element in this vector identifies the input channel to
         * which to apply the corresponding impulse response in irs. */
        MHAParser::vint_t inch;
        /** Vector of output channel indices.
         * Each element in this vector identifies the output channel to
         * which the result of filtering with the corresponding impulse
         * response in irs is mixed. */
        MHAParser::vint_t outch;
        /** Impulse responses, one per row.  For each row, the
         * corresponding element of inch identifies the source channel,
         * and the corresponding element of outch identifies the target
         * channel. */
        MHAParser::mfloat_t irs;

        /** Number of input channels, set during prepare. */
        unsigned int nchannels_in;

        /** Fragsize, set during prepare, is used as the partition length in the
         * partitioned convolution */
        unsigned int fragsize;

        MHAEvents::patchbay_t<MConv> patchbay;
    };

    MConv::MConv(const algo_comm_t & iac,
                 const std::string & chainname,
                 const std::string & algoname)
        : MHAPlugin::plugin_t<MHAFilter::partitioned_convolution_t>
        ("FFT based FIR filter using partitioned convolution\n"
         "  This plugin filters its input channels using partitioned fast\n"
         "convolution. The variables in this plugin define a sparse matrix of\n"
         "impulse responses. The number of elements in the vectors inch and\n"
         "outch and the number of rows in irs have to be equal.\n", iac),
        nchannels_out("Number of output channels to produce", "1", "[0,["),
        inch("Vector of input channel indices.\n"
             "  Each element in this vector identifies the input channel to\n"
             "which to apply the corresponding impulse response in irs.",
             "[0]", "[0,["),
        outch("Vector of output channel indices.\n"
              "  Each element in this vector identifies the output channel to\n"
              "which the result of filtering with the corresponding impulse\n"
              "response in irs is mixed.", "[0]", "[0,["),
        irs("Impulse responses, one per row.  For each row, the corresponding\n"
            "element of inch identifies the source channel, and the\n"
            "corresponding element of outch identifies the target channel.",
            "[[1]]"),
        nchannels_in(0),
        fragsize(0)
    {
        insert_item("nchannels_out", &nchannels_out);
        insert_item("inch", &inch);
        insert_item("outch", &outch);
        insert_item("irs", &irs);

        patchbay.connect(&irs.writeaccess, this, &MConv::update_irs);
    }

    void MConv::prepare(mhaconfig_t & mhaconfig)
    {
        if (mhaconfig.domain != MHA_WAVEFORM)
            throw MHA_ErrorMsg("Plugin supports waveform processing only.");
        nchannels_in = mhaconfig.channels;
        mhaconfig.channels = nchannels_out.data;
        fragsize = mhaconfig.fragsize;
        update();
        inch.setlock(true);
        outch.setlock(true);
        nchannels_out.setlock(true);
    }

    void MConv::release()
    {
        nchannels_out.setlock(false);
        inch.setlock(false);
        outch.setlock(false);
    }

    void MConv::update()
    {
        if (irs.data.size() != inch.data.size()
            || irs.data.size() != outch.data.size())
            throw MHA_Error(__FILE__, __LINE__,
                            "Sizes of irs (%zu), inch (%zu), and outch (%zu) do not match",
                            irs.data.size(), inch.data.size(), outch.data.size());

        MHAFilter::transfer_function_t tf;
        MHAFilter::transfer_matrix_t tm;
        for (size_t index = 0; index < irs.data.size(); ++index) {
            if (inch.data[index] < 0 || inch.data[index] >= (int)nchannels_in)
                throw MHA_Error(__FILE__,__LINE__,
                                "Source channel index inch[%d]=%d is out of range",
                                int(index), inch.data[index]);
            tf.source_channel_index = inch.data[index];
            if (outch.data[index] < 0 || outch.data[index] >= nchannels_out.data)
                throw MHA_Error(__FILE__,__LINE__,
                                "Target channel index outch[%d]=%d is out of range",
                                int(index), outch.data[index]);
            tf.target_channel_index = outch.data[index];
            tf.impulse_response = irs.data[index];
            tm.push_back(tf);
        }

        if (is_prepared())
            push_config(new MHAFilter::partitioned_convolution_t(fragsize,
                                                             nchannels_in,
                                                             nchannels_out.data,
                                                             tm));
    }

    void MConv::update_irs()
    {
        if (!is_prepared())
            return;
        if (irs.data.size() != inch.data.size()
            || irs.data.size() != outch.data.size())
            throw MHA_Error(__FILE__, __LINE__,
                            "Sizes of irs (%zu), inch (%zu), and outch (%zu) do not match",
                            irs.data.size(), inch.data.size(), outch.data.size());

        MHAFilter::transfer_function_t tf;
        MHAFilter::transfer_matrix_t tm;
        for (size_t index = 0; index < irs.data.size(); ++index) {
            tf.source_channel_index = inch.data[index];
            tf.target_channel_index = outch.data[index];
            tf.impulse_response = irs.data[index];
            tm.push_back(tf);
        }

        push_config(new MHAFilter::partitioned_convolution_t(fragsize,
                                                             nchannels_in,
                                                             nchannels_out.data,
                                                             tm));
    }

    mha_wave_t* MConv::process(mha_wave_t * s_in)
    {
        poll_config();
        mha_wave_t * s_out = cfg->process(s_in);
        return s_out;
    }
}

MHAPLUGIN_CALLBACKS(mconv,mconv::MConv, wave, wave)
MHAPLUGIN_DOCUMENTATION(mconv,
                        "filter",
                        "The plugin {\\em mconv} performs partitioned convolution, using a"
                        " sparse matrix of impulse responses.\n\n"
                        " The partition size used for the partitioned convolution is equal to"
                        " fragsize, the number of samples per channel in one block of audio. "
                        " The impulse responses are separated into partitions, and each partition"
                        " is applied with the appropriate delay. Each partition is applied using the"
                        "overlap-save method. The FFT length used is 2*fragsize."
                        "For efficiency reasons, fragsize should be a power of two.\n\n"
                        " This implementation discards impulse response partitions where the coefficients are all zero."
                        )

// Local Variables:
// compile-command: "make"
// c-basic-offset: 4
// indent-tabs-mode: nil
// coding: utf-8-unix
// End:
<|endoftext|>


<commit_before>// The MIT License (MIT)

// Copyright (c) 2013 lailongwei<lailongwei@126.com>
//
// Permission is hereby granted, free of charge, to any person obtaining a copy of
// this software and associated documentation files (the "Software"), to deal in
// the Software without restriction, including without limitation the rights to
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
// the Software, and to permit persons to whom the Software is furnished to do so,
// subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

#include "llbc/common/Export.h"
#include "llbc/common/BeforeIncl.h"

#include "llbc/core/time/Time.h"

#include "llbc/core/log/LogData.h"
#include "llbc/core/log/LogFormattingInfo.h"
#include "llbc/core/log/LogTimeToken.h"

__LLBC_NS_BEGIN

LLBC_LogTimeToken::LLBC_LogTimeToken()
: _lastFmtTime(0)
, _cacheLen(0)
, _fmtCache("")
{
}

LLBC_LogTimeToken::~LLBC_LogTimeToken()
{
}

int LLBC_LogTimeToken::Initialize(LLBC_LogFormattingInfo *formatter, const LLBC_String &str)
{
    SetFormatter(formatter);
    return LLBC_OK;
}

int LLBC_LogTimeToken::GetType() const
{
    return LLBC_LogTokenType::TimeToken;
}

void LLBC_LogTimeToken::Format(const LLBC_LogData &data, LLBC_String &formattedData) const
{
    // Format non millisecond part.
    int index = static_cast<int>(formattedData.size());
    time_t timeInSecond = static_cast<time_t>(data.logTime / 1000);

    if (timeInSecond != _lastFmtTime)
    {
        struct tm timeStruct;
    #if LLBC_TARGET_PLATFORM_WIN32
        localtime_s(&timeStruct, &timeInSecond);
    #else
        localtime_r(&timeInSecond, &timeStruct);
    #endif
        _lastFmtTime = timeInSecond;
        _cacheLen = strftime(_fmtCache, sizeof(_fmtCache), "%y-%m-%d %H:%M:%S.", &timeStruct);
    }

    formattedData.append(_fmtCache, _cacheLen);

    // Format millisecond part.
    formattedData.append_format("%03llu", data.logTime % 1000);

    LLBC_LogFormattingInfo *formatter = GetFormatter();
    formatter->Format(formattedData, index);
}

__LLBC_NS_END

#include "llbc/common/AfterIncl.h"
<commit_msg>Linux平台编译错误fix<commit_after>// The MIT License (MIT)

// Copyright (c) 2013 lailongwei<lailongwei@126.com>
//
// Permission is hereby granted, free of charge, to any person obtaining a copy of
// this software and associated documentation files (the "Software"), to deal in
// the Software without restriction, including without limitation the rights to
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
// the Software, and to permit persons to whom the Software is furnished to do so,
// subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

#include "llbc/common/Export.h"
#include "llbc/common/BeforeIncl.h"

#include "llbc/core/time/Time.h"

#include "llbc/core/log/LogData.h"
#include "llbc/core/log/LogFormattingInfo.h"
#include "llbc/core/log/LogTimeToken.h"

__LLBC_NS_BEGIN

LLBC_LogTimeToken::LLBC_LogTimeToken()
: _lastFmtTime(0)
, _cacheLen(0)
, _fmtCache{}
{
}

LLBC_LogTimeToken::~LLBC_LogTimeToken()
{
}

int LLBC_LogTimeToken::Initialize(LLBC_LogFormattingInfo *formatter, const LLBC_String &str)
{
    SetFormatter(formatter);
    return LLBC_OK;
}

int LLBC_LogTimeToken::GetType() const
{
    return LLBC_LogTokenType::TimeToken;
}

void LLBC_LogTimeToken::Format(const LLBC_LogData &data, LLBC_String &formattedData) const
{
    // Format non millisecond part.
    int index = static_cast<int>(formattedData.size());
    time_t timeInSecond = static_cast<time_t>(data.logTime / 1000);

    if (timeInSecond != _lastFmtTime)
    {
        struct tm timeStruct;
    #if LLBC_TARGET_PLATFORM_WIN32
        localtime_s(&timeStruct, &timeInSecond);
    #else
        localtime_r(&timeInSecond, &timeStruct);
    #endif
        _lastFmtTime = timeInSecond;
        _cacheLen = strftime(_fmtCache, sizeof(_fmtCache), "%y-%m-%d %H:%M:%S.", &timeStruct);
    }

    formattedData.append(_fmtCache, _cacheLen);

    // Format millisecond part.
    formattedData.append_format("%03llu", data.logTime % 1000);

    LLBC_LogFormattingInfo *formatter = GetFormatter();
    formatter->Format(formattedData, index);
}

__LLBC_NS_END

#include "llbc/common/AfterIncl.h"
<|endoftext|>


<commit_before><commit_msg>implementation of demo_generator<commit_after>/*
*   Copyright 2020 Google LLC
*
*   Licensed under the Apache License, Version 2.0 (the "License");
*   you may not use this file except in compliance with the License.
*   You may obtain a copy of the License at
*
*       https://www.apache.org/licenses/LICENSE-2.0
*
*   Unless required by applicable law or agreed to in writing, software
*   distributed under the License is distributed on an "AS IS" BASIS,
*   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*   See the License for the specific language governing permissions and
*   limitations under the License.
*/

#include <filesystem>
#include <fstream>

#include "../src/proto_value.h"
#include "../src/proto_parser.h"
#include "proto/event_predicate.pb.h"

using ::wireless_android_play_analytics::ProtoValue;
using ::wireless_android_play_analytics::MessageValue;
using ::wireless_android_play_analytics::PrimitiveValue;
using ::wireless_android_play_analytics::EventPredicate;
using ::wireless_android_play_analytics::ProtoParser;

namespace {

std::string Generate(MessageValue* message) {
  const std::vector<ProtoValue*>& message_fields = message->GetFieldsMutable();
  absl::variant<double, float, int, unsigned int, int64_t, uint64_t, bool,
      const google::protobuf::EnumValueDescriptor*, std::string> val;

  // Generate random int_comparator.
  MessageValue* event_matcher = static_cast<MessageValue*>(message_fields[0]);
  if (rand() % 2) {
    std::unique_ptr<ProtoValue> int_comparator =
        absl::make_unique<PrimitiveValue>("int_comparator", 1, 8);

    PrimitiveValue* int_comparator_ptr =
        static_cast<PrimitiveValue*>(int_comparator.get());

    // Generate comment
    if (rand() % 2) {
      int_comparator_ptr->SetCommentBehindField("# randomly generated comment");
    }
    std::vector<std::string> comments_above_field;
    int count = 0;
    while(rand() % 2) {
      comments_above_field.push_back("# randomly generated comment " +
          std::to_string(count++));
    }
    int_comparator_ptr->SetCommentAboveField(comments_above_field);

    int input = rand() % 1000;
    val = input;
    int_comparator_ptr->SetVal(val);

    event_matcher->AddField(std::move(int_comparator));
  }

  // Randomly erase leaf_ui_predicates.
  MessageValue* ui_element_path_predicate = static_cast<MessageValue*>(
      message_fields[2]);
  if (rand() % 2) {
    ui_element_path_predicate->DeleteField(2);
  }
  if (rand() % 2) {
    ui_element_path_predicate->DeleteField(1);
  }

  return message->PrintToTextProto();
}

} // namespace

int main() {
  std::ifstream ifs;
  std::string text_proto;
  EventPredicate event_predicate;

  ifs.open("demo/proto_texts/original_proto_text.txt");

  assert(ifs.good());

  while (ifs.good()) {
    std::string tmp;
    std::getline(ifs, tmp);
    text_proto += tmp + "\n";
  }

  ProtoParser parser(text_proto);

  for(int i = 0; i < 10; ++i) {
    std::unique_ptr<ProtoValue> message = parser.Create(event_predicate);
    std::ofstream outs;
    outs.open("demo/proto_texts/proto_text(" + std::to_string(i) +").txt");
    outs << Generate(static_cast<MessageValue*>(message.get()));
  }

  return 0;
}<|endoftext|>


<commit_before><commit_msg>Re-enable optimal bloom on Intel GPUs.<commit_after><|endoftext|>


<commit_before>#include "rosplan_planning_system/PlannerInterface/LPGPlannerInterface.h"

namespace KCL_rosplan {

	/*-------------*/
	/* constructor */
	/*-------------*/

	LPGPlannerInterface::LPGPlannerInterface(ros::NodeHandle& nh)
	{
		node_handle = &nh;

		plan_server = new actionlib::SimpleActionServer<rosplan_dispatch_msgs::PlanAction>((*node_handle), "start_planning", boost::bind(&PlannerInterface::runPlanningServerAction, this, _1), false);

		// publishing raw planner output
		std::string plannerTopic = "planner_output";
		node_handle->getParam("planner_topic", plannerTopic);
		plan_publisher = node_handle->advertise<std_msgs::String>(plannerTopic, 1, true);

		// start planning action server
		plan_server->start();
	}

	LPGPlannerInterface::~LPGPlannerInterface()
	{
		delete plan_server;
	}

	/**
	 * Runs external commands
	 */
	std::string LPGPlannerInterface::runCommand(std::string cmd) {
		std::string data;
		FILE *stream;
		char buffer[1000];
		stream = popen(cmd.c_str(), "r");
		while ( fgets(buffer, 1000, stream) != NULL )
			data.append(buffer);
		pclose(stream);
		return data;
	}

	/*------------------*/
	/* Plan and process */
	/*------------------*/

	/**
	 * passes the problem to the Planner; the plan to post-processing.
	 */
	bool LPGPlannerInterface::runPlanner() {

		// save problem to file for LPG
		if(use_problem_topic && problem_instance_received) {
			ROS_INFO("KCL: (%s) (%s) Writing problem to file.", ros::this_node::getName().c_str(), problem_name.c_str());
			std::ofstream dest;
			dest.open((problem_path).c_str());
			dest << problem_instance;
			dest.close();
		}

		// prepare the planner command line
		std::string str = planner_command;
		std::size_t dit = str.find("DOMAIN");
		if(dit!=std::string::npos) str.replace(dit,6,domain_path);
		std::size_t pit = str.find("PROBLEM");
		if(pit!=std::string::npos) str.replace(pit,7,problem_path);
        std::string updatePlan = "cp "+data_path+"lpgplan.SOL"+" "+data_path+"plan.pddl";

        // call the planer
		ROS_INFO("KCL: (%s) (%s) Running: %s", ros::this_node::getName().c_str(), problem_name.c_str(),  str.c_str());
		std::string plan = runCommand(str.c_str());
		ROS_INFO("KCL: (%s) (%s) Planning complete", ros::this_node::getName().c_str(), problem_name.c_str());

        // move plan to correct path
        runCommand(updatePlan.c_str());

		// check the planner solved the problem
		std::ifstream planfile;
		planfile.open((data_path + "plan.pddl").c_str());
		std::string line;
		std::stringstream ss;

		int curr, next;
		bool solved = false;
		double planDuration;

		while (std::getline(planfile, line)) {

			if (line.find("0.0", 0) != std::string::npos){
				solved = true;
			}else if (line.find("; ", 0) == std::string::npos) {
                // consume useless lines
            }
            planDuration = 0;
            if ((line.length()>1)){
                ss.str("");
            }
			while (std::getline(planfile, line)) {
				if (line.length()<2)
					break;

				ss << line << std::endl;
			}
			planner_output = ss.str();

		}
		planfile.close();

		if(!solved) ROS_INFO("KCL: (%s) (%s) Plan was unsolvable.", ros::this_node::getName().c_str(), problem_name.c_str());
		else ROS_INFO("KCL: (%s) (%s) Plan was solved.", ros::this_node::getName().c_str(), problem_name.c_str());

		return solved;
	}

} // close namespace

/*-------------*/
/* Main method */
/*-------------*/

int main(int argc, char **argv) {

	srand (static_cast <unsigned> (time(0)));

	ros::init(argc,argv,"rosplan_planner_interface");
	ros::NodeHandle nh("~");

	KCL_rosplan::LPGPlannerInterface pi(nh);

	// subscribe to problem instance
	std::string problemTopic = "problem_instance";
	nh.getParam("problem_topic", problemTopic);
	ros::Subscriber problem_sub = nh.subscribe(problemTopic, 1, &KCL_rosplan::PlannerInterface::problemCallback, dynamic_cast<KCL_rosplan::PlannerInterface*>(&pi));

	// start the planning services
	ros::ServiceServer service1 = nh.advertiseService("planning_server", &KCL_rosplan::PlannerInterface::runPlanningServerDefault, dynamic_cast<KCL_rosplan::PlannerInterface*>(&pi));
	ros::ServiceServer service2 = nh.advertiseService("planning_server_params", &KCL_rosplan::PlannerInterface::runPlanningServerParams, dynamic_cast<KCL_rosplan::PlannerInterface*>(&pi));

	ROS_INFO("KCL: (%s) Ready to receive", ros::this_node::getName().c_str());
	ros::spin();

	return 0;
}
<commit_msg>added inline comment for plan extraction<commit_after>#include "rosplan_planning_system/PlannerInterface/LPGPlannerInterface.h"

namespace KCL_rosplan {

	/*-------------*/
	/* constructor */
	/*-------------*/

	LPGPlannerInterface::LPGPlannerInterface(ros::NodeHandle& nh)
	{
		node_handle = &nh;

		plan_server = new actionlib::SimpleActionServer<rosplan_dispatch_msgs::PlanAction>((*node_handle), "start_planning", boost::bind(&PlannerInterface::runPlanningServerAction, this, _1), false);

		// publishing raw planner output
		std::string plannerTopic = "planner_output";
		node_handle->getParam("planner_topic", plannerTopic);
		plan_publisher = node_handle->advertise<std_msgs::String>(plannerTopic, 1, true);

		// start planning action server
		plan_server->start();
	}

	LPGPlannerInterface::~LPGPlannerInterface()
	{
		delete plan_server;
	}

	/**
	 * Runs external commands
	 */
	std::string LPGPlannerInterface::runCommand(std::string cmd) {
		std::string data;
		FILE *stream;
		char buffer[1000];
		stream = popen(cmd.c_str(), "r");
		while ( fgets(buffer, 1000, stream) != NULL )
			data.append(buffer);
		pclose(stream);
		return data;
	}

	/*------------------*/
	/* Plan and process */
	/*------------------*/

	/**
	 * passes the problem to the Planner; the plan to post-processing.
	 */
	bool LPGPlannerInterface::runPlanner() {

		// save problem to file for LPG
		if(use_problem_topic && problem_instance_received) {
			ROS_INFO("KCL: (%s) (%s) Writing problem to file.", ros::this_node::getName().c_str(), problem_name.c_str());
			std::ofstream dest;
			dest.open((problem_path).c_str());
			dest << problem_instance;
			dest.close();
		}

		// prepare the planner command line
		std::string str = planner_command;
		std::size_t dit = str.find("DOMAIN");
		if(dit!=std::string::npos) str.replace(dit,6,domain_path);
		std::size_t pit = str.find("PROBLEM");
		if(pit!=std::string::npos) str.replace(pit,7,problem_path);
        std::string updatePlan = "cp "+data_path+"lpgplan.SOL"+" "+data_path+"plan.pddl";

        // call the planer
		ROS_INFO("KCL: (%s) (%s) Running: %s", ros::this_node::getName().c_str(), problem_name.c_str(),  str.c_str());
		std::string plan = runCommand(str.c_str());
		ROS_INFO("KCL: (%s) (%s) Planning complete", ros::this_node::getName().c_str(), problem_name.c_str());

        // move plan to correct path
        runCommand(updatePlan.c_str());

		// check the planner solved the problem
		std::ifstream planfile;
		planfile.open((data_path + "plan.pddl").c_str());
		std::string line;
		std::stringstream ss;

		int curr, next;
		bool solved = false;
		double planDuration;

		while (std::getline(planfile, line)) {

			if (line.find("0.0", 0) != std::string::npos){
				solved = true;
			}else if (line.find("; ", 0) == std::string::npos) {
                // consume useless lines
            }
            planDuration = 0;

            // extract second block of uninterrupted lines (the actual plan) from .SOL file content
            if ((line.length()>1)){
                ss.str("");
            }
			while (std::getline(planfile, line)) {
				if (line.length()<2)
					break;

				ss << line << std::endl;
			}
			planner_output = ss.str();

		}
		planfile.close();

		if(!solved) ROS_INFO("KCL: (%s) (%s) Plan was unsolvable.", ros::this_node::getName().c_str(), problem_name.c_str());
		else ROS_INFO("KCL: (%s) (%s) Plan was solved.", ros::this_node::getName().c_str(), problem_name.c_str());

		return solved;
	}

} // close namespace

/*-------------*/
/* Main method */
/*-------------*/

int main(int argc, char **argv) {

	srand (static_cast <unsigned> (time(0)));

	ros::init(argc,argv,"rosplan_planner_interface");
	ros::NodeHandle nh("~");

	KCL_rosplan::LPGPlannerInterface pi(nh);

	// subscribe to problem instance
	std::string problemTopic = "problem_instance";
	nh.getParam("problem_topic", problemTopic);
	ros::Subscriber problem_sub = nh.subscribe(problemTopic, 1, &KCL_rosplan::PlannerInterface::problemCallback, dynamic_cast<KCL_rosplan::PlannerInterface*>(&pi));

	// start the planning services
	ros::ServiceServer service1 = nh.advertiseService("planning_server", &KCL_rosplan::PlannerInterface::runPlanningServerDefault, dynamic_cast<KCL_rosplan::PlannerInterface*>(&pi));
	ros::ServiceServer service2 = nh.advertiseService("planning_server_params", &KCL_rosplan::PlannerInterface::runPlanningServerParams, dynamic_cast<KCL_rosplan::PlannerInterface*>(&pi));

	ROS_INFO("KCL: (%s) Ready to receive", ros::this_node::getName().c_str());
	ros::spin();

	return 0;
}
<|endoftext|>


<commit_before>/*
   Copyright (C) 2013 Nipun Talukdar

   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at

       http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.

*/

#ifndef __GEETCASS_CQL3RESULT__
#define __GEETCASS_CQL3RESULT__
#include <boost/shared_ptr.hpp>
#include <boost/noncopyable.hpp>
#include <bytebuffer.hpp>
#include <cql3cons.hpp>
#include <cql3header.hpp>
#include <encode.hpp>
#include <vector>
using std::vector;

namespace GeetCass
{

struct Column
{
    string column;
    Cql3Types column_type;
    Column(const string& col, Cql3Types type) : column(col), column_type(type)
    {
    }
};

struct Cql3RowMetaData
{
    static void init(ByteBuffer& buffer, Cql3RowMetaData& metadata);
    uint32_t flags;
    uint32_t column_count;
    string global_table_spec[2];
    vector <Column *> columns;
};

class Cql3Row : public boost::noncopyable
{
public:
    Cql3Row(void *buffer = 0, size_t size = 0, Cql3RowMetaData* metadata =0);
///TBD
};

class Cql3Rows
{
public:
    uint32_t getRowCount();
    Cql3Row getNextRow();
    Cql3Row getRow(uint32_t rowNum);
// TBD
private:
    ByteBuffer *_buffer;
    Cql3RowMetaData _metaData;
    size_t _startInByteBuffer;
    size_t _stopInByteBuffer;
    uint32_t _currentRow;
    uint32_t _maxRow;
    vector <int> _rowPositions;
};

class Cql3Result
{

public:
    Cql3Result(ByteBuffer& buffer);
    Cql3Result();
    Cql3Result(const Cql3Result& result);
    Cql3Result& operator=(const Cql3Result& result);
    void setBuffer(ByteBuffer& buffer);
    ResultCode getResultCode() const;
    ~Cql3Result();

private:
    ByteBuffer* _resultData;
    ResultCode _resultCode;
};
}  // GeetCass napespace ends

#endif
<commit_msg>A change<commit_after>/*
   Copyright (C) 2013 Nipun Talukdar

   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at

       http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.

*/

#ifndef __GEETCASS_CQL3RESULT__
#define __GEETCASS_CQL3RESULT__
#include <boost/shared_ptr.hpp>
#include <boost/noncopyable.hpp>
#include <bytebuffer.hpp>
#include <cql3cons.hpp>
#include <cql3header.hpp>
#include <encode.hpp>
#include <vector>
using std::vector;

namespace GeetCass
{

struct Column
{
    string column;
    Cql3Types column_type;
    Column(const string& col, Cql3Types type) : column(col), column_type(type)
    {
    }
};

struct Cql3RowMetaData
{
    static void init(ByteBuffer& buffer, Cql3RowMetaData& metadata);
    uint32_t flags;
    uint32_t column_count;
    string global_table_spec[2];
    vector <Column *> columns;
};

class Cql3Row : public boost::noncopyable
{
public:
    Cql3Row(void *buffer = 0, size_t size = 0, Cql3RowMetaData* metadata =0);

private:
    std::unordered_map<string, size_t > _columnPositions;
    bool getString(const string& column, string& out);
    bool getInt(const string& column, int32_t& val);
///TBD
};

class Cql3Rows
{
public:
    uint32_t getRowCount();
    Cql3Row getNextRow();
    Cql3Row getRow(uint32_t rowNum);
// TBD
private:
    ByteBuffer *_buffer;
    Cql3RowMetaData _metaData;
    size_t _startInByteBuffer;
    size_t _stopInByteBuffer;
    uint32_t _currentRow;
    uint32_t _maxRow;
    vector <int> _rowPositions;
};

class Cql3Result
{

public:
    Cql3Result(ByteBuffer& buffer);
    Cql3Result();
    Cql3Result(const Cql3Result& result);
    Cql3Result& operator=(const Cql3Result& result);
    void setBuffer(ByteBuffer& buffer);
    ResultCode getResultCode() const;
    ~Cql3Result();

private:
    ByteBuffer* _resultData;
    ResultCode _resultCode;
};
}  // GeetCass napespace ends

#endif
<|endoftext|>


<commit_before> /*
  *   jabberprotocol.cpp  -  Base class for the Kopete Jabber protocol
  *
  * Copyright (c) 2002-2003 by Till Gerken <till@tantalo.net>
  * Copyright (c) 2002 by Daniel Stone <dstone@kde.org>
  *
  *  Kopete   (c) by the Kopete developers  <kopete-devel@kde.org>
  *
  * *************************************************************************
  * *                                                                       *
  * * This program is free software; you can redistribute it and/or modify  *
  * * it under the terms of the GNU General Public License as published by  *
  * * the Free Software Foundation; either version 2 of the License, or     *
  * * (at your option) any later version.                                   *
  * *                                                                       *
  * *************************************************************************
  */

#include <kdebug.h>
#include <kgenericfactory.h>
#include <kconfig.h>
#include <kmessagebox.h>
#include <kiconloader.h>
#include <kpopupmenu.h>
#include <kstandarddirs.h>
#include <klineeditdlg.h>

#include <qapplication.h>
#include <qcursor.h>
#include <qmap.h>
#include <qtimer.h>
#include <qpixmap.h>
#include <qstringlist.h>

#include "im.h"
#include "xmpp.h"

#include <sys/utsname.h>

#include "kopetecontact.h"
#include "kopetecontactlist.h"
#include "kopetemetacontact.h"
#include "kopetechatsession.h"
#include "kopeteonlinestatusmanager.h"
#include "kopeteaway.h"
#include "kopeteglobal.h"
#include "kopeteprotocol.h"
#include "kopeteplugin.h"
#include "addcontactpage.h"
#include "jabbercontact.h"
#include "dlgjabbersendraw.h"
#include "dlgjabberservices.h"
#include "dlgjabberchatjoin.h"
#include "jabberaddcontactpage.h"
#include "jabberprotocol.h"
#include "jabberaccount.h"
#include "kopeteaccountmanager.h"
#include "jabbereditaccountwidget.h"
#include "kopetecommandhandler.h"

JabberProtocol *JabberProtocol::protocolInstance = 0;

typedef KGenericFactory<JabberProtocol> JabberProtocolFactory;

K_EXPORT_COMPONENT_FACTORY( kopete_jabber, JabberProtocolFactory( "kopete_jabber" )  )

JabberProtocol::JabberProtocol (QObject * parent, const char *name, const QStringList &)
: Kopete::Protocol( JabberProtocolFactory::instance(), parent, name ),
	JabberKOSChatty(Kopete::OnlineStatus::Online,        100, this, JabberFreeForChat, "jabber_chatty", i18n ("Free for Chat"), i18n ("Free for Chat"), Kopete::OnlineStatusManager::FreeForChat ),
	JabberKOSOnline(Kopete::OnlineStatus::Online,         90, this, JabberOnline, QString::null, i18n ("Online"), i18n ("Online"), Kopete::OnlineStatusManager::Online ),
	JabberKOSAway(Kopete::OnlineStatus::Away,             80, this, JabberAway, "contact_away_overlay", i18n ("Away"), i18n ("Away"), Kopete::OnlineStatusManager::Away, Kopete::OnlineStatusManager::HasAwayMessage),
	JabberKOSXA(Kopete::OnlineStatus::Away,               70, this, JabberXA, "contact_xa_overlay", i18n ("Extended Away"), i18n ("Extended Away"), Kopete::OnlineStatusManager::Away, Kopete::OnlineStatusManager::HasAwayMessage),
	JabberKOSDND(Kopete::OnlineStatus::Away,              60, this, JabberDND, "contact_busy_overlay", i18n ("Do not Disturb"), i18n ("Do not Disturb"), Kopete::OnlineStatusManager::Busy, Kopete::OnlineStatusManager::HasAwayMessage),
	JabberKOSOffline(Kopete::OnlineStatus::Offline,       50, this, JabberOffline, QString::null, i18n ("Offline") ,i18n ("Offline"), Kopete::OnlineStatusManager::Offline ),
	JabberKOSInvisible(Kopete::OnlineStatus::Invisible,   40, this, JabberInvisible, "contact_invisible_overlay",   i18n ("Invisible") ,i18n ("Invisible"), Kopete::OnlineStatusManager::Invisible),
	JabberKOSConnecting(Kopete::OnlineStatus::Connecting, 30, this, JabberConnecting, "jabber_connecting",  i18n("Connecting")),
	propAwayMessage(Kopete::Global::Properties::self()->awayMessage()),
	propFirstName(Kopete::Global::Properties::self()->firstName()),
	propLastName(Kopete::Global::Properties::self()->lastName()),
	propFullName(Kopete::Global::Properties::self()->fullName()),
	propEmailAddress(Kopete::Global::Properties::self()->emailAddress()),
	propPrivatePhone(Kopete::Global::Properties::self()->privatePhone()),
	propPrivateMobilePhone(Kopete::Global::Properties::self()->privateMobilePhone()),
	propWorkPhone(Kopete::Global::Properties::self()->workPhone()),
	propWorkMobilePhone(Kopete::Global::Properties::self()->workMobilePhone()),
	propNickName(Kopete::Global::Properties::self()->nickName()),
	propSubscriptionStatus("jabberSubscriptionStatus", i18n ("Subscription"), QString::null, true, false),
	propAuthorizationStatus("jabberAuthorizationStatus", i18n ("Authorization Status"), QString::null, true, false),
	propAvailableResources("jabberAvailableResources", i18n ("Available Resources"), "jabber_chatty", false, true),
	propVCardCacheTimeStamp("jabberVCardCacheTimeStamp", i18n ("vCard Cache Timestamp"), QString::null, true, false, true)

{

	kdDebug (JABBER_DEBUG_GLOBAL) << "[JabberProtocol] Loading ..." << endl;

	/* This is meant to be a singleton, so we will check if we have
	 * been loaded before. */
	if (protocolInstance)
	{
		kdDebug (JABBER_DEBUG_GLOBAL) << "[JabberProtocol] Warning: Protocol already " << "loaded, not initializing again." << endl;
		return;
	}

	protocolInstance = this;

	addAddressBookField ("messaging/xmpp", Kopete::Plugin::MakeIndexField);
}

JabberProtocol::~JabberProtocol ()
{
	//disconnectAll();

	/* make sure that the next attempt to load Jabber
	 * re-initializes the protocol class. */
	protocolInstance = 0L;
}

AddContactPage *JabberProtocol::createAddContactWidget (QWidget * parent, Kopete::Account * i)
{
	kdDebug (JABBER_DEBUG_GLOBAL) << "[Jabber Protocol] Create Add Contact  Widget\n" << endl;
	return new JabberAddContactPage (i, parent);
}

KopeteEditAccountWidget *JabberProtocol::createEditAccountWidget (Kopete::Account * account, QWidget * parent)
{
	kdDebug (JABBER_DEBUG_GLOBAL) << "[Jabber Protocol] Edit Account Widget\n" << endl;
	return new JabberEditAccountWidget (this, static_cast < JabberAccount * >(account), parent);
}

Kopete::Account *JabberProtocol::createNewAccount (const QString & accountId)
{
	kdDebug (JABBER_DEBUG_GLOBAL) << "[Jabber Protocol] Create New Account. ID: " << accountId << "\n" << endl;
	return new JabberAccount (this, accountId);
}

Kopete::OnlineStatus JabberProtocol::resourceToKOS ( const XMPP::Resource &resource )
{

	// update to offline by default
	Kopete::OnlineStatus status = JabberKOSOffline;

	if ( !resource.status().isAvailable () )
	{
		// resource is offline
		status = JabberKOSOffline;
	}
	else
	{
		if (resource.status ().show ().isEmpty ())
		{
			if (resource.status ().isInvisible ())
			{
				status = JabberKOSInvisible;
			}
			else
			{
				status = JabberKOSOnline;
			}
		}
		else
		if (resource.status ().show () == "chat")
		{
			status = JabberKOSChatty;
		}
		else if (resource.status ().show () == "away")
		{
			status = JabberKOSAway;
		}
		else if (resource.status ().show () == "xa")
		{
			status = JabberKOSXA;
		}
		else if (resource.status ().show () == "dnd")
		{
			status = JabberKOSDND;
		}
		else if (resource.status ().show () == "connecting")
		{
			status = JabberKOSConnecting;
		}
	}

	return status;

}

JabberProtocol *JabberProtocol::protocol ()
{
	// return current instance
	return protocolInstance;
}

Kopete::Contact *JabberProtocol::deserializeContact (Kopete::MetaContact * metaContact,
										 const QMap < QString, QString > &serializedData, const QMap < QString, QString > & /* addressBookData */ )
{
//  kdDebug (JABBER_DEBUG_GLOBAL) << k_funcinfo << "Deserializing data for metacontact " << metaContact->displayName () << "\n" << endl;

	QString contactId = serializedData["contactId"];
	QString displayName = serializedData["displayName"];
	QString accountId = serializedData["accountId"];

	QDict < Kopete::Account > accounts = Kopete::AccountManager::self ()->accounts (this);
	Kopete::Account *account = accounts[accountId];

	if (!account)
	{
		kdDebug(JABBER_DEBUG_GLOBAL) << k_funcinfo << "WARNING: Account for contact does not exist, skipping." << endl;
		return 0;
	}

	if (account)
		account->addContact (contactId,  metaContact);
	return account->contacts()[contactId];
}

#include "jabberprotocol.moc"
<commit_msg>Fix KOS categories so that there is just one status in each category. Prevents undefined behaviour in libkopete and inconsistent away behaviour from the UI.<commit_after> /*
  *   jabberprotocol.cpp  -  Base class for the Kopete Jabber protocol
  *
  * Copyright (c) 2002-2003 by Till Gerken <till@tantalo.net>
  * Copyright (c) 2002 by Daniel Stone <dstone@kde.org>
  *
  *  Kopete   (c) by the Kopete developers  <kopete-devel@kde.org>
  *
  * *************************************************************************
  * *                                                                       *
  * * This program is free software; you can redistribute it and/or modify  *
  * * it under the terms of the GNU General Public License as published by  *
  * * the Free Software Foundation; either version 2 of the License, or     *
  * * (at your option) any later version.                                   *
  * *                                                                       *
  * *************************************************************************
  */

#include <kdebug.h>
#include <kgenericfactory.h>
#include <kconfig.h>
#include <kmessagebox.h>
#include <kiconloader.h>
#include <kpopupmenu.h>
#include <kstandarddirs.h>
#include <klineeditdlg.h>

#include <qapplication.h>
#include <qcursor.h>
#include <qmap.h>
#include <qtimer.h>
#include <qpixmap.h>
#include <qstringlist.h>

#include "im.h"
#include "xmpp.h"

#include <sys/utsname.h>

#include "kopetecontact.h"
#include "kopetecontactlist.h"
#include "kopetemetacontact.h"
#include "kopetechatsession.h"
#include "kopeteonlinestatusmanager.h"
#include "kopeteaway.h"
#include "kopeteglobal.h"
#include "kopeteprotocol.h"
#include "kopeteplugin.h"
#include "addcontactpage.h"
#include "jabbercontact.h"
#include "dlgjabbersendraw.h"
#include "dlgjabberservices.h"
#include "dlgjabberchatjoin.h"
#include "jabberaddcontactpage.h"
#include "jabberprotocol.h"
#include "jabberaccount.h"
#include "kopeteaccountmanager.h"
#include "jabbereditaccountwidget.h"
#include "kopetecommandhandler.h"

JabberProtocol *JabberProtocol::protocolInstance = 0;

typedef KGenericFactory<JabberProtocol> JabberProtocolFactory;

K_EXPORT_COMPONENT_FACTORY( kopete_jabber, JabberProtocolFactory( "kopete_jabber" )  )

JabberProtocol::JabberProtocol (QObject * parent, const char *name, const QStringList &)
: Kopete::Protocol( JabberProtocolFactory::instance(), parent, name ),
	JabberKOSChatty(Kopete::OnlineStatus::Online,        100, this, JabberFreeForChat, "jabber_chatty", i18n ("Free for Chat"), i18n ("Free for Chat"), Kopete::OnlineStatusManager::FreeForChat ),
	JabberKOSOnline(Kopete::OnlineStatus::Online,         90, this, JabberOnline, QString::null, i18n ("Online"), i18n ("Online"), Kopete::OnlineStatusManager::Online ),
	JabberKOSAway(Kopete::OnlineStatus::Away,             80, this, JabberAway, "contact_away_overlay", i18n ("Away"), i18n ("Away"), Kopete::OnlineStatusManager::Away, Kopete::OnlineStatusManager::HasAwayMessage),
	JabberKOSXA(Kopete::OnlineStatus::Away,               70, this, JabberXA, "contact_xa_overlay", i18n ("Extended Away"), i18n ("Extended Away"), 0, Kopete::OnlineStatusManager::HasAwayMessage),
	JabberKOSDND(Kopete::OnlineStatus::Away,              60, this, JabberDND, "contact_busy_overlay", i18n ("Do not Disturb"), i18n ("Do not Disturb"), Kopete::OnlineStatusManager::Busy, Kopete::OnlineStatusManager::HasAwayMessage),
	JabberKOSOffline(Kopete::OnlineStatus::Offline,       50, this, JabberOffline, QString::null, i18n ("Offline") ,i18n ("Offline"), Kopete::OnlineStatusManager::Offline ),
	JabberKOSInvisible(Kopete::OnlineStatus::Invisible,   40, this, JabberInvisible, "contact_invisible_overlay",   i18n ("Invisible") ,i18n ("Invisible"), Kopete::OnlineStatusManager::Invisible),
	JabberKOSConnecting(Kopete::OnlineStatus::Connecting, 30, this, JabberConnecting, "jabber_connecting",  i18n("Connecting")),
	propAwayMessage(Kopete::Global::Properties::self()->awayMessage()),
	propFirstName(Kopete::Global::Properties::self()->firstName()),
	propLastName(Kopete::Global::Properties::self()->lastName()),
	propFullName(Kopete::Global::Properties::self()->fullName()),
	propEmailAddress(Kopete::Global::Properties::self()->emailAddress()),
	propPrivatePhone(Kopete::Global::Properties::self()->privatePhone()),
	propPrivateMobilePhone(Kopete::Global::Properties::self()->privateMobilePhone()),
	propWorkPhone(Kopete::Global::Properties::self()->workPhone()),
	propWorkMobilePhone(Kopete::Global::Properties::self()->workMobilePhone()),
	propNickName(Kopete::Global::Properties::self()->nickName()),
	propSubscriptionStatus("jabberSubscriptionStatus", i18n ("Subscription"), QString::null, true, false),
	propAuthorizationStatus("jabberAuthorizationStatus", i18n ("Authorization Status"), QString::null, true, false),
	propAvailableResources("jabberAvailableResources", i18n ("Available Resources"), "jabber_chatty", false, true),
	propVCardCacheTimeStamp("jabberVCardCacheTimeStamp", i18n ("vCard Cache Timestamp"), QString::null, true, false, true)

{

	kdDebug (JABBER_DEBUG_GLOBAL) << "[JabberProtocol] Loading ..." << endl;

	/* This is meant to be a singleton, so we will check if we have
	 * been loaded before. */
	if (protocolInstance)
	{
		kdDebug (JABBER_DEBUG_GLOBAL) << "[JabberProtocol] Warning: Protocol already " << "loaded, not initializing again." << endl;
		return;
	}

	protocolInstance = this;

	addAddressBookField ("messaging/xmpp", Kopete::Plugin::MakeIndexField);
}

JabberProtocol::~JabberProtocol ()
{
	//disconnectAll();

	/* make sure that the next attempt to load Jabber
	 * re-initializes the protocol class. */
	protocolInstance = 0L;
}

AddContactPage *JabberProtocol::createAddContactWidget (QWidget * parent, Kopete::Account * i)
{
	kdDebug (JABBER_DEBUG_GLOBAL) << "[Jabber Protocol] Create Add Contact  Widget\n" << endl;
	return new JabberAddContactPage (i, parent);
}

KopeteEditAccountWidget *JabberProtocol::createEditAccountWidget (Kopete::Account * account, QWidget * parent)
{
	kdDebug (JABBER_DEBUG_GLOBAL) << "[Jabber Protocol] Edit Account Widget\n" << endl;
	return new JabberEditAccountWidget (this, static_cast < JabberAccount * >(account), parent);
}

Kopete::Account *JabberProtocol::createNewAccount (const QString & accountId)
{
	kdDebug (JABBER_DEBUG_GLOBAL) << "[Jabber Protocol] Create New Account. ID: " << accountId << "\n" << endl;
	return new JabberAccount (this, accountId);
}

Kopete::OnlineStatus JabberProtocol::resourceToKOS ( const XMPP::Resource &resource )
{

	// update to offline by default
	Kopete::OnlineStatus status = JabberKOSOffline;

	if ( !resource.status().isAvailable () )
	{
		// resource is offline
		status = JabberKOSOffline;
	}
	else
	{
		if (resource.status ().show ().isEmpty ())
		{
			if (resource.status ().isInvisible ())
			{
				status = JabberKOSInvisible;
			}
			else
			{
				status = JabberKOSOnline;
			}
		}
		else
		if (resource.status ().show () == "chat")
		{
			status = JabberKOSChatty;
		}
		else if (resource.status ().show () == "away")
		{
			status = JabberKOSAway;
		}
		else if (resource.status ().show () == "xa")
		{
			status = JabberKOSXA;
		}
		else if (resource.status ().show () == "dnd")
		{
			status = JabberKOSDND;
		}
		else if (resource.status ().show () == "connecting")
		{
			status = JabberKOSConnecting;
		}
	}

	return status;

}

JabberProtocol *JabberProtocol::protocol ()
{
	// return current instance
	return protocolInstance;
}

Kopete::Contact *JabberProtocol::deserializeContact (Kopete::MetaContact * metaContact,
										 const QMap < QString, QString > &serializedData, const QMap < QString, QString > & /* addressBookData */ )
{
//  kdDebug (JABBER_DEBUG_GLOBAL) << k_funcinfo << "Deserializing data for metacontact " << metaContact->displayName () << "\n" << endl;

	QString contactId = serializedData["contactId"];
	QString displayName = serializedData["displayName"];
	QString accountId = serializedData["accountId"];

	QDict < Kopete::Account > accounts = Kopete::AccountManager::self ()->accounts (this);
	Kopete::Account *account = accounts[accountId];

	if (!account)
	{
		kdDebug(JABBER_DEBUG_GLOBAL) << k_funcinfo << "WARNING: Account for contact does not exist, skipping." << endl;
		return 0;
	}

	if (account)
		account->addContact (contactId,  metaContact);
	return account->contacts()[contactId];
}

#include "jabberprotocol.moc"
<|endoftext|>


<commit_before>/*
    msndebugrawcmddlg.cpp - Send a raw MSN command for debugging

    Copyright (c) 2002 by Martijn Klingens       <klingens@kde.org>
    Kopete    (c) 2002 by the Kopete developers  <kopete-devel@kde.org>

    Portions of this code are taken from KMerlin,
              (c) 2001 by Olaf Lueg              <olueg@olsd.de>

    *************************************************************************
    *                                                                       *
    * This program is free software; you can redistribute it and/or modify  *
    * it under the terms of the GNU General Public License as published by  *
    * the Free Software Foundation; either version 2 of the License, or     *
    * (at your option) any later version.                                   *
    *                                                                       *
    *************************************************************************
*/

#include "msndebugrawcmddlg.h"

#include "ui_msndebugrawcommand_base.h"

#include <qcheckbox.h>
#include <qlineedit.h>
#include <ktextedit.h>

#include <klocale.h>

MSNDebugRawCmdDlg::MSNDebugRawCmdDlg( QWidget *parent )
: KDialog( parent )
{
	setCaption( i18n( "DEBUG: Send Raw Command - MSN Plugin" ) );
	setButtons( KDialog::Ok | KDialog::Cancel );
	setDefaultButton( KDialog::Ok );
	showButtonSeparator( true );

	setInitialSize( QSize( 350, 200 ) );

	QWidget* w = new QWidget( this );
	m_main = new Ui::MSNDebugRawCommand_base();
	m_main->setupUi( w );
	setMainWidget( w );
}

MSNDebugRawCmdDlg::~MSNDebugRawCmdDlg()
{
	m_main;
}

QString MSNDebugRawCmdDlg::command()
{
	return m_main->m_command->text();
}

QString MSNDebugRawCmdDlg::params()
{
	return m_main->m_params->text();
}

bool MSNDebugRawCmdDlg::addNewline()
{
	return m_main->m_addNewline->isChecked();
}

bool MSNDebugRawCmdDlg::addId()
{
	return m_main->m_addId->isChecked();
}

QString MSNDebugRawCmdDlg::msg()
{
	return m_main->m_msg->text();
}

#include "msndebugrawcmddlg.moc"

// vim: set noet ts=4 sts=4 sw=4:

<commit_msg><commit_after>/*
    msndebugrawcmddlg.cpp - Send a raw MSN command for debugging

    Copyright (c) 2002 by Martijn Klingens       <klingens@kde.org>
    Kopete    (c) 2002 by the Kopete developers  <kopete-devel@kde.org>

    Portions of this code are taken from KMerlin,
              (c) 2001 by Olaf Lueg              <olueg@olsd.de>

    *************************************************************************
    *                                                                       *
    * This program is free software; you can redistribute it and/or modify  *
    * it under the terms of the GNU General Public License as published by  *
    * the Free Software Foundation; either version 2 of the License, or     *
    * (at your option) any later version.                                   *
    *                                                                       *
    *************************************************************************
*/

#include "msndebugrawcmddlg.h"

#include "ui_msndebugrawcommand_base.h"

#include <qcheckbox.h>
#include <qlineedit.h>
#include <ktextedit.h>

#include <klocale.h>

MSNDebugRawCmdDlg::MSNDebugRawCmdDlg( QWidget *parent )
: KDialog( parent )
{
	setCaption( i18n( "DEBUG: Send Raw Command - MSN Plugin" ) );
	setButtons( KDialog::Ok | KDialog::Cancel );
	setDefaultButton( KDialog::Ok );
	showButtonSeparator( true );

	setInitialSize( QSize( 350, 200 ) );

	QWidget* w = new QWidget( this );
	m_main = new Ui::MSNDebugRawCommand_base();
	m_main->setupUi( w );
	setMainWidget( w );
}

MSNDebugRawCmdDlg::~MSNDebugRawCmdDlg()
{
	delete m_main;
}

QString MSNDebugRawCmdDlg::command()
{
	return m_main->m_command->text();
}

QString MSNDebugRawCmdDlg::params()
{
	return m_main->m_params->text();
}

bool MSNDebugRawCmdDlg::addNewline()
{
	return m_main->m_addNewline->isChecked();
}

bool MSNDebugRawCmdDlg::addId()
{
	return m_main->m_addId->isChecked();
}

QString MSNDebugRawCmdDlg::msg()
{
	return m_main->m_msg->toPlainText();
}

#include "msndebugrawcmddlg.moc"

// vim: set noet ts=4 sts=4 sw=4:

<|endoftext|>