<commit_before>/*
  This file is part of KDE Kontact.

  Copyright (c) 2004 Tobias Koenig <tokoe@kde.org>
  Copyright (c) 2008 Allen Winter <winter@kde.org>

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

  This program is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  GNU General Public License for more details.

  You should have received a copy of the GNU General Public License along
  with this program; if not, write to the Free Software Foundation, Inc.,
  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.

  As a special exception, permission is given to link this program
  with any edition of Qt, and distribute the resulting executable,
  without including the source code for Qt in the source distribution.
*/

#include "kcmkontactsummary.h"
#include "plugin.h"

#include <kaboutdata.h>
#include <kconfig.h>
#include <kdebug.h>
#include <kdialog.h>
#include <kiconloader.h>
#include <klocale.h>
#include <kdemacros.h>
#include <kplugininfo.h>
#include <kservicetypetrader.h>
#include <kcomponentdata.h>

#include <QLabel>
#include <QVBoxLayout>
#include <QTreeWidgetItem>

extern "C"
{
  KDE_EXPORT KCModule *create_kontactsummary( QWidget *parent, const char * ) {
    KComponentData inst( "kcmkontactsummary" );
    return new KCMKontactSummary( inst, parent );
  }
}

class PluginItem : public QTreeWidgetItem
{
  public:
    PluginItem( const KPluginInfo &info, QTreeWidget *parent )
      : QTreeWidgetItem( parent ), mInfo( info )
    {
      setIcon( 0, KIcon( mInfo.icon() ) );
      setText( 0, mInfo.name() );
      setToolTip( 0, mInfo.comment() );
      setFlags( Qt::ItemIsEnabled | Qt::ItemIsUserCheckable );
    }

    KPluginInfo pluginInfo() const
    {
      return mInfo;
    }

    virtual QString text( int column ) const
    {
      if ( column == 0 ) {
        return mInfo.name();
      } else if ( column == 1 ) {
        return mInfo.comment();
      } else {
        return QString();
      }
    }

  private:
    KPluginInfo mInfo;
};

PluginView::PluginView( QWidget *parent )
  : QTreeWidget( parent )
{
  setColumnCount( 1 );
  setHeaderLabel( i18nc( "@title:column plugin name", "Summary Plugin Name" ) );
}

PluginView::~PluginView()
{
}

KCMKontactSummary::KCMKontactSummary( const KComponentData &inst, QWidget *parent )
  : KCModule( inst, parent )
{
  setButtons( NoAdditionalButton );
  QVBoxLayout *layout = new QVBoxLayout( this );
  layout->setSpacing( KDialog::spacingHint() );
  layout->setMargin( 0 );

  QLabel *label =
    new QLabel( i18n( "Select the plugin summaries to show on the summary page." ), this );
  layout->addWidget( label );

  mPluginView = new PluginView( this );
  layout->addWidget( mPluginView );

  layout->setStretchFactor( mPluginView, 1 );

  load();

  KAboutData *about = new KAboutData( I18N_NOOP( "kontactsummary" ), 0,
                                      ki18n( "KDE Kontact Summary" ),
                                      0, KLocalizedString(), KAboutData::License_GPL,
                                      ki18n( "(c), 2004 Tobias Koenig" ) );

  about->addAuthor( ki18n( "Tobias Koenig" ), KLocalizedString(), "tokoe@kde.org" );
  setAboutData( about );
}

void KCMKontactSummary::load()
{
  KService::List offers = KServiceTypeTrader::self()->query(
      QString::fromLatin1( "Kontact/Plugin" ),
      QString( "[X-KDE-KontactPluginVersion] == %1" ).arg( KONTACT_PLUGIN_VERSION ) );

  QStringList activeSummaries;

  KConfig config( "kontact_summaryrc" );
  KConfigGroup grp( &config, QString() );
  if ( !grp.hasKey( "ActiveSummaries" ) ) {
    activeSummaries << "kontact_kaddressbookplugin";
    activeSummaries << "kontact_specialdatesplugin";
    activeSummaries << "kontact_korganizerplugin";
    activeSummaries << "kontact_todoplugin";
    activeSummaries << "kontact_knotesplugin";
    activeSummaries << "kontact_kmailplugin";
    activeSummaries << "kontact_weatherplugin";
    activeSummaries << "kontact_newstickerplugin";
    activeSummaries << "kontact_plannerplugin";
  } else {
    activeSummaries = grp.readEntry( "ActiveSummaries", QStringList() );
  }

  mPluginView->clear();

  KPluginInfo::List pluginList =
    KPluginInfo::fromServices( offers, KConfigGroup( &config, "Plugins" ) );
  KPluginInfo::List::Iterator it;
  for ( it = pluginList.begin(); it != pluginList.end(); ++it ) {
    it->load();

    if ( !it->isPluginEnabled() ) {
      continue;
    }

    QVariant var = it->property( "X-KDE-KontactPluginHasSummary" );
    if ( var.isValid() && var.toBool() == true ) {
      PluginItem *item = new PluginItem( *it, mPluginView );

      if ( activeSummaries.contains( it->pluginName() ) ) {
        item->setCheckState( 0, Qt::Checked );
      } else {
        item->setCheckState( 0, Qt::Unchecked );
      }
    }
  }
}

void KCMKontactSummary::save()
{
  kDebug();
  QStringList activeSummaries;

  QTreeWidgetItemIterator it( mPluginView );
  while ( *it ) {
    PluginItem *item = static_cast<PluginItem *>( *it );
    if ( item->checkState( 0 ) == Qt::Checked ) {
      activeSummaries.append( item->pluginInfo().pluginName() );
    }
    ++it;
  }

  KConfig config( "kontact_summaryrc" );
  KConfigGroup grp( &config, QString() );
  kDebug() << "saving activesummaries " << activeSummaries;
  grp.writeEntry( "ActiveSummaries", activeSummaries );
}

#include "kcmkontactsummary.moc"
<commit_msg>build against kdelibs 4.0<commit_after>/*
  This file is part of KDE Kontact.

  Copyright (c) 2004 Tobias Koenig <tokoe@kde.org>
  Copyright (c) 2008 Allen Winter <winter@kde.org>

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

  This program is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  GNU General Public License for more details.

  You should have received a copy of the GNU General Public License along
  with this program; if not, write to the Free Software Foundation, Inc.,
  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.

  As a special exception, permission is given to link this program
  with any edition of Qt, and distribute the resulting executable,
  without including the source code for Qt in the source distribution.
*/

#include "kcmkontactsummary.h"
#include "plugin.h"

#include <kaboutdata.h>
#include <kconfig.h>
#include <kdebug.h>
#include <kdialog.h>
#include <kiconloader.h>
#include <klocale.h>
#include <kdemacros.h>
#include <kdeversion.h>
#include <kplugininfo.h>
#include <kservicetypetrader.h>
#include <kcomponentdata.h>

#include <QLabel>
#include <QVBoxLayout>
#include <QTreeWidgetItem>

extern "C"
{
  KDE_EXPORT KCModule *create_kontactsummary( QWidget *parent, const char * ) {
    KComponentData inst( "kcmkontactsummary" );
    return new KCMKontactSummary( inst, parent );
  }
}

class PluginItem : public QTreeWidgetItem
{
  public:
    PluginItem( const KPluginInfo &info, QTreeWidget *parent )
      : QTreeWidgetItem( parent ), mInfo( info )
    {
      setIcon( 0, KIcon( mInfo.icon() ) );
      setText( 0, mInfo.name() );
      setToolTip( 0, mInfo.comment() );
      setFlags( Qt::ItemIsEnabled | Qt::ItemIsUserCheckable );
    }

    KPluginInfo pluginInfo() const
    {
      return mInfo;
    }

    virtual QString text( int column ) const
    {
      if ( column == 0 ) {
        return mInfo.name();
      } else if ( column == 1 ) {
        return mInfo.comment();
      } else {
        return QString();
      }
    }

  private:
    KPluginInfo mInfo;
};

PluginView::PluginView( QWidget *parent )
  : QTreeWidget( parent )
{
  setColumnCount( 1 );
  setHeaderLabel( i18nc( "@title:column plugin name", "Summary Plugin Name" ) );
}

PluginView::~PluginView()
{
}

KCMKontactSummary::KCMKontactSummary( const KComponentData &inst, QWidget *parent )
  : KCModule( inst, parent )
{
#if KDE_IS_VERSION(4,0,71 )
  setButtons( NoAdditionalButton );
#endif
  QVBoxLayout *layout = new QVBoxLayout( this );
  layout->setSpacing( KDialog::spacingHint() );
  layout->setMargin( 0 );

  QLabel *label =
    new QLabel( i18n( "Select the plugin summaries to show on the summary page." ), this );
  layout->addWidget( label );

  mPluginView = new PluginView( this );
  layout->addWidget( mPluginView );

  layout->setStretchFactor( mPluginView, 1 );

  load();

  KAboutData *about = new KAboutData( I18N_NOOP( "kontactsummary" ), 0,
                                      ki18n( "KDE Kontact Summary" ),
                                      0, KLocalizedString(), KAboutData::License_GPL,
                                      ki18n( "(c), 2004 Tobias Koenig" ) );

  about->addAuthor( ki18n( "Tobias Koenig" ), KLocalizedString(), "tokoe@kde.org" );
  setAboutData( about );
}

void KCMKontactSummary::load()
{
  KService::List offers = KServiceTypeTrader::self()->query(
      QString::fromLatin1( "Kontact/Plugin" ),
      QString( "[X-KDE-KontactPluginVersion] == %1" ).arg( KONTACT_PLUGIN_VERSION ) );

  QStringList activeSummaries;

  KConfig config( "kontact_summaryrc" );
  KConfigGroup grp( &config, QString() );
  if ( !grp.hasKey( "ActiveSummaries" ) ) {
    activeSummaries << "kontact_kaddressbookplugin";
    activeSummaries << "kontact_specialdatesplugin";
    activeSummaries << "kontact_korganizerplugin";
    activeSummaries << "kontact_todoplugin";
    activeSummaries << "kontact_knotesplugin";
    activeSummaries << "kontact_kmailplugin";
    activeSummaries << "kontact_weatherplugin";
    activeSummaries << "kontact_newstickerplugin";
    activeSummaries << "kontact_plannerplugin";
  } else {
    activeSummaries = grp.readEntry( "ActiveSummaries", QStringList() );
  }

  mPluginView->clear();

  KPluginInfo::List pluginList =
    KPluginInfo::fromServices( offers, KConfigGroup( &config, "Plugins" ) );
  KPluginInfo::List::Iterator it;
  for ( it = pluginList.begin(); it != pluginList.end(); ++it ) {
    it->load();

    if ( !it->isPluginEnabled() ) {
      continue;
    }

    QVariant var = it->property( "X-KDE-KontactPluginHasSummary" );
    if ( var.isValid() && var.toBool() == true ) {
      PluginItem *item = new PluginItem( *it, mPluginView );

      if ( activeSummaries.contains( it->pluginName() ) ) {
        item->setCheckState( 0, Qt::Checked );
      } else {
        item->setCheckState( 0, Qt::Unchecked );
      }
    }
  }
}

void KCMKontactSummary::save()
{
  kDebug();
  QStringList activeSummaries;

  QTreeWidgetItemIterator it( mPluginView );
  while ( *it ) {
    PluginItem *item = static_cast<PluginItem *>( *it );
    if ( item->checkState( 0 ) == Qt::Checked ) {
      activeSummaries.append( item->pluginInfo().pluginName() );
    }
    ++it;
  }

  KConfig config( "kontact_summaryrc" );
  KConfigGroup grp( &config, QString() );
  kDebug() << "saving activesummaries " << activeSummaries;
  grp.writeEntry( "ActiveSummaries", activeSummaries );
}

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


<commit_before>#include "../../interface/PhaseISplitClusterAnalyzer.h"

PhaseISplitClusterAnalyzer::PhaseISplitClusterAnalyzer(const edm::ParameterSet& t_iConfig):
	m_iConfig(t_iConfig),
	m_outputFilePath(t_iConfig.getUntrackedParameter<std::string>("outputFileName", DEFAULT_OUTPUT_FILE_PATH))
{
	m_clustersToken = consumes<edmNew::DetSetVector<SiPixelCluster>>(edm::InputTag("siPixelClusters"));
}

PhaseISplitClusterAnalyzer::~PhaseISplitClusterAnalyzer()
{
	savePerEventDistributions();
	saveCummulativeDistributions();
	m_outputFile -> Close();
}

void PhaseISplitClusterAnalyzer::beginJob()
{
	m_outputFile = new TFile(m_outputFilePath.c_str(), "RECREATE");
	generateHistogramCollections();
}

void PhaseISplitClusterAnalyzer::endJob()
{
	// Don't put anything here that you want to run even if an exception is thrown
}

void PhaseISplitClusterAnalyzer::analyze(const edm::Event& t_iEvent, const edm::EventSetup& t_iSetup)
{
	m_iEvent = &t_iEvent;
	// Set the event identifiers
	updateTimestamp();
	m_siPixelCoordinates.init(t_iSetup);
	// Get the cluster collection in the event
	m_iEvent -> getByToken(m_clustersToken, m_clusterCollectionHandle);

	edm::ESHandle<TrackerGeometry> trackerGeometryHandle;
	t_iSetup.get<TrackerDigiGeometryRecord>().get(trackerGeometryHandle);
	m_trackerGeometry = trackerGeometryHandle.product();

	edm::ESHandle<PixelClusterParameterEstimator> pixelClusterParameterEstimatorHandle;
	t_iSetup.get<TkPixelCPERecord>().get("PixelCPEGeneric", pixelClusterParameterEstimatorHandle);
	m_pixelClusterParameterEstimator = pixelClusterParameterEstimatorHandle.product();
	// Module cluster plots
	handleModuleClusterPlots();
	// Generate statistics
	handleEventStatisticsForDistributions();
}

void PhaseISplitClusterAnalyzer::beginRun(edm::Run const&, edm::EventSetup const&)
{

}

void PhaseISplitClusterAnalyzer::endRun(edm::Run const&, edm::EventSetup const&)
{

}

void PhaseISplitClusterAnalyzer::beginLuminosityBlock(edm::LuminosityBlock const&, edm::EventSetup const&)
{

}

void PhaseISplitClusterAnalyzer::endLuminosityBlock(edm::LuminosityBlock const&, edm::EventSetup const&)
{

}

void PhaseISplitClusterAnalyzer::updateRunNumber()
{
	int newRunNumber = m_iEvent -> id().run();
	if(m_runNumber == newRunNumber)
	{
		m_isNewRun = false;
		return;
	}
	m_runNumber = newRunNumber;
	m_isNewRun = true;
}

void PhaseISplitClusterAnalyzer::updateLuminosityBlockNumber()
{
	int newLuminosityBlock = m_iEvent -> luminosityBlock();
	if(m_luminosityBlock == newLuminosityBlock)
	{
		m_isNewLuminosityBlock = false;
		return;
	}
	m_luminosityBlock = newLuminosityBlock;
	m_isNewLuminosityBlock = true;
}

void PhaseISplitClusterAnalyzer::updateTimestamp()
{
	updateRunNumber();
	updateLuminosityBlockNumber();
	m_eventNumber = m_iEvent -> id().event();
}

void PhaseISplitClusterAnalyzer::getModuleData(ModuleData& t_mod, const DetId& t_detId)
{
	t_mod.init();
	t_mod.det  = t_detId.subdetId() - 1;
	t_mod.shl  = m_siPixelCoordinates.quadrant(t_detId);
	t_mod.side = m_siPixelCoordinates.side(t_detId);
	if(t_detId.subdetId() == PixelSubdetector::PixelBarrel)
	{
		t_mod.sec     = m_siPixelCoordinates.sector(t_detId);
		t_mod.half    = m_siPixelCoordinates.half(t_detId);
		t_mod.layer   = m_siPixelCoordinates.layer(t_detId);
		t_mod.flipped = m_siPixelCoordinates.flipped(t_detId); // opposite of outer
		t_mod.ladder = m_siPixelCoordinates.signed_ladder(t_detId);
		t_mod.module = m_siPixelCoordinates.signed_module(t_detId);
	}
	else if(t_detId.subdetId() == PixelSubdetector::PixelEndcap)
	{
		t_mod.ring   = m_siPixelCoordinates.ring(t_detId);
		t_mod.panel  = m_siPixelCoordinates.panel(t_detId);
		t_mod.module = m_siPixelCoordinates.module(t_detId);
		t_mod.disk  = m_siPixelCoordinates.signed_disk(t_detId);
		t_mod.blade = m_siPixelCoordinates.signed_blade(t_detId);
	}
	t_mod.rawid = t_detId.rawId();
	t_mod.fedid = m_siPixelCoordinates.fedid(t_detId);
}
<commit_msg>Move save from destructor to endJob<commit_after>#include "../../interface/PhaseISplitClusterAnalyzer.h"

PhaseISplitClusterAnalyzer::PhaseISplitClusterAnalyzer(const edm::ParameterSet& t_iConfig):
	m_iConfig(t_iConfig),
	m_outputFilePath(t_iConfig.getUntrackedParameter<std::string>("outputFileName", DEFAULT_OUTPUT_FILE_PATH))
{
	m_clustersToken = consumes<edmNew::DetSetVector<SiPixelCluster>>(edm::InputTag("siPixelClusters"));
}

PhaseISplitClusterAnalyzer::~PhaseISplitClusterAnalyzer() {}

void PhaseISplitClusterAnalyzer::beginJob()
{
	m_outputFile = new TFile(m_outputFilePath.c_str(), "RECREATE");
	generateHistogramCollections();
}

void PhaseISplitClusterAnalyzer::endJob()
{
	// Don't put anything here that you want to run even if an exception is thrown
	savePerEventDistributions();
	saveCummulativeDistributions();
	m_outputFile -> Close();
}

void PhaseISplitClusterAnalyzer::analyze(const edm::Event& t_iEvent, const edm::EventSetup& t_iSetup)
{
	m_iEvent = &t_iEvent;
	// Set the event identifiers
	updateTimestamp();
	m_siPixelCoordinates.init(t_iSetup);
	// Get the cluster collection in the event
	m_iEvent -> getByToken(m_clustersToken, m_clusterCollectionHandle);

	edm::ESHandle<TrackerGeometry> trackerGeometryHandle;
	t_iSetup.get<TrackerDigiGeometryRecord>().get(trackerGeometryHandle);
	m_trackerGeometry = trackerGeometryHandle.product();

	edm::ESHandle<PixelClusterParameterEstimator> pixelClusterParameterEstimatorHandle;
	t_iSetup.get<TkPixelCPERecord>().get("PixelCPEGeneric", pixelClusterParameterEstimatorHandle);
	m_pixelClusterParameterEstimator = pixelClusterParameterEstimatorHandle.product();
	// Module cluster plots
	handleModuleClusterPlots();
	// Generate statistics
	handleEventStatisticsForDistributions();
}

void PhaseISplitClusterAnalyzer::beginRun(edm::Run const&, edm::EventSetup const&)
{

}

void PhaseISplitClusterAnalyzer::endRun(edm::Run const&, edm::EventSetup const&)
{

}

void PhaseISplitClusterAnalyzer::beginLuminosityBlock(edm::LuminosityBlock const&, edm::EventSetup const&)
{

}

void PhaseISplitClusterAnalyzer::endLuminosityBlock(edm::LuminosityBlock const&, edm::EventSetup const&)
{

}

void PhaseISplitClusterAnalyzer::updateRunNumber()
{
	int newRunNumber = m_iEvent -> id().run();
	if(m_runNumber == newRunNumber)
	{
		m_isNewRun = false;
		return;
	}
	m_runNumber = newRunNumber;
	m_isNewRun = true;
}

void PhaseISplitClusterAnalyzer::updateLuminosityBlockNumber()
{
	int newLuminosityBlock = m_iEvent -> luminosityBlock();
	if(m_luminosityBlock == newLuminosityBlock)
	{
		m_isNewLuminosityBlock = false;
		return;
	}
	m_luminosityBlock = newLuminosityBlock;
	m_isNewLuminosityBlock = true;
}

void PhaseISplitClusterAnalyzer::updateTimestamp()
{
	updateRunNumber();
	updateLuminosityBlockNumber();
	m_eventNumber = m_iEvent -> id().event();
}

void PhaseISplitClusterAnalyzer::getModuleData(ModuleData& t_mod, const DetId& t_detId)
{
	t_mod.init();
	t_mod.det  = t_detId.subdetId() - 1;
	t_mod.shl  = m_siPixelCoordinates.quadrant(t_detId);
	t_mod.side = m_siPixelCoordinates.side(t_detId);
	if(t_detId.subdetId() == PixelSubdetector::PixelBarrel)
	{
		t_mod.sec     = m_siPixelCoordinates.sector(t_detId);
		t_mod.half    = m_siPixelCoordinates.half(t_detId);
		t_mod.layer   = m_siPixelCoordinates.layer(t_detId);
		t_mod.flipped = m_siPixelCoordinates.flipped(t_detId); // opposite of outer
		t_mod.ladder = m_siPixelCoordinates.signed_ladder(t_detId);
		t_mod.module = m_siPixelCoordinates.signed_module(t_detId);
	}
	else if(t_detId.subdetId() == PixelSubdetector::PixelEndcap)
	{
		t_mod.ring   = m_siPixelCoordinates.ring(t_detId);
		t_mod.panel  = m_siPixelCoordinates.panel(t_detId);
		t_mod.module = m_siPixelCoordinates.module(t_detId);
		t_mod.disk  = m_siPixelCoordinates.signed_disk(t_detId);
		t_mod.blade = m_siPixelCoordinates.signed_blade(t_detId);
	}
	t_mod.rawid = t_detId.rawId();
	t_mod.fedid = m_siPixelCoordinates.fedid(t_detId);
}
<|endoftext|>


<commit_before>/******************************************************************************
 *                       ____    _    _____                                   *
 *                      / ___|  / \  |  ___|    C++                           *
 *                     | |     / _ \ | |_       Actor                         *
 *                     | |___ / ___ \|  _|      Framework                     *
 *                      \____/_/   \_|_|                                      *
 *                                                                            *
 * Copyright 2011-2019 Dominik Charousset                                     *
 *                                                                            *
 * Distributed under the terms and conditions of the BSD 3-Clause License or  *
 * (at your option) under the terms and conditions of the Boost Software      *
 * License 1.0. See accompanying files LICENSE and LICENSE_ALTERNATIVE.       *
 *                                                                            *
 * If you did not receive a copy of the license files, see                    *
 * http://opensource.org/licenses/BSD-3-Clause and                            *
 * http://www.boost.org/LICENSE_1_0.txt.                                      *
 ******************************************************************************/

#include "caf/net/tcp_stream_socket.hpp"

#include "caf/detail/net_syscall.hpp"
#include "caf/detail/sockaddr_members.hpp"
#include "caf/detail/socket_sys_includes.hpp"
#include "caf/expected.hpp"
#include "caf/ipv4_address.hpp"
#include "caf/logger.hpp"
#include "caf/net/ip.hpp"
#include "caf/net/socket_guard.hpp"
#include "caf/sec.hpp"
#include "caf/variant.hpp"

namespace caf::net {

namespace {

template <int Family>
bool ip_connect(stream_socket fd, std::string host, uint16_t port) {
  CAF_LOG_TRACE("Family =" << (Family == AF_INET ? "AF_INET" : "AF_INET6")
                           << CAF_ARG(fd.id) << CAF_ARG(host) << CAF_ARG(port));
  static_assert(Family == AF_INET || Family == AF_INET6, "invalid family");
  using sockaddr_type = typename std::conditional<
    Family == AF_INET, sockaddr_in, sockaddr_in6>::type;
  sockaddr_type sa;
  memset(&sa, 0, sizeof(sockaddr_type));
  inet_pton(Family, host.c_str(), &detail::addr_of(sa));
  detail::family_of(sa) = Family;
  detail::port_of(sa) = htons(port);
  using sa_ptr = const sockaddr*;
  return ::connect(fd.id, reinterpret_cast<sa_ptr>(&sa), sizeof(sa)) == 0;
}

} // namespace

expected<tcp_stream_socket> make_connected_tcp_stream_socket(ip_endpoint node) {
  CAF_LOG_DEBUG("tcp connect to: " << to_string(node));
  auto proto = node.address().embeds_v4() ? AF_INET : AF_INET6;
  int socktype = SOCK_STREAM;
#ifdef SOCK_CLOEXEC
  socktype |= SOCK_CLOEXEC;
#endif
  CAF_NET_SYSCALL("socket", fd, ==, -1, ::socket(proto, socktype, 0));
  tcp_stream_socket sock{fd};
  child_process_inherit(sock, false);
  auto sguard = make_socket_guard(sock);
  if (proto == AF_INET6) {
    if (ip_connect<AF_INET6>(sock, to_string(node.address()), node.port())) {
      CAF_LOG_INFO("successfully connected to (IPv6):" << to_string(node));
      return sguard.release();
    }
  } else if (ip_connect<AF_INET>(sock, to_string(node.address().embedded_v4()),
                                 node.port())) {
    CAF_LOG_INFO("successfully connected to (IPv4):" << to_string(node));
    return sguard.release();
  }
  CAF_LOG_WARNING("could not connect to: " << to_string(node));
  return make_error(sec::cannot_connect_to_node);
}

expected<tcp_stream_socket>
make_connected_tcp_stream_socket(const uri::authority_type& node) {
  auto port = node.port;
  if (port == 0)
    return make_error(sec::cannot_connect_to_node, "port is zero");
  std::vector<ip_address> addrs;
  if (auto str = get_if<std::string>(&node.host))
    addrs = ip::local_addresses(*str);
  else if (auto addr = get_if<ip_address>(&node.host))
    addrs.push_back(*addr);
  if (addrs.empty())
    return make_error(sec::cannot_connect_to_node, "empty authority");
  for (auto& addr : addrs) {
    if (auto sock = make_connected_tcp_stream_socket(ip_endpoint{addr, port}))
      return *sock;
  }
  return make_error(sec::cannot_connect_to_node, to_string(node));
}

} // namespace caf::net
<commit_msg>Fix bug in tcp_stream_socket<commit_after>/******************************************************************************
 *                       ____    _    _____                                   *
 *                      / ___|  / \  |  ___|    C++                           *
 *                     | |     / _ \ | |_       Actor                         *
 *                     | |___ / ___ \|  _|      Framework                     *
 *                      \____/_/   \_|_|                                      *
 *                                                                            *
 * Copyright 2011-2019 Dominik Charousset                                     *
 *                                                                            *
 * Distributed under the terms and conditions of the BSD 3-Clause License or  *
 * (at your option) under the terms and conditions of the Boost Software      *
 * License 1.0. See accompanying files LICENSE and LICENSE_ALTERNATIVE.       *
 *                                                                            *
 * If you did not receive a copy of the license files, see                    *
 * http://opensource.org/licenses/BSD-3-Clause and                            *
 * http://www.boost.org/LICENSE_1_0.txt.                                      *
 ******************************************************************************/

#include "caf/net/tcp_stream_socket.hpp"

#include "caf/detail/net_syscall.hpp"
#include "caf/detail/sockaddr_members.hpp"
#include "caf/detail/socket_sys_includes.hpp"
#include "caf/expected.hpp"
#include "caf/ipv4_address.hpp"
#include "caf/logger.hpp"
#include "caf/net/ip.hpp"
#include "caf/net/socket_guard.hpp"
#include "caf/sec.hpp"
#include "caf/variant.hpp"

namespace caf::net {

namespace {

template <int Family>
bool ip_connect(stream_socket fd, std::string host, uint16_t port) {
  CAF_LOG_TRACE("Family =" << (Family == AF_INET ? "AF_INET" : "AF_INET6")
                           << CAF_ARG(fd.id) << CAF_ARG(host) << CAF_ARG(port));
  static_assert(Family == AF_INET || Family == AF_INET6, "invalid family");
  using sockaddr_type = typename std::conditional<
    Family == AF_INET, sockaddr_in, sockaddr_in6>::type;
  sockaddr_type sa;
  memset(&sa, 0, sizeof(sockaddr_type));
  inet_pton(Family, host.c_str(), &detail::addr_of(sa));
  detail::family_of(sa) = Family;
  detail::port_of(sa) = htons(port);
  using sa_ptr = const sockaddr*;
  return ::connect(fd.id, reinterpret_cast<sa_ptr>(&sa), sizeof(sa)) == 0;
}

} // namespace

expected<tcp_stream_socket> make_connected_tcp_stream_socket(ip_endpoint node) {
  CAF_LOG_DEBUG("tcp connect to: " << to_string(node));
  auto proto = node.address().embeds_v4() ? AF_INET : AF_INET6;
  int socktype = SOCK_STREAM;
#ifdef SOCK_CLOEXEC
  socktype |= SOCK_CLOEXEC;
#endif
  CAF_NET_SYSCALL("socket", fd, ==, -1, ::socket(proto, socktype, 0));
  tcp_stream_socket sock{fd};
  child_process_inherit(sock, false);
  auto sguard = make_socket_guard(sock);
  if (proto == AF_INET6) {
    if (ip_connect<AF_INET6>(sock, to_string(node.address()), node.port())) {
      CAF_LOG_INFO("successfully connected to (IPv6):" << to_string(node));
      return sguard.release();
    }
  } else if (ip_connect<AF_INET>(sock, to_string(node.address().embedded_v4()),
                                 node.port())) {
    CAF_LOG_INFO("successfully connected to (IPv4):" << to_string(node));
    return sguard.release();
  }
  CAF_LOG_WARNING("could not connect to: " << to_string(node));
  return make_error(sec::cannot_connect_to_node);
}

expected<tcp_stream_socket>
make_connected_tcp_stream_socket(const uri::authority_type& node) {
  auto port = node.port;
  if (port == 0)
    return make_error(sec::cannot_connect_to_node, "port is zero");
  std::vector<ip_address> addrs;
  if (auto str = get_if<std::string>(&node.host))
    addrs = ip::resolve(*str);
  else if (auto addr = get_if<ip_address>(&node.host))
    addrs.push_back(*addr);
  if (addrs.empty())
    return make_error(sec::cannot_connect_to_node, "empty authority");
  for (auto& addr : addrs) {
    if (auto sock = make_connected_tcp_stream_socket(ip_endpoint{addr, port}))
      return *sock;
  }
  return make_error(sec::cannot_connect_to_node, to_string(node));
}

} // namespace caf::net
<|endoftext|>


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

#include <precomp.h>
#include <toolkit/hf_funcdecl.hxx>

// NOT FULLY DEFINED SERVICES

const String C_sValignTop("top");
const String C_sValignBottom("bottom");

HF_FunctionDeclaration::HF_FunctionDeclaration( Xml::Element & o_rParent,
                                                const String & i_sRaisesText )
    :   HtmlMaker(o_rParent),
        sRaisesText(i_sRaisesText),
        pTable(0),
        pReturnCell(0),
        pNameCell(0),
        pParameterLine(0),
        pLastParameterCell(0),
        pExceptionCell(0)
{
    pTable = new Html::Table;
    CurOut()
        >> *pTable
            << new Html::ClassAttr("table-in-method")
            << new Xml::AnAttribute("border","0");
}

HF_FunctionDeclaration::~HF_FunctionDeclaration()
{
}

Xml::Element &
HF_FunctionDeclaration::ReturnCell()
{
    if (pReturnCell != 0)
        return *pReturnCell;

    pReturnCell = &( *pTable
                        >> *new Html::TableRow
                            >> *new Html::TableCell
                                << new Html::VAlignAttr(C_sValignTop)
                                << new Xml::AnAttribute("colspan", "3")
                    );
    return *pReturnCell;
}

Xml::Element &
HF_FunctionDeclaration::NameCell()
{
    if (pNameCell != 0)
        return *pNameCell;

    pNameCell = &( ParameterLine()
                    >> *new Html::TableCell
                        << new Html::VAlignAttr(C_sValignTop)
                 );
    pLastParameterCell = pNameCell;

    return *pNameCell;
}

Xml::Element &
HF_FunctionDeclaration::NewParamTypeCell()
{
    if (pLastParameterCell != pNameCell)
    {
        pParameterLine = 0;
        ParameterLine()
            >> *new Html::TableCell;
    }

    Xml::Element &
        rParamType = ParameterLine()
                        >> *new Html::TableCell
                            << new Html::VAlignAttr(C_sValignTop);
    pLastParameterCell
                   = &( ParameterLine()
                            >> *new Html::TableCell
                                << new Html::VAlignAttr(C_sValignBottom)
                                << new Xml::XmlCode(" ")
                      );
    return rParamType;
}

Xml::Element &
HF_FunctionDeclaration::ParamNameCell()
{
    csv_assert(pLastParameterCell != pNameCell);
    return *pLastParameterCell;
}

Xml::Element &
HF_FunctionDeclaration::ExceptionCell()
{
    if (pExceptionCell != 0)
        return *pExceptionCell;

    Xml::Element &
        rExceptionRow = *pTable
                            >> *new Html::TableRow;
    rExceptionRow
        >> *new Html::TableCell
            << new Html::VAlignAttr(C_sValignTop)
            << new Xml::AnAttribute("align", "right")
            << sRaisesText
            << "( ";

    pExceptionCell = &( rExceptionRow
                            >> *new Html::TableCell
                                << new Html::VAlignAttr(C_sValignTop)
                                << new Xml::AnAttribute("colspan", "2")
                      );
    return *pExceptionCell;
}

Html::TableRow &
HF_FunctionDeclaration::ParameterLine()
{
    if (pParameterLine != 0)
        return *pParameterLine;

    pParameterLine = new Html::TableRow;
    *pTable
        >> *pParameterLine;

    return *pParameterLine;
}

#if 0   // old
HF_FunctionDeclaration::HF_FunctionDeclaration( Xml::Element & o_rParent )
    :   HtmlMaker(o_rParent),
        pFront(0),
        pTypes(0),
        pNames(0)
{
    Xml::Element &
        rRow = CurOut()
                >> *new Html::Table
                    << new Xml::AnAttribute("border","0")
                    >> *new Html::TableRow;
    pFront = &(rRow >> *new Html::TableCell << new Html::VAlignAttr(C_sValignTop));
    pTypes = &(rRow >> *new Html::TableCell << new Html::VAlignAttr(C_sValignTop));
    pNames = &(rRow >> *new Html::TableCell << new Html::VAlignAttr(C_sValignTop));
}

HF_FunctionDeclaration::~HF_FunctionDeclaration()
{
}

Xml::Element &
HF_FunctionDeclaration::Add_ReturnLine()
{
    (*pTypes) << new Xml::XmlCode("
\n");
    (*pNames) << new Xml::XmlCode("
\n");
    return *pFront;
}

Xml::Element &
HF_FunctionDeclaration::Add_RaisesLine( const char * i_sRaisesText,
                                        bool         i_bSuppressExtraLine )
{
    if (NOT i_bSuppressExtraLine)
    {
        (*pTypes) << new Xml::XmlCode("
");
        (*pNames) << new Xml::XmlCode("
\n");
    }
    (*pTypes)
        << new Xml::XmlCode("
")
        << i_sRaisesText
        << new Xml::XmlCode("(
\n");
    return *pNames;
}
#endif // 0    old
<commit_msg>INTEGRATION: CWS changefileheader (1.7.26); FILE MERGED 2008/03/28 16:02:13 rt 1.7.26.1: #i87441# Change license header to LPGL v3.<commit_after>/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2008 by Sun Microsystems, Inc.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * $RCSfile: hf_funcdecl.cxx,v $
 * $Revision: 1.8 $
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/

#include <precomp.h>
#include <toolkit/hf_funcdecl.hxx>

// NOT FULLY DEFINED SERVICES

const String C_sValignTop("top");
const String C_sValignBottom("bottom");

HF_FunctionDeclaration::HF_FunctionDeclaration( Xml::Element & o_rParent,
                                                const String & i_sRaisesText )
    :   HtmlMaker(o_rParent),
        sRaisesText(i_sRaisesText),
        pTable(0),
        pReturnCell(0),
        pNameCell(0),
        pParameterLine(0),
        pLastParameterCell(0),
        pExceptionCell(0)
{
    pTable = new Html::Table;
    CurOut()
        >> *pTable
            << new Html::ClassAttr("table-in-method")
            << new Xml::AnAttribute("border","0");
}

HF_FunctionDeclaration::~HF_FunctionDeclaration()
{
}

Xml::Element &
HF_FunctionDeclaration::ReturnCell()
{
    if (pReturnCell != 0)
        return *pReturnCell;

    pReturnCell = &( *pTable
                        >> *new Html::TableRow
                            >> *new Html::TableCell
                                << new Html::VAlignAttr(C_sValignTop)
                                << new Xml::AnAttribute("colspan", "3")
                    );
    return *pReturnCell;
}

Xml::Element &
HF_FunctionDeclaration::NameCell()
{
    if (pNameCell != 0)
        return *pNameCell;

    pNameCell = &( ParameterLine()
                    >> *new Html::TableCell
                        << new Html::VAlignAttr(C_sValignTop)
                 );
    pLastParameterCell = pNameCell;

    return *pNameCell;
}

Xml::Element &
HF_FunctionDeclaration::NewParamTypeCell()
{
    if (pLastParameterCell != pNameCell)
    {
        pParameterLine = 0;
        ParameterLine()
            >> *new Html::TableCell;
    }

    Xml::Element &
        rParamType = ParameterLine()
                        >> *new Html::TableCell
                            << new Html::VAlignAttr(C_sValignTop);
    pLastParameterCell
                   = &( ParameterLine()
                            >> *new Html::TableCell
                                << new Html::VAlignAttr(C_sValignBottom)
                                << new Xml::XmlCode(" ")
                      );
    return rParamType;
}

Xml::Element &
HF_FunctionDeclaration::ParamNameCell()
{
    csv_assert(pLastParameterCell != pNameCell);
    return *pLastParameterCell;
}

Xml::Element &
HF_FunctionDeclaration::ExceptionCell()
{
    if (pExceptionCell != 0)
        return *pExceptionCell;

    Xml::Element &
        rExceptionRow = *pTable
                            >> *new Html::TableRow;
    rExceptionRow
        >> *new Html::TableCell
            << new Html::VAlignAttr(C_sValignTop)
            << new Xml::AnAttribute("align", "right")
            << sRaisesText
            << "( ";

    pExceptionCell = &( rExceptionRow
                            >> *new Html::TableCell
                                << new Html::VAlignAttr(C_sValignTop)
                                << new Xml::AnAttribute("colspan", "2")
                      );
    return *pExceptionCell;
}

Html::TableRow &
HF_FunctionDeclaration::ParameterLine()
{
    if (pParameterLine != 0)
        return *pParameterLine;

    pParameterLine = new Html::TableRow;
    *pTable
        >> *pParameterLine;

    return *pParameterLine;
}

#if 0   // old
HF_FunctionDeclaration::HF_FunctionDeclaration( Xml::Element & o_rParent )
    :   HtmlMaker(o_rParent),
        pFront(0),
        pTypes(0),
        pNames(0)
{
    Xml::Element &
        rRow = CurOut()
                >> *new Html::Table
                    << new Xml::AnAttribute("border","0")
                    >> *new Html::TableRow;
    pFront = &(rRow >> *new Html::TableCell << new Html::VAlignAttr(C_sValignTop));
    pTypes = &(rRow >> *new Html::TableCell << new Html::VAlignAttr(C_sValignTop));
    pNames = &(rRow >> *new Html::TableCell << new Html::VAlignAttr(C_sValignTop));
}

HF_FunctionDeclaration::~HF_FunctionDeclaration()
{
}

Xml::Element &
HF_FunctionDeclaration::Add_ReturnLine()
{
    (*pTypes) << new Xml::XmlCode("
\n");
    (*pNames) << new Xml::XmlCode("
\n");
    return *pFront;
}

Xml::Element &
HF_FunctionDeclaration::Add_RaisesLine( const char * i_sRaisesText,
                                        bool         i_bSuppressExtraLine )
{
    if (NOT i_bSuppressExtraLine)
    {
        (*pTypes) << new Xml::XmlCode("
");
        (*pNames) << new Xml::XmlCode("
\n");
    }
    (*pTypes)
        << new Xml::XmlCode("
")
        << i_sRaisesText
        << new Xml::XmlCode("(
\n");
    return *pNames;
}
#endif // 0    old
<|endoftext|>


<commit_before>#include "TextBox.h"
#include "Game.h"

namespace gameplay
{

bool space(char c) {
    return isspace(c);
}

TextBox::TextBox() : _lastKeypress(0), _fontSize(0), _caretImage(NULL), _passwordChar('*'), _inputMode(TEXT), _ctrlPressed(false)
{
}

TextBox::~TextBox()
{
}

TextBox* TextBox::create(const char* id, Theme::Style* style)
{
    GP_ASSERT(style);

    TextBox* textBox = new TextBox();
    if (id)
        textBox->_id = id;
    textBox->setStyle(style);

    return textBox;
}

TextBox* TextBox::create(Theme::Style* style, Properties* properties)
{
    TextBox* textBox = new TextBox();
    textBox->initialize(style, properties);

    return textBox;
}

void TextBox::initialize(Theme::Style* style, Properties* properties)
{
    GP_ASSERT(properties);

    Label::initialize(style, properties);
    _inputMode = getInputMode(properties->getString("inputMode"));
}

int TextBox::getLastKeypress()
{
    return _lastKeypress;
}

void TextBox::addListener(Control::Listener* listener, int eventFlags)
{
    if ((eventFlags & Control::Listener::VALUE_CHANGED) == Control::Listener::VALUE_CHANGED)
    {
        GP_ERROR("VALUE_CHANGED event is not applicable to TextBox.");
    }

    Control::addListener(listener, eventFlags);
}

bool TextBox::touchEvent(Touch::TouchEvent evt, int x, int y, unsigned int contactIndex)
{
    switch (evt)
    {
    case Touch::TOUCH_PRESS:
        if (x > _clipBounds.x && x <= _clipBounds.x + _clipBounds.width &&
                 y > _clipBounds.y && y <= _clipBounds.y + _clipBounds.height)
        {
            _contactIndex = (int) contactIndex;

            if (_state == NORMAL)
                Game::getInstance()->displayKeyboard(true);

            setCaretLocation(x, y);

            _state = ACTIVE;
            _dirty = true;
        }
        else
        {
            _contactIndex = INVALID_CONTACT_INDEX;
            _state = NORMAL;
            Game::getInstance()->displayKeyboard(false);
            _dirty = true;
            return false;
        }
        break;
    case Touch::TOUCH_MOVE:
        if (_state == ACTIVE &&
            x > _clipBounds.x && x <= _clipBounds.x + _clipBounds.width &&
            y > _clipBounds.y && y <= _clipBounds.y + _clipBounds.height)
        {
            setCaretLocation(x, y);
            _dirty = true;
        }
        break;
    case Touch::TOUCH_RELEASE:
        if (x > _clipBounds.x && x <= _clipBounds.x + _clipBounds.width &&
            y > _clipBounds.y && y <= _clipBounds.y + _clipBounds.height)
        {
            setCaretLocation(x, y);
            _state = FOCUS;
        }
        else
        {
            _state = NORMAL;
            Game::getInstance()->displayKeyboard(false);
        }
        _contactIndex = INVALID_CONTACT_INDEX;
        _dirty = true;
        break;
    }

    return _consumeInputEvents;
}

bool TextBox::keyEvent(Keyboard::KeyEvent evt, int key)
{
    switch (evt)
    {
        case Keyboard::KEY_PRESS:
        {
            switch (key)
            {
                case Keyboard::KEY_CTRL:
                {
                    _ctrlPressed = true;
                    break;
                }
                case Keyboard::KEY_HOME:
                {
                    // TODO: Move cursor to beginning of line.
                    // This only works for left alignment...

                    //_caretLocation.x = _viewportClipBounds.x;
                    //_dirty = true;
                    break;
                }
                case Keyboard::KEY_END:
                {
                    // TODO: Move cursor to end of line.
                    break;
                }
                case Keyboard::KEY_DELETE:
                {
                    Font* font = getFont(_state);
                    GP_ASSERT(font);
                    unsigned int fontSize = getFontSize(_state);
                    Font::Justify textAlignment = getTextAlignment(_state);
                    bool rightToLeft = getTextRightToLeft(_state);

                    int textIndex = font->getIndexAtLocation(getDisplayedText().c_str(), _textBounds, fontSize, _caretLocation, &_caretLocation,
                        textAlignment, true, rightToLeft);

                    _text.erase(textIndex, 1);
                    font->getLocationAtIndex(getDisplayedText().c_str(), _textBounds, fontSize, &_caretLocation, textIndex,
                        textAlignment, true, rightToLeft);
                    _dirty = true;
                    notifyListeners(Control::Listener::TEXT_CHANGED);
                    break;
                }
                case Keyboard::KEY_TAB:
                {
                    // Allow tab to move the focus forward.
                    return false;
                    break;
                }
                case Keyboard::KEY_LEFT_ARROW:
                {
                    const std::string displayedText = getDisplayedText();
                    Font* font = getFont(_state);
                    GP_ASSERT(font);
                    unsigned int fontSize = getFontSize(_state);
                    Font::Justify textAlignment = getTextAlignment(_state);
                    bool rightToLeft = getTextRightToLeft(_state);

                    int textIndex = font->getIndexAtLocation(displayedText.c_str(), _textBounds, fontSize, _caretLocation, &_caretLocation,
                        textAlignment, true, rightToLeft);
                    if (_ctrlPressed)
                    {
                        std::string::const_reverse_iterator it = std::find_if(displayedText.rend() - (textIndex - 1), displayedText.rend(), space);
                        textIndex = std::distance(displayedText.begin(), it.base());
                    }
                    else
                    {
                        --textIndex;
                    }
                    font->getLocationAtIndex(displayedText.c_str(), _textBounds, fontSize, &_caretLocation, textIndex,
                        textAlignment, true, rightToLeft);
                    _dirty = true;
                    break;
                }
                case Keyboard::KEY_RIGHT_ARROW:
                {
                    const std::string displayedText = getDisplayedText();
                    Font* font = getFont(_state);
                    GP_ASSERT(font);
                    unsigned int fontSize = getFontSize(_state);
                    Font::Justify textAlignment = getTextAlignment(_state);
                    bool rightToLeft = getTextRightToLeft(_state);

                    int textIndex = font->getIndexAtLocation(displayedText.c_str(), _textBounds, fontSize, _caretLocation, &_caretLocation,
                        textAlignment, true, rightToLeft);
                    font->getLocationAtIndex(displayedText.c_str(), _textBounds, fontSize, &_caretLocation, textIndex + 1,
                        textAlignment, true, rightToLeft);
                    _dirty = true;
                    break;
                }
                case Keyboard::KEY_UP_ARROW:
                {
                    Font* font = getFont(_state);
                    GP_ASSERT(font);
                    unsigned int fontSize = getFontSize(_state);
                    Font::Justify textAlignment = getTextAlignment(_state);
                    bool rightToLeft = getTextRightToLeft(_state);
                    _prevCaretLocation.set(_caretLocation);
                    _caretLocation.y -= fontSize;
                    int textIndex = font->getIndexAtLocation(getDisplayedText().c_str(), _textBounds, fontSize, _caretLocation, &_caretLocation,
                        textAlignment, true, rightToLeft);
                    if (textIndex == -1)
                    {
                        _caretLocation.set(_prevCaretLocation);
                    }

                    _dirty = true;
                    break;
                }
                case Keyboard::KEY_DOWN_ARROW:
                {
                    Font* font = getFont(_state);
                    GP_ASSERT(font);
                    unsigned int fontSize = getFontSize(_state);
                    Font::Justify textAlignment = getTextAlignment(_state);
                    bool rightToLeft = getTextRightToLeft(_state);
                    _prevCaretLocation.set(_caretLocation);
                    _caretLocation.y += fontSize;
                    int textIndex = font->getIndexAtLocation(getDisplayedText().c_str(), _textBounds, fontSize, _caretLocation, &_caretLocation,
                        textAlignment, true, rightToLeft);
                    if (textIndex == -1)
                    {
                        _caretLocation.set(_prevCaretLocation);
                    }

                    _dirty = true;
                    break;
                }
            }
            break;
        }

        case Keyboard::KEY_CHAR:
        {
            Font* font = getFont(_state);
            GP_ASSERT(font);
            unsigned int fontSize = getFontSize(_state);
            Font::Justify textAlignment = getTextAlignment(_state);
            bool rightToLeft = getTextRightToLeft(_state);

            int textIndex = font->getIndexAtLocation(getDisplayedText().c_str(), _textBounds, fontSize, _caretLocation, &_caretLocation,
                textAlignment, true, rightToLeft);
            if (textIndex == -1)
            {
                textIndex = 0;
                font->getLocationAtIndex(getDisplayedText().c_str(), _textBounds, fontSize, &_caretLocation, 0,
                    textAlignment, true, rightToLeft);
            }

            switch (key)
            {
                case Keyboard::KEY_BACKSPACE:
                {
                    if (textIndex > 0)
                    {
                        --textIndex;
                        _text.erase(textIndex, 1);
                        font->getLocationAtIndex(getDisplayedText().c_str(), _textBounds, fontSize, &_caretLocation, textIndex,
                            textAlignment, true, rightToLeft);

                        _dirty = true;
                    }
                    break;
                }
                case Keyboard::KEY_RETURN:
                    // TODO: Handle line-break insertion correctly.
                    break;
                case Keyboard::KEY_ESCAPE:
                    break;
                case Keyboard::KEY_TAB:
                    // Allow tab to move the focus forward.
                    return false;
                    break;
                default:
                {
                    // Insert character into string.
                    _text.insert(textIndex, 1, (char)key);

                    // Get new location of caret.
                    font->getLocationAtIndex(getDisplayedText().c_str(), _textBounds, fontSize, &_caretLocation, textIndex + 1,
                        textAlignment, true, rightToLeft);

                    if (key == ' ')
                    {
                        // If a space was entered, check that caret is still within bounds.
                        if (_caretLocation.x >= _textBounds.x + _textBounds.width ||
                            _caretLocation.y >= _textBounds.y + _textBounds.height)
                        {
                            // If not, undo the character insertion.
                            _text.erase(textIndex, 1);
                            font->getLocationAtIndex(getDisplayedText().c_str(), _textBounds, fontSize, &_caretLocation, textIndex,
                                textAlignment, true, rightToLeft);

                            // No need to check again.
                            break;
                        }
                    }

                    // Always check that the text still fits within the clip region.
                    Rectangle textBounds;
                    font->measureText(getDisplayedText().c_str(), _textBounds, fontSize, &textBounds, textAlignment, true, true);
                    if (textBounds.x < _textBounds.x || textBounds.y < _textBounds.y ||
                        textBounds.width >= _textBounds.width || textBounds.height >= _textBounds.height)
                    {
                        // If not, undo the character insertion.
                        _text.erase(textIndex, 1);
                        font->getLocationAtIndex(getDisplayedText().c_str(), _textBounds, fontSize, &_caretLocation, textIndex,
                            textAlignment, true, rightToLeft);

                        // TextBox is not dirty.
                        break;
                    }

                    _dirty = true;
                    break;
                }

                break;
            }

            notifyListeners(Control::Listener::TEXT_CHANGED);
            break;
        }
        case Keyboard::KEY_RELEASE:
            switch (key)
            {
                case Keyboard::KEY_CTRL:
                {
                    _ctrlPressed = false;
                    break;
                }
            }
    }

    _lastKeypress = key;

    return _consumeInputEvents;
}

void TextBox::update(const Control* container, const Vector2& offset)
{
    Label::update(container, offset);

    _fontSize = getFontSize(_state);
    _caretImage = getImage("textCaret", _state);
}

void TextBox::drawImages(SpriteBatch* spriteBatch, const Rectangle& clip)
{
    if (_caretImage && (_state == ACTIVE || hasFocus()))
    {
        // Draw the cursor at its current location.
        const Rectangle& region = _caretImage->getRegion();
        if (!region.isEmpty())
        {
            GP_ASSERT(spriteBatch);
            const Theme::UVs uvs = _caretImage->getUVs();
            Vector4 color = _caretImage->getColor();
            color.w *= _opacity;

            spriteBatch->draw(_caretLocation.x - (region.width / 2.0f), _caretLocation.y, region.width, _fontSize, uvs.u1, uvs.v1, uvs.u2, uvs.v2, color, _viewportClipBounds);
        }
    }

    _dirty = false;
}

void TextBox::setCaretLocation(int x, int y)
{
    // Get index into string and cursor location from the latest touch location.
    _prevCaretLocation.set(_caretLocation);
    _caretLocation.set(x + _absoluteBounds.x,
                       y + _absoluteBounds.y);

    Font* font = getFont(_state);
    unsigned int fontSize = getFontSize(_state);
    Font::Justify textAlignment = getTextAlignment(_state);
    bool rightToLeft = getTextRightToLeft(_state);
    const std::string displayedText = getDisplayedText();

    int index = font->getIndexAtLocation(displayedText.c_str(), _textBounds, fontSize, _caretLocation, &_caretLocation,
            textAlignment, true, rightToLeft);

    if (index == -1)
    {
        // Attempt to find the nearest valid caret location.
        Rectangle textBounds;
        font->measureText(displayedText.c_str(), _textBounds, fontSize, &textBounds, textAlignment, true, true);

        if (_caretLocation.x > textBounds.x + textBounds.width &&
            _caretLocation.y > textBounds.y + textBounds.height)
        {
            font->getLocationAtIndex(displayedText.c_str(), _textBounds, fontSize, &_caretLocation, (unsigned int)_text.length(),
                textAlignment, true, rightToLeft);
            return;
        }

        if (_caretLocation.x < textBounds.x)
        {
            _caretLocation.x = textBounds.x;
        }
        else if (_caretLocation.x > textBounds.x + textBounds.width)
        {
            _caretLocation.x = textBounds.x + textBounds.width;
        }

        if (_caretLocation.y < textBounds.y)
        {
            _caretLocation.y = textBounds.y;
        }
        else if (_caretLocation.y > textBounds.y + textBounds.height)
        {
            Font* font = getFont(_state);
            GP_ASSERT(font);
            unsigned int fontSize = getFontSize(_state);
            _caretLocation.y = textBounds.y + textBounds.height - fontSize;
        }

        index = font->getIndexAtLocation(displayedText.c_str(), _textBounds, fontSize, _caretLocation, &_caretLocation,
            textAlignment, true, rightToLeft);

        if (index == -1)
        {
            // We failed to find a valid location; just put the caret back to where it was.
            _caretLocation.set(_prevCaretLocation);
        }
    }
}

const char* TextBox::getType() const
{
    return "textBox";
}

void TextBox::setPasswordChar(char character)
{
    _passwordChar = character;
}

char TextBox::getPasswordChar() const
{
    return _passwordChar;
}

void TextBox::setInputMode(InputMode inputMode)
{
    _inputMode = inputMode;
}

TextBox::InputMode TextBox::getInputMode() const
{
    return _inputMode;
}

void TextBox::drawText(const Rectangle& clip)
{
    if (_text.size() <= 0)
        return;

    // Draw the text.
    if (_font)
    {
        const std::string displayedText = getDisplayedText();
        _font->start();
        _font->drawText(displayedText.c_str(), _textBounds, _textColor, getFontSize(_state), getTextAlignment(_state), true, getTextRightToLeft(_state), &_viewportClipBounds);
        _font->finish();
    }
}

TextBox::InputMode TextBox::getInputMode(const char* inputMode)
{
    if (!inputMode)
    {
        return TextBox::TEXT;
    }

    if (strcmp(inputMode, "TEXT") == 0)
    {
        return TextBox::TEXT;
    }
    else if (strcmp(inputMode, "PASSWORD") == 0)
    {
        return TextBox::PASSWORD;
    }
    else
    {
        GP_ERROR("Failed to get corresponding textbox inputmode for unsupported value '%s'.", inputMode);
    }

    // Default.
    return TextBox::TEXT;
}

std::string TextBox::getDisplayedText() const
{
    std::string displayedText;
    switch (_inputMode) {
        case PASSWORD:
            displayedText.insert(0, _text.length(), _passwordChar);
            break;

        case TEXT:
        default:
            displayedText = _text;
            break;
    }

    return displayedText;
}

}
<commit_msg>Implement CTRL+right move (go to end of word)<commit_after>#include "TextBox.h"
#include "Game.h"

namespace gameplay
{

bool space(char c) {
    return isspace(c);
}

TextBox::TextBox() : _lastKeypress(0), _fontSize(0), _caretImage(NULL), _passwordChar('*'), _inputMode(TEXT), _ctrlPressed(false)
{
}

TextBox::~TextBox()
{
}

TextBox* TextBox::create(const char* id, Theme::Style* style)
{
    GP_ASSERT(style);

    TextBox* textBox = new TextBox();
    if (id)
        textBox->_id = id;
    textBox->setStyle(style);

    return textBox;
}

TextBox* TextBox::create(Theme::Style* style, Properties* properties)
{
    TextBox* textBox = new TextBox();
    textBox->initialize(style, properties);

    return textBox;
}

void TextBox::initialize(Theme::Style* style, Properties* properties)
{
    GP_ASSERT(properties);

    Label::initialize(style, properties);
    _inputMode = getInputMode(properties->getString("inputMode"));
}

int TextBox::getLastKeypress()
{
    return _lastKeypress;
}

void TextBox::addListener(Control::Listener* listener, int eventFlags)
{
    if ((eventFlags & Control::Listener::VALUE_CHANGED) == Control::Listener::VALUE_CHANGED)
    {
        GP_ERROR("VALUE_CHANGED event is not applicable to TextBox.");
    }

    Control::addListener(listener, eventFlags);
}

bool TextBox::touchEvent(Touch::TouchEvent evt, int x, int y, unsigned int contactIndex)
{
    switch (evt)
    {
    case Touch::TOUCH_PRESS:
        if (x > _clipBounds.x && x <= _clipBounds.x + _clipBounds.width &&
                 y > _clipBounds.y && y <= _clipBounds.y + _clipBounds.height)
        {
            _contactIndex = (int) contactIndex;

            if (_state == NORMAL)
                Game::getInstance()->displayKeyboard(true);

            setCaretLocation(x, y);

            _state = ACTIVE;
            _dirty = true;
        }
        else
        {
            _contactIndex = INVALID_CONTACT_INDEX;
            _state = NORMAL;
            Game::getInstance()->displayKeyboard(false);
            _dirty = true;
            return false;
        }
        break;
    case Touch::TOUCH_MOVE:
        if (_state == ACTIVE &&
            x > _clipBounds.x && x <= _clipBounds.x + _clipBounds.width &&
            y > _clipBounds.y && y <= _clipBounds.y + _clipBounds.height)
        {
            setCaretLocation(x, y);
            _dirty = true;
        }
        break;
    case Touch::TOUCH_RELEASE:
        if (x > _clipBounds.x && x <= _clipBounds.x + _clipBounds.width &&
            y > _clipBounds.y && y <= _clipBounds.y + _clipBounds.height)
        {
            setCaretLocation(x, y);
            _state = FOCUS;
        }
        else
        {
            _state = NORMAL;
            Game::getInstance()->displayKeyboard(false);
        }
        _contactIndex = INVALID_CONTACT_INDEX;
        _dirty = true;
        break;
    }

    return _consumeInputEvents;
}

bool TextBox::keyEvent(Keyboard::KeyEvent evt, int key)
{
    switch (evt)
    {
        case Keyboard::KEY_PRESS:
        {
            switch (key)
            {
                case Keyboard::KEY_CTRL:
                {
                    _ctrlPressed = true;
                    break;
                }
                case Keyboard::KEY_HOME:
                {
                    // TODO: Move cursor to beginning of line.
                    // This only works for left alignment...

                    //_caretLocation.x = _viewportClipBounds.x;
                    //_dirty = true;
                    break;
                }
                case Keyboard::KEY_END:
                {
                    // TODO: Move cursor to end of line.
                    break;
                }
                case Keyboard::KEY_DELETE:
                {
                    Font* font = getFont(_state);
                    GP_ASSERT(font);
                    unsigned int fontSize = getFontSize(_state);
                    Font::Justify textAlignment = getTextAlignment(_state);
                    bool rightToLeft = getTextRightToLeft(_state);

                    int textIndex = font->getIndexAtLocation(getDisplayedText().c_str(), _textBounds, fontSize, _caretLocation, &_caretLocation,
                        textAlignment, true, rightToLeft);

                    _text.erase(textIndex, 1);
                    font->getLocationAtIndex(getDisplayedText().c_str(), _textBounds, fontSize, &_caretLocation, textIndex,
                        textAlignment, true, rightToLeft);
                    _dirty = true;
                    notifyListeners(Control::Listener::TEXT_CHANGED);
                    break;
                }
                case Keyboard::KEY_TAB:
                {
                    // Allow tab to move the focus forward.
                    return false;
                    break;
                }
                case Keyboard::KEY_LEFT_ARROW:
                {
                    const std::string displayedText = getDisplayedText();
                    Font* font = getFont(_state);
                    GP_ASSERT(font);
                    unsigned int fontSize = getFontSize(_state);
                    Font::Justify textAlignment = getTextAlignment(_state);
                    bool rightToLeft = getTextRightToLeft(_state);

                    int textIndex = font->getIndexAtLocation(displayedText.c_str(), _textBounds, fontSize, _caretLocation, &_caretLocation,
                        textAlignment, true, rightToLeft);
                    if (_ctrlPressed)
                    {
                        std::string::const_reverse_iterator it = std::find_if(displayedText.rend() - (textIndex - 1), displayedText.rend(), space);
                        textIndex = std::distance(displayedText.begin(), it.base());
                    }
                    else
                    {
                        --textIndex;
                    }
                    font->getLocationAtIndex(displayedText.c_str(), _textBounds, fontSize, &_caretLocation, textIndex,
                        textAlignment, true, rightToLeft);
                    _dirty = true;
                    break;
                }
                case Keyboard::KEY_RIGHT_ARROW:
                {
                    const std::string displayedText = getDisplayedText();
                    Font* font = getFont(_state);
                    GP_ASSERT(font);
                    unsigned int fontSize = getFontSize(_state);
                    Font::Justify textAlignment = getTextAlignment(_state);
                    bool rightToLeft = getTextRightToLeft(_state);

                    int textIndex = font->getIndexAtLocation(displayedText.c_str(), _textBounds, fontSize, _caretLocation, &_caretLocation,
                        textAlignment, true, rightToLeft);
                    if (_ctrlPressed)
                    {
                        std::string::const_iterator it = std::find_if(displayedText.begin() + (textIndex + 1), displayedText.end(), space);
                        textIndex = std::distance(displayedText.begin(), it);
                    }
                    else
                    {
                        ++textIndex;
                    }
                    font->getLocationAtIndex(displayedText.c_str(), _textBounds, fontSize, &_caretLocation, textIndex,
                        textAlignment, true, rightToLeft);
                    _dirty = true;
                    break;
                }
                case Keyboard::KEY_UP_ARROW:
                {
                    Font* font = getFont(_state);
                    GP_ASSERT(font);
                    unsigned int fontSize = getFontSize(_state);
                    Font::Justify textAlignment = getTextAlignment(_state);
                    bool rightToLeft = getTextRightToLeft(_state);
                    _prevCaretLocation.set(_caretLocation);
                    _caretLocation.y -= fontSize;
                    int textIndex = font->getIndexAtLocation(getDisplayedText().c_str(), _textBounds, fontSize, _caretLocation, &_caretLocation,
                        textAlignment, true, rightToLeft);
                    if (textIndex == -1)
                    {
                        _caretLocation.set(_prevCaretLocation);
                    }

                    _dirty = true;
                    break;
                }
                case Keyboard::KEY_DOWN_ARROW:
                {
                    Font* font = getFont(_state);
                    GP_ASSERT(font);
                    unsigned int fontSize = getFontSize(_state);
                    Font::Justify textAlignment = getTextAlignment(_state);
                    bool rightToLeft = getTextRightToLeft(_state);
                    _prevCaretLocation.set(_caretLocation);
                    _caretLocation.y += fontSize;
                    int textIndex = font->getIndexAtLocation(getDisplayedText().c_str(), _textBounds, fontSize, _caretLocation, &_caretLocation,
                        textAlignment, true, rightToLeft);
                    if (textIndex == -1)
                    {
                        _caretLocation.set(_prevCaretLocation);
                    }

                    _dirty = true;
                    break;
                }
            }
            break;
        }

        case Keyboard::KEY_CHAR:
        {
            Font* font = getFont(_state);
            GP_ASSERT(font);
            unsigned int fontSize = getFontSize(_state);
            Font::Justify textAlignment = getTextAlignment(_state);
            bool rightToLeft = getTextRightToLeft(_state);

            int textIndex = font->getIndexAtLocation(getDisplayedText().c_str(), _textBounds, fontSize, _caretLocation, &_caretLocation,
                textAlignment, true, rightToLeft);
            if (textIndex == -1)
            {
                textIndex = 0;
                font->getLocationAtIndex(getDisplayedText().c_str(), _textBounds, fontSize, &_caretLocation, 0,
                    textAlignment, true, rightToLeft);
            }

            switch (key)
            {
                case Keyboard::KEY_BACKSPACE:
                {
                    if (textIndex > 0)
                    {
                        --textIndex;
                        _text.erase(textIndex, 1);
                        font->getLocationAtIndex(getDisplayedText().c_str(), _textBounds, fontSize, &_caretLocation, textIndex,
                            textAlignment, true, rightToLeft);

                        _dirty = true;
                    }
                    break;
                }
                case Keyboard::KEY_RETURN:
                    // TODO: Handle line-break insertion correctly.
                    break;
                case Keyboard::KEY_ESCAPE:
                    break;
                case Keyboard::KEY_TAB:
                    // Allow tab to move the focus forward.
                    return false;
                    break;
                default:
                {
                    // Insert character into string.
                    _text.insert(textIndex, 1, (char)key);

                    // Get new location of caret.
                    font->getLocationAtIndex(getDisplayedText().c_str(), _textBounds, fontSize, &_caretLocation, textIndex + 1,
                        textAlignment, true, rightToLeft);

                    if (key == ' ')
                    {
                        // If a space was entered, check that caret is still within bounds.
                        if (_caretLocation.x >= _textBounds.x + _textBounds.width ||
                            _caretLocation.y >= _textBounds.y + _textBounds.height)
                        {
                            // If not, undo the character insertion.
                            _text.erase(textIndex, 1);
                            font->getLocationAtIndex(getDisplayedText().c_str(), _textBounds, fontSize, &_caretLocation, textIndex,
                                textAlignment, true, rightToLeft);

                            // No need to check again.
                            break;
                        }
                    }

                    // Always check that the text still fits within the clip region.
                    Rectangle textBounds;
                    font->measureText(getDisplayedText().c_str(), _textBounds, fontSize, &textBounds, textAlignment, true, true);
                    if (textBounds.x < _textBounds.x || textBounds.y < _textBounds.y ||
                        textBounds.width >= _textBounds.width || textBounds.height >= _textBounds.height)
                    {
                        // If not, undo the character insertion.
                        _text.erase(textIndex, 1);
                        font->getLocationAtIndex(getDisplayedText().c_str(), _textBounds, fontSize, &_caretLocation, textIndex,
                            textAlignment, true, rightToLeft);

                        // TextBox is not dirty.
                        break;
                    }

                    _dirty = true;
                    break;
                }

                break;
            }

            notifyListeners(Control::Listener::TEXT_CHANGED);
            break;
        }
        case Keyboard::KEY_RELEASE:
            switch (key)
            {
                case Keyboard::KEY_CTRL:
                {
                    _ctrlPressed = false;
                    break;
                }
            }
    }

    _lastKeypress = key;

    return _consumeInputEvents;
}

void TextBox::update(const Control* container, const Vector2& offset)
{
    Label::update(container, offset);

    _fontSize = getFontSize(_state);
    _caretImage = getImage("textCaret", _state);
}

void TextBox::drawImages(SpriteBatch* spriteBatch, const Rectangle& clip)
{
    if (_caretImage && (_state == ACTIVE || hasFocus()))
    {
        // Draw the cursor at its current location.
        const Rectangle& region = _caretImage->getRegion();
        if (!region.isEmpty())
        {
            GP_ASSERT(spriteBatch);
            const Theme::UVs uvs = _caretImage->getUVs();
            Vector4 color = _caretImage->getColor();
            color.w *= _opacity;

            spriteBatch->draw(_caretLocation.x - (region.width / 2.0f), _caretLocation.y, region.width, _fontSize, uvs.u1, uvs.v1, uvs.u2, uvs.v2, color, _viewportClipBounds);
        }
    }

    _dirty = false;
}

void TextBox::setCaretLocation(int x, int y)
{
    // Get index into string and cursor location from the latest touch location.
    _prevCaretLocation.set(_caretLocation);
    _caretLocation.set(x + _absoluteBounds.x,
                       y + _absoluteBounds.y);

    Font* font = getFont(_state);
    unsigned int fontSize = getFontSize(_state);
    Font::Justify textAlignment = getTextAlignment(_state);
    bool rightToLeft = getTextRightToLeft(_state);
    const std::string displayedText = getDisplayedText();

    int index = font->getIndexAtLocation(displayedText.c_str(), _textBounds, fontSize, _caretLocation, &_caretLocation,
            textAlignment, true, rightToLeft);

    if (index == -1)
    {
        // Attempt to find the nearest valid caret location.
        Rectangle textBounds;
        font->measureText(displayedText.c_str(), _textBounds, fontSize, &textBounds, textAlignment, true, true);

        if (_caretLocation.x > textBounds.x + textBounds.width &&
            _caretLocation.y > textBounds.y + textBounds.height)
        {
            font->getLocationAtIndex(displayedText.c_str(), _textBounds, fontSize, &_caretLocation, (unsigned int)_text.length(),
                textAlignment, true, rightToLeft);
            return;
        }

        if (_caretLocation.x < textBounds.x)
        {
            _caretLocation.x = textBounds.x;
        }
        else if (_caretLocation.x > textBounds.x + textBounds.width)
        {
            _caretLocation.x = textBounds.x + textBounds.width;
        }

        if (_caretLocation.y < textBounds.y)
        {
            _caretLocation.y = textBounds.y;
        }
        else if (_caretLocation.y > textBounds.y + textBounds.height)
        {
            Font* font = getFont(_state);
            GP_ASSERT(font);
            unsigned int fontSize = getFontSize(_state);
            _caretLocation.y = textBounds.y + textBounds.height - fontSize;
        }

        index = font->getIndexAtLocation(displayedText.c_str(), _textBounds, fontSize, _caretLocation, &_caretLocation,
            textAlignment, true, rightToLeft);

        if (index == -1)
        {
            // We failed to find a valid location; just put the caret back to where it was.
            _caretLocation.set(_prevCaretLocation);
        }
    }
}

const char* TextBox::getType() const
{
    return "textBox";
}

void TextBox::setPasswordChar(char character)
{
    _passwordChar = character;
}

char TextBox::getPasswordChar() const
{
    return _passwordChar;
}

void TextBox::setInputMode(InputMode inputMode)
{
    _inputMode = inputMode;
}

TextBox::InputMode TextBox::getInputMode() const
{
    return _inputMode;
}

void TextBox::drawText(const Rectangle& clip)
{
    if (_text.size() <= 0)
        return;

    // Draw the text.
    if (_font)
    {
        const std::string displayedText = getDisplayedText();
        _font->start();
        _font->drawText(displayedText.c_str(), _textBounds, _textColor, getFontSize(_state), getTextAlignment(_state), true, getTextRightToLeft(_state), &_viewportClipBounds);
        _font->finish();
    }
}

TextBox::InputMode TextBox::getInputMode(const char* inputMode)
{
    if (!inputMode)
    {
        return TextBox::TEXT;
    }

    if (strcmp(inputMode, "TEXT") == 0)
    {
        return TextBox::TEXT;
    }
    else if (strcmp(inputMode, "PASSWORD") == 0)
    {
        return TextBox::PASSWORD;
    }
    else
    {
        GP_ERROR("Failed to get corresponding textbox inputmode for unsupported value '%s'.", inputMode);
    }

    // Default.
    return TextBox::TEXT;
}

std::string TextBox::getDisplayedText() const
{
    std::string displayedText;
    switch (_inputMode) {
        case PASSWORD:
            displayedText.insert(0, _text.length(), _passwordChar);
            break;

        case TEXT:
        default:
            displayedText = _text;
            break;
    }

    return displayedText;
}

}
<|endoftext|>


<commit_before>/* The GC superclass methods, used by both GCs. */
#include "object_utils.hpp"
#include "gc/gc.hpp"

#include "objectmemory.hpp"

#include "gc/object_mark.hpp"

#include "builtin/class.hpp"
#include "builtin/tuple.hpp"
#include "builtin/module.hpp"
#include "builtin/symbol.hpp"
#include "builtin/weakref.hpp"
#include "builtin/compiledmethod.hpp"
#include "call_frame.hpp"
#include "builtin/variable_scope.hpp"
#include "builtin/staticscope.hpp"
#include "builtin/block_environment.hpp"
#include "capi/handle.hpp"

#include "arguments.hpp"

#include "object_watch.hpp"

namespace rubinius {

  GCData::GCData(STATE)
    : roots_(state->globals().roots)
    , handles_(state->shared.global_handles())
    , cached_handles_(state->shared.cached_handles())
    , global_cache_(state->shared.global_cache)
    , threads_(state->shared.threads())
    , global_handle_locations_(state->shared.global_handle_locations())
  {}

  GarbageCollector::GarbageCollector(ObjectMemory *om)
                   :object_memory_(om), weak_refs_(NULL) { }

  VM* GarbageCollector::state() {
    return object_memory_->state();
  }

  /* Understands how to read the inside of an object and find all references
   * located within. It copies the objects pointed to, but does not follow into
   * those further (ie, not recursive) */
  void GarbageCollector::scan_object(Object* obj) {
    Object* slot;

    if(watched_p(obj)) {
      std::cout << "detected " << obj << " during scan_object.\n";
    }

    // Check and update an inflated header
    if(obj->inflated_header_p()) {
      obj->inflated_header()->reset_object(obj);
    }

    slot = saw_object(obj->klass());
    if(slot) obj->klass(object_memory_, force_as<Class>(slot));

    if(obj->ivars()->reference_p()) {
      slot = saw_object(obj->ivars());
      if(slot) obj->ivars(object_memory_, slot);
    }

    // Handle Tuple directly, because it's so common
    if(Tuple* tup = try_as<Tuple>(obj)) {
      int size = tup->num_fields();

      for(int i = 0; i < size; i++) {
        slot = tup->field[i];
        if(slot->reference_p()) {
          slot = saw_object(slot);
          if(slot) {
            tup->field[i] = slot;
            object_memory_->write_barrier(tup, slot);
          }
        }
      }
    } else {
      TypeInfo* ti = object_memory_->type_info[obj->type_id()];

      ObjectMark mark(this);
      ti->mark(obj, mark);
    }
  }

  void GarbageCollector::delete_object(Object* obj) {
    if(obj->remembered_p()) {
      object_memory_->unremember_object(obj);
    }
  }

  void GarbageCollector::saw_variable_scope(CallFrame* call_frame,
      StackVariables* scope)
  {
    scope->self_ = mark_object(scope->self());
    scope->block_ = mark_object(scope->block());
    scope->module_ = (Module*)mark_object(scope->module());

    int locals = call_frame->cm->backend_method()->number_of_locals;
    for(int i = 0; i < locals; i++) {
      Object* local = scope->get_local(i);
      if(local->reference_p()) {
        scope->set_local(i, mark_object(local));
      }
    }

    if(scope->last_match_ && scope->last_match_->reference_p()) {
      scope->last_match_ = mark_object(scope->last_match_);
    }

    VariableScope* parent = scope->parent();
    if(parent) {
      scope->parent_ = (VariableScope*)mark_object(parent);
    }

    VariableScope* heap = scope->on_heap();
    if(heap) {
      scope->on_heap_ = (VariableScope*)mark_object(heap);
    }
  }

  void GarbageCollector::walk_call_frame(CallFrame* top_call_frame) {
    CallFrame* call_frame = top_call_frame;
    while(call_frame) {
      if(call_frame->custom_static_scope_p() &&
          call_frame->static_scope_ &&
          call_frame->static_scope_->reference_p()) {
        call_frame->static_scope_ =
          (StaticScope*)mark_object(call_frame->static_scope_);
      }

      if(call_frame->cm && call_frame->cm->reference_p()) {
        call_frame->cm = (CompiledMethod*)mark_object(call_frame->cm);
      }

      if(call_frame->cm && call_frame->stk) {
        native_int stack_size = call_frame->cm->stack_size()->to_native();
        for(native_int i = 0; i < stack_size; i++) {
          Object* obj = call_frame->stk[i];
          if(obj && obj->reference_p()) {
            call_frame->stk[i] = mark_object(obj);
          }
        }
      }

      if(call_frame->multiple_scopes_p() &&
          call_frame->top_scope_) {
        call_frame->top_scope_ = (VariableScope*)mark_object(call_frame->top_scope_);
      }

      if(BlockEnvironment* env = call_frame->block_env()) {
        call_frame->set_block_env((BlockEnvironment*)mark_object(env));
      }

      Arguments* args = call_frame->arguments;
      if(!call_frame->inline_method_p() && args) {
        args->set_recv(mark_object(args->recv()));
        args->set_block(mark_object(args->block()));

        if(Tuple* tup = args->argument_container()) {
          args->update_argument_container((Tuple*)mark_object(tup));
        } else {
          Object** ary = args->arguments();
          for(uint32_t i = 0; i < args->total(); i++) {
            ary[i] = mark_object(ary[i]);
          }
        }
      }

#ifdef ENABLE_LLVM
      if(jit::RuntimeDataHolder* jd = call_frame->jit_data()) {
        jd->set_mark();

        ObjectMark mark(this);
        jd->mark_all(0, mark);
      }

      if(jit::RuntimeData* rd = call_frame->runtime_data()) {
        rd->method_ = (CompiledMethod*)mark_object(rd->method());
        rd->name_ = (Symbol*)mark_object(rd->name());
        rd->module_ = (Module*)mark_object(rd->module());
      }
#endif

      saw_variable_scope(call_frame, call_frame->scope);

      call_frame = static_cast<CallFrame*>(call_frame->previous);
    }
  }

  class UnmarkVisitor : public ObjectVisitor {
    std::vector<Object*> stack_;
    ObjectMemory* object_memory_;

  public:

    UnmarkVisitor(ObjectMemory* om)
      : object_memory_(om)
    {}

    Object* call(Object* obj) {
      if(watched_p(obj)) {
        std::cout << "detected " << obj << " during unmarking.\n";
      }

      if(obj->reference_p() && obj->marked_p(object_memory_->mark())) {
        obj->clear_mark();
        stack_.push_back(obj);
      }

      return obj;
    }

  };

  void GarbageCollector::clean_weakrefs(bool check_forwards) {
    if(!weak_refs_) return;

    for(ObjectArray::iterator i = weak_refs_->begin();
        i != weak_refs_->end();
        i++) {
      WeakRef* ref = try_as<WeakRef>(*i);
      if(!ref) continue; // WTF.

      Object* obj = ref->object();
      if(!obj->reference_p()) continue;

      if(check_forwards) {
        if(obj->young_object_p()) {
          if(!obj->forwarded_p()) {
            ref->set_object(object_memory_, Qnil);
          } else {
            ref->set_object(object_memory_, obj->forward());
          }
        }
      } else if(!obj->marked_p(object_memory_->mark())) {
        ref->set_object(object_memory_, Qnil);
      }
    }

    delete weak_refs_;
    weak_refs_ = NULL;
  }
}
<commit_msg>Add back functions deleted by merge<commit_after>/* The GC superclass methods, used by both GCs. */
#include "object_utils.hpp"
#include "gc/gc.hpp"

#include "objectmemory.hpp"

#include "gc/object_mark.hpp"

#include "builtin/class.hpp"
#include "builtin/tuple.hpp"
#include "builtin/module.hpp"
#include "builtin/symbol.hpp"
#include "builtin/weakref.hpp"
#include "builtin/compiledmethod.hpp"
#include "call_frame.hpp"
#include "builtin/variable_scope.hpp"
#include "builtin/staticscope.hpp"
#include "builtin/block_environment.hpp"
#include "capi/handle.hpp"

#include "arguments.hpp"

#include "object_watch.hpp"

namespace rubinius {

  GCData::GCData(STATE)
    : roots_(state->globals().roots)
    , handles_(state->shared.global_handles())
    , cached_handles_(state->shared.cached_handles())
    , global_cache_(state->shared.global_cache)
    , threads_(state->shared.threads())
    , global_handle_locations_(state->shared.global_handle_locations())
  {}

  GarbageCollector::GarbageCollector(ObjectMemory *om)
                   :object_memory_(om), weak_refs_(NULL) { }

  VM* GarbageCollector::state() {
    return object_memory_->state();
  }

  /* Understands how to read the inside of an object and find all references
   * located within. It copies the objects pointed to, but does not follow into
   * those further (ie, not recursive) */
  void GarbageCollector::scan_object(Object* obj) {
    Object* slot;

    if(watched_p(obj)) {
      std::cout << "detected " << obj << " during scan_object.\n";
    }

    // Check and update an inflated header
    if(obj->inflated_header_p()) {
      obj->inflated_header()->reset_object(obj);
    }

    slot = saw_object(obj->klass());
    if(slot) obj->klass(object_memory_, force_as<Class>(slot));

    if(obj->ivars()->reference_p()) {
      slot = saw_object(obj->ivars());
      if(slot) obj->ivars(object_memory_, slot);
    }

    // Handle Tuple directly, because it's so common
    if(Tuple* tup = try_as<Tuple>(obj)) {
      int size = tup->num_fields();

      for(int i = 0; i < size; i++) {
        slot = tup->field[i];
        if(slot->reference_p()) {
          slot = saw_object(slot);
          if(slot) {
            tup->field[i] = slot;
            object_memory_->write_barrier(tup, slot);
          }
        }
      }
    } else {
      TypeInfo* ti = object_memory_->type_info[obj->type_id()];

      ObjectMark mark(this);
      ti->mark(obj, mark);
    }
  }

  void GarbageCollector::delete_object(Object* obj) {
    if(obj->remembered_p()) {
      object_memory_->unremember_object(obj);
    }
  }

  void GarbageCollector::saw_variable_scope(CallFrame* call_frame,
      StackVariables* scope)
  {
    scope->self_ = mark_object(scope->self());
    scope->block_ = mark_object(scope->block());
    scope->module_ = (Module*)mark_object(scope->module());

    int locals = call_frame->cm->backend_method()->number_of_locals;
    for(int i = 0; i < locals; i++) {
      Object* local = scope->get_local(i);
      if(local->reference_p()) {
        scope->set_local(i, mark_object(local));
      }
    }

    if(scope->last_match_ && scope->last_match_->reference_p()) {
      scope->last_match_ = mark_object(scope->last_match_);
    }

    VariableScope* parent = scope->parent();
    if(parent) {
      scope->parent_ = (VariableScope*)mark_object(parent);
    }

    VariableScope* heap = scope->on_heap();
    if(heap) {
      scope->on_heap_ = (VariableScope*)mark_object(heap);
    }
  }

  void GarbageCollector::walk_call_frame(CallFrame* top_call_frame) {
    CallFrame* call_frame = top_call_frame;
    while(call_frame) {
      if(call_frame->custom_static_scope_p() &&
          call_frame->static_scope_ &&
          call_frame->static_scope_->reference_p()) {
        call_frame->static_scope_ =
          (StaticScope*)mark_object(call_frame->static_scope_);
      }

      if(call_frame->cm && call_frame->cm->reference_p()) {
        call_frame->cm = (CompiledMethod*)mark_object(call_frame->cm);
      }

      if(call_frame->cm && call_frame->stk) {
        native_int stack_size = call_frame->cm->stack_size()->to_native();
        for(native_int i = 0; i < stack_size; i++) {
          Object* obj = call_frame->stk[i];
          if(obj && obj->reference_p()) {
            call_frame->stk[i] = mark_object(obj);
          }
        }
      }

      if(call_frame->multiple_scopes_p() &&
          call_frame->top_scope_) {
        call_frame->top_scope_ = (VariableScope*)mark_object(call_frame->top_scope_);
      }

      if(BlockEnvironment* env = call_frame->block_env()) {
        call_frame->set_block_env((BlockEnvironment*)mark_object(env));
      }

      Arguments* args = call_frame->arguments;
      if(!call_frame->inline_method_p() && args) {
        args->set_recv(mark_object(args->recv()));
        args->set_block(mark_object(args->block()));

        if(Tuple* tup = args->argument_container()) {
          args->update_argument_container((Tuple*)mark_object(tup));
        } else {
          Object** ary = args->arguments();
          for(uint32_t i = 0; i < args->total(); i++) {
            ary[i] = mark_object(ary[i]);
          }
        }
      }

#ifdef ENABLE_LLVM
      if(jit::RuntimeDataHolder* jd = call_frame->jit_data()) {
        jd->set_mark();

        ObjectMark mark(this);
        jd->mark_all(0, mark);
      }

      if(jit::RuntimeData* rd = call_frame->runtime_data()) {
        rd->method_ = (CompiledMethod*)mark_object(rd->method());
        rd->name_ = (Symbol*)mark_object(rd->name());
        rd->module_ = (Module*)mark_object(rd->module());
      }
#endif

      saw_variable_scope(call_frame, call_frame->scope);

      call_frame = static_cast<CallFrame*>(call_frame->previous);
    }
  }

  void GarbageCollector::scan(ManagedThread* thr, bool young_only) {
    for(Roots::Iterator ri(thr->roots()); ri.more(); ri.advance()) {
      ri->set(saw_object(ri->get()));
    }

    scan(thr->variable_root_buffers(), young_only);
    scan(thr->root_buffers(), young_only);

    if(VM* vm = thr->as_vm()) {
      if(CallFrame* cf = vm->saved_call_frame()) {
        walk_call_frame(cf);
      }
    }

    std::list<ObjectHeader*>& los = thr->locked_objects();
    for(std::list<ObjectHeader*>::iterator i = los.begin();
        i != los.end();
        i++) {
      *i = saw_object((Object*)*i);
    }
  }

  void GarbageCollector::scan(VariableRootBuffers& buffers, bool young_only) {
    for(VariableRootBuffers::Iterator vi(buffers);
        vi.more();
        vi.advance())
    {
      Object*** buffer = vi->buffer();
      for(int idx = 0; idx < vi->size(); idx++) {
        Object** var = buffer[idx];
        Object* tmp = *var;

        if(tmp->reference_p() && (!young_only || tmp->young_object_p())) {
          *var = saw_object(tmp);
        }
      }
    }
  }

  void GarbageCollector::scan(RootBuffers& buffers, bool young_only) {
    for(RootBuffers::Iterator i(buffers);
        i.more();
        i.advance())
    {
      Object** buffer = i->buffer();
      for(int idx = 0; idx < i->size(); idx++) {
        Object* tmp = buffer[idx];

        if(tmp->reference_p() && (!young_only || tmp->young_object_p())) {
          buffer[idx] = saw_object(tmp);
        }
      }
    }
  }

  void GarbageCollector::clean_weakrefs(bool check_forwards) {
    if(!weak_refs_) return;

    for(ObjectArray::iterator i = weak_refs_->begin();
        i != weak_refs_->end();
        i++) {
      WeakRef* ref = try_as<WeakRef>(*i);
      if(!ref) continue; // WTF.

      Object* obj = ref->object();
      if(!obj->reference_p()) continue;

      if(check_forwards) {
        if(obj->young_object_p()) {
          if(!obj->forwarded_p()) {
            ref->set_object(object_memory_, Qnil);
          } else {
            ref->set_object(object_memory_, obj->forward());
          }
        }
      } else if(!obj->marked_p(object_memory_->mark())) {
        ref->set_object(object_memory_, Qnil);
      }
    }

    delete weak_refs_;
    weak_refs_ = NULL;
  }
}
<|endoftext|>


<commit_before>#pragma once

#include <GL/gl3w.h>

#include <cstddef>

namespace atlas::glx
{
    template<typename T>
    constexpr void* bufferOffset(std::size_t offset)
    {
        return reinterpret_cast<void*>(offset * sizeof(T));
    }

    template<typename T>
    constexpr GLsizei stride(std::size_t step)
    {
        return static_cast<GLsizei>(step * sizeof(T));
    }

    template<typename T>
    constexpr GLsizei size(std::size_t num)
    {
        return static_cast<GLsizei>(num * sizeof(T));
    }
} // namespace atlas::glx
<commit_msg>[brief] Adds an offset function that returns unsigned int.<commit_after>#pragma once

#include <GL/gl3w.h>

#include <cstddef>

namespace atlas::glx
{
    template<typename T>
    constexpr void* bufferOffset(std::size_t offset)
    {
        return reinterpret_cast<void*>(offset * sizeof(T));
    }

    template<typename T>
    constexpr GLsizei stride(std::size_t step)
    {
        return static_cast<GLsizei>(step * sizeof(T));
    }

    template<typename T>
    constexpr GLsizei size(std::size_t num)
    {
        return static_cast<GLsizei>(num * sizeof(T));
    }

    template<typename T>
    constexpr GLuint relativeOffset(std::size_t num)
    {
        return static_cast<GLuint>(num * sizeof(T));
    }
} // namespace atlas::glx
<|endoftext|>