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

#include "app.hxx"
#include "langselect.hxx"
#include "langselect.hrc"
#include <stdio.h>

#ifndef _RTL_STRING_HXX
#include <rtl/string.hxx>
#endif
#ifndef _SVTOOLS_PATHOPTIONS_HXX
#include <svtools/pathoptions.hxx>
#endif
#ifndef _TOOLS_RESID_HXX
#include <tools/resid.hxx>
#endif
#ifndef _TOOLS_ISOLANG_HXX
#include <tools/isolang.hxx>
#endif
#ifndef _COMPHELPER_PROCESSFACTORY_HXX_
#include <comphelper/processfactory.hxx>
#endif
#ifndef _COM_SUN_STAR_CONTAINER_XNAMEACCESS_HPP_
#include <com/sun/star/container/XNameAccess.hpp>
#endif
#include <com/sun/star/lang/XComponent.hpp>
#include <com/sun/star/beans/NamedValue.hpp>
#include <com/sun/star/uno/Any.hxx>
#include <com/sun/star/lang/XLocalizable.hpp>
#include <com/sun/star/lang/Locale.hpp>
#include <rtl/locale.hxx>
#ifndef INCLUDED_RTL_INSTANCE_HXX
#include <rtl/instance.hxx>
#endif
#include <osl/process.h>

using namespace rtl;
using namespace com::sun::star::uno;
using namespace com::sun::star::lang;
using namespace com::sun::star::container;
using namespace com::sun::star::beans;

namespace desktop {

LanguageSelectionDialog::LanguageSelectionDialog(ResMgr *pResMgr) :
    ModalDialog(NULL,ResId(DLG_LANGSELECT, pResMgr)),
    m_aText(this, ResId(TXT_DLG_LANGSELECT, pResMgr)),
    m_aListBox(this, ResId(LST_DLG_LANGSELECT, pResMgr)),
    m_aButton(this, ResId(BTN_DLG_LANGSELECT_OK, pResMgr))
{
    FreeResource();
}

namespace { struct lLanguages : public rtl::Static<IsoList, lLanguages> {}; }

// execute the language selection
// display a dialog if more than one language is installed
// XXX this is a temporary solution
static sal_Bool bFoundLanguage = sal_False;
//static LanguageType aFoundLanguageType = LANGUAGE_DONTKNOW;
static OUString aFoundLanguage;

Locale LanguageSelection::IsoStringToLocale(const OUString& str)
{
    Locale l;
    sal_Int32 index=0;
    l.Language = str.getToken(0, '-', index);
    if (index >= 0) l.Country = str.getToken(0, '-', index);
    if (index >= 0) l.Variant = str.getToken(0, '-', index);
    return l;
}

void LanguageSelection::prepareLanguage()
{
    // XXX make everything works without assertions in first run
    // in multi-language installations, some things might fail in first run
    if (getUserLanguage().getLength() > 0) return;
    IsoList l = getInstalledIsoLanguages();
    if (l.size() >= 1)
    {
        // throw any away existing default config
        OUString sConfigSrvc = OUString::createFromAscii("com.sun.star.configuration.ConfigurationProvider");
        Reference< XMultiServiceFactory > theMSF = comphelper::getProcessServiceFactory();
        Reference< XLocalizable > theConfigProvider(
            theMSF->createInstance( sConfigSrvc ),UNO_QUERY );
        OSL_ENSURE(theConfigProvider.is(), "cannot localize config manager.");
        if (theConfigProvider.is())
        {
            OUString aLocaleString = *l.begin();
            Locale loc = LanguageSelection::IsoStringToLocale(aLocaleString);
            theConfigProvider->setLocale(loc);
        }
    }
}

OUString LanguageSelection::getLanguageString()
{

    if (bFoundLanguage)
        return aFoundLanguage;

    // check whether there was aleady a language selected by the user
    OUString aUserLanguage = getUserLanguage();
    if (aUserLanguage.getLength() > 0 )
    {
        bFoundLanguage = sal_True;
        aFoundLanguage = aUserLanguage;
        // return aFoundLanguageType;
        // we can not return yet, we need to check whether this instance supports
        // the language that was previously chosen by the user...
    }

    // fill list
    IsoList &rLanguages = lLanguages::get();
    if (rLanguages.size() < 1)
        rLanguages = getInstalledIsoLanguages();
    // check whether found language is available
    if (bFoundLanguage)
    {
        IsoList::const_iterator iLang = rLanguages.begin();
        while (iLang != rLanguages.end())
        {
            if (iLang->equals(aFoundLanguage))
                return aFoundLanguage;
            else
                iLang++;
        }
    }
    if (rLanguages.size() > 1) {
        // are there multiple languages installed?
        // get resource
        rtl::OString aMgrName = OString("langselect") + OString::valueOf((sal_Int32)SUPD, 10);
        ::com::sun::star::lang::Locale aLocale;
        ResMgr* pResMgr = ResMgr::SearchCreateResMgr( aMgrName, aLocale );
        LanguageSelectionDialog lsd(pResMgr);
        StrList languages(getLanguageStrings(rLanguages));
        for (StrList::iterator str_iter = languages.begin(); str_iter != languages.end(); str_iter++)
        {
            lsd.m_aListBox.InsertEntry(*str_iter);
        }

        lsd.Execute();
        short nSelected = lsd.m_aListBox.GetSelectEntryPos();
        IsoList::const_iterator i = rLanguages.begin();
        for (sal_Int32 n=0; n<nSelected; n++) i++;
        bFoundLanguage = sal_True;
        aFoundLanguage = *i;
        return aFoundLanguage;
    } else {
        // if there is only one language, use it
        if (rLanguages.size() == 1) {
            bFoundLanguage = sal_True;
            aFoundLanguage = *(rLanguages.begin());
            return aFoundLanguage;
        } else {
            // last resort
            // don't save
            return ConvertLanguageToIsoString((LanguageType) SvtPathOptions().SubstituteVariable(
                String::CreateFromAscii("$(langid)")).ToInt32()) ;
            /*
            ::com::sun::star::lang::Locale aLocale;
            OUString aLocString( aLocale.Language );
            if ( aLocale.Country.getLength() != 0 )
            {
                aLocString += OUString::createFromAscii("-")
                                + aLocale.Country;
                if ( aLocale.Variant.getLength() != 0 )
                {
                    aLocString += OUString::createFromAscii("-")
                                    + aLocale.Variant;
                }
            }
            return aLocString;
            */
        }
    }
}

// Get the localized selection strings for the list of languages
StrList LanguageSelection::getLanguageStrings(const IsoList& langLst)
{
    StrList aList;
    rtl::OString aMgrName = OString("langselect") + OString::valueOf((sal_Int32)SUPD, 10);
    for (IsoList::const_iterator lang_iter = langLst.begin(); lang_iter != langLst.end(); lang_iter++)
    {
        rtl::OUString lang = static_cast<OUString>(*lang_iter);
        ::com::sun::star::lang::Locale aLocale = LanguageSelection::IsoStringToLocale(lang);
        ResMgr* pResMgr = ResMgr::SearchCreateResMgr( aMgrName, aLocale );
        if (pResMgr != NULL) {
            String aString(ResId(STR_LANGSELECT, pResMgr));
            aList.push_back(aString);
            delete pResMgr;
        }
    }
    return aList;
}

// get a language choosen by the user
OUString LanguageSelection::getUserLanguage()
{
    OUString aLanguage;
    try{

        OUString sConfigSrvc = OUString::createFromAscii("com.sun.star.configuration.ConfigurationProvider");
        OUString sAccessSrvc = OUString::createFromAscii("com.sun.star.configuration.ConfigurationAccess");
        OUString sConfigURL = OUString::createFromAscii("org.openoffice.Setup/L10N/");
        OUString sLocales = OUString::createFromAscii("ooLocale");

        // get configuration provider
        Reference< XMultiServiceFactory > theMSF = comphelper::getProcessServiceFactory();
        Reference< XMultiServiceFactory > theConfigProvider = Reference< XMultiServiceFactory > (
                theMSF->createInstance( sConfigSrvc ),UNO_QUERY );
        // check provider
        if (!theConfigProvider.is()) return aLanguage;

        // access the provider
        Sequence< Any > theArgs(1);
        theArgs[ 0 ] <<= sConfigURL;
        Reference< XNameAccess > theNameAccess = Reference< XNameAccess > (
                theConfigProvider->createInstanceWithArguments(
                sAccessSrvc, theArgs ), UNO_QUERY );
        // check access
        if (!theNameAccess.is()) return aLanguage;
        // run query
        Any aResult = theNameAccess->getByName( sLocales );
        OUString aLangString;
        if (aResult >>= aLangString)
        {
            aLanguage = aLangString;
        }
    } catch (com::sun::star::uno::RuntimeException)
    {
        // didn't work - return dontknow
        return aLanguage;
    }
    return aLanguage;
}

// get a list with the languages that are installed
IsoList LanguageSelection::getInstalledIsoLanguages()
{
    IsoList aList;
    // read language list from org.openoffice.Setup/Office/ooSetupLocales
    try{
        OUString sConfigSrvc = OUString::createFromAscii("com.sun.star.configuration.ConfigurationProvider");
        OUString sAccessSrvc = OUString::createFromAscii("com.sun.star.configuration.ConfigurationAccess");
        OUString sConfigURL = OUString::createFromAscii("org.openoffice.Setup/Office/InstalledLocales");

        // get configuration provider
        Reference< XMultiServiceFactory > theMSF = comphelper::getProcessServiceFactory();
        Reference< XMultiServiceFactory > theConfigProvider = Reference< XMultiServiceFactory > (
                theMSF->createInstance( sConfigSrvc ),UNO_QUERY );
        // check provider
        if (!theConfigProvider.is()) return aList;

        // access the provider
        Sequence< Any > theArgs(1);
        theArgs[ 0 ] <<= sConfigURL;
        Reference< XNameAccess > theNameAccess = Reference< XNameAccess > (
                theConfigProvider->createInstanceWithArguments(
                sAccessSrvc, theArgs ), UNO_QUERY );
        //check access
        if (!theNameAccess.is()) return aList;

        Sequence< OUString > aLangSeq = theNameAccess->getElementNames();

        for (int i=0; i<aLangSeq.getLength(); i++)
               aList.push_back(aLangSeq[i]);
    } catch (com::sun::star::uno::RuntimeException)
    {
        // didn't work - return empty list
    }
    return aList;
}

/*
// get a list with the languages that are installed
LangList LanguageSelection::getInstalledLanguages()
{
    LangList aList;
    // read language list from org.openoffice.Setup/Office/ooSetupLocales
    try{
        OUString sConfigSrvc = OUString::createFromAscii("com.sun.star.configuration.ConfigurationProvider");
        OUString sAccessSrvc = OUString::createFromAscii("com.sun.star.configuration.ConfigurationAccess");
        OUString sConfigURL = OUString::createFromAscii("org.openoffice.Setup/Office/InstalledLocales");

        // get configuration provider
        Reference< XMultiServiceFactory > theMSF = comphelper::getProcessServiceFactory();
        Reference< XMultiServiceFactory > theConfigProvider = Reference< XMultiServiceFactory > (
                theMSF->createInstance( sConfigSrvc ),UNO_QUERY );
        // check provider
        if (!theConfigProvider.is()) return aList;

        // access the provider
        Sequence< Any > theArgs(1);
        theArgs[ 0 ] <<= sConfigURL;
        Reference< XNameAccess > theNameAccess = Reference< XNameAccess > (
                theConfigProvider->createInstanceWithArguments(
                sAccessSrvc, theArgs ), UNO_QUERY );
        //check access
        if (!theNameAccess.is()) return aList;

        Sequence< OUString > aLangSeq = theNameAccess->getElementNames();

        for (int i=0; i<aLangSeq.getLength(); i++)
            aList.push_back(ConvertIsoStringToLanguage(aLangSeq[i]));

    } catch (com::sun::star::uno::Exception&)
    {
        // didn't work - return empty list
    }
    return aList;
}
*/
} // namespace desktop
<commit_msg>INTEGRATION: CWS cfgruggedised (1.7.10); FILE MERGED 2004/07/23 13:43:11 jb 1.7.10.1: #i28654# Configuration can fail with more than RuntimeException -> catch them all<commit_after>/*************************************************************************
 *
 *  $RCSfile: langselect.cxx,v $
 *
 *  $Revision: 1.10 $
 *  last change: $Author: rt $ $Date: 2004-08-20 13:00:26 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (the "License"); You may not use this file
 *  except in compliance with the License. You may obtain a copy of the
 *  License at http://www.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

#include "app.hxx"
#include "langselect.hxx"
#include "langselect.hrc"
#include <stdio.h>

#ifndef _RTL_STRING_HXX
#include <rtl/string.hxx>
#endif
#ifndef _SVTOOLS_PATHOPTIONS_HXX
#include <svtools/pathoptions.hxx>
#endif
#ifndef _TOOLS_RESID_HXX
#include <tools/resid.hxx>
#endif
#ifndef _TOOLS_ISOLANG_HXX
#include <tools/isolang.hxx>
#endif
#ifndef _COMPHELPER_PROCESSFACTORY_HXX_
#include <comphelper/processfactory.hxx>
#endif
#ifndef _COM_SUN_STAR_CONTAINER_XNAMEACCESS_HPP_
#include <com/sun/star/container/XNameAccess.hpp>
#endif
#include <com/sun/star/lang/XComponent.hpp>
#include <com/sun/star/beans/NamedValue.hpp>
#include <com/sun/star/uno/Any.hxx>
#include <com/sun/star/lang/XLocalizable.hpp>
#include <com/sun/star/lang/Locale.hpp>
#include <rtl/locale.hxx>
#ifndef INCLUDED_RTL_INSTANCE_HXX
#include <rtl/instance.hxx>
#endif
#include <osl/process.h>

using namespace rtl;
using namespace com::sun::star::uno;
using namespace com::sun::star::lang;
using namespace com::sun::star::container;
using namespace com::sun::star::beans;

namespace desktop {

LanguageSelectionDialog::LanguageSelectionDialog(ResMgr *pResMgr) :
    ModalDialog(NULL,ResId(DLG_LANGSELECT, pResMgr)),
    m_aText(this, ResId(TXT_DLG_LANGSELECT, pResMgr)),
    m_aListBox(this, ResId(LST_DLG_LANGSELECT, pResMgr)),
    m_aButton(this, ResId(BTN_DLG_LANGSELECT_OK, pResMgr))
{
    FreeResource();
}

namespace { struct lLanguages : public rtl::Static<IsoList, lLanguages> {}; }

// execute the language selection
// display a dialog if more than one language is installed
// XXX this is a temporary solution
static sal_Bool bFoundLanguage = sal_False;
//static LanguageType aFoundLanguageType = LANGUAGE_DONTKNOW;
static OUString aFoundLanguage;

Locale LanguageSelection::IsoStringToLocale(const OUString& str)
{
    Locale l;
    sal_Int32 index=0;
    l.Language = str.getToken(0, '-', index);
    if (index >= 0) l.Country = str.getToken(0, '-', index);
    if (index >= 0) l.Variant = str.getToken(0, '-', index);
    return l;
}

void LanguageSelection::prepareLanguage()
{
    // XXX make everything works without assertions in first run
    // in multi-language installations, some things might fail in first run
    if (getUserLanguage().getLength() > 0) return;
    IsoList l = getInstalledIsoLanguages();
    if (l.size() >= 1)
    {
        // throw any away existing default config
        OUString sConfigSrvc = OUString::createFromAscii("com.sun.star.configuration.ConfigurationProvider");
        Reference< XMultiServiceFactory > theMSF = comphelper::getProcessServiceFactory();
        Reference< XLocalizable > theConfigProvider(
            theMSF->createInstance( sConfigSrvc ),UNO_QUERY );
        OSL_ENSURE(theConfigProvider.is(), "cannot localize config manager.");
        if (theConfigProvider.is())
        {
            OUString aLocaleString = *l.begin();
            Locale loc = LanguageSelection::IsoStringToLocale(aLocaleString);
            theConfigProvider->setLocale(loc);
        }
    }
}

OUString LanguageSelection::getLanguageString()
{

    if (bFoundLanguage)
        return aFoundLanguage;

    // check whether there was aleady a language selected by the user
    OUString aUserLanguage = getUserLanguage();
    if (aUserLanguage.getLength() > 0 )
    {
        bFoundLanguage = sal_True;
        aFoundLanguage = aUserLanguage;
        // return aFoundLanguageType;
        // we can not return yet, we need to check whether this instance supports
        // the language that was previously chosen by the user...
    }

    // fill list
    IsoList &rLanguages = lLanguages::get();
    if (rLanguages.size() < 1)
        rLanguages = getInstalledIsoLanguages();
    // check whether found language is available
    if (bFoundLanguage)
    {
        IsoList::const_iterator iLang = rLanguages.begin();
        while (iLang != rLanguages.end())
        {
            if (iLang->equals(aFoundLanguage))
                return aFoundLanguage;
            else
                iLang++;
        }
    }
    if (rLanguages.size() > 1) {
        // are there multiple languages installed?
        // get resource
        rtl::OString aMgrName = OString("langselect") + OString::valueOf((sal_Int32)SUPD, 10);
        ::com::sun::star::lang::Locale aLocale;
        ResMgr* pResMgr = ResMgr::SearchCreateResMgr( aMgrName, aLocale );
        LanguageSelectionDialog lsd(pResMgr);
        StrList languages(getLanguageStrings(rLanguages));
        for (StrList::iterator str_iter = languages.begin(); str_iter != languages.end(); str_iter++)
        {
            lsd.m_aListBox.InsertEntry(*str_iter);
        }

        lsd.Execute();
        short nSelected = lsd.m_aListBox.GetSelectEntryPos();
        IsoList::const_iterator i = rLanguages.begin();
        for (sal_Int32 n=0; n<nSelected; n++) i++;
        bFoundLanguage = sal_True;
        aFoundLanguage = *i;
        return aFoundLanguage;
    } else {
        // if there is only one language, use it
        if (rLanguages.size() == 1) {
            bFoundLanguage = sal_True;
            aFoundLanguage = *(rLanguages.begin());
            return aFoundLanguage;
        } else {
            // last resort
            // don't save
            return ConvertLanguageToIsoString((LanguageType) SvtPathOptions().SubstituteVariable(
                String::CreateFromAscii("$(langid)")).ToInt32()) ;
            /*
            ::com::sun::star::lang::Locale aLocale;
            OUString aLocString( aLocale.Language );
            if ( aLocale.Country.getLength() != 0 )
            {
                aLocString += OUString::createFromAscii("-")
                                + aLocale.Country;
                if ( aLocale.Variant.getLength() != 0 )
                {
                    aLocString += OUString::createFromAscii("-")
                                    + aLocale.Variant;
                }
            }
            return aLocString;
            */
        }
    }
}

// Get the localized selection strings for the list of languages
StrList LanguageSelection::getLanguageStrings(const IsoList& langLst)
{
    StrList aList;
    rtl::OString aMgrName = OString("langselect") + OString::valueOf((sal_Int32)SUPD, 10);
    for (IsoList::const_iterator lang_iter = langLst.begin(); lang_iter != langLst.end(); lang_iter++)
    {
        rtl::OUString lang = static_cast<OUString>(*lang_iter);
        ::com::sun::star::lang::Locale aLocale = LanguageSelection::IsoStringToLocale(lang);
        ResMgr* pResMgr = ResMgr::SearchCreateResMgr( aMgrName, aLocale );
        if (pResMgr != NULL) {
            String aString(ResId(STR_LANGSELECT, pResMgr));
            aList.push_back(aString);
            delete pResMgr;
        }
    }
    return aList;
}

// get a language choosen by the user
OUString LanguageSelection::getUserLanguage()
{
    OUString aLanguage;
    try{

        OUString sConfigSrvc = OUString::createFromAscii("com.sun.star.configuration.ConfigurationProvider");
        OUString sAccessSrvc = OUString::createFromAscii("com.sun.star.configuration.ConfigurationAccess");
        OUString sConfigURL = OUString::createFromAscii("org.openoffice.Setup/L10N/");
        OUString sLocales = OUString::createFromAscii("ooLocale");

        // get configuration provider
        Reference< XMultiServiceFactory > theMSF = comphelper::getProcessServiceFactory();
        Reference< XMultiServiceFactory > theConfigProvider = Reference< XMultiServiceFactory > (
                theMSF->createInstance( sConfigSrvc ),UNO_QUERY );
        // check provider
        if (!theConfigProvider.is()) return aLanguage;

        // access the provider
        Sequence< Any > theArgs(1);
        theArgs[ 0 ] <<= sConfigURL;
        Reference< XNameAccess > theNameAccess = Reference< XNameAccess > (
                theConfigProvider->createInstanceWithArguments(
                sAccessSrvc, theArgs ), UNO_QUERY );
        // check access
        if (!theNameAccess.is()) return aLanguage;
        // run query
        Any aResult = theNameAccess->getByName( sLocales );
        OUString aLangString;
        if (aResult >>= aLangString)
        {
            aLanguage = aLangString;
        }
    } catch (com::sun::star::uno::Exception)
    {
        // didn't work - return dontknow
        return aLanguage;
    }
    return aLanguage;
}

// get a list with the languages that are installed
IsoList LanguageSelection::getInstalledIsoLanguages()
{
    IsoList aList;
    // read language list from org.openoffice.Setup/Office/ooSetupLocales
    try{
        OUString sConfigSrvc = OUString::createFromAscii("com.sun.star.configuration.ConfigurationProvider");
        OUString sAccessSrvc = OUString::createFromAscii("com.sun.star.configuration.ConfigurationAccess");
        OUString sConfigURL = OUString::createFromAscii("org.openoffice.Setup/Office/InstalledLocales");

        // get configuration provider
        Reference< XMultiServiceFactory > theMSF = comphelper::getProcessServiceFactory();
        Reference< XMultiServiceFactory > theConfigProvider = Reference< XMultiServiceFactory > (
                theMSF->createInstance( sConfigSrvc ),UNO_QUERY );
        // check provider
        if (!theConfigProvider.is()) return aList;

        // access the provider
        Sequence< Any > theArgs(1);
        theArgs[ 0 ] <<= sConfigURL;
        Reference< XNameAccess > theNameAccess = Reference< XNameAccess > (
                theConfigProvider->createInstanceWithArguments(
                sAccessSrvc, theArgs ), UNO_QUERY );
        //check access
        if (!theNameAccess.is()) return aList;

        Sequence< OUString > aLangSeq = theNameAccess->getElementNames();

        for (int i=0; i<aLangSeq.getLength(); i++)
               aList.push_back(aLangSeq[i]);
    } catch (com::sun::star::uno::Exception)
    {
        // didn't work - return empty list
    }
    return aList;
}

/*
// get a list with the languages that are installed
LangList LanguageSelection::getInstalledLanguages()
{
    LangList aList;
    // read language list from org.openoffice.Setup/Office/ooSetupLocales
    try{
        OUString sConfigSrvc = OUString::createFromAscii("com.sun.star.configuration.ConfigurationProvider");
        OUString sAccessSrvc = OUString::createFromAscii("com.sun.star.configuration.ConfigurationAccess");
        OUString sConfigURL = OUString::createFromAscii("org.openoffice.Setup/Office/InstalledLocales");

        // get configuration provider
        Reference< XMultiServiceFactory > theMSF = comphelper::getProcessServiceFactory();
        Reference< XMultiServiceFactory > theConfigProvider = Reference< XMultiServiceFactory > (
                theMSF->createInstance( sConfigSrvc ),UNO_QUERY );
        // check provider
        if (!theConfigProvider.is()) return aList;

        // access the provider
        Sequence< Any > theArgs(1);
        theArgs[ 0 ] <<= sConfigURL;
        Reference< XNameAccess > theNameAccess = Reference< XNameAccess > (
                theConfigProvider->createInstanceWithArguments(
                sAccessSrvc, theArgs ), UNO_QUERY );
        //check access
        if (!theNameAccess.is()) return aList;

        Sequence< OUString > aLangSeq = theNameAccess->getElementNames();

        for (int i=0; i<aLangSeq.getLength(); i++)
            aList.push_back(ConvertIsoStringToLanguage(aLangSeq[i]));

    } catch (com::sun::star::uno::Exception&)
    {
        // didn't work - return empty list
    }
    return aList;
}
*/
} // namespace desktop
<|endoftext|>


<commit_before>// Copyright (c) 2012, Andre Caron (andre.l.caron@gmail.com)
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
//  * Redistributions of source code must retain the above copyright
//    notice, this list of conditions and the following disclaimer.
//
//  * Redistributions in binary form must reproduce the above copyright
//    notice, this list of conditions and the following disclaimer in the
//    documentation and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

#include "SocketChannel.hpp"
#include "Engine.hpp"
#include "Hub.hpp" // TODO: include "Slave.hpp"

#include "FileReader.hpp"
#include "FileWriter.hpp"

#include "trace.hpp"

namespace {

    w32::net::Socket::Handle create_socket ()
    {
        const ::SOCKET result = ::socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
        if ( result == INVALID_SOCKET ) {
            const int error = ::WSAGetLastError();
            UNCHECKED_WIN32C_ERROR(socket, error);
        }
        return (w32::net::Socket::claim(result));
    }

    // Create a bound, unconnected stream socket.
    w32::net::StreamSocket create_socket (w32::net::ipv4::EndPoint host)
    {
        cz_trace(" >> Creating socket.");

        w32::net::tcp::Stream stream(create_socket());

        cz_trace(" >> Binding to local address.");

        const ::BOOL result = ::bind(stream.handle(), host.raw(), host.size());
        if (result == SOCKET_ERROR)
        {
            const int error = ::WSAGetLastError();
            UNCHECKED_WIN32C_ERROR(bind, error);
        }

        return (stream);
    }

}

namespace cz {

    SocketChannel::SocketChannel (Engine& engine,
                                  w32::net::StreamSocket& stream,
                                  w32::net::ipv4::EndPoint host,
                                  w32::net::ipv4::EndPoint peer)
        : myEngine(engine)
        , myStream(stream)
        , myHost(host)
        , myPeer(peer)
    {
        // Note: stream is already bound to the completion port at this point.
    }

    const w32::net::ipv4::EndPoint& SocketChannel::host () const
    {
        return (myHost);
    }

    const w32::net::ipv4::EndPoint& SocketChannel::peer () const
    {
        return (myPeer);
    }

    size_t SocketChannel::get (void * data, size_t size)
    {
        Hub::Slave& self = Hub::Slave::self();

        // Start the I/O operation.
        GetRequest request(myEngine, myStream);
        request.start(data, size);

        // Switch to master, it will resume us when it receives a completion
        // notification for the asynchronous I/O operation.
        self.hub().resume();

        return (request.close());
    }

    size_t SocketChannel::put (const void * data, size_t size)
    {
        Hub::Slave& self = Hub::Slave::self();

        // Start the I/O operation.
        PutRequest request(myEngine, myStream);
        request.start(data, size);

        // Switch to master, it will resume us when it receives a completion
        // notification for the asynchronous I/O operation.
        self.hub().resume();

        return (request.close());
    }

    ConnectRequest::ConnectRequest (Engine& engine,
                          w32::net::ipv4::EndPoint host,
                          w32::net::ipv4::EndPoint peer)
        : myRequest(engine)
        , myHost(host)
        , myPeer(peer)
        , mySent(0)
        , myStream(::create_socket(myHost))
    {
        Hub::Slave& self = Hub::Slave::self();

        // Make sure we receive I/O completion notifications :-)
        engine.completion_port().bind(myStream, &engine);
    }

    void ConnectRequest::start ()
    {
        w32::net::tcp::Stream::ConnectEx connect_ex =
            w32::net::tcp::Stream(myStream.handle()).connect_ex();

        cz_trace(" >> Starting connect request.");

        // Start the asynchronous connection request.
        const ::BOOL result = connect_ex(myStream.handle(),
                                         myPeer.raw(),
                                         myPeer.size(),
                                         0, 0, // initial payload.
                                         &mySent,
                                         &myRequest.data());
        if (result == FALSE)
        {
            const ::DWORD error = ::GetLastError();
            if (error != ERROR_IO_PENDING) {
                UNCHECKED_WIN32C_ERROR(ConnectEx, error);
            }
        }
    }

    bool ConnectRequest::ready () const
    {
        return (myRequest.ready());
    }

    SocketChannel * ConnectRequest::close()
    {
        // The hub has resume us, collect results!
        const w32::io::Notification notification = myRequest.notification();

        // Connect requests can be cancelled :-(
        if (notification.aborted()) {
            cz_trace(" >> Connect request cancelled.");
            return (0);
        }

        // Propagate I/O exception to the caller if necessary.
        notification.report_error();

        cz_trace(" >> Connected!");
        cz_trace(" >> Host: " << myHost);
        cz_trace(" >> Peer: " << myPeer);

        // Patch socket for shutdown() and others to work as expected.
        const int result = ::setsockopt(myStream.handle(), SOL_SOCKET,
                                        SO_UPDATE_CONNECT_CONTEXT, 0, 0);
        if (result == SOCKET_ERROR)
        {
            const int error = ::WSAGetLastError();
            UNCHECKED_WIN32C_ERROR(setsockopt, error);
        }

        return (new SocketChannel(myRequest.engine(), myStream, myHost, myPeer));
    }

}
<commit_msg>Implements declared but unimplemented method.<commit_after>// Copyright (c) 2012, Andre Caron (andre.l.caron@gmail.com)
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
//  * Redistributions of source code must retain the above copyright
//    notice, this list of conditions and the following disclaimer.
//
//  * Redistributions in binary form must reproduce the above copyright
//    notice, this list of conditions and the following disclaimer in the
//    documentation and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

#include "SocketChannel.hpp"
#include "Engine.hpp"
#include "Hub.hpp" // TODO: include "Slave.hpp"

#include "FileReader.hpp"
#include "FileWriter.hpp"

#include "trace.hpp"

namespace {

    w32::net::Socket::Handle create_socket ()
    {
        const ::SOCKET result = ::socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
        if ( result == INVALID_SOCKET ) {
            const int error = ::WSAGetLastError();
            UNCHECKED_WIN32C_ERROR(socket, error);
        }
        return (w32::net::Socket::claim(result));
    }

    // Create a bound, unconnected stream socket.
    w32::net::StreamSocket create_socket (w32::net::ipv4::EndPoint host)
    {
        cz_trace(" >> Creating socket.");

        w32::net::tcp::Stream stream(create_socket());

        cz_trace(" >> Binding to local address.");

        const ::BOOL result = ::bind(stream.handle(), host.raw(), host.size());
        if (result == SOCKET_ERROR)
        {
            const int error = ::WSAGetLastError();
            UNCHECKED_WIN32C_ERROR(bind, error);
        }

        return (stream);
    }

}

namespace cz {

    SocketChannel::SocketChannel (Engine& engine,
                                  w32::net::StreamSocket& stream,
                                  w32::net::ipv4::EndPoint host,
                                  w32::net::ipv4::EndPoint peer)
        : myEngine(engine)
        , myStream(stream)
        , myHost(host)
        , myPeer(peer)
    {
        // Note: stream is already bound to the completion port at this point.
    }

    const w32::net::ipv4::EndPoint& SocketChannel::host () const
    {
        return (myHost);
    }

    const w32::net::ipv4::EndPoint& SocketChannel::peer () const
    {
        return (myPeer);
    }

    w32::net::StreamSocket& SocketChannel::socket ()
    {
        return (myStream);
    }

    size_t SocketChannel::get (void * data, size_t size)
    {
        Hub::Slave& self = Hub::Slave::self();

        // Start the I/O operation.
        GetRequest request(myEngine, myStream);
        request.start(data, size);

        // Switch to master, it will resume us when it receives a completion
        // notification for the asynchronous I/O operation.
        self.hub().resume();

        return (request.close());
    }

    size_t SocketChannel::put (const void * data, size_t size)
    {
        Hub::Slave& self = Hub::Slave::self();

        // Start the I/O operation.
        PutRequest request(myEngine, myStream);
        request.start(data, size);

        // Switch to master, it will resume us when it receives a completion
        // notification for the asynchronous I/O operation.
        self.hub().resume();

        return (request.close());
    }

    ConnectRequest::ConnectRequest (Engine& engine,
                          w32::net::ipv4::EndPoint host,
                          w32::net::ipv4::EndPoint peer)
        : myRequest(engine)
        , myHost(host)
        , myPeer(peer)
        , mySent(0)
        , myStream(::create_socket(myHost))
    {
        Hub::Slave& self = Hub::Slave::self();

        // Make sure we receive I/O completion notifications :-)
        engine.completion_port().bind(myStream, &engine);
    }

    void ConnectRequest::start ()
    {
        w32::net::tcp::Stream::ConnectEx connect_ex =
            w32::net::tcp::Stream(myStream.handle()).connect_ex();

        cz_trace(" >> Starting connect request.");

        // Start the asynchronous connection request.
        const ::BOOL result = connect_ex(myStream.handle(),
                                         myPeer.raw(),
                                         myPeer.size(),
                                         0, 0, // initial payload.
                                         &mySent,
                                         &myRequest.data());
        if (result == FALSE)
        {
            const ::DWORD error = ::GetLastError();
            if (error != ERROR_IO_PENDING) {
                UNCHECKED_WIN32C_ERROR(ConnectEx, error);
            }
        }
    }

    bool ConnectRequest::ready () const
    {
        return (myRequest.ready());
    }

    SocketChannel * ConnectRequest::close()
    {
        // The hub has resume us, collect results!
        const w32::io::Notification notification = myRequest.notification();

        // Connect requests can be cancelled :-(
        if (notification.aborted()) {
            cz_trace(" >> Connect request cancelled.");
            return (0);
        }

        // Propagate I/O exception to the caller if necessary.
        notification.report_error();

        cz_trace(" >> Connected!");
        cz_trace(" >> Host: " << myHost);
        cz_trace(" >> Peer: " << myPeer);

        // Patch socket for shutdown() and others to work as expected.
        const int result = ::setsockopt(myStream.handle(), SOL_SOCKET,
                                        SO_UPDATE_CONNECT_CONTEXT, 0, 0);
        if (result == SOCKET_ERROR)
        {
            const int error = ::WSAGetLastError();
            UNCHECKED_WIN32C_ERROR(setsockopt, error);
        }

        return (new SocketChannel(myRequest.engine(), myStream, myHost, myPeer));
    }

}
<|endoftext|>


<commit_before>#ifndef _crumbs_configure_hpp__
#define _crumbs_configure_hpp__

// Copyright (c) 2012, Andre Caron (andre.l.caron@gmail.com)
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
//  * Redistributions of source code must retain the above copyright
//    notice, this list of conditions and the following disclaimer.
//
//  * Redistributions in binary form must reproduce the above copyright
//    notice, this list of conditions and the following disclaimer in the
//    documentation and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

// Unless explicitly disabled.
#ifndef CRUMBS_ENABLED
#   define CRUMBS_ENABLED 1
#endif

// Default to single threaded mode.
#if CRUMBS_ENABLED
#   ifndef CRUMBS_SINGLE_THREADED
#      define CRUMBS_SINGLE_THREADED 1
#   endif
#else
#endif

// Introspection is not portable :-(
#ifdef _MSC_VER
#   define CRUMBS_CURRENT_FUNCTION() __FUNCSIG__
#else
#   error "CRUMBS_CURRENT_FUNCTION() is not defined for current compiler."
#endif

#endif /* _crumbs_configure_hpp__ */
<commit_msg>Adds support for G++.<commit_after>#ifndef _crumbs_configure_hpp__
#define _crumbs_configure_hpp__

// Copyright (c) 2012, Andre Caron (andre.l.caron@gmail.com)
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
//  * Redistributions of source code must retain the above copyright
//    notice, this list of conditions and the following disclaimer.
//
//  * Redistributions in binary form must reproduce the above copyright
//    notice, this list of conditions and the following disclaimer in the
//    documentation and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

// Unless explicitly disabled.
#ifndef CRUMBS_ENABLED
#   define CRUMBS_ENABLED 1
#endif

// Default to single threaded mode.
#if CRUMBS_ENABLED
#   ifndef CRUMBS_SINGLE_THREADED
#      define CRUMBS_SINGLE_THREADED 1
#   endif
#else
#endif

// Introspection is not portable :-(
#ifdef _MSC_VER
#   define CRUMBS_CURRENT_FUNCTION() __FUNCSIG__
#elif defined(__GNUC__)
#   define CRUMBS_CURRENT_FUNCTION() __PRETTY_FUNCTION__
#else
#   error "CRUMBS_CURRENT_FUNCTION() is not defined for current compiler."
#endif

#endif /* _crumbs_configure_hpp__ */
<|endoftext|>


<commit_before><commit_msg>Delete json.hpp<commit_after><|endoftext|>


<commit_before><commit_msg>Remove noexcept from lazy<commit_after><|endoftext|>


<commit_before>/* Begin CVS Header
   $Source: /Volumes/Home/Users/shoops/cvs/copasi_dev/copasi/optimization/COptMethodSA.cpp,v $
   $Revision: 1.5 $
   $Name:  $
   $Author: shoops $
   $Date: 2003/10/30 17:58:53 $
   End CVS Header */

/* COptMethodSA code */

/***************************************************************************************
 * This is the implementation of the Simulated Annealing for Optimization.  The
 * class is inherited from the COptAlgorithm class
 *
 *       Implemented by Dingjun Chen
 *  Starting Date: 09/22/03
 *
 ***************************************************************************************/

#define BESTFOUNDSOFAR 2
#define NumDirection 10
#define TRUE 1
#define FALSE 0
// #define PI 3.1415926

#include <vector>
#include <math.h>

#include "copasi.h"
#include "COptMethod.h"
#include "COptMethodSA.h"
#include "CRealProblem.h"
#include "randomGenerator/CRandom.h"

static double PI = 4.0 * atan(1.0);

COptMethodSA::COptMethodSA():
    COptMethod(CCopasiMethod::SimulatedAnnealing)
{
  addParameter("SimulatedAnnealing.Iterations",
               CCopasiParameter::UINT,
               (unsigned C_INT32) 10000);
  addParameter("SimulatedAnnealing.RandomGenerator.Type",
               CCopasiParameter::INT,
               (C_INT32) CRandom::mt19937);
  addParameter("SimulatedAnnealing.RandomGenerator.Seed",
               CCopasiParameter::INT,
               (C_INT32) 0);
}

COptMethodSA::COptMethodSA(const COptMethodSA & src):
    COptMethod(src)
{}

/**
 * Destructor
 */
COptMethodSA::~COptMethodSA(){}

/**
 * Optimizer Function
 * Returns: nothing
 */

C_INT32 COptMethodSA::optimise()
{
  C_FLOAT64 la;
  C_INT32 NumSignificantPoint, NumTempChange, NumIteration = (C_INT32) getValue("SimulatedAnnealing.Iterations");
  C_INT32 j, NumParameter = mParameters->size();

  //variable settings neccessary for SA
  CVector<double> candparameter(NumParameter);  //one-dimentional array of candidate value for parameters
  double candFuncValue;                // candidate value of objective function

  CVector<double> thisparameter(NumParameter);  //current parameters
  double thisFuncValue;                //current value of the objective function

  CVector <double> newparameter(NumParameter);   //new parameter value
  double newFuncValue;     //function value of new point

  CVector <double> step(NumParameter);   //array of maximum steps for each parameter
  CVector <int> NumStepAccep(NumParameter);       //number of steps accepted

  double TempDecreaseRate = 0.85; //temperature decrease rate
  double BoltzmannConstant = 1.0; //Boltzmann constant

  double InitialTemp = 1.0; //initial temperature
  double t;  //current temperature

  double ConvgCriterion = 0.00001; // convergence criterion or program termination criterion
  double ChangeValue, EnergyDifference;

  CVector <double> fk(BESTFOUNDSOFAR);
  bool ready, linear;

  /* Create a random number generator */
  CRandom::Type Type;
  Type = (CRandom::Type) (C_INT32) getValue("SimulatedAnnealing.RandomGenerator.Type");
  unsigned C_INT32 Seed;
  Seed = (unsigned C_INT32) getValue("SimulatedAnnealing.RandomGenerator.Seed");
  CRandom * pRand = CRandom::createGenerator(Type, Seed);

  assert(pRand);

  double * Minimum = mParameterMin->array();
  double * Maximum = mParameterMax->array();
  double * Parameter = mParameters->array();

  //dump_datafile_init()

  //inital temperature
  t = InitialTemp;

  //inital point
  NumSignificantPoint = 0;

  //generate initial parameters randomly
  for (j = 0; j < NumParameter; j++)
    {
      linear = false;
      la = 1.0;

      if (Minimum[j] == 0.0) Minimum[j] = DBL_EPSILON;

      if ((Maximum[j] <= 0.0) || (Minimum[j] <= 0.0)) linear = true;

      else
        {
          la = log10(Maximum[j]) - log10(Minimum[j]);
          if (la < 1.8) linear = true;
        }

      if (linear)
        Parameter[j] =
          Minimum[j] + pRand->getRandomCC() * (Maximum[j] - Minimum[j]);
      else
        Parameter[j] = Minimum[j] * pow(10, la * pRand->getRandomCC());
    } //  Initialization ends

  for (int kk = 0; kk < NumParameter; kk++)
    candparameter[kk] = thisparameter[kk] = newparameter[kk] = Parameter[kk];

  // calculate the function fitness value
  double FitnessValue = mOptProblem->calculate();
  thisFuncValue = candFuncValue = FitnessValue;

  //Remember them
  for (int mm = 0; mm < BESTFOUNDSOFAR; mm++) fk[mm] = thisFuncValue;

  //initial step sizes
  for (int jj = 0; jj < NumParameter; jj++)
    {
      NumStepAccep[jj] = 0;
      step[jj] = fabs(candparameter[jj]);
    }

  //no temperature reductions yet
  NumTempChange = 0;

  do
    {
      for (int ff = 0; ff < NumIteration; ff++) //step adjustments
        {
          std::cout << "New iteration begins ......" << std::endl;
          std::cout << "Current Temperature: " << t << std::endl;
          std::cout << "Number of Temperature Change: " << NumTempChange << std::endl;

          for (j = 0; j < NumDirection; j++) // adjustment in all directions
            {
              for (int hh = 0; hh < NumParameter; hh++)
                {
                  // ChangeValue=tan(2*PI*rand()/RAND_MAX)*(t/pow(pow(2,2.0)+t*t,(NumParameter+1)/2.0));
                  ChangeValue = tan(2 * PI * pRand->getRandomCC()) * (t / pow(pow(2, 2.0) + t * t, (NumParameter + 1) / 2.0));
                  newparameter[hh] = thisparameter[hh] + step[hh] * ChangeValue;

                  if (newparameter[hh] < Minimum[hh]) newparameter[hh] = Minimum[hh] + pRand->getRandomCC() * (Maximum[hh] - Minimum[hh]);
                  if (newparameter[hh] > Maximum[hh]) newparameter[hh] = Minimum[hh] + pRand->getRandomCC() * (Maximum[hh] - Minimum[hh]);
                  for (int exchange = 0; exchange < NumParameter; exchange++)
                    {
                      Parameter[exchange] = newparameter[exchange];
                    }

                  // calculate the function value
                  double FitnessValue = mOptProblem->calculate();
                  newFuncValue = FitnessValue;

                  //Calculate the energy difference
                  EnergyDifference = newFuncValue - thisFuncValue;

                  //keep newparameter if energy is reduced
                  if (newFuncValue <= thisFuncValue)
                    {
                      for (int exchange = 0; exchange < NumParameter; exchange++)
                        {
                          thisparameter[exchange] = newparameter[exchange];
                        }
                      thisFuncValue = newFuncValue;

                      NumSignificantPoint++; // a new point counted
                      NumStepAccep[hh]++; //a new point in this coordinate counted

                      if (thisFuncValue < candFuncValue)
                        {
                          for (int aa = 0; aa < NumParameter; aa++)
                            Parameter[aa] = candparameter[aa] = thisparameter[aa];
                          candFuncValue = thisFuncValue;

                          if (!mOptProblem->checkFunctionalConstraints())
                            continue;

                          //set the  best function value
                          mOptProblem->setBestValue(candFuncValue);
                          std::cout << "the Best value (" << NumSignificantPoint << "): " << candFuncValue << std::endl;

                          //store the combination of the best parameter values found so far at current temperature
                          mOptProblem->getBestParameter() = *mParameters;

                          std::cout << "the Best Parameters: (";
                          for (int kk = 0; kk < mOptProblem->getParameterNum(); kk++)
                            std::cout << mOptProblem->getParameter(kk) << ", ";

                          std::cout << ")" << std::endl;
                        }
                    }
                  else
                    {
                      //keep newparameter with probability, if newFuncValue is increased
                      double Probability = exp(-(newFuncValue - thisFuncValue) / (BoltzmannConstant * t));
                      if (Probability > pRand->getRandomCC())
                        {
                          //Keep the new point
                          for (int exchange = 0; exchange < NumParameter; exchange++)
                            {
                              thisparameter[exchange] = newparameter[exchange];
                            }
                          thisFuncValue = newFuncValue;
                          NumSignificantPoint++; // a new point counted
                          NumStepAccep[hh]++; //a new point in this coordinate counted
                        }
                    }
                }
            }

          //update the step sizes
          for (int nn = 0; nn < NumParameter; nn++)
            {
              double StepAdjustment = (double) NumStepAccep[nn] / (double)NumDirection;
              if (StepAdjustment > 0.6) step[nn] *= 1 + 5 * (StepAdjustment - 0.6);
              if (StepAdjustment < 0.4) step[nn] /= 1 + 5 * (0.4 - StepAdjustment);
              NumStepAccep[nn] = 0;
            }
        }

      //update the temperature
      t *= TempDecreaseRate;
      NumTempChange++;

      // if this is the first cycle then ignore the convergence test
      if (NumTempChange == 1) ready = FALSE;
      else
        {
          ready = TRUE;
          //check if there is not much change for termination criterion since last BESTFOUNDSOFAR times
          for (int ii = 0; ii < BESTFOUNDSOFAR; ii++)
            if (fabs(fk[ii] - thisFuncValue) > ConvgCriterion)
              {
                ready = FALSE;
                break;
              }
          if (!ready)
            {
              for (int aa = 0; aa < BESTFOUNDSOFAR - 1; aa++)
                fk[aa] = fk[aa + 1];
              fk[BESTFOUNDSOFAR - 1] = thisFuncValue;
            }
          else
            //check the termination criterion of not much larger than last optimal
            if (fabs(thisFuncValue - candFuncValue) > ConvgCriterion)ready = FALSE;
        }

      if (!ready)
        {
          NumSignificantPoint++;
          for (int kk = 0; kk < NumParameter; kk++)
            thisparameter[kk] = candparameter[kk];
          thisFuncValue = candFuncValue;
        }
    }
  while (!ready); // do-while loop ends

  pdelete(pRand);
  return 0;
}
<commit_msg>use the M_PI constant from math.h (assuming this is standard and also available on windows)<commit_after>/* Begin CVS Header
   $Source: /Volumes/Home/Users/shoops/cvs/copasi_dev/copasi/optimization/COptMethodSA.cpp,v $
   $Revision: 1.6 $
   $Name:  $
   $Author: ssahle $
   $Date: 2004/06/22 11:01:17 $
   End CVS Header */

/* COptMethodSA code */

/***************************************************************************************
 * This is the implementation of the Simulated Annealing for Optimization.  The
 * class is inherited from the COptAlgorithm class
 *
 *       Implemented by Dingjun Chen
 *  Starting Date: 09/22/03
 *
 ***************************************************************************************/

#define BESTFOUNDSOFAR 2
#define NumDirection 10
#define TRUE 1
#define FALSE 0

#include <vector>
#include <math.h>

#include "copasi.h"
#include "COptMethod.h"
#include "COptMethodSA.h"
#include "CRealProblem.h"
#include "randomGenerator/CRandom.h"

//static double PI = 4.0 * atan(1.0);

COptMethodSA::COptMethodSA():
    COptMethod(CCopasiMethod::SimulatedAnnealing)
{
  addParameter("SimulatedAnnealing.Iterations",
               CCopasiParameter::UINT,
               (unsigned C_INT32) 10000);
  addParameter("SimulatedAnnealing.RandomGenerator.Type",
               CCopasiParameter::INT,
               (C_INT32) CRandom::mt19937);
  addParameter("SimulatedAnnealing.RandomGenerator.Seed",
               CCopasiParameter::INT,
               (C_INT32) 0);
}

COptMethodSA::COptMethodSA(const COptMethodSA & src):
    COptMethod(src)
{}

/**
 * Destructor
 */
COptMethodSA::~COptMethodSA(){}

/**
 * Optimizer Function
 * Returns: nothing
 */

C_INT32 COptMethodSA::optimise()
{
  C_FLOAT64 la;
  C_INT32 NumSignificantPoint, NumTempChange, NumIteration = (C_INT32) getValue("SimulatedAnnealing.Iterations");
  C_INT32 j, NumParameter = mParameters->size();

  //variable settings neccessary for SA
  CVector<double> candparameter(NumParameter);  //one-dimentional array of candidate value for parameters
  double candFuncValue;                // candidate value of objective function

  CVector<double> thisparameter(NumParameter);  //current parameters
  double thisFuncValue;                //current value of the objective function

  CVector <double> newparameter(NumParameter);   //new parameter value
  double newFuncValue;     //function value of new point

  CVector <double> step(NumParameter);   //array of maximum steps for each parameter
  CVector <int> NumStepAccep(NumParameter);       //number of steps accepted

  double TempDecreaseRate = 0.85; //temperature decrease rate
  double BoltzmannConstant = 1.0; //Boltzmann constant

  double InitialTemp = 1.0; //initial temperature
  double t;  //current temperature

  double ConvgCriterion = 0.00001; // convergence criterion or program termination criterion
  double ChangeValue, EnergyDifference;

  CVector <double> fk(BESTFOUNDSOFAR);
  bool ready, linear;

  /* Create a random number generator */
  CRandom::Type Type;
  Type = (CRandom::Type) (C_INT32) getValue("SimulatedAnnealing.RandomGenerator.Type");
  unsigned C_INT32 Seed;
  Seed = (unsigned C_INT32) getValue("SimulatedAnnealing.RandomGenerator.Seed");
  CRandom * pRand = CRandom::createGenerator(Type, Seed);

  assert(pRand);

  double * Minimum = mParameterMin->array();
  double * Maximum = mParameterMax->array();
  double * Parameter = mParameters->array();

  //dump_datafile_init()

  //inital temperature
  t = InitialTemp;

  //inital point
  NumSignificantPoint = 0;

  //generate initial parameters randomly
  for (j = 0; j < NumParameter; j++)
    {
      linear = false;
      la = 1.0;

      if (Minimum[j] == 0.0) Minimum[j] = DBL_EPSILON;

      if ((Maximum[j] <= 0.0) || (Minimum[j] <= 0.0)) linear = true;

      else
        {
          la = log10(Maximum[j]) - log10(Minimum[j]);
          if (la < 1.8) linear = true;
        }

      if (linear)
        Parameter[j] =
          Minimum[j] + pRand->getRandomCC() * (Maximum[j] - Minimum[j]);
      else
        Parameter[j] = Minimum[j] * pow(10, la * pRand->getRandomCC());
    } //  Initialization ends

  for (int kk = 0; kk < NumParameter; kk++)
    candparameter[kk] = thisparameter[kk] = newparameter[kk] = Parameter[kk];

  // calculate the function fitness value
  double FitnessValue = mOptProblem->calculate();
  thisFuncValue = candFuncValue = FitnessValue;

  //Remember them
  for (int mm = 0; mm < BESTFOUNDSOFAR; mm++) fk[mm] = thisFuncValue;

  //initial step sizes
  for (int jj = 0; jj < NumParameter; jj++)
    {
      NumStepAccep[jj] = 0;
      step[jj] = fabs(candparameter[jj]);
    }

  //no temperature reductions yet
  NumTempChange = 0;

  do
    {
      for (int ff = 0; ff < NumIteration; ff++) //step adjustments
        {
          std::cout << "New iteration begins ......" << std::endl;
          std::cout << "Current Temperature: " << t << std::endl;
          std::cout << "Number of Temperature Change: " << NumTempChange << std::endl;

          for (j = 0; j < NumDirection; j++) // adjustment in all directions
            {
              for (int hh = 0; hh < NumParameter; hh++)
                {
                  // ChangeValue=tan(2*PI*rand()/RAND_MAX)*(t/pow(pow(2,2.0)+t*t,(NumParameter+1)/2.0));
                  ChangeValue = tan(2 * M_PI * pRand->getRandomCC()) * (t / pow(pow(2, 2.0) + t * t, (NumParameter + 1) / 2.0));
                  newparameter[hh] = thisparameter[hh] + step[hh] * ChangeValue;

                  if (newparameter[hh] < Minimum[hh]) newparameter[hh] = Minimum[hh] + pRand->getRandomCC() * (Maximum[hh] - Minimum[hh]);
                  if (newparameter[hh] > Maximum[hh]) newparameter[hh] = Minimum[hh] + pRand->getRandomCC() * (Maximum[hh] - Minimum[hh]);
                  for (int exchange = 0; exchange < NumParameter; exchange++)
                    {
                      Parameter[exchange] = newparameter[exchange];
                    }

                  // calculate the function value
                  double FitnessValue = mOptProblem->calculate();
                  newFuncValue = FitnessValue;

                  //Calculate the energy difference
                  EnergyDifference = newFuncValue - thisFuncValue;

                  //keep newparameter if energy is reduced
                  if (newFuncValue <= thisFuncValue)
                    {
                      for (int exchange = 0; exchange < NumParameter; exchange++)
                        {
                          thisparameter[exchange] = newparameter[exchange];
                        }
                      thisFuncValue = newFuncValue;

                      NumSignificantPoint++; // a new point counted
                      NumStepAccep[hh]++; //a new point in this coordinate counted

                      if (thisFuncValue < candFuncValue)
                        {
                          for (int aa = 0; aa < NumParameter; aa++)
                            Parameter[aa] = candparameter[aa] = thisparameter[aa];
                          candFuncValue = thisFuncValue;

                          if (!mOptProblem->checkFunctionalConstraints())
                            continue;

                          //set the  best function value
                          mOptProblem->setBestValue(candFuncValue);
                          std::cout << "the Best value (" << NumSignificantPoint << "): " << candFuncValue << std::endl;

                          //store the combination of the best parameter values found so far at current temperature
                          mOptProblem->getBestParameter() = *mParameters;

                          std::cout << "the Best Parameters: (";
                          for (int kk = 0; kk < mOptProblem->getParameterNum(); kk++)
                            std::cout << mOptProblem->getParameter(kk) << ", ";

                          std::cout << ")" << std::endl;
                        }
                    }
                  else
                    {
                      //keep newparameter with probability, if newFuncValue is increased
                      double Probability = exp(-(newFuncValue - thisFuncValue) / (BoltzmannConstant * t));
                      if (Probability > pRand->getRandomCC())
                        {
                          //Keep the new point
                          for (int exchange = 0; exchange < NumParameter; exchange++)
                            {
                              thisparameter[exchange] = newparameter[exchange];
                            }
                          thisFuncValue = newFuncValue;
                          NumSignificantPoint++; // a new point counted
                          NumStepAccep[hh]++; //a new point in this coordinate counted
                        }
                    }
                }
            }

          //update the step sizes
          for (int nn = 0; nn < NumParameter; nn++)
            {
              double StepAdjustment = (double) NumStepAccep[nn] / (double)NumDirection;
              if (StepAdjustment > 0.6) step[nn] *= 1 + 5 * (StepAdjustment - 0.6);
              if (StepAdjustment < 0.4) step[nn] /= 1 + 5 * (0.4 - StepAdjustment);
              NumStepAccep[nn] = 0;
            }
        }

      //update the temperature
      t *= TempDecreaseRate;
      NumTempChange++;

      // if this is the first cycle then ignore the convergence test
      if (NumTempChange == 1) ready = FALSE;
      else
        {
          ready = TRUE;
          //check if there is not much change for termination criterion since last BESTFOUNDSOFAR times
          for (int ii = 0; ii < BESTFOUNDSOFAR; ii++)
            if (fabs(fk[ii] - thisFuncValue) > ConvgCriterion)
              {
                ready = FALSE;
                break;
              }
          if (!ready)
            {
              for (int aa = 0; aa < BESTFOUNDSOFAR - 1; aa++)
                fk[aa] = fk[aa + 1];
              fk[BESTFOUNDSOFAR - 1] = thisFuncValue;
            }
          else
            //check the termination criterion of not much larger than last optimal
            if (fabs(thisFuncValue - candFuncValue) > ConvgCriterion)ready = FALSE;
        }

      if (!ready)
        {
          NumSignificantPoint++;
          for (int kk = 0; kk < NumParameter; kk++)
            thisparameter[kk] = candparameter[kk];
          thisFuncValue = candFuncValue;
        }
    }
  while (!ready); // do-while loop ends

  pdelete(pRand);
  return 0;
}
<|endoftext|>


<commit_before>be492d9c-2747-11e6-86c6-e0f84713e7b8<commit_msg>fix for the previous fix<commit_after>be58b09e-2747-11e6-8316-e0f84713e7b8<|endoftext|>


<commit_before><commit_msg>fix HIP-clang compile<commit_after><|endoftext|>


<commit_before><commit_msg>I'm done<commit_after><|endoftext|>


<commit_before>#pragma once

// `krbn::event_tap_manager` can be used safely in a multi-threaded environment.

#include "boost_defs.hpp"

#include "cf_utility.hpp"
#include "logger.hpp"
#include <CoreGraphics/CoreGraphics.h>
#include <boost/optional.hpp>
#include <boost/signals2.hpp>

namespace krbn {
class event_tap_manager final {
public:
  // Signals

  boost::signals2::signal<void(bool)> caps_lock_state_changed;
  boost::signals2::signal<void(CGEventType, CGEventRef _Nullable)> pointing_device_event_arrived;

  // Methods

  event_tap_manager(const event_tap_manager&) = delete;

  event_tap_manager(void) : event_tap_(nullptr),
                            run_loop_source_(nullptr) {
    run_loop_thread_ = std::make_unique<cf_utility::run_loop_thread>();
  }

  ~event_tap_manager(void) {
    run_loop_thread_->enqueue(^{
      if (event_tap_) {
        CGEventTapEnable(event_tap_, false);

        if (run_loop_source_) {
          CFRunLoopRemoveSource(run_loop_thread_->get_run_loop(),
                                run_loop_source_,
                                kCFRunLoopCommonModes);
          CFRelease(run_loop_source_);
          run_loop_source_ = nullptr;
        }

        CFRelease(event_tap_);
        event_tap_ = nullptr;
      }
      logger::get_logger().info("event_tap_manager terminated");
    });

    run_loop_thread_ = nullptr;
  }

  void async_start(void) {
    run_loop_thread_->enqueue(^{
      if (event_tap_) {
        return;
      }

      // Observe flags changed in order to get the caps lock state and pointing device events from Apple trackpads.
      //
      // Note:
      // We cannot catch pointing device events from Apple trackpads without eventtap.
      // (Apple trackpad driver does not send events to IOKit.)

      auto mask = CGEventMaskBit(kCGEventFlagsChanged) |
                  CGEventMaskBit(kCGEventLeftMouseDown) |
                  CGEventMaskBit(kCGEventLeftMouseUp) |
                  CGEventMaskBit(kCGEventRightMouseDown) |
                  CGEventMaskBit(kCGEventRightMouseUp) |
                  CGEventMaskBit(kCGEventMouseMoved) |
                  CGEventMaskBit(kCGEventLeftMouseDragged) |
                  CGEventMaskBit(kCGEventRightMouseDragged) |
                  CGEventMaskBit(kCGEventScrollWheel) |
                  CGEventMaskBit(kCGEventOtherMouseDown) |
                  CGEventMaskBit(kCGEventOtherMouseUp) |
                  CGEventMaskBit(kCGEventOtherMouseDragged);

      event_tap_ = CGEventTapCreate(kCGHIDEventTap,
                                    kCGTailAppendEventTap,
                                    kCGEventTapOptionListenOnly,
                                    mask,
                                    event_tap_manager::static_callback,
                                    this);

      if (event_tap_) {
        run_loop_source_ = CFMachPortCreateRunLoopSource(kCFAllocatorDefault, event_tap_, 0);
        if (run_loop_source_) {
          CFRunLoopAddSource(run_loop_thread_->get_run_loop(),
                             run_loop_source_,
                             kCFRunLoopCommonModes);
          CGEventTapEnable(event_tap_, true);

          logger::get_logger().info("event_tap_manager initialized");
        }
      }
    });
  }

private:
  static CGEventRef _Nullable static_callback(CGEventTapProxy _Nullable proxy, CGEventType type, CGEventRef _Nullable event, void* _Nonnull refcon) {
    auto self = static_cast<event_tap_manager*>(refcon);
    if (self) {
      return self->callback(proxy, type, event);
    }
    return nullptr;
  }

  CGEventRef _Nullable callback(CGEventTapProxy _Nullable proxy, CGEventType type, CGEventRef _Nullable event) {
    switch (type) {
      case kCGEventTapDisabledByTimeout:
        logger::get_logger().info("Re-enable event_tap_ by kCGEventTapDisabledByTimeout");
        CGEventTapEnable(event_tap_, true);
        break;

      case kCGEventTapDisabledByUserInput:
        break;

      case kCGEventFlagsChanged:
        // The caps lock key event from keyboard might be ignored by caps lock delay.
        // Thus, we need to observe kCGEventFlagsChanged event in EventTap to detect the caps lock state change.
        if (event) {
          auto old_caps_lock_state = get_caps_lock_state();
          last_flags_ = CGEventGetFlags(event);
          auto new_caps_lock_state = get_caps_lock_state();

          if (old_caps_lock_state &&
              new_caps_lock_state &&
              *old_caps_lock_state == *new_caps_lock_state) {
            // the caps lock state is not changed.
          } else {
            caps_lock_state_changed(*new_caps_lock_state);
          }
        }
        break;

      case kCGEventLeftMouseDown:
      case kCGEventLeftMouseUp:
      case kCGEventRightMouseDown:
      case kCGEventRightMouseUp:
      case kCGEventMouseMoved:
      case kCGEventLeftMouseDragged:
      case kCGEventRightMouseDragged:
      case kCGEventScrollWheel:
      case kCGEventOtherMouseDown:
      case kCGEventOtherMouseUp:
      case kCGEventOtherMouseDragged:
        pointing_device_event_arrived(type, event);
        break;

      case kCGEventNull:
      case kCGEventKeyDown:
      case kCGEventKeyUp:
      case kCGEventTabletPointer:
      case kCGEventTabletProximity:
        // These events are not captured.
        break;
    }

    return event;
  }

  boost::optional<bool> get_caps_lock_state(void) const {
    if (last_flags_) {
      return (*last_flags_ & NX_ALPHASHIFTMASK);
    }
    return boost::none;
  }

  std::unique_ptr<cf_utility::run_loop_thread> run_loop_thread_;
  CFMachPortRef _Nullable event_tap_;
  CFRunLoopSourceRef _Nullable run_loop_source_;
  boost::optional<CGEventFlags> last_flags_;
};
} // namespace krbn
<commit_msg>call run_loop_thread::terminate in event_tap_manager<commit_after>#pragma once

// `krbn::event_tap_manager` can be used safely in a multi-threaded environment.

#include "boost_defs.hpp"

#include "cf_utility.hpp"
#include "logger.hpp"
#include <CoreGraphics/CoreGraphics.h>
#include <boost/optional.hpp>
#include <boost/signals2.hpp>

namespace krbn {
class event_tap_manager final {
public:
  // Signals

  boost::signals2::signal<void(bool)> caps_lock_state_changed;
  boost::signals2::signal<void(CGEventType, CGEventRef _Nullable)> pointing_device_event_arrived;

  // Methods

  event_tap_manager(const event_tap_manager&) = delete;

  event_tap_manager(void) : event_tap_(nullptr),
                            run_loop_source_(nullptr) {
    run_loop_thread_ = std::make_unique<cf_utility::run_loop_thread>();
  }

  ~event_tap_manager(void) {
    run_loop_thread_->enqueue(^{
      if (event_tap_) {
        CGEventTapEnable(event_tap_, false);

        if (run_loop_source_) {
          CFRunLoopRemoveSource(run_loop_thread_->get_run_loop(),
                                run_loop_source_,
                                kCFRunLoopCommonModes);
          CFRelease(run_loop_source_);
          run_loop_source_ = nullptr;
        }

        CFRelease(event_tap_);
        event_tap_ = nullptr;
      }
      logger::get_logger().info("event_tap_manager terminated");
    });

    run_loop_thread_->terminate();
    run_loop_thread_ = nullptr;
  }

  void async_start(void) {
    run_loop_thread_->enqueue(^{
      if (event_tap_) {
        return;
      }

      // Observe flags changed in order to get the caps lock state and pointing device events from Apple trackpads.
      //
      // Note:
      // We cannot catch pointing device events from Apple trackpads without eventtap.
      // (Apple trackpad driver does not send events to IOKit.)

      auto mask = CGEventMaskBit(kCGEventFlagsChanged) |
                  CGEventMaskBit(kCGEventLeftMouseDown) |
                  CGEventMaskBit(kCGEventLeftMouseUp) |
                  CGEventMaskBit(kCGEventRightMouseDown) |
                  CGEventMaskBit(kCGEventRightMouseUp) |
                  CGEventMaskBit(kCGEventMouseMoved) |
                  CGEventMaskBit(kCGEventLeftMouseDragged) |
                  CGEventMaskBit(kCGEventRightMouseDragged) |
                  CGEventMaskBit(kCGEventScrollWheel) |
                  CGEventMaskBit(kCGEventOtherMouseDown) |
                  CGEventMaskBit(kCGEventOtherMouseUp) |
                  CGEventMaskBit(kCGEventOtherMouseDragged);

      event_tap_ = CGEventTapCreate(kCGHIDEventTap,
                                    kCGTailAppendEventTap,
                                    kCGEventTapOptionListenOnly,
                                    mask,
                                    event_tap_manager::static_callback,
                                    this);

      if (event_tap_) {
        run_loop_source_ = CFMachPortCreateRunLoopSource(kCFAllocatorDefault, event_tap_, 0);
        if (run_loop_source_) {
          CFRunLoopAddSource(run_loop_thread_->get_run_loop(),
                             run_loop_source_,
                             kCFRunLoopCommonModes);
          CGEventTapEnable(event_tap_, true);

          logger::get_logger().info("event_tap_manager initialized");
        }
      }
    });
  }

private:
  static CGEventRef _Nullable static_callback(CGEventTapProxy _Nullable proxy, CGEventType type, CGEventRef _Nullable event, void* _Nonnull refcon) {
    auto self = static_cast<event_tap_manager*>(refcon);
    if (self) {
      return self->callback(proxy, type, event);
    }
    return nullptr;
  }

  CGEventRef _Nullable callback(CGEventTapProxy _Nullable proxy, CGEventType type, CGEventRef _Nullable event) {
    switch (type) {
      case kCGEventTapDisabledByTimeout:
        logger::get_logger().info("Re-enable event_tap_ by kCGEventTapDisabledByTimeout");
        CGEventTapEnable(event_tap_, true);
        break;

      case kCGEventTapDisabledByUserInput:
        break;

      case kCGEventFlagsChanged:
        // The caps lock key event from keyboard might be ignored by caps lock delay.
        // Thus, we need to observe kCGEventFlagsChanged event in EventTap to detect the caps lock state change.
        if (event) {
          auto old_caps_lock_state = get_caps_lock_state();
          last_flags_ = CGEventGetFlags(event);
          auto new_caps_lock_state = get_caps_lock_state();

          if (old_caps_lock_state &&
              new_caps_lock_state &&
              *old_caps_lock_state == *new_caps_lock_state) {
            // the caps lock state is not changed.
          } else {
            caps_lock_state_changed(*new_caps_lock_state);
          }
        }
        break;

      case kCGEventLeftMouseDown:
      case kCGEventLeftMouseUp:
      case kCGEventRightMouseDown:
      case kCGEventRightMouseUp:
      case kCGEventMouseMoved:
      case kCGEventLeftMouseDragged:
      case kCGEventRightMouseDragged:
      case kCGEventScrollWheel:
      case kCGEventOtherMouseDown:
      case kCGEventOtherMouseUp:
      case kCGEventOtherMouseDragged:
        pointing_device_event_arrived(type, event);
        break;

      case kCGEventNull:
      case kCGEventKeyDown:
      case kCGEventKeyUp:
      case kCGEventTabletPointer:
      case kCGEventTabletProximity:
        // These events are not captured.
        break;
    }

    return event;
  }

  boost::optional<bool> get_caps_lock_state(void) const {
    if (last_flags_) {
      return (*last_flags_ & NX_ALPHASHIFTMASK);
    }
    return boost::none;
  }

  std::unique_ptr<cf_utility::run_loop_thread> run_loop_thread_;
  CFMachPortRef _Nullable event_tap_;
  CFRunLoopSourceRef _Nullable run_loop_source_;
  boost::optional<CGEventFlags> last_flags_;
};
} // namespace krbn
<|endoftext|>


<commit_before>#include "WinImpl.h"

#ifdef SFML_SYSTEM_WINDOWS
#include <Windows.h>
#endif

WinImpl::WinImpl()
{
}

WinImpl::~WinImpl()
{
}

// Windows Implementation

#if defined SFML_SYSTEM_WINDOWS

unsigned window_count = 0;

LRESULT CALLBACK globalCallback(HWND handle, UINT message, WPARAM wParam, LPARAM lParam)
{
	// Associate handle and Window instance when the creation message is received
	if (message == WM_CREATE)
	{
		// Get Gwindow instance (it was passed as the last argument of CreateWindow)
		LONG_PTR window = (LONG_PTR)reinterpret_cast<CREATESTRUCT*>(lParam)->lpCreateParams;

		// Set as the "user data" parameter of the window
		SetWindowLongPtrW(handle, GWLP_USERDATA, window);
	}

	//// Get the WindowImpl instance corresponding to the window handle
	//gWindow* window = handle ? reinterpret_cast<gWindow*>(GetWindowLongPtr(handle, GWLP_USERDATA)) : NULL;

	//// Forward the event to the appropriate function
	//if (window)
	//{
	//	window->processEvent(message, wParam, lParam);

	//	if (window->m_callback)
	//		return CallWindowProcW(reinterpret_cast<WNDPROC>(window->m_callback), handle, message, wParam, lParam);
	//}

	// We don't forward the WM_CLOSE message to prevent the OS from automatically destroying the window
	if (message == WM_CLOSE)
		return 0;

	// Don't forward the menu system command, so that pressing ALT or F10 doesn't steal the focus
	if ((message == WM_SYSCOMMAND) && (wParam == SC_KEYMENU))
		return 0;

	return DefWindowProcW(handle, message, wParam, lParam);
}

gWindowHandle WinImpl::createHandle(int x, int y, int width, int height) {
	if (window_count == 0) {
		WNDCLASSW window_class;
		window_class.style = CS_DROPSHADOW;
		window_class.lpfnWndProc = &globalCallback;
		window_class.cbClsExtra = 0;
		window_class.cbWndExtra = 0;
		window_class.hInstance = GetModuleHandleW(NULL);
		window_class.hIcon = NULL;
		window_class.hCursor = 0;
		window_class.hbrBackground = 0;
		window_class.lpszMenuName = NULL;
		window_class.lpszClassName = L"gSplasher_Window";
		RegisterClassW(&window_class);
	}

	DWORD win_style = WS_EX_LAYERED | WS_POPUP;

	RECT rect = { 0, 0, width, height };
	AdjustWindowRect(&rect, win_style, false);
	width = rect.right - rect.left;
	height = rect.bottom - rect.top;

	HWND w_hwnd = CreateWindowExW(
		WS_EX_LAYERED | WS_EX_TOOLWINDOW,
		L"gSplasher_Window",
		nullptr,
		WS_POPUP | WS_VISIBLE,
		x,
		y,
		width,
		height,
		nullptr,
		nullptr,
		GetModuleHandle(nullptr),
		this
		);
	++window_count;

	return w_hwnd;
}

void WinImpl::processEvents() {
	MSG message;
	while (PeekMessageW(&message, NULL, 0, 0, PM_REMOVE))
	{
		TranslateMessage(&message);
		DispatchMessageW(&message);
	}
}

void WinImpl::setTransparency(gWindowHandle handle, unsigned char alpha) {
	SetLayeredWindowAttributes(handle, 0, alpha, LWA_ALPHA);
}

void WinImpl::redraw(gWindowHandle handle, int x, int y, int width, int height) {
	int m = 20;
	int btm_x = x + width - (m + 3);
	int btm_y = y + height;
	int c_offset_x = x + width - m;
	int c_offset_y = y;

	HRGN window_shape = CreateRoundRectRgn(
		x,
		y,
		btm_x,
		btm_y,
		3,
		3);

	HRGN exit_shape = CreateEllipticRgn(
		c_offset_x,
		c_offset_y,
		c_offset_x + m,
		c_offset_y + m
		);

	c_offset_y += 10;
	HRGN minimize_shape = CreateEllipticRgn(
		c_offset_x,
		c_offset_y,
		c_offset_x + m,
		c_offset_y + m
		);

	CombineRgn(window_shape, exit_shape, window_shape, RGN_OR);

	SetWindowRgn(handle, window_shape, true);
	DeleteObject(window_shape);
	DeleteObject(exit_shape);
	DeleteObject(minimize_shape);
}
#endif
<commit_msg>Customized exit shape;<commit_after>#include "WinImpl.h"
#include <string>
#include <SFML/Graphics/Image.hpp>

#ifdef SFML_SYSTEM_WINDOWS
#include <Windows.h>
#endif

WinImpl::WinImpl()
{
}

WinImpl::~WinImpl()
{
}

// Windows Implementation

#if defined SFML_SYSTEM_WINDOWS

unsigned window_count = 0;

LRESULT CALLBACK globalCallback(HWND handle, UINT message, WPARAM wParam, LPARAM lParam)
{
	// Associate handle and Window instance when the creation message is received
	if (message == WM_CREATE)
	{
		// Get Gwindow instance (it was passed as the last argument of CreateWindow)
		LONG_PTR window = (LONG_PTR)reinterpret_cast<CREATESTRUCT*>(lParam)->lpCreateParams;

		// Set as the "user data" parameter of the window
		SetWindowLongPtrW(handle, GWLP_USERDATA, window);
	}

	//// Get the WindowImpl instance corresponding to the window handle
	//gWindow* window = handle ? reinterpret_cast<gWindow*>(GetWindowLongPtr(handle, GWLP_USERDATA)) : NULL;

	//// Forward the event to the appropriate function
	//if (window)
	//{
	//	window->processEvent(message, wParam, lParam);

	//	if (window->m_callback)
	//		return CallWindowProcW(reinterpret_cast<WNDPROC>(window->m_callback), handle, message, wParam, lParam);
	//}

	// We don't forward the WM_CLOSE message to prevent the OS from automatically destroying the window
	if (message == WM_CLOSE)
		return 0;

	// Don't forward the menu system command, so that pressing ALT or F10 doesn't steal the focus
	if ((message == WM_SYSCOMMAND) && (wParam == SC_KEYMENU))
		return 0;

	return DefWindowProcW(handle, message, wParam, lParam);
}

gWindowHandle WinImpl::createHandle(int x, int y, int width, int height) {
	if (window_count == 0) {
		WNDCLASSW window_class;
		window_class.style = CS_DROPSHADOW;
		window_class.lpfnWndProc = &globalCallback;
		window_class.cbClsExtra = 0;
		window_class.cbWndExtra = 0;
		window_class.hInstance = GetModuleHandleW(NULL);
		window_class.hIcon = NULL;
		window_class.hCursor = 0;
		window_class.hbrBackground = 0;
		window_class.lpszMenuName = NULL;
		window_class.lpszClassName = L"gSplasher_Window";
		RegisterClassW(&window_class);
	}

	DWORD win_style = WS_EX_LAYERED | WS_POPUP;

	RECT rect = { 0, 0, width, height };
	AdjustWindowRect(&rect, win_style, false);
	width = rect.right - rect.left;
	height = rect.bottom - rect.top;

	HWND w_hwnd = CreateWindowExW(
		WS_EX_LAYERED | WS_EX_TOOLWINDOW,
		L"gSplasher_Window",
		nullptr,
		WS_POPUP | WS_VISIBLE,
		x,
		y,
		width,
		height,
		nullptr,
		nullptr,
		GetModuleHandle(nullptr),
		this
		);
	++window_count;

	return w_hwnd;
}

void WinImpl::processEvents() {
	MSG message;
	while (PeekMessageW(&message, NULL, 0, 0, PM_REMOVE))
	{
		TranslateMessage(&message);
		DispatchMessageW(&message);
	}
}

void WinImpl::setTransparency(gWindowHandle handle, unsigned char alpha) {
	SetLayeredWindowAttributes(handle, 0, alpha, LWA_ALPHA);
}

HRGN createShape(std::string path_to_file, int x, int y) {
	sf::Image image;
	image.loadFromFile(path_to_file) ? printf("true") : printf("false");

	int offset_x = x + image.getSize().x;
	int offset_y = y + image.getSize().y;

	const sf::Uint8* pixelData = image.getPixelsPtr();
	HRGN hRegion = CreateRectRgn(x, y, offset_x, offset_y);

	// Determine the visible region
	for (unsigned y2 = 0; y2 < image.getSize().y; y2++)
	{
		for (unsigned x2 = 0; x2 < image.getSize().x; x2++)
		{
			if (pixelData[y2 * image.getSize().x * 4 + x2 * 4 + 3] == 0)
			{
				HRGN hRegionPixel = CreateRectRgn(x+x2, y+y2, x+x2 + 1, y+y2 + 1);
				CombineRgn(hRegion, hRegion, hRegionPixel, RGN_XOR);
				DeleteObject(hRegionPixel);
			}
		}
	}

	// WARNING: remember to delete object!!!
	return hRegion;
}

void WinImpl::redraw(gWindowHandle handle, int x, int y, int width, int height) {
	int m = 30;
	int btm_x = x + width - (m + 3);
	int btm_y = y + height;
	int c_offset_x = x + width - m;
	int c_offset_y = y;

	HRGN window_shape = CreateRoundRectRgn(
		x,
		y,
		btm_x,
		btm_y,
		3,
		3);

	HRGN exit_shape = createShape(
		"C:/Users/Autriche/Documents/Code/gSplasher/gSplasher/Reference/icon/add_normal.png",
		c_offset_x, c_offset_y);

	c_offset_y += 10;
	HRGN minimize_shape = CreateEllipticRgn(
		c_offset_x,
		c_offset_y,
		c_offset_x + m,
		c_offset_y + m
		);

	CombineRgn(window_shape, exit_shape, window_shape, RGN_OR);

	SetWindowRgn(handle, window_shape, true);
	DeleteObject(window_shape);
	DeleteObject(exit_shape);
	DeleteObject(minimize_shape);
}

#endif
<|endoftext|>