<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: Function.cxx,v $
 *
 *  $Revision: 1.2 $
 *
 *  last change: $Author: rt $ $Date: 2007-07-09 11:56:14 $
 *
 *  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 RPT_FUNCTION_HXX
#include "Function.hxx"
#endif
#ifndef _COM_SUN_STAR_BEANS_PROPERTYATTRIBUTE_HPP_
#include <com/sun/star/beans/PropertyAttribute.hpp>
#endif
#ifndef REPORTDESIGN_SHARED_CORESTRINGS_HRC
#include "corestrings.hrc"
#endif
#ifndef _TOOLS_DEBUG_HXX
#include <tools/debug.hxx>
#endif
#ifndef _CONNECTIVITY_DBTOOLS_HXX_
#include <connectivity/dbtools.hxx>
#endif
#ifndef _COMPHELPER_SEQUENCE_HXX_
#include <comphelper/sequence.hxx>
#endif
#ifndef _COMPHELPER_PROPERTY_HXX_
#include <comphelper/property.hxx>
#endif
#ifndef REPORTDESIGN_TOOLS_HXX
#include "Tools.hxx"
#endif
#include "corestrings.hrc"
// =============================================================================
namespace reportdesign
{
// =============================================================================
    using namespace com::sun::star;
    using namespace comphelper;
//------------------------------------------------------------------------------
uno::Reference< uno::XInterface > OFunction::create(uno::Reference< uno::XComponentContext > const & xContext)
{
    return *(new OFunction(xContext));
}

DBG_NAME( rpt_OFunction )
// -----------------------------------------------------------------------------
OFunction::OFunction(uno::Reference< uno::XComponentContext > const & _xContext)
:FunctionBase(m_aMutex)
,FunctionPropertySet(_xContext,static_cast< Implements >(IMPLEMENTS_PROPERTY_SET),uno::Sequence< ::rtl::OUString >())
,m_xContext(_xContext)
,m_bPreEvaluated(sal_False)
,m_bDeepTraversing(sal_False)
{
    m_sInitialFormula.IsPresent = sal_False;
    DBG_CTOR( rpt_OFunction,NULL);
}
// -----------------------------------------------------------------------------
OFunction::~OFunction()
{
    DBG_DTOR( rpt_OFunction,NULL);
}
// -----------------------------------------------------------------------------
IMPLEMENT_FORWARD_XINTERFACE2(OFunction,FunctionBase,FunctionPropertySet)
// -----------------------------------------------------------------------------
void SAL_CALL OFunction::dispose() throw(uno::RuntimeException)
{
    FunctionPropertySet::dispose();
    cppu::WeakComponentImplHelperBase::dispose();
}
// -----------------------------------------------------------------------------
::rtl::OUString OFunction::getImplementationName_Static(  ) throw(uno::RuntimeException)
{
    return ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.comp.report.OFunction"));
}

//--------------------------------------------------------------------------
::rtl::OUString SAL_CALL OFunction::getImplementationName(  ) throw(uno::RuntimeException)
{
    return getImplementationName_Static();
}
//--------------------------------------------------------------------------
uno::Sequence< ::rtl::OUString > OFunction::getSupportedServiceNames_Static(  ) throw(uno::RuntimeException)
{
    uno::Sequence< ::rtl::OUString > aServices(1);
    aServices.getArray()[0] = SERVICE_FUNCTION;

    return aServices;
}
//--------------------------------------------------------------------------
uno::Sequence< ::rtl::OUString > SAL_CALL OFunction::getSupportedServiceNames(  ) throw(uno::RuntimeException)
{
    return getSupportedServiceNames_Static();
}
//------------------------------------------------------------------------------
sal_Bool SAL_CALL OFunction::supportsService(const ::rtl::OUString& ServiceName) throw( uno::RuntimeException )
{
    return ::comphelper::existsValue(ServiceName,getSupportedServiceNames_Static());
}
// -----------------------------------------------------------------------------
uno::Reference< beans::XPropertySetInfo > SAL_CALL OFunction::getPropertySetInfo(  ) throw(uno::RuntimeException)
{
    return FunctionPropertySet::getPropertySetInfo();
}
// -----------------------------------------------------------------------------
void SAL_CALL OFunction::setPropertyValue( const ::rtl::OUString& aPropertyName, const uno::Any& aValue ) throw (beans::UnknownPropertyException, beans::PropertyVetoException, lang::IllegalArgumentException, lang::WrappedTargetException, uno::RuntimeException)
{
    FunctionPropertySet::setPropertyValue( aPropertyName, aValue );
}
// -----------------------------------------------------------------------------
uno::Any SAL_CALL OFunction::getPropertyValue( const ::rtl::OUString& PropertyName ) throw (beans::UnknownPropertyException, lang::WrappedTargetException, uno::RuntimeException)
{
    return FunctionPropertySet::getPropertyValue( PropertyName);
}
// -----------------------------------------------------------------------------
void SAL_CALL OFunction::addPropertyChangeListener( const ::rtl::OUString& aPropertyName, const uno::Reference< beans::XPropertyChangeListener >& xListener ) throw (beans::UnknownPropertyException, lang::WrappedTargetException, uno::RuntimeException)
{
    FunctionPropertySet::addPropertyChangeListener( aPropertyName, xListener );
}
// -----------------------------------------------------------------------------
void SAL_CALL OFunction::removePropertyChangeListener( const ::rtl::OUString& aPropertyName, const uno::Reference< beans::XPropertyChangeListener >& aListener ) throw (beans::UnknownPropertyException, lang::WrappedTargetException, uno::RuntimeException)
{
    FunctionPropertySet::removePropertyChangeListener( aPropertyName, aListener );
}
// -----------------------------------------------------------------------------
void SAL_CALL OFunction::addVetoableChangeListener( const ::rtl::OUString& PropertyName, const uno::Reference< beans::XVetoableChangeListener >& aListener ) throw (beans::UnknownPropertyException, lang::WrappedTargetException, uno::RuntimeException)
{
    FunctionPropertySet::addVetoableChangeListener( PropertyName, aListener );
}
// -----------------------------------------------------------------------------
void SAL_CALL OFunction::removeVetoableChangeListener( const ::rtl::OUString& PropertyName, const uno::Reference< beans::XVetoableChangeListener >& aListener ) throw (beans::UnknownPropertyException, lang::WrappedTargetException, uno::RuntimeException)
{
    FunctionPropertySet::removeVetoableChangeListener( PropertyName, aListener );
}
// -----------------------------------------------------------------------------
// report::XFunction:
::sal_Bool SAL_CALL OFunction::getPreEvaluated() throw (uno::RuntimeException)
{
    osl::MutexGuard g(m_aMutex);
    return m_bPreEvaluated;
}
// -----------------------------------------------------------------------------

void SAL_CALL OFunction::setPreEvaluated(::sal_Bool the_value) throw (uno::RuntimeException)
{
    set(PROPERTY_PREEVALUATED,the_value,m_bPreEvaluated);
}
// -----------------------------------------------------------------------------
::sal_Bool SAL_CALL OFunction::getDeepTraversing() throw (uno::RuntimeException)
{
    osl::MutexGuard g(m_aMutex);
    return m_bDeepTraversing;
}
// -----------------------------------------------------------------------------

void SAL_CALL OFunction::setDeepTraversing(::sal_Bool the_value) throw (uno::RuntimeException)
{
    set(PROPERTY_DEEPTRAVERSING,the_value,m_bPreEvaluated);
}
// -----------------------------------------------------------------------------

::rtl::OUString SAL_CALL OFunction::getName() throw (uno::RuntimeException)
{
    osl::MutexGuard g(m_aMutex);
    return m_sName;
}
// -----------------------------------------------------------------------------

void SAL_CALL OFunction::setName(const ::rtl::OUString & the_value) throw (uno::RuntimeException)
{
    set(PROPERTY_NAME,the_value,m_sName);
}
// -----------------------------------------------------------------------------
::rtl::OUString SAL_CALL OFunction::getFormula() throw (uno::RuntimeException)
{
    osl::MutexGuard g(m_aMutex);
    return m_sFormula;
}
// -----------------------------------------------------------------------------
void SAL_CALL OFunction::setFormula(const ::rtl::OUString & the_value) throw (uno::RuntimeException)
{
    set(PROPERTY_FORMULA,the_value,m_sFormula);
}
// -----------------------------------------------------------------------------
beans::Optional< ::rtl::OUString> SAL_CALL OFunction::getInitialFormula() throw (uno::RuntimeException)
{
    osl::MutexGuard g(m_aMutex);
    return m_sInitialFormula;
}
// -----------------------------------------------------------------------------
void SAL_CALL OFunction::setInitialFormula(const beans::Optional< ::rtl::OUString> & the_value) throw (uno::RuntimeException)
{
    set(PROPERTY_INITIALFORMULA,the_value,m_sInitialFormula);
}
// -----------------------------------------------------------------------------
// XChild
uno::Reference< uno::XInterface > SAL_CALL OFunction::getParent(  ) throw (uno::RuntimeException)
{
    osl::MutexGuard g(m_aMutex);
    return m_xParent;
}
// -----------------------------------------------------------------------------
void SAL_CALL OFunction::setParent( const uno::Reference< uno::XInterface >& Parent ) throw (lang::NoSupportException, uno::RuntimeException)
{
    osl::MutexGuard g(m_aMutex);
    if ( Parent.is() )
    {
        uno::Reference< report::XFunctions> xFunctions(Parent,uno::UNO_QUERY_THROW);
        m_xParent = xFunctions;
    }
    else
        m_xParent = uno::WeakReference< report::XFunctions >();
}
// -----------------------------------------------------------------------------

// =============================================================================
} // namespace reportdesign
// =============================================================================
<commit_msg>INTEGRATION: CWS rpt23fix01 (1.2.2); FILE MERGED 2007/07/12 12:59:56 oj 1.2.2.1: #i77832# #i77146# impl group on and interval<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: Function.cxx,v $
 *
 *  $Revision: 1.3 $
 *
 *  last change: $Author: hr $ $Date: 2007-08-02 14:29:49 $
 *
 *  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 RPT_FUNCTION_HXX
#include "Function.hxx"
#endif
#ifndef _COM_SUN_STAR_BEANS_PROPERTYATTRIBUTE_HPP_
#include <com/sun/star/beans/PropertyAttribute.hpp>
#endif
#ifndef REPORTDESIGN_SHARED_CORESTRINGS_HRC
#include "corestrings.hrc"
#endif
#ifndef _TOOLS_DEBUG_HXX
#include <tools/debug.hxx>
#endif
#ifndef _CONNECTIVITY_DBTOOLS_HXX_
#include <connectivity/dbtools.hxx>
#endif
#ifndef _COMPHELPER_SEQUENCE_HXX_
#include <comphelper/sequence.hxx>
#endif
#ifndef _COMPHELPER_PROPERTY_HXX_
#include <comphelper/property.hxx>
#endif
#ifndef REPORTDESIGN_TOOLS_HXX
#include "Tools.hxx"
#endif
#include "corestrings.hrc"
// =============================================================================
namespace reportdesign
{
// =============================================================================
    using namespace com::sun::star;
    using namespace comphelper;
//------------------------------------------------------------------------------
uno::Reference< uno::XInterface > OFunction::create(uno::Reference< uno::XComponentContext > const & xContext)
{
    return *(new OFunction(xContext));
}

DBG_NAME( rpt_OFunction )
// -----------------------------------------------------------------------------
OFunction::OFunction(uno::Reference< uno::XComponentContext > const & _xContext)
:FunctionBase(m_aMutex)
,FunctionPropertySet(_xContext,static_cast< Implements >(IMPLEMENTS_PROPERTY_SET),uno::Sequence< ::rtl::OUString >())
,m_xContext(_xContext)
,m_bPreEvaluated(sal_False)
,m_bDeepTraversing(sal_False)
{
    m_sInitialFormula.IsPresent = sal_False;
    DBG_CTOR( rpt_OFunction,NULL);
}
// -----------------------------------------------------------------------------
OFunction::~OFunction()
{
    DBG_DTOR( rpt_OFunction,NULL);
}
// -----------------------------------------------------------------------------
IMPLEMENT_FORWARD_XINTERFACE2(OFunction,FunctionBase,FunctionPropertySet)
// -----------------------------------------------------------------------------
void SAL_CALL OFunction::dispose() throw(uno::RuntimeException)
{
    FunctionPropertySet::dispose();
    cppu::WeakComponentImplHelperBase::dispose();
}
// -----------------------------------------------------------------------------
::rtl::OUString OFunction::getImplementationName_Static(  ) throw(uno::RuntimeException)
{
    return ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.comp.report.OFunction"));
}

//--------------------------------------------------------------------------
::rtl::OUString SAL_CALL OFunction::getImplementationName(  ) throw(uno::RuntimeException)
{
    return getImplementationName_Static();
}
//--------------------------------------------------------------------------
uno::Sequence< ::rtl::OUString > OFunction::getSupportedServiceNames_Static(  ) throw(uno::RuntimeException)
{
    uno::Sequence< ::rtl::OUString > aServices(1);
    aServices.getArray()[0] = SERVICE_FUNCTION;

    return aServices;
}
//--------------------------------------------------------------------------
uno::Sequence< ::rtl::OUString > SAL_CALL OFunction::getSupportedServiceNames(  ) throw(uno::RuntimeException)
{
    return getSupportedServiceNames_Static();
}
//------------------------------------------------------------------------------
sal_Bool SAL_CALL OFunction::supportsService(const ::rtl::OUString& ServiceName) throw( uno::RuntimeException )
{
    return ::comphelper::existsValue(ServiceName,getSupportedServiceNames_Static());
}
// -----------------------------------------------------------------------------
uno::Reference< beans::XPropertySetInfo > SAL_CALL OFunction::getPropertySetInfo(  ) throw(uno::RuntimeException)
{
    return FunctionPropertySet::getPropertySetInfo();
}
// -----------------------------------------------------------------------------
void SAL_CALL OFunction::setPropertyValue( const ::rtl::OUString& aPropertyName, const uno::Any& aValue ) throw (beans::UnknownPropertyException, beans::PropertyVetoException, lang::IllegalArgumentException, lang::WrappedTargetException, uno::RuntimeException)
{
    FunctionPropertySet::setPropertyValue( aPropertyName, aValue );
}
// -----------------------------------------------------------------------------
uno::Any SAL_CALL OFunction::getPropertyValue( const ::rtl::OUString& PropertyName ) throw (beans::UnknownPropertyException, lang::WrappedTargetException, uno::RuntimeException)
{
    return FunctionPropertySet::getPropertyValue( PropertyName);
}
// -----------------------------------------------------------------------------
void SAL_CALL OFunction::addPropertyChangeListener( const ::rtl::OUString& aPropertyName, const uno::Reference< beans::XPropertyChangeListener >& xListener ) throw (beans::UnknownPropertyException, lang::WrappedTargetException, uno::RuntimeException)
{
    FunctionPropertySet::addPropertyChangeListener( aPropertyName, xListener );
}
// -----------------------------------------------------------------------------
void SAL_CALL OFunction::removePropertyChangeListener( const ::rtl::OUString& aPropertyName, const uno::Reference< beans::XPropertyChangeListener >& aListener ) throw (beans::UnknownPropertyException, lang::WrappedTargetException, uno::RuntimeException)
{
    FunctionPropertySet::removePropertyChangeListener( aPropertyName, aListener );
}
// -----------------------------------------------------------------------------
void SAL_CALL OFunction::addVetoableChangeListener( const ::rtl::OUString& PropertyName, const uno::Reference< beans::XVetoableChangeListener >& aListener ) throw (beans::UnknownPropertyException, lang::WrappedTargetException, uno::RuntimeException)
{
    FunctionPropertySet::addVetoableChangeListener( PropertyName, aListener );
}
// -----------------------------------------------------------------------------
void SAL_CALL OFunction::removeVetoableChangeListener( const ::rtl::OUString& PropertyName, const uno::Reference< beans::XVetoableChangeListener >& aListener ) throw (beans::UnknownPropertyException, lang::WrappedTargetException, uno::RuntimeException)
{
    FunctionPropertySet::removeVetoableChangeListener( PropertyName, aListener );
}
// -----------------------------------------------------------------------------
// report::XFunction:
::sal_Bool SAL_CALL OFunction::getPreEvaluated() throw (uno::RuntimeException)
{
    osl::MutexGuard g(m_aMutex);
    return m_bPreEvaluated;
}
// -----------------------------------------------------------------------------

void SAL_CALL OFunction::setPreEvaluated(::sal_Bool the_value) throw (uno::RuntimeException)
{
    set(PROPERTY_PREEVALUATED,the_value,m_bPreEvaluated);
}
// -----------------------------------------------------------------------------
::sal_Bool SAL_CALL OFunction::getDeepTraversing() throw (uno::RuntimeException)
{
    osl::MutexGuard g(m_aMutex);
    return m_bDeepTraversing;
}
// -----------------------------------------------------------------------------

void SAL_CALL OFunction::setDeepTraversing(::sal_Bool the_value) throw (uno::RuntimeException)
{
    set(PROPERTY_DEEPTRAVERSING,the_value,m_bDeepTraversing);
}
// -----------------------------------------------------------------------------

::rtl::OUString SAL_CALL OFunction::getName() throw (uno::RuntimeException)
{
    osl::MutexGuard g(m_aMutex);
    return m_sName;
}
// -----------------------------------------------------------------------------

void SAL_CALL OFunction::setName(const ::rtl::OUString & the_value) throw (uno::RuntimeException)
{
    set(PROPERTY_NAME,the_value,m_sName);
}
// -----------------------------------------------------------------------------
::rtl::OUString SAL_CALL OFunction::getFormula() throw (uno::RuntimeException)
{
    osl::MutexGuard g(m_aMutex);
    return m_sFormula;
}
// -----------------------------------------------------------------------------
void SAL_CALL OFunction::setFormula(const ::rtl::OUString & the_value) throw (uno::RuntimeException)
{
    set(PROPERTY_FORMULA,the_value,m_sFormula);
}
// -----------------------------------------------------------------------------
beans::Optional< ::rtl::OUString> SAL_CALL OFunction::getInitialFormula() throw (uno::RuntimeException)
{
    osl::MutexGuard g(m_aMutex);
    return m_sInitialFormula;
}
// -----------------------------------------------------------------------------
void SAL_CALL OFunction::setInitialFormula(const beans::Optional< ::rtl::OUString> & the_value) throw (uno::RuntimeException)
{
    set(PROPERTY_INITIALFORMULA,the_value,m_sInitialFormula);
}
// -----------------------------------------------------------------------------
// XChild
uno::Reference< uno::XInterface > SAL_CALL OFunction::getParent(  ) throw (uno::RuntimeException)
{
    osl::MutexGuard g(m_aMutex);
    return m_xParent;
}
// -----------------------------------------------------------------------------
void SAL_CALL OFunction::setParent( const uno::Reference< uno::XInterface >& Parent ) throw (lang::NoSupportException, uno::RuntimeException)
{
    osl::MutexGuard g(m_aMutex);
    if ( Parent.is() )
    {
        uno::Reference< report::XFunctions> xFunctions(Parent,uno::UNO_QUERY_THROW);
        m_xParent = xFunctions;
    }
    else
        m_xParent = uno::WeakReference< report::XFunctions >();
}
// -----------------------------------------------------------------------------

// =============================================================================
} // namespace reportdesign
// =============================================================================
<|endoftext|>


<commit_before>/** \copyright
 * Copyright (c) 2016, Balazs Racz
 * 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.
 *
 * \file Esp8266GPIO.hxx
 *
 * Helper declarations for using GPIO pins on the Esp8266 MCU.
 *
 * @author Balazs Racz
 * @date 16 May 2016
 */

#ifndef _DRIVERS_ESP8266_ESP8266GPIO_HXX_
#define _DRIVERS_ESP8266_ESP8266GPIO_HXX_

#include "os/Gpio.hxx"

extern "C" {
#include <gpio.h>
#include <eagle_soc.h>
}

constexpr uint32_t pinmux_to_gpio_arr[] = {
    PERIPHS_IO_MUX_GPIO0_U, // 0
    PERIPHS_IO_MUX_U0TXD_U, // 1
    PERIPHS_IO_MUX_GPIO2_U, // 2
    PERIPHS_IO_MUX_U0RXD_U, // 3
    PERIPHS_IO_MUX_GPIO4_U, // 4
    PERIPHS_IO_MUX_GPIO5_U, // 5
    PERIPHS_IO_MUX_SD_CLK_U, // 6
    PERIPHS_IO_MUX_SD_DATA0_U, // 7
    PERIPHS_IO_MUX_SD_DATA1_U, // 8
    PERIPHS_IO_MUX_SD_DATA2_U, // 9
    PERIPHS_IO_MUX_SD_DATA3_U, // 10
    PERIPHS_IO_MUX_SD_CMD_U, // 11
    PERIPHS_IO_MUX_MTDI_U, // 12
    PERIPHS_IO_MUX_MTCK_U, // 13
    PERIPHS_IO_MUX_MTMS_U, // 14
    PERIPHS_IO_MUX_MTDO_U, // 15
};

constexpr uint32_t gpio_num_to_pinmux_reg(int gpio_pin_num)
{
    return pinmux_to_gpio_arr[gpio_pin_num];
}

/// Defines a GPIO output pin. Writes to this structure will change the output
/// level of the pin. Reads will return the pin's current level.
///
/// The pin is set to output at initialization time, with the level defined by
/// `SAFE_VALUE'.
///
/// Do not use this class directly. Use @ref GPIO_PIN instead.
template <int PIN_NUM, uint32_t MUXREG, uint32_t FUNC_GPIO>
class Esp8266StaticGpio
{
public:
    static constexpr const uint32_t PIN = PIN_NUM;
    static constexpr const uint32_t PIN_BIT = (1 << PIN_NUM);
    static constexpr const uint32_t PIN_MUX_REG = MUXREG;
    static constexpr const uint32_t PIN_MUX_FUNC_GPIO = FUNC_GPIO;

    static void set_gpio()
    {
        PIN_FUNC_SELECT(PIN_MUX_REG, PIN_MUX_FUNC_GPIO);
    }

    static void set_output()
    {
        GPIO_REG_WRITE(GPIO_ENABLE_W1TS_ADDRESS, PIN_BIT);
    }

    static void set_input()
    {
        GPIO_REG_WRITE(GPIO_ENABLE_W1TC_ADDRESS, PIN_BIT);
    }

    static void set_pullup_on()
    {
        PIN_PULLUP_EN(PIN_MUX_REG);
    }

    static void set_pullup_off()
    {
        PIN_PULLUP_DIS(PIN_MUX_REG);
    }

    static void set_on()
    {
        GPIO_REG_WRITE(GPIO_OUT_W1TS_ADDRESS, PIN_BIT);
    }

    static void set_off()
    {
        GPIO_REG_WRITE(GPIO_OUT_W1TC_ADDRESS, PIN_BIT);
    }

    static bool get()
    {
        return (GPIO_REG_READ(GPIO_IN_ADDRESS) & PIN_BIT) != 0;
    }

    static void set(bool value)
    {
        if (value)
        {
            set_on();
        }
        else
        {
            set_off();
        }
    }

    static void toggle()
    {
        set(!get());
    }

    static bool is_output()
    {
        return GPIO_REG_READ(GPIO_ENABLE_ADDRESS) & PIN_BIT;
    }
};

template <class Base, bool SAFE_VALUE, bool INVERT = false> struct GpioOutputPin : public Base
{
public:
    static void hw_init()
    {
        Base::set(SAFE_VALUE);
        Base::set_output();
        Base::set_gpio();
        Base::set(SAFE_VALUE);
    }
    static void hw_set_to_safe()
    {
        Base::set(SAFE_VALUE);
    }
    static void set(bool value)
    {
        if (INVERT)
        {
            Base::set(!value);
        }
        else
        {
            Base::set(value);
        }
    }
};

/// Defines a GPIO output pin, initialized to be an output pin with low level.
///
/// Do not use this class directly. Use @ref GPIO_PIN instead.
template <class Defs>
struct GpioOutputSafeLow : public GpioOutputPin<Defs, false>
{
};

/// Defines a GPIO output pin, initialized to be an output pin with low
/// level. All set() commands are acted upon by inverting the value.
///
/// Do not use this class directly. Use @ref GPIO_PIN instead.
template <class Defs>
struct GpioOutputSafeLowInvert : public GpioOutputPin<Defs, false, true>
{
};

/// Defines a GPIO output pin, initialized to be an output pin with high level.
///
/// Do not use this class directly. Use @ref GPIO_PIN instead.
template <class Defs>
struct GpioOutputSafeHigh : public GpioOutputPin<Defs, true>
{
};

/// Defines a GPIO output pin, initialized to be an output pin with high
/// level. All set() commands are acted upon by inverting the value.
///
/// Do not use this class directly. Use @ref GPIO_PIN instead.
template <class Defs>
struct GpioOutputSafeHighInvert : public GpioOutputPin<Defs, true, true>
{
};

template <class Base, bool PUEN> struct GpioInputPar : public Base
{
public:
    static void hw_init()
    {
        Base::set_input();
        if (PUEN) {
            Base::set_pullup_on();
        } else {
            Base::set_pullup_off();
        }
        Base::set_gpio();
    }
    static void hw_set_to_safe()
    {
        hw_init();
    }
};

/// Defines a GPIO input pin. No pull-up.
///
/// Do not use this class directly. Use @ref GPIO_PIN instead.
template <class Defs>
struct GpioInputNP : public GpioInputPar<Defs, false>
{
};

/// Defines a GPIO input pin with pull-up.
///
/// Do not use this class directly. Use @ref GPIO_PIN instead.
template <class Defs>
struct GpioInputPU : public GpioInputPar<Defs, true>
{
};

/// Helper macro for defining GPIO pins on the ESP8266 microcontroller.
///
/// @param NAME is the basename of the declaration. For NAME==FOO the macro
/// declared FOO_Pin as a structure on which the read-write functions will be
/// available.
///
/// @param BaseClass is the initialization structure, such as @ref LedPin, or
/// @ref GpioOutputSafeHigh or @ref GpioOutputSafeLow.
///
/// @param pin is the pin number, such as 3 (range: 0..15 GPIO16 is not
/// supported)
///
/// Example:
///  GPIO_PIN(FOO, GpioOutputSafeLow, 3);
///  ...
///  FOO_Pin::set(true);
#define GPIO_PIN(NAME, BaseClass, NUM)                                         \
    typedef BaseClass<Esp8266StaticGpio<NUM, gpio_num_to_pinmux_reg(NUM),      \
        FUNC_GPIO##NUM>> NAME##_Pin

#endif // _DRIVERS_ESP8266_ESP8266GPIO_HXX_
<commit_msg>Adds missing extern declarations for GPIO16.<commit_after>/** \copyright
 * Copyright (c) 2016, Balazs Racz
 * 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.
 *
 * \file Esp8266GPIO.hxx
 *
 * Helper declarations for using GPIO pins on the Esp8266 MCU.
 *
 * @author Balazs Racz
 * @date 16 May 2016
 */

#ifndef _DRIVERS_ESP8266_ESP8266GPIO_HXX_
#define _DRIVERS_ESP8266_ESP8266GPIO_HXX_

#include "os/Gpio.hxx"

extern "C" {
#include <gpio.h>
#include <eagle_soc.h>

/**
  * @brief   Enable GPIO16 output.
  *
  * @param   null
  *
  * @return  null
  */
void gpio16_output_conf(void);

/**
  * @brief   Set GPIO16 output level.
  *
  * @param   uint8 value : GPIO16 output level.
  *
  * @return  null
  */
void gpio16_output_set(uint8 value);

/**
  * @brief   Enable GPIO pin intput.
  *
  * @param   null
  *
  * @return  null
  */
void gpio16_input_conf(void);

/**
  * @brief   Sample the value of GPIO16 input.
  *
  * @param   null
  *
  * @return  the level  of GPIO16 input.
  */
uint8 gpio16_input_get(void);

}

constexpr uint32_t pinmux_to_gpio_arr[] = {
    PERIPHS_IO_MUX_GPIO0_U,    // 0
    PERIPHS_IO_MUX_U0TXD_U,    // 1
    PERIPHS_IO_MUX_GPIO2_U,    // 2
    PERIPHS_IO_MUX_U0RXD_U,    // 3
    PERIPHS_IO_MUX_GPIO4_U,    // 4
    PERIPHS_IO_MUX_GPIO5_U,    // 5
    PERIPHS_IO_MUX_SD_CLK_U,   // 6
    PERIPHS_IO_MUX_SD_DATA0_U, // 7
    PERIPHS_IO_MUX_SD_DATA1_U, // 8
    PERIPHS_IO_MUX_SD_DATA2_U, // 9
    PERIPHS_IO_MUX_SD_DATA3_U, // 10
    PERIPHS_IO_MUX_SD_CMD_U,   // 11
    PERIPHS_IO_MUX_MTDI_U,     // 12
    PERIPHS_IO_MUX_MTCK_U,     // 13
    PERIPHS_IO_MUX_MTMS_U,     // 14
    PERIPHS_IO_MUX_MTDO_U,     // 15
};

constexpr uint32_t gpio_num_to_pinmux_reg(int gpio_pin_num)
{
    return pinmux_to_gpio_arr[gpio_pin_num];
}

/// Defines a GPIO output pin. Writes to this structure will change the output
/// level of the pin. Reads will return the pin's current level.
///
/// The pin is set to output at initialization time, with the level defined by
/// `SAFE_VALUE'.
///
/// Do not use this class directly. Use @ref GPIO_PIN instead.
template <int PIN_NUM, uint32_t MUXREG, uint32_t FUNC_GPIO>
class Esp8266StaticGpio
{
public:
    static constexpr const uint32_t PIN = PIN_NUM;
    static constexpr const uint32_t PIN_BIT = (1 << PIN_NUM);
    static constexpr const uint32_t PIN_MUX_REG = MUXREG;
    static constexpr const uint32_t PIN_MUX_FUNC_GPIO = FUNC_GPIO;

    static void set_gpio()
    {
        PIN_FUNC_SELECT(PIN_MUX_REG, PIN_MUX_FUNC_GPIO);
    }

    static void set_output()
    {
        GPIO_REG_WRITE(GPIO_ENABLE_W1TS_ADDRESS, PIN_BIT);
    }

    static void set_input()
    {
        GPIO_REG_WRITE(GPIO_ENABLE_W1TC_ADDRESS, PIN_BIT);
    }

    static void set_pullup_on()
    {
        CLEAR_PERI_REG_MASK(PIN_MUX_REG, PERIPHS_IO_MUX_PULLUP2 | PERIPHS_IO_MUX_SLEEP_PULLUP | PERIPHS_IO_MUX_SLEEP_PULLUP2);
        SET_PERI_REG_MASK(PIN_MUX_REG, PERIPHS_IO_MUX_PULLUP);
    }

    static void set_pullup_off()
    {
        CLEAR_PERI_REG_MASK(
            PIN_MUX_REG, PERIPHS_IO_MUX_PULLUP | PERIPHS_IO_MUX_PULLUP2);
    }

    static void set_pulldown_on()
    {
        CLEAR_PERI_REG_MASK(PIN_MUX_REG, PERIPHS_IO_MUX_PULLUP | PERIPHS_IO_MUX_SLEEP_PULLUP | PERIPHS_IO_MUX_SLEEP_PULLUP2);
        SET_PERI_REG_MASK(PIN_MUX_REG, PERIPHS_IO_MUX_PULLUP2);
    }

    static void set_pulldown_off()
    {
        CLEAR_PERI_REG_MASK(
            PIN_MUX_REG, PERIPHS_IO_MUX_PULLUP | PERIPHS_IO_MUX_PULLUP2);
    }

    static void set_on()
    {
        GPIO_REG_WRITE(GPIO_OUT_W1TS_ADDRESS, PIN_BIT);
    }

    static void set_off()
    {
        GPIO_REG_WRITE(GPIO_OUT_W1TC_ADDRESS, PIN_BIT);
    }

    static bool get()
    {
        return (GPIO_REG_READ(GPIO_IN_ADDRESS) & PIN_BIT) != 0;
    }

    static void set(bool value)
    {
        if (value)
        {
            set_on();
        }
        else
        {
            set_off();
        }
    }

    static void toggle()
    {
        set(!get());
    }

    static bool is_output()
    {
        return GPIO_REG_READ(GPIO_ENABLE_ADDRESS) & PIN_BIT;
    }
};

template <class Base, bool SAFE_VALUE, bool INVERT = false>
struct GpioOutputPin : public Base
{
public:
    static void hw_init()
    {
        Base::set(SAFE_VALUE);
        Base::set_output();
        Base::set_gpio();
        Base::set(SAFE_VALUE);
    }
    static void hw_set_to_safe()
    {
        Base::set(SAFE_VALUE);
    }
    static void set(bool value)
    {
        if (INVERT)
        {
            Base::set(!value);
        }
        else
        {
            Base::set(value);
        }
    }
};

template <class Base>
struct GpioPullOutPin : public Base
{
public:
    static void hw_init()
    {
        Base::set_input();
        Base::set_gpio();
        Base::set_pullup_on();
    }
    static void hw_set_to_safe()
    {
        Base::set_pullup_on();
    }
    static void set(bool value)
    {
        if (value) {
            Base::set_pullup_on();
        } else {
            Base::set_pulldown_on();
        }
    }
    static void set_on() {
        Base::set_pullup_on();
    }
    static void set_off() {
        Base::set_pulldown_on();
    }
};

/// Defines a GPIO output pin, initialized to be an output pin with low level.
///
/// Do not use this class directly. Use @ref GPIO_PIN instead.
template <class Defs>
struct GpioOutputSafeLow : public GpioOutputPin<Defs, false>
{
};

/// Defines a GPIO output pin, initialized to be an output pin with low
/// level. All set() commands are acted upon by inverting the value.
///
/// Do not use this class directly. Use @ref GPIO_PIN instead.
template <class Defs>
struct GpioOutputSafeLowInvert : public GpioOutputPin<Defs, false, true>
{
};

/// Defines a GPIO output pin, initialized to be an output pin with high level.
///
/// Do not use this class directly. Use @ref GPIO_PIN instead.
template <class Defs>
struct GpioOutputSafeHigh : public GpioOutputPin<Defs, true>
{
};

/// Defines a GPIO output pin, initialized to be an output pin with high
/// level. All set() commands are acted upon by inverting the value.
///
/// Do not use this class directly. Use @ref GPIO_PIN instead.
template <class Defs>
struct GpioOutputSafeHighInvert : public GpioOutputPin<Defs, true, true>
{
};

template <class Base, bool PUEN> struct GpioInputPar : public Base
{
public:
    static void hw_init()
    {
        Base::set_input();
        if (PUEN)
        {
            Base::set_pullup_on();
        }
        else
        {
            Base::set_pullup_off();
        }
        Base::set_gpio();
    }
    static void hw_set_to_safe()
    {
        hw_init();
    }
};

/// Defines a GPIO input pin. No pull-up.
///
/// Do not use this class directly. Use @ref GPIO_PIN instead.
template <class Defs> struct GpioInputNP : public GpioInputPar<Defs, false>
{
};

/// Defines a GPIO input pin with pull-up.
///
/// Do not use this class directly. Use @ref GPIO_PIN instead.
template <class Defs> struct GpioInputPU : public GpioInputPar<Defs, true>
{
};

/// Helper macro for defining GPIO pins on the ESP8266 microcontroller.
///
/// @param NAME is the basename of the declaration. For NAME==FOO the macro
/// declared FOO_Pin as a structure on which the read-write functions will be
/// available.
///
/// @param BaseClass is the initialization structure, such as @ref LedPin, or
/// @ref GpioOutputSafeHigh or @ref GpioOutputSafeLow.
///
/// @param pin is the pin number, such as 3 (range: 0..15 GPIO16 is not
/// supported)
///
/// Example:
///  GPIO_PIN(FOO, GpioOutputSafeLow, 3);
///  ...
///  FOO_Pin::set(true);
#define GPIO_PIN(NAME, BaseClass, NUM)                                         \
    typedef BaseClass<Esp8266StaticGpio<NUM, gpio_num_to_pinmux_reg(NUM),      \
        FUNC_GPIO##NUM>> NAME##_Pin

#endif // _DRIVERS_ESP8266_ESP8266GPIO_HXX_
<|endoftext|>


<commit_before>/*      _______   __   __   __   ______   __   __   _______   __   __
 *     / _____/\ / /\ / /\ / /\ / ____/\ / /\ / /\ / ___  /\ /  |\/ /\
 *    / /\____\// / // / // / // /\___\// /_// / // /\_/ / // , |/ / /
 *   / / /__   / / // / // / // / /    / ___  / // ___  / // /| ' / /
 *  / /_// /\ / /_// / // / // /_/_   / / // / // /\_/ / // / |  / /
 * /______/ //______/ //_/ //_____/\ /_/ //_/ //_/ //_/ //_/ /|_/ /
 * \______\/ \______\/ \_\/ \_____\/ \_\/ \_\/ \_\/ \_\/ \_\/ \_\/
 *
 * Copyright (c) 2004 darkbits                              Js_./
 * Per Larsson a.k.a finalman                          _RqZ{a<^_aa
 * Olof Naessn a.k.a jansem/yakslem                _asww7!uY`>  )\a//
 *                                                 _Qhm`] _f "'c  1!5m
 * Visit: http://guichan.darkbits.org             )Qk<P ` _: :+' .'  "{[
 *                                               .)j(] .d_/ '-(  P .   S
 * License: (BSD)                                <Td/Z <fP"5(\"??"\a.  .L
 * Redistribution and use in source and          _dV>ws?a-?'      ._/L  #'
 * binary forms, with or without                 )4d[#7r, .   '     )d`)[
 * modification, are permitted provided         _Q-5'5W..j/?'   -?!\)cam'
 * that the following conditions are met:       j<<WP+k/);.        _W=j f
 * 1. Redistributions of source code must       .$%w\/]Q  . ."'  .  mj$
 *    retain the above copyright notice,        ]E.pYY(Q]>.   a     J@\
 *    this list of conditions and the           j(]1u<sE"L,. .   ./^ ]{a
 *    following disclaimer.                     4'_uomm\.  )L);-4     (3=
 * 2. Redistributions in binary form must        )_]X{Z('a_"a7'<a"a,  ]"[
 *    reproduce the above copyright notice,       #}<]m7`Za??4,P-"'7. ).m
 *    this list of conditions and the            ]d2e)Q(<Q(  ?94   b-  LQ/
 *    following disclaimer in the                <B!</]C)d_, '(<' .f. =C+m
 *    documentation and/or other materials      .Z!=J ]e []('-4f _ ) -.)m]'
 *    provided with the distribution.          .w[5]' _[ /.)_-"+?   _/ <W"
 * 3. Neither the name of Guichan nor the      :$we` _! + _/ .        j?
 *    names of its contributors may be used     =3)= _f  (_yQmWW$#(    "
 *    to endorse or promote products derived     -   W,  sQQQQmZQ#Wwa]..
 *    from this software without specific        (js, \[QQW$QWW#?!V"".
 *    prior written permission.                    ]y:.<\..          .
 *                                                 -]n w/ '         [.
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT       )/ )/           !
 * HOLDERS AND CONTRIBUTORS "AS IS" AND ANY         <  (; sac    ,    '
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING,               ]^ .-  %
 * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF            c <   r
 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR            aga<  <La
 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE          5%  )P'-3L
 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR        _bQf` y`..)a
 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,          ,J?4P'.P"_(\?d'.,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES               _Pa,)!f/<[]/  ?"
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT      _2-..:. .r+_,.. .
 * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,     ?a.<%"'  " -'.a_ _,
 * 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.
 */

/*
 * For comments regarding functions please see the header file.
 */

#include "guichan/allegro/allegrographics.hpp"
#include "guichan/rectangle.hpp"
#include "guichan/exception.hpp"
#include "guichan/cliprectangle.hpp"
#include "guichan/color.hpp"

namespace gcn
{
	AllegroGraphics::AllegroGraphics()
	{
		mTarget = NULL;
		mClipNull = false;
	}

	AllegroGraphics::AllegroGraphics(BITMAP *target)
	{
		mTarget = target;
	}

	AllegroGraphics::~AllegroGraphics()
	{
	}

	void AllegroGraphics::setTarget(BITMAP *target)
	{
		mTarget = target;
	}

	BITMAP *AllegroGraphics::getTarget()
	{
		return mTarget;
	}

	void AllegroGraphics::_beginDraw()
	{
		if (mTarget == NULL)
		{
			throw GCN_EXCEPTION("AllegroGraphics::_beginDraw. Target BITMAP is null, set it with setTarget first");
		}

//		acquire_bitmap(mTarget);

		// push a clip area the size of the target bitmap
		pushClipArea(Rectangle(0, 0, mTarget->w - 1, mTarget->h - 1));
	}

	void AllegroGraphics::_endDraw()
	{
		// pop the clip area pushed in _beginDraw
		popClipArea();

//		release_bitmap(mTarget);
	}

	bool AllegroGraphics::pushClipArea(Rectangle area)
	{
		bool result = Graphics::pushClipArea(area);

		ClipRectangle cr = mClipStack.top();

		// Allegro won't let you set clip areas
		// that have zero width or height
		// so we have to check for that.
		if (cr.width == 0 || cr.height == 0)
		{
			mClipNull = true;
		}
		else
		{
			mClipNull = false;
			set_clip_rect(mTarget, cr.x, cr.y, cr.x + cr.width - 1, cr.y + cr.height - 1);
		}

		return result;
	}

	void AllegroGraphics::popClipArea()
	{
		Graphics::popClipArea();

		if (mClipStack.empty())
		{
			return;
		}

		ClipRectangle cr = mClipStack.top();

		// Allegro won't let you set clip areas
		//that have zero width or height
		// so we have to check for that.
		if (cr.width == 0 || cr.height == 0)
		{
			mClipNull = true;
		}
		else
		{
			mClipNull = false;
			set_clip_rect(mTarget, cr.x, cr.y, cr.x + cr.width - 1, cr.y + cr.height - 1);
		}
	}

	void AllegroGraphics::drawImage(const Image* image,
																	int srcX, int srcY,
																	int dstX, int dstY,
																	int width, int height)
	{
		if (mClipNull)
		{
			return;
		}

		BITMAP *src = (BITMAP *)image->_getData();

		dstX += mClipStack.top().xOffset;
		dstY += mClipStack.top().yOffset;

		masked_blit(src, mTarget, srcX, srcY, dstX, dstY, width, height);
	}

	void AllegroGraphics::drawPoint(int x, int y)
	{
		if (mClipNull)
		{
			return;
		}

		int xOffset = mClipStack.top().xOffset;
		int yOffset = mClipStack.top().yOffset;

		putpixel(mTarget,
						 x + xOffset,
						 y + yOffset,
						 mAlColor);
	}

	void AllegroGraphics::drawLine(int x1, int y1, int x2, int y2)
	{
		if (mClipNull)
		{
			return;
		}

		int xOffset = mClipStack.top().xOffset;
		int yOffset = mClipStack.top().yOffset;

		line(mTarget,
				 x1 + xOffset,
				 y1 + yOffset,
				 x2 + xOffset,
				 y2 + yOffset,
				 mAlColor);
	}

	void AllegroGraphics::drawRectangle(const Rectangle& rectangle)
	{
		if (mClipNull)
		{
			return;
		}

		int xOffset = mClipStack.top().xOffset;
		int yOffset = mClipStack.top().yOffset;

		rect(mTarget,
				 rectangle.x + xOffset,
				 rectangle.y + yOffset,
				 rectangle.x + rectangle.width - 1 + xOffset,
				 rectangle.y + rectangle.height - 1 + yOffset,
				 mAlColor);
	}

	void AllegroGraphics::fillRectangle(const Rectangle& rectangle)
	{
		if (mClipNull)
		{
			return;
		}

		int xOffset = mClipStack.top().xOffset;
		int yOffset = mClipStack.top().yOffset;

		rectfill(mTarget,
						 rectangle.x + xOffset,
						 rectangle.y + yOffset,
						 rectangle.x + rectangle.width - 1 + xOffset,
						 rectangle.y + rectangle.height - 1 + yOffset,
						 mAlColor);
	}

	void AllegroGraphics::setColor(const Color& color)
	{
		Graphics::setColor(color);

		mAlColor = makecol(color.r, color.g, color.b);
	}
} // end gcn
<commit_msg>Added check for allegro beta. If beta then use set_clip_rect instead of set_clip.<commit_after>/*      _______   __   __   __   ______   __   __   _______   __   __
 *     / _____/\ / /\ / /\ / /\ / ____/\ / /\ / /\ / ___  /\ /  |\/ /\
 *    / /\____\// / // / // / // /\___\// /_// / // /\_/ / // , |/ / /
 *   / / /__   / / // / // / // / /    / ___  / // ___  / // /| ' / /
 *  / /_// /\ / /_// / // / // /_/_   / / // / // /\_/ / // / |  / /
 * /______/ //______/ //_/ //_____/\ /_/ //_/ //_/ //_/ //_/ /|_/ /
 * \______\/ \______\/ \_\/ \_____\/ \_\/ \_\/ \_\/ \_\/ \_\/ \_\/
 *
 * Copyright (c) 2004 darkbits                              Js_./
 * Per Larsson a.k.a finalman                          _RqZ{a<^_aa
 * Olof Naessn a.k.a jansem/yakslem                _asww7!uY`>  )\a//
 *                                                 _Qhm`] _f "'c  1!5m
 * Visit: http://guichan.darkbits.org             )Qk<P ` _: :+' .'  "{[
 *                                               .)j(] .d_/ '-(  P .   S
 * License: (BSD)                                <Td/Z <fP"5(\"??"\a.  .L
 * Redistribution and use in source and          _dV>ws?a-?'      ._/L  #'
 * binary forms, with or without                 )4d[#7r, .   '     )d`)[
 * modification, are permitted provided         _Q-5'5W..j/?'   -?!\)cam'
 * that the following conditions are met:       j<<WP+k/);.        _W=j f
 * 1. Redistributions of source code must       .$%w\/]Q  . ."'  .  mj$
 *    retain the above copyright notice,        ]E.pYY(Q]>.   a     J@\
 *    this list of conditions and the           j(]1u<sE"L,. .   ./^ ]{a
 *    following disclaimer.                     4'_uomm\.  )L);-4     (3=
 * 2. Redistributions in binary form must        )_]X{Z('a_"a7'<a"a,  ]"[
 *    reproduce the above copyright notice,       #}<]m7`Za??4,P-"'7. ).m
 *    this list of conditions and the            ]d2e)Q(<Q(  ?94   b-  LQ/
 *    following disclaimer in the                <B!</]C)d_, '(<' .f. =C+m
 *    documentation and/or other materials      .Z!=J ]e []('-4f _ ) -.)m]'
 *    provided with the distribution.          .w[5]' _[ /.)_-"+?   _/ <W"
 * 3. Neither the name of Guichan nor the      :$we` _! + _/ .        j?
 *    names of its contributors may be used     =3)= _f  (_yQmWW$#(    "
 *    to endorse or promote products derived     -   W,  sQQQQmZQ#Wwa]..
 *    from this software without specific        (js, \[QQW$QWW#?!V"".
 *    prior written permission.                    ]y:.<\..          .
 *                                                 -]n w/ '         [.
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT       )/ )/           !
 * HOLDERS AND CONTRIBUTORS "AS IS" AND ANY         <  (; sac    ,    '
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING,               ]^ .-  %
 * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF            c <   r
 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR            aga<  <La
 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE          5%  )P'-3L
 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR        _bQf` y`..)a
 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,          ,J?4P'.P"_(\?d'.,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES               _Pa,)!f/<[]/  ?"
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT      _2-..:. .r+_,.. .
 * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,     ?a.<%"'  " -'.a_ _,
 * 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.
 */

/*
 * For comments regarding functions please see the header file.
 */

#include "guichan/allegro/allegrographics.hpp"
#include "guichan/rectangle.hpp"
#include "guichan/exception.hpp"
#include "guichan/cliprectangle.hpp"
#include "guichan/color.hpp"

namespace gcn
{
	AllegroGraphics::AllegroGraphics()
	{
		mTarget = NULL;
		mClipNull = false;
	}

	AllegroGraphics::AllegroGraphics(BITMAP *target)
	{
		mTarget = target;
	}

	AllegroGraphics::~AllegroGraphics()
	{
	}

	void AllegroGraphics::setTarget(BITMAP *target)
	{
		mTarget = target;
	}

	BITMAP *AllegroGraphics::getTarget()
	{
		return mTarget;
	}

	void AllegroGraphics::_beginDraw()
	{
		if (mTarget == NULL)
		{
			throw GCN_EXCEPTION("AllegroGraphics::_beginDraw. Target BITMAP is null, set it with setTarget first");
		}

//		acquire_bitmap(mTarget);

		// push a clip area the size of the target bitmap
		pushClipArea(Rectangle(0, 0, mTarget->w - 1, mTarget->h - 1));
	}

	void AllegroGraphics::_endDraw()
	{
		// pop the clip area pushed in _beginDraw
		popClipArea();

//		release_bitmap(mTarget);
	}

	bool AllegroGraphics::pushClipArea(Rectangle area)
	{
		bool result = Graphics::pushClipArea(area);

		ClipRectangle cr = mClipStack.top();

		// Allegro won't let you set clip areas
		// that have zero width or height
		// so we have to check for that.
		if (cr.width == 0 || cr.height == 0)
		{
			mClipNull = true;
		}
		else
		{
			mClipNull = false;
#if ALLEGRO_VERSION == 4 && ALLEGRO_SUB_VERSION == 0
			set_clip(mTarget, cr.x, cr.y, cr.x + cr.width - 1, cr.y + cr.height - 1);
#else
			set_clip_rect(mTarget, cr.x, cr.y, cr.x + cr.width - 1, cr.y + cr.height - 1);
#endif
		}

		return result;
	}

	void AllegroGraphics::popClipArea()
	{
		Graphics::popClipArea();

		if (mClipStack.empty())
		{
			return;
		}

		ClipRectangle cr = mClipStack.top();

		// Allegro won't let you set clip areas
		//that have zero width or height
		// so we have to check for that.
		if (cr.width == 0 || cr.height == 0)
		{
			mClipNull = true;
		}
		else
		{
			mClipNull = false;
			set_clip_rect(mTarget, cr.x, cr.y, cr.x + cr.width - 1, cr.y + cr.height - 1);
		}
	}

	void AllegroGraphics::drawImage(const Image* image,
																	int srcX, int srcY,
																	int dstX, int dstY,
																	int width, int height)
	{
		if (mClipNull)
		{
			return;
		}

		BITMAP *src = (BITMAP *)image->_getData();

		dstX += mClipStack.top().xOffset;
		dstY += mClipStack.top().yOffset;

		masked_blit(src, mTarget, srcX, srcY, dstX, dstY, width, height);
	}

	void AllegroGraphics::drawPoint(int x, int y)
	{
		if (mClipNull)
		{
			return;
		}

		int xOffset = mClipStack.top().xOffset;
		int yOffset = mClipStack.top().yOffset;

		putpixel(mTarget,
						 x + xOffset,
						 y + yOffset,
						 mAlColor);
	}

	void AllegroGraphics::drawLine(int x1, int y1, int x2, int y2)
	{
		if (mClipNull)
		{
			return;
		}

		int xOffset = mClipStack.top().xOffset;
		int yOffset = mClipStack.top().yOffset;

		line(mTarget,
				 x1 + xOffset,
				 y1 + yOffset,
				 x2 + xOffset,
				 y2 + yOffset,
				 mAlColor);
	}

	void AllegroGraphics::drawRectangle(const Rectangle& rectangle)
	{
		if (mClipNull)
		{
			return;
		}

		int xOffset = mClipStack.top().xOffset;
		int yOffset = mClipStack.top().yOffset;

		rect(mTarget,
				 rectangle.x + xOffset,
				 rectangle.y + yOffset,
				 rectangle.x + rectangle.width - 1 + xOffset,
				 rectangle.y + rectangle.height - 1 + yOffset,
				 mAlColor);
	}

	void AllegroGraphics::fillRectangle(const Rectangle& rectangle)
	{
		if (mClipNull)
		{
			return;
		}

		int xOffset = mClipStack.top().xOffset;
		int yOffset = mClipStack.top().yOffset;

		rectfill(mTarget,
						 rectangle.x + xOffset,
						 rectangle.y + yOffset,
						 rectangle.x + rectangle.width - 1 + xOffset,
						 rectangle.y + rectangle.height - 1 + yOffset,
						 mAlColor);
	}

	void AllegroGraphics::setColor(const Color& color)
	{
		Graphics::setColor(color);

		mAlColor = makecol(color.r, color.g, color.b);
	}
} // end gcn
<|endoftext|>


<commit_before>// =============================================================================
// PROJECT CHRONO - http://projectchrono.org
//
// Copyright (c) 2014 projectchrono.org
// All right reserved.
//
// Use of this source code is governed by a BSD-style license that can be found
// in the LICENSE file at the top level of the distribution and at
// http://projectchrono.org/license-chrono.txt.
//
// =============================================================================
// Authors: Radu Serban, Hammad Mazhar
// =============================================================================
//
// ChronoParallel test program using penalty method for frictional contact.
//
// The model simulated here consists of a number of spherical objects falling
// onto a mixer blade attached through a revolute joint to the ground.
//
// The global reference frame has Z up.
//
// If available, OpenGL is used for run-time rendering. Otherwise, the
// simulation is carried out for a pre-defined duration and output files are
// generated for post-processing with POV-Ray.
// =============================================================================

#include <stdio.h>
#include <vector>
#include <cmath>

#include "chrono_parallel/physics/ChSystemParallel.h"

#include "chrono/ChConfig.h"
#include "chrono/utils/ChUtilsCreators.h"
#include "chrono/utils/ChUtilsInputOutput.h"
#include "chrono/utils/ChUtilsGeometry.h"
#include "chrono/utils/ChUtilsGenerators.h"

#include "chrono_parallel/physics/Ch3DOFContainer.h"

#include <fstream>
#ifdef CHRONO_OPENGL
#include "chrono_opengl/ChOpenGLWindow.h"
#endif

using namespace chrono;
using namespace chrono::collision;
ChMPMContainer* mpm_container;
// -----------------------------------------------------------------------------
// Create a bin consisting of five boxes attached to the ground and a mixer
// blade attached through a revolute joint to ground. The mixer is constrained
// to rotate at constant angular velocity.
// -----------------------------------------------------------------------------
void AddContainer(ChSystemParallelDVI* sys) {
    // IDs for the two bodies
    int binId = -200;
    int mixerId = -201;

    // Create a common material
    ChSharedPtr<ChMaterialSurface> mat(new ChMaterialSurface);
    mat->SetFriction(0.4f);

    // Create the containing bin (2 x 2 x 1)
    ChSharedBodyPtr bin(new ChBody(new ChCollisionModelParallel));
    bin->SetMaterialSurface(mat);
    bin->SetIdentifier(binId);
    bin->SetMass(1);
    bin->SetPos(ChVector<>(0, 0, 0));
    bin->SetRot(ChQuaternion<>(1, 0, 0, 0));
    bin->SetCollide(true);
    bin->SetBodyFixed(true);

    ChVector<> hdim(.5, .5, 0.05);

    bin->GetCollisionModel()->ClearModel();
    utils::AddBoxGeometry(bin.get_ptr(), ChVector<>(hdim.x, hdim.y, hdim.z), ChVector<>(0, 0, -hdim.z));
    // utils::AddBoxGeometry(bin.get_ptr(), ChVector<>(hdim.x, hdim.y, hdim.z), ChVector<>(0, 0, hdim.z*10));
    bin->GetCollisionModel()->SetFamily(1);
    bin->GetCollisionModel()->SetFamilyMaskNoCollisionWithFamily(2);
    bin->GetCollisionModel()->BuildModel();

    sys->AddBody(bin);
}

// -----------------------------------------------------------------------------
// Create the fluid in the shape of a sphere.
// -----------------------------------------------------------------------------
void AddFluid(ChSystemParallelDVI* sys) {
    mpm_container = new ChMPMContainer(sys);

    real youngs_modulus = 1.4e8;
    real poissons_ratio = 0.2;

    mpm_container->theta_c = 2.5e-2;
    mpm_container->theta_s = 7.5e-3;
    mpm_container->lambda = youngs_modulus * poissons_ratio / ((1. + poissons_ratio) * (1. - 2. * poissons_ratio));
    mpm_container->mu = youngs_modulus / (2. * (1. + poissons_ratio));
    mpm_container->alpha = .95;
    mpm_container->hardening_coefficient = 10.0;

    real initial_density = 1000;
    mpm_container->mass = .004;
    mpm_container->max_iterations = 20;
    mpm_container->kernel_radius = .005;
    mpm_container->contact_recovery_speed = 10000;

    real radius = mpm_container->kernel_radius * 10;  //*5
    real dens = 30;
    real3 num_fluid = real3(10, 10, 10);
    real3 origin(0, 0, .2);
    real vol;

    std::vector<real3> pos_fluid;
    std::vector<real3> vel_fluid;
#if 1
    double dist = mpm_container->kernel_radius * .9;
    utils::HCPSampler<> sampler(dist);
    utils::Generator::PointVector points = sampler.SampleSphere(ChVector<>(-.1, 0, 0), radius);

    pos_fluid.resize(points.size());
    vel_fluid.resize(points.size());
    for (int i = 0; i < points.size(); i++) {
        pos_fluid[i] = real3(points[i].x, points[i].y, points[i].z) + origin;
        vel_fluid[i] = real3(-3, 0, 0);
    }
    mpm_container->UpdatePosition(0);
    mpm_container->AddNodes(pos_fluid, vel_fluid);

    points = sampler.SampleSphere(ChVector<>(.1, 0, 0), radius);

    pos_fluid.resize(points.size());
    vel_fluid.resize(points.size());
    for (int i = 0; i < points.size(); i++) {
        pos_fluid[i] = real3(points[i].x, points[i].y, points[i].z) + origin;
        vel_fluid[i] = real3(-3, 0, 0);
    }
    mpm_container->AddNodes(pos_fluid, vel_fluid);

#else
    std::ifstream ifile("snowMPMinit.dat");
    while (ifile.fail() == false) {
        real m;
        real3 p, v;
        ifile >> m;
        if (ifile.fail() == false) {
            ifile >> p.x >> p.y >> p.z;
            ifile >> v.x >> v.y >> v.z;
        }
        if (ifile.fail() == false) {
            pos_fluid.push_back(p);
            vel_fluid.push_back(v);
        }
    }
    //    pos_fluid.push_back(real3(.5, .5, .5));
    //    vel_fluid.push_back(real3(0, -3, 0));
    //
    //    pos_fluid.push_back(real3(.5, .8, .5));
    //    vel_fluid.push_back(real3(0, -2, 0));
    fluid_container->UpdatePosition(0);
    fluid_container->AddFluid(pos_fluid, vel_fluid);
#endif
}
// -----------------------------------------------------------------------------
// Create the system, specify simulation parameters, and run simulation loop.
// -----------------------------------------------------------------------------
int main(int argc, char* argv[]) {
    int threads = 8;

    // Simulation parameters
    // ---------------------

    double gravity = 9.81;
    double time_step = 1e-3;
    double time_end = 1;

    double out_fps = 50;

    uint max_iteration = 30;
    real tolerance = 1e-3;

    // Create system
    // -------------

    ChSystemParallelDVI msystem;
    // omp_set_num_threads(4);
    // Set number of threads.
    //    int max_threads = 2;//CHOMPfunctions::GetNumProcs();
    //    if (threads > max_threads)
    //        threads = max_threads;
    //    msystem.SetParallelThreadNumber(threads);
    //    CHOMPfunctions::SetNumThreads(threads);

    // Set gravitational acceleration
    msystem.Set_G_acc(ChVector<>(0, 0, -gravity));

    // Set solver parameters
    msystem.GetSettings()->solver.solver_mode = SLIDING;
    msystem.GetSettings()->solver.max_iteration_normal = 0;
    msystem.GetSettings()->solver.max_iteration_sliding = 40;
    msystem.GetSettings()->solver.max_iteration_spinning = 0;
    msystem.GetSettings()->solver.max_iteration_bilateral = 0;
    msystem.GetSettings()->solver.tolerance = tolerance;
    msystem.GetSettings()->solver.alpha = 0;
    msystem.GetSettings()->solver.use_full_inertia_tensor = false;
    msystem.GetSettings()->collision.use_two_level = false;
    msystem.GetSettings()->solver.contact_recovery_speed = 10000;
    msystem.GetSettings()->solver.cache_step_length = true;
    msystem.ChangeSolverType(BB);
    msystem.GetSettings()->collision.narrowphase_algorithm = NARROWPHASE_HYBRID_MPR;

    AddFluid(&msystem);

    msystem.GetSettings()->collision.collision_envelope = (mpm_container->kernel_radius * .05);
    msystem.GetSettings()->collision.bins_per_axis = int3(2, 2, 2);
    msystem.SetLoggingLevel(LOG_TRACE, true);
    msystem.SetLoggingLevel(LOG_INFO, true);
    // Create the fixed and moving bodies
    // ----------------------------------

    AddContainer(&msystem);

    // This initializes all of the MPM stuff
    msystem.Initialize();
// Perform the simulation
// ----------------------
//#undef CHRONO_OPENGL
#ifdef CHRONO_OPENGL
    opengl::ChOpenGLWindow& gl_window = opengl::ChOpenGLWindow::getInstance();
    gl_window.Initialize(1280, 720, "snowMPM", &msystem);
    gl_window.SetCamera(ChVector<>(0, -.4, 0), ChVector<>(0, 0, 0), ChVector<>(0, 0, 1), .1);
    gl_window.Pause();
    // Uncomment the following two lines for the OpenGL manager to automatically
    // run the simulation in an infinite loop.
    // gl_window.StartDrawLoop(time_step);
    // return 0;
    while (true) {
        if (gl_window.Active()) {
            gl_window.DoStepDynamics(time_step);
            gl_window.Render();
        } else {
            break;
        }
    }
#else
    // Run simulation for specified time
    int num_steps = std::ceil(time_end / time_step);

    double time = 0;
    for (int i = 0; i < num_steps; i++) {
        msystem.DoStepDynamics(time_step);
        time += time_step;
    }
#endif

    return 0;
}
<commit_msg>update snow model<commit_after>// =============================================================================
// PROJECT CHRONO - http://projectchrono.org
//
// Copyright (c) 2014 projectchrono.org
// All right reserved.
//
// Use of this source code is governed by a BSD-style license that can be found
// in the LICENSE file at the top level of the distribution and at
// http://projectchrono.org/license-chrono.txt.
//
// =============================================================================
// Authors: Radu Serban, Hammad Mazhar
// =============================================================================
//
// ChronoParallel test program using penalty method for frictional contact.
//
// The model simulated here consists of a number of spherical objects falling
// onto a mixer blade attached through a revolute joint to the ground.
//
// The global reference frame has Z up.
//
// If available, OpenGL is used for run-time rendering. Otherwise, the
// simulation is carried out for a pre-defined duration and output files are
// generated for post-processing with POV-Ray.
// =============================================================================

#include <stdio.h>
#include <vector>
#include <cmath>

#include "chrono_parallel/physics/ChSystemParallel.h"

#include "chrono/ChConfig.h"
#include "chrono/utils/ChUtilsCreators.h"
#include "chrono/utils/ChUtilsInputOutput.h"
#include "chrono/utils/ChUtilsGeometry.h"
#include "chrono/utils/ChUtilsGenerators.h"

#include "chrono_parallel/physics/Ch3DOFContainer.h"

#include <fstream>
#ifdef CHRONO_OPENGL
#include "chrono_opengl/ChOpenGLWindow.h"
#endif

using namespace chrono;
using namespace chrono::collision;
ChMPMContainer* mpm_container;
// -----------------------------------------------------------------------------
// Create a bin consisting of five boxes attached to the ground and a mixer
// blade attached through a revolute joint to ground. The mixer is constrained
// to rotate at constant angular velocity.
// -----------------------------------------------------------------------------
void AddContainer(ChSystemParallelDVI* sys) {
    // IDs for the two bodies
    int binId = -200;
    int mixerId = -201;

    // Create a common material
    ChSharedPtr<ChMaterialSurface> mat(new ChMaterialSurface);
    mat->SetFriction(0.4f);

    // Create the containing bin (2 x 2 x 1)
    ChSharedBodyPtr bin(new ChBody(new ChCollisionModelParallel));
    bin->SetMaterialSurface(mat);
    bin->SetIdentifier(binId);
    bin->SetMass(1);
    bin->SetPos(ChVector<>(0, 0, 0));
    bin->SetRot(ChQuaternion<>(1, 0, 0, 0));
    bin->SetCollide(true);
    bin->SetBodyFixed(true);

    ChVector<> hdim(.15, .15, 0.05);

    bin->GetCollisionModel()->ClearModel();
    utils::AddBoxGeometry(bin.get_ptr(), ChVector<>(hdim.x, hdim.y, hdim.z), ChVector<>(0, 0, -hdim.z));
    // utils::AddBoxGeometry(bin.get_ptr(), ChVector<>(hdim.x, hdim.y, hdim.z), ChVector<>(0, 0, hdim.z*10));
    bin->GetCollisionModel()->SetFamily(1);
    bin->GetCollisionModel()->SetFamilyMaskNoCollisionWithFamily(2);
    bin->GetCollisionModel()->BuildModel();

    sys->AddBody(bin);
}

// -----------------------------------------------------------------------------
// Create the fluid in the shape of a sphere.
// -----------------------------------------------------------------------------
void AddFluid(ChSystemParallelDVI* sys) {
    mpm_container = new ChMPMContainer(sys);

    real youngs_modulus = 1.4e2;
    real poissons_ratio = 0.2;

    mpm_container->theta_c = 2.5e-2;
    mpm_container->theta_s = 7.5e-3;
    mpm_container->lambda = youngs_modulus * poissons_ratio / ((1. + poissons_ratio) * (1. - 2. * poissons_ratio));
    mpm_container->mu = youngs_modulus / (2. * (1. + poissons_ratio));
    mpm_container->alpha = .95;
    mpm_container->hardening_coefficient = 10.0;

    real initial_density = 4e2;
    mpm_container->mass = .001;
    mpm_container->max_iterations = 20;
    mpm_container->kernel_radius = .01;
    mpm_container->contact_recovery_speed = 10000;

    real radius = mpm_container->kernel_radius * 8;  //*5
    real dens = 30;
    real3 num_fluid = real3(10, 10, 10);
    real3 origin(0, 0, .1);
    real vol;

    std::vector<real3> pos_fluid;
    std::vector<real3> vel_fluid;

#if 1
    double dist = mpm_container->kernel_radius;
    vol = dist * dist * dist;
    mpm_container->mass = initial_density * vol;

    utils::PDSampler<> sampler(dist);
    utils::Generator::PointVector points = sampler.SampleBox(ChVector<>(-.2, radius, 0), ChVector<>(15,4,.3));

    pos_fluid.resize(points.size());
    vel_fluid.resize(points.size());
    for (int i = 0; i < points.size(); i++) {
        pos_fluid[i] = real3(points[i].x, points[i].y, points[i].z) + origin;
        vel_fluid[i] = real3(6, 0, 0);
    }
    mpm_container->UpdatePosition(0);
    mpm_container->AddNodes(pos_fluid, vel_fluid);

//    points = sampler.SampleBox(ChVector<>(.2, 0, 0), ChVector<>(radius,radius,radius));
//
//    pos_fluid.resize(points.size());
//    vel_fluid.resize(points.size());
//    for (int i = 0; i < points.size(); i++) {
//        pos_fluid[i] = real3(points[i].x, points[i].y, points[i].z) + origin;
//        vel_fluid[i] = real3(-6, 0, 0);
//    }
//    mpm_container->AddNodes(pos_fluid, vel_fluid);

#else
    std::ifstream ifile("state_0.029.dat");
    while (ifile.fail() == false) {
        real m;
        real3 p, v;
        // ifile >> m;
        if (ifile.fail() == false) {
            ifile >> p.x >> p.y >> p.z;
            ifile >> v.x >> v.y >> v.z;
        }
        if (ifile.fail() == false) {
            pos_fluid.push_back(p);
            vel_fluid.push_back(v);
        }
    }
    //    pos_fluid.push_back(real3(.5, .5, .5));
    //    vel_fluid.push_back(real3(0, -3, 0));
    //
    //    pos_fluid.push_back(real3(.5, .8, .5));
    //    vel_fluid.push_back(real3(0, -2, 0));
    // mpm_container->UpdatePosition(0);
    mpm_container->AddNodes(pos_fluid, vel_fluid);
#endif
}
// -----------------------------------------------------------------------------
// Create the system, specify simulation parameters, and run simulation loop.
// -----------------------------------------------------------------------------
int main(int argc, char* argv[]) {
    int threads = 8;

    // Simulation parameters
    // ---------------------

    double gravity = 9.81;
    double time_step = 1e-3;
    double time_end = 1;

    double out_fps = 50;

    uint max_iteration = 30;
    real tolerance = 1e-3;

    // Create system
    // -------------

    ChSystemParallelDVI msystem;
    // omp_set_num_threads(4);
    // Set number of threads.
    //    int max_threads = 2;//CHOMPfunctions::GetNumProcs();
    //    if (threads > max_threads)
    //        threads = max_threads;
    //    msystem.SetParallelThreadNumber(threads);
    //    CHOMPfunctions::SetNumThreads(threads);

    // Set gravitational acceleration
    msystem.Set_G_acc(ChVector<>(0, 0, -gravity));

    // Set solver parameters
    msystem.GetSettings()->solver.solver_mode = SLIDING;
    msystem.GetSettings()->solver.max_iteration_normal = 0;
    msystem.GetSettings()->solver.max_iteration_sliding = 40;
    msystem.GetSettings()->solver.max_iteration_spinning = 0;
    msystem.GetSettings()->solver.max_iteration_bilateral = 0;
    msystem.GetSettings()->solver.tolerance = 1e-2;
    msystem.GetSettings()->solver.alpha = 0;
    msystem.GetSettings()->solver.use_full_inertia_tensor = false;
    msystem.GetSettings()->collision.use_two_level = false;
    msystem.GetSettings()->solver.contact_recovery_speed = 10000;
    msystem.GetSettings()->solver.cache_step_length = true;
    msystem.ChangeSolverType(BB);
    msystem.GetSettings()->collision.narrowphase_algorithm = NARROWPHASE_HYBRID_MPR;

    AddFluid(&msystem);

    msystem.GetSettings()->collision.collision_envelope = (mpm_container->kernel_radius * .05);
    msystem.GetSettings()->collision.bins_per_axis = int3(2, 2, 2);
    msystem.SetLoggingLevel(LOG_TRACE, true);
    msystem.SetLoggingLevel(LOG_INFO, true);
    // Create the fixed and moving bodies
    // ----------------------------------

    AddContainer(&msystem);

    // This initializes all of the MPM stuff
    msystem.Initialize();
// Perform the simulation
// ----------------------
//#undef CHRONO_OPENGL
#ifdef CHRONO_OPENGL
    opengl::ChOpenGLWindow& gl_window = opengl::ChOpenGLWindow::getInstance();
    gl_window.Initialize(1280, 720, "snowMPM", &msystem);
    gl_window.SetCamera(ChVector<>(0, -.4, 0), ChVector<>(0, 0, 0), ChVector<>(0, 0, 1), .1);
    gl_window.Pause();
    // Uncomment the following two lines for the OpenGL manager to automatically
    // run the simulation in an infinite loop.
    // gl_window.StartDrawLoop(time_step);
    // return 0;
    while (true) {
        if (gl_window.Active()) {
            gl_window.DoStepDynamics(time_step);
            gl_window.Render();
        } else {
            break;
        }
    }
#else
    // Run simulation for specified time
    int num_steps = std::ceil(time_end / time_step);

    double time = 0;
    for (int i = 0; i < num_steps; i++) {
        msystem.DoStepDynamics(time_step);
        time += time_step;
    }
#endif

    return 0;
}
<|endoftext|>


<commit_before>#include "chainerx/native/native_device.h"

#include <cstdint>

#include "chainerx/array.h"
#include "chainerx/axes.h"
#include "chainerx/device.h"
#include "chainerx/dtype.h"
#include "chainerx/kernels/reduction.h"
#include "chainerx/kernels/sorting.h"
#include "chainerx/macro.h"
#include "chainerx/native/data_type.h"
#include "chainerx/native/kernel_regist.h"
#include "chainerx/native/reduce.h"
#include "chainerx/numeric.h"
#include "chainerx/numeric_limits.h"
#include "chainerx/shape.h"

namespace chainerx {
namespace native {
namespace {

class NativeArgMaxKernel : public ArgMaxKernel {
public:
    void Call(const Array& a, const Axes& axis, const Array& out) override {
        CHAINERX_ASSERT(std::all_of(axis.begin(), axis.end(), [&a](int8_t i) { return a.shape()[i] > 0; }));
        CHAINERX_ASSERT(internal::IsValidReductionShape(a.shape(), axis, out.shape(), false));
        a.device().CheckDevicesCompatible(a, out);

        VisitDtype(a.dtype(), [&a, &axis, &out](auto pt) {
            using T = typename decltype(pt)::type;
            struct Impl {
                struct MaxAndArgMax {
                    T max;
                    int64_t argmax;
                };

                MaxAndArgMax Identity() { return {T{}, -1}; }
                MaxAndArgMax MapIn(T in, int64_t index) { return {in, index}; }
                void Reduce(MaxAndArgMax next, MaxAndArgMax& accum) {
                    if (accum.argmax < 0 || accum.max < next.max) {
                        accum = next;
                    }
                }
                int64_t MapOut(MaxAndArgMax accum) { return accum.argmax; }
            };
            Reduce<T, int64_t>(a, axis, out, Impl{});
        });
    }
};

CHAINERX_NATIVE_REGISTER_KERNEL(ArgMaxKernel, NativeArgMaxKernel);

class NativeArgMinKernel : public ArgMinKernel {
public:
    void Call(const Array& a, const Axes& axis, const Array& out) override {
        CHAINERX_ASSERT(std::all_of(axis.begin(), axis.end(), [&a](int8_t i) { return a.shape()[i] > 0; }));
        CHAINERX_ASSERT(internal::IsValidReductionShape(a.shape(), axis, out.shape(), false));
        a.device().CheckDevicesCompatible(a, out);

        VisitDtype(a.dtype(), [&a, &axis, &out](auto pt) {
            using T = typename decltype(pt)::type;
            struct Impl {
                struct MinAndArgMin {
                    T min;
                    int64_t argmin;
                };

                MinAndArgMin Identity() { return {T{}, -1}; }
                MinAndArgMin MapIn(T in, int64_t index) { return {in, index}; }
                void Reduce(MinAndArgMin next, MinAndArgMin& accum) {
                    if (accum.argmin < 0 || accum.min > next.min) {
                        accum = next;
                    }
                }
                int64_t MapOut(MinAndArgMin accum) { return accum.argmin; }
            };
            Reduce<T, int64_t>(a, axis, out, Impl{});
        });
    }
};

CHAINERX_NATIVE_REGISTER_KERNEL(ArgMinKernel, NativeArgMinKernel);

class NativeSumKernel : public SumKernel {
public:
    void Call(const Array& a, const Axes& axis, const Array& out) override {
        CHAINERX_ASSERT(internal::IsValidReductionShape(a.shape(), axis, out.shape(), true));
        a.device().CheckDevicesCompatible(a, out);

        auto do_sum = [&a, &axis, &out](auto in_pt, auto out_pt) {
            using In = typename decltype(in_pt)::type;
            using Out = typename decltype(out_pt)::type;
            using Accum = std::conditional_t<std::is_same<Out, Float16>{}, float, Out>;
            struct Impl {
                Accum Identity() { return Accum{0}; }
                Accum MapIn(In in, int64_t /*index*/) { return static_cast<Accum>(in); }
                void Reduce(Accum next, Accum& accum) { accum += next; }
                Out MapOut(Accum accum) { return static_cast<Out>(accum); }
            };
            Reduce<In, Out>(a, axis, out, Impl{});
        };

        VisitDtype(out.dtype(), [a_dtype = a.dtype(), &do_sum](auto out_pt) { VisitDtype(a_dtype, do_sum, out_pt); });
    }
};

CHAINERX_NATIVE_REGISTER_KERNEL(SumKernel, NativeSumKernel);

class NativeCumsumKernel : public CumsumKernel {
// TODO(imanishi): Performance improvement.
public:
    void Call(const Array& a, int8_t axis, const Array& out) override {
        a.device().CheckDevicesCompatible(a, out);
        const Array& a_cast = a.dtype() != out.dtype() ? a.AsType(out.dtype()) : a;

        VisitDtype(out.dtype(), [&a_cast, axis, &out](auto pt) {
            using T = typename decltype(pt)::type;

            IndexableArray<const T> a_iarray{a_cast};
            IndexableArray<T> out_iarray{out};
            Indexer<> out_indexer{out.shape()};
            Indexer<> prev_indexer{a_cast.shape()};

            int64_t axis_dim = a_cast.shape()[axis];

            // left: set of input dimensions lower than the axis
            // right: set of input dimensions higher than the axis
            Shape left_shape{a_cast.shape().begin(), a_cast.shape().begin() + axis};
            Shape right_shape{a_cast.shape().begin() + (axis + 1), a_cast.shape().end()};
            Shape axis_shape{axis_dim};  // always ndim==1

            Indexer<> left_indexer{left_shape};
            Indexer<> right_indexer{right_shape};
            Indexer<> indices_indexer{axis_shape};

            auto it_left = left_indexer.It(0);
            auto it_right = right_indexer.It(0);
            auto it_out = out_indexer.It(0);
            auto it_prev = prev_indexer.It(0);

            // Copy
            for (auto it = out_indexer.It(0); it; ++it) {
                out_iarray[it] = a_iarray[it];
            }

            for (auto it = indices_indexer.It(1); it; ++it) {
                int64_t index = it.raw_index();
                index = index % axis_dim;
                CHAINERX_ASSERT(0 <= index);
                CHAINERX_ASSERT(index < axis_dim);

                it_out.CopyIndex(it, it_left.ndim());

                for (it_left.Restart(); it_left; ++it_left) {
                    it_out.CopyIndex(it_left);

                    for (it_right.Restart(); it_right; ++it_right) {
                        it_out.CopyIndex(it_right, it_left.ndim() + it.ndim());
                        it_prev.CopyIndex(it_out);
                        it_prev.index()[axis] -= 1;
                        native_internal::StorageToDataType<T>(out_iarray[it_out]) +=
                                native_internal::StorageToDataType<T>(out_iarray[it_prev]);
                        it_prev.index()[axis] += 1;
                    }
                }
            }
        });
    }
};

CHAINERX_NATIVE_REGISTER_KERNEL(CumsumKernel, NativeCumsumKernel);

}  // namespace
}  // namespace native
}  // namespace chainerx
<commit_msg>Fix formatting<commit_after>#include "chainerx/native/native_device.h"

#include <cstdint>

#include "chainerx/array.h"
#include "chainerx/axes.h"
#include "chainerx/device.h"
#include "chainerx/dtype.h"
#include "chainerx/kernels/reduction.h"
#include "chainerx/kernels/sorting.h"
#include "chainerx/macro.h"
#include "chainerx/native/data_type.h"
#include "chainerx/native/kernel_regist.h"
#include "chainerx/native/reduce.h"
#include "chainerx/numeric.h"
#include "chainerx/numeric_limits.h"
#include "chainerx/shape.h"

namespace chainerx {
namespace native {
namespace {

class NativeArgMaxKernel : public ArgMaxKernel {
public:
    void Call(const Array& a, const Axes& axis, const Array& out) override {
        CHAINERX_ASSERT(std::all_of(axis.begin(), axis.end(), [&a](int8_t i) { return a.shape()[i] > 0; }));
        CHAINERX_ASSERT(internal::IsValidReductionShape(a.shape(), axis, out.shape(), false));
        a.device().CheckDevicesCompatible(a, out);

        VisitDtype(a.dtype(), [&a, &axis, &out](auto pt) {
            using T = typename decltype(pt)::type;
            struct Impl {
                struct MaxAndArgMax {
                    T max;
                    int64_t argmax;
                };

                MaxAndArgMax Identity() { return {T{}, -1}; }
                MaxAndArgMax MapIn(T in, int64_t index) { return {in, index}; }
                void Reduce(MaxAndArgMax next, MaxAndArgMax& accum) {
                    if (accum.argmax < 0 || accum.max < next.max) {
                        accum = next;
                    }
                }
                int64_t MapOut(MaxAndArgMax accum) { return accum.argmax; }
            };
            Reduce<T, int64_t>(a, axis, out, Impl{});
        });
    }
};

CHAINERX_NATIVE_REGISTER_KERNEL(ArgMaxKernel, NativeArgMaxKernel);

class NativeArgMinKernel : public ArgMinKernel {
public:
    void Call(const Array& a, const Axes& axis, const Array& out) override {
        CHAINERX_ASSERT(std::all_of(axis.begin(), axis.end(), [&a](int8_t i) { return a.shape()[i] > 0; }));
        CHAINERX_ASSERT(internal::IsValidReductionShape(a.shape(), axis, out.shape(), false));
        a.device().CheckDevicesCompatible(a, out);

        VisitDtype(a.dtype(), [&a, &axis, &out](auto pt) {
            using T = typename decltype(pt)::type;
            struct Impl {
                struct MinAndArgMin {
                    T min;
                    int64_t argmin;
                };

                MinAndArgMin Identity() { return {T{}, -1}; }
                MinAndArgMin MapIn(T in, int64_t index) { return {in, index}; }
                void Reduce(MinAndArgMin next, MinAndArgMin& accum) {
                    if (accum.argmin < 0 || accum.min > next.min) {
                        accum = next;
                    }
                }
                int64_t MapOut(MinAndArgMin accum) { return accum.argmin; }
            };
            Reduce<T, int64_t>(a, axis, out, Impl{});
        });
    }
};

CHAINERX_NATIVE_REGISTER_KERNEL(ArgMinKernel, NativeArgMinKernel);

class NativeSumKernel : public SumKernel {
public:
    void Call(const Array& a, const Axes& axis, const Array& out) override {
        CHAINERX_ASSERT(internal::IsValidReductionShape(a.shape(), axis, out.shape(), true));
        a.device().CheckDevicesCompatible(a, out);

        auto do_sum = [&a, &axis, &out](auto in_pt, auto out_pt) {
            using In = typename decltype(in_pt)::type;
            using Out = typename decltype(out_pt)::type;
            using Accum = std::conditional_t<std::is_same<Out, Float16>{}, float, Out>;
            struct Impl {
                Accum Identity() { return Accum{0}; }
                Accum MapIn(In in, int64_t /*index*/) { return static_cast<Accum>(in); }
                void Reduce(Accum next, Accum& accum) { accum += next; }
                Out MapOut(Accum accum) { return static_cast<Out>(accum); }
            };
            Reduce<In, Out>(a, axis, out, Impl{});
        };

        VisitDtype(out.dtype(), [a_dtype = a.dtype(), &do_sum](auto out_pt) { VisitDtype(a_dtype, do_sum, out_pt); });
    }
};

CHAINERX_NATIVE_REGISTER_KERNEL(SumKernel, NativeSumKernel);

// TODO(imanishi): Performance improvement.
class NativeCumsumKernel : public CumsumKernel {
public:
    void Call(const Array& a, int8_t axis, const Array& out) override {
        a.device().CheckDevicesCompatible(a, out);
        const Array& a_cast = a.dtype() != out.dtype() ? a.AsType(out.dtype()) : a;

        VisitDtype(out.dtype(), [&a_cast, axis, &out](auto pt) {
            using T = typename decltype(pt)::type;

            IndexableArray<const T> a_iarray{a_cast};
            IndexableArray<T> out_iarray{out};
            Indexer<> out_indexer{out.shape()};
            Indexer<> prev_indexer{a_cast.shape()};

            int64_t axis_dim = a_cast.shape()[axis];

            // left: set of input dimensions lower than the axis
            // right: set of input dimensions higher than the axis
            Shape left_shape{a_cast.shape().begin(), a_cast.shape().begin() + axis};
            Shape right_shape{a_cast.shape().begin() + (axis + 1), a_cast.shape().end()};
            Shape axis_shape{axis_dim};  // always ndim==1

            Indexer<> left_indexer{left_shape};
            Indexer<> right_indexer{right_shape};
            Indexer<> indices_indexer{axis_shape};

            auto it_left = left_indexer.It(0);
            auto it_right = right_indexer.It(0);
            auto it_out = out_indexer.It(0);
            auto it_prev = prev_indexer.It(0);

            // Copy
            for (auto it = out_indexer.It(0); it; ++it) {
                out_iarray[it] = a_iarray[it];
            }

            for (auto it = indices_indexer.It(1); it; ++it) {
                int64_t index = it.raw_index();
                index = index % axis_dim;
                CHAINERX_ASSERT(0 <= index);
                CHAINERX_ASSERT(index < axis_dim);

                it_out.CopyIndex(it, it_left.ndim());

                for (it_left.Restart(); it_left; ++it_left) {
                    it_out.CopyIndex(it_left);

                    for (it_right.Restart(); it_right; ++it_right) {
                        it_out.CopyIndex(it_right, it_left.ndim() + it.ndim());
                        it_prev.CopyIndex(it_out);
                        it_prev.index()[axis] -= 1;
                        native_internal::StorageToDataType<T>(out_iarray[it_out]) +=
                                native_internal::StorageToDataType<T>(out_iarray[it_prev]);
                        it_prev.index()[axis] += 1;
                    }
                }
            }
        });
    }
};

CHAINERX_NATIVE_REGISTER_KERNEL(CumsumKernel, NativeCumsumKernel);

}  // namespace
}  // namespace native
}  // namespace chainerx
<|endoftext|>


<commit_before>// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/chromeos/input_method/hotkey_manager.h"

#include "base/basictypes.h"
#include "base/logging.h"
#include "base/stl_util.h"

#include <X11/X.h>  // ShiftMask, ControlMask, etc.
#include <X11/Xlib.h>  // KeySym, XLookupString.
#include <X11/Xutil.h>  // XK_* macros.

namespace {

uint32 KeySymToModifier(KeySym keysym) {
  switch (keysym) {
    case XK_Control_L:
      return ControlMask;
    case XK_Control_R:
      return ControlMask;
    case XK_Shift_L:
      return ShiftMask;
    case XK_Shift_R:
      return ShiftMask;
    case XK_Alt_L:
      return Mod1Mask;
    case XK_Alt_R:
      return Mod1Mask;
    case XK_Meta_L:
      return Mod1Mask;
    case XK_Meta_R:
      return Mod1Mask;
    case XK_Super_L:
      return Mod2Mask;
    case XK_Super_R:
      return Mod2Mask;
    case XK_Hyper_L:
      return Mod3Mask;
    case XK_Hyper_R:
      return Mod3Mask;
    default:
      break;
  }
  return 0;
}

}  // namespace

namespace chromeos {
namespace input_method {

const int HotkeyManager::kNoEvent = -1;
const int HotkeyManager::kFiltered = -2;
const uint32 HotkeyManager::kKeyReleaseMask = 1U << 31;

// Make sure kKeyReleaseMask is not the same value as XXXMask in X11/X.h.
COMPILE_ASSERT(ControlMask != (1U << 31), CheckMaskValue);
COMPILE_ASSERT(ShiftMask != (1U << 31), CheckMaskValue);
COMPILE_ASSERT(LockMask != (1U << 31), CheckMaskValue);
COMPILE_ASSERT(Mod1Mask != (1U << 31), CheckMaskValue);
COMPILE_ASSERT(Mod2Mask != (1U << 31), CheckMaskValue);
COMPILE_ASSERT(Mod3Mask != (1U << 31), CheckMaskValue);
COMPILE_ASSERT(Mod4Mask != (1U << 31), CheckMaskValue);
COMPILE_ASSERT(Mod5Mask != (1U << 31), CheckMaskValue);

HotkeyManager::HotkeyManager()
  : previous_keysym_(NoSymbol),
    previous_modifiers_(0x0U),
    filter_release_events_(false) {
}

HotkeyManager::~HotkeyManager() {
}

void HotkeyManager::AddObserver(Observer* observer) {
  observers_.AddObserver(observer);
}

void HotkeyManager::RemoveObserver(Observer* observer) {
  observers_.RemoveObserver(observer);
}

bool HotkeyManager::AddHotkey(int event_id,
                              uint32 keysym,
                              uint32 modifiers,
                              bool trigger_on_key_press) {
  if (event_id < 0) {
    LOG(ERROR) << "Bad hotkey event id: " << event_id;
    return false;
  }
  modifiers = NormalizeModifiers(keysym, modifiers, trigger_on_key_press);
  return hotkeys_.insert(
      std::make_pair(std::make_pair(keysym, modifiers), event_id)).second;
}

bool HotkeyManager::RemoveHotkey(int event_id) {
  bool result = false;
  std::map<std::pair<uint32, uint32>, int>::iterator iter;
  for (iter = hotkeys_.begin(); iter != hotkeys_.end();) {
    if (iter->second == event_id) {
      hotkeys_.erase(iter++);
      result = true;
    } else {
      ++iter;
    }
  }
  return result;
}

bool HotkeyManager::FilterKeyEvent(const XEvent& key_event) {
  bool is_key_press = true;
  switch (key_event.type) {
    case KeyRelease:
      is_key_press = false;
      /* fall through */
    case KeyPress:
      break;
    default:
      LOG(ERROR) << "Unknown event: " << key_event.type;
      return false;
  }

  KeySym keysym = NoSymbol;
  ::XLookupString(
      const_cast<XKeyEvent*>(&key_event.xkey), NULL, 0, &keysym, NULL);

  const int event_id =
      FilterKeyEventInternal(keysym, key_event.xkey.state, is_key_press);
  if (event_id >= 0) {
    FOR_EACH_OBSERVER(Observer, observers_, HotkeyPressed(this, event_id));
    return true;  // The key event should be consumed since it's an IME hotkey.
  } else if (event_id == kFiltered) {
    return true;
  }
  return false;
}

uint32 HotkeyManager::NormalizeModifiers(
    uint32 keysym, uint32 modifiers, bool is_key_press) const {
  modifiers &= (ControlMask | ShiftMask | Mod1Mask | Mod2Mask | Mod3Mask);
  modifiers |= KeySymToModifier(keysym);
  if (!is_key_press) {
    modifiers |= kKeyReleaseMask;
  }
  return modifiers;
}

bool HotkeyManager::IsModifier(uint32 keysym) const {
  return KeySymToModifier(keysym) != 0;
}

int HotkeyManager::FilterKeyEventInternal(
    uint32 keysym, uint32 modifiers, bool is_key_press) {
  modifiers = NormalizeModifiers(keysym, modifiers, is_key_press);

  // This logic is the same as bus_input_context_filter_keyboard_shortcuts in
  // ibus-daemon.
  if (filter_release_events_) {
    if (modifiers & kKeyReleaseMask) {
      // This release event should not be passed to the application.
      return kFiltered;
    }
    filter_release_events_ = false;
  }

  int event_id = kNoEvent;
  // This logic is the same as ibus_hotkey_profile_filter_key_event in libibus.
  // See also http://crosbug.com/6225.
  do {
    if (modifiers & kKeyReleaseMask) {
      if (previous_modifiers_ & kKeyReleaseMask) {
        // The previous event has to be a key press event. This is necessary not
        // to switch IME when e.g. X is released after Shift+Alt+X is pressed.
        break;
      }
      if ((keysym != previous_keysym_) &&
          (!IsModifier(keysym) || !IsModifier(previous_keysym_))) {
        // This check is useful when e.g. Alt is released after Shift+Alt+X is
        // pressed, and the release event if X is intercepted by the window
        // manager. In this case, we should not switch IME, but the first check
        // does not work.
        // The IsModifier() checks are necessary for the 'press Alt, press
        // Shift, release Alt, release Shift' case to work.
        break;
      }
    }
    std::map<std::pair<uint32, uint32>, int>::const_iterator iter =
        hotkeys_.find(std::make_pair(keysym, modifiers));
    if (iter != hotkeys_.end()) {
      event_id = iter->second;
    }
  } while (false);

  // This logic is the same as bus_input_context_filter_keyboard_shortcuts in
  // ibus-daemon.
  previous_keysym_ = keysym;
  previous_modifiers_ = modifiers;
  // Start filtering release events if a hotkey is detected.
  filter_release_events_ = (event_id != kNoEvent);

  return event_id;
}

}  // namespace input_method
}  // namespace chromeos
<commit_msg>Fix typo in hotkey_manager.cc.<commit_after>// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/chromeos/input_method/hotkey_manager.h"

#include "base/basictypes.h"
#include "base/logging.h"
#include "base/stl_util.h"

#include <X11/X.h>  // ShiftMask, ControlMask, etc.
#include <X11/Xlib.h>  // KeySym, XLookupString.
#include <X11/Xutil.h>  // XK_* macros.

namespace {

uint32 KeySymToModifier(KeySym keysym) {
  switch (keysym) {
    case XK_Control_L:
      return ControlMask;
    case XK_Control_R:
      return ControlMask;
    case XK_Shift_L:
      return ShiftMask;
    case XK_Shift_R:
      return ShiftMask;
    case XK_Alt_L:
      return Mod1Mask;
    case XK_Alt_R:
      return Mod1Mask;
    case XK_Meta_L:
      return Mod1Mask;
    case XK_Meta_R:
      return Mod1Mask;
    case XK_Super_L:
      return Mod2Mask;
    case XK_Super_R:
      return Mod2Mask;
    case XK_Hyper_L:
      return Mod3Mask;
    case XK_Hyper_R:
      return Mod3Mask;
    default:
      break;
  }
  return 0;
}

}  // namespace

namespace chromeos {
namespace input_method {

const int HotkeyManager::kNoEvent = -1;
const int HotkeyManager::kFiltered = -2;
const uint32 HotkeyManager::kKeyReleaseMask = 1U << 31;

// Make sure kKeyReleaseMask is not the same value as XXXMask in X11/X.h.
COMPILE_ASSERT(ControlMask != (1U << 31), CheckMaskValue);
COMPILE_ASSERT(ShiftMask != (1U << 31), CheckMaskValue);
COMPILE_ASSERT(LockMask != (1U << 31), CheckMaskValue);
COMPILE_ASSERT(Mod1Mask != (1U << 31), CheckMaskValue);
COMPILE_ASSERT(Mod2Mask != (1U << 31), CheckMaskValue);
COMPILE_ASSERT(Mod3Mask != (1U << 31), CheckMaskValue);
COMPILE_ASSERT(Mod4Mask != (1U << 31), CheckMaskValue);
COMPILE_ASSERT(Mod5Mask != (1U << 31), CheckMaskValue);

HotkeyManager::HotkeyManager()
  : previous_keysym_(NoSymbol),
    previous_modifiers_(0x0U),
    filter_release_events_(false) {
}

HotkeyManager::~HotkeyManager() {
}

void HotkeyManager::AddObserver(Observer* observer) {
  observers_.AddObserver(observer);
}

void HotkeyManager::RemoveObserver(Observer* observer) {
  observers_.RemoveObserver(observer);
}

bool HotkeyManager::AddHotkey(int event_id,
                              uint32 keysym,
                              uint32 modifiers,
                              bool trigger_on_key_press) {
  if (event_id < 0) {
    LOG(ERROR) << "Bad hotkey event id: " << event_id;
    return false;
  }
  modifiers = NormalizeModifiers(keysym, modifiers, trigger_on_key_press);
  return hotkeys_.insert(
      std::make_pair(std::make_pair(keysym, modifiers), event_id)).second;
}

bool HotkeyManager::RemoveHotkey(int event_id) {
  bool result = false;
  std::map<std::pair<uint32, uint32>, int>::iterator iter;
  for (iter = hotkeys_.begin(); iter != hotkeys_.end();) {
    if (iter->second == event_id) {
      hotkeys_.erase(iter++);
      result = true;
    } else {
      ++iter;
    }
  }
  return result;
}

bool HotkeyManager::FilterKeyEvent(const XEvent& key_event) {
  bool is_key_press = true;
  switch (key_event.type) {
    case KeyRelease:
      is_key_press = false;
      /* fall through */
    case KeyPress:
      break;
    default:
      LOG(ERROR) << "Unknown event: " << key_event.type;
      return false;
  }

  KeySym keysym = NoSymbol;
  ::XLookupString(
      const_cast<XKeyEvent*>(&key_event.xkey), NULL, 0, &keysym, NULL);

  const int event_id =
      FilterKeyEventInternal(keysym, key_event.xkey.state, is_key_press);
  if (event_id >= 0) {
    FOR_EACH_OBSERVER(Observer, observers_, HotkeyPressed(this, event_id));
    return true;  // The key event should be consumed since it's an IME hotkey.
  } else if (event_id == kFiltered) {
    return true;
  }
  return false;
}

uint32 HotkeyManager::NormalizeModifiers(
    uint32 keysym, uint32 modifiers, bool is_key_press) const {
  modifiers &= (ControlMask | ShiftMask | Mod1Mask | Mod2Mask | Mod3Mask);
  modifiers |= KeySymToModifier(keysym);
  if (!is_key_press) {
    modifiers |= kKeyReleaseMask;
  }
  return modifiers;
}

bool HotkeyManager::IsModifier(uint32 keysym) const {
  return KeySymToModifier(keysym) != 0;
}

int HotkeyManager::FilterKeyEventInternal(
    uint32 keysym, uint32 modifiers, bool is_key_press) {
  modifiers = NormalizeModifiers(keysym, modifiers, is_key_press);

  // This logic is the same as bus_input_context_filter_keyboard_shortcuts in
  // ibus-daemon.
  if (filter_release_events_) {
    if (modifiers & kKeyReleaseMask) {
      // This release event should not be passed to the application.
      return kFiltered;
    }
    filter_release_events_ = false;
  }

  int event_id = kNoEvent;
  // This logic is the same as ibus_hotkey_profile_filter_key_event in libibus.
  // See also http://crosbug.com/6225.
  do {
    if (modifiers & kKeyReleaseMask) {
      if (previous_modifiers_ & kKeyReleaseMask) {
        // The previous event has to be a key press event. This is necessary not
        // to switch IME when e.g. X is released after Shift+Alt+X is pressed.
        break;
      }
      if ((keysym != previous_keysym_) &&
          (!IsModifier(keysym) || !IsModifier(previous_keysym_))) {
        // This check is useful when e.g. Alt is released after Shift+Alt+X is
        // pressed, and the release event of X is intercepted by the window
        // manager. In this case, we should not switch IME, but the first check
        // does not work.
        // The IsModifier() checks are necessary for the 'press Alt, press
        // Shift, release Alt, release Shift' case to work.
        break;
      }
    }
    std::map<std::pair<uint32, uint32>, int>::const_iterator iter =
        hotkeys_.find(std::make_pair(keysym, modifiers));
    if (iter != hotkeys_.end()) {
      event_id = iter->second;
    }
  } while (false);

  // This logic is the same as bus_input_context_filter_keyboard_shortcuts in
  // ibus-daemon.
  previous_keysym_ = keysym;
  previous_modifiers_ = modifiers;
  // Start filtering release events if a hotkey is detected.
  filter_release_events_ = (event_id != kNoEvent);

  return event_id;
}

}  // namespace input_method
}  // namespace chromeos
<|endoftext|>