<commit_before>/****************************************************************************
 *   Copyright (C) 2012-2016 by Savoir-faire Linux                          *
 *   Author : Emmanuel Lepage Vallee <emmanuel.lepage@savoirfairelinux.com> *
 *   Author : Guillaume Roguez <guillaume.roguez@savoirfairelinux.com>      *
 *                                                                          *
 *   This library is free software; you can redistribute it and/or          *
 *   modify it under the terms of the GNU Lesser General Public             *
 *   License as published by the Free Software Foundation; either           *
 *   version 2.1 of the License, or (at your option) any later version.     *
 *                                                                          *
 *   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 General Public License      *
 *   along with this program.  If not, see <http://www.gnu.org/licenses/>.  *
 ***************************************************************************/
#include "shmrenderer.h"

#include <QtCore/QDebug>
#include <QtCore/QMutex>
#include <QtCore/QThread>

#include <sys/ipc.h>
#include <sys/sem.h>
#include <sys/shm.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/mman.h>
#include <semaphore.h>
#include <errno.h>

#ifndef CLOCK_REALTIME
#define CLOCK_REALTIME 0
#endif

#include <QtCore/QTimer>
#include <chrono>

#include "private/videorenderermanager.h"
#include "video/resolution.h"
#include "private/videorenderer_p.h"
#include "videomanager_interface.h"

// Uncomment following line to output in console the FPS value
//#define DEBUG_FPS

/* Shared memory object
 * Implementation note: double-buffering
 * Shared memory is divided in two regions, each representing one frame.
 * First byte of each frame is warranted to by aligned on 16 bytes.
 * One region is marked readable: this region can be safely read.
 * The other region is writeable: only the producer can use it.
 */

struct SHMHeader {
   sem_t    mutex        ; /*!< Lock it before any operations on following fields.           */
   sem_t    frameGenMutex; /*!< unlocked by producer when frameGen modified                  */
   unsigned frameGen     ; /*!< monotonically incremented when a producer changes readOffset */
   unsigned frameSize    ; /*!< size in bytes of 1 frame                                     */
   unsigned mapSize      ; /*!< size to map if you need to see all data                      */
   unsigned readOffset   ; /*!< offset of readable frame in data                             */
   unsigned writeOffset  ; /*!< offset of writable frame in data                             */

#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-pedantic"
   uint8_t data[]     ; /*!< the whole shared memory                                      */
#pragma GCC diagnostic pop
};

namespace Video {

class ShmRendererPrivate final : public QObject
{
   Q_OBJECT

public:
   ShmRendererPrivate(ShmRenderer* parent);

   //Types
   using TimePoint = std::chrono::time_point<std::chrono::system_clock>;

   // Attributes
   QString    m_ShmPath       ;
   int        m_fd            ;
   SHMHeader* m_pShmArea      ;
   unsigned   m_ShmAreaLen    ;
   uint       m_FrameGen      ;
   int        m_fpsC          ;
   int        m_Fps           ;
   TimePoint  m_lastFrameDebug;
   QTimer*    m_pTimer        ;

   // Constants
   constexpr static const int FPS_RATE_SEC        = 1  ;
   constexpr static const int FRAME_CHECK_RATE_HZ = 120;

   // Helpers
   timespec createTimeout(           );
   bool     shmLock      (           );
   void     shmUnlock    (           );
   bool     getNewFrame  ( bool wait );
   bool     remapShm     (           );

private:
   Video::ShmRenderer* q_ptr;
};

ShmRendererPrivate::ShmRendererPrivate(ShmRenderer* parent)
   : QObject     ( parent                              )
   , q_ptr       ( parent                              )
   , m_fd        ( -1                                  )
   , m_fpsC      ( 0                                   )
   , m_Fps       ( 0                                   )
   , m_pShmArea  ( (SHMHeader*)MAP_FAILED              )
   , m_ShmAreaLen( 0                                   )
   , m_FrameGen  ( 0                                   )
   , m_pTimer    ( nullptr                             )
#ifdef DEBUG_FPS
   , m_frameCount( 0                                   )
   , m_lastFrameDebug(std::chrono::system_clock::now() )
#endif
{
}

/// Constructor
ShmRenderer::ShmRenderer(const QByteArray& id, const QString& shmPath, const QSize& res)
   : Renderer(id, res)
   , d_ptr(new ShmRendererPrivate(this))
{
   d_ptr->m_ShmPath = shmPath;
   setObjectName("Video::Renderer:"+id);
}

/// Destructor
ShmRenderer::~ShmRenderer()
{
   if (d_ptr->m_pTimer) {
      d_ptr->m_pTimer->stop();
      d_ptr->m_pTimer = nullptr;
   }
   stopShm();
}

/// Wait new frame data from shared memory and save pointer
bool ShmRendererPrivate::getNewFrame(bool wait)
{
   if (!shmLock())
      return false;

   if (m_FrameGen == m_pShmArea->frameGen) {
      shmUnlock();

      if (not wait)
         return false;

      // wait for a new frame, max 33ms
      static const struct timespec timeout = {0, 33000000};
      if (::sem_timedwait(&m_pShmArea->frameGenMutex, &timeout) < 0)
         return false;

      if (!shmLock())
         return false;

   }

   // valid frame to render (daemon may have stopped)?
   if (! m_pShmArea->frameSize) {
      shmUnlock();
      return false;
   }

   // map frame data
   if (!remapShm()) {
      qDebug() << "Could not resize shared memory";
      return false;
   }

   auto& frame_ptr = q_ptr->Video::Renderer::d_ptr->m_pFrame;
   if (not frame_ptr)
       frame_ptr.reset(new Frame);
   frame_ptr->storage.clear();
   frame_ptr->ptr = m_pShmArea->data + m_pShmArea->readOffset;
   frame_ptr->size = m_pShmArea->frameSize;
   m_FrameGen = m_pShmArea->frameGen;

   shmUnlock();

   ++m_fpsC;

   // Compute the FPS shown to the client
   auto currentTime = std::chrono::system_clock::now();
   const std::chrono::duration<double> seconds = currentTime - m_lastFrameDebug;
   if (seconds.count() >= FPS_RATE_SEC) {
      m_Fps = (int)(m_fpsC / seconds.count());
      m_fpsC = 0;
      m_lastFrameDebug = currentTime;
#ifdef DEBUG_FPS
      qDebug() << this << ": FPS " << m_fps;
#endif
   }

   return true;
}

/// Remap the shared memory
/// Shared memory in unlocked state if returns false (resize failed).
bool ShmRendererPrivate::remapShm()
{
   // This loop handles case where daemon resize shared memory
   // during time we unlock it for remapping.
   while (m_ShmAreaLen != m_pShmArea->mapSize) {
      auto mapSize = m_pShmArea->mapSize;
      shmUnlock();

      if (::munmap(m_pShmArea, m_ShmAreaLen)) {
         qDebug() << "Could not unmap shared area: " << strerror(errno);
         return false;
      }

      m_pShmArea = (SHMHeader*) ::mmap(nullptr, mapSize, PROT_READ | PROT_WRITE,
                                       MAP_SHARED, m_fd, 0);

      if (m_pShmArea == MAP_FAILED) {
         qDebug() << "Could not remap shared area: " << strerror(errno);
         return false;
      }

      if (!shmLock())
         return false;

      m_ShmAreaLen = mapSize;
   }

   return true;
}

/// Connect to the shared memory
bool ShmRenderer::startShm()
{
   if (d_ptr->m_fd != -1) {
      qDebug() << "fd must be -1";
      return false;
   }

   d_ptr->m_fd = ::shm_open(d_ptr->m_ShmPath.toLatin1(), O_RDWR, 0);

   if (d_ptr->m_fd < 0) {
      qDebug() << "could not open shm area" << d_ptr->m_ShmPath
               << ", shm_open failed:"      << strerror(errno);
      return false;
   }

   // Map only header data
   const auto mapSize = sizeof(SHMHeader);
   d_ptr->m_pShmArea = (SHMHeader*) ::mmap(nullptr, mapSize,
      PROT_READ | PROT_WRITE,
      MAP_SHARED, d_ptr->m_fd, 0
   );

   if (d_ptr->m_pShmArea == MAP_FAILED) {
      qDebug() << "Could not remap shared area";
      return false;
   }

   d_ptr->m_ShmAreaLen = mapSize;
   return true;
}

/// Disconnect from the shared memory
void ShmRenderer::stopShm()
{
   if (d_ptr->m_fd < 0)
      return;

   if (d_ptr->m_pTimer) {
      d_ptr->m_pTimer->stop();
      d_ptr->m_pTimer = nullptr;
   }

   // reset the frame so it doesn't point to an old value
   Video::Renderer::d_ptr->m_pFrame.reset();

   //Emit the signal before closing the file, this lower the risk of invalid
   //memory access
   emit stopped();

   ::close(d_ptr->m_fd);
   d_ptr->m_fd = -1;

   if (d_ptr->m_pShmArea == MAP_FAILED)
      return;

   ::munmap(d_ptr->m_pShmArea, d_ptr->m_ShmAreaLen);
   d_ptr->m_ShmAreaLen = 0;
   d_ptr->m_pShmArea = (SHMHeader*) MAP_FAILED;
}

/// Lock the memory while the copy is being made
bool ShmRendererPrivate::shmLock()
{
   return ::sem_wait(&m_pShmArea->mutex) >= 0;
}

/// Remove the lock, allow a new frame to be drawn
void ShmRendererPrivate::shmUnlock()
{
   ::sem_post(&m_pShmArea->mutex);
}

/*****************************************************************************
 *                                                                           *
 *                                   Slots                                   *
 *                                                                           *
 ****************************************************************************/

/// Start the rendering loop
void ShmRenderer::startRendering()
{
   QMutexLocker locker {mutex()};

   if (!startShm())
      return;

   Video::Renderer::d_ptr->m_isRendering = true;

   if (!d_ptr->m_pTimer) {
      d_ptr->m_pTimer = new QTimer(this);
      d_ptr->m_pTimer->setInterval(33);
      connect(d_ptr->m_pTimer,&QTimer::timeout,[this]() {
         emit this->frameUpdated();
      });
   }
   //FIXME This is a temporary hack as frameUpdated() is no longer emitted
   d_ptr->m_pTimer->start();

   emit started();
}

/// Stop the rendering loop
void ShmRenderer::stopRendering()
{
   QMutexLocker locker {mutex()};
   Video::Renderer::d_ptr->m_isRendering = false;

   if (d_ptr->m_pTimer) {
      d_ptr->m_pTimer->stop();
      d_ptr->m_pTimer = nullptr;
   }

   stopShm();
}

/*****************************************************************************
 *                                                                           *
 *                                 Getters                                   *
 *                                                                           *
 ****************************************************************************/

/// Get the current frame rate of this renderer
int ShmRenderer::fps() const
{
   return d_ptr->m_Fps;
}

/// Get frame data pointer from shared memory
Frame ShmRenderer::currentFrame() const
{
    if (not isRendering())
        return {};

    QMutexLocker lk {mutex()};
    if (d_ptr->getNewFrame(false)) {
        if (auto frame_ptr = Video::Renderer::d_ptr->m_pFrame)
            return std::move(*frame_ptr);
    }
    return {};
}

Video::Renderer::ColorSpace ShmRenderer::colorSpace() const
{
   return Video::Renderer::ColorSpace::BGRA;
}

/*****************************************************************************
 *                                                                           *
 *                                 Setters                                   *
 *                                                                           *
 ****************************************************************************/

void ShmRenderer::setShmPath(const QString& path)
{
   d_ptr->m_ShmPath = path;
}

} // namespace Video

#include <shmrenderer.moc>
<commit_msg>shm: Remove wrongly included file<commit_after>/****************************************************************************
 *   Copyright (C) 2012-2016 by Savoir-faire Linux                          *
 *   Author : Emmanuel Lepage Vallee <emmanuel.lepage@savoirfairelinux.com> *
 *   Author : Guillaume Roguez <guillaume.roguez@savoirfairelinux.com>      *
 *                                                                          *
 *   This library is free software; you can redistribute it and/or          *
 *   modify it under the terms of the GNU Lesser General Public             *
 *   License as published by the Free Software Foundation; either           *
 *   version 2.1 of the License, or (at your option) any later version.     *
 *                                                                          *
 *   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 General Public License      *
 *   along with this program.  If not, see <http://www.gnu.org/licenses/>.  *
 ***************************************************************************/
#include "shmrenderer.h"

#include <QtCore/QDebug>
#include <QtCore/QMutex>
#include <QtCore/QThread>

#include <sys/ipc.h>
#include <sys/sem.h>
#include <sys/shm.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/mman.h>
#include <semaphore.h>
#include <errno.h>

#ifndef CLOCK_REALTIME
#define CLOCK_REALTIME 0
#endif

#include <QtCore/QTimer>
#include <chrono>

#include "private/videorenderermanager.h"
#include "video/resolution.h"
#include "private/videorenderer_p.h"

// Uncomment following line to output in console the FPS value
//#define DEBUG_FPS

/* Shared memory object
 * Implementation note: double-buffering
 * Shared memory is divided in two regions, each representing one frame.
 * First byte of each frame is warranted to by aligned on 16 bytes.
 * One region is marked readable: this region can be safely read.
 * The other region is writeable: only the producer can use it.
 */

struct SHMHeader {
   sem_t    mutex        ; /*!< Lock it before any operations on following fields.           */
   sem_t    frameGenMutex; /*!< unlocked by producer when frameGen modified                  */
   unsigned frameGen     ; /*!< monotonically incremented when a producer changes readOffset */
   unsigned frameSize    ; /*!< size in bytes of 1 frame                                     */
   unsigned mapSize      ; /*!< size to map if you need to see all data                      */
   unsigned readOffset   ; /*!< offset of readable frame in data                             */
   unsigned writeOffset  ; /*!< offset of writable frame in data                             */

#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-pedantic"
   uint8_t data[]     ; /*!< the whole shared memory                                      */
#pragma GCC diagnostic pop
};

namespace Video {

class ShmRendererPrivate final : public QObject
{
   Q_OBJECT

public:
   ShmRendererPrivate(ShmRenderer* parent);

   //Types
   using TimePoint = std::chrono::time_point<std::chrono::system_clock>;

   // Attributes
   QString    m_ShmPath       ;
   int        m_fd            ;
   SHMHeader* m_pShmArea      ;
   unsigned   m_ShmAreaLen    ;
   uint       m_FrameGen      ;
   int        m_fpsC          ;
   int        m_Fps           ;
   TimePoint  m_lastFrameDebug;
   QTimer*    m_pTimer        ;

   // Constants
   constexpr static const int FPS_RATE_SEC        = 1  ;
   constexpr static const int FRAME_CHECK_RATE_HZ = 120;

   // Helpers
   timespec createTimeout(           );
   bool     shmLock      (           );
   void     shmUnlock    (           );
   bool     getNewFrame  ( bool wait );
   bool     remapShm     (           );

private:
   Video::ShmRenderer* q_ptr;
};

ShmRendererPrivate::ShmRendererPrivate(ShmRenderer* parent)
   : QObject     ( parent                              )
   , q_ptr       ( parent                              )
   , m_fd        ( -1                                  )
   , m_fpsC      ( 0                                   )
   , m_Fps       ( 0                                   )
   , m_pShmArea  ( (SHMHeader*)MAP_FAILED              )
   , m_ShmAreaLen( 0                                   )
   , m_FrameGen  ( 0                                   )
   , m_pTimer    ( nullptr                             )
#ifdef DEBUG_FPS
   , m_frameCount( 0                                   )
   , m_lastFrameDebug(std::chrono::system_clock::now() )
#endif
{
}

/// Constructor
ShmRenderer::ShmRenderer(const QByteArray& id, const QString& shmPath, const QSize& res)
   : Renderer(id, res)
   , d_ptr(new ShmRendererPrivate(this))
{
   d_ptr->m_ShmPath = shmPath;
   setObjectName("Video::Renderer:"+id);
}

/// Destructor
ShmRenderer::~ShmRenderer()
{
   if (d_ptr->m_pTimer) {
      d_ptr->m_pTimer->stop();
      d_ptr->m_pTimer = nullptr;
   }
   stopShm();
}

/// Wait new frame data from shared memory and save pointer
bool ShmRendererPrivate::getNewFrame(bool wait)
{
   if (!shmLock())
      return false;

   if (m_FrameGen == m_pShmArea->frameGen) {
      shmUnlock();

      if (not wait)
         return false;

      // wait for a new frame, max 33ms
      static const struct timespec timeout = {0, 33000000};
      if (::sem_timedwait(&m_pShmArea->frameGenMutex, &timeout) < 0)
         return false;

      if (!shmLock())
         return false;

   }

   // valid frame to render (daemon may have stopped)?
   if (! m_pShmArea->frameSize) {
      shmUnlock();
      return false;
   }

   // map frame data
   if (!remapShm()) {
      qDebug() << "Could not resize shared memory";
      return false;
   }

   auto& frame_ptr = q_ptr->Video::Renderer::d_ptr->m_pFrame;
   if (not frame_ptr)
       frame_ptr.reset(new Frame);
   frame_ptr->storage.clear();
   frame_ptr->ptr = m_pShmArea->data + m_pShmArea->readOffset;
   frame_ptr->size = m_pShmArea->frameSize;
   m_FrameGen = m_pShmArea->frameGen;

   shmUnlock();

   ++m_fpsC;

   // Compute the FPS shown to the client
   auto currentTime = std::chrono::system_clock::now();
   const std::chrono::duration<double> seconds = currentTime - m_lastFrameDebug;
   if (seconds.count() >= FPS_RATE_SEC) {
      m_Fps = (int)(m_fpsC / seconds.count());
      m_fpsC = 0;
      m_lastFrameDebug = currentTime;
#ifdef DEBUG_FPS
      qDebug() << this << ": FPS " << m_fps;
#endif
   }

   return true;
}

/// Remap the shared memory
/// Shared memory in unlocked state if returns false (resize failed).
bool ShmRendererPrivate::remapShm()
{
   // This loop handles case where daemon resize shared memory
   // during time we unlock it for remapping.
   while (m_ShmAreaLen != m_pShmArea->mapSize) {
      auto mapSize = m_pShmArea->mapSize;
      shmUnlock();

      if (::munmap(m_pShmArea, m_ShmAreaLen)) {
         qDebug() << "Could not unmap shared area: " << strerror(errno);
         return false;
      }

      m_pShmArea = (SHMHeader*) ::mmap(nullptr, mapSize, PROT_READ | PROT_WRITE,
                                       MAP_SHARED, m_fd, 0);

      if (m_pShmArea == MAP_FAILED) {
         qDebug() << "Could not remap shared area: " << strerror(errno);
         return false;
      }

      if (!shmLock())
         return false;

      m_ShmAreaLen = mapSize;
   }

   return true;
}

/// Connect to the shared memory
bool ShmRenderer::startShm()
{
   if (d_ptr->m_fd != -1) {
      qDebug() << "fd must be -1";
      return false;
   }

   d_ptr->m_fd = ::shm_open(d_ptr->m_ShmPath.toLatin1(), O_RDWR, 0);

   if (d_ptr->m_fd < 0) {
      qDebug() << "could not open shm area" << d_ptr->m_ShmPath
               << ", shm_open failed:"      << strerror(errno);
      return false;
   }

   // Map only header data
   const auto mapSize = sizeof(SHMHeader);
   d_ptr->m_pShmArea = (SHMHeader*) ::mmap(nullptr, mapSize,
      PROT_READ | PROT_WRITE,
      MAP_SHARED, d_ptr->m_fd, 0
   );

   if (d_ptr->m_pShmArea == MAP_FAILED) {
      qDebug() << "Could not remap shared area";
      return false;
   }

   d_ptr->m_ShmAreaLen = mapSize;
   return true;
}

/// Disconnect from the shared memory
void ShmRenderer::stopShm()
{
   if (d_ptr->m_fd < 0)
      return;

   if (d_ptr->m_pTimer) {
      d_ptr->m_pTimer->stop();
      d_ptr->m_pTimer = nullptr;
   }

   // reset the frame so it doesn't point to an old value
   Video::Renderer::d_ptr->m_pFrame.reset();

   //Emit the signal before closing the file, this lower the risk of invalid
   //memory access
   emit stopped();

   ::close(d_ptr->m_fd);
   d_ptr->m_fd = -1;

   if (d_ptr->m_pShmArea == MAP_FAILED)
      return;

   ::munmap(d_ptr->m_pShmArea, d_ptr->m_ShmAreaLen);
   d_ptr->m_ShmAreaLen = 0;
   d_ptr->m_pShmArea = (SHMHeader*) MAP_FAILED;
}

/// Lock the memory while the copy is being made
bool ShmRendererPrivate::shmLock()
{
   return ::sem_wait(&m_pShmArea->mutex) >= 0;
}

/// Remove the lock, allow a new frame to be drawn
void ShmRendererPrivate::shmUnlock()
{
   ::sem_post(&m_pShmArea->mutex);
}

/*****************************************************************************
 *                                                                           *
 *                                   Slots                                   *
 *                                                                           *
 ****************************************************************************/

/// Start the rendering loop
void ShmRenderer::startRendering()
{
   QMutexLocker locker {mutex()};

   if (!startShm())
      return;

   Video::Renderer::d_ptr->m_isRendering = true;

   if (!d_ptr->m_pTimer) {
      d_ptr->m_pTimer = new QTimer(this);
      d_ptr->m_pTimer->setInterval(33);
      connect(d_ptr->m_pTimer,&QTimer::timeout,[this]() {
         emit this->frameUpdated();
      });
   }
   //FIXME This is a temporary hack as frameUpdated() is no longer emitted
   d_ptr->m_pTimer->start();

   emit started();
}

/// Stop the rendering loop
void ShmRenderer::stopRendering()
{
   QMutexLocker locker {mutex()};
   Video::Renderer::d_ptr->m_isRendering = false;

   if (d_ptr->m_pTimer) {
      d_ptr->m_pTimer->stop();
      d_ptr->m_pTimer = nullptr;
   }

   stopShm();
}

/*****************************************************************************
 *                                                                           *
 *                                 Getters                                   *
 *                                                                           *
 ****************************************************************************/

/// Get the current frame rate of this renderer
int ShmRenderer::fps() const
{
   return d_ptr->m_Fps;
}

/// Get frame data pointer from shared memory
Frame ShmRenderer::currentFrame() const
{
    if (not isRendering())
        return {};

    QMutexLocker lk {mutex()};
    if (d_ptr->getNewFrame(false)) {
        if (auto frame_ptr = Video::Renderer::d_ptr->m_pFrame)
            return std::move(*frame_ptr);
    }
    return {};
}

Video::Renderer::ColorSpace ShmRenderer::colorSpace() const
{
   return Video::Renderer::ColorSpace::BGRA;
}

/*****************************************************************************
 *                                                                           *
 *                                 Setters                                   *
 *                                                                           *
 ****************************************************************************/

void ShmRenderer::setShmPath(const QString& path)
{
   d_ptr->m_ShmPath = path;
}

} // namespace Video

#include <shmrenderer.moc>
<|endoftext|>


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

#include "ui/aura/desktop/desktop_activation_client.h"

#include "base/auto_reset.h"
#include "ui/aura/client/activation_delegate.h"
#include "ui/aura/focus_manager.h"
#include "ui/aura/root_window.h"
#include "ui/aura/window.h"

namespace aura {

DesktopActivationClient::DesktopActivationClient(RootWindow* root_window)
    : root_window_(root_window),
      current_active_(NULL),
      updating_activation_(false) {
  root_window->AddRootWindowObserver(this);
}

DesktopActivationClient::~DesktopActivationClient() {
  root_window_->RemoveRootWindowObserver(this);
}

void DesktopActivationClient::ActivateWindow(Window* window) {
  // Prevent recursion when called from focus.
  if (updating_activation_)
    return;

  AutoReset<bool> in_activate_window(&updating_activation_, true);
  // Nothing may actually have changed.
  aura::Window* old_active = GetActiveWindow();
  if (old_active == window)
    return;
  // The stacking client may impose rules on what window configurations can be
  // activated or deactivated.
  if (window && !CanActivateWindow(window))
    return;
  // Switch internal focus before we change the activation. Will probably cause
  // recursion.
  if (window &&
      !window->Contains(window->GetFocusManager()->GetFocusedWindow())) {
    window->GetFocusManager()->SetFocusedWindow(window, NULL);
  }

  // Send a deactivation to the old window
  if (current_active_ && aura::client::GetActivationDelegate(current_active_))
    aura::client::GetActivationDelegate(current_active_)->OnLostActive();

  current_active_ = window;

  // Send an activation event to the new window
  if (window && aura::client::GetActivationDelegate(window))
    aura::client::GetActivationDelegate(window)->OnActivated();
}

void DesktopActivationClient::DeactivateWindow(Window* window) {
  if (window == current_active_)
    current_active_ = NULL;
}

aura::Window* DesktopActivationClient::GetActiveWindow() {
  return current_active_;
}

bool DesktopActivationClient::OnWillFocusWindow(Window* window,
                                                const Event* event) {
  // TODO(erg): Is this OK? Logic is much more nuanced in ash.
  return true;
}

void DesktopActivationClient::OnWindowFocused(aura::Window* window) {
  ActivateWindow(GetActivatableWindow(window));
}

bool DesktopActivationClient::CanActivateWindow(aura::Window* window) const {
  return window &&
      window->IsVisible() &&
      (!aura::client::GetActivationDelegate(window) ||
        aura::client::GetActivationDelegate(window)->ShouldActivate(NULL));
}

aura::Window* DesktopActivationClient::GetActivatableWindow(
    aura::Window* window) {
  aura::Window* parent = window->parent();
  aura::Window* child = window;
  while (parent) {
    if (CanActivateWindow(child))
      return child;
    // If |child| isn't activatable, but has transient parent, trace
    // that path instead.
    if (child->transient_parent())
      return GetActivatableWindow(child->transient_parent());
    parent = parent->parent();
    child = child->parent();
  }
  return NULL;
}

}  // namespace aura
<commit_msg>Aura desktop: Really implement DesktopActivationClient::OnWillFocusWindow().<commit_after>// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "ui/aura/desktop/desktop_activation_client.h"

#include "base/auto_reset.h"
#include "ui/aura/client/activation_delegate.h"
#include "ui/aura/focus_manager.h"
#include "ui/aura/root_window.h"
#include "ui/aura/window.h"

namespace aura {

DesktopActivationClient::DesktopActivationClient(RootWindow* root_window)
    : root_window_(root_window),
      current_active_(NULL),
      updating_activation_(false) {
  root_window->AddRootWindowObserver(this);
}

DesktopActivationClient::~DesktopActivationClient() {
  root_window_->RemoveRootWindowObserver(this);
}

void DesktopActivationClient::ActivateWindow(Window* window) {
  // Prevent recursion when called from focus.
  if (updating_activation_)
    return;

  AutoReset<bool> in_activate_window(&updating_activation_, true);
  // Nothing may actually have changed.
  aura::Window* old_active = GetActiveWindow();
  if (old_active == window)
    return;
  // The stacking client may impose rules on what window configurations can be
  // activated or deactivated.
  if (window && !CanActivateWindow(window))
    return;
  // Switch internal focus before we change the activation. Will probably cause
  // recursion.
  if (window &&
      !window->Contains(window->GetFocusManager()->GetFocusedWindow())) {
    window->GetFocusManager()->SetFocusedWindow(window, NULL);
  }

  // Send a deactivation to the old window
  if (current_active_ && aura::client::GetActivationDelegate(current_active_))
    aura::client::GetActivationDelegate(current_active_)->OnLostActive();

  current_active_ = window;

  // Send an activation event to the new window
  if (window && aura::client::GetActivationDelegate(window))
    aura::client::GetActivationDelegate(window)->OnActivated();
}

void DesktopActivationClient::DeactivateWindow(Window* window) {
  if (window == current_active_)
    current_active_ = NULL;
}

aura::Window* DesktopActivationClient::GetActiveWindow() {
  return current_active_;
}

bool DesktopActivationClient::OnWillFocusWindow(Window* window,
                                                const Event* event) {
  return CanActivateWindow(window);
}

void DesktopActivationClient::OnWindowFocused(aura::Window* window) {
  ActivateWindow(GetActivatableWindow(window));
}

bool DesktopActivationClient::CanActivateWindow(aura::Window* window) const {
  return window &&
      window->IsVisible() &&
      (!aura::client::GetActivationDelegate(window) ||
        aura::client::GetActivationDelegate(window)->ShouldActivate(NULL));
}

aura::Window* DesktopActivationClient::GetActivatableWindow(
    aura::Window* window) {
  aura::Window* parent = window->parent();
  aura::Window* child = window;
  while (parent) {
    if (CanActivateWindow(child))
      return child;
    // If |child| isn't activatable, but has transient parent, trace
    // that path instead.
    if (child->transient_parent())
      return GetActivatableWindow(child->transient_parent());
    parent = parent->parent();
    child = child->parent();
  }
  return NULL;
}

}  // namespace aura
<|endoftext|>


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

#include "ui/ozone/platform/dri/gbm_surface_factory.h"

#include <gbm.h>

#include "base/command_line.h"
#include "base/files/file_path.h"
#include "third_party/khronos/EGL/egl.h"
#include "ui/ozone/platform/dri/dri_window_delegate_impl.h"
#include "ui/ozone/platform/dri/dri_window_manager.h"
#include "ui/ozone/platform/dri/gbm_buffer.h"
#include "ui/ozone/platform/dri/gbm_surface.h"
#include "ui/ozone/platform/dri/gbm_surfaceless.h"
#include "ui/ozone/platform/dri/screen_manager.h"
#include "ui/ozone/public/native_pixmap.h"
#include "ui/ozone/public/overlay_candidates_ozone.h"
#include "ui/ozone/public/ozone_switches.h"
#include "ui/ozone/public/surface_ozone_egl.h"

namespace ui {
namespace {

class SingleOverlay : public OverlayCandidatesOzone {
 public:
  SingleOverlay() {}
  virtual ~SingleOverlay() {}

  virtual void CheckOverlaySupport(OverlaySurfaceCandidateList* candidates) {
    if (candidates->size() == 2) {
      OverlayCandidatesOzone::OverlaySurfaceCandidate* first =
          &(*candidates)[0];
      OverlayCandidatesOzone::OverlaySurfaceCandidate* second =
          &(*candidates)[1];
      OverlayCandidatesOzone::OverlaySurfaceCandidate* overlay;
      if (first->plane_z_order == 0) {
        overlay = second;
      } else if (second->plane_z_order == 0) {
        overlay = first;
      } else {
        NOTREACHED();
        return;
      }
      if (overlay->plane_z_order > 0 &&
          IsTransformSupported(overlay->transform)) {
        overlay->overlay_handled = true;
      }
    }
  }

 private:
  bool IsTransformSupported(gfx::OverlayTransform transform) {
    switch (transform) {
      case gfx::OVERLAY_TRANSFORM_NONE:
        return true;
      default:
        return false;
    }
  }

  DISALLOW_COPY_AND_ASSIGN(SingleOverlay);
};

}  // namespace

GbmSurfaceFactory::GbmSurfaceFactory(bool allow_surfaceless)
    : DriSurfaceFactory(NULL, NULL, NULL),
      device_(NULL),
      allow_surfaceless_(allow_surfaceless) {
}

GbmSurfaceFactory::~GbmSurfaceFactory() {}

void GbmSurfaceFactory::InitializeGpu(DriWrapper* dri,
                                      gbm_device* device,
                                      ScreenManager* screen_manager,
                                      DriWindowManager* window_manager) {
  drm_ = dri;
  device_ = device;
  screen_manager_ = screen_manager;
  window_manager_ = window_manager;
}

intptr_t GbmSurfaceFactory::GetNativeDisplay() {
  DCHECK(state_ == INITIALIZED);
  return reinterpret_cast<intptr_t>(device_);
}

const int32* GbmSurfaceFactory::GetEGLSurfaceProperties(
    const int32* desired_list) {
  static const int32 kConfigAttribs[] = {
    EGL_BUFFER_SIZE, 32,
    EGL_ALPHA_SIZE, 8,
    EGL_BLUE_SIZE, 8,
    EGL_GREEN_SIZE, 8,
    EGL_RED_SIZE, 8,
    EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
    EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
    EGL_NONE
  };

  return kConfigAttribs;
}

bool GbmSurfaceFactory::LoadEGLGLES2Bindings(
      AddGLLibraryCallback add_gl_library,
      SetGLGetProcAddressProcCallback set_gl_get_proc_address) {
  base::NativeLibraryLoadError error;
  base::NativeLibrary gles_library = base::LoadNativeLibrary(
      base::FilePath("libGLESv2.so.2"),
      &error);
  if (!gles_library) {
    LOG(WARNING) << "Failed to load GLES library: " << error.ToString();
    return false;
  }

  base::NativeLibrary egl_library = base::LoadNativeLibrary(
      base::FilePath("libEGL.so.1"),
      &error);
  if (!egl_library) {
    LOG(WARNING) << "Failed to load EGL library: " << error.ToString();
    base::UnloadNativeLibrary(gles_library);
    return false;
  }

  GLGetProcAddressProc get_proc_address =
      reinterpret_cast<GLGetProcAddressProc>(
          base::GetFunctionPointerFromNativeLibrary(
              egl_library, "eglGetProcAddress"));
  if (!get_proc_address) {
    LOG(ERROR) << "eglGetProcAddress not found.";
    base::UnloadNativeLibrary(egl_library);
    base::UnloadNativeLibrary(gles_library);
    return false;
  }

  set_gl_get_proc_address.Run(get_proc_address);
  add_gl_library.Run(egl_library);
  add_gl_library.Run(gles_library);

  return true;
}

scoped_ptr<SurfaceOzoneEGL> GbmSurfaceFactory::CreateEGLSurfaceForWidget(
    gfx::AcceleratedWidget widget) {
  DCHECK(state_ == INITIALIZED);

  DriWindowDelegate* delegate = GetOrCreateWindowDelegate(widget);

  ResetCursor(widget);

  scoped_ptr<GbmSurface> surface(new GbmSurface(delegate, device_, drm_));
  if (!surface->Initialize())
    return scoped_ptr<SurfaceOzoneEGL>();

  return surface.PassAs<SurfaceOzoneEGL>();
}

scoped_ptr<SurfaceOzoneEGL>
GbmSurfaceFactory::CreateSurfacelessEGLSurfaceForWidget(
    gfx::AcceleratedWidget widget) {
  if (!allow_surfaceless_)
    return scoped_ptr<SurfaceOzoneEGL>();

  DriWindowDelegate* delegate = GetOrCreateWindowDelegate(widget);
  return scoped_ptr<SurfaceOzoneEGL>(new GbmSurfaceless(delegate));
}

scoped_refptr<ui::NativePixmap> GbmSurfaceFactory::CreateNativePixmap(
    gfx::Size size,
    BufferFormat format) {
  scoped_refptr<GbmBuffer> buffer = GbmBuffer::CreateBuffer(
      drm_, device_, format, size, true);
  if (!buffer)
    return NULL;

  return scoped_refptr<GbmPixmap>(new GbmPixmap(buffer));
}

OverlayCandidatesOzone* GbmSurfaceFactory::GetOverlayCandidates(
    gfx::AcceleratedWidget w) {
  if (CommandLine::ForCurrentProcess()->HasSwitch(
          switches::kOzoneTestSingleOverlaySupport))
    return new SingleOverlay();
  return NULL;
}

bool GbmSurfaceFactory::ScheduleOverlayPlane(
    gfx::AcceleratedWidget widget,
    int plane_z_order,
    gfx::OverlayTransform plane_transform,
    scoped_refptr<NativePixmap> buffer,
    const gfx::Rect& display_bounds,
    const gfx::RectF& crop_rect) {
  scoped_refptr<GbmPixmap> pixmap = static_cast<GbmPixmap*>(buffer.get());
  if (!pixmap) {
    LOG(ERROR) << "ScheduleOverlayPlane passed NULL buffer.";
    return false;
  }
  HardwareDisplayController* hdc =
      window_manager_->GetWindowDelegate(widget)->GetController();
  if (!hdc)
    return true;

  hdc->QueueOverlayPlane(OverlayPlane(pixmap->buffer(),
                                      plane_z_order,
                                      plane_transform,
                                      display_bounds,
                                      crop_rect));
  return true;
}

bool GbmSurfaceFactory::CanShowPrimaryPlaneAsOverlay() {
  return allow_surfaceless_;
}

DriWindowDelegate* GbmSurfaceFactory::GetOrCreateWindowDelegate(
    gfx::AcceleratedWidget widget) {
  if (!window_manager_->HasWindowDelegate(widget)) {
    scoped_ptr<DriWindowDelegate> delegate(
        new DriWindowDelegateImpl(widget, screen_manager_));
    delegate->Initialize();
    window_manager_->AddWindowDelegate(widget, delegate.Pass());
  }

  return window_manager_->GetWindowDelegate(widget);
}

}  // namespace ui
<commit_msg>ozone: gbm: Fix missing OVERRIDE<commit_after>// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "ui/ozone/platform/dri/gbm_surface_factory.h"

#include <gbm.h>

#include "base/command_line.h"
#include "base/files/file_path.h"
#include "third_party/khronos/EGL/egl.h"
#include "ui/ozone/platform/dri/dri_window_delegate_impl.h"
#include "ui/ozone/platform/dri/dri_window_manager.h"
#include "ui/ozone/platform/dri/gbm_buffer.h"
#include "ui/ozone/platform/dri/gbm_surface.h"
#include "ui/ozone/platform/dri/gbm_surfaceless.h"
#include "ui/ozone/platform/dri/screen_manager.h"
#include "ui/ozone/public/native_pixmap.h"
#include "ui/ozone/public/overlay_candidates_ozone.h"
#include "ui/ozone/public/ozone_switches.h"
#include "ui/ozone/public/surface_ozone_egl.h"

namespace ui {
namespace {

class SingleOverlay : public OverlayCandidatesOzone {
 public:
  SingleOverlay() {}
  virtual ~SingleOverlay() {}

  virtual void CheckOverlaySupport(
      OverlaySurfaceCandidateList* candidates) OVERRIDE {
    if (candidates->size() == 2) {
      OverlayCandidatesOzone::OverlaySurfaceCandidate* first =
          &(*candidates)[0];
      OverlayCandidatesOzone::OverlaySurfaceCandidate* second =
          &(*candidates)[1];
      OverlayCandidatesOzone::OverlaySurfaceCandidate* overlay;
      if (first->plane_z_order == 0) {
        overlay = second;
      } else if (second->plane_z_order == 0) {
        overlay = first;
      } else {
        NOTREACHED();
        return;
      }
      if (overlay->plane_z_order > 0 &&
          IsTransformSupported(overlay->transform)) {
        overlay->overlay_handled = true;
      }
    }
  }

 private:
  bool IsTransformSupported(gfx::OverlayTransform transform) {
    switch (transform) {
      case gfx::OVERLAY_TRANSFORM_NONE:
        return true;
      default:
        return false;
    }
  }

  DISALLOW_COPY_AND_ASSIGN(SingleOverlay);
};

}  // namespace

GbmSurfaceFactory::GbmSurfaceFactory(bool allow_surfaceless)
    : DriSurfaceFactory(NULL, NULL, NULL),
      device_(NULL),
      allow_surfaceless_(allow_surfaceless) {
}

GbmSurfaceFactory::~GbmSurfaceFactory() {}

void GbmSurfaceFactory::InitializeGpu(DriWrapper* dri,
                                      gbm_device* device,
                                      ScreenManager* screen_manager,
                                      DriWindowManager* window_manager) {
  drm_ = dri;
  device_ = device;
  screen_manager_ = screen_manager;
  window_manager_ = window_manager;
}

intptr_t GbmSurfaceFactory::GetNativeDisplay() {
  DCHECK(state_ == INITIALIZED);
  return reinterpret_cast<intptr_t>(device_);
}

const int32* GbmSurfaceFactory::GetEGLSurfaceProperties(
    const int32* desired_list) {
  static const int32 kConfigAttribs[] = {
    EGL_BUFFER_SIZE, 32,
    EGL_ALPHA_SIZE, 8,
    EGL_BLUE_SIZE, 8,
    EGL_GREEN_SIZE, 8,
    EGL_RED_SIZE, 8,
    EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
    EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
    EGL_NONE
  };

  return kConfigAttribs;
}

bool GbmSurfaceFactory::LoadEGLGLES2Bindings(
      AddGLLibraryCallback add_gl_library,
      SetGLGetProcAddressProcCallback set_gl_get_proc_address) {
  base::NativeLibraryLoadError error;
  base::NativeLibrary gles_library = base::LoadNativeLibrary(
      base::FilePath("libGLESv2.so.2"),
      &error);
  if (!gles_library) {
    LOG(WARNING) << "Failed to load GLES library: " << error.ToString();
    return false;
  }

  base::NativeLibrary egl_library = base::LoadNativeLibrary(
      base::FilePath("libEGL.so.1"),
      &error);
  if (!egl_library) {
    LOG(WARNING) << "Failed to load EGL library: " << error.ToString();
    base::UnloadNativeLibrary(gles_library);
    return false;
  }

  GLGetProcAddressProc get_proc_address =
      reinterpret_cast<GLGetProcAddressProc>(
          base::GetFunctionPointerFromNativeLibrary(
              egl_library, "eglGetProcAddress"));
  if (!get_proc_address) {
    LOG(ERROR) << "eglGetProcAddress not found.";
    base::UnloadNativeLibrary(egl_library);
    base::UnloadNativeLibrary(gles_library);
    return false;
  }

  set_gl_get_proc_address.Run(get_proc_address);
  add_gl_library.Run(egl_library);
  add_gl_library.Run(gles_library);

  return true;
}

scoped_ptr<SurfaceOzoneEGL> GbmSurfaceFactory::CreateEGLSurfaceForWidget(
    gfx::AcceleratedWidget widget) {
  DCHECK(state_ == INITIALIZED);

  DriWindowDelegate* delegate = GetOrCreateWindowDelegate(widget);

  ResetCursor(widget);

  scoped_ptr<GbmSurface> surface(new GbmSurface(delegate, device_, drm_));
  if (!surface->Initialize())
    return scoped_ptr<SurfaceOzoneEGL>();

  return surface.PassAs<SurfaceOzoneEGL>();
}

scoped_ptr<SurfaceOzoneEGL>
GbmSurfaceFactory::CreateSurfacelessEGLSurfaceForWidget(
    gfx::AcceleratedWidget widget) {
  if (!allow_surfaceless_)
    return scoped_ptr<SurfaceOzoneEGL>();

  DriWindowDelegate* delegate = GetOrCreateWindowDelegate(widget);
  return scoped_ptr<SurfaceOzoneEGL>(new GbmSurfaceless(delegate));
}

scoped_refptr<ui::NativePixmap> GbmSurfaceFactory::CreateNativePixmap(
    gfx::Size size,
    BufferFormat format) {
  scoped_refptr<GbmBuffer> buffer = GbmBuffer::CreateBuffer(
      drm_, device_, format, size, true);
  if (!buffer)
    return NULL;

  return scoped_refptr<GbmPixmap>(new GbmPixmap(buffer));
}

OverlayCandidatesOzone* GbmSurfaceFactory::GetOverlayCandidates(
    gfx::AcceleratedWidget w) {
  if (CommandLine::ForCurrentProcess()->HasSwitch(
          switches::kOzoneTestSingleOverlaySupport))
    return new SingleOverlay();
  return NULL;
}

bool GbmSurfaceFactory::ScheduleOverlayPlane(
    gfx::AcceleratedWidget widget,
    int plane_z_order,
    gfx::OverlayTransform plane_transform,
    scoped_refptr<NativePixmap> buffer,
    const gfx::Rect& display_bounds,
    const gfx::RectF& crop_rect) {
  scoped_refptr<GbmPixmap> pixmap = static_cast<GbmPixmap*>(buffer.get());
  if (!pixmap) {
    LOG(ERROR) << "ScheduleOverlayPlane passed NULL buffer.";
    return false;
  }
  HardwareDisplayController* hdc =
      window_manager_->GetWindowDelegate(widget)->GetController();
  if (!hdc)
    return true;

  hdc->QueueOverlayPlane(OverlayPlane(pixmap->buffer(),
                                      plane_z_order,
                                      plane_transform,
                                      display_bounds,
                                      crop_rect));
  return true;
}

bool GbmSurfaceFactory::CanShowPrimaryPlaneAsOverlay() {
  return allow_surfaceless_;
}

DriWindowDelegate* GbmSurfaceFactory::GetOrCreateWindowDelegate(
    gfx::AcceleratedWidget widget) {
  if (!window_manager_->HasWindowDelegate(widget)) {
    scoped_ptr<DriWindowDelegate> delegate(
        new DriWindowDelegateImpl(widget, screen_manager_));
    delegate->Initialize();
    window_manager_->AddWindowDelegate(widget, delegate.Pass());
  }

  return window_manager_->GetWindowDelegate(widget);
}

}  // namespace ui
<|endoftext|>


<commit_before>/* Copyright (C) 2006 The cairomm Development Team
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * 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
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
 * 02110-1301, USA.
 */

#include <cairomm/scaledfont.h>
#include <cairomm/fontface.h>
#include <cairomm/private.h>  // for check_status_and_throw_exception

namespace Cairo
{

ScaledFont::ScaledFont(cobject* cobj, bool has_reference)
: m_cobject(0)
{
  if(has_reference)
    m_cobject = cobj;
  else
    m_cobject = cairo_scaled_font_reference(cobj);
}

ScaledFont::ScaledFont(const RefPtr<FontFace>& font_face, const cairo_matrix_t& font_matrix,
                       const cairo_matrix_t& ctm, const FontOptions& options)
: m_cobject(0)
{
  m_cobject =
    cairo_scaled_font_create(font_face->cobj(),
                             &font_matrix,
                             &ctm,
                             options.cobj());
  check_object_status_and_throw_exception(*this);
}

ScaledFont::~ScaledFont()
{
  if (cobj())
    cairo_scaled_font_destroy(cobj());
}

RefPtr<ScaledFont> ScaledFont::create(const RefPtr<FontFace>& font_face, const Matrix& font_matrix,
    const Matrix& ctm, const FontOptions& options)
{
  return RefPtr<ScaledFont>(new ScaledFont(font_face, font_matrix, ctm, options));
}

RefPtr<ScaledFont> ScaledFont::create(const RefPtr<FontFace>& font_face, const cairo_matrix_t& font_matrix,
    const cairo_matrix_t& ctm, const FontOptions& options)
{
  return RefPtr<ScaledFont>(new ScaledFont(font_face, font_matrix, ctm, options));
}

void ScaledFont::extents(FontExtents& extents) const
{
  cairo_scaled_font_extents(m_cobject, static_cast<cairo_font_extents_t*>(&extents));
  check_object_status_and_throw_exception(*this);
}

void ScaledFont::text_extents(const std::string& utf8, TextExtents& extents) const
{
  cairo_scaled_font_text_extents(m_cobject, utf8.c_str(), static_cast<cairo_text_extents_t*>(&extents));
  check_object_status_and_throw_exception(*this);
}

void ScaledFont::glyph_extents(const std::vector<Glyph>& glyphs, TextExtents& extents)
{
  // copy the data from the vector to a standard C array.  I don't believe
  // this will be a frequently used function so I think the performance hit is
  // more than offset by the increased flexibility of the STL interface.

  // Use new to allocate memory as MSCV complains about non-const array size with
  // Glyph glyph_array[glyphs.size()]
  Glyph* glyph_array= new Glyph[glyphs.size()];
  std::copy(glyphs.begin(), glyphs.end(), glyph_array);

  cairo_scaled_font_glyph_extents(m_cobject, glyph_array, glyphs.size(),
      static_cast<cairo_text_extents_t*>(&extents));
  check_object_status_and_throw_exception(*this);
  delete[] glyph_array;
}

RefPtr<FontFace> ScaledFont::get_font_face() const
{
  cairo_font_face_t* face = cairo_scaled_font_get_font_face(m_cobject);
  check_object_status_and_throw_exception(*this);
  return RefPtr<FontFace>(new FontFace(face, false /* returned face doesn't have a reference */));
}

void ScaledFont::get_font_options(FontOptions& options) const
{
  cairo_scaled_font_get_font_options(m_cobject, options.cobj());
  check_object_status_and_throw_exception(*this);
}

void ScaledFont::get_font_matrix(Matrix& font_matrix) const
{
  cairo_scaled_font_get_font_matrix(m_cobject,
                                    &font_matrix);
  check_object_status_and_throw_exception(*this);
}

void ScaledFont::get_font_matrix(cairo_matrix_t& font_matrix) const
{
  cairo_scaled_font_get_font_matrix(m_cobject,
                                    &font_matrix);
  check_object_status_and_throw_exception(*this);
}

void ScaledFont::get_ctm(Matrix& ctm) const
{
  cairo_scaled_font_get_ctm(m_cobject, &ctm);
  check_object_status_and_throw_exception(*this);
}

void ScaledFont::get_ctm(cairo_matrix_t& ctm) const
{
  cairo_scaled_font_get_ctm(m_cobject, &ctm);
  check_object_status_and_throw_exception(*this);
}

FontType ScaledFont::get_type() const
{
  cairo_font_type_t font_type = cairo_scaled_font_get_type(m_cobject);
  check_object_status_and_throw_exception(*this);
  return static_cast<FontType>(font_type);
}

void
ScaledFont::text_to_glyphs (double x,
                            double y,
                            const std::string& utf8,
                            std::vector<Glyph>& glyphs,
                            std::vector<TextCluster>& clusters,
                            TextClusterFlags& cluster_flags)
{
  int num_glyphs = -1;
  int num_clusters = -1;
  cairo_glyph_t* c_glyphs = 0;
  cairo_text_cluster_t* c_clusters = 0;
  cairo_status_t status = cairo_scaled_font_text_to_glyphs(cobj(), x, y,
                                                           utf8.c_str(),
                                                           utf8.size(),
                                                           &c_glyphs,
                                                           &num_glyphs,
                                                           &c_clusters,
                                                           &num_clusters,
                                                           reinterpret_cast<cairo_text_cluster_flags_t*>(&cluster_flags));
  if (num_glyphs > 0 && c_glyphs) {
    glyphs.assign(static_cast<Glyph*>(c_glyphs),
                  static_cast<Glyph*>(c_glyphs + num_glyphs));
    cairo_glyph_free(c_glyphs);
  }
  if (num_clusters > 0 && c_clusters) {
    clusters.assign(static_cast<TextCluster*>(c_clusters),
                    static_cast<TextCluster*>(c_clusters + num_clusters));
    cairo_text_cluster_free(c_clusters);
  }
  check_status_and_throw_exception(status);
  check_object_status_and_throw_exception(*this);
}

void ScaledFont::get_scale_matrix(Matrix& scale_matrix) const
{
  cairo_scaled_font_get_scale_matrix(const_cast<cairo_scaled_font_t*>(cobj()), &scale_matrix);
  check_object_status_and_throw_exception(*this);
}

#ifdef CAIRO_HAS_FT_FONT
FtScaledFont::FtScaledFont(const RefPtr<FtFontFace>& font_face, const Matrix& font_matrix,
                           const Matrix& ctm, const FontOptions& options) :
  ScaledFont(font_face, font_matrix, ctm, options)
{
  check_object_status_and_throw_exception(*this);
}

RefPtr<FtScaledFont>
FtScaledFont::create(const RefPtr<FtFontFace>& font_face,
                     const Matrix& font_matrix, const Matrix& ctm,
                     const FontOptions& options)
{
  return RefPtr<FtScaledFont>(new FtScaledFont(font_face, font_matrix, ctm, options));
}

FT_Face FtScaledFont::lock_face()
{
  FT_Face face = cairo_ft_scaled_font_lock_face(cobj());
  check_object_status_and_throw_exception(*this);
  return face;
}

void FtScaledFont::unlock_face()
{
  cairo_ft_scaled_font_unlock_face(cobj());
  check_object_status_and_throw_exception(*this);
}
#endif // CAIRO_HAS_FT_FONT

}   // namespace Cairo
// vim: ts=2 sw=2 et
<commit_msg>ScaledFont: Add the missing get_extents() method implementation.<commit_after>/* Copyright (C) 2006 The cairomm Development Team
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * 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
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
 * 02110-1301, USA.
 */

#include <cairomm/scaledfont.h>
#include <cairomm/fontface.h>
#include <cairomm/private.h>  // for check_status_and_throw_exception

namespace Cairo
{

ScaledFont::ScaledFont(cobject* cobj, bool has_reference)
: m_cobject(0)
{
  if(has_reference)
    m_cobject = cobj;
  else
    m_cobject = cairo_scaled_font_reference(cobj);
}

ScaledFont::ScaledFont(const RefPtr<FontFace>& font_face, const cairo_matrix_t& font_matrix,
                       const cairo_matrix_t& ctm, const FontOptions& options)
: m_cobject(0)
{
  m_cobject =
    cairo_scaled_font_create(font_face->cobj(),
                             &font_matrix,
                             &ctm,
                             options.cobj());
  check_object_status_and_throw_exception(*this);
}

ScaledFont::~ScaledFont()
{
  if (cobj())
    cairo_scaled_font_destroy(cobj());
}

RefPtr<ScaledFont> ScaledFont::create(const RefPtr<FontFace>& font_face, const Matrix& font_matrix,
    const Matrix& ctm, const FontOptions& options)
{
  return RefPtr<ScaledFont>(new ScaledFont(font_face, font_matrix, ctm, options));
}

RefPtr<ScaledFont> ScaledFont::create(const RefPtr<FontFace>& font_face, const cairo_matrix_t& font_matrix,
    const cairo_matrix_t& ctm, const FontOptions& options)
{
  return RefPtr<ScaledFont>(new ScaledFont(font_face, font_matrix, ctm, options));
}

void ScaledFont::extents(FontExtents& extents) const
{
  get_extents(extents);
}

void ScaledFont::get_extents(FontExtents& extents) const
{
  cairo_scaled_font_extents(m_cobject, static_cast<cairo_font_extents_t*>(&extents));
  check_object_status_and_throw_exception(*this);
}

void ScaledFont::text_extents(const std::string& utf8, TextExtents& extents) const
{
  cairo_scaled_font_text_extents(m_cobject, utf8.c_str(), static_cast<cairo_text_extents_t*>(&extents));
  check_object_status_and_throw_exception(*this);
}

void ScaledFont::glyph_extents(const std::vector<Glyph>& glyphs, TextExtents& extents)
{
  // copy the data from the vector to a standard C array.  I don't believe
  // this will be a frequently used function so I think the performance hit is
  // more than offset by the increased flexibility of the STL interface.

  // Use new to allocate memory as MSCV complains about non-const array size with
  // Glyph glyph_array[glyphs.size()]
  Glyph* glyph_array= new Glyph[glyphs.size()];
  std::copy(glyphs.begin(), glyphs.end(), glyph_array);

  cairo_scaled_font_glyph_extents(m_cobject, glyph_array, glyphs.size(),
      static_cast<cairo_text_extents_t*>(&extents));
  check_object_status_and_throw_exception(*this);
  delete[] glyph_array;
}

RefPtr<FontFace> ScaledFont::get_font_face() const
{
  cairo_font_face_t* face = cairo_scaled_font_get_font_face(m_cobject);
  check_object_status_and_throw_exception(*this);
  return RefPtr<FontFace>(new FontFace(face, false /* returned face doesn't have a reference */));
}

void ScaledFont::get_font_options(FontOptions& options) const
{
  cairo_scaled_font_get_font_options(m_cobject, options.cobj());
  check_object_status_and_throw_exception(*this);
}

void ScaledFont::get_font_matrix(Matrix& font_matrix) const
{
  cairo_scaled_font_get_font_matrix(m_cobject,
                                    &font_matrix);
  check_object_status_and_throw_exception(*this);
}

void ScaledFont::get_font_matrix(cairo_matrix_t& font_matrix) const
{
  cairo_scaled_font_get_font_matrix(m_cobject,
                                    &font_matrix);
  check_object_status_and_throw_exception(*this);
}

void ScaledFont::get_ctm(Matrix& ctm) const
{
  cairo_scaled_font_get_ctm(m_cobject, &ctm);
  check_object_status_and_throw_exception(*this);
}

void ScaledFont::get_ctm(cairo_matrix_t& ctm) const
{
  cairo_scaled_font_get_ctm(m_cobject, &ctm);
  check_object_status_and_throw_exception(*this);
}

FontType ScaledFont::get_type() const
{
  cairo_font_type_t font_type = cairo_scaled_font_get_type(m_cobject);
  check_object_status_and_throw_exception(*this);
  return static_cast<FontType>(font_type);
}

void
ScaledFont::text_to_glyphs (double x,
                            double y,
                            const std::string& utf8,
                            std::vector<Glyph>& glyphs,
                            std::vector<TextCluster>& clusters,
                            TextClusterFlags& cluster_flags)
{
  int num_glyphs = -1;
  int num_clusters = -1;
  cairo_glyph_t* c_glyphs = 0;
  cairo_text_cluster_t* c_clusters = 0;
  cairo_status_t status = cairo_scaled_font_text_to_glyphs(cobj(), x, y,
                                                           utf8.c_str(),
                                                           utf8.size(),
                                                           &c_glyphs,
                                                           &num_glyphs,
                                                           &c_clusters,
                                                           &num_clusters,
                                                           reinterpret_cast<cairo_text_cluster_flags_t*>(&cluster_flags));
  if (num_glyphs > 0 && c_glyphs) {
    glyphs.assign(static_cast<Glyph*>(c_glyphs),
                  static_cast<Glyph*>(c_glyphs + num_glyphs));
    cairo_glyph_free(c_glyphs);
  }
  if (num_clusters > 0 && c_clusters) {
    clusters.assign(static_cast<TextCluster*>(c_clusters),
                    static_cast<TextCluster*>(c_clusters + num_clusters));
    cairo_text_cluster_free(c_clusters);
  }
  check_status_and_throw_exception(status);
  check_object_status_and_throw_exception(*this);
}

void ScaledFont::get_scale_matrix(Matrix& scale_matrix) const
{
  cairo_scaled_font_get_scale_matrix(const_cast<cairo_scaled_font_t*>(cobj()), &scale_matrix);
  check_object_status_and_throw_exception(*this);
}

#ifdef CAIRO_HAS_FT_FONT
FtScaledFont::FtScaledFont(const RefPtr<FtFontFace>& font_face, const Matrix& font_matrix,
                           const Matrix& ctm, const FontOptions& options) :
  ScaledFont(font_face, font_matrix, ctm, options)
{
  check_object_status_and_throw_exception(*this);
}

RefPtr<FtScaledFont>
FtScaledFont::create(const RefPtr<FtFontFace>& font_face,
                     const Matrix& font_matrix, const Matrix& ctm,
                     const FontOptions& options)
{
  return RefPtr<FtScaledFont>(new FtScaledFont(font_face, font_matrix, ctm, options));
}

FT_Face FtScaledFont::lock_face()
{
  FT_Face face = cairo_ft_scaled_font_lock_face(cobj());
  check_object_status_and_throw_exception(*this);
  return face;
}

void FtScaledFont::unlock_face()
{
  cairo_ft_scaled_font_unlock_face(cobj());
  check_object_status_and_throw_exception(*this);
}
#endif // CAIRO_HAS_FT_FONT

}   // namespace Cairo
// vim: ts=2 sw=2 et
<|endoftext|>


<commit_before>#include "stdsneezy.h"
#include "database.h"
#include "session.cgi.h"

#include <map>
#include "sstring.h"

#include "cgicc/Cgicc.h"
#include "cgicc/HTTPHTMLHeader.h"
#include "cgicc/HTMLClasses.h"
#include <cgicc/HTTPCookie.h>
#include <cgicc/CgiEnvironment.h>
#include <cgicc/HTTPRedirectHeader.h>

#include <sys/types.h>
#include <md5.h>

using namespace cgicc;

void sendJavaScript();

void sendLogin();
void sendLoginCheck(Cgicc cgi, TSession);
void sendPickPlayer(int);
void sendMessageList(Cgicc cgi, int);

void deleteMessage(int, int);

int main(int argc, char **argv)
{
  // trick the db code into using the prod database
  gamePort = PROD_GAMEPORT;
  toggleInfo.loadToggles();

  Cgicc cgi;
  form_iterator state_form=cgi.getElement("state");
  TSession session(cgi, "mudmail");

  if(!session.isValid()){
    if(state_form == cgi.getElements().end() ||
       **state_form != "logincheck"){
      sendLogin();
      return 0;
    } else {
      sendLoginCheck(cgi, session);
      return 0;
    }
  } else {
    if(state_form == cgi.getElements().end() || **state_form == "main"){
      sendPickPlayer(session.getAccountID());
      return 0;
    } else if(**state_form == "listmessages"){
      sendMessageList(cgi, session.getAccountID());
      return 0;
    } else if(**state_form == "logout"){
      session.logout();
      cout << HTTPRedirectHeader("mudmail.cgi").setCookie(session.getCookie());
      cout << endl;
      return 0;
    } else if(**state_form == "messageaction"){
      form_iterator delete_form=cgi.getElement("delete");

      if(delete_form != cgi.getElements().end()){
	deleteMessage(convertTo<int>(**delete_form), session.getAccountID());
	sendMessageList(cgi, session.getAccountID());
      }
      return 0;
    }

    cout << HTTPHTMLHeader() << endl;
    cout << html() << head() << title("Mudmail") << endl;
    cout << head() << body() << endl;
    cout << "Fell through state switch.

" << endl;
    cout << body() << endl;
    cout << html() << endl;

    return 0;
  }

  // shouldn't get here
  cout << HTTPHTMLHeader() << endl;
  cout << html() << head() << title("Mudmail") << endl;
  cout << head() << body() << endl;
  cout << "This is bad.

" << endl;
  cout << body() << endl;
  cout << html() << endl;

}

void deleteMessage(int mail_id, int account_id)
{
  TDatabase db(DB_SNEEZY);

  // make sure they aren't trying to delete someone elses messages
  db.query("delete from mail where mail.mailid=%i and mail.mailto=player.name and player.account_id=%i", mail_id, account_id);
}

void sendMessageList(Cgicc cgi, int account_id)
{
  int player_id=convertTo<int>(**(cgi.getElement("player")));
  TDatabase db(DB_SNEEZY);

  cout << HTTPHTMLHeader() << endl;
  cout << html() << head() << title("Mudmail") << endl;
  cout << head() << body() << endl;

  db.query("select m.mailid, m.mailfrom, m.timesent, m.content from mail m, player p where m.mailto=p.name and p.id=%i order by m.timesent desc", player_id);

  cout << "go back
" << endl;
  cout << "
" << endl;

  cout << "<form method=post action=mudmail.cgi>" << endl;
  cout << "<input type=hidden name=player value=" << player_id << endl;
  cout << "<input type=hidden name=state value=messageaction>" << endl;

  while(db.fetchRow()){
    cout << "
";
    cout << "
From:	" << db["mailfrom"];
    cout << "
" << endl;
    cout << "
Date:	" << db["timesent"];
    cout << "
" << endl;
    cout << "

" << db["content"];
    cout << "

" << endl;
    cout << "
";
    cout << "<button name=delete value=" << db["mailid"] << " type=submit>";
    cout << "delete</button>
";
  }

  cout << "
" << endl;
  cout << "</form>" << endl;

  cout << body() << endl;
  cout << html() << endl;
}

void sendLoginCheck(Cgicc cgi, TSession session)
{
  // validate, create session cookie + db entry, redirect to main
  sstring name=**(cgi.getElement("account"));
  sstring passwd=**(cgi.getElement("passwd"));
  form_iterator autologin=cgi.getElement("autologin");

  if(!session.checkPasswd(name, passwd)){
    cout << HTTPHTMLHeader() << endl;
    cout << html() << head() << title("Mudmail") << endl;
    cout << head() << body() << endl;
    cout << "Password incorrect or account not found.

" << endl;
    cout << body() << endl;
    cout << html() << endl;
    return;
  }

  if(autologin == cgi.getElements().end()){
    session.createSession();
  } else {
    // log them in for a year or so
    session.createSession(60*60*24*365);
  }

  cout << HTTPRedirectHeader("mudmail.cgi").setCookie(session.getCookie());
  cout << endl;
  cout << html() << head() << title("Mudmail") << endl;
  cout << head() << body() << endl;
  cout << "Good job, you logged in.

" << endl;
  cout << body() << endl;
  cout << html() << endl;
}

void sendLogin()
{
  cout << HTTPHTMLHeader() << endl;
  cout << html() << head() << title("Mudmail") << endl;
  cout << head() << body() << endl;

  cout << "<form action=\"mudmail.cgi\" method=post>" << endl;
  cout << "
" << endl;
  cout << "
Account	" << endl;
  cout << "<input type=text name=account>
" << endl;
  cout << "
Password	" << endl;
  cout << "<input type=password name=passwd>
" << endl;
  cout << "
<input type=checkbox name=autologin>	" << endl;
  cout << "Log me on automatically each visit.
" << endl;
  cout << "
<input type=submit value=Login>
" <<endl;
  cout << "
" << endl;
  cout << "<input type=hidden name=state value=logincheck>" << endl;
  cout << "</form>" << endl;

  cout << body() << endl;
  cout << html() << endl;
}

void sendPickPlayer(int account_id)
{
  TDatabase db(DB_SNEEZY);

  cout << HTTPHTMLHeader() << endl;
  cout << html() << head() << title("Mudmail") << endl;
  sendJavaScript();
  cout << head() << body() << endl;
  cout << "logout
" << endl;

  // get a list of players in this account
  db.query("select p.id, p.name, count(m.*) as count from player p left outer join mail m on (p.name=m.mailto) where account_id=%i group by p.id, p.name order by p.name",
	   account_id);

  if(!db.fetchRow()){
    cout << "No players were found in this account." << endl;
    return;
  }

  cout << "<form action=\"mudmail.cgi\" method=post name=pickplayer>" << endl;
  cout << "<input type=hidden name=player>" << endl;
  cout << "<input type=hidden name=state value=listmessages>" << endl;
  cout << "
" << endl;
  cout << "
Player	# of Letters
";

  do {
    cout << "
" << endl;
    cout << "<a href=javascript:pickplayer('" << db["id"] << "')>";
    cout << db["name"] << "	" << endl;
    cout << db["count"] << "
";
  } while(db.fetchRow());

  cout << "</form>" << endl;

  cout << body() << endl;
  cout << html() << endl;
}

void sendJavaScript()
{
  cout << "" << endl;
}
<commit_msg>added escapes for &, < and > in mail display<commit_after>#include "stdsneezy.h"
#include "database.h"
#include "session.cgi.h"

#include <map>
#include "sstring.h"

#include "cgicc/Cgicc.h"
#include "cgicc/HTTPHTMLHeader.h"
#include "cgicc/HTMLClasses.h"
#include <cgicc/HTTPCookie.h>
#include <cgicc/CgiEnvironment.h>
#include <cgicc/HTTPRedirectHeader.h>

#include <sys/types.h>
#include <md5.h>

using namespace cgicc;

void sendJavaScript();

void sendLogin();
void sendLoginCheck(Cgicc cgi, TSession);
void sendPickPlayer(int);
void sendMessageList(Cgicc cgi, int);

void deleteMessage(int, int);

int main(int argc, char **argv)
{
  // trick the db code into using the prod database
  gamePort = PROD_GAMEPORT;
  toggleInfo.loadToggles();

  Cgicc cgi;
  form_iterator state_form=cgi.getElement("state");
  TSession session(cgi, "mudmail");

  if(!session.isValid()){
    if(state_form == cgi.getElements().end() ||
       **state_form != "logincheck"){
      sendLogin();
      return 0;
    } else {
      sendLoginCheck(cgi, session);
      return 0;
    }
  } else {
    if(state_form == cgi.getElements().end() || **state_form == "main"){
      sendPickPlayer(session.getAccountID());
      return 0;
    } else if(**state_form == "listmessages"){
      sendMessageList(cgi, session.getAccountID());
      return 0;
    } else if(**state_form == "logout"){
      session.logout();
      cout << HTTPRedirectHeader("mudmail.cgi").setCookie(session.getCookie());
      cout << endl;
      return 0;
    } else if(**state_form == "messageaction"){
      form_iterator delete_form=cgi.getElement("delete");

      if(delete_form != cgi.getElements().end()){
	deleteMessage(convertTo<int>(**delete_form), session.getAccountID());
	sendMessageList(cgi, session.getAccountID());
      }
      return 0;
    }

    cout << HTTPHTMLHeader() << endl;
    cout << html() << head() << title("Mudmail") << endl;
    cout << head() << body() << endl;
    cout << "Fell through state switch.

" << endl;
    cout << body() << endl;
    cout << html() << endl;

    return 0;
  }

  // shouldn't get here
  cout << HTTPHTMLHeader() << endl;
  cout << html() << head() << title("Mudmail") << endl;
  cout << head() << body() << endl;
  cout << "This is bad.

" << endl;
  cout << body() << endl;
  cout << html() << endl;

}

void deleteMessage(int mail_id, int account_id)
{
  TDatabase db(DB_SNEEZY);

  // make sure they aren't trying to delete someone elses messages
  db.query("delete from mail where mail.mailid=%i and mail.mailto=player.name and player.account_id=%i", mail_id, account_id);
}

void sendMessageList(Cgicc cgi, int account_id)
{
  int player_id=convertTo<int>(**(cgi.getElement("player")));
  TDatabase db(DB_SNEEZY);
  sstring content;

  cout << HTTPHTMLHeader() << endl;
  cout << html() << head() << title("Mudmail") << endl;
  cout << head() << body() << endl;

  db.query("select m.mailid, m.mailfrom, m.timesent, m.content from mail m, player p where m.mailto=p.name and p.id=%i order by m.timesent desc", player_id);

  cout << "go back
" << endl;
  cout << "
" << endl;

  cout << "<form method=post action=mudmail.cgi>" << endl;
  cout << "<input type=hidden name=player value=" << player_id << endl;
  cout << "<input type=hidden name=state value=messageaction>" << endl;

  while(db.fetchRow()){
    cout << "
";
    cout << "
From:	" << db["mailfrom"];
    cout << "
" << endl;
    cout << "
Date:	" << db["timesent"];
    cout << "
" << endl;
    cout << "

" << endl;

    content=db["content"];
    unsigned int loc;
    for(loc=content.find("&");loc!=sstring::npos;loc=content.find("&"))
      content.replace(loc, 1, "&");
    for(loc=content.find("<");loc!=sstring::npos;loc=content.find("<"))
      content.replace(loc, 1, "<");
    for(loc=content.find(">");loc!=sstring::npos;loc=content.find(">"))
      content.replace(loc, 1, ">");

    cout << content;

    cout << "

" << endl;
    cout << "
";
    cout << "<button name=delete value=" << db["mailid"] << " type=submit>";
    cout << "delete</button>
";
  }

  cout << "
" << endl;
  cout << "</form>" << endl;

  cout << body() << endl;
  cout << html() << endl;
}

void sendLoginCheck(Cgicc cgi, TSession session)
{
  // validate, create session cookie + db entry, redirect to main
  sstring name=**(cgi.getElement("account"));
  sstring passwd=**(cgi.getElement("passwd"));
  form_iterator autologin=cgi.getElement("autologin");

  if(!session.checkPasswd(name, passwd)){
    cout << HTTPHTMLHeader() << endl;
    cout << html() << head() << title("Mudmail") << endl;
    cout << head() << body() << endl;
    cout << "Password incorrect or account not found.

" << endl;
    cout << body() << endl;
    cout << html() << endl;
    return;
  }

  if(autologin == cgi.getElements().end()){
    session.createSession();
  } else {
    // log them in for a year or so
    session.createSession(60*60*24*365);
  }

  cout << HTTPRedirectHeader("mudmail.cgi").setCookie(session.getCookie());
  cout << endl;
  cout << html() << head() << title("Mudmail") << endl;
  cout << head() << body() << endl;
  cout << "Good job, you logged in.

" << endl;
  cout << body() << endl;
  cout << html() << endl;
}

void sendLogin()
{
  cout << HTTPHTMLHeader() << endl;
  cout << html() << head() << title("Mudmail") << endl;
  cout << head() << body() << endl;

  cout << "<form action=\"mudmail.cgi\" method=post>" << endl;
  cout << "
" << endl;
  cout << "
Account	" << endl;
  cout << "<input type=text name=account>
" << endl;
  cout << "
Password	" << endl;
  cout << "<input type=password name=passwd>
" << endl;
  cout << "
<input type=checkbox name=autologin>	" << endl;
  cout << "Log me on automatically each visit.
" << endl;
  cout << "
<input type=submit value=Login>
" <<endl;
  cout << "
" << endl;
  cout << "<input type=hidden name=state value=logincheck>" << endl;
  cout << "</form>" << endl;

  cout << body() << endl;
  cout << html() << endl;
}

void sendPickPlayer(int account_id)
{
  TDatabase db(DB_SNEEZY);

  cout << HTTPHTMLHeader() << endl;
  cout << html() << head() << title("Mudmail") << endl;
  sendJavaScript();
  cout << head() << body() << endl;
  cout << "logout
" << endl;

  // get a list of players in this account
  db.query("select p.id, p.name, count(m.*) as count from player p left outer join mail m on (p.name=m.mailto) where account_id=%i group by p.id, p.name order by p.name",
	   account_id);

  if(!db.fetchRow()){
    cout << "No players were found in this account." << endl;
    return;
  }

  cout << "<form action=\"mudmail.cgi\" method=post name=pickplayer>" << endl;
  cout << "<input type=hidden name=player>" << endl;
  cout << "<input type=hidden name=state value=listmessages>" << endl;
  cout << "
" << endl;
  cout << "
Player	# of Letters
";

  do {
    cout << "
" << endl;
    cout << "<a href=javascript:pickplayer('" << db["id"] << "')>";
    cout << db["name"] << "	" << endl;
    cout << db["count"] << "
";
  } while(db.fetchRow());

  cout << "</form>" << endl;

  cout << body() << endl;
  cout << html() << endl;
}

void sendJavaScript()
{
  cout << "" << endl;
}
<|endoftext|>


<commit_before>/*=========================================================================

  Library   : Image Registration Toolkit (IRTK)
  Module    : $Id$
  Copyright : Imperial College, Department of Computing
              Visual Information Processing (VIP), 2008 onwards
  Date      : $Date$
  Version   : $Revision$
  Changes   : $Author$

=========================================================================*/

#include <irtkRegistration.h>

#include <irtkHomogeneousTransformationIterator.h>

#include <irtkMultiThreadedImageRigidRegistration.h>

void irtkImageRigidRegistration::GuessParameter()
{
  int i;
  double xsize, ysize, zsize;

  if ((_target == NULL) || (_source == NULL)) {
    cerr << "irtkImageRigidRegistration::GuessParameter: Target and source image not found" << endl;
    exit(1);
  }

  // Default parameters for registration
  _NumberOfLevels     = 3;
  _NumberOfBins       = 64;

  // Default parameters for optimization
  _SimilarityMeasure  = NMI;
  _OptimizationMethod = GradientDescent;
  _Epsilon            = 0.0001;

  // Read target pixel size
  _target->GetPixelSize(&xsize, &ysize, &zsize);

  // Default target parameters
  _TargetBlurring[0]      = GuessResolution(xsize, ysize, zsize) / 2.0;
  _TargetResolution[0][0] = GuessResolution(xsize, ysize, zsize);
  _TargetResolution[0][1] = GuessResolution(xsize, ysize, zsize);
  _TargetResolution[0][2] = GuessResolution(xsize, ysize, zsize);

  for (i = 1; i < _NumberOfLevels; i++) {
    _TargetBlurring[i]      = _TargetBlurring[i-1] * 2;
    _TargetResolution[i][0] = _TargetResolution[i-1][0] * 2;
    _TargetResolution[i][1] = _TargetResolution[i-1][1] * 2;
    _TargetResolution[i][2] = _TargetResolution[i-1][2] * 2;
  }

  // Read source pixel size
  _source->GetPixelSize(&xsize, &ysize, &zsize);

  // Default source parameters
  _SourceBlurring[0]      = GuessResolution(xsize, ysize, zsize) / 2.0;
  _SourceResolution[0][0] = GuessResolution(xsize, ysize, zsize);
  _SourceResolution[0][1] = GuessResolution(xsize, ysize, zsize);
  _SourceResolution[0][2] = GuessResolution(xsize, ysize, zsize);

  for (i = 1; i < _NumberOfLevels; i++) {
    _SourceBlurring[i]      = _SourceBlurring[i-1] * 2;
    _SourceResolution[i][0] = _SourceResolution[i-1][0] * 2;
    _SourceResolution[i][1] = _SourceResolution[i-1][1] * 2;
    _SourceResolution[i][2] = _SourceResolution[i-1][2] * 2;
  }

  // Remaining parameters
  for (i = 0; i < _NumberOfLevels; i++) {
    _NumberOfIterations[i] = 20;
    _NumberOfSteps[i]      = 4;
    _LengthOfSteps[i]      = 2 * pow(2.0, i);
  }

  // Try to guess padding by looking at voxel values in all eight corners of the volume:
  // If all values are the same we assume that they correspond to the padding value
  _TargetPadding = MIN_GREY;
  if ((_target->Get(_target->GetX()-1, 0, 0)                                 == _target->Get(0, 0, 0)) &&
      (_target->Get(0, _target->GetY()-1, 0)                                 == _target->Get(0, 0, 0)) &&
      (_target->Get(0, 0, _target->GetZ()-1)                                 == _target->Get(0, 0, 0)) &&
      (_target->Get(_target->GetX()-1, _target->GetY()-1, 0)                 == _target->Get(0, 0, 0)) &&
      (_target->Get(0, _target->GetY()-1, _target->GetZ()-1)                 == _target->Get(0, 0, 0)) &&
      (_target->Get(_target->GetX()-1, 0, _target->GetZ()-1)                 == _target->Get(0, 0, 0)) &&
      (_target->Get(_target->GetX()-1, _target->GetY()-1, _target->GetZ()-1) == _target->Get(0, 0, 0))) {
    _TargetPadding = _target->Get(0, 0, 0);
  }
}

void irtkImageRigidRegistration::Initialize()
{
  // Call base class
  this->irtkImageRegistration::Initialize();

  // Invert rigid transformation (to be backwards compatible)
  //((irtkRigidTransformation *)_transformation)->Invert();
  //((irtkRigidTransformation *)_transformation)->UpdateParameter();
}

void irtkImageRigidRegistration::Finalize()
{
  // Call base class
  this->irtkImageRegistration::Finalize();

  // Invert rigid transformation (to be backwards compatible)
  //((irtkRigidTransformation *)_transformation)->Invert();
  //((irtkRigidTransformation *)_transformation)->UpdateParameter();
}

double irtkImageRigidRegistration::Evaluate()
{

#ifndef HAS_TBB
  int i, j, k, t;
#endif

  // Pointer to reference data
  irtkGreyPixel *ptr2target;

  // Print debugging information
  this->Debug("irtkImageRigidRegistration::Evaluate");

  // Invert transformation
  //((irtkRigidTransformation *)_transformation)->Invert();

  // Create iterator
  irtkHomogeneousTransformationIterator
  iterator((irtkHomogeneousTransformation *)_transformation);

  // Initialize metric
  _metric->Reset();

  // Pointer to voxels in target image
  ptr2target = _target->GetPointerToVoxels();

#ifdef HAS_TBB
  irtkMultiThreadedImageRigidRegistrationEvaluate evaluate(this);
  parallel_reduce(blocked_range<int>(0, _target->GetZ(), 20), evaluate);
#else

  for (t = 0; t < _target->GetT(); t++) {

    // Initialize iterator
    iterator.Initialize(_target, _source);

    // Loop over all voxels in the target (reference) volume
    for (k = 0; k < _target->GetZ(); k++) {
      for (j = 0; j < _target->GetY(); j++) {
        for (i = 0; i < _target->GetX(); i++) {
          // Check whether reference point is valid
          if (*ptr2target >= 0) {
            // Check whether transformed point is inside source volume
            if ((iterator._x > _source_x1) && (iterator._x < _source_x2) &&
                (iterator._y > _source_y1) && (iterator._y < _source_y2) &&
                (iterator._z > _source_z1) && (iterator._z < _source_z2)) {
              // Add sample to metric
              _metric->Add(*ptr2target, round(_interpolator->EvaluateInside(iterator._x, iterator._y, iterator._z, t)));
            }
            iterator.NextX();
          } else {
            // Advance iterator by offset
            iterator.NextX(*ptr2target * -1);
            i          -= (*ptr2target) + 1;
            ptr2target -= (*ptr2target) + 1;
          }
          ptr2target++;
        }
        iterator.NextY();
      }
      iterator.NextZ();
    }
  }

#endif

  // Invert transformation
  //((irtkRigidTransformation *)_transformation)->Invert();

  // Evaluate similarity measure
  return _metric->Evaluate();
}
<commit_msg>Added functions GuessParameterSliceToVolume() and GuessParameterThickSlice() which are used in class irtkReconstruction<commit_after>/*=========================================================================

  Library   : Image Registration Toolkit (IRTK)
  Module    : $Id$
  Copyright : Imperial College, Department of Computing
              Visual Information Processing (VIP), 2008 onwards
  Date      : $Date$
  Version   : $Revision$
  Changes   : $Author$

=========================================================================*/

#include <irtkRegistration.h>

#include <irtkHomogeneousTransformationIterator.h>

#include <irtkMultiThreadedImageRigidRegistration.h>

void irtkImageRigidRegistration::GuessParameter()
{
  int i;
  double xsize, ysize, zsize;

  if ((_target == NULL) || (_source == NULL)) {
    cerr << "irtkImageRigidRegistration::GuessParameter: Target and source image not found" << endl;
    exit(1);
  }

  // Default parameters for registration
  _NumberOfLevels     = 3;
  _NumberOfBins       = 64;

  // Default parameters for optimization
  _SimilarityMeasure  = NMI;
  _OptimizationMethod = GradientDescent;
  _Epsilon            = 0.0001;

  // Read target pixel size
  _target->GetPixelSize(&xsize, &ysize, &zsize);

  // Default target parameters
  _TargetBlurring[0]      = GuessResolution(xsize, ysize, zsize) / 2.0;
  _TargetResolution[0][0] = GuessResolution(xsize, ysize, zsize);
  _TargetResolution[0][1] = GuessResolution(xsize, ysize, zsize);
  _TargetResolution[0][2] = GuessResolution(xsize, ysize, zsize);

  for (i = 1; i < _NumberOfLevels; i++) {
    _TargetBlurring[i]      = _TargetBlurring[i-1] * 2;
    _TargetResolution[i][0] = _TargetResolution[i-1][0] * 2;
    _TargetResolution[i][1] = _TargetResolution[i-1][1] * 2;
    _TargetResolution[i][2] = _TargetResolution[i-1][2] * 2;
  }

  // Read source pixel size
  _source->GetPixelSize(&xsize, &ysize, &zsize);

  // Default source parameters
  _SourceBlurring[0]      = GuessResolution(xsize, ysize, zsize) / 2.0;
  _SourceResolution[0][0] = GuessResolution(xsize, ysize, zsize);
  _SourceResolution[0][1] = GuessResolution(xsize, ysize, zsize);
  _SourceResolution[0][2] = GuessResolution(xsize, ysize, zsize);

  for (i = 1; i < _NumberOfLevels; i++) {
    _SourceBlurring[i]      = _SourceBlurring[i-1] * 2;
    _SourceResolution[i][0] = _SourceResolution[i-1][0] * 2;
    _SourceResolution[i][1] = _SourceResolution[i-1][1] * 2;
    _SourceResolution[i][2] = _SourceResolution[i-1][2] * 2;
  }

  // Remaining parameters
  for (i = 0; i < _NumberOfLevels; i++) {
    _NumberOfIterations[i] = 20;
    _NumberOfSteps[i]      = 4;
    _LengthOfSteps[i]      = 2 * pow(2.0, i);
  }

  // Try to guess padding by looking at voxel values in all eight corners of the volume:
  // If all values are the same we assume that they correspond to the padding value
  _TargetPadding = MIN_GREY;
  if ((_target->Get(_target->GetX()-1, 0, 0)                                 == _target->Get(0, 0, 0)) &&
      (_target->Get(0, _target->GetY()-1, 0)                                 == _target->Get(0, 0, 0)) &&
      (_target->Get(0, 0, _target->GetZ()-1)                                 == _target->Get(0, 0, 0)) &&
      (_target->Get(_target->GetX()-1, _target->GetY()-1, 0)                 == _target->Get(0, 0, 0)) &&
      (_target->Get(0, _target->GetY()-1, _target->GetZ()-1)                 == _target->Get(0, 0, 0)) &&
      (_target->Get(_target->GetX()-1, 0, _target->GetZ()-1)                 == _target->Get(0, 0, 0)) &&
      (_target->Get(_target->GetX()-1, _target->GetY()-1, _target->GetZ()-1) == _target->Get(0, 0, 0))) {
    _TargetPadding = _target->Get(0, 0, 0);
  }
}

void irtkImageRigidRegistration::GuessParameterThickSlices()
{
  int i;
  double xsize, ysize, zsize,size;

  if ((_target == NULL) || (_source == NULL)) {
    cerr << "irtkImageRigidRegistration::GuessParameter: Target and source image not found" << endl;
    exit(1);
  }

  // Default parameters for registration
  _NumberOfLevels     = 3;
  _NumberOfBins       = 64;

  // Default parameters for optimization
  _SimilarityMeasure  = NMI;
  _OptimizationMethod = GradientDescent;
  _Epsilon            = 0.0001;

  // Read target pixel size
  _target->GetPixelSize(&xsize, &ysize, &zsize);

  if (ysize<xsize)
    size = ysize;
  else
    size = xsize;
  if (zsize<size)
    size = zsize;

  // Default target parameters
  _TargetBlurring[0]      = size / 2.0;
  _TargetResolution[0][0] = size;
  _TargetResolution[0][1] = size;
  _TargetResolution[0][2] = size;

  for (i = 1; i < _NumberOfLevels; i++) {
    _TargetBlurring[i]      = _TargetBlurring[i-1] * 2;
    _TargetResolution[i][0] = _TargetResolution[i-1][0] * 2;
    _TargetResolution[i][1] = _TargetResolution[i-1][1] * 2;
    _TargetResolution[i][2] = _TargetResolution[i-1][2] * 2;
  }

  // Read source pixel size
  _source->GetPixelSize(&xsize, &ysize, &zsize);

  if (ysize<xsize)
    size = ysize;
  else
    size = xsize;
  if (zsize<size)
    size = zsize;

  // Default source parameters
  _SourceBlurring[0]      = size / 2.0;
  _SourceResolution[0][0] = size;
  _SourceResolution[0][1] = size;
  _SourceResolution[0][2] = size;

  for (i = 1; i < _NumberOfLevels; i++) {
    _SourceBlurring[i]      = _SourceBlurring[i-1] * 2;
    _SourceResolution[i][0] = _SourceResolution[i-1][0] * 2;
    _SourceResolution[i][1] = _SourceResolution[i-1][1] * 2;
    _SourceResolution[i][2] = _SourceResolution[i-1][2] * 2;
  }

  // Remaining parameters
  for (i = 0; i < _NumberOfLevels; i++) {
    _NumberOfIterations[i] = 20;
    _NumberOfSteps[i]      = 4;
    _LengthOfSteps[i]      = 2 * pow(2.0, i);
  }

  // Try to guess padding by looking at voxel values in all eight corners of the volume:
  // If all values are the same we assume that they correspond to the padding value
  _TargetPadding = MIN_GREY;
  if ((_target->Get(_target->GetX()-1, 0, 0)                                 == _target->Get(0, 0, 0)) &&
      (_target->Get(0, _target->GetY()-1, 0)                                 == _target->Get(0, 0, 0)) &&
      (_target->Get(0, 0, _target->GetZ()-1)                                 == _target->Get(0, 0, 0)) &&
      (_target->Get(_target->GetX()-1, _target->GetY()-1, 0)                 == _target->Get(0, 0, 0)) &&
      (_target->Get(0, _target->GetY()-1, _target->GetZ()-1)                 == _target->Get(0, 0, 0)) &&
      (_target->Get(_target->GetX()-1, 0, _target->GetZ()-1)                 == _target->Get(0, 0, 0)) &&
      (_target->Get(_target->GetX()-1, _target->GetY()-1, _target->GetZ()-1) == _target->Get(0, 0, 0))) {
    _TargetPadding = _target->Get(0, 0, 0);
  }
}

void irtkImageRigidRegistration::GuessParameterSliceToVolume()
{
  int i;
  double xsize, ysize, zsize;

  if ((_target == NULL) || (_source == NULL)) {
    cerr << "irtkImageRigidRegistration::GuessParameter: Target and source image not found" << endl;
    exit(1);
  }

  // Default parameters for registration
  _NumberOfLevels     = 2;
  _NumberOfBins       = 64;

  // Default parameters for optimization
  _SimilarityMeasure  = NMI;
  _OptimizationMethod = GradientDescent;
  _Epsilon            = 0.0001;

  // Read target pixel size
  _target->GetPixelSize(&xsize, &ysize, &zsize);

  double size;

  if (ysize<xsize)
    size = ysize;
  else
    size = xsize;

  // Default target parameters
  _TargetBlurring[0]      = size / 2.0;
  _TargetResolution[0][0] = size;
  _TargetResolution[0][1] = size;
  _TargetResolution[0][2] = zsize;

  for (i = 1; i < _NumberOfLevels; i++) {
    _TargetBlurring[i]      = _TargetBlurring[i-1] * 2;
    _TargetResolution[i][0] = _TargetResolution[i-1][0] * 2;
    _TargetResolution[i][1] = _TargetResolution[i-1][1] * 2;
    _TargetResolution[i][2] = _TargetResolution[i-1][2];
  }

  // Read source pixel size
  _source->GetPixelSize(&xsize, &ysize, &zsize);

  if (ysize<xsize)
    size = ysize;
  else
    size = xsize;
  if (zsize<size)
    size = zsize;

  // Default source parameters
  _SourceBlurring[0]      = size / 2.0;
  _SourceResolution[0][0] = size;
  _SourceResolution[0][1] = size;
  _SourceResolution[0][2] = size;

  for (i = 1; i < _NumberOfLevels; i++) {
    _SourceBlurring[i]      = _SourceBlurring[i-1] * 2;
    _SourceResolution[i][0] = _SourceResolution[i-1][0] * 2;
    _SourceResolution[i][1] = _SourceResolution[i-1][1] * 2;
    _SourceResolution[i][2] = _SourceResolution[i-1][2] * 2;
  }

  // Remaining parameters
  for (i = 0; i < _NumberOfLevels; i++) {
    _NumberOfIterations[i] = 20;
    _NumberOfSteps[i]      = 4;
    _LengthOfSteps[i]      = 2 * pow(2.0, i);
  }

  // Try to guess padding by looking at voxel values in all eight corners of the volume:
  // If all values are the same we assume that they correspond to the padding value
  _TargetPadding = MIN_GREY;
  if ((_target->Get(_target->GetX()-1, 0, 0)                                 == _target->Get(0, 0, 0)) &&
      (_target->Get(0, _target->GetY()-1, 0)                                 == _target->Get(0, 0, 0)) &&
      (_target->Get(0, 0, _target->GetZ()-1)                                 == _target->Get(0, 0, 0)) &&
      (_target->Get(_target->GetX()-1, _target->GetY()-1, 0)                 == _target->Get(0, 0, 0)) &&
      (_target->Get(0, _target->GetY()-1, _target->GetZ()-1)                 == _target->Get(0, 0, 0)) &&
      (_target->Get(_target->GetX()-1, 0, _target->GetZ()-1)                 == _target->Get(0, 0, 0)) &&
      (_target->Get(_target->GetX()-1, _target->GetY()-1, _target->GetZ()-1) == _target->Get(0, 0, 0))) {
    _TargetPadding = _target->Get(0, 0, 0);
  }
}

void irtkImageRigidRegistration::Initialize()
{
  // Call base class
  this->irtkImageRegistration::Initialize();

  // Invert rigid transformation (to be backwards compatible)
  //((irtkRigidTransformation *)_transformation)->Invert();
  //((irtkRigidTransformation *)_transformation)->UpdateParameter();
}

void irtkImageRigidRegistration::Finalize()
{
  // Call base class
  this->irtkImageRegistration::Finalize();

  // Invert rigid transformation (to be backwards compatible)
  //((irtkRigidTransformation *)_transformation)->Invert();
  //((irtkRigidTransformation *)_transformation)->UpdateParameter();
}

double irtkImageRigidRegistration::Evaluate()
{

#ifndef HAS_TBB
  int i, j, k, t;
#endif

  // Pointer to reference data
  irtkGreyPixel *ptr2target;

  // Print debugging information
  this->Debug("irtkImageRigidRegistration::Evaluate");

  // Invert transformation
  //((irtkRigidTransformation *)_transformation)->Invert();

  // Create iterator
  irtkHomogeneousTransformationIterator
  iterator((irtkHomogeneousTransformation *)_transformation);

  // Initialize metric
  _metric->Reset();

  // Pointer to voxels in target image
  ptr2target = _target->GetPointerToVoxels();

#ifdef HAS_TBB
  irtkMultiThreadedImageRigidRegistrationEvaluate evaluate(this);
  parallel_reduce(blocked_range<int>(0, _target->GetZ(), 20), evaluate);
#else

  for (t = 0; t < _target->GetT(); t++) {

    // Initialize iterator
    iterator.Initialize(_target, _source);

    // Loop over all voxels in the target (reference) volume
    for (k = 0; k < _target->GetZ(); k++) {
      for (j = 0; j < _target->GetY(); j++) {
        for (i = 0; i < _target->GetX(); i++) {
          // Check whether reference point is valid
          if (*ptr2target >= 0) {
            // Check whether transformed point is inside source volume
            if ((iterator._x > _source_x1) && (iterator._x < _source_x2) &&
                (iterator._y > _source_y1) && (iterator._y < _source_y2) &&
                (iterator._z > _source_z1) && (iterator._z < _source_z2)) {
              // Add sample to metric
              _metric->Add(*ptr2target, round(_interpolator->EvaluateInside(iterator._x, iterator._y, iterator._z, t)));
            }
            iterator.NextX();
          } else {
            // Advance iterator by offset
            iterator.NextX(*ptr2target * -1);
            i          -= (*ptr2target) + 1;
            ptr2target -= (*ptr2target) + 1;
          }
          ptr2target++;
        }
        iterator.NextY();
      }
      iterator.NextZ();
    }
  }

#endif

  // Invert transformation
  //((irtkRigidTransformation *)_transformation)->Invert();

  // Evaluate similarity measure
  return _metric->Evaluate();
}
<|endoftext|>


<commit_before>/**
 * @file template.cpp
 * @brief plustache template
 * @author Daniel Schauenberg <d@unwiredcouch.com>
 * @version 0.1
 * @date 2010-03-12
 */

#include <template.hpp>

void template_t::hello_world()
{
    cout << "Hello World!\n";
}

template_t::template_t()
{
    otag = "\\{\\{";
    ctag = "\\}\\}";
    tag.assign(otag + "(#|=|&|!|>|\\{)?(.+?)\\1?" + ctag);
}

template_t::~template_t()
{

}

string template_t::render(string tmplate, context ctx)
{
    string ret = "";
    return ret;
}

string template_t::render(string tmplate, map<string, string> ctx)
{
    string ret = "";
    string rest;
    string::const_iterator start, end;
    match_results<std::string::const_iterator> matches;
    start = tmplate.begin();
    end = tmplate.end();
    while (regex_search(start, end, matches, tag,
                            match_default | format_all))
    {
        string key(matches[2].first, matches[2].second);
        string repl = ctx[key];
        string text(start,matches[0].second);
        ret += regex_replace(text, tag, repl, match_default | format_all);
        start = matches[0].second;
        string foo(matches[0].second, end);
        rest = foo;
    }
    ret += rest;
    return ret;
}

<commit_msg>better assignment of rest string<commit_after>/**
 * @file template.cpp
 * @brief plustache template
 * @author Daniel Schauenberg <d@unwiredcouch.com>
 * @version 0.1
 * @date 2010-03-12
 */

#include <template.hpp>

void template_t::hello_world()
{
    cout << "Hello World!\n";
}

template_t::template_t()
{
    otag = "\\{\\{";
    ctag = "\\}\\}";
    tag.assign(otag + "(#|=|&|!|>|\\{)?(.+?)\\1?" + ctag);
}

template_t::~template_t()
{

}

string template_t::render(string tmplate, context ctx)
{
    string ret = "";
    return ret;
}

string template_t::render(string tmplate, map<string, string> ctx)
{
    string ret = "";
    string rest;
    string::const_iterator start, end;
    match_results<std::string::const_iterator> matches;
    start = tmplate.begin();
    end = tmplate.end();
    while (regex_search(start, end, matches, tag,
                            match_default | format_all))
    {
        string key(matches[2].first, matches[2].second);
        string repl = ctx[key];
        string text(start,matches[0].second);
        ret += regex_replace(text, tag, repl, match_default | format_all);
        rest.assign(matches[0].second, end);
        start = matches[0].second;
    }
    ret += rest;
    return ret;
}

<|endoftext|>