<commit_before>#ifndef DUNE_DETAILED_DISCRETIZATIONS_DISCRETEFUNCTION_LOCAL_HH
#define DUNE_DETAILED_DISCRETIZATIONS_DISCRETEFUNCTION_LOCAL_HH

#include <vector>

namespace Dune {
namespace Detailed {
namespace Discretizations {
namespace DiscreteFunction {

template< class DiscreteFunctionImp >
class LocalConst
{
public:
  typedef DiscreteFunctionImp DiscreteFunctionType;

  typedef LocalConst< DiscreteFunctionType > ThisType;

  typedef typename DiscreteFunctionType::DiscreteFunctionSpaceType DiscreteFunctionSpaceType;

  typedef typename DiscreteFunctionSpaceType::GridPartType::template Codim< 0 >::EntityType EntityType;

  typedef typename DiscreteFunctionSpaceType::FunctionSpaceType FunctionSpaceType;

  typedef typename FunctionSpaceType::DomainType DomainType;

  typedef typename FunctionSpaceType::RangeFieldType RangeFieldType;

  typedef typename FunctionSpaceType::RangeType RangeType;

  typedef typename FunctionSpaceType::JacobianRangeType JacobianRangeType;

  typedef typename DiscreteFunctionType::size_type size_type;

private:
  typedef typename DiscreteFunctionSpaceType::BaseFunctionSetType::LocalBaseFunctionSetType
    LocalBaseFunctionSetType;

public:
  LocalConst(const DiscreteFunctionType& discreteFunction, const EntityType& entity)
    : discreteFunction_(discreteFunction)
    , entity_(entity)
    , localBaseFunctionSet_(discreteFunction_.space().baseFunctionSet().local(entity_))
    , size_(localBaseFunctionSet_.size())
    , order_(localBaseFunctionSet_.order())
  {}

  LocalConst(const ThisType& other)
    : discreteFunction_(other.discreteFunction_)
    , entity_( other.entity_)
    , localBaseFunctionSet_(other.localBaseFunctionSet_)
    , size_(other.size_)
    , order_(other.order_)
  {}

  const DiscreteFunctionType& discreteFunction() const
  {
    return discreteFunction_;
  }

  const EntityType& entity() const
  {
    return entity_;
  }

  const RangeFieldType get(const size_type localDofNumber) const
  {
    assert(localDofNumber < size());
    const size_type globalDofNumber = discreteFunction_.space().map().toGlobal(entity_, localDofNumber);
    assert(globalDofNumber < discreteFunction_.vector()->size());
    return discreteFunction_.vector()->get(globalDofNumber);
  }

  int order() const
  {
    return order_;
  }

  size_type size() const
  {
    return size_;
  }

  void evaluate( const DomainType& x, RangeType& ret) const
  {
    std::vector< RangeType > baseFunctionValues( size(), RangeType( 0.0 ) );
    localBaseFunctionSet_.evaluate( x, baseFunctionValues );
    ret = 0.0;
    for( size_type i = 0; i < size(); ++i )
    {
      baseFunctionValues[i] *= get(i);
      ret += baseFunctionValues[i];
    }
  }

  void jacobian( const DomainType& x, JacobianRangeType& ret ) const
  {
    std::vector< JacobianRangeType > baseFunctionJacobianValues( size(), JacobianRangeType( 0.0 ) );
    localBaseFunctionSet_.jacobian( x, baseFunctionJacobianValues );
    ret = 0.0;
    for( size_type i = 0; i < size(); ++i )
    {
      baseFunctionJacobianValues[i] *= get(i);
      ret += baseFunctionJacobianValues[i];
    }
  }

private:
  ThisType& operator=(const ThisType&);

  const DiscreteFunctionType& discreteFunction_;
  const EntityType& entity_;
  const LocalBaseFunctionSetType localBaseFunctionSet_;
  const size_type size_;
  const int order_;
}; // end class LocalConst

template< class DiscreteFunctionImp >
class Local
  : public LocalConst< DiscreteFunctionImp >
{
public:
  typedef DiscreteFunctionImp DiscreteFunctionType;

  typedef Local< DiscreteFunctionType > ThisType;

  typedef LocalConst< DiscreteFunctionType > BaseType;

  typedef typename BaseType::EntityType EntityType;

  typedef typename BaseType::RangeFieldType RangeFieldType;

  typedef typename DiscreteFunctionType::size_type size_type;

  Local(DiscreteFunctionType& discreteFunction, const EntityType& entity)
    : BaseType(const_cast< const DiscreteFunctionType& >(discreteFunction), entity)
    , discreteFunction_(discreteFunction)
  {}

  using BaseType::entity;

  using BaseType::get;

  using BaseType::size;

  using BaseType::evaluate;

  using BaseType::jacobian;

  void set(const size_type _localDofNumber, const RangeFieldType& _val)
  {
    assert(_localDofNumber < size());
    const size_type globalDofNumber = discreteFunction_.space().map().toGlobal(BaseType::entity(), _localDofNumber);
    assert(globalDofNumber < discreteFunction_.vector()->size());
    discreteFunction_.vector()->set(globalDofNumber, _val);
  }

private:
  DiscreteFunctionType& discreteFunction_;
}; // end class Local

} // namespace DiscreteFunction
} // namespace Discretizations
} // namespace Detailed
} // namespace Dune

#endif // DUNE_DETAILED_DISCRETIZATIONS_DISCRETEFUNCTION_LOCAL_HH
<commit_msg>[discretefunction.local] added LocalDoFVector and DiscreteFunctionLocalConst<commit_after>#ifndef DUNE_DETAILED_DISCRETIZATIONS_DISCRETEFUNCTION_LOCAL_HH
#define DUNE_DETAILED_DISCRETIZATIONS_DISCRETEFUNCTION_LOCAL_HH

#include <vector>

#include <dune/common/dynvector.hh>

#include <dune/stuff/localfunction/interface.hh>
#include <dune/stuff/la/container/interface.hh>
#include <dune/stuff/common/vector.hh>
#include <dune/stuff/common/matrix.hh>

#include <dune/detailed/discretizations/mapper/interface.hh>

namespace Dune {
namespace Detailed {
namespace Discretizations {

template< class VectorImp >
class LocalDoFVector
{
public:
  typedef typename Dune::Stuff::LA::Container::VectorInterface< typename VectorImp::Traits >::derived_type VectorType;
  typedef typename VectorType::ElementType ElementType;

  template< class M, class EntityType >
  LocalDoFVector(const MapperInterface< M >& mapper,
                 const EntityType& entity,
                 VectorType& vector)
    : indices_(mapper.numDofs(entity))
    , vector_(vector)
  {
    mapper.globalIndices(entity, indices_);
  }

  size_t size() const
  {
    return indices_.size();
  }

  ElementType get(const size_t ii) const
  {
    assert(ii < indices_.size());
    return vector_.get(indices_[ii]);
  }

  void set(const size_t ii, const ElementType& val)
  {
    assert(ii < indices_.size());
    vector_.set(indices_[ii], val);
  }

  void add(const size_t ii, const ElementType& val)
  {
    assert(ii < indices_.size());
    vector_.add(indices_[ii], val);
  }

private:
  Dune::DynamicVector< size_t > indices_;
  VectorType& vector_;
}; // class LocalDoFVector

// forward, includes are below
template< class SpaceImp, class VectorImp >
class DiscreteFunctionDefaultConst;

// forward, to be used in the traits
template< class SpaceImp, class VectorImp >
class DiscreteFunctionLocalConst;

template< class SpaceImp, class VectorImp >
class DiscreteFunctionLocalConstTraits
{
public:
  typedef DiscreteFunctionLocalConst< SpaceImp, VectorImp > derived_type;
  typedef typename DiscreteFunctionDefaultConst< SpaceImp, VectorImp >::EntityType EntityType;
};

template< class SpaceImp, class VectorImp >
class DiscreteFunctionLocalConst
  : public Dune::Stuff::LocalFunctionInterface< DiscreteFunctionLocalConstTraits< SpaceImp, VectorImp >,
                                                typename SpaceImp::DomainFieldType, SpaceImp::dimDomain,
                                                typename SpaceImp::RangeFieldType, SpaceImp::dimRangeRows, SpaceImp::dimRangeCols >
{
public:
  typedef DiscreteFunctionDefaultConst< SpaceImp, VectorImp >         DiscreteFunctionType;
  typedef typename DiscreteFunctionType::SpaceType                    SpaceType;
  typedef LocalDoFVector< typename DiscreteFunctionType::VectorType > LocalDoFVectorType;
  typedef typename DiscreteFunctionType::EntityType                   EntityType;
  typedef typename SpaceType::DomainFieldType DomainFieldType;
  static const unsigned int                   dimDomain = SpaceType::dimDomain;
  typedef typename SpaceType::RangeFieldType  RangeFieldType;
  static const unsigned int                   dimRangeRows = SpaceType::dimRangeRows;
  static const unsigned int                   dimRangeCols = SpaceType::dimRangeCols;
private:
  typedef typename SpaceType::BaseFunctionSetType BaseFunctionSetType;
public:
  typedef typename BaseFunctionSetType::DomainType        DomainType;
  typedef typename BaseFunctionSetType::RangeType         RangeType;
  typedef typename BaseFunctionSetType::JacobianRangeType JacobianRangeType;

  DiscreteFunctionLocalConst(const DiscreteFunctionType& discreteFunction, const EntityType& entity)
    : function_(discreteFunction)
    , entity_(entity)
    , base_(function_.space().baseFunctionSet(entity_))
    , localVector_(function_.space().mapper(), entity_, const_cast< typename DiscreteFunctionType::VectorType& >(*(function_.vector())))
    , tmpBaseValues_(base_.size(), RangeType(0))
    , tmpBaseJacobianValues_(base_.size(), JacobianRangeType(0))
  {
    assert(localVector_.size() == base_.size());
  }

  const DiscreteFunctionType& discreteFunction() const
  {
    return function_;
  }

  const EntityType& entity() const
  {
    return entity_;
  }

  const LocalDoFVectorType& vector() const
  {
    return localVector_;
  }

  int order() const
  {
    return base_.order();
  }

  size_t size() const
  {
    return base_.size();
  }

  void evaluate(const DomainType& x, RangeType& ret) const
  {
    Dune::Stuff::Common::clear(ret);
    assert(localVector_.size() == tmpBaseValues_.size());
    base_.evaluate(x, tmpBaseValues_);
    for (size_t ii = 0; ii < localVector_.size(); ++ii) {
      tmpBaseValues_[ii] *= localVector_.get(ii);
      ret += tmpBaseValues_[ii];
    }
  } // ... evaluate(...)

  void jacobian(const DomainType& x, JacobianRangeType& ret) const
  {
    Dune::Stuff::Common::clear(ret);
    assert(localVector_.size() == tmpBaseJacobianValues_.size());
    base_.jacobian(x, tmpBaseJacobianValues_);
    for (size_t ii = 0; ii < localVector_.size(); ++ii) {
      tmpBaseJacobianValues_[ii] *= localVector_.get(ii);
      ret += tmpBaseJacobianValues_[ii];
    }
  } // ... jacobian(...)

private:
  const DiscreteFunctionType& function_;
  const EntityType& entity_;
  const BaseFunctionSetType base_;
  LocalDoFVectorType localVector_;
  mutable std::vector< RangeType > tmpBaseValues_;
  mutable std::vector< JacobianRangeType > tmpBaseJacobianValues_;
}; // class DiscreteFunctionLocalConst

//template< class DiscreteFunctionImp >
//class Local
//  : public LocalConst< DiscreteFunctionImp >
//{
//public:
//  typedef DiscreteFunctionImp DiscreteFunctionType;

//  typedef Local< DiscreteFunctionType > ThisType;

//  typedef LocalConst< DiscreteFunctionType > BaseType;

//  typedef typename BaseType::EntityType EntityType;

//  typedef typename BaseType::RangeFieldType RangeFieldType;

//  typedef typename DiscreteFunctionType::size_type size_type;

//  Local(DiscreteFunctionType& discreteFunction, const EntityType& entity)
//    : BaseType(const_cast< const DiscreteFunctionType& >(discreteFunction), entity)
//    , discreteFunction_(discreteFunction)
//  {}

//  using BaseType::entity;

//  using BaseType::get;

//  using BaseType::size;

//  using BaseType::evaluate;

//  using BaseType::jacobian;

//  void set(const size_type _localDofNumber, const RangeFieldType& _val)
//  {
//    assert(_localDofNumber < size());
//    const size_type globalDofNumber = discreteFunction_.space().map().toGlobal(BaseType::entity(), _localDofNumber);
//    assert(globalDofNumber < discreteFunction_.vector()->size());
//    discreteFunction_.vector()->set(globalDofNumber, _val);
//  }

//private:
//  DiscreteFunctionType& discreteFunction_;
//}; // end class Local

} // namespace Discretizations
} // namespace Detailed
} // namespace Dune

#include "default.hh"

#endif // DUNE_DETAILED_DISCRETIZATIONS_DISCRETEFUNCTION_LOCAL_HH
<|endoftext|>


<commit_before>// Copyright (c) 2010 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 "webkit/tools/test_shell/webwidget_host.h"

#include "base/logging.h"
#include "base/win_util.h"
#include "gfx/rect.h"
#include "skia/ext/platform_canvas.h"
#include "third_party/WebKit/WebKit/chromium/public/WebInputEvent.h"
#include "third_party/WebKit/WebKit/chromium/public/WebPopupMenu.h"
#include "third_party/WebKit/WebKit/chromium/public/WebScreenInfo.h"
#include "third_party/WebKit/WebKit/chromium/public/WebSize.h"
#include "third_party/WebKit/WebKit/chromium/public/win/WebInputEventFactory.h"
#include "third_party/WebKit/WebKit/chromium/public/win/WebScreenInfoFactory.h"
#include "webkit/tools/test_shell/test_shell.h"

using WebKit::WebInputEvent;
using WebKit::WebInputEventFactory;
using WebKit::WebKeyboardEvent;
using WebKit::WebMouseEvent;
using WebKit::WebMouseWheelEvent;
using WebKit::WebPopupMenu;
using WebKit::WebScreenInfo;
using WebKit::WebScreenInfoFactory;
using WebKit::WebSize;
using WebKit::WebWidget;
using WebKit::WebWidgetClient;

static const wchar_t kWindowClassName[] = L"WebWidgetHost";

/*static*/
WebWidgetHost* WebWidgetHost::Create(HWND parent_view,
                                     WebWidgetClient* client) {
  WebWidgetHost* host = new WebWidgetHost();

  static bool registered_class = false;
  if (!registered_class) {
    WNDCLASSEX wcex = {0};
    wcex.cbSize        = sizeof(wcex);
    wcex.style         = CS_DBLCLKS;
    wcex.lpfnWndProc   = WebWidgetHost::WndProc;
    wcex.hInstance     = GetModuleHandle(NULL);
    wcex.hCursor       = LoadCursor(NULL, IDC_ARROW);
    wcex.lpszClassName = kWindowClassName;
    RegisterClassEx(&wcex);
    registered_class = true;
  }

  host->view_ = CreateWindowEx(WS_EX_TOOLWINDOW,
                               kWindowClassName, kWindowClassName, WS_POPUP,
                               0, 0, 0, 0,
                               parent_view, NULL, GetModuleHandle(NULL), NULL);
  win_util::SetWindowUserData(host->view_, host);

  host->webwidget_ = WebPopupMenu::create(client);

  return host;
}

static WebWidgetHost* FromWindow(HWND view) {
  return reinterpret_cast<WebWidgetHost*>(win_util::GetWindowUserData(view));
}

/*static*/
LRESULT CALLBACK WebWidgetHost::WndProc(HWND hwnd, UINT message, WPARAM wparam,
                                        LPARAM lparam) {
  WebWidgetHost* host = FromWindow(hwnd);
  if (host && !host->WndProc(message, wparam, lparam)) {
    switch (message) {
      case WM_DESTROY:
        delete host;
        break;

      case WM_PAINT: {
        RECT rect;
        if (GetUpdateRect(hwnd, &rect, FALSE)) {
          host->UpdatePaintRect(gfx::Rect(rect));
        }
        host->Paint();
        return 0;
      }

      case WM_ERASEBKGND:
        // Do nothing here to avoid flashing, the background will be erased
        // during painting.
        return 0;

      case WM_SIZE:
        host->Resize(lparam);
        return 0;

      case WM_MOUSEMOVE:
      case WM_MOUSELEAVE:
      case WM_LBUTTONDOWN:
      case WM_MBUTTONDOWN:
      case WM_RBUTTONDOWN:
      case WM_LBUTTONUP:
      case WM_MBUTTONUP:
      case WM_RBUTTONUP:
      case WM_LBUTTONDBLCLK:
      case WM_MBUTTONDBLCLK:
      case WM_RBUTTONDBLCLK:
        host->MouseEvent(message, wparam, lparam);
        break;

      case WM_MOUSEWHEEL:
        host->WheelEvent(wparam, lparam);
        break;

      case WM_CAPTURECHANGED:
      case WM_CANCELMODE:
        host->CaptureLostEvent();
        break;

      // TODO(darin): add WM_SYSKEY{DOWN/UP} to capture ALT key actions
      case WM_KEYDOWN:
      case WM_KEYUP:
      case WM_SYSKEYDOWN:
      case WM_SYSKEYUP:
      case WM_CHAR:
      case WM_SYSCHAR:
      case WM_IME_CHAR:
        host->KeyEvent(message, wparam, lparam);
        break;

      case WM_SETFOCUS:
        host->SetFocus(true);
        break;

      case WM_KILLFOCUS:
        host->SetFocus(false);
        break;
    }
  }

  return DefWindowProc(hwnd, message, wparam, lparam);;
}

void WebWidgetHost::DidInvalidateRect(const gfx::Rect& damaged_rect) {
  DLOG_IF(WARNING, painting_) << "unexpected invalidation while painting";

  // If this invalidate overlaps with a pending scroll, then we have to
  // downgrade to invalidating the scroll rect.
  if (damaged_rect.Intersects(scroll_rect_)) {
    paint_rect_ = paint_rect_.Union(scroll_rect_);
    ResetScrollRect();
  }
  paint_rect_ = paint_rect_.Union(damaged_rect);

  RECT r = damaged_rect.ToRECT();
  InvalidateRect(view_, &r, FALSE);
}

void WebWidgetHost::DidScrollRect(int dx, int dy, const gfx::Rect& clip_rect) {
  if (dx != 0 && dy != 0) {
    // We only support uni-directional scroll
    DidScrollRect(0, dy, clip_rect);
    dy = 0;
  }

  // If we already have a pending scroll operation or if this scroll operation
  // intersects the existing paint region, then just failover to invalidating.
  if (!scroll_rect_.IsEmpty() || paint_rect_.Intersects(clip_rect)) {
    paint_rect_ = paint_rect_.Union(scroll_rect_);
    ResetScrollRect();
    paint_rect_ = paint_rect_.Union(clip_rect);
  }

  // We will perform scrolling lazily, when requested to actually paint.
  scroll_rect_ = clip_rect;
  scroll_dx_ = dx;
  scroll_dy_ = dy;

  RECT r = clip_rect.ToRECT();
  InvalidateRect(view_, &r, FALSE);
}

void WebWidgetHost::SetCursor(HCURSOR cursor) {
  SetClassLong(view_, GCL_HCURSOR,
      static_cast<LONG>(reinterpret_cast<LONG_PTR>(cursor)));
  ::SetCursor(cursor);
}

void WebWidgetHost::DiscardBackingStore() {
  canvas_.reset();
}

WebWidgetHost::WebWidgetHost()
    : view_(NULL),
      webwidget_(NULL),
      track_mouse_leave_(false),
      scroll_dx_(0),
      scroll_dy_(0) {
  set_painting(false);
}

WebWidgetHost::~WebWidgetHost() {
  win_util::SetWindowUserData(view_, 0);

  TrackMouseLeave(false);

  webwidget_->close();
}

bool WebWidgetHost::WndProc(UINT message, WPARAM wparam, LPARAM lparam) {
  switch (message) {
  case WM_ACTIVATE:
    if (wparam == WA_INACTIVE) {
      PostMessage(view_, WM_CLOSE, 0, 0);
      return true;
    }
    break;
  }

  return false;
}

void WebWidgetHost::UpdatePaintRect(const gfx::Rect& rect) {
  paint_rect_ = paint_rect_.Union(rect);
}

void WebWidgetHost::Paint() {
  RECT r;
  GetClientRect(view_, &r);
  gfx::Rect client_rect(r);

  // Allocate a canvas if necessary
  if (!canvas_.get()) {
    ResetScrollRect();
    paint_rect_ = client_rect;
    canvas_.reset(new skia::PlatformCanvas(
        paint_rect_.width(), paint_rect_.height(), true));
  }

  // This may result in more invalidation
  webwidget_->layout();

  // Scroll the canvas if necessary
  scroll_rect_ = client_rect.Intersect(scroll_rect_);
  if (!scroll_rect_.IsEmpty()) {
    HDC hdc = canvas_->getTopPlatformDevice().getBitmapDC();

    RECT damaged_rect, r = scroll_rect_.ToRECT();
    ScrollDC(hdc, scroll_dx_, scroll_dy_, NULL, &r, NULL, &damaged_rect);

    PaintRect(gfx::Rect(damaged_rect));
  }
  ResetScrollRect();

  // Paint the canvas if necessary.  Allow painting to generate extra rects the
  // first time we call it.  This is necessary because some WebCore rendering
  // objects update their layout only when painted.
  for (int i = 0; i < 2; ++i) {
    paint_rect_ = client_rect.Intersect(paint_rect_);
    if (!paint_rect_.IsEmpty()) {
      gfx::Rect rect(paint_rect_);
      paint_rect_ = gfx::Rect();

      DLOG_IF(WARNING, i == 1) << "painting caused additional invalidations";
      PaintRect(rect);
    }
  }
  DCHECK(paint_rect_.IsEmpty());

  // Paint to the screen
  PAINTSTRUCT ps;
  BeginPaint(view_, &ps);
  canvas_->getTopPlatformDevice().drawToHDC(ps.hdc,
                                            ps.rcPaint.left,
                                            ps.rcPaint.top,
                                            &ps.rcPaint);
  EndPaint(view_, &ps);

  // Draw children
  UpdateWindow(view_);
}

WebScreenInfo WebWidgetHost::GetScreenInfo() {
  return WebScreenInfoFactory::screenInfo(view_);
}

void WebWidgetHost::Resize(LPARAM lparam) {
  // Force an entire re-paint.  TODO(darin): Maybe reuse this memory buffer.
  DiscardBackingStore();

  webwidget_->resize(WebSize(LOWORD(lparam), HIWORD(lparam)));
}

void WebWidgetHost::MouseEvent(UINT message, WPARAM wparam, LPARAM lparam) {
  const WebMouseEvent& event = WebInputEventFactory::mouseEvent(
      view_, message, wparam, lparam);
  webwidget_->handleInputEvent(event);
  switch (event.type) {
    case WebInputEvent::MouseMove:
      TrackMouseLeave(true);
      break;
    case WebInputEvent::MouseLeave:
      TrackMouseLeave(false);
      break;
    case WebInputEvent::MouseDown:
      SetCapture(view_);
      // This mimics a temporary workaround in RenderWidgetHostViewWin for bug
      // 765011 to get focus when the mouse is clicked. This happens after the
      // mouse down event is sent to the renderer because normally Windows does
      // a WM_SETFOCUS after WM_LBUTTONDOWN.
      ::SetFocus(view_);
      break;
    case WebInputEvent::MouseUp:
      if (GetCapture() == view_)
        ReleaseCapture();
      break;
  }
}

void WebWidgetHost::WheelEvent(WPARAM wparam, LPARAM lparam) {
  const WebMouseWheelEvent& event = WebInputEventFactory::mouseWheelEvent(
      view_, WM_MOUSEWHEEL, wparam, lparam);
  webwidget_->handleInputEvent(event);
}

void WebWidgetHost::KeyEvent(UINT message, WPARAM wparam, LPARAM lparam) {
  const WebKeyboardEvent& event = WebInputEventFactory::keyboardEvent(
      view_, message, wparam, lparam);
  webwidget_->handleInputEvent(event);
}

void WebWidgetHost::CaptureLostEvent() {
  webwidget_->mouseCaptureLost();
}

void WebWidgetHost::SetFocus(bool enable) {
  // Ignore focus calls in layout test mode so that tests don't mess with each
  // other's focus when running in parallel.
  if (!TestShell::layout_test_mode())
    webwidget_->setFocus(enable);
}

void WebWidgetHost::TrackMouseLeave(bool track) {
  if (track == track_mouse_leave_)
    return;
  track_mouse_leave_ = track;

  DCHECK(view_);

  TRACKMOUSEEVENT tme;
  tme.cbSize = sizeof(TRACKMOUSEEVENT);
  tme.dwFlags = TME_LEAVE;
  if (!track_mouse_leave_)
    tme.dwFlags |= TME_CANCEL;
  tme.hwndTrack = view_;

  TrackMouseEvent(&tme);
}

void WebWidgetHost::ResetScrollRect() {
  scroll_rect_ = gfx::Rect();
  scroll_dx_ = 0;
  scroll_dy_ = 0;
}

void WebWidgetHost::PaintRect(const gfx::Rect& rect) {
#ifndef NDEBUG
  DCHECK(!painting_);
#endif
  DCHECK(canvas_.get());

  set_painting(true);
  webwidget_->paint(canvas_.get(), rect);
  set_painting(false);
}
<commit_msg>A quick fix for Issue 38417. Our test_shell does not support on-the-spot (or over-the-spot) IME. For such applications, Windows sends two messages for inserting IME text: WM_IME_CHAR and WM_CHAR. Since WM_IME_CHAR messages are only for MBCS applications, our test_shell (which is a Unicode application) doesn't have to receive them.<commit_after>// Copyright (c) 2010 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 "webkit/tools/test_shell/webwidget_host.h"

#include "base/logging.h"
#include "base/win_util.h"
#include "gfx/rect.h"
#include "skia/ext/platform_canvas.h"
#include "third_party/WebKit/WebKit/chromium/public/WebInputEvent.h"
#include "third_party/WebKit/WebKit/chromium/public/WebPopupMenu.h"
#include "third_party/WebKit/WebKit/chromium/public/WebScreenInfo.h"
#include "third_party/WebKit/WebKit/chromium/public/WebSize.h"
#include "third_party/WebKit/WebKit/chromium/public/win/WebInputEventFactory.h"
#include "third_party/WebKit/WebKit/chromium/public/win/WebScreenInfoFactory.h"
#include "webkit/tools/test_shell/test_shell.h"

using WebKit::WebInputEvent;
using WebKit::WebInputEventFactory;
using WebKit::WebKeyboardEvent;
using WebKit::WebMouseEvent;
using WebKit::WebMouseWheelEvent;
using WebKit::WebPopupMenu;
using WebKit::WebScreenInfo;
using WebKit::WebScreenInfoFactory;
using WebKit::WebSize;
using WebKit::WebWidget;
using WebKit::WebWidgetClient;

static const wchar_t kWindowClassName[] = L"WebWidgetHost";

/*static*/
WebWidgetHost* WebWidgetHost::Create(HWND parent_view,
                                     WebWidgetClient* client) {
  WebWidgetHost* host = new WebWidgetHost();

  static bool registered_class = false;
  if (!registered_class) {
    WNDCLASSEX wcex = {0};
    wcex.cbSize        = sizeof(wcex);
    wcex.style         = CS_DBLCLKS;
    wcex.lpfnWndProc   = WebWidgetHost::WndProc;
    wcex.hInstance     = GetModuleHandle(NULL);
    wcex.hCursor       = LoadCursor(NULL, IDC_ARROW);
    wcex.lpszClassName = kWindowClassName;
    RegisterClassEx(&wcex);
    registered_class = true;
  }

  host->view_ = CreateWindowEx(WS_EX_TOOLWINDOW,
                               kWindowClassName, kWindowClassName, WS_POPUP,
                               0, 0, 0, 0,
                               parent_view, NULL, GetModuleHandle(NULL), NULL);
  win_util::SetWindowUserData(host->view_, host);

  host->webwidget_ = WebPopupMenu::create(client);

  return host;
}

static WebWidgetHost* FromWindow(HWND view) {
  return reinterpret_cast<WebWidgetHost*>(win_util::GetWindowUserData(view));
}

/*static*/
LRESULT CALLBACK WebWidgetHost::WndProc(HWND hwnd, UINT message, WPARAM wparam,
                                        LPARAM lparam) {
  WebWidgetHost* host = FromWindow(hwnd);
  if (host && !host->WndProc(message, wparam, lparam)) {
    switch (message) {
      case WM_DESTROY:
        delete host;
        break;

      case WM_PAINT: {
        RECT rect;
        if (GetUpdateRect(hwnd, &rect, FALSE)) {
          host->UpdatePaintRect(gfx::Rect(rect));
        }
        host->Paint();
        return 0;
      }

      case WM_ERASEBKGND:
        // Do nothing here to avoid flashing, the background will be erased
        // during painting.
        return 0;

      case WM_SIZE:
        host->Resize(lparam);
        return 0;

      case WM_MOUSEMOVE:
      case WM_MOUSELEAVE:
      case WM_LBUTTONDOWN:
      case WM_MBUTTONDOWN:
      case WM_RBUTTONDOWN:
      case WM_LBUTTONUP:
      case WM_MBUTTONUP:
      case WM_RBUTTONUP:
      case WM_LBUTTONDBLCLK:
      case WM_MBUTTONDBLCLK:
      case WM_RBUTTONDBLCLK:
        host->MouseEvent(message, wparam, lparam);
        break;

      case WM_MOUSEWHEEL:
        host->WheelEvent(wparam, lparam);
        break;

      case WM_CAPTURECHANGED:
      case WM_CANCELMODE:
        host->CaptureLostEvent();
        break;

      // TODO(darin): add WM_SYSKEY{DOWN/UP} to capture ALT key actions
      case WM_KEYDOWN:
      case WM_KEYUP:
      case WM_SYSKEYDOWN:
      case WM_SYSKEYUP:
      case WM_CHAR:
      case WM_SYSCHAR:
        host->KeyEvent(message, wparam, lparam);
        break;

      case WM_SETFOCUS:
        host->SetFocus(true);
        break;

      case WM_KILLFOCUS:
        host->SetFocus(false);
        break;
    }
  }

  return DefWindowProc(hwnd, message, wparam, lparam);;
}

void WebWidgetHost::DidInvalidateRect(const gfx::Rect& damaged_rect) {
  DLOG_IF(WARNING, painting_) << "unexpected invalidation while painting";

  // If this invalidate overlaps with a pending scroll, then we have to
  // downgrade to invalidating the scroll rect.
  if (damaged_rect.Intersects(scroll_rect_)) {
    paint_rect_ = paint_rect_.Union(scroll_rect_);
    ResetScrollRect();
  }
  paint_rect_ = paint_rect_.Union(damaged_rect);

  RECT r = damaged_rect.ToRECT();
  InvalidateRect(view_, &r, FALSE);
}

void WebWidgetHost::DidScrollRect(int dx, int dy, const gfx::Rect& clip_rect) {
  if (dx != 0 && dy != 0) {
    // We only support uni-directional scroll
    DidScrollRect(0, dy, clip_rect);
    dy = 0;
  }

  // If we already have a pending scroll operation or if this scroll operation
  // intersects the existing paint region, then just failover to invalidating.
  if (!scroll_rect_.IsEmpty() || paint_rect_.Intersects(clip_rect)) {
    paint_rect_ = paint_rect_.Union(scroll_rect_);
    ResetScrollRect();
    paint_rect_ = paint_rect_.Union(clip_rect);
  }

  // We will perform scrolling lazily, when requested to actually paint.
  scroll_rect_ = clip_rect;
  scroll_dx_ = dx;
  scroll_dy_ = dy;

  RECT r = clip_rect.ToRECT();
  InvalidateRect(view_, &r, FALSE);
}

void WebWidgetHost::SetCursor(HCURSOR cursor) {
  SetClassLong(view_, GCL_HCURSOR,
      static_cast<LONG>(reinterpret_cast<LONG_PTR>(cursor)));
  ::SetCursor(cursor);
}

void WebWidgetHost::DiscardBackingStore() {
  canvas_.reset();
}

WebWidgetHost::WebWidgetHost()
    : view_(NULL),
      webwidget_(NULL),
      track_mouse_leave_(false),
      scroll_dx_(0),
      scroll_dy_(0) {
  set_painting(false);
}

WebWidgetHost::~WebWidgetHost() {
  win_util::SetWindowUserData(view_, 0);

  TrackMouseLeave(false);

  webwidget_->close();
}

bool WebWidgetHost::WndProc(UINT message, WPARAM wparam, LPARAM lparam) {
  switch (message) {
  case WM_ACTIVATE:
    if (wparam == WA_INACTIVE) {
      PostMessage(view_, WM_CLOSE, 0, 0);
      return true;
    }
    break;
  }

  return false;
}

void WebWidgetHost::UpdatePaintRect(const gfx::Rect& rect) {
  paint_rect_ = paint_rect_.Union(rect);
}

void WebWidgetHost::Paint() {
  RECT r;
  GetClientRect(view_, &r);
  gfx::Rect client_rect(r);

  // Allocate a canvas if necessary
  if (!canvas_.get()) {
    ResetScrollRect();
    paint_rect_ = client_rect;
    canvas_.reset(new skia::PlatformCanvas(
        paint_rect_.width(), paint_rect_.height(), true));
  }

  // This may result in more invalidation
  webwidget_->layout();

  // Scroll the canvas if necessary
  scroll_rect_ = client_rect.Intersect(scroll_rect_);
  if (!scroll_rect_.IsEmpty()) {
    HDC hdc = canvas_->getTopPlatformDevice().getBitmapDC();

    RECT damaged_rect, r = scroll_rect_.ToRECT();
    ScrollDC(hdc, scroll_dx_, scroll_dy_, NULL, &r, NULL, &damaged_rect);

    PaintRect(gfx::Rect(damaged_rect));
  }
  ResetScrollRect();

  // Paint the canvas if necessary.  Allow painting to generate extra rects the
  // first time we call it.  This is necessary because some WebCore rendering
  // objects update their layout only when painted.
  for (int i = 0; i < 2; ++i) {
    paint_rect_ = client_rect.Intersect(paint_rect_);
    if (!paint_rect_.IsEmpty()) {
      gfx::Rect rect(paint_rect_);
      paint_rect_ = gfx::Rect();

      DLOG_IF(WARNING, i == 1) << "painting caused additional invalidations";
      PaintRect(rect);
    }
  }
  DCHECK(paint_rect_.IsEmpty());

  // Paint to the screen
  PAINTSTRUCT ps;
  BeginPaint(view_, &ps);
  canvas_->getTopPlatformDevice().drawToHDC(ps.hdc,
                                            ps.rcPaint.left,
                                            ps.rcPaint.top,
                                            &ps.rcPaint);
  EndPaint(view_, &ps);

  // Draw children
  UpdateWindow(view_);
}

WebScreenInfo WebWidgetHost::GetScreenInfo() {
  return WebScreenInfoFactory::screenInfo(view_);
}

void WebWidgetHost::Resize(LPARAM lparam) {
  // Force an entire re-paint.  TODO(darin): Maybe reuse this memory buffer.
  DiscardBackingStore();

  webwidget_->resize(WebSize(LOWORD(lparam), HIWORD(lparam)));
}

void WebWidgetHost::MouseEvent(UINT message, WPARAM wparam, LPARAM lparam) {
  const WebMouseEvent& event = WebInputEventFactory::mouseEvent(
      view_, message, wparam, lparam);
  webwidget_->handleInputEvent(event);
  switch (event.type) {
    case WebInputEvent::MouseMove:
      TrackMouseLeave(true);
      break;
    case WebInputEvent::MouseLeave:
      TrackMouseLeave(false);
      break;
    case WebInputEvent::MouseDown:
      SetCapture(view_);
      // This mimics a temporary workaround in RenderWidgetHostViewWin for bug
      // 765011 to get focus when the mouse is clicked. This happens after the
      // mouse down event is sent to the renderer because normally Windows does
      // a WM_SETFOCUS after WM_LBUTTONDOWN.
      ::SetFocus(view_);
      break;
    case WebInputEvent::MouseUp:
      if (GetCapture() == view_)
        ReleaseCapture();
      break;
  }
}

void WebWidgetHost::WheelEvent(WPARAM wparam, LPARAM lparam) {
  const WebMouseWheelEvent& event = WebInputEventFactory::mouseWheelEvent(
      view_, WM_MOUSEWHEEL, wparam, lparam);
  webwidget_->handleInputEvent(event);
}

void WebWidgetHost::KeyEvent(UINT message, WPARAM wparam, LPARAM lparam) {
  const WebKeyboardEvent& event = WebInputEventFactory::keyboardEvent(
      view_, message, wparam, lparam);
  webwidget_->handleInputEvent(event);
}

void WebWidgetHost::CaptureLostEvent() {
  webwidget_->mouseCaptureLost();
}

void WebWidgetHost::SetFocus(bool enable) {
  // Ignore focus calls in layout test mode so that tests don't mess with each
  // other's focus when running in parallel.
  if (!TestShell::layout_test_mode())
    webwidget_->setFocus(enable);
}

void WebWidgetHost::TrackMouseLeave(bool track) {
  if (track == track_mouse_leave_)
    return;
  track_mouse_leave_ = track;

  DCHECK(view_);

  TRACKMOUSEEVENT tme;
  tme.cbSize = sizeof(TRACKMOUSEEVENT);
  tme.dwFlags = TME_LEAVE;
  if (!track_mouse_leave_)
    tme.dwFlags |= TME_CANCEL;
  tme.hwndTrack = view_;

  TrackMouseEvent(&tme);
}

void WebWidgetHost::ResetScrollRect() {
  scroll_rect_ = gfx::Rect();
  scroll_dx_ = 0;
  scroll_dy_ = 0;
}

void WebWidgetHost::PaintRect(const gfx::Rect& rect) {
#ifndef NDEBUG
  DCHECK(!painting_);
#endif
  DCHECK(canvas_.get());

  set_painting(true);
  webwidget_->paint(canvas_.get(), rect);
  set_painting(false);
}
<|endoftext|>


<commit_before>#include "palabos3D.h"
#include "palabos3D.hh"
#include <vector>
#include <cmath>

using namespace plb;
using namespace plb::descriptors;
using namespace std;

typedef double T;
typedef Array<T,3> Velocity;
//#define DESCRIPTOR descriptors::D3Q27Descriptor
#define DESCRIPTOR MRTD3Q19Descriptor
 typedef MRTdynamics<T,DESCRIPTOR> BackgroundDynamics;
 typedef AnechoicMRTdynamics<T,DESCRIPTOR> AnechoicBackgroundDynamics;

// ---------------------------------------------
// Includes of acoustics resources
#include "acoustics/acoustics3D.h"
using namespace plb_acoustics_3D;
// ---------------------------------------------

const T rho0 = 1;
const T drho = rho0/10;

void writeGifs(MultiBlockLattice3D<T,DESCRIPTOR>& lattice, plint iter){
    const plint nx = lattice.getNx();
    const plint ny = lattice.getNy();
    const plint nz = lattice.getNz();

    const plint imSize = 600;
    ImageWriter<T> imageWriter("leeloo");

    Box3D slice(0, nx-1, 0, ny-1, nz/2, nz/2);
    //imageWriter.writeGif(createFileName("u", iT, 6),
     //*computeDensity(lattice), );

    imageWriter.writeGif( createFileName("rho", iter, 6),
    *computeDensity(lattice, slice),
    (T) rho0 - drho/1000000, (T) rho0 + drho/1000000, imSize, imSize);
}

void writeVTK(MultiBlockLattice3D<T,DESCRIPTOR>& lattice, plint iter){
        VtkImageOutput3D<T> vtkOut(createFileName("vtk", iter, 6), 1.);
        vtkOut.writeData<float>(*computeDensity(lattice), "density", 1.);
        vtkOut.writeData<3,float>(*computeVelocity(lattice), "velocity", 1.);
}

int main(int argc, char **argv){
    plbInit(&argc, &argv);
    std::string fNameOut = "tmp";

    const plint nx = 350;
    const plint ny = 160;
    const plint nz = 160;
    const T lattice_speed_sound = 1/sqrt(3);

    const T omega = 1.985;
    const plint maxT = 120000;

    Array<T,3> u0(0, 0, 0);

    global::directories().setOutputDir(fNameOut+"/");

    //Build geometry
    Array<T,3> centerLB(30, ny/2, nz/2);
    //TriangleSet<T> triangleSet("Duto_Fechado.STL");
    //Array<T,3> center(param.cx, param.cy, param.cz);
    TriangleSet<T> triangleSet;
    pcout << "construindo o duto" << std::endl;
    /*
    (Array<T,3> const& inletCenter, T externRadius, T internRadius,
                                 T length, plint nAxial, plint nCirc)
                                 */
    T thickness_duct = 4;
    T radius = 20;
    triangleSet = constructDuct(centerLB, radius + thickness_duct, radius
    , (T) 250, (plint) 10, (plint) 50);

    //triangleSet = constructSphere<T>(centerLB, (T) 10, (plint)40);
    /*TriangleSet<T> triangleSet("duto_fechado.STL");
    triangleSet.translate(centerLB);*/
    // rotate: Z, X, Y in radians
    //triangleSet.rotate((T) 0, (T) 0, (T) 0);
    //triangleSet.scale((T) 3.95253e+2);

    //   tube to more efficient data structures that are internally used by palabos.
    //   The TriangleBoundary3D structure will be later used to assign proper boundary conditions.
    plint borderWidth = 1;  // Because the Guo boundary condition acts in a one-cell layer.
                        // Requirement: margin>=borderWidth.
    plint margin      = 1;  // Extra margin of allocated cells around the obstacle.
    plint extraLayer  = 0;  // Make the bounding box larger; for visualization purposes
                        //   only. For the simulation, it is OK to have extraLayer=0.
    plint xDirection = 0;
    DEFscaledMesh<T> defMesh(triangleSet, 0, xDirection, margin, Dot3D(0, 0, 0));
    defMesh.setDx((T) 1.);

    pcout << "Valor do Dx: " << defMesh.getDx() << std::endl;
    Array<T, 3> physical_position = defMesh.getPhysicalLocation();
    pcout << "posicao fisica em x: " << physical_position[0] << std::endl;
    pcout << "posicao fisica em y: " << physical_position[1] << std::endl;
    pcout << "posicao fisica em z: " << physical_position[2] << std::endl;
    //Array< T, 3 > position_lattice(50, ny/2, nz/2);
    //defMesh.setPhysicalLocation(position_lattice);
    Array<T, 3> physical_position_c = defMesh.getPhysicalLocation();
    pcout << "posicao fisica em x_c: " << physical_position_c[0] << std::endl;
    pcout << "posicao fisica em y_c: " << physical_position_c[1] << std::endl;
    pcout << "posicao fisica em z_c: " << physical_position_c[2] << std::endl;
    defMesh.getMesh().inflate();
    TriangleBoundary3D<T> boundary(defMesh);

    boundary.getMesh().writeBinarySTL("duct.stl");
    pcout << "Number of triangles: " << boundary.getMesh().getNumTriangles() << std::endl;
    //   handled by the following voxelization process.
    pcout << std::endl << "Voxelizing the domain." << std::endl;
    const int flowType = voxelFlag::outside;
    const plint extendedEnvelopeWidth = 2;
    const plint blockSize = 0; // Zero means: no sparse representation.
     // Because the Guo boundary condition needs 2-cell neighbor access.
    Box3D full_domain(0, nx-1, 0, ny-1, 0, nz-1);
    VoxelizedDomain3D<T> voxelizedDomain (
            boundary, flowType, full_domain, borderWidth, extendedEnvelopeWidth, blockSize);
    pcout << getMultiBlockInfo(voxelizedDomain.getVoxelMatrix()) << std::endl;

    // Build lattice and set default dynamics
    //-------------------------------------
    MultiBlockLattice3D<T,DESCRIPTOR> *lattice =
    new MultiBlockLattice3D<T,DESCRIPTOR>(voxelizedDomain.getVoxelMatrix());

    // Setting anechoic dynamics like this way
    defineDynamics(*lattice, lattice->getBoundingBox(),
                new AnechoicBackgroundDynamics(omega));
    defineDynamics(*lattice, lattice->getBoundingBox(),
                new BackgroundDynamics(omega));
    //-------------------------------------

    //Set geometry in lattice
     // The Guo off *lattice boundary condition is set up.
    pcout << "Creating boundary condition." << std::endl;
    BoundaryProfiles3D<T,Velocity> profiles;
    //profiles.setWallProfile(new NoSlipProfile3D<T>);

    bool useAllDirections = true; // Extrapolation scheme for the off *lattice boundary condition.
    GuoOffLatticeModel3D<T,DESCRIPTOR>* model =
            new GuoOffLatticeModel3D<T,DESCRIPTOR> (
                new TriangleFlowShape3D<T,Array<T,3> > (
                    voxelizedDomain.getBoundary(), profiles),
                flowType, useAllDirections );
    bool useRegularized = true;
    // Use an off *lattice boundary condition which is closer in spirit to
    //   regularized boundary conditions.
    model->selectUseRegularizedModel(useRegularized);
    // ---
    OffLatticeBoundaryCondition3D<T,DESCRIPTOR,Velocity> boundaryCondition (
            model, voxelizedDomain, *lattice);
    boundaryCondition.insert();
    defineDynamics(*lattice, voxelizedDomain.getVoxelMatrix(),
     lattice->getBoundingBox(), new NoDynamics<T,DESCRIPTOR>(-999), voxelFlag::inside);

    pcout << "Creation of the lattice." << endl;

    // Switch off periodicity.
    lattice->periodicity().toggleAll(false);

    pcout << "Initilization of rho and u." << endl;
    initializeAtEquilibrium( *lattice, lattice->getBoundingBox(), rho0 , u0 );

    T rhoBar_target = 0;
    const T mach_number = 0.2;
    const T velocity_flow = mach_number*lattice_speed_sound;
    Array<T,3> j_target(0, 0, 0);
    T size_anechoic_buffer = 30;
    defineAnechoicMRTBoards(nx, ny, nz, *lattice, size_anechoic_buffer,
      omega, j_target, j_target, j_target, j_target, j_target, j_target,
      rhoBar_target);

    lattice->initialize();

    pcout << std::endl << "Voxelizing the domain." << std::endl;

    pcout << "Simulation begins" << endl;

    plb_ofstream history_pressures("tmp/history_pressures.dat");
    plb_ofstream history_velocities_x("tmp/history_velocities_x.dat");
    plb_ofstream history_velocities_y("tmp/history_velocities_y.dat");
    plb_ofstream history_velocities_z("tmp/history_velocities_z.dat");
    for (plint iT=0; iT<maxT; ++iT){
        if (iT != 0){
            T lattice_speed_sound = 1/sqrt(3);
            T rho_changing = 1. + drho*sin(2*M_PI*(lattice_speed_sound/20)*iT);
            //Box3D impulse(nx/2 + 50, nx/2 + 50, ny/2 + 50, ny/2 + 50, nz/2 + 50, nz/2 + 50);
            Box3D impulse(centerLB[0] + 10, centerLB[0] + 10, ny/2, ny/2, nz/2, nz/2);
            initializeAtEquilibrium( *lattice, impulse, rho_changing, u0);
        }

        if (iT % 10 == 0 && iT>0) {
            pcout << "Iteration " << iT << endl;
            //writeGifs(lattice,iT);
            writeVTK(*lattice, iT);
        }

        history_pressures << setprecision(10) << lattice->get(nx/2+30, ny/2+30, nz/2+30).computeDensity() - rho0 << endl;
        Array<T,3> velocities;
        lattice->get(nx/2+30, ny/2+30, nz/2+30).computeVelocity(velocities);
        history_velocities_x << setprecision(10) << velocities[0]/lattice_speed_sound << endl;
        history_velocities_y << setprecision(10) << velocities[1]/lattice_speed_sound << endl;
        history_velocities_z << setprecision(10) << velocities[2]/lattice_speed_sound << endl;
        lattice->collideAndStream();

    }

    pcout << "End of simulation at iteration " << endl;
}
<commit_msg>Source sound putted in duct<commit_after>#include "palabos3D.h"
#include "palabos3D.hh"
#include <vector>
#include <cmath>

using namespace plb;
using namespace plb::descriptors;
using namespace std;

typedef double T;
typedef Array<T,3> Velocity;
//#define DESCRIPTOR descriptors::D3Q27Descriptor
#define DESCRIPTOR MRTD3Q19Descriptor
 typedef MRTdynamics<T,DESCRIPTOR> BackgroundDynamics;
 typedef AnechoicMRTdynamics<T,DESCRIPTOR> AnechoicBackgroundDynamics;

// ---------------------------------------------
// Includes of acoustics resources
#include "acoustics/acoustics3D.h"
using namespace plb_acoustics_3D;
// ---------------------------------------------

const T rho0 = 1;
const T drho = rho0/10;

void writeGifs(MultiBlockLattice3D<T,DESCRIPTOR>& lattice, plint iter){
    const plint nx = lattice.getNx();
    const plint ny = lattice.getNy();
    const plint nz = lattice.getNz();

    const plint imSize = 600;
    ImageWriter<T> imageWriter("leeloo");

    Box3D slice(0, nx-1, 0, ny-1, nz/2, nz/2);
    //imageWriter.writeGif(createFileName("u", iT, 6),
     //*computeDensity(lattice), );

    imageWriter.writeGif( createFileName("rho", iter, 6),
    *computeDensity(lattice, slice),
    (T) rho0 - drho/1000000, (T) rho0 + drho/1000000, imSize, imSize);
}

void writeVTK(MultiBlockLattice3D<T,DESCRIPTOR>& lattice, plint iter){
        VtkImageOutput3D<T> vtkOut(createFileName("vtk", iter, 6), 1.);
        vtkOut.writeData<float>(*computeDensity(lattice), "density", 1.);
        vtkOut.writeData<3,float>(*computeVelocity(lattice), "velocity", 1.);
}

int main(int argc, char **argv){
    plbInit(&argc, &argv);
    std::string fNameOut = "tmp";

    const plint nx = 350;
    const plint ny = 160;
    const plint nz = 160;
    const T lattice_speed_sound = 1/sqrt(3);

    const T omega = 1.985;
    const plint maxT = 120000;

    Array<T,3> u0(0, 0, 0);

    global::directories().setOutputDir(fNameOut+"/");

    //Build geometry
    Array<T,3> centerLB(30, ny/2, nz/2);
    //TriangleSet<T> triangleSet("Duto_Fechado.STL");
    //Array<T,3> center(param.cx, param.cy, param.cz);
    TriangleSet<T> triangleSet;
    pcout << "construindo o duto" << std::endl;
    /*
    (Array<T,3> const& inletCenter, T externRadius, T internRadius,
                                 T length, plint nAxial, plint nCirc)
                                 */
    T thickness_duct = 4;
    T radius = 20;
    triangleSet = constructDuct(centerLB, radius + thickness_duct, radius
    , (T) 250, (plint) 10, (plint) 50);

    //triangleSet = constructSphere<T>(centerLB, (T) 10, (plint)40);
    /*TriangleSet<T> triangleSet("duto_fechado.STL");
    triangleSet.translate(centerLB);*/
    // rotate: Z, X, Y in radians
    //triangleSet.rotate((T) 0, (T) 0, (T) 0);
    //triangleSet.scale((T) 3.95253e+2);

    //   tube to more efficient data structures that are internally used by palabos.
    //   The TriangleBoundary3D structure will be later used to assign proper boundary conditions.
    plint borderWidth = 1;  // Because the Guo boundary condition acts in a one-cell layer.
                        // Requirement: margin>=borderWidth.
    plint margin      = 1;  // Extra margin of allocated cells around the obstacle.
    plint extraLayer  = 0;  // Make the bounding box larger; for visualization purposes
                        //   only. For the simulation, it is OK to have extraLayer=0.
    plint xDirection = 0;
    DEFscaledMesh<T> defMesh(triangleSet, 0, xDirection, margin, Dot3D(0, 0, 0));
    defMesh.setDx((T) 1.);

    pcout << "Valor do Dx: " << defMesh.getDx() << std::endl;
    Array<T, 3> physical_position = defMesh.getPhysicalLocation();
    pcout << "posicao fisica em x: " << physical_position[0] << std::endl;
    pcout << "posicao fisica em y: " << physical_position[1] << std::endl;
    pcout << "posicao fisica em z: " << physical_position[2] << std::endl;
    //Array< T, 3 > position_lattice(50, ny/2, nz/2);
    //defMesh.setPhysicalLocation(position_lattice);
    Array<T, 3> physical_position_c = defMesh.getPhysicalLocation();
    pcout << "posicao fisica em x_c: " << physical_position_c[0] << std::endl;
    pcout << "posicao fisica em y_c: " << physical_position_c[1] << std::endl;
    pcout << "posicao fisica em z_c: " << physical_position_c[2] << std::endl;
    defMesh.getMesh().inflate();
    TriangleBoundary3D<T> boundary(defMesh);

    boundary.getMesh().writeBinarySTL("duct.stl");
    pcout << "Number of triangles: " << boundary.getMesh().getNumTriangles() << std::endl;
    //   handled by the following voxelization process.
    pcout << std::endl << "Voxelizing the domain." << std::endl;
    const int flowType = voxelFlag::outside;
    const plint extendedEnvelopeWidth = 2;
    const plint blockSize = 0; // Zero means: no sparse representation.
     // Because the Guo boundary condition needs 2-cell neighbor access.
    Box3D full_domain(0, nx-1, 0, ny-1, 0, nz-1);
    VoxelizedDomain3D<T> voxelizedDomain (
            boundary, flowType, full_domain, borderWidth, extendedEnvelopeWidth, blockSize);
    pcout << getMultiBlockInfo(voxelizedDomain.getVoxelMatrix()) << std::endl;

    // Build lattice and set default dynamics
    //-------------------------------------
    MultiBlockLattice3D<T,DESCRIPTOR> *lattice =
    new MultiBlockLattice3D<T,DESCRIPTOR>(voxelizedDomain.getVoxelMatrix());

    // Setting anechoic dynamics like this way
    defineDynamics(*lattice, lattice->getBoundingBox(),
                new AnechoicBackgroundDynamics(omega));
    defineDynamics(*lattice, lattice->getBoundingBox(),
                new BackgroundDynamics(omega));
    //-------------------------------------

    //Set geometry in lattice
     // The Guo off *lattice boundary condition is set up.
    pcout << "Creating boundary condition." << std::endl;
    BoundaryProfiles3D<T,Velocity> profiles;
    //profiles.setWallProfile(new NoSlipProfile3D<T>);

    bool useAllDirections = true; // Extrapolation scheme for the off *lattice boundary condition.
    GuoOffLatticeModel3D<T,DESCRIPTOR>* model =
            new GuoOffLatticeModel3D<T,DESCRIPTOR> (
                new TriangleFlowShape3D<T,Array<T,3> > (
                    voxelizedDomain.getBoundary(), profiles),
                flowType, useAllDirections );
    bool useRegularized = true;
    // Use an off *lattice boundary condition which is closer in spirit to
    //   regularized boundary conditions.
    model->selectUseRegularizedModel(useRegularized);
    // ---
    OffLatticeBoundaryCondition3D<T,DESCRIPTOR,Velocity> boundaryCondition (
            model, voxelizedDomain, *lattice);
    boundaryCondition.insert();
    defineDynamics(*lattice, voxelizedDomain.getVoxelMatrix(),
     lattice->getBoundingBox(), new NoDynamics<T,DESCRIPTOR>(-999), voxelFlag::inside);

    pcout << "Creation of the lattice." << endl;

    // Switch off periodicity.
    lattice->periodicity().toggleAll(false);

    pcout << "Initilization of rho and u." << endl;
    initializeAtEquilibrium( *lattice, lattice->getBoundingBox(), rho0 , u0 );

    // Set anechoic condition on boundaries
    T rhoBar_target = 0;
    const T mach_number = 0.2;
    const T velocity_flow = mach_number*lattice_speed_sound;
    Array<T,3> j_target(0, 0, 0);
    T size_anechoic_buffer = 30;
    defineAnechoicMRTBoards(nx, ny, nz, *lattice, size_anechoic_buffer,
      omega, j_target, j_target, j_target, j_target, j_target, j_target,
      rhoBar_target);

    lattice->initialize();

    pcout << std::endl << "Voxelizing the domain." << std::endl;

    pcout << "Simulation begins" << endl;

    plb_ofstream history_pressures("tmp/history_pressures.dat");
    plb_ofstream history_velocities_x("tmp/history_velocities_x.dat");
    plb_ofstream history_velocities_y("tmp/history_velocities_y.dat");
    plb_ofstream history_velocities_z("tmp/history_velocities_z.dat");
    for (plint iT=0; iT<maxT; ++iT){

        if (iT != 0){
            T lattice_speed_sound = 1/sqrt(3);
            T rho_changing = 1. + drho*sin(2*M_PI*(lattice_speed_sound/20)*iT);

            // Set source sound
            T rhoBar_target_source = rho_changing - 1;
            plint source_begin = centerLB[0] + 10;
            plint source_thickness = 30;
            plint center_z = centerLB[2];
            plint center_y = centerLB[1];
            plint source_radius = radius;
            for(plint x = source_begin; x <= source_begin + source_thickness; ++x){
                DotList3D points_to_aplly_dynamics;
                AnechoicBackgroundDynamics *anechoicDynamics =
                new AnechoicBackgroundDynamics(omega);
                T delta_efective = 30 - x;
                anechoicDynamics->setDelta(delta_efective);
                anechoicDynamics->setRhoBar_target(rhoBar_target_source);
                anechoicDynamics->setJ_target(j_target);

                for (plint z = center_z - source_radius;
                    z <= center_z + source_radius; ++z){
                    for (plint y = center_y - source_radius;
                        y <= center_y + source_radius; ++y){
                        if (plb::util::sqr(y) + plb::util::sqr(z)
                         <= plb::util::sqr(source_radius)){
                            points_to_aplly_dynamics.addDot(Dot3D(x,y,z));
                        }
                    }
                }
                Box3D test_source(centerLB[0] + 10, centerLB[0] + 40,
                    ny/2 - source_radius/sqrt(2),
                    ny/2 + source_radius/sqrt(2),
                    nz/2 - source_radius/sqrt(2),
                    nz/2 + source_radius/sqrt(2));
                defineDynamics(*lattice, test_source, anechoicDynamics);
            }

            //Box3D impulse(nx/2 + 50, nx/2 + 50, ny/2 + 50, ny/2 + 50, nz/2 + 50, nz/2 + 50);
            Box3D impulse(centerLB[0] + 70, centerLB[0] + 70, ny/2, ny/2, nz/2, nz/2);
            //initializeAtEquilibrium( *lattice, impulse, rho_changing, u0);
        }

        if (iT % 10 == 0 && iT>0) {
            pcout << "Iteration " << iT << endl;
            //writeGifs(lattice,iT);
            writeVTK(*lattice, iT);
        }

        history_pressures << setprecision(10) << lattice->get(nx/2+30, ny/2+30, nz/2+30).computeDensity() - rho0 << endl;
        Array<T,3> velocities;
        lattice->get(nx/2+30, ny/2+30, nz/2+30).computeVelocity(velocities);
        history_velocities_x << setprecision(10) << velocities[0]/lattice_speed_sound << endl;
        history_velocities_y << setprecision(10) << velocities[1]/lattice_speed_sound << endl;
        history_velocities_z << setprecision(10) << velocities[2]/lattice_speed_sound << endl;
        lattice->collideAndStream();

    }

    pcout << "End of simulation at iteration " << endl;
}
<|endoftext|>


<commit_before>//=====================================================================//
/*!	@file
	@brief	GUI widget_dialog クラス
	@author	平松邦仁 (hira@rvf-rc45.net)
*/
//=====================================================================//
#include "widgets/widget_dialog.hpp"
#include "widgets/widget_utils.hpp"

namespace gui {

	//-----------------------------------------------------------------//
	/*!
		@brief	文書の設定
		@param[in]	text	文書
	*/
	//-----------------------------------------------------------------//
	void widget_dialog::set_text(const std::string& text)
	{
		if(text_) {
			text_->at_local_param().text_param_.text_ = text;
		}
	}

	//-----------------------------------------------------------------//
	/*!
		@brief	初期化
	*/
	//-----------------------------------------------------------------//
	void widget_dialog::initialize()
	{
		// 自由な大きさの変更を禁止
		at_param().state_.set(widget::state::SIZE_LOCK);
		at_param().state_.set(widget::state::SERVICE);

		param_.plate_param_.resizeble_ = true;
		// フレームの生成
		objh_ = frame_init(wd_, at_param(), param_.plate_param_, param_.color_param_);

		// 構成部品の作成
		const vtx::spos& size = get_rect().size;

		short fw = param_.plate_param_.frame_width_;
		short btn_width = 100;
		short btn_height = 40;
		short space_height = 10;
		vtx::spos btn_size(btn_width, btn_height);
		short y = size.y - space_height - btn_height;
		if(param_.style_ == param::style::OK) {
			widget::param wp(vtx::srect(vtx::spos(
				(size.x - fw - btn_width) / 2, y),
				btn_size), this);
			widget_button::param wp_("OK");
			ok_ = wd_.add_widget<widget_button>(wp, wp_);
		} else if(param_.style_ == param::style::CANCEL_OK) {
			short ofs = (size.x - fw * 2 - btn_width * 2) / 3;
			{
				widget::param wp(vtx::srect(vtx::spos(fw + ofs, y),
				btn_size), this);
				widget_button::param wp_("Cancel");
				ok_ = wd_.add_widget<widget_button>(wp, wp_);
			}
			{
				widget::param wp(vtx::srect(vtx::spos(fw + ofs + btn_width + ofs, y),
				btn_size), this);
				widget_button::param wp_("OK");
				cancel_ = wd_.add_widget<widget_button>(wp, wp_);
			}
		}

		{
			param_.text_area_.size.x = size.x - param_.text_area_.org.x * 2;
			param_.text_area_.size.y = size.y - param_.text_area_.org.y * 2
				- space_height - btn_height;
			widget::param wp(param_.text_area_, this);
			widget_text::param wp_;
			text_ = wd_.add_widget<widget_text>(wp, wp_);
		}
	}

	//-----------------------------------------------------------------//
	/*!
		@brief	アップデート
	*/
	//-----------------------------------------------------------------//
	void widget_dialog::update()
	{
		bool f = false;
		if(ok_ && ok_->get_selected()) {
			param_.return_ok_ = true;
			f = true;
		}
		if(cancel_ && cancel_->get_selected()) {
			param_.return_cancel_ = true;
			f = true;
		}

		if(f) {
			enable(false);
		}
	}

	//-----------------------------------------------------------------//
	/*!
		@brief	レンダリング
	*/
	//-----------------------------------------------------------------//
	void widget_dialog::render()
	{
		if(objh_ == 0) return;

		wd_.at_mobj().resize(objh_, get_param().rect_.size);
		glEnable(GL_TEXTURE_2D);
		wd_.at_mobj().draw(objh_, gl::mobj::normal, 0, 0);
	}

	//-----------------------------------------------------------------//
	/*!
		@brief	廃棄
	*/
	//-----------------------------------------------------------------//
	void widget_dialog::destroy_()
	{
		wd_.del_widget(cancel_);
		wd_.del_widget(ok_);
		wd_.del_widget(text_);
	}
}
<commit_msg>ダイアログのテキスト表示、標準配置の修正<commit_after>//=====================================================================//
/*!	@file
	@brief	GUI widget_dialog クラス
	@author	平松邦仁 (hira@rvf-rc45.net)
*/
//=====================================================================//
#include "widgets/widget_dialog.hpp"
#include "widgets/widget_utils.hpp"

namespace gui {

	//-----------------------------------------------------------------//
	/*!
		@brief	文書の設定
		@param[in]	text	文書
	*/
	//-----------------------------------------------------------------//
	void widget_dialog::set_text(const std::string& text)
	{
		if(text_) {
			text_->at_local_param().text_param_.text_ = text;
		}
	}

	//-----------------------------------------------------------------//
	/*!
		@brief	初期化
	*/
	//-----------------------------------------------------------------//
	void widget_dialog::initialize()
	{
		// 自由な大きさの変更を禁止
		at_param().state_.set(widget::state::SIZE_LOCK);
		at_param().state_.set(widget::state::SERVICE);

		param_.plate_param_.resizeble_ = true;
		// フレームの生成
		objh_ = frame_init(wd_, at_param(), param_.plate_param_, param_.color_param_);

		// 構成部品の作成
		const vtx::spos& size = get_rect().size;

		short fw = param_.plate_param_.frame_width_;
		short btn_width = 100;
		short btn_height = 40;
		short space_height = 10;
		vtx::spos btn_size(btn_width, btn_height);
		short y = size.y - space_height - btn_height;
		if(param_.style_ == param::style::OK) {
			widget::param wp(vtx::srect(vtx::spos(
				(size.x - fw - btn_width) / 2, y),
				btn_size), this);
			widget_button::param wp_("OK");
			ok_ = wd_.add_widget<widget_button>(wp, wp_);
		} else if(param_.style_ == param::style::CANCEL_OK) {
			short ofs = (size.x - fw * 2 - btn_width * 2) / 3;
			{
				widget::param wp(vtx::srect(vtx::spos(fw + ofs, y),
				btn_size), this);
				widget_button::param wp_("Cancel");
				ok_ = wd_.add_widget<widget_button>(wp, wp_);
			}
			{
				widget::param wp(vtx::srect(vtx::spos(fw + ofs + btn_width + ofs, y),
				btn_size), this);
				widget_button::param wp_("OK");
				cancel_ = wd_.add_widget<widget_button>(wp, wp_);
			}
		}

		{
			param_.text_area_.size.x = size.x - param_.text_area_.org.x * 2;
			param_.text_area_.size.y = size.y - param_.text_area_.org.y * 2
				- space_height - btn_height;
			widget::param wp(param_.text_area_, this);
			widget_text::param wp_;
			wp_.text_param_.placement_.hpt = vtx::placement::holizontal::CENTER;
			wp_.text_param_.placement_.vpt = vtx::placement::vertical::CENTER;
			text_ = wd_.add_widget<widget_text>(wp, wp_);
		}
	}

	//-----------------------------------------------------------------//
	/*!
		@brief	アップデート
	*/
	//-----------------------------------------------------------------//
	void widget_dialog::update()
	{
		bool f = false;
		if(ok_ && ok_->get_selected()) {
			param_.return_ok_ = true;
			f = true;
		}
		if(cancel_ && cancel_->get_selected()) {
			param_.return_cancel_ = true;
			f = true;
		}

		if(f) {
			enable(false);
		}
	}

	//-----------------------------------------------------------------//
	/*!
		@brief	レンダリング
	*/
	//-----------------------------------------------------------------//
	void widget_dialog::render()
	{
		if(objh_ == 0) return;

		wd_.at_mobj().resize(objh_, get_param().rect_.size);
		glEnable(GL_TEXTURE_2D);
		wd_.at_mobj().draw(objh_, gl::mobj::normal, 0, 0);
	}

	//-----------------------------------------------------------------//
	/*!
		@brief	廃棄
	*/
	//-----------------------------------------------------------------//
	void widget_dialog::destroy_()
	{
		wd_.del_widget(cancel_);
		wd_.del_widget(ok_);
		wd_.del_widget(text_);
	}
}
<|endoftext|>


<commit_before>/* BEGIN_COMMON_COPYRIGHT_HEADER
 * (c)LGPL2+
 *
 * Flacon - audio File Encoder
 * https://github.com/flacon/flacon
 *
 * Copyright: 2012-2013
 *   Alexander Sokoloff <sokoloff.a@gmail.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 Lesser 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
 *
 * END_COMMON_COPYRIGHT_HEADER */

#include "gain.h"
#include "profiles.h"
#include "settings.h"

#include <QProcess>
#include <QDir>
#include <QTextStream>
#include <QDebug>
#include <QLoggingCategory>

namespace {
Q_LOGGING_CATEGORY(LOG, "Converter")
}

using namespace Conv;

/************************************************
 *
 ************************************************/
Gain::Gain(const Profile &profile, QObject *parent) :
    Worker(parent),
    mProfile(profile)
{
}

/************************************************
 *
 ************************************************/
void Gain::addTrack(const ConvTrack &track, const QString &file)
{
    mJobs << Job { track, file };
}

/************************************************
 *
 ************************************************/
void Gain::run()
{
    QStringList files;
    for (const Job &job : qAsConst(mJobs)) {
        emit trackProgress(job.track, TrackState::CalcGain, 0);
        files << QDir::toNativeSeparators(job.file);
    }

    QStringList args = programArgs(files, mProfile.gainType());
    QString     prog = args.takeFirst();

    qCDebug(LOG) << "Start gain:" << debugProgramArgs(prog, args);

    QProcess process;

    process.start(prog, args);
    process.waitForFinished(-1);

    if (process.exitCode() != 0) {
        qWarning() << "Gain command failed: " << debugProgramArgs(prog, args);
        QString msg = tr("Gain error:\n") + QString::fromLocal8Bit(process.readAllStandardError());
        emit    error(mJobs.first().track, msg);
        return;
    }

    for (const Job &job : qAsConst(mJobs)) {
        emit trackProgress(job.track, TrackState::WriteGain, 100);
        emit trackReady(job.track, job.file);
    }
}

QString Gain::programPath() const
{
    return Settings::i()->programName(programName());
}
<commit_msg>Handling errors of external programs in the gain<commit_after>/* BEGIN_COMMON_COPYRIGHT_HEADER
 * (c)LGPL2+
 *
 * Flacon - audio File Encoder
 * https://github.com/flacon/flacon
 *
 * Copyright: 2012-2013
 *   Alexander Sokoloff <sokoloff.a@gmail.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 Lesser 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
 *
 * END_COMMON_COPYRIGHT_HEADER */

#include "gain.h"
#include "profiles.h"
#include "settings.h"

#include <QProcess>
#include <QDir>
#include <QTextStream>
#include <QDebug>
#include <QLoggingCategory>
#include "extprogram.h"

namespace {
Q_LOGGING_CATEGORY(LOG, "Converter")
}

using namespace Conv;

/************************************************
 *
 ************************************************/
Gain::Gain(const Profile &profile, QObject *parent) :
    Worker(parent),
    mProfile(profile)
{
}

/************************************************
 *
 ************************************************/
void Gain::addTrack(const ConvTrack &track, const QString &file)
{
    mJobs << Job { track, file };
}

/************************************************
 *
 ************************************************/
void Gain::run()
{
    QStringList files;
    for (const Job &job : qAsConst(mJobs)) {
        emit trackProgress(job.track, TrackState::CalcGain, 0);
        files << QDir::toNativeSeparators(job.file);
    }

    QStringList args = programArgs(files, mProfile.gainType());
    QString     prog = args.takeFirst();

    qCDebug(LOG) << "Start gain:" << debugProgramArgs(prog, args);

    ExtProgram process;

    try {
        process.start(prog, args);
        process.waitForFinished(-1);
    }
    catch (const FlaconError &err) {
        QString msg = tr("Gain error:\n") + err.what();
        emit    error(mJobs.first().track, msg);
        return;
    }

    if (process.exitCode() != 0) {
        qWarning() << "Gain command failed: " << debugProgramArgs(prog, args);
        QString msg = tr("Gain error:\n") + QString::fromLocal8Bit(process.readAllStandardError());
        emit    error(mJobs.first().track, msg);
        return;
    }

    for (const Job &job : qAsConst(mJobs)) {
        emit trackProgress(job.track, TrackState::WriteGain, 100);
        emit trackReady(job.track, job.file);
    }
}

QString Gain::programPath() const
{
    return Settings::i()->programName(programName());
}
<|endoftext|>


<commit_before>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this file,
 * You can obtain one at http://mozilla.org/MPL/2.0/. */
#include <map>
#include <string>

#include "MessageHandler.h"
#include "NfcService.h"
#include "NfcIpcSocket.h"
#include "NfcUtil.h"
#include "NdefMessage.h"
#include "NdefRecord.h"
#include <jansson.h>

#undef LOG_TAG
#define LOG_TAG "nfcd"
#include <utils/Log.h>

using android::Parcel;

void MessageHandler::initialize()
{
}

void MessageHandler::notifyTechDiscovered(Parcel& parcel, void* data)
{

  INfcTag* pINfcTag = reinterpret_cast<INfcTag*>(data);
  std::vector<int>& techList = pINfcTag->getTechList();

  //TODO write SessionId.
  int numberOfTech = techList.size();
  parcel.writeInt32(numberOfTech);
  for (int i = 0; i < numberOfTech; i++) {
    parcel->writeInt32(techList[i]);
  }
  sendResponse(parcel);
}

// static
void MessageHandler::processRequest(const uint8_t* data, size_t dataLen)
{
  Parcel parcel;
  int32_t sizeLe, size, request, token;
  uint32_t status;

  ALOGD("%s enter data=%p, dataLen=%d", __func__, data, dataLen);
  parcel.setData((uint8_t*)data, dataLen);
  status = parcel.readInt32(&request);
  status = parcel.readInt32(&token);

  if (status != 0) {
    ALOGE("Invalid request block");
    return;
  }

  switch (request) {
    case NFC_REQUEST_READ_NDEF:
      handleReadNdefRequest(parcel, token);
      break;
    case NFC_REQUEST_WRITE_NDEF:
      handleWriteNdefRequest(parcel, token);
      break;
    case NFC_REQUEST_CONNECT:
      handleConnectRequest(parcel, token);
      break;
    case NFC_REQUEST_CLOSE:
      handleCloseRequest(parcel, token);
      break;
    default:
      ALOGE("Unhandled Request %d", request);
      break;
  }
}

// static
void MessageHandler::processResponse(NfcRequest request, int token, void* data)
{
  ALOGD("%s enter request=%d, token=%d ", __func__, request, token);
  Parcel parcel;
  parcel.writeInt32(NFCC_MESSAGE_RESPONSE);
  parcel.writeInt32(token);
  parcel.writeInt32(0); //error code

  switch (request) {
    case NFC_REQUEST_READ_NDEF:
      handleReadNdefResponse(parcel, data);
      break;
    case NFC_REQUEST_CONNECT:
      handleConnectResponse(parcel);
      break;
  }
}

// static
void MessageHandler::processNotification(NfcNotification notification, void* data)
{
  Parcel parcel;
  parcel.writeInt32(NFCC_MESSAGE_NOTIFICATION);
  parcel.writeInt32(notification);

  switch (notification) {
    case NFC_NOTIFICATION_TECH_DISCOVERED:
      notifyTechDiscovered(parcel, data);
      break;
  }
}

// static
void MessageHandler::sendResponse(Parcel& parcel)
{
  NfcIpcSocket::writeToOutgoingQueue(const_cast<uint8_t*>(parcel.data()), parcel.dataSize());
}

#if 0
bool MessageHandler::handleWriteNdef(const char *input, size_t length)
{
  return true;
}

bool MessageHandler::handleNdefPush(const char *input, size_t length)
{
  return true;
}

bool MessageHandler::handleNdefDetailsRequest()
{
  return true;
}
#endif

bool MessageHandler::handleReadNdefRequest(Parcel& parcel, int token)
{
  //TODO read SessionId
  return NfcService::handleReadNdefRequest(token);
}

bool MessageHandler::handleWriteNdefRequest(Parcel& parcel, int token)
{
  //TODO read SessionId
  NdefMessagePdu ndefMessagePdu;
  NdefMessage ndefMessage;

  uint32_t numRecords = parcel.readInt32();
  ndefMessagePdu.numRecords = numRecords;
  ndefMessagePdu.records = new NdefRecordPdu[numRecords];

  for (uint32_t i = 0; i < numRecords; i++) {
    ndefMessagePdu.records[i].tnf = parcel.readInt32();

    uint32_t typeLength = parcel.readInt32();
    ndefMessagePdu.records[i].typeLength = typeLength;
    ndefMessagePdu.records[i].type = new uint32_t[typeLength];
    for (uint32_t j = 0; j < typeLength; j++) {
      ndefMessagePdu.records[i].type[j] = parcel.readInt32();
    }

    uint32_t idLength = parcel.readInt32();
    ndefMessagePdu.records[i].idLength = idLength;
    ndefMessagePdu.records[i].id = new uint32_t[idLength];
    for (uint32_t j = 0; j < idLength; j++) {
      ndefMessagePdu.records[i].id[j] = parcel.readInt32();
    }

    uint32_t payloadLength = parcel.readInt32();
    ndefMessagePdu.records[i].payloadLength = payloadLength;
    ndefMessagePdu.records[i].payload = new uint32_t[payloadLength];
    for (uint32_t j = 0; j < payloadLength; j++) {
      ndefMessagePdu.records[i].payload[j] = parcel.readInt32();
    }
  }

  NfcUtil::convertNdefPduToNdefMessage(ndefMessagePdu, ndefMessage);

  for (uint32_t i = 0; i < numRecords; i++) {
    delete[] ndefMessagePdu.records[i].type;
    delete[] ndefMessagePdu.records[i].id;
    delete[] ndefMessagePdu.records[i].payload;
  }
  delete[] ndefMessagePdu.records;

  return NfcService::handleWriteNdef(ndefMessage, token);
}

bool MessageHandler::handleConnectRequest(Parcel& parcel, int token)
{
  int32_t techType = parcel.readInt32();
  ALOGD("%s techType=%d", __func__, techType);
  NfcService::handleConnect(techType, token);
  return false;
}

bool MessageHandler::handleCloseRequest(Parcel& parcel, int token)
{
  return false;
}

bool MessageHandler::handleReadNdefResponse(Parcel& parcel, void* data)
{
  NdefMessage* ndef = reinterpret_cast<NdefMessage*>(data);
  //TODO write SessionId
  int numRecords = ndef->mRecords.size();
  parcel.writeInt32(numRecords);

  for (int i = 0; i < numRecords; i++) {
    NdefRecord &record = ndef->mRecords[i];

    ALOGV("tnf=%u",record.mTnf);
    parcel.writeInt32(record.mTnf);

    uint32_t typeLength = record.mType.size();
    ALOGV("typeLength=%u",typeLength);
    parcel.writeInt32(typeLength);
    for (int j = 0; j < typeLength; j++) {
      ALOGV("mType %d = %u", j, record.mType[j]);
      parcel.writeInt32(record.mType[j]);
    }

    uint8_t idLength = record.mId.size();
    ALOGV("idLength=%d",idLength);
    parcel.writeInt32(idLength);
    for (int j = 0; j < idLength; j++) {
      ALOGV("mId %d = %u", j, record.mId[j]);
      parcel.writeInt32(record.mId[j]);
    }

    uint32_t payloadLength = record.mPayload.size();
    ALOGV("payloadLength=%d",payloadLength);
    parcel.writeInt32(payloadLength);
    for (int j = 0; j < payloadLength; j++) {
      ALOGV("mPayload %d = %u", j, record.mPayload[j]);
      parcel.writeInt32(record.mPayload[j]);
    }
  }

  //TODO check when will parcel release data.
  sendResponse(parcel);
  return false;
}

bool MessageHandler::handleConnectResponse(Parcel& parcel)
{
  sendResponse(parcel);
  return true;
}
<commit_msg>Add handleWriteNdefResponse.<commit_after>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this file,
 * You can obtain one at http://mozilla.org/MPL/2.0/. */
#include <map>
#include <string>

#include "MessageHandler.h"
#include "NfcService.h"
#include "NfcIpcSocket.h"
#include "NfcUtil.h"
#include "NdefMessage.h"
#include "NdefRecord.h"
#include <jansson.h>

#undef LOG_TAG
#define LOG_TAG "nfcd"
#include <utils/Log.h>

using android::Parcel;

void MessageHandler::initialize()
{
}

void MessageHandler::notifyTechDiscovered(Parcel& parcel, void* data)
{

  INfcTag* pINfcTag = reinterpret_cast<INfcTag*>(data);
  std::vector<int>& techList = pINfcTag->getTechList();

  //TODO write SessionId.
  int numberOfTech = techList.size();
  parcel.writeInt32(numberOfTech);
  for (int i = 0; i < numberOfTech; i++) {
    parcel->writeInt32(techList[i]);
  }
  sendResponse(parcel);
}

// static
void MessageHandler::processRequest(const uint8_t* data, size_t dataLen)
{
  Parcel parcel;
  int32_t sizeLe, size, request, token;
  uint32_t status;

  ALOGD("%s enter data=%p, dataLen=%d", __func__, data, dataLen);
  parcel.setData((uint8_t*)data, dataLen);
  status = parcel.readInt32(&request);
  status = parcel.readInt32(&token);

  if (status != 0) {
    ALOGE("Invalid request block");
    return;
  }

  switch (request) {
    case NFC_REQUEST_READ_NDEF:
      handleReadNdefRequest(parcel, token);
      break;
    case NFC_REQUEST_WRITE_NDEF:
      handleWriteNdefRequest(parcel, token);
      break;
    case NFC_REQUEST_CONNECT:
      handleConnectRequest(parcel, token);
      break;
    case NFC_REQUEST_CLOSE:
      handleCloseRequest(parcel, token);
      break;
    default:
      ALOGE("Unhandled Request %d", request);
      break;
  }
}

// static
void MessageHandler::processResponse(NfcRequest request, int token, void* data)
{
  ALOGD("%s enter request=%d, token=%d ", __func__, request, token);
  Parcel parcel;
  parcel.writeInt32(NFCC_MESSAGE_RESPONSE);
  parcel.writeInt32(token);
  parcel.writeInt32(0); //error code

  switch (request) {
    case NFC_REQUEST_READ_NDEF:
      handleReadNdefResponse(parcel, data);
      break;
    case NFC_REQUEST_WRITE_NDEF:
      handleWriteNdefResponse(parcel);
      break;
    case NFC_REQUEST_CONNECT:
      handleConnectResponse(parcel);
      break;
  }
}

// static
void MessageHandler::processNotification(NfcNotification notification, void* data)
{
  Parcel parcel;
  parcel.writeInt32(NFCC_MESSAGE_NOTIFICATION);
  parcel.writeInt32(notification);

  switch (notification) {
    case NFC_NOTIFICATION_TECH_DISCOVERED:
      notifyTechDiscovered(parcel, data);
      break;
  }
}

// static
void MessageHandler::sendResponse(Parcel& parcel)
{
  NfcIpcSocket::writeToOutgoingQueue(const_cast<uint8_t*>(parcel.data()), parcel.dataSize());
}

#if 0
bool MessageHandler::handleWriteNdef(const char *input, size_t length)
{
  return true;
}

bool MessageHandler::handleNdefPush(const char *input, size_t length)
{
  return true;
}

bool MessageHandler::handleNdefDetailsRequest()
{
  return true;
}
#endif

bool MessageHandler::handleReadNdefRequest(Parcel& parcel, int token)
{
  //TODO read SessionId
  return NfcService::handleReadNdefRequest(token);
}

bool MessageHandler::handleWriteNdefRequest(Parcel& parcel, int token)
{
  //TODO read SessionId
  NdefMessagePdu ndefMessagePdu;
  NdefMessage ndefMessage;

  uint32_t numRecords = parcel.readInt32();
  ndefMessagePdu.numRecords = numRecords;
  ndefMessagePdu.records = new NdefRecordPdu[numRecords];

  for (uint32_t i = 0; i < numRecords; i++) {
    ndefMessagePdu.records[i].tnf = parcel.readInt32();

    uint32_t typeLength = parcel.readInt32();
    ndefMessagePdu.records[i].typeLength = typeLength;
    ndefMessagePdu.records[i].type = new uint32_t[typeLength];
    for (uint32_t j = 0; j < typeLength; j++) {
      ndefMessagePdu.records[i].type[j] = parcel.readInt32();
    }

    uint32_t idLength = parcel.readInt32();
    ndefMessagePdu.records[i].idLength = idLength;
    ndefMessagePdu.records[i].id = new uint32_t[idLength];
    for (uint32_t j = 0; j < idLength; j++) {
      ndefMessagePdu.records[i].id[j] = parcel.readInt32();
    }

    uint32_t payloadLength = parcel.readInt32();
    ndefMessagePdu.records[i].payloadLength = payloadLength;
    ndefMessagePdu.records[i].payload = new uint32_t[payloadLength];
    for (uint32_t j = 0; j < payloadLength; j++) {
      ndefMessagePdu.records[i].payload[j] = parcel.readInt32();
    }
  }

  NfcUtil::convertNdefPduToNdefMessage(ndefMessagePdu, ndefMessage);

  for (uint32_t i = 0; i < numRecords; i++) {
    delete[] ndefMessagePdu.records[i].type;
    delete[] ndefMessagePdu.records[i].id;
    delete[] ndefMessagePdu.records[i].payload;
  }
  delete[] ndefMessagePdu.records;

  return NfcService::handleWriteNdef(ndefMessage, token);
}

bool MessageHandler::handleConnectRequest(Parcel& parcel, int token)
{
  int32_t techType = parcel.readInt32();
  ALOGD("%s techType=%d", __func__, techType);
  NfcService::handleConnect(techType, token);
  return false;
}

bool MessageHandler::handleCloseRequest(Parcel& parcel, int token)
{
  return false;
}

bool MessageHandler::handleReadNdefResponse(Parcel& parcel, void* data)
{
  NdefMessage* ndef = reinterpret_cast<NdefMessage*>(data);
  //TODO write SessionId
  int numRecords = ndef->mRecords.size();
  parcel.writeInt32(numRecords);

  for (int i = 0; i < numRecords; i++) {
    NdefRecord &record = ndef->mRecords[i];

    ALOGV("tnf=%u",record.mTnf);
    parcel.writeInt32(record.mTnf);

    uint32_t typeLength = record.mType.size();
    ALOGV("typeLength=%u",typeLength);
    parcel.writeInt32(typeLength);
    for (int j = 0; j < typeLength; j++) {
      ALOGV("mType %d = %u", j, record.mType[j]);
      parcel.writeInt32(record.mType[j]);
    }

    uint8_t idLength = record.mId.size();
    ALOGV("idLength=%d",idLength);
    parcel.writeInt32(idLength);
    for (int j = 0; j < idLength; j++) {
      ALOGV("mId %d = %u", j, record.mId[j]);
      parcel.writeInt32(record.mId[j]);
    }

    uint32_t payloadLength = record.mPayload.size();
    ALOGV("payloadLength=%d",payloadLength);
    parcel.writeInt32(payloadLength);
    for (int j = 0; j < payloadLength; j++) {
      ALOGV("mPayload %d = %u", j, record.mPayload[j]);
      parcel.writeInt32(record.mPayload[j]);
    }
  }

  //TODO check when will parcel release data.
  sendResponse(parcel);
  return true;
}

bool handleWriteNdefResponse(android::Parcel& parcel)
{
  //TODO write SessionId
  sendResponse(parcel);
  return true;
}

bool MessageHandler::handleConnectResponse(Parcel& parcel)
{
  sendResponse(parcel);
  return true;
}
<|endoftext|>