<commit_before>#include "LocalCluster.hpp"

#include "TelegramServer.hpp"
#include "RemoteServerConnection.hpp"
#include "Storage.hpp"
#include "TelegramServerUser.hpp"
#include "DefaultAuthorizationProvider.hpp"

#include <QLoggingCategory>

Q_LOGGING_CATEGORY(c_loggingClusterCategory, "telegram.server.cluster", QtWarningMsg)

namespace Telegram {

namespace Server {

LocalCluster::LocalCluster(QObject *parent)
    : QObject(parent)
{
    m_constructor = [](QObject *parent) { return new Server(parent); };
}

void LocalCluster::setServerContructor(LocalCluster::ServerConstructor constructor)
{
    m_constructor = constructor;
}

void LocalCluster::setStorage(Storage *storage)
{
    m_storage = storage;
}

void LocalCluster::setAuthorizationProvider(Authorization::Provider *provider)
{
    m_authProvider = provider;
}

void LocalCluster::setServerConfiguration(const DcConfiguration &config)
{
    m_serverConfiguration = config;
}

void LocalCluster::setServerPrivateRsaKey(const Telegram::RsaKey &key)
{
    m_key = key;
}

bool LocalCluster::start()
{
    if (m_serverConfiguration.dcOptions.isEmpty()) {
        qCCritical(c_loggingClusterCategory) << Q_FUNC_INFO << "Unable to start cluster: DC options is empty.";
        return false;
    }

    if (!m_key.isPrivate()) {
        qCCritical(c_loggingClusterCategory) << Q_FUNC_INFO << "Unable to start cluster: Invalid private key.";
        return false;
    }

    if (!m_storage) {
        qCDebug(c_loggingClusterCategory) << Q_FUNC_INFO << "Fallback to default Storage implementation";
        m_storage = new Storage(this);
    }

    if (!m_authProvider) {
        qCDebug(c_loggingClusterCategory) << Q_FUNC_INFO << "Fallback to default auth provider";
        m_authProvider = new Authorization::DefaultProvider();
    }

    for (const DcOption &dc : m_serverConfiguration.dcOptions) {
        if (!dc.id) {
            qCCritical(c_loggingClusterCategory) << Q_FUNC_INFO << "Invalid configuration: DC id is null.";
            return false;
        }
        if (!dc.port) {
            qCCritical(c_loggingClusterCategory) << Q_FUNC_INFO << "Invalid configuration: Server port is not set.";
            return false;
        }
        if (dc.address.isEmpty()) {
            qCCritical(c_loggingClusterCategory) << Q_FUNC_INFO << "Invalid configuration: Server address is not set.";
            return false;
        }
        Server *server = m_constructor(this);
        server->setServerConfiguration(m_serverConfiguration);
        server->setDcOption(dc);
        server->setServerPrivateRsaKey(m_key);
        server->setStorage(m_storage);
        server->setAuthorizationProvider(m_authProvider);
        m_serverInstances.append(server);
    }

    bool hasFails = false;
    for (Server *server : m_serverInstances) {
        for (Server *peer : m_serverInstances) {
            if (server == peer) {
                continue;
            }
            RemoteServerConnection *remote = new RemoteServerConnection(server);
            remote->setRemoteServer(peer);
            server->addServerConnection(remote);
        }

        if (!server->start()) {
            qCCritical(c_loggingClusterCategory) << Q_FUNC_INFO << "Unable to start server" << server->dcId();
            hasFails = true;
        }
    }
    return !hasFails;
}

void LocalCluster::stop()
{
    for (Server *server : m_serverInstances) {
        server->stop();
    }
}

LocalUser *LocalCluster::addUser(const QString &identifier, quint32 dcId)
{
    Server *server = getServerInstance(dcId);
    if (!server) {
        qCWarning(c_loggingClusterCategory) << Q_FUNC_INFO << "Unable to add user" << identifier << "to unknown server id" << dcId;
        return nullptr;
    }
    return server->addUser(identifier);
}

LocalUser *LocalCluster::getUser(const QString &identifier)
{
    AbstractUser *u = m_serverInstances.first()->getAbstractUser(identifier);
    Server *s = getServerInstance(u->dcId());
    return s->getUser(identifier);
}

Server *LocalCluster::getServerInstance(quint32 dcId)
{
    for (Server *server : m_serverInstances) {
        if (server->dcId() == dcId) {
            return server;
        }
    }
    return nullptr;
}

ServerApi *LocalCluster::getServerApiInstance(quint32 dcId)
{
    return getServerInstance(dcId);
}

} // Server namespace

} // Telegram namespace
<commit_msg>LocalCluster: Check if an identifier is free on addUser()<commit_after>#include "LocalCluster.hpp"

#include "TelegramServer.hpp"
#include "RemoteServerConnection.hpp"
#include "Storage.hpp"
#include "TelegramServerUser.hpp"
#include "DefaultAuthorizationProvider.hpp"

#include <QLoggingCategory>

Q_LOGGING_CATEGORY(c_loggingClusterCategory, "telegram.server.cluster", QtWarningMsg)

namespace Telegram {

namespace Server {

LocalCluster::LocalCluster(QObject *parent)
    : QObject(parent)
{
    m_constructor = [](QObject *parent) { return new Server(parent); };
}

void LocalCluster::setServerContructor(LocalCluster::ServerConstructor constructor)
{
    m_constructor = constructor;
}

void LocalCluster::setStorage(Storage *storage)
{
    m_storage = storage;
}

void LocalCluster::setAuthorizationProvider(Authorization::Provider *provider)
{
    m_authProvider = provider;
}

void LocalCluster::setServerConfiguration(const DcConfiguration &config)
{
    m_serverConfiguration = config;
}

void LocalCluster::setServerPrivateRsaKey(const Telegram::RsaKey &key)
{
    m_key = key;
}

bool LocalCluster::start()
{
    if (m_serverConfiguration.dcOptions.isEmpty()) {
        qCCritical(c_loggingClusterCategory) << Q_FUNC_INFO << "Unable to start cluster: DC options is empty.";
        return false;
    }

    if (!m_key.isPrivate()) {
        qCCritical(c_loggingClusterCategory) << Q_FUNC_INFO << "Unable to start cluster: Invalid private key.";
        return false;
    }

    if (!m_storage) {
        qCDebug(c_loggingClusterCategory) << Q_FUNC_INFO << "Fallback to default Storage implementation";
        m_storage = new Storage(this);
    }

    if (!m_authProvider) {
        qCDebug(c_loggingClusterCategory) << Q_FUNC_INFO << "Fallback to default auth provider";
        m_authProvider = new Authorization::DefaultProvider();
    }

    for (const DcOption &dc : m_serverConfiguration.dcOptions) {
        if (!dc.id) {
            qCCritical(c_loggingClusterCategory) << Q_FUNC_INFO << "Invalid configuration: DC id is null.";
            return false;
        }
        if (!dc.port) {
            qCCritical(c_loggingClusterCategory) << Q_FUNC_INFO << "Invalid configuration: Server port is not set.";
            return false;
        }
        if (dc.address.isEmpty()) {
            qCCritical(c_loggingClusterCategory) << Q_FUNC_INFO << "Invalid configuration: Server address is not set.";
            return false;
        }
        Server *server = m_constructor(this);
        server->setServerConfiguration(m_serverConfiguration);
        server->setDcOption(dc);
        server->setServerPrivateRsaKey(m_key);
        server->setStorage(m_storage);
        server->setAuthorizationProvider(m_authProvider);
        m_serverInstances.append(server);
    }

    bool hasFails = false;
    for (Server *server : m_serverInstances) {
        for (Server *peer : m_serverInstances) {
            if (server == peer) {
                continue;
            }
            RemoteServerConnection *remote = new RemoteServerConnection(server);
            remote->setRemoteServer(peer);
            server->addServerConnection(remote);
        }

        if (!server->start()) {
            qCCritical(c_loggingClusterCategory) << Q_FUNC_INFO << "Unable to start server" << server->dcId();
            hasFails = true;
        }
    }
    return !hasFails;
}

void LocalCluster::stop()
{
    for (Server *server : m_serverInstances) {
        server->stop();
    }
}

LocalUser *LocalCluster::addUser(const QString &identifier, quint32 dcId)
{
    if (getUser(identifier)) {
        qCWarning(c_loggingClusterCategory) << Q_FUNC_INFO << "Unable to add user"
                                            << identifier << "(the identifier is already taken)";
        return nullptr;
    }
    Server *server = getServerInstance(dcId);
    if (!server) {
        qCWarning(c_loggingClusterCategory) << Q_FUNC_INFO << "Unable to add user"
                                            << identifier << "to unknown server id" << dcId;
        return nullptr;
    }
    return server->addUser(identifier);
}

LocalUser *LocalCluster::getUser(const QString &identifier)
{
    AbstractUser *u = m_serverInstances.first()->getAbstractUser(identifier);
    if (!u) {
        return nullptr;
    }
    Server *s = getServerInstance(u->dcId());
    return s->getUser(identifier);
}

Server *LocalCluster::getServerInstance(quint32 dcId)
{
    for (Server *server : m_serverInstances) {
        if (server->dcId() == dcId) {
            return server;
        }
    }
    return nullptr;
}

ServerApi *LocalCluster::getServerApiInstance(quint32 dcId)
{
    return getServerInstance(dcId);
}

} // Server namespace

} // Telegram namespace
<|endoftext|>


<commit_before>
#include <gtest/gtest.h>
#include <Unittests/unittests_common.hh>
#include <OpenMesh/Tools/Decimater/DecimaterT.hh>
#include <OpenMesh/Tools/Decimater/ModQuadricT.hh>

namespace {

class OpenMeshDecimater : public OpenMeshBase {

    protected:

        // This function is called before each test is run
        virtual void SetUp() {

            // Do some initial stuff with the member data here...
        }

        // This function is called after all tests are through
        virtual void TearDown() {

            // Do some final stuff with the member data here...
        }

    // Member already defined in OpenMeshBase
    //Mesh mesh_;
};

/*
 * ====================================================================
 * Define tests below
 * ====================================================================
 */

/*
 */
TEST_F(OpenMeshDecimater, DecimateMesh) {

  bool ok = OpenMesh::IO::read_mesh(mesh_, "cube1.off");

  ASSERT_TRUE(ok);

  typedef OpenMesh::Decimater::DecimaterT< Mesh >  Decimater;
  typedef OpenMesh::Decimater::ModQuadricT< Mesh >::Handle HModQuadric;

  Decimater decimaterDBG(mesh_);
  HModQuadric hModQuadricDBG;
  decimaterDBG.add( hModQuadricDBG );
  decimaterDBG.initialize();
  size_t removedVertices = 0;
  removedVertices = decimaterDBG.decimate_to(5000);
                    decimaterDBG.mesh().garbage_collection();

  EXPECT_EQ(2526u, removedVertices)     << "The number of remove vertices is not correct!";
  EXPECT_EQ(5000u, mesh_.n_vertices()) << "The number of vertices after decimation is not correct!";
  EXPECT_EQ(14994u, mesh_.n_edges())   << "The number of edges after decimation is not correct!";
  EXPECT_EQ(9996u, mesh_.n_faces())    << "The number of faces after decimation is not correct!";
}

TEST_F(OpenMeshDecimater, DecimateMeshToFaceVerticesLimit) {

  bool ok = OpenMesh::IO::read_mesh(mesh_, "cube1.off");

  ASSERT_TRUE(ok);

  typedef OpenMesh::Decimater::DecimaterT< Mesh >  Decimater;
  typedef OpenMesh::Decimater::ModQuadricT< Mesh >::Handle HModQuadric;

  Decimater decimaterDBG(mesh_);
  HModQuadric hModQuadricDBG;
  decimaterDBG.add( hModQuadricDBG );
  decimaterDBG.initialize();
  size_t removedVertices = 0;
  removedVertices = decimaterDBG.decimate_to_faces(5000, 8000);
                    decimaterDBG.mesh().garbage_collection();

  EXPECT_EQ(2526u, removedVertices) << "The number of remove vertices is not correct!";
  EXPECT_EQ(5000u, mesh_.n_vertices()) << "The number of vertices after decimation is not correct!";
  EXPECT_EQ(14994u, mesh_.n_edges()) << "The number of edges after decimation is not correct!";
  EXPECT_EQ(9996u, mesh_.n_faces()) << "The number of faces after decimation is not correct!";
}

TEST_F(OpenMeshDecimater, DecimateMeshToFaceFaceLimit) {

  bool ok = OpenMesh::IO::read_mesh(mesh_, "cube1.off");

  ASSERT_TRUE(ok);

  typedef OpenMesh::Decimater::DecimaterT< Mesh >  Decimater;
  typedef OpenMesh::Decimater::ModQuadricT< Mesh >::Handle HModQuadric;

  Decimater decimaterDBG(mesh_);
  HModQuadric hModQuadricDBG;
  decimaterDBG.add( hModQuadricDBG );
  decimaterDBG.initialize();
  size_t removedVertices = 0;
  removedVertices = decimaterDBG.decimate_to_faces(4500, 9996);
                    decimaterDBG.mesh().garbage_collection();

  EXPECT_EQ(2526u, removedVertices) << "The number of remove vertices is not correct!";
  EXPECT_EQ(5000u, mesh_.n_vertices()) << "The number of vertices after decimation is not correct!";
  EXPECT_EQ(14994u, mesh_.n_edges()) << "The number of edges after decimation is not correct!";
  EXPECT_EQ(9996u, mesh_.n_faces()) << "The number of faces after decimation is not correct!";
}

TEST_F(OpenMeshDecimater, DecimateMeshExampleFromDoc) {

  bool ok = OpenMesh::IO::read_mesh(mesh_, "cube1.off");

  ASSERT_TRUE(ok);

  typedef OpenMesh::Decimater::DecimaterT< Mesh >  Decimater;
  typedef OpenMesh::Decimater::ModQuadricT< Mesh >::Handle HModQuadric;

  Decimater decimaterDBG(mesh_);
  HModQuadric hModQuadricDBG;
  decimaterDBG.add( hModQuadricDBG );

  std::cout << decimaterDBG.module( hModQuadricDBG ).name() << std::endl;

  decimaterDBG.module( hModQuadricDBG ).unset_max_err();

  decimaterDBG.initialize();
  size_t removedVertices = 0;
  removedVertices = decimaterDBG.decimate_to_faces(4500, 9996);
                    decimaterDBG.mesh().garbage_collection();

  EXPECT_EQ(2526u, removedVertices) << "The number of remove vertices is not correct!";
  EXPECT_EQ(5000u, mesh_.n_vertices()) << "The number of vertices after decimation is not correct!";
  EXPECT_EQ(14994u, mesh_.n_edges()) << "The number of edges after decimation is not correct!";
  EXPECT_EQ(9996u, mesh_.n_faces()) << "The number of faces after decimation is not correct!";
}

}
<commit_msg>Silence Decimater test<commit_after>
#include <gtest/gtest.h>
#include <Unittests/unittests_common.hh>
#include <OpenMesh/Tools/Decimater/DecimaterT.hh>
#include <OpenMesh/Tools/Decimater/ModQuadricT.hh>

namespace {

class OpenMeshDecimater : public OpenMeshBase {

    protected:

        // This function is called before each test is run
        virtual void SetUp() {

            // Do some initial stuff with the member data here...
        }

        // This function is called after all tests are through
        virtual void TearDown() {

            // Do some final stuff with the member data here...
        }

    // Member already defined in OpenMeshBase
    //Mesh mesh_;
};

/*
 * ====================================================================
 * Define tests below
 * ====================================================================
 */

/*
 */
TEST_F(OpenMeshDecimater, DecimateMesh) {

  bool ok = OpenMesh::IO::read_mesh(mesh_, "cube1.off");

  ASSERT_TRUE(ok);

  typedef OpenMesh::Decimater::DecimaterT< Mesh >  Decimater;
  typedef OpenMesh::Decimater::ModQuadricT< Mesh >::Handle HModQuadric;

  Decimater decimaterDBG(mesh_);
  HModQuadric hModQuadricDBG;
  decimaterDBG.add( hModQuadricDBG );
  decimaterDBG.initialize();
  size_t removedVertices = 0;
  removedVertices = decimaterDBG.decimate_to(5000);
                    decimaterDBG.mesh().garbage_collection();

  EXPECT_EQ(2526u, removedVertices)     << "The number of remove vertices is not correct!";
  EXPECT_EQ(5000u, mesh_.n_vertices()) << "The number of vertices after decimation is not correct!";
  EXPECT_EQ(14994u, mesh_.n_edges())   << "The number of edges after decimation is not correct!";
  EXPECT_EQ(9996u, mesh_.n_faces())    << "The number of faces after decimation is not correct!";
}

TEST_F(OpenMeshDecimater, DecimateMeshToFaceVerticesLimit) {

  bool ok = OpenMesh::IO::read_mesh(mesh_, "cube1.off");

  ASSERT_TRUE(ok);

  typedef OpenMesh::Decimater::DecimaterT< Mesh >  Decimater;
  typedef OpenMesh::Decimater::ModQuadricT< Mesh >::Handle HModQuadric;

  Decimater decimaterDBG(mesh_);
  HModQuadric hModQuadricDBG;
  decimaterDBG.add( hModQuadricDBG );
  decimaterDBG.initialize();
  size_t removedVertices = 0;
  removedVertices = decimaterDBG.decimate_to_faces(5000, 8000);
                    decimaterDBG.mesh().garbage_collection();

  EXPECT_EQ(2526u, removedVertices) << "The number of remove vertices is not correct!";
  EXPECT_EQ(5000u, mesh_.n_vertices()) << "The number of vertices after decimation is not correct!";
  EXPECT_EQ(14994u, mesh_.n_edges()) << "The number of edges after decimation is not correct!";
  EXPECT_EQ(9996u, mesh_.n_faces()) << "The number of faces after decimation is not correct!";
}

TEST_F(OpenMeshDecimater, DecimateMeshToFaceFaceLimit) {

  bool ok = OpenMesh::IO::read_mesh(mesh_, "cube1.off");

  ASSERT_TRUE(ok);

  typedef OpenMesh::Decimater::DecimaterT< Mesh >  Decimater;
  typedef OpenMesh::Decimater::ModQuadricT< Mesh >::Handle HModQuadric;

  Decimater decimaterDBG(mesh_);
  HModQuadric hModQuadricDBG;
  decimaterDBG.add( hModQuadricDBG );
  decimaterDBG.initialize();
  size_t removedVertices = 0;
  removedVertices = decimaterDBG.decimate_to_faces(4500, 9996);
                    decimaterDBG.mesh().garbage_collection();

  EXPECT_EQ(2526u, removedVertices) << "The number of remove vertices is not correct!";
  EXPECT_EQ(5000u, mesh_.n_vertices()) << "The number of vertices after decimation is not correct!";
  EXPECT_EQ(14994u, mesh_.n_edges()) << "The number of edges after decimation is not correct!";
  EXPECT_EQ(9996u, mesh_.n_faces()) << "The number of faces after decimation is not correct!";
}

TEST_F(OpenMeshDecimater, DecimateMeshExampleFromDoc) {

  bool ok = OpenMesh::IO::read_mesh(mesh_, "cube1.off");

  ASSERT_TRUE(ok);

  typedef OpenMesh::Decimater::DecimaterT< Mesh >  Decimater;
  typedef OpenMesh::Decimater::ModQuadricT< Mesh >::Handle HModQuadric;

  Decimater decimaterDBG(mesh_);
  HModQuadric hModQuadricDBG;
  decimaterDBG.add( hModQuadricDBG );

  decimaterDBG.module( hModQuadricDBG ).unset_max_err();

  decimaterDBG.initialize();
  size_t removedVertices = 0;
  removedVertices = decimaterDBG.decimate_to_faces(4500, 9996);
                    decimaterDBG.mesh().garbage_collection();

  EXPECT_EQ(2526u, removedVertices) << "The number of remove vertices is not correct!";
  EXPECT_EQ(5000u, mesh_.n_vertices()) << "The number of vertices after decimation is not correct!";
  EXPECT_EQ(14994u, mesh_.n_edges()) << "The number of edges after decimation is not correct!";
  EXPECT_EQ(9996u, mesh_.n_faces()) << "The number of faces after decimation is not correct!";
}

}
<|endoftext|>


<commit_before>/*
 * Copyright (C) 2005-2020 Centre National d'Etudes Spatiales (CNES)
 *
 * This file is part of Orfeo Toolbox
 *
 *     https://www.orfeo-toolbox.org/
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "otbWrapperApplication.h"
#include "otbWrapperApplicationFactory.h"

#include "otbImageToNoDataMaskFilter.h"
#include "otbChangeNoDataValueFilter.h"
#include "itkMaskImageFilter.h"
#include "otbVectorImageToImageListFilter.h"
#include "otbImageListToVectorImageFilter.h"
#include "otbChangeInformationImageFilter.h"

namespace otb
{
namespace Wrapper
{

class ManageNoData : public Application
{
public:
  /** Standard class typedefs. */
  typedef ManageNoData                  Self;
  typedef Application                   Superclass;
  typedef itk::SmartPointer<Self>       Pointer;
  typedef itk::SmartPointer<const Self> ConstPointer;

  /** Standard macro */
  itkNewMacro(Self);

  itkTypeMacro(ManageNoData, otb::Application);

  /** Filters typedef */
  typedef otb::ImageToNoDataMaskFilter<FloatVectorImageType, UInt8ImageType>       FilterType;
  typedef otb::ChangeNoDataValueFilter<FloatVectorImageType, FloatVectorImageType> ChangeNoDataFilterType;

  typedef otb::ImageList<FloatImageType> ImageListType;
  typedef otb::VectorImageToImageListFilter<FloatVectorImageType, ImageListType> VectorToListFilterType;
  typedef otb::ImageListToVectorImageFilter<ImageListType, FloatVectorImageType> ListToVectorFilterType;
  typedef itk::MaskImageFilter<FloatImageType, UInt8ImageType, FloatImageType> MaskFilterType;
  typedef otb::ChangeInformationImageFilter<FloatVectorImageType> ChangeInfoFilterType;

private:
  void DoInit() override
  {
    SetName("ManageNoData");
    SetDescription("Manage No-Data");
    // Documentation
    SetDocLongDescription(
        "This application has two modes. The first allows building a mask of no-data pixels from the no-data flags read from the image file. The second allows "
        "updating the change the no-data value of an image (pixels value and metadata). This last mode also allows replacing NaN in images with a proper "
        "no-data value. To do so, one should activate the NaN is no-data option.");
    SetDocLimitations("None");
    SetDocAuthors("OTB-Team");
    SetDocSeeAlso("BandMath");

    AddDocTag(Tags::Manip);
    AddDocTag("Conversion");
    AddDocTag("Image Dynamic");

    AddParameter(ParameterType_InputImage, "in", "Input image");
    SetParameterDescription("in", "Input image");

    AddParameter(ParameterType_OutputImage, "out", "Output Image");
    SetParameterDescription("out", "Output image");

    AddParameter(ParameterType_Bool, "usenan", "Consider NaN as no-data");
    SetParameterDescription("usenan", "If active, the application will consider NaN as no-data values as well");

    AddParameter(ParameterType_Choice, "mode", "No-data handling mode");
    SetParameterDescription("mode", "Allows choosing between different no-data handling options");

    AddChoice("mode.buildmask", "Build a no-data Mask");

    AddParameter(ParameterType_Float, "mode.buildmask.inv", "Inside Value");
    SetParameterDescription("mode.buildmask.inv", "Value given in the output mask to pixels that are not no data pixels");
    SetDefaultParameterInt("mode.buildmask.inv", 1);

    AddParameter(ParameterType_Float, "mode.buildmask.outv", "Outside Value");
    SetParameterDescription("mode.buildmask.outv", "Value given in the output mask to pixels that are no data pixels");
    SetDefaultParameterInt("mode.buildmask.outv", 0);

    AddChoice("mode.changevalue", "Change the no-data value");

    AddParameter(ParameterType_Float, "mode.changevalue.newv", "The new no-data value");
    SetParameterDescription("mode.changevalue.newv", "The new no-data value");
    SetDefaultParameterInt("mode.changevalue.newv", 0);

    AddChoice("mode.apply", "Apply a mask as no-data");

    SetParameterDescription("mode.apply", "Apply an external mask to an image using the no-data value of the input image");
    AddParameter(ParameterType_InputImage, "mode.apply.mask", "Mask image");
    SetParameterDescription("mode.apply.mask", "Mask to be applied on input image (valid pixels have non null values)");
    AddParameter(ParameterType_Float, "mode.apply.ndval", "Nodata value used");
    SetParameterDescription("mode.apply.ndval", "No Data value used according to the mask image");
    SetDefaultParameterFloat("mode.apply.ndval", 0.0);

    SetParameterString("mode", "buildmask");

    AddRAMParameter();

    // Doc example parameter settings
    SetDocExampleParameterValue("in", "QB_Toulouse_Ortho_XS.tif");
    SetDocExampleParameterValue("out", "QB_Toulouse_Ortho_XS_nodatamask.tif uint8");
    SetDocExampleParameterValue("mode.buildmask.inv", "255");
    SetDocExampleParameterValue("mode.buildmask.outv", "0");

    SetOfficialDocLink();
  }

  void DoUpdateParameters() override
  {
    // Nothing to do here for the parameters : all are independent
  }

  void DoExecute() override
  {
    FloatVectorImageType::Pointer inputPtr = this->GetParameterImage("in");

    m_Filter = FilterType::New();
    m_Filter->SetInsideValue(this->GetParameterFloat("mode.buildmask.inv"));
    m_Filter->SetOutsideValue(this->GetParameterFloat("mode.buildmask.outv"));
    m_Filter->SetNaNIsNoData(GetParameterInt("usenan"));
    m_Filter->SetInput(inputPtr);

    m_ChangeNoDataFilter = ChangeNoDataFilterType::New();
    m_ChangeNoDataFilter->SetInput(inputPtr);
    m_ChangeNoDataFilter->SetNaNIsNoData(GetParameterInt("usenan"));

    std::vector<double> newNoData(inputPtr->GetNumberOfComponentsPerPixel(), GetParameterFloat("mode.changevalue.newv"));

    m_ChangeNoDataFilter->SetNewNoDataValues(newNoData);

    if (GetParameterString("mode") == "buildmask")
    {
      SetParameterOutputImage("out", m_Filter->GetOutput());
    }
    else if (GetParameterString("mode") == "changevalue")
    {
      SetParameterOutputImage("out", m_ChangeNoDataFilter->GetOutput());
    }
    else if (GetParameterString("mode") == "apply")
    {
      m_MaskFilters.clear();
      UInt8ImageType::Pointer  maskPtr = this->GetParameterUInt8Image("mode.apply.mask");
      unsigned int             nbBands = inputPtr->GetNumberOfComponentsPerPixel();
      const auto & imd                 = inputPtr->GetImageMetadata();
      std::vector<bool>        flags;
      std::vector<double>      values;
      bool                     ret = otb::ReadNoDataFlags(imd, flags, values);
      if (!ret)
      {
        flags.resize(nbBands, true);
        values.resize(nbBands, GetParameterFloat("mode.apply.ndval"));
      }

      m_V2L = VectorToListFilterType::New();
      m_V2L->SetInput(inputPtr);
      ImageListType::Pointer inputList = m_V2L->GetOutput();
      inputList->UpdateOutputInformation();
      ImageListType::Pointer outputList = ImageListType::New();
      for (unsigned int i = 0; i < nbBands; ++i)
      {
        if (flags[i])
        {
          MaskFilterType::Pointer masker = MaskFilterType::New();
          masker->SetInput(inputList->GetNthElement(i));
          masker->SetMaskImage(maskPtr);
          masker->SetMaskingValue(0);
          masker->SetOutsideValue(values[i]);
          outputList->PushBack(masker->GetOutput());
          m_MaskFilters.push_back(masker);
        }
        else
        {
          outputList->PushBack(inputList->GetNthElement(i));
        }
      }
      m_L2V = ListToVectorFilterType::New();
      m_L2V->SetInput(outputList);
      if (!ret)
      {
        m_MetaDataChanger = ChangeInfoFilterType::New();
        m_MetaDataChanger->SetInput(m_L2V->GetOutput());
        m_MetaDataChanger->SetOutputMetaData<std::vector<bool>>(otb::MetaDataKey::NoDataValueAvailable, &flags);
        m_MetaDataChanger->SetOutputMetaData<std::vector<double>>(otb::MetaDataKey::NoDataValue, &values);
        SetParameterOutputImage("out", m_MetaDataChanger->GetOutput());
      }
      else
      {
        SetParameterOutputImage("out", m_L2V->GetOutput());
      }
    }
  }

  FilterType::Pointer                  m_Filter;
  ChangeNoDataFilterType::Pointer      m_ChangeNoDataFilter;
  std::vector<MaskFilterType::Pointer> m_MaskFilters;
  VectorToListFilterType::Pointer      m_V2L;
  ListToVectorFilterType::Pointer      m_L2V;
  ChangeInfoFilterType::Pointer        m_MetaDataChanger;
};
}
}

OTB_APPLICATION_EXPORT(otb::Wrapper::ManageNoData)
<commit_msg>REFAC: use ImageMetadata instead of itk dictionary to manage NoData in the applymask mode of ManageNoData<commit_after>/*
 * Copyright (C) 2005-2020 Centre National d'Etudes Spatiales (CNES)
 *
 * This file is part of Orfeo Toolbox
 *
 *     https://www.orfeo-toolbox.org/
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "otbWrapperApplication.h"
#include "otbWrapperApplicationFactory.h"

#include "otbImageToNoDataMaskFilter.h"
#include "otbChangeNoDataValueFilter.h"
#include "itkMaskImageFilter.h"
#include "otbVectorImageToImageListFilter.h"
#include "otbImageListToVectorImageFilter.h"

namespace otb
{
namespace Wrapper
{

class ManageNoData : public Application
{
public:
  /** Standard class typedefs. */
  typedef ManageNoData                  Self;
  typedef Application                   Superclass;
  typedef itk::SmartPointer<Self>       Pointer;
  typedef itk::SmartPointer<const Self> ConstPointer;

  /** Standard macro */
  itkNewMacro(Self);

  itkTypeMacro(ManageNoData, otb::Application);

  /** Filters typedef */
  typedef otb::ImageToNoDataMaskFilter<FloatVectorImageType, UInt8ImageType>       FilterType;
  typedef otb::ChangeNoDataValueFilter<FloatVectorImageType, FloatVectorImageType> ChangeNoDataFilterType;

  typedef otb::ImageList<FloatImageType> ImageListType;
  typedef otb::VectorImageToImageListFilter<FloatVectorImageType, ImageListType> VectorToListFilterType;
  typedef otb::ImageListToVectorImageFilter<ImageListType, FloatVectorImageType> ListToVectorFilterType;
  typedef itk::MaskImageFilter<FloatImageType, UInt8ImageType, FloatImageType> MaskFilterType;

private:
  void DoInit() override
  {
    SetName("ManageNoData");
    SetDescription("Manage No-Data");
    // Documentation
    SetDocLongDescription(
        "This application has two modes. The first allows building a mask of no-data pixels from the no-data flags read from the image file. The second allows "
        "updating the change the no-data value of an image (pixels value and metadata). This last mode also allows replacing NaN in images with a proper "
        "no-data value. To do so, one should activate the NaN is no-data option.");
    SetDocLimitations("None");
    SetDocAuthors("OTB-Team");
    SetDocSeeAlso("BandMath");

    AddDocTag(Tags::Manip);
    AddDocTag("Conversion");
    AddDocTag("Image Dynamic");

    AddParameter(ParameterType_InputImage, "in", "Input image");
    SetParameterDescription("in", "Input image");

    AddParameter(ParameterType_OutputImage, "out", "Output Image");
    SetParameterDescription("out", "Output image");

    AddParameter(ParameterType_Bool, "usenan", "Consider NaN as no-data");
    SetParameterDescription("usenan", "If active, the application will consider NaN as no-data values as well");

    AddParameter(ParameterType_Choice, "mode", "No-data handling mode");
    SetParameterDescription("mode", "Allows choosing between different no-data handling options");

    AddChoice("mode.buildmask", "Build a no-data Mask");

    AddParameter(ParameterType_Float, "mode.buildmask.inv", "Inside Value");
    SetParameterDescription("mode.buildmask.inv", "Value given in the output mask to pixels that are not no data pixels");
    SetDefaultParameterInt("mode.buildmask.inv", 1);

    AddParameter(ParameterType_Float, "mode.buildmask.outv", "Outside Value");
    SetParameterDescription("mode.buildmask.outv", "Value given in the output mask to pixels that are no data pixels");
    SetDefaultParameterInt("mode.buildmask.outv", 0);

    AddChoice("mode.changevalue", "Change the no-data value");

    AddParameter(ParameterType_Float, "mode.changevalue.newv", "The new no-data value");
    SetParameterDescription("mode.changevalue.newv", "The new no-data value");
    SetDefaultParameterInt("mode.changevalue.newv", 0);

    AddChoice("mode.apply", "Apply a mask as no-data");

    SetParameterDescription("mode.apply", "Apply an external mask to an image using the no-data value of the input image");
    AddParameter(ParameterType_InputImage, "mode.apply.mask", "Mask image");
    SetParameterDescription("mode.apply.mask", "Mask to be applied on input image (valid pixels have non null values)");
    AddParameter(ParameterType_Float, "mode.apply.ndval", "Nodata value used");
    SetParameterDescription("mode.apply.ndval", "No Data value used according to the mask image");
    SetDefaultParameterFloat("mode.apply.ndval", 0.0);

    SetParameterString("mode", "buildmask");

    AddRAMParameter();

    // Doc example parameter settings
    SetDocExampleParameterValue("in", "QB_Toulouse_Ortho_XS.tif");
    SetDocExampleParameterValue("out", "QB_Toulouse_Ortho_XS_nodatamask.tif uint8");
    SetDocExampleParameterValue("mode.buildmask.inv", "255");
    SetDocExampleParameterValue("mode.buildmask.outv", "0");

    SetOfficialDocLink();
  }

  void DoUpdateParameters() override
  {
    // Nothing to do here for the parameters : all are independent
  }

  void DoExecute() override
  {
    FloatVectorImageType::Pointer inputPtr = this->GetParameterImage("in");

    m_Filter = FilterType::New();
    m_Filter->SetInsideValue(this->GetParameterFloat("mode.buildmask.inv"));
    m_Filter->SetOutsideValue(this->GetParameterFloat("mode.buildmask.outv"));
    m_Filter->SetNaNIsNoData(GetParameterInt("usenan"));
    m_Filter->SetInput(inputPtr);

    m_ChangeNoDataFilter = ChangeNoDataFilterType::New();
    m_ChangeNoDataFilter->SetInput(inputPtr);
    m_ChangeNoDataFilter->SetNaNIsNoData(GetParameterInt("usenan"));

    std::vector<double> newNoData(inputPtr->GetNumberOfComponentsPerPixel(), GetParameterFloat("mode.changevalue.newv"));

    m_ChangeNoDataFilter->SetNewNoDataValues(newNoData);

    if (GetParameterString("mode") == "buildmask")
    {
      SetParameterOutputImage("out", m_Filter->GetOutput());
    }
    else if (GetParameterString("mode") == "changevalue")
    {
      SetParameterOutputImage("out", m_ChangeNoDataFilter->GetOutput());
    }
    else if (GetParameterString("mode") == "apply")
    {
      m_MaskFilters.clear();
      UInt8ImageType::Pointer  maskPtr = this->GetParameterUInt8Image("mode.apply.mask");
      unsigned int             nbBands = inputPtr->GetNumberOfComponentsPerPixel();
      const auto & imd                 = inputPtr->GetImageMetadata();
      std::vector<bool>        flags;
      std::vector<double>      values;
      bool                     ret = otb::ReadNoDataFlags(imd, flags, values);
      if (!ret)
      {
        flags = std::vector<bool>(nbBands, true);
        values = std::vector<double>(nbBands, GetParameterFloat("mode.apply.ndval"));
      }

      m_V2L = VectorToListFilterType::New();
      m_V2L->SetInput(inputPtr);
      ImageListType::Pointer inputList = m_V2L->GetOutput();
      inputList->UpdateOutputInformation();
      ImageListType::Pointer outputList = ImageListType::New();
      for (unsigned int i = 0; i < nbBands; ++i)
      {
        if (flags[i])
        {
          MaskFilterType::Pointer masker = MaskFilterType::New();
          masker->SetInput(inputList->GetNthElement(i));
          masker->SetMaskImage(maskPtr);
          masker->SetMaskingValue(0);
          masker->SetOutsideValue(values[i]);
          outputList->PushBack(masker->GetOutput());
          m_MaskFilters.push_back(masker);
        }
        else
        {
          outputList->PushBack(inputList->GetNthElement(i));
        }
      }
      m_L2V = ListToVectorFilterType::New();
      m_L2V->SetInput(outputList);
      if (!ret)
      {
        // write the new NoData values in the output metadata (mode.apply.ndval)
        m_L2V->UpdateOutputInformation();
        otb::WriteNoDataFlags(flags, values, m_L2V->GetOutput()->GetImageMetadata());
      }
      SetParameterOutputImage("out", m_L2V->GetOutput());
    }
  }

  FilterType::Pointer                  m_Filter;
  ChangeNoDataFilterType::Pointer      m_ChangeNoDataFilter;
  std::vector<MaskFilterType::Pointer> m_MaskFilters;
  VectorToListFilterType::Pointer      m_V2L;
  ListToVectorFilterType::Pointer      m_L2V;
};
}
}

OTB_APPLICATION_EXPORT(otb::Wrapper::ManageNoData)
<|endoftext|>


<commit_before>#include <iostream>
#include <list>
#include <gmpxx.h>

#define BITSET_SIZE 64

class DivisorGenerator {

private:
	std::list<mpz_class> divisors;
	std::string divisorsCSV;
	const mpz_class dividend;
	const mpz_class firstValueToTest;
	const int count;
	void computeDivisors();
	void computeDivisorsCSV();

public:
	DivisorGenerator(mpz_class d, mpz_class f, int c);
	DivisorGenerator(std::string d, std::string f, int c);
	const std::list<mpz_class> &getDivisors();
	const std::string &getDivisorsCSV();
	std::list<mpz_class>::const_iterator getIterator();
};<commit_msg>Added class to generate divisors<commit_after>#include <iostream>
#include <list>
#include <gmpxx.h>

class DivisorGenerator {

private:
	std::list<mpz_class> divisors;
	std::string divisorsCSV;
	const mpz_class dividend;
	const mpz_class firstValueToTest;
	const int count;
	void computeDivisors();
	void computeDivisorsCSV();

public:
	DivisorGenerator(mpz_class d, mpz_class f, int c);
	DivisorGenerator(std::string d, std::string f, int c);
	const std::list<mpz_class> &getDivisors();
	const std::string &getDivisorsCSV();
	std::list<mpz_class>::const_iterator getIterator();
};<|endoftext|>


<commit_before>#if !defined (__CINT__) || (defined(__MAKECINT__))
#include <iostream>
#include "TObject.h"
#include "AliVEvent.h"
#include "AliAnalysisTaskdNdEtapp13.h"
#include "AliAnalysisManager.h"
#include "TProof.h"
#include "TFile.h"
#include "TROOT.h"
#endif

const Double_t centBinsMultV0MSPD[] = {1e-10, 1., 5., 10., 15., 20., 30., 40., 50., 70., 100};
const Double_t centBinsMultV0M[] =   {0., 1., 5., 10., 15., 20., 30., 40., 50., 70., 100};
const Double_t centBinsMultV0M_Ridge[] = {0., 0.01, 0.1, 0.5, 1., 5., 10., 15., 20., 30., 40., 50., 70., 100};
//const Double_t centBinsMultV0M_Ridge[] = {0., 0.001, 0.01, 0.1, 0.5, 1., 5., 10., 15., 20., 30., 40., 50., 70., 100};
//const Double_t centBinsMultV0M_Ridge[] = {0., 0.001, 0.01, 0.1, 0.5, 1., 3., 5., 10., 20., 30., 40., 50., 90., 100};
//const Double_t centBinsMultV0M_Ridge[] = {0., 1., 8., 16., 25., 27., 43., 45., 68., 69., 100.};
const Double_t centBinsMultRef[] = {0., 1., 5., 10., 15., 20., 30., 40., 50., 70., 100};
const Double_t centBinsMB[] = {0., 100.};

//__________________________________________________________________

AliAnalysisTaskdNdEtapp13 *
AddAnalysisTaskdNdEtaPP13(const Char_t *outfilename = "AnalysisResults.root",
const Char_t *listname = "clist",
//
Float_t etaMin     =-5,          // min eta range to fill in histos
Float_t etaMax     = 5,          // max eta range to fill in histos
Float_t zMin       = -10,         // process events with Z vertex min
Float_t zMax       =  10,         //                     max positions
const char* useCentVar = "V0M",          // centrality variable to use
//
Float_t cutSigNStd  = 1.5,        // cut on weighed distance used to extract signal
Float_t cutSigDPhiS = -1,        // cut on dPhi-phiBent used to extract signal (if negative -> dphi*sqrt(cutSigNStd)
Bool_t  useMC  = kTRUE,          // fill MC info
//
Bool_t doRec  = kFALSE,          // fill data histos from new reco
Bool_t doInj  = kFALSE,          // create Inj. bg
Bool_t doRot  = kFALSE,          // create Rot. bg
//
// specific parameters for reconstruction
float  phiRot      = 3.14159e+00, // angle for bg. generation with rotation
float  injScale    = 1.,//0.7,    // inject injScale*Ncl(Lr1/Lr2) hits
Bool_t scaleDTheta = kTRUE,       // scale dTheta by 1/sin^2(theta) in trackleting
float  nStdDev     = 25.,         // number of st.dev. for tracklet cut to keep
float  dphi        = 0.08,        // dphi window (sigma of tracklet cut)
float  dtht        = 0.025,       // dtheta .... (if negative, abs will be used with additional cut on |dthetaX|, apart from w.distance
  float  phishift    = 0.0045,      // bending shift
  Bool_t remOvl      = kTRUE,
  float  ovlPhiCut   = 0.005,
  float  ovlZetaCut  = 0.05,
  Bool_t checkReconstructables = kFALSE,
  UInt_t trigSel = AliVEvent::kINT7,//kTRUE, // fill histos for reconstructable (needs useMC and doRec)
  Bool_t ridgeBins      = kFALSE,             // VOM percentiles with ridge binning
  Bool_t useBCmod      = kFALSE,              // set Bunch crossing mode 4
  Int_t BCmod4      = 2,              // set Bunch crossing mode 4
  const char* phicuts      = "phi0",       // set cut on affected phi regions
Float_t mcscale = 1.0,                // set mc scale for V0 amplitude
Bool_t mcCalib      = kTRUE,       // set cut on affected phi regions
TString calibfile = "./V0M_bins_LHC15g3a3.root"
//  const Char_t *calibfile = "$HOME/alice/ali-master/AliPhysics/PWGLF/ppVsMult/dNdEtaPP13/task/V0M_bins_LHC15g3a3.root",
)
{

  if (cutSigDPhiS<0) cutSigDPhiS = TMath::Sqrt(cutSigNStd)*dphi;

  /* init analysis name */
  TString analysisName = "dNdEtapp13";

  /* check analysis manager */
  AliAnalysisManager *mgr = AliAnalysisManager::GetAnalysisManager();
  if (!mgr) {
    Error("", "cannot get analysis manager");
    return NULL;
  }

  /* check input event handler */
  if (!mgr->GetInputEventHandler()) {
    Error("", "cannot get input event handler");
    return NULL;
  }

  /* get common input data container */
  AliAnalysisDataContainer *inputc = mgr->GetCommonInputContainer();
  if (!inputc) {
    Error("", "cannot get common input container");
    return NULL;
  }

  /* create output data container */
  AliAnalysisDataContainer *outputc1 = mgr->CreateContainer(listname, TList::Class(), AliAnalysisManager::kOutputContainer, outfilename);

  if (!outputc1) {
    Error("", "cannot create output container \"clist\"");
    return NULL;
  }

  /*  create task and connect input/output */
  AliAnalysisTaskdNdEtapp13 *task = new AliAnalysisTaskdNdEtapp13("AliAnalysisTaskdNdEtapp13");
  mgr->AddTask(task);
  mgr->ConnectInput(task, 0, inputc);
  mgr->ConnectOutput(task, 1, outputc1);
  //__________________________________________________________________
  //__________________________________________________________________
  //__________________________________________________________________

  /* configure task */

  //__________________________________________________________________
  //__________________________________________________________________
  //__________________________________________________________________

  //

  TFile *fcalib = TFile::Open(calibfile);
  TH1D * hMCcalib2 = (TH1D*)fcalib->Get("h3") ;

  task->SetCalibfilePath(calibfile);
  task->SetCalibHisto(hMCcalib2);

  task->SetUseCentralityVar(useCentVar);

  const Double_t *centBins = NULL;
  //const Float_t *centBins = NULL;

  Int_t nCentBins = 0;
  TString strCentr = useCentVar;
  if (strCentr == "MB"){
    centBins = centBinsMB;
    nCentBins = sizeof(centBinsMB) / 8 - 1;
  }
  else if (strCentr == "V0M" && ridgeBins){
    centBins = centBinsMultV0M_Ridge;
    nCentBins = sizeof(centBinsMultV0M_Ridge) / 8 - 1;
  }
  else if (strCentr == "V0M" || strCentr == "V0av"){
    centBins = centBinsMultV0M;
    nCentBins = sizeof(centBinsMultV0M) / 8 - 1;
  }
  else if(strCentr == "RefMult08"){
    centBins = centBinsMultRef;
    nCentBins = sizeof(centBinsMultRef) / 8 - 1;
  }
  else if(strCentr == "SPDClusters1"){
    centBins = centBinsMultV0MSPD;
    nCentBins = sizeof(centBinsMultV0MSPD) / 8 - 1;
  }
  else if(strCentr == "CL0"){
    centBins = centBinsMultV0M;
    nCentBins = sizeof(centBinsMultV0M) / 8 - 1;
  }
  else if(strCentr == "SPDTracklets08"){
    centBins = centBinsMultV0M;
    nCentBins = sizeof(centBinsMultV0M) / 8 - 1;
  }
  else if(strCentr == "SPDTracklets08to15"){
    centBins = centBinsMultV0M;
    nCentBins = sizeof(centBinsMultV0M) / 8 - 1;
  }
  else if (strCentr == "SPDTracklets" && ridgeBins){
    centBins = centBinsMultV0M_Ridge;
    nCentBins = sizeof(centBinsMultV0M_Ridge) / 8 - 1;
  }
  else if(strCentr == "SPDTracklets"){
    centBins = centBinsMultV0M;
    nCentBins = sizeof(centBinsMultV0M) / 8 - 1;
  }

  task->SetCentPercentiles(centBins, nCentBins);
  task->SetTriggerSelection(trigSel);
  //
  task->SetDoNormalReco(doRec);
  task->SetDoInjection(doInj);
  task->SetDoRotation(doRot);
  //
  task->SetUseMC(useMC);
  task->SetCheckReconstructables(checkReconstructables);
  //
  task->SetEtaMin(etaMin);
  task->SetEtaMax(etaMax);
  task->SetZVertexMin(zMin);
  task->SetZVertexMax(zMax);
  //
  task->SetDPhiSCut(cutSigDPhiS);
  task->SetNStdCut(cutSigNStd);
  //
  task->SetScaleDThetaBySin2T(scaleDTheta);
  task->SetNStdDev(nStdDev);
  task->SetPhiWindow(dphi);
  task->SetThetaWindow(dtht);
  task->SetPhiShift(phishift);
  task->SetPhiOverlapCut(ovlPhiCut);
  task->SetZetaOverlapCut(ovlZetaCut);
  task->SetPhiRot(phiRot);
  task->SetInjScale(injScale);
  task->SetRemoveOverlaps(remOvl);
  task->SetUseBCMod(useBCmod);
  task->SetMCCalib(mcCalib);
  task->SetBCMod(BCmod4);
  task->SetCutOnPhi(phicuts);
  task->SetScaleMCV0(mcscale);

  //
  //    task->Dump();
  return task;
}
<commit_msg>changed HM bins<commit_after>#if !defined (__CINT__) || (defined(__MAKECINT__))
#include <iostream>
#include "TObject.h"
#include "AliVEvent.h"
#include "AliAnalysisTaskdNdEtapp13.h"
#include "AliAnalysisManager.h"
#include "TProof.h"
#include "TFile.h"
#include "TROOT.h"
#endif

const Double_t centBinsMultV0MSPD[] = {1e-10, 1., 5., 10., 15., 20., 30., 40., 50., 70., 100.};
const Double_t centBinsMultV0M[] =   {0., 1., 5., 10., 15., 20., 30., 40., 50., 70., 100.};
const Double_t centBinsMultV0M_Ridge[] = {0., 0.01, 0.1, 1., 5., 10., 15., 20., 30., 40., 50., 70., 100.};
//const Double_t centBinsMultV0M_Ridge[] = {0., 0.001, 0.01, 0.1, 0.5, 1., 5., 10., 15., 20., 30., 40., 50., 70., 100};
//const Double_t centBinsMultV0M_Ridge[] = {0., 0.001, 0.01, 0.1, 0.5, 1., 3., 5., 10., 20., 30., 40., 50., 90., 100};
//const Double_t centBinsMultV0M_Ridge[] = {0., 1., 8., 16., 25., 27., 43., 45., 68., 69., 100.};
const Double_t centBinsMultRef[] = {0., 1., 5., 10., 15., 20., 30., 40., 50., 70., 100.};
const Double_t centBinsMB[] = {0., 100.};

//__________________________________________________________________

AliAnalysisTaskdNdEtapp13 *
AddAnalysisTaskdNdEtaPP13(const Char_t *outfilename = "AnalysisResults.root",
const Char_t *listname = "clist",
//
Float_t etaMin     =-5,          // min eta range to fill in histos
Float_t etaMax     = 5,          // max eta range to fill in histos
Float_t zMin       = -10,         // process events with Z vertex min
Float_t zMax       =  10,         //                     max positions
const char* useCentVar = "V0M",          // centrality variable to use
//
Float_t cutSigNStd  = 1.5,        // cut on weighed distance used to extract signal
Float_t cutSigDPhiS = -1,        // cut on dPhi-phiBent used to extract signal (if negative -> dphi*sqrt(cutSigNStd)
Bool_t  useMC  = kTRUE,          // fill MC info
//
Bool_t doRec  = kFALSE,          // fill data histos from new reco
Bool_t doInj  = kFALSE,          // create Inj. bg
Bool_t doRot  = kFALSE,          // create Rot. bg
//
// specific parameters for reconstruction
float  phiRot      = 3.14159e+00, // angle for bg. generation with rotation
float  injScale    = 1.,//0.7,    // inject injScale*Ncl(Lr1/Lr2) hits
Bool_t scaleDTheta = kTRUE,       // scale dTheta by 1/sin^2(theta) in trackleting
float  nStdDev     = 25.,         // number of st.dev. for tracklet cut to keep
float  dphi        = 0.08,        // dphi window (sigma of tracklet cut)
float  dtht        = 0.025,       // dtheta .... (if negative, abs will be used with additional cut on |dthetaX|, apart from w.distance
  float  phishift    = 0.0045,      // bending shift
  Bool_t remOvl      = kTRUE,
  float  ovlPhiCut   = 0.005,
  float  ovlZetaCut  = 0.05,
  Bool_t checkReconstructables = kFALSE,
  UInt_t trigSel = AliVEvent::kINT7,//kTRUE, // fill histos for reconstructable (needs useMC and doRec)
  Bool_t ridgeBins      = kFALSE,             // VOM percentiles with ridge binning
  Bool_t useBCmod      = kFALSE,              // set Bunch crossing mode 4
  Int_t BCmod4      = 2,              // set Bunch crossing mode 4
  const char* phicuts      = "phi0",       // set cut on affected phi regions
Float_t mcscale = 1.0,                // set mc scale for V0 amplitude
Bool_t mcCalib      = kTRUE,       // set cut on affected phi regions
TString calibfile = "./V0M_bins_LHC15g3a3.root"
//  const Char_t *calibfile = "$HOME/alice/ali-master/AliPhysics/PWGLF/ppVsMult/dNdEtaPP13/task/V0M_bins_LHC15g3a3.root",
)
{

  if (cutSigDPhiS<0) cutSigDPhiS = TMath::Sqrt(cutSigNStd)*dphi;

  /* init analysis name */
  TString analysisName = "dNdEtapp13";

  /* check analysis manager */
  AliAnalysisManager *mgr = AliAnalysisManager::GetAnalysisManager();
  if (!mgr) {
    Error("", "cannot get analysis manager");
    return NULL;
  }

  /* check input event handler */
  if (!mgr->GetInputEventHandler()) {
    Error("", "cannot get input event handler");
    return NULL;
  }

  /* get common input data container */
  AliAnalysisDataContainer *inputc = mgr->GetCommonInputContainer();
  if (!inputc) {
    Error("", "cannot get common input container");
    return NULL;
  }

  /* create output data container */
  AliAnalysisDataContainer *outputc1 = mgr->CreateContainer(listname, TList::Class(), AliAnalysisManager::kOutputContainer, outfilename);

  if (!outputc1) {
    Error("", "cannot create output container \"clist\"");
    return NULL;
  }

  /*  create task and connect input/output */
  AliAnalysisTaskdNdEtapp13 *task = new AliAnalysisTaskdNdEtapp13("AliAnalysisTaskdNdEtapp13");
  mgr->AddTask(task);
  mgr->ConnectInput(task, 0, inputc);
  mgr->ConnectOutput(task, 1, outputc1);
  //__________________________________________________________________
  //__________________________________________________________________
  //__________________________________________________________________

  /* configure task */

  //__________________________________________________________________
  //__________________________________________________________________
  //__________________________________________________________________

  //

  TFile *fcalib = TFile::Open(calibfile);
  TH1D * hMCcalib2 = (TH1D*)fcalib->Get("h3") ;

  task->SetCalibfilePath(calibfile);
  task->SetCalibHisto(hMCcalib2);

  task->SetUseCentralityVar(useCentVar);

  const Double_t *centBins = NULL;
  //const Float_t *centBins = NULL;

  Int_t nCentBins = 0;
  TString strCentr = useCentVar;
  if (strCentr == "MB"){
    centBins = centBinsMB;
    nCentBins = sizeof(centBinsMB) / 8 - 1;
  }
  else if (strCentr == "V0M" && ridgeBins){
    centBins = centBinsMultV0M_Ridge;
    nCentBins = sizeof(centBinsMultV0M_Ridge) / 8 - 1;
  }
  else if (strCentr == "V0M" || strCentr == "V0av"){
    centBins = centBinsMultV0M;
    nCentBins = sizeof(centBinsMultV0M) / 8 - 1;
  }
  else if(strCentr == "RefMult08"){
    centBins = centBinsMultRef;
    nCentBins = sizeof(centBinsMultRef) / 8 - 1;
  }
  else if(strCentr == "SPDClusters1"){
    centBins = centBinsMultV0MSPD;
    nCentBins = sizeof(centBinsMultV0MSPD) / 8 - 1;
  }
  else if(strCentr == "CL0"){
    centBins = centBinsMultV0M;
    nCentBins = sizeof(centBinsMultV0M) / 8 - 1;
  }
  else if(strCentr == "SPDTracklets08"){
    centBins = centBinsMultV0M;
    nCentBins = sizeof(centBinsMultV0M) / 8 - 1;
  }
  else if(strCentr == "SPDTracklets08to15"){
    centBins = centBinsMultV0M;
    nCentBins = sizeof(centBinsMultV0M) / 8 - 1;
  }
  else if (strCentr == "SPDTracklets" && ridgeBins){
    centBins = centBinsMultV0M_Ridge;
    nCentBins = sizeof(centBinsMultV0M_Ridge) / 8 - 1;
  }
  else if(strCentr == "SPDTracklets"){
    centBins = centBinsMultV0M;
    nCentBins = sizeof(centBinsMultV0M) / 8 - 1;
  }

  task->SetCentPercentiles(centBins, nCentBins);
  task->SetTriggerSelection(trigSel);
  //
  task->SetDoNormalReco(doRec);
  task->SetDoInjection(doInj);
  task->SetDoRotation(doRot);
  //
  task->SetUseMC(useMC);
  task->SetCheckReconstructables(checkReconstructables);
  //
  task->SetEtaMin(etaMin);
  task->SetEtaMax(etaMax);
  task->SetZVertexMin(zMin);
  task->SetZVertexMax(zMax);
  //
  task->SetDPhiSCut(cutSigDPhiS);
  task->SetNStdCut(cutSigNStd);
  //
  task->SetScaleDThetaBySin2T(scaleDTheta);
  task->SetNStdDev(nStdDev);
  task->SetPhiWindow(dphi);
  task->SetThetaWindow(dtht);
  task->SetPhiShift(phishift);
  task->SetPhiOverlapCut(ovlPhiCut);
  task->SetZetaOverlapCut(ovlZetaCut);
  task->SetPhiRot(phiRot);
  task->SetInjScale(injScale);
  task->SetRemoveOverlaps(remOvl);
  task->SetUseBCMod(useBCmod);
  task->SetMCCalib(mcCalib);
  task->SetBCMod(BCmod4);
  task->SetCutOnPhi(phicuts);
  task->SetScaleMCV0(mcscale);

  //
  //    task->Dump();
  return task;
}
<|endoftext|>


<commit_before>/*
-----------------------------------------------------------------------------
This source file is part of OGRE
    (Object-oriented Graphics Rendering Engine)
For the latest info, see http://www.ogre3d.org/

Copyright (c) 2000-2014 Torus Knot Software Ltd

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
-----------------------------------------------------------------------------
*/

#include "OgreGLES2HardwareBufferManager.h"
#include "OgreGLES2HardwareVertexBuffer.h"
#include "OgreGLES2HardwareIndexBuffer.h"
#include "OgreGLES2HardwareUniformBuffer.h"
#include "OgreGLES2RenderToVertexBuffer.h"
#include "OgreGLES2RenderSystem.h"
#include "OgreGLVertexArrayObject.h"
#include "OgreGLUtil.h"
#include "OgreRoot.h"

namespace Ogre {
    //-----------------------------------------------------------------------
    GLES2HardwareBufferManagerBase::GLES2HardwareBufferManagerBase()
    {
        mRenderSystem = getGLES2RenderSystem();
    }

    GLES2HardwareBufferManagerBase::~GLES2HardwareBufferManagerBase()
    {
        destroyAllDeclarations();
        destroyAllBindings();
    }

    GLES2StateCacheManager * GLES2HardwareBufferManagerBase::getStateCacheManager()
    {
        return mRenderSystem->_getStateCacheManager();
    }

    void GLES2HardwareBufferManagerBase::::notifyContextDestroyed(GLContext* context)
    {
        OGRE_LOCK_MUTEX(mVertexDeclarationsMutex);
        for(VertexDeclarationList::iterator it = mVertexDeclarations.begin(), it_end = mVertexDeclarations.end(); it != it_end; ++it)
            static_cast<GLVertexArrayObject*>(*it)->notifyContextDestroyed(context);
    }

    HardwareVertexBufferSharedPtr
        GLES2HardwareBufferManagerBase::createVertexBuffer(size_t vertexSize,
                                                      size_t numVerts,
                                                      HardwareBuffer::Usage usage,
                                                      bool useShadowBuffer)
    {
        if(!Root::getSingleton().getRenderSystem()->getCapabilities()->hasCapability(RSC_MAPBUFFER))
            useShadowBuffer = true;

        GLES2HardwareVertexBuffer* buf = OGRE_NEW GLES2HardwareVertexBuffer(this, vertexSize, numVerts, usage, useShadowBuffer);

        {
            OGRE_LOCK_MUTEX(mVertexBuffersMutex);
            mVertexBuffers.insert(buf);
        }
        return HardwareVertexBufferSharedPtr(buf);
    }

    HardwareIndexBufferSharedPtr GLES2HardwareBufferManagerBase::createIndexBuffer(HardwareIndexBuffer::IndexType itype,
                                                                              size_t numIndexes,
                                                                              HardwareBuffer::Usage usage,
                                                                              bool useShadowBuffer)
    {
        if(!Root::getSingleton().getRenderSystem()->getCapabilities()->hasCapability(RSC_MAPBUFFER))
            useShadowBuffer = true;

        GLES2HardwareIndexBuffer* buf = OGRE_NEW GLES2HardwareIndexBuffer(this, itype, numIndexes, usage, useShadowBuffer);

        {
            OGRE_LOCK_MUTEX(mIndexBuffersMutex);
            mIndexBuffers.insert(buf);
        }
        return HardwareIndexBufferSharedPtr(buf);
    }

    RenderToVertexBufferSharedPtr GLES2HardwareBufferManagerBase::createRenderToVertexBuffer()
    {
#if OGRE_NO_GLES3_SUPPORT == 0
        return RenderToVertexBufferSharedPtr(new GLES2RenderToVertexBuffer());
#else
        // not supported
        return RenderToVertexBufferSharedPtr();
#endif
    }

    VertexDeclaration* GLES2HardwareBufferManagerBase::createVertexDeclarationImpl(void)
    {
        return OGRE_NEW GLVertexArrayObject();
    }

    void GLES2HardwareBufferManagerBase::destroyVertexDeclarationImpl(VertexDeclaration* decl)
    {
        if(decl)
            OGRE_DELETE decl;
    }

    GLenum GLES2HardwareBufferManagerBase::getGLUsage(unsigned int usage)
    {
        return  (usage & HardwareBuffer::HBU_DISCARDABLE) ? GL_STREAM_DRAW :
                (usage & HardwareBuffer::HBU_STATIC) ? GL_STATIC_DRAW :
                GL_DYNAMIC_DRAW;
    }

    GLenum GLES2HardwareBufferManagerBase::getGLType(VertexElementType type)
    {
        switch(type)
        {
            case VET_FLOAT1:
            case VET_FLOAT2:
            case VET_FLOAT3:
            case VET_FLOAT4:
                return GL_FLOAT;
            case VET_SHORT1:
            case VET_SHORT2:
            case VET_SHORT3:
            case VET_SHORT4:
            case VET_SHORT2_NORM:
            case VET_SHORT4_NORM:
                return GL_SHORT;
            case VET_COLOUR:
            case VET_COLOUR_ABGR:
            case VET_COLOUR_ARGB:
            case VET_UBYTE4:
            case VET_UBYTE4_NORM:
                return GL_UNSIGNED_BYTE;
            case VET_BYTE4:
            case VET_BYTE4_NORM:
                return GL_BYTE;
            case VET_INT1:
            case VET_INT2:
            case VET_INT3:
            case VET_INT4:
#if OGRE_NO_GLES3_SUPPORT == 0
                return GL_INT;
#endif
            case VET_UINT1:
            case VET_UINT2:
            case VET_UINT3:
            case VET_UINT4:
#if OGRE_NO_GLES3_SUPPORT == 0
                return GL_UNSIGNED_INT;
#endif
            case VET_USHORT1:
            case VET_USHORT2:
            case VET_USHORT3:
            case VET_USHORT4:
            case VET_USHORT2_NORM:
            case VET_USHORT4_NORM:
#if OGRE_NO_GLES3_SUPPORT == 0
                return GL_UNSIGNED_SHORT;
#endif
            case VET_DOUBLE1:
            case VET_DOUBLE2:
            case VET_DOUBLE3:
            case VET_DOUBLE4:
                return 0;
        };

        OgreAssert(false, "unknown Vertex Element Type");
        return 0;
    }

    //---------------------------------------------------------------------
    Ogre::HardwareUniformBufferSharedPtr GLES2HardwareBufferManagerBase::createUniformBuffer( size_t sizeBytes, HardwareBuffer::Usage usage, bool useShadowBuffer, const String& name )
    {
#if OGRE_NO_GLES3_SUPPORT == 0
        GLES2HardwareUniformBuffer* buf =
        new GLES2HardwareUniformBuffer(this, sizeBytes, usage, useShadowBuffer, name);
        {
            OGRE_LOCK_MUTEX(mUniformBuffersMutex);
            mUniformBuffers.insert(buf);
        }
        return HardwareUniformBufferSharedPtr(buf);
#else
        OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR,
            "GLES2 does not support uniform buffer objects",
            "GLES2HardwareBufferManagerBase::createUniformBuffer");
#endif
    }
    //---------------------------------------------------------------------
    Ogre::HardwareCounterBufferSharedPtr GLES2HardwareBufferManagerBase::createCounterBuffer( size_t sizeBytes, HardwareBuffer::Usage usage, bool useShadowBuffer, const String& name )
    {
        OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR,
                    "GLES2 does not support atomic counter buffers",
                    "GLES2HardwareBufferManagerBase::createCounterBuffer");
    }

}
<commit_msg>Fixed GLES2 build<commit_after>/*
-----------------------------------------------------------------------------
This source file is part of OGRE
    (Object-oriented Graphics Rendering Engine)
For the latest info, see http://www.ogre3d.org/

Copyright (c) 2000-2014 Torus Knot Software Ltd

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
-----------------------------------------------------------------------------
*/

#include "OgreGLES2HardwareBufferManager.h"
#include "OgreGLES2HardwareVertexBuffer.h"
#include "OgreGLES2HardwareIndexBuffer.h"
#include "OgreGLES2HardwareUniformBuffer.h"
#include "OgreGLES2RenderToVertexBuffer.h"
#include "OgreGLES2RenderSystem.h"
#include "OgreGLVertexArrayObject.h"
#include "OgreGLUtil.h"
#include "OgreRoot.h"

namespace Ogre {
    //-----------------------------------------------------------------------
    GLES2HardwareBufferManagerBase::GLES2HardwareBufferManagerBase()
    {
        mRenderSystem = getGLES2RenderSystem();
    }

    GLES2HardwareBufferManagerBase::~GLES2HardwareBufferManagerBase()
    {
        destroyAllDeclarations();
        destroyAllBindings();
    }

    GLES2StateCacheManager * GLES2HardwareBufferManagerBase::getStateCacheManager()
    {
        return mRenderSystem->_getStateCacheManager();
    }

    void GLES2HardwareBufferManagerBase::notifyContextDestroyed(GLContext* context)
    {
        OGRE_LOCK_MUTEX(mVertexDeclarationsMutex);
        for(VertexDeclarationList::iterator it = mVertexDeclarations.begin(), it_end = mVertexDeclarations.end(); it != it_end; ++it)
            static_cast<GLVertexArrayObject*>(*it)->notifyContextDestroyed(context);
    }

    HardwareVertexBufferSharedPtr
        GLES2HardwareBufferManagerBase::createVertexBuffer(size_t vertexSize,
                                                      size_t numVerts,
                                                      HardwareBuffer::Usage usage,
                                                      bool useShadowBuffer)
    {
        if(!Root::getSingleton().getRenderSystem()->getCapabilities()->hasCapability(RSC_MAPBUFFER))
            useShadowBuffer = true;

        GLES2HardwareVertexBuffer* buf = OGRE_NEW GLES2HardwareVertexBuffer(this, vertexSize, numVerts, usage, useShadowBuffer);

        {
            OGRE_LOCK_MUTEX(mVertexBuffersMutex);
            mVertexBuffers.insert(buf);
        }
        return HardwareVertexBufferSharedPtr(buf);
    }

    HardwareIndexBufferSharedPtr GLES2HardwareBufferManagerBase::createIndexBuffer(HardwareIndexBuffer::IndexType itype,
                                                                              size_t numIndexes,
                                                                              HardwareBuffer::Usage usage,
                                                                              bool useShadowBuffer)
    {
        if(!Root::getSingleton().getRenderSystem()->getCapabilities()->hasCapability(RSC_MAPBUFFER))
            useShadowBuffer = true;

        GLES2HardwareIndexBuffer* buf = OGRE_NEW GLES2HardwareIndexBuffer(this, itype, numIndexes, usage, useShadowBuffer);

        {
            OGRE_LOCK_MUTEX(mIndexBuffersMutex);
            mIndexBuffers.insert(buf);
        }
        return HardwareIndexBufferSharedPtr(buf);
    }

    RenderToVertexBufferSharedPtr GLES2HardwareBufferManagerBase::createRenderToVertexBuffer()
    {
#if OGRE_NO_GLES3_SUPPORT == 0
        return RenderToVertexBufferSharedPtr(new GLES2RenderToVertexBuffer());
#else
        // not supported
        return RenderToVertexBufferSharedPtr();
#endif
    }

    VertexDeclaration* GLES2HardwareBufferManagerBase::createVertexDeclarationImpl(void)
    {
        return OGRE_NEW GLVertexArrayObject();
    }

    void GLES2HardwareBufferManagerBase::destroyVertexDeclarationImpl(VertexDeclaration* decl)
    {
        if(decl)
            OGRE_DELETE decl;
    }

    GLenum GLES2HardwareBufferManagerBase::getGLUsage(unsigned int usage)
    {
        return  (usage & HardwareBuffer::HBU_DISCARDABLE) ? GL_STREAM_DRAW :
                (usage & HardwareBuffer::HBU_STATIC) ? GL_STATIC_DRAW :
                GL_DYNAMIC_DRAW;
    }

    GLenum GLES2HardwareBufferManagerBase::getGLType(VertexElementType type)
    {
        switch(type)
        {
            case VET_FLOAT1:
            case VET_FLOAT2:
            case VET_FLOAT3:
            case VET_FLOAT4:
                return GL_FLOAT;
            case VET_SHORT1:
            case VET_SHORT2:
            case VET_SHORT3:
            case VET_SHORT4:
            case VET_SHORT2_NORM:
            case VET_SHORT4_NORM:
                return GL_SHORT;
            case VET_COLOUR:
            case VET_COLOUR_ABGR:
            case VET_COLOUR_ARGB:
            case VET_UBYTE4:
            case VET_UBYTE4_NORM:
                return GL_UNSIGNED_BYTE;
            case VET_BYTE4:
            case VET_BYTE4_NORM:
                return GL_BYTE;
            case VET_INT1:
            case VET_INT2:
            case VET_INT3:
            case VET_INT4:
#if OGRE_NO_GLES3_SUPPORT == 0
                return GL_INT;
#endif
            case VET_UINT1:
            case VET_UINT2:
            case VET_UINT3:
            case VET_UINT4:
#if OGRE_NO_GLES3_SUPPORT == 0
                return GL_UNSIGNED_INT;
#endif
            case VET_USHORT1:
            case VET_USHORT2:
            case VET_USHORT3:
            case VET_USHORT4:
            case VET_USHORT2_NORM:
            case VET_USHORT4_NORM:
#if OGRE_NO_GLES3_SUPPORT == 0
                return GL_UNSIGNED_SHORT;
#endif
            case VET_DOUBLE1:
            case VET_DOUBLE2:
            case VET_DOUBLE3:
            case VET_DOUBLE4:
                return 0;
        };

        OgreAssert(false, "unknown Vertex Element Type");
        return 0;
    }

    //---------------------------------------------------------------------
    Ogre::HardwareUniformBufferSharedPtr GLES2HardwareBufferManagerBase::createUniformBuffer( size_t sizeBytes, HardwareBuffer::Usage usage, bool useShadowBuffer, const String& name )
    {
#if OGRE_NO_GLES3_SUPPORT == 0
        GLES2HardwareUniformBuffer* buf =
        new GLES2HardwareUniformBuffer(this, sizeBytes, usage, useShadowBuffer, name);
        {
            OGRE_LOCK_MUTEX(mUniformBuffersMutex);
            mUniformBuffers.insert(buf);
        }
        return HardwareUniformBufferSharedPtr(buf);
#else
        OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR,
            "GLES2 does not support uniform buffer objects",
            "GLES2HardwareBufferManagerBase::createUniformBuffer");
#endif
    }
    //---------------------------------------------------------------------
    Ogre::HardwareCounterBufferSharedPtr GLES2HardwareBufferManagerBase::createCounterBuffer( size_t sizeBytes, HardwareBuffer::Usage usage, bool useShadowBuffer, const String& name )
    {
        OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR,
                    "GLES2 does not support atomic counter buffers",
                    "GLES2HardwareBufferManagerBase::createCounterBuffer");
    }

}
<|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 "views/touchui/touch_factory.h"

#include <gtk/gtk.h>
#include <gdk/gdkx.h>
#include <X11/cursorfont.h>
#include <X11/extensions/XInput.h>
#include <X11/extensions/XInput2.h>
#include <X11/extensions/XIproto.h>

#include "base/basictypes.h"
#include "base/compiler_specific.h"
#include "base/logging.h"
#include "ui/base/x/x11_util.h"

namespace {

// The X cursor is hidden if it is idle for kCursorIdleSeconds seconds.
int kCursorIdleSeconds = 5;

// Given the TouchParam, return the correspoding valuator index using
// the X device information through Atom name matching.
char FindTPValuator(Display* display,
                    XIDeviceInfo* info,
                    views::TouchFactory::TouchParam touch_param) {
  // Lookup table for mapping TouchParam to Atom string used in X.
  // A full set of Atom strings can be found at xserver-properties.h.
  static struct {
    views::TouchFactory::TouchParam tp;
    const char* atom;
  } kTouchParamAtom[] = {
    { views::TouchFactory::TP_TOUCH_MAJOR, "Abs MT Touch Major" },
    { views::TouchFactory::TP_TOUCH_MINOR, "Abs MT Touch Minor" },
    { views::TouchFactory::TP_ORIENTATION, "Abs MT Orientation" },
    { views::TouchFactory::TP_LAST_ENTRY, NULL },
  };

  const char* atom_tp = NULL;

  for (size_t i = 0; i < ARRAYSIZE_UNSAFE(kTouchParamAtom); i++) {
    if (touch_param == kTouchParamAtom[i].tp) {
      atom_tp = kTouchParamAtom[i].atom;
      break;
    }
  }

  if (!atom_tp)
    return -1;

  for (int i = 0; i < info->num_classes; i++) {
    if (info->classes[i]->type != XIValuatorClass)
      continue;
    XIValuatorClassInfo* v =
        reinterpret_cast<XIValuatorClassInfo*>(info->classes[i]);

    const char* atom = XGetAtomName(display, v->label);

    if (atom && strcmp(atom, atom_tp) == 0)
      return v->number;
  }

  return -1;
}

// Setup XInput2 select for the GtkWidget.
gboolean GtkWidgetRealizeCallback(GSignalInvocationHint* hint, guint nparams,
                                  const GValue* pvalues, gpointer data) {
  GtkWidget* widget = GTK_WIDGET(g_value_get_object(pvalues));
  GdkWindow* window = widget->window;
  views::TouchFactory* factory = static_cast<views::TouchFactory*>(data);

  if (GDK_WINDOW_TYPE(window) != GDK_WINDOW_TOPLEVEL &&
      GDK_WINDOW_TYPE(window) != GDK_WINDOW_CHILD &&
      GDK_WINDOW_TYPE(window) != GDK_WINDOW_DIALOG)
    return true;

  factory->SetupXI2ForXWindow(GDK_WINDOW_XID(window));
  return true;
}

// We need to capture all the GDK windows that get created, and start
// listening for XInput2 events. So we setup a callback to the 'realize'
// signal for GTK+ widgets, so that whenever the signal triggers for any
// GtkWidget, which means the GtkWidget should now have a GdkWindow, we can
// setup XInput2 events for the GdkWindow.
guint realize_signal_id = 0;
guint realize_hook_id = 0;

void SetupGtkWidgetRealizeNotifier(views::TouchFactory* factory) {
  gpointer klass = g_type_class_ref(GTK_TYPE_WIDGET);

  g_signal_parse_name("realize", GTK_TYPE_WIDGET,
                      &realize_signal_id, NULL, FALSE);
  realize_hook_id = g_signal_add_emission_hook(realize_signal_id, 0,
      GtkWidgetRealizeCallback, static_cast<gpointer>(factory), NULL);

  g_type_class_unref(klass);
}

void RemoveGtkWidgetRealizeNotifier() {
  if (realize_signal_id != 0)
    g_signal_remove_emission_hook(realize_signal_id, realize_hook_id);
  realize_signal_id = 0;
  realize_hook_id = 0;
}

}  // namespace

namespace views {

// static
TouchFactory* TouchFactory::GetInstance() {
  return Singleton<TouchFactory>::get();
}

TouchFactory::TouchFactory()
    : is_cursor_visible_(true),
      cursor_timer_(),
      pointer_device_lookup_(),
      touch_device_list_() {
  char nodata[] = { 0, 0, 0, 0, 0, 0, 0, 0 };
  XColor black;
  black.red = black.green = black.blue = 0;
  Display* display = ui::GetXDisplay();
  Pixmap blank = XCreateBitmapFromData(display, ui::GetX11RootWindow(),
                                       nodata, 8, 8);
  invisible_cursor_ = XCreatePixmapCursor(display, blank, blank,
                                          &black, &black, 0, 0);
  arrow_cursor_ = XCreateFontCursor(display, XC_arrow);

  SetCursorVisible(false, false);
  UpdateDeviceList(display);

  // TODO(sad): Here, we only setup so that the X windows created by GTK+ are
  // setup for XInput2 events. We need a way to listen for XInput2 events for X
  // windows created by other means (e.g. for context menus).
  SetupGtkWidgetRealizeNotifier(this);

  // Make sure the list of devices is kept up-to-date by listening for
  // XI_HierarchyChanged event on the root window.
  unsigned char mask[XIMaskLen(XI_LASTEVENT)];
  memset(mask, 0, sizeof(mask));

  XISetMask(mask, XI_HierarchyChanged);

  XIEventMask evmask;
  evmask.deviceid = XIAllDevices;
  evmask.mask_len = sizeof(mask);
  evmask.mask = mask;
  XISelectEvents(display, ui::GetX11RootWindow(), &evmask, 1);
}

TouchFactory::~TouchFactory() {
  SetCursorVisible(true, false);
  Display* display = ui::GetXDisplay();
  XFreeCursor(display, invisible_cursor_);
  XFreeCursor(display, arrow_cursor_);

  RemoveGtkWidgetRealizeNotifier();
}

void TouchFactory::UpdateDeviceList(Display* display) {
  // Detect touch devices.
  // NOTE: The new API for retrieving the list of devices (XIQueryDevice) does
  // not provide enough information to detect a touch device. As a result, the
  // old version of query function (XListInputDevices) is used instead.
  // If XInput2 is not supported, this will return null (with count of -1) so
  // we assume there cannot be any touch devices.
  int count = 0;
  touch_device_lookup_.reset();
  touch_device_list_.clear();
  XDeviceInfo* devlist = XListInputDevices(display, &count);
  for (int i = 0; i < count; i++) {
    const char* devtype = XGetAtomName(display, devlist[i].type);
    if (devtype && !strcmp(devtype, XI_TOUCHSCREEN)) {
      touch_device_lookup_[devlist[i].id] = true;
      touch_device_list_.push_back(devlist[i].id);
    }
  }
  if (devlist)
    XFreeDeviceList(devlist);

  // Instead of asking X for the list of devices all the time, let's maintain a
  // list of pointer devices we care about.
  // It is not necessary to select for slave devices. XInput2 provides enough
  // information to the event callback to decide which slave device triggered
  // the event, thus decide whether the 'pointer event' is a 'mouse event' or a
  // 'touch event'.
  // If the touch device has 'GrabDevice' set and 'SendCoreEvents' unset (which
  // is possible), then the device is detected as a floating device, and a
  // floating device is not connected to a master device. So it is necessary to
  // also select on the floating devices.
  pointer_device_lookup_.reset();
  XIDeviceInfo* devices = XIQueryDevice(display, XIAllDevices, &count);
  for (int i = 0; i < count; i++) {
    XIDeviceInfo* devinfo = devices + i;
    if (devinfo->use == XIFloatingSlave || devinfo->use == XIMasterPointer) {
      pointer_device_lookup_[devinfo->deviceid] = true;
    }
  }
  XIFreeDeviceInfo(devices);

  SetupValuator();
}

bool TouchFactory::ShouldProcessXI2Event(XEvent* xev) {
  DCHECK_EQ(GenericEvent, xev->type);

  XGenericEventCookie* cookie = &xev->xcookie;
  if (cookie->evtype != XI_ButtonPress &&
      cookie->evtype != XI_ButtonRelease &&
      cookie->evtype != XI_Motion)
    return true;

  XIDeviceEvent* xiev = static_cast<XIDeviceEvent*>(cookie->data);
  return pointer_device_lookup_[xiev->sourceid];
}

void TouchFactory::SetupXI2ForXWindow(Window window) {
  // Setup mask for mouse events. It is possible that a device is loaded/plugged
  // in after we have setup XInput2 on a window. In such cases, we need to
  // either resetup XInput2 for the window, so that we get events from the new
  // device, or we need to listen to events from all devices, and then filter
  // the events from uninteresting devices. We do the latter because that's
  // simpler.

  Display* display = ui::GetXDisplay();

  unsigned char mask[XIMaskLen(XI_LASTEVENT)];
  memset(mask, 0, sizeof(mask));

  XISetMask(mask, XI_ButtonPress);
  XISetMask(mask, XI_ButtonRelease);
  XISetMask(mask, XI_Motion);

  XIEventMask evmask;
  evmask.deviceid = XIAllDevices;
  evmask.mask_len = sizeof(mask);
  evmask.mask = mask;
  XISelectEvents(display, window, &evmask, 1);
  XFlush(display);
}

void TouchFactory::SetTouchDeviceList(
    const std::vector<unsigned int>& devices) {
  touch_device_lookup_.reset();
  touch_device_list_.clear();
  for (std::vector<unsigned int>::const_iterator iter = devices.begin();
       iter != devices.end(); ++iter) {
    DCHECK(*iter < touch_device_lookup_.size());
    touch_device_lookup_[*iter] = true;
    touch_device_list_.push_back(*iter);
  }

  SetupValuator();
}

bool TouchFactory::IsTouchDevice(unsigned deviceid) const {
  return deviceid < touch_device_lookup_.size() ?
      touch_device_lookup_[deviceid] : false;
}

bool TouchFactory::GrabTouchDevices(Display* display, ::Window window) {
  if (touch_device_list_.empty())
    return true;

  unsigned char mask[XIMaskLen(XI_LASTEVENT)];
  bool success = true;

  memset(mask, 0, sizeof(mask));
  XISetMask(mask, XI_ButtonPress);
  XISetMask(mask, XI_ButtonRelease);
  XISetMask(mask, XI_Motion);

  XIEventMask evmask;
  evmask.mask_len = sizeof(mask);
  evmask.mask = mask;
  for (std::vector<int>::const_iterator iter =
       touch_device_list_.begin();
       iter != touch_device_list_.end(); ++iter) {
    evmask.deviceid = *iter;
    Status status = XIGrabDevice(display, *iter, window, CurrentTime, None,
                                 GrabModeAsync, GrabModeAsync, False, &evmask);
    success = success && status == GrabSuccess;
  }

  return success;
}

bool TouchFactory::UngrabTouchDevices(Display* display) {
  bool success = true;
  for (std::vector<int>::const_iterator iter =
       touch_device_list_.begin();
       iter != touch_device_list_.end(); ++iter) {
    Status status = XIUngrabDevice(display, *iter, CurrentTime);
    success = success && status == GrabSuccess;
  }
  return success;
}

void TouchFactory::SetCursorVisible(bool show, bool start_timer) {
  // The cursor is going to be shown. Reset the timer for hiding it.
  if (show && start_timer) {
    cursor_timer_.Stop();
    cursor_timer_.Start(base::TimeDelta::FromSeconds(kCursorIdleSeconds),
        this, &TouchFactory::HideCursorForInactivity);
  } else {
    cursor_timer_.Stop();
  }

  if (show == is_cursor_visible_)
    return;

  is_cursor_visible_ = show;

  Display* display = ui::GetXDisplay();
  Window window = DefaultRootWindow(display);

  if (is_cursor_visible_) {
    XDefineCursor(display, window, arrow_cursor_);
  } else {
    XDefineCursor(display, window, invisible_cursor_);
  }
}

void TouchFactory::SetupValuator() {
  memset(valuator_lookup_, -1, sizeof(valuator_lookup_));

  Display* display = ui::GetXDisplay();
  int ndevice;
  XIDeviceInfo* info_list = XIQueryDevice(display, XIAllDevices, &ndevice);

  for (int i = 0; i < ndevice; i++) {
    XIDeviceInfo* info = info_list + i;

    if (!IsTouchDevice(info->deviceid))
      continue;

    for (int i = 0; i < TP_LAST_ENTRY; i++) {
      TouchParam tp = static_cast<TouchParam>(i);
      valuator_lookup_[info->deviceid][i] = FindTPValuator(display, info, tp);
    }
  }

  if (info_list)
    XIFreeDeviceInfo(info_list);
}

bool TouchFactory::ExtractTouchParam(const XEvent& xev,
                                     TouchParam tp,
                                     float* value) {
  XIDeviceEvent* xiev = static_cast<XIDeviceEvent*>(xev.xcookie.data);
  if (xiev->sourceid >= kMaxDeviceNum)
    return false;
  int v = valuator_lookup_[xiev->sourceid][tp];
  if (v >= 0 && XIMaskIsSet(xiev->valuators.mask, v)) {
    *value = xiev->valuators.values[v];
    return true;
  }

  return false;
}

}  // namespace views
<commit_msg>Select on slave pointers instead of master pointers.<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 "views/touchui/touch_factory.h"

#include <gtk/gtk.h>
#include <gdk/gdkx.h>
#include <X11/cursorfont.h>
#include <X11/extensions/XInput.h>
#include <X11/extensions/XInput2.h>
#include <X11/extensions/XIproto.h>

#include "base/basictypes.h"
#include "base/compiler_specific.h"
#include "base/logging.h"
#include "ui/base/x/x11_util.h"

namespace {

// The X cursor is hidden if it is idle for kCursorIdleSeconds seconds.
int kCursorIdleSeconds = 5;

// Given the TouchParam, return the correspoding valuator index using
// the X device information through Atom name matching.
char FindTPValuator(Display* display,
                    XIDeviceInfo* info,
                    views::TouchFactory::TouchParam touch_param) {
  // Lookup table for mapping TouchParam to Atom string used in X.
  // A full set of Atom strings can be found at xserver-properties.h.
  static struct {
    views::TouchFactory::TouchParam tp;
    const char* atom;
  } kTouchParamAtom[] = {
    { views::TouchFactory::TP_TOUCH_MAJOR, "Abs MT Touch Major" },
    { views::TouchFactory::TP_TOUCH_MINOR, "Abs MT Touch Minor" },
    { views::TouchFactory::TP_ORIENTATION, "Abs MT Orientation" },
    { views::TouchFactory::TP_LAST_ENTRY, NULL },
  };

  const char* atom_tp = NULL;

  for (size_t i = 0; i < ARRAYSIZE_UNSAFE(kTouchParamAtom); i++) {
    if (touch_param == kTouchParamAtom[i].tp) {
      atom_tp = kTouchParamAtom[i].atom;
      break;
    }
  }

  if (!atom_tp)
    return -1;

  for (int i = 0; i < info->num_classes; i++) {
    if (info->classes[i]->type != XIValuatorClass)
      continue;
    XIValuatorClassInfo* v =
        reinterpret_cast<XIValuatorClassInfo*>(info->classes[i]);

    const char* atom = XGetAtomName(display, v->label);

    if (atom && strcmp(atom, atom_tp) == 0)
      return v->number;
  }

  return -1;
}

// Setup XInput2 select for the GtkWidget.
gboolean GtkWidgetRealizeCallback(GSignalInvocationHint* hint, guint nparams,
                                  const GValue* pvalues, gpointer data) {
  GtkWidget* widget = GTK_WIDGET(g_value_get_object(pvalues));
  GdkWindow* window = widget->window;
  views::TouchFactory* factory = static_cast<views::TouchFactory*>(data);

  if (GDK_WINDOW_TYPE(window) != GDK_WINDOW_TOPLEVEL &&
      GDK_WINDOW_TYPE(window) != GDK_WINDOW_CHILD &&
      GDK_WINDOW_TYPE(window) != GDK_WINDOW_DIALOG)
    return true;

  factory->SetupXI2ForXWindow(GDK_WINDOW_XID(window));
  return true;
}

// We need to capture all the GDK windows that get created, and start
// listening for XInput2 events. So we setup a callback to the 'realize'
// signal for GTK+ widgets, so that whenever the signal triggers for any
// GtkWidget, which means the GtkWidget should now have a GdkWindow, we can
// setup XInput2 events for the GdkWindow.
guint realize_signal_id = 0;
guint realize_hook_id = 0;

void SetupGtkWidgetRealizeNotifier(views::TouchFactory* factory) {
  gpointer klass = g_type_class_ref(GTK_TYPE_WIDGET);

  g_signal_parse_name("realize", GTK_TYPE_WIDGET,
                      &realize_signal_id, NULL, FALSE);
  realize_hook_id = g_signal_add_emission_hook(realize_signal_id, 0,
      GtkWidgetRealizeCallback, static_cast<gpointer>(factory), NULL);

  g_type_class_unref(klass);
}

void RemoveGtkWidgetRealizeNotifier() {
  if (realize_signal_id != 0)
    g_signal_remove_emission_hook(realize_signal_id, realize_hook_id);
  realize_signal_id = 0;
  realize_hook_id = 0;
}

}  // namespace

namespace views {

// static
TouchFactory* TouchFactory::GetInstance() {
  return Singleton<TouchFactory>::get();
}

TouchFactory::TouchFactory()
    : is_cursor_visible_(true),
      cursor_timer_(),
      pointer_device_lookup_(),
      touch_device_list_() {
  char nodata[] = { 0, 0, 0, 0, 0, 0, 0, 0 };
  XColor black;
  black.red = black.green = black.blue = 0;
  Display* display = ui::GetXDisplay();
  Pixmap blank = XCreateBitmapFromData(display, ui::GetX11RootWindow(),
                                       nodata, 8, 8);
  invisible_cursor_ = XCreatePixmapCursor(display, blank, blank,
                                          &black, &black, 0, 0);
  arrow_cursor_ = XCreateFontCursor(display, XC_arrow);

  SetCursorVisible(false, false);
  UpdateDeviceList(display);

  // TODO(sad): Here, we only setup so that the X windows created by GTK+ are
  // setup for XInput2 events. We need a way to listen for XInput2 events for X
  // windows created by other means (e.g. for context menus).
  SetupGtkWidgetRealizeNotifier(this);

  // Make sure the list of devices is kept up-to-date by listening for
  // XI_HierarchyChanged event on the root window.
  unsigned char mask[XIMaskLen(XI_LASTEVENT)];
  memset(mask, 0, sizeof(mask));

  XISetMask(mask, XI_HierarchyChanged);

  XIEventMask evmask;
  evmask.deviceid = XIAllDevices;
  evmask.mask_len = sizeof(mask);
  evmask.mask = mask;
  XISelectEvents(display, ui::GetX11RootWindow(), &evmask, 1);
}

TouchFactory::~TouchFactory() {
  SetCursorVisible(true, false);
  Display* display = ui::GetXDisplay();
  XFreeCursor(display, invisible_cursor_);
  XFreeCursor(display, arrow_cursor_);

  RemoveGtkWidgetRealizeNotifier();
}

void TouchFactory::UpdateDeviceList(Display* display) {
  // Detect touch devices.
  // NOTE: The new API for retrieving the list of devices (XIQueryDevice) does
  // not provide enough information to detect a touch device. As a result, the
  // old version of query function (XListInputDevices) is used instead.
  // If XInput2 is not supported, this will return null (with count of -1) so
  // we assume there cannot be any touch devices.
  int count = 0;
  touch_device_lookup_.reset();
  touch_device_list_.clear();
  XDeviceInfo* devlist = XListInputDevices(display, &count);
  for (int i = 0; i < count; i++) {
    const char* devtype = XGetAtomName(display, devlist[i].type);
    if (devtype && !strcmp(devtype, XI_TOUCHSCREEN)) {
      touch_device_lookup_[devlist[i].id] = true;
      touch_device_list_.push_back(devlist[i].id);
    }
  }
  if (devlist)
    XFreeDeviceList(devlist);

  // Instead of asking X for the list of devices all the time, let's maintain a
  // list of pointer devices we care about.
  // It should not be necessary to select for slave devices. XInput2 provides
  // enough information to the event callback to decide which slave device
  // triggered the event, thus decide whether the 'pointer event' is a
  // 'mouse event' or a 'touch event'.
  // However, on some desktops, some events from a master pointer are
  // not delivered to the client. So we select for slave devices instead.
  // If the touch device has 'GrabDevice' set and 'SendCoreEvents' unset (which
  // is possible), then the device is detected as a floating device, and a
  // floating device is not connected to a master device. So it is necessary to
  // also select on the floating devices.
  pointer_device_lookup_.reset();
  XIDeviceInfo* devices = XIQueryDevice(display, XIAllDevices, &count);
  for (int i = 0; i < count; i++) {
    XIDeviceInfo* devinfo = devices + i;
    if (devinfo->use == XIFloatingSlave || devinfo->use == XISlavePointer) {
      pointer_device_lookup_[devinfo->deviceid] = true;
    }
  }
  XIFreeDeviceInfo(devices);

  SetupValuator();
}

bool TouchFactory::ShouldProcessXI2Event(XEvent* xev) {
  DCHECK_EQ(GenericEvent, xev->type);

  XGenericEventCookie* cookie = &xev->xcookie;
  if (cookie->evtype != XI_ButtonPress &&
      cookie->evtype != XI_ButtonRelease &&
      cookie->evtype != XI_Motion)
    return true;

  XIDeviceEvent* xiev = static_cast<XIDeviceEvent*>(cookie->data);
  return pointer_device_lookup_[xiev->sourceid];
}

void TouchFactory::SetupXI2ForXWindow(Window window) {
  // Setup mask for mouse events. It is possible that a device is loaded/plugged
  // in after we have setup XInput2 on a window. In such cases, we need to
  // either resetup XInput2 for the window, so that we get events from the new
  // device, or we need to listen to events from all devices, and then filter
  // the events from uninteresting devices. We do the latter because that's
  // simpler.

  Display* display = ui::GetXDisplay();

  unsigned char mask[XIMaskLen(XI_LASTEVENT)];
  memset(mask, 0, sizeof(mask));

  XISetMask(mask, XI_ButtonPress);
  XISetMask(mask, XI_ButtonRelease);
  XISetMask(mask, XI_Motion);

  XIEventMask evmask;
  evmask.deviceid = XIAllDevices;
  evmask.mask_len = sizeof(mask);
  evmask.mask = mask;
  XISelectEvents(display, window, &evmask, 1);
  XFlush(display);
}

void TouchFactory::SetTouchDeviceList(
    const std::vector<unsigned int>& devices) {
  touch_device_lookup_.reset();
  touch_device_list_.clear();
  for (std::vector<unsigned int>::const_iterator iter = devices.begin();
       iter != devices.end(); ++iter) {
    DCHECK(*iter < touch_device_lookup_.size());
    touch_device_lookup_[*iter] = true;
    touch_device_list_.push_back(*iter);
  }

  SetupValuator();
}

bool TouchFactory::IsTouchDevice(unsigned deviceid) const {
  return deviceid < touch_device_lookup_.size() ?
      touch_device_lookup_[deviceid] : false;
}

bool TouchFactory::GrabTouchDevices(Display* display, ::Window window) {
  if (touch_device_list_.empty())
    return true;

  unsigned char mask[XIMaskLen(XI_LASTEVENT)];
  bool success = true;

  memset(mask, 0, sizeof(mask));
  XISetMask(mask, XI_ButtonPress);
  XISetMask(mask, XI_ButtonRelease);
  XISetMask(mask, XI_Motion);

  XIEventMask evmask;
  evmask.mask_len = sizeof(mask);
  evmask.mask = mask;
  for (std::vector<int>::const_iterator iter =
       touch_device_list_.begin();
       iter != touch_device_list_.end(); ++iter) {
    evmask.deviceid = *iter;
    Status status = XIGrabDevice(display, *iter, window, CurrentTime, None,
                                 GrabModeAsync, GrabModeAsync, False, &evmask);
    success = success && status == GrabSuccess;
  }

  return success;
}

bool TouchFactory::UngrabTouchDevices(Display* display) {
  bool success = true;
  for (std::vector<int>::const_iterator iter =
       touch_device_list_.begin();
       iter != touch_device_list_.end(); ++iter) {
    Status status = XIUngrabDevice(display, *iter, CurrentTime);
    success = success && status == GrabSuccess;
  }
  return success;
}

void TouchFactory::SetCursorVisible(bool show, bool start_timer) {
  // The cursor is going to be shown. Reset the timer for hiding it.
  if (show && start_timer) {
    cursor_timer_.Stop();
    cursor_timer_.Start(base::TimeDelta::FromSeconds(kCursorIdleSeconds),
        this, &TouchFactory::HideCursorForInactivity);
  } else {
    cursor_timer_.Stop();
  }

  if (show == is_cursor_visible_)
    return;

  is_cursor_visible_ = show;

  Display* display = ui::GetXDisplay();
  Window window = DefaultRootWindow(display);

  if (is_cursor_visible_) {
    XDefineCursor(display, window, arrow_cursor_);
  } else {
    XDefineCursor(display, window, invisible_cursor_);
  }
}

void TouchFactory::SetupValuator() {
  memset(valuator_lookup_, -1, sizeof(valuator_lookup_));

  Display* display = ui::GetXDisplay();
  int ndevice;
  XIDeviceInfo* info_list = XIQueryDevice(display, XIAllDevices, &ndevice);

  for (int i = 0; i < ndevice; i++) {
    XIDeviceInfo* info = info_list + i;

    if (!IsTouchDevice(info->deviceid))
      continue;

    for (int i = 0; i < TP_LAST_ENTRY; i++) {
      TouchParam tp = static_cast<TouchParam>(i);
      valuator_lookup_[info->deviceid][i] = FindTPValuator(display, info, tp);
    }
  }

  if (info_list)
    XIFreeDeviceInfo(info_list);
}

bool TouchFactory::ExtractTouchParam(const XEvent& xev,
                                     TouchParam tp,
                                     float* value) {
  XIDeviceEvent* xiev = static_cast<XIDeviceEvent*>(xev.xcookie.data);
  if (xiev->sourceid >= kMaxDeviceNum)
    return false;
  int v = valuator_lookup_[xiev->sourceid][tp];
  if (v >= 0 && XIMaskIsSet(xiev->valuators.mask, v)) {
    *value = xiev->valuators.values[v];
    return true;
  }

  return false;
}

}  // namespace views
<|endoftext|>