<commit_before>// Copyright 2004-present Facebook. All Rights Reserved.

#include "rsocket/RSocketResponder.h"

#include <folly/io/async/EventBase.h>

namespace rsocket {

yarpl::Reference<yarpl::single::Single<rsocket::Payload>>
RSocketResponder::handleRequestResponse(rsocket::Payload, rsocket::StreamId) {
  return yarpl::single::Singles::error<rsocket::Payload>(
      std::logic_error("handleRequestResponse not implemented"));
}

yarpl::Reference<yarpl::flowable::Flowable<rsocket::Payload>>
RSocketResponder::handleRequestStream(rsocket::Payload, rsocket::StreamId) {
  return yarpl::flowable::Flowables::error<rsocket::Payload>(
      std::logic_error("handleRequestStream not implemented"));
}

yarpl::Reference<yarpl::flowable::Flowable<rsocket::Payload>>
RSocketResponder::handleRequestChannel(
    rsocket::Payload,
    yarpl::Reference<yarpl::flowable::Flowable<rsocket::Payload>>,
    rsocket::StreamId) {
  return yarpl::flowable::Flowables::error<rsocket::Payload>(
      std::logic_error("handleRequestChannel not implemented"));
}

void RSocketResponder::handleFireAndForget(
    rsocket::Payload,
    rsocket::StreamId) {
  // No default implementation, no error response to provide.
}

void RSocketResponder::handleMetadataPush(std::unique_ptr<folly::IOBuf>) {
  // No default implementation, no error response to provide.
}

/// Handles a new Channel requested by the other end.
yarpl::Reference<yarpl::flowable::Subscriber<Payload>>
RSocketResponder::handleRequestChannelCore(
    Payload request,
    StreamId streamId,
    const yarpl::Reference<yarpl::flowable::Subscriber<Payload>>&
    response) noexcept {
  class EagerSubscriberBridge
      : public yarpl::flowable::Subscriber<rsocket::Payload> {
   public:
    void onSubscribe(yarpl::Reference<yarpl::flowable::Subscription>
                         subscription) noexcept override {
      CHECK(!subscription_);
      subscription_ = std::move(subscription);
      if (inner_) {
        inner_->onSubscribe(subscription_);
      }
    }

    void onNext(rsocket::Payload element) noexcept override {
      DCHECK(inner_);
      inner_->onNext(std::move(element));
    }

    void onComplete() noexcept override {
      DCHECK(inner_);
      inner_->onComplete();

      inner_.reset();
      subscription_.reset();
    }

    void onError(folly::exception_wrapper ex) noexcept override {
      DCHECK(inner_);
      inner_->onError(std::move(ex));

      inner_.reset();
      subscription_.reset();
    }

    void subscribe(
        yarpl::Reference<yarpl::flowable::Subscriber<rsocket::Payload>> inner) {
      CHECK(!inner_); // only one call to subscribe is supported
      CHECK(inner);
      inner_ = std::move(inner);
      if (subscription_) {
        inner_->onSubscribe(subscription_);
      }
    }

   private:
    yarpl::Reference<yarpl::flowable::Subscriber<rsocket::Payload>> inner_;
    yarpl::Reference<yarpl::flowable::Subscription> subscription_;
  };

  auto eagerSubscriber = yarpl::make_ref<EagerSubscriberBridge>();
  auto flowable = handleRequestChannel(
      std::move(request),
      yarpl::flowable::Flowables::fromPublisher<Payload>([eagerSubscriber](
          yarpl::Reference<yarpl::flowable::Subscriber<Payload>> subscriber) {
        eagerSubscriber->subscribe(subscriber);
      }),
      std::move(streamId));
  // bridge from the existing eager RequestHandler and old Subscriber type
  // to the lazy Flowable and new Subscriber type
  flowable->subscribe(std::move(response));
  return eagerSubscriber;
}

/// Handles a new Stream requested by the other end.
void RSocketResponder::handleRequestStreamCore(
    Payload request,
    StreamId streamId,
    const yarpl::Reference<yarpl::flowable::Subscriber<Payload>>&
    response) noexcept {
  auto flowable = handleRequestStream(std::move(request), std::move(streamId));
  flowable->subscribe(std::move(response));
}

/// Handles a new inbound RequestResponse requested by the other end.
void RSocketResponder::handleRequestResponseCore(
    Payload request,
    StreamId streamId,
    const yarpl::Reference<yarpl::single::SingleObserver<Payload>>&
    responseObserver) noexcept {
  auto single = handleRequestResponse(std::move(request), streamId);
  single->subscribe(std::move(responseObserver));
}
}
<commit_msg>Client pushes data immediately without any request, which causes server to crash<commit_after>// Copyright 2004-present Facebook. All Rights Reserved.

#include "rsocket/RSocketResponder.h"

#include <folly/io/async/EventBase.h>

namespace rsocket {

yarpl::Reference<yarpl::single::Single<rsocket::Payload>>
RSocketResponder::handleRequestResponse(rsocket::Payload, rsocket::StreamId) {
  return yarpl::single::Singles::error<rsocket::Payload>(
      std::logic_error("handleRequestResponse not implemented"));
}

yarpl::Reference<yarpl::flowable::Flowable<rsocket::Payload>>
RSocketResponder::handleRequestStream(rsocket::Payload, rsocket::StreamId) {
  return yarpl::flowable::Flowables::error<rsocket::Payload>(
      std::logic_error("handleRequestStream not implemented"));
}

yarpl::Reference<yarpl::flowable::Flowable<rsocket::Payload>>
RSocketResponder::handleRequestChannel(
    rsocket::Payload,
    yarpl::Reference<yarpl::flowable::Flowable<rsocket::Payload>>,
    rsocket::StreamId) {
  return yarpl::flowable::Flowables::error<rsocket::Payload>(
      std::logic_error("handleRequestChannel not implemented"));
}

void RSocketResponder::handleFireAndForget(
    rsocket::Payload,
    rsocket::StreamId) {
  // No default implementation, no error response to provide.
}

void RSocketResponder::handleMetadataPush(std::unique_ptr<folly::IOBuf>) {
  // No default implementation, no error response to provide.
}

/// Handles a new Channel requested by the other end.
yarpl::Reference<yarpl::flowable::Subscriber<Payload>>
RSocketResponder::handleRequestChannelCore(
    Payload request,
    StreamId streamId,
    const yarpl::Reference<yarpl::flowable::Subscriber<Payload>>&
        response) noexcept {
  class EagerSubscriberBridge
      : public yarpl::flowable::Subscriber<rsocket::Payload> {
   public:
    void onSubscribe(yarpl::Reference<yarpl::flowable::Subscription>
                         subscription) noexcept override {
      CHECK(!subscription_);
      subscription_ = std::move(subscription);
      if (inner_) {
        inner_->onSubscribe(subscription_);
      }
    }

    void onNext(rsocket::Payload element) noexcept override {
      DCHECK(inner_);
      inner_->onNext(std::move(element));
    }

    void onComplete() noexcept override {
      DCHECK(inner_);
      inner_->onComplete();

      inner_.reset();
      subscription_.reset();
    }

    void onError(folly::exception_wrapper ex) noexcept override {
      VLOG(3) << "handleRequestChannelCore::onError: " << ex.what();
      std::lock_guard<std::mutex> guard(errorMutex_);
      if (inner_) {
        inner_->onError(std::move(ex));

        inner_.reset();
        subscription_.reset();
        error_.reset();
      } else {
        error_ = std::move(ex);
      }
    }

    void subscribe(
        yarpl::Reference<yarpl::flowable::Subscriber<rsocket::Payload>> inner) {
      CHECK(!inner_); // only one call to subscribe is supported
      CHECK(inner);
      std::lock_guard<std::mutex> guard(errorMutex_);

      inner_ = std::move(inner);
      if (subscription_) {
        inner_->onSubscribe(subscription_);
      }

      // it's possible to get an error before subscribe happens, delay sending
      // it but send it when this class gets subscribed
      if (error_) {
        onError(error_);
      }
    }

   private:
    yarpl::Reference<yarpl::flowable::Subscriber<rsocket::Payload>> inner_;
    yarpl::Reference<yarpl::flowable::Subscription> subscription_;
    std::mutex errorMutex_;
    folly::exception_wrapper error_;
  };

  auto eagerSubscriber = yarpl::make_ref<EagerSubscriberBridge>();
  auto flowable = handleRequestChannel(
      std::move(request),
      yarpl::flowable::Flowables::fromPublisher<Payload>(
          [eagerSubscriber](
              yarpl::Reference<yarpl::flowable::Subscriber<Payload>>
                  subscriber) { eagerSubscriber->subscribe(subscriber); }),
      std::move(streamId));
  // bridge from the existing eager RequestHandler and old Subscriber type
  // to the lazy Flowable and new Subscriber type
  flowable->subscribe(std::move(response));
  return eagerSubscriber;
}

/// Handles a new Stream requested by the other end.
void RSocketResponder::handleRequestStreamCore(
    Payload request,
    StreamId streamId,
    const yarpl::Reference<yarpl::flowable::Subscriber<Payload>>&
        response) noexcept {
  auto flowable = handleRequestStream(std::move(request), std::move(streamId));
  flowable->subscribe(std::move(response));
}

/// Handles a new inbound RequestResponse requested by the other end.
void RSocketResponder::handleRequestResponseCore(
    Payload request,
    StreamId streamId,
    const yarpl::Reference<yarpl::single::SingleObserver<Payload>>&
        responseObserver) noexcept {
  auto single = handleRequestResponse(std::move(request), streamId);
  single->subscribe(std::move(responseObserver));
}
} // namespace rsocket
<|endoftext|>


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

  Program:   Visualization Toolkit
  Module:    vtkHedgeHog.cxx
  Language:  C++
  Date:      $Date$
  Version:   $Revision$

Copyright (c) 1993-2001 Ken Martin, Will Schroeder, Bill Lorensen
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:

 * Redistributions of source code must retain the above copyright notice,
   this list of conditions and the following disclaimer.

 * Redistributions in binary form must reproduce the above copyright notice,
   this list of conditions and the following disclaimer in the documentation
   and/or other materials provided with the distribution.

 * Neither name of Ken Martin, Will Schroeder, or Bill Lorensen nor the names
   of any contributors may be used to endorse or promote products derived
   from this software without specific prior written permission.

 * Modified source versions must be plainly marked as such, and must not be
   misrepresented as being the original software.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

=========================================================================*/
#include "vtkHedgeHog.h"
#include "vtkObjectFactory.h"

//------------------------------------------------------------------------
vtkHedgeHog* vtkHedgeHog::New()
{
  // First try to create the object from the vtkObjectFactory
  vtkObject* ret = vtkObjectFactory::CreateInstance("vtkHedgeHog");
  if(ret)
    {
    return (vtkHedgeHog*)ret;
    }
  // If the factory was unable to create the object, then create it here.
  return new vtkHedgeHog;
}

vtkHedgeHog::vtkHedgeHog()
{
  this->ScaleFactor = 1.0;
  this->VectorMode = VTK_USE_VECTOR;
}

void vtkHedgeHog::Execute()
{
  vtkDataSet *input= this->GetInput();
  vtkIdType numPts;
  vtkPoints *newPts;
  vtkPointData *pd;
  vtkDataArray *inVectors;
  vtkDataArray *inNormals;
  vtkIdType ptId;
  int i;
  vtkIdType pts[2];
  vtkCellArray *newLines;
  float *x, *v;
  float newX[3];
  vtkPolyData *output = this->GetOutput();
  vtkPointData *outputPD = output->GetPointData();

  // Initialize
  //
  numPts = input->GetNumberOfPoints();
  pd = input->GetPointData();
  inVectors = pd->GetActiveVectors();
  if ( numPts < 1 )
    {
    vtkErrorMacro(<<"No input data");
    return;
    }
  if ( !inVectors && this->VectorMode == VTK_USE_VECTOR)
    {
    vtkErrorMacro(<<"No vectors in input data");
    return;
    }

  inNormals = pd->GetActiveNormals();
  if ( !inNormals && this->VectorMode == VTK_USE_NORMAL)
    {
    vtkErrorMacro(<<"No normals in input data");
    return;
    }
  outputPD->CopyAllocate(pd, 2*numPts);

  newPts = vtkPoints::New(); newPts->SetNumberOfPoints(2*numPts);
  newLines = vtkCellArray::New();
  newLines->Allocate(newLines->EstimateSize(numPts,2));

  // Loop over all points, creating oriented line
  //
  for (ptId=0; ptId < numPts; ptId++)
    {
    if ( ! (ptId % 10000) ) //abort/progress
      {
      this->UpdateProgress ((float)ptId/numPts);
      if (this->GetAbortExecute())
	{
	break;
	}
      }

    x = input->GetPoint(ptId);
    if (this->VectorMode == VTK_USE_VECTOR)
      {
      v = inVectors->GetTuple(ptId);
      }
    else
      {
      v = inNormals->GetTuple(ptId);
      }
    for (i=0; i<3; i++)
      {
      newX[i] = x[i] + this->ScaleFactor * v[i];
      }

    pts[0] = ptId;
    pts[1] = ptId + numPts;;

    newPts->SetPoint(pts[0], x);
    newPts->SetPoint(pts[1], newX);

    newLines->InsertNextCell(2,pts);

    outputPD->CopyData(pd,ptId,pts[0]);
    outputPD->CopyData(pd,ptId,pts[1]);
    }

  // Update ourselves and release memory
  //
  output->SetPoints(newPts);
  newPts->Delete();

  output->SetLines(newLines);
  newLines->Delete();
}

void vtkHedgeHog::PrintSelf(ostream& os, vtkIndent indent)
{
  vtkDataSetToPolyDataFilter::PrintSelf(os,indent);

  os << indent << "Scale Factor: " << this->ScaleFactor << "\n";
  os << indent << "Orient Mode: " << (this->VectorMode == VTK_USE_VECTOR ?
                                       "Orient by vector\n" : "Orient by normal\n");
}
<commit_msg>Too many CopyData's<commit_after>/*=========================================================================

  Program:   Visualization Toolkit
  Module:    vtkHedgeHog.cxx
  Language:  C++
  Date:      $Date$
  Version:   $Revision$

Copyright (c) 1993-2001 Ken Martin, Will Schroeder, Bill Lorensen
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:

 * Redistributions of source code must retain the above copyright notice,
   this list of conditions and the following disclaimer.

 * Redistributions in binary form must reproduce the above copyright notice,
   this list of conditions and the following disclaimer in the documentation
   and/or other materials provided with the distribution.

 * Neither name of Ken Martin, Will Schroeder, or Bill Lorensen nor the names
   of any contributors may be used to endorse or promote products derived
   from this software without specific prior written permission.

 * Modified source versions must be plainly marked as such, and must not be
   misrepresented as being the original software.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

=========================================================================*/
#include "vtkHedgeHog.h"
#include "vtkObjectFactory.h"

//------------------------------------------------------------------------
vtkHedgeHog* vtkHedgeHog::New()
{
  // First try to create the object from the vtkObjectFactory
  vtkObject* ret = vtkObjectFactory::CreateInstance("vtkHedgeHog");
  if(ret)
    {
    return (vtkHedgeHog*)ret;
    }
  // If the factory was unable to create the object, then create it here.
  return new vtkHedgeHog;
}

vtkHedgeHog::vtkHedgeHog()
{
  this->ScaleFactor = 1.0;
  this->VectorMode = VTK_USE_VECTOR;
}

void vtkHedgeHog::Execute()
{
  vtkDataSet *input= this->GetInput();
  vtkIdType numPts;
  vtkPoints *newPts;
  vtkPointData *pd;
  vtkDataArray *inVectors;
  vtkDataArray *inNormals;
  vtkIdType ptId;
  int i;
  vtkIdType pts[2];
  vtkCellArray *newLines;
  float *x, *v;
  float newX[3];
  vtkPolyData *output = this->GetOutput();
  vtkPointData *outputPD = output->GetPointData();

  // Initialize
  //
  numPts = input->GetNumberOfPoints();
  pd = input->GetPointData();
  inVectors = pd->GetActiveVectors();
  if ( numPts < 1 )
    {
    vtkErrorMacro(<<"No input data");
    return;
    }
  if ( !inVectors && this->VectorMode == VTK_USE_VECTOR)
    {
    vtkErrorMacro(<<"No vectors in input data");
    return;
    }

  inNormals = pd->GetActiveNormals();
  if ( !inNormals && this->VectorMode == VTK_USE_NORMAL)
    {
    vtkErrorMacro(<<"No normals in input data");
    return;
    }
  outputPD->CopyAllocate(pd, 2*numPts);

  newPts = vtkPoints::New(); newPts->SetNumberOfPoints(2*numPts);
  newLines = vtkCellArray::New();
  newLines->Allocate(newLines->EstimateSize(numPts,2));

  // Loop over all points, creating oriented line
  //
  for (ptId=0; ptId < numPts; ptId++)
    {
    if ( ! (ptId % 10000) ) //abort/progress
      {
      this->UpdateProgress ((float)ptId/numPts);
      if (this->GetAbortExecute())
	{
	break;
	}
      }

    x = input->GetPoint(ptId);
    if (this->VectorMode == VTK_USE_VECTOR)
      {
      v = inVectors->GetTuple(ptId);
      }
    else
      {
      v = inNormals->GetTuple(ptId);
      }
    for (i=0; i<3; i++)
      {
      newX[i] = x[i] + this->ScaleFactor * v[i];
      }

    pts[0] = ptId;
    pts[1] = ptId + numPts;;

    newPts->SetPoint(pts[0], x);
    newPts->SetPoint(pts[1], newX);

    newLines->InsertNextCell(2,pts);

    outputPD->CopyData(pd,ptId,pts[0]);
    }

  // Update ourselves and release memory
  //
  output->SetPoints(newPts);
  newPts->Delete();

  output->SetLines(newLines);
  newLines->Delete();
}

void vtkHedgeHog::PrintSelf(ostream& os, vtkIndent indent)
{
  vtkDataSetToPolyDataFilter::PrintSelf(os,indent);

  os << indent << "Scale Factor: " << this->ScaleFactor << "\n";
  os << indent << "Orient Mode: " << (this->VectorMode == VTK_USE_VECTOR ?
                                       "Orient by vector\n" : "Orient by normal\n");
}
<|endoftext|>


<commit_before>/****************************************************************************
**
** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** This file is part of the plugins of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** No Commercial Usage
** This file contains pre-release code and may not be distributed.
** You may use this file in accordance with the terms and conditions
** contained in the Technology Preview License Agreement accompanying
** this package.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file.  Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights.  These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** If you have questions regarding the use of this file, please contact
** Nokia at qt-info@nokia.com.
**
**
**
**
**
**
**
**
** $QT_END_LICENSE$
**
****************************************************************************/

#include "qdirectfbwindowsurface.h"
#include "qdirectfbscreen.h"
#include "qdirectfbpaintengine.h"

#include <private/qwidget_p.h>
#include <qwidget.h>
#include <qwindowsystem_qws.h>
#include <qpaintdevice.h>
#include <qvarlengtharray.h>

#ifndef QT_NO_QWS_DIRECTFB

QT_BEGIN_NAMESPACE

QDirectFBWindowSurface::QDirectFBWindowSurface(DFBSurfaceFlipFlags flip, QDirectFBScreen *scr)
    : QDirectFBPaintDevice(scr)
    , sibling(0)
#ifndef QT_NO_DIRECTFB_WM
    , dfbWindow(0)
#endif
    , flipFlags(flip)
    , boundingRectFlip(scr->directFBFlags() & QDirectFBScreen::BoundingRectFlip)
{
#ifdef QT_NO_DIRECTFB_WM
    mode = Offscreen;
#endif
    setSurfaceFlags(Opaque | Buffered);
#ifdef QT_DIRECTFB_TIMING
    frames = 0;
    timer.start();
#endif
}

QDirectFBWindowSurface::QDirectFBWindowSurface(DFBSurfaceFlipFlags flip, QDirectFBScreen *scr, QWidget *widget)
    : QWSWindowSurface(widget), QDirectFBPaintDevice(scr)
    , sibling(0)
#ifndef QT_NO_DIRECTFB_WM
    , dfbWindow(0)
#endif
    , flipFlags(flip)
    , boundingRectFlip(scr->directFBFlags() & QDirectFBScreen::BoundingRectFlip)
{
    SurfaceFlags flags = 0;
    if (!widget || widget->window()->windowOpacity() == 0xff)
        flags |= Opaque;
#ifdef QT_NO_DIRECTFB_WM
    if (widget && widget->testAttribute(Qt::WA_PaintOnScreen)) {
        flags = RegionReserved;
        mode = Primary;
    } else {
        mode = Offscreen;
        flags = Buffered;
    }
#else
    noSystemBackground = widget && widget->testAttribute(Qt::WA_NoSystemBackground);
    if (noSystemBackground)
        flags &= ~Opaque;
#endif
    setSurfaceFlags(flags);
#ifdef QT_DIRECTFB_TIMING
    frames = 0;
    timer.start();
#endif
}

QDirectFBWindowSurface::~QDirectFBWindowSurface()
{
    releaseSurface();
    // these are not tracked by QDirectFBScreen so we don't want QDirectFBPaintDevice to release it
}

bool QDirectFBWindowSurface::isValid() const
{
    return true;
}

#ifdef QT_DIRECTFB_WM
void QDirectFBWindowSurface::raise()
{
    if (IDirectFBWindow *window = directFBWindow()) {
        window->RaiseToTop(window);
    }
}

IDirectFBWindow *QDirectFBWindowSurface::directFBWindow() const
{
    return (dfbWindow ? dfbWindow : (sibling ? sibling->dfbWindow : 0));
}

void QDirectFBWindowSurface::createWindow(const QRect &rect)
{
    IDirectFBDisplayLayer *layer = screen->dfbDisplayLayer();
    if (!layer)
        qFatal("QDirectFBWindowSurface: Unable to get primary display layer!");

    DFBWindowDescription description;
    memset(&description, 0, sizeof(DFBWindowDescription));

    description.caps = DWCAPS_NODECORATION|DWCAPS_DOUBLEBUFFER;
    description.flags = DWDESC_CAPS|DWDESC_SURFACE_CAPS|DWDESC_PIXELFORMAT|DWDESC_HEIGHT|DWDESC_WIDTH|DWDESC_POSX|DWDESC_POSY;
#if (Q_DIRECTFB_VERSION >= 0x010200)
    description.flags |= DWDESC_OPTIONS;
#endif

    if (noSystemBackground) {
        description.caps |= DWCAPS_ALPHACHANNEL;
#if (Q_DIRECTFB_VERSION >= 0x010200)
        description.options |= DWOP_ALPHACHANNEL;
#endif
    }

    description.posx = rect.x();
    description.posy = rect.y();
    description.width = rect.width();
    description.height = rect.height();
    description.surface_caps = DSCAPS_NONE;
    if (screen->directFBFlags() & QDirectFBScreen::VideoOnly)
        description.surface_caps |= DSCAPS_VIDEOONLY;
    const QImage::Format format = (noSystemBackground ? screen->alphaPixmapFormat() : screen->pixelFormat());
    description.pixelformat = QDirectFBScreen::getSurfacePixelFormat(format);
    if (QDirectFBScreen::isPremultiplied(format))
        description.surface_caps = DSCAPS_PREMULTIPLIED;

    DFBResult result = layer->CreateWindow(layer, &description, &dfbWindow);

    if (result != DFB_OK)
        DirectFBErrorFatal("QDirectFBWindowSurface::createWindow", result);

    Q_ASSERT(!dfbSurface);
    dfbWindow->GetSurface(dfbWindow, &dfbSurface);
    updateFormat();
}

static DFBResult setWindowGeometry(IDirectFBWindow *dfbWindow, const QRect &old, const QRect &rect)
{
    DFBResult result = DFB_OK;
    const bool isMove = old.isEmpty() || rect.topLeft() != old.topLeft();
    const bool isResize = rect.size() != old.size();

#if (Q_DIRECTFB_VERSION >= 0x010000)
    if (isResize && isMove) {
        result = dfbWindow->SetBounds(dfbWindow, rect.x(), rect.y(),
                                      rect.width(), rect.height());
    } else if (isResize) {
        result = dfbWindow->Resize(dfbWindow,
                                   rect.width(), rect.height());
    } else if (isMove) {
        result = dfbWindow->MoveTo(dfbWindow, rect.x(), rect.y());
    }
#else
    if (isResize) {
        result = dfbWindow->Resize(dfbWindow,
                                   rect.width(), rect.height());
    }
    if (isMove) {
        result = dfbWindow->MoveTo(dfbWindow, rect.x(), rect.y());
    }
#endif
    return result;
}
#endif // QT_NO_DIRECTFB_WM

void QDirectFBWindowSurface::setGeometry(const QRect &rect)
{
    const QRect oldRect = geometry();
    if (oldRect == rect)
        return;

    IDirectFBSurface *oldSurface = dfbSurface;
    const bool sizeChanged = oldRect.size() != rect.size();
    if (sizeChanged) {
        delete engine;
        engine = 0;
        releaseSurface();
        Q_ASSERT(!dfbSurface);
    }

    if (rect.isNull()) {
#ifndef QT_NO_DIRECTFB_WM
        if (dfbWindow) {
            dfbWindow->Release(dfbWindow);
            dfbWindow = 0;
        }
#endif
        Q_ASSERT(!dfbSurface);
#ifdef QT_DIRECTFB_SUBSURFACE
        Q_ASSERT(!subSurface);
#endif
    } else {
#ifdef QT_DIRECTFB_WM
        if (!dfbWindow) {
            createWindow(rect);
        } else {
            setWindowGeometry(dfbWindow, oldRect, rect);
            Q_ASSERT(!sizeChanged || !dfbSurface);
            if (sizeChanged)
                dfbWindow->GetSurface(dfbWindow, &dfbSurface);
        }
#else
        IDirectFBSurface *primarySurface = screen->primarySurface();
        DFBResult result = DFB_OK;
        if (mode == Primary) {
            Q_ASSERT(primarySurface);
            if (rect == screen->region().boundingRect()) {
                dfbSurface = primarySurface;
            } else {
                const DFBRectangle r = { rect.x(), rect.y(),
                                         rect.width(), rect.height() };
                result = primarySurface->GetSubSurface(primarySurface, &r, &dfbSurface);
            }
        } else { // mode == Offscreen
            if (!dfbSurface) {
                dfbSurface = screen->createDFBSurface(rect.size(), screen->pixelFormat(), QDirectFBScreen::DontTrackSurface);
            }
        }
        if (result != DFB_OK)
            DirectFBErrorFatal("QDirectFBWindowSurface::setGeometry()", result);
#endif
    }
    if (oldSurface != dfbSurface)
        updateFormat();

    QWSWindowSurface::setGeometry(rect);
}

QByteArray QDirectFBWindowSurface::permanentState() const
{
    QByteArray state(sizeof(this), 0);
    *reinterpret_cast<const QDirectFBWindowSurface**>(state.data()) = this;
    return state;
}

void QDirectFBWindowSurface::setPermanentState(const QByteArray &state)
{
    if (state.size() == sizeof(this)) {
        sibling = *reinterpret_cast<QDirectFBWindowSurface *const*>(state.constData());
        Q_ASSERT(sibling);
        sibling->setSurfaceFlags(surfaceFlags());
    }
}

static inline void scrollSurface(IDirectFBSurface *surface, const QRect &r, int dx, int dy)
{
    const DFBRectangle rect = { r.x(), r.y(), r.width(), r.height() };
    surface->Blit(surface, surface, &rect, r.x() + dx, r.y() + dy);
    const DFBRegion region = { rect.x + dx, rect.y + dy, r.right() + dx, r.bottom() + dy };
    surface->Flip(surface, &region, DSFLIP_BLIT);
}

bool QDirectFBWindowSurface::scroll(const QRegion &region, int dx, int dy)
{
    if (!dfbSurface || !(flipFlags & DSFLIP_BLIT) || region.isEmpty())
        return false;
    dfbSurface->SetBlittingFlags(dfbSurface, DSBLIT_NOFX);
    if (region.numRects() == 1) {
        scrollSurface(dfbSurface, region.boundingRect(), dx, dy);
    } else {
        const QVector<QRect> rects = region.rects();
        const int n = rects.size();
        for (int i=0; i<n; ++i) {
            scrollSurface(dfbSurface, rects.at(i), dx, dy);
        }
    }
    return true;
}

bool QDirectFBWindowSurface::move(const QPoint &moveBy)
{
    setGeometry(geometry().translated(moveBy));
    return true;
}

void QDirectFBWindowSurface::setOpaque(bool opaque)
{
    SurfaceFlags flags = surfaceFlags();
    if (opaque != (flags & Opaque)) {
        if (opaque) {
            flags |= Opaque;
        } else {
            flags &= ~Opaque;
        }
        setSurfaceFlags(flags);
    }
}

void QDirectFBWindowSurface::flush(QWidget *widget, const QRegion &region,
                                   const QPoint &offset)
{
    QWidget *win = window();
    if (!win)
        return;

    QWExtra *extra = qt_widget_private(widget)->extraData();
    if (extra && extra->proxyWidget)
        return;

    const quint8 windowOpacity = quint8(win->windowOpacity() * 0xff);
    const QRect windowGeometry = geometry();
#ifdef QT_DIRECTFB_WM
    const bool wasNoSystemBackground = noSystemBackground;
    noSystemBackground = win->testAttribute(Qt::WA_NoSystemBackground);
    quint8 currentOpacity;
    Q_ASSERT(dfbWindow);
    dfbWindow->GetOpacity(dfbWindow, &currentOpacity);
    if (currentOpacity != windowOpacity) {
        dfbWindow->SetOpacity(dfbWindow, windowOpacity);
    }

    setOpaque(noSystemBackground || windowOpacity != 0xff);
    if (wasNoSystemBackground != noSystemBackground) {
        releaseSurface();
        dfbWindow->Release(dfbWindow);
        dfbWindow = 0;
        createWindow(windowGeometry);
        win->update();
        return;
    }
    screen->flipSurface(dfbSurface, flipFlags, region, offset);
    if (noSystemBackground) {
        dfbSurface->Clear(dfbSurface, 0, 0, 0, 0);
    }
#else
    setOpaque(windowOpacity != 0xff);
    if (mode == Offscreen) {
        screen->exposeRegion(region.translated(offset + geometry().topLeft()), 0);
    } else {
        screen->flipSurface(dfbSurface, flipFlags, region, offset);
    }
#endif

#ifdef QT_DIRECTFB_TIMING
    enum { Secs = 3 };
    ++frames;
    if (timer.elapsed() >= Secs * 1000) {
        qDebug("%d fps", int(double(frames) / double(Secs)));
        frames = 0;
        timer.restart();
    }
#endif
}

void QDirectFBWindowSurface::beginPaint(const QRegion &)
{
    if (!engine) {
        engine = new QDirectFBPaintEngine(this);
    }
}

void QDirectFBWindowSurface::endPaint(const QRegion &)
{
#ifdef QT_NO_DIRECTFB_SUBSURFACE
    unlockSurface();
#endif
}

IDirectFBSurface *QDirectFBWindowSurface::directFBSurface() const
{
    if (!dfbSurface && sibling && sibling->dfbSurface)
        return sibling->dfbSurface;
    return dfbSurface;
}

IDirectFBSurface *QDirectFBWindowSurface::surfaceForWidget(const QWidget *widget, QRect *rect) const
{
    Q_ASSERT(widget);
    if (!dfbSurface) {
        if (sibling && (!sibling->sibling || sibling->dfbSurface))
            return sibling->surfaceForWidget(widget, rect);
        return 0;
    }
    QWidget *win = window();
    Q_ASSERT(win);
    if (rect) {
        if (win == widget) {
            *rect = widget->rect();
        } else {
            *rect = QRect(widget->mapTo(win, QPoint(0, 0)), widget->size());
        }
    }

    Q_ASSERT(win == widget || win->isAncestorOf(widget));
    return dfbSurface;
}

void QDirectFBWindowSurface::updateFormat()
{
    imageFormat = dfbSurface ? QDirectFBScreen::getImageFormat(dfbSurface) : QImage::Format_Invalid;
}

void QDirectFBWindowSurface::releaseSurface()
{
    if (dfbSurface) {
#ifdef QT_DIRECTFB_SUBSURFACE
        releaseSubSurface();
#else
        unlockSurface();
#endif
#ifdef QT_NO_DIRECTFB_WM
        Q_ASSERT(screen->primarySurface());
        if (dfbSurface != screen->primarySurface())
#endif

            dfbSurface->Release(dfbSurface);
        dfbSurface = 0;
    }
}

QT_END_NAMESPACE

#endif // QT_NO_QWS_DIRECTFB

<commit_msg>Don't create too many window surfaces in DFB<commit_after>/****************************************************************************
**
** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** This file is part of the plugins of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** No Commercial Usage
** This file contains pre-release code and may not be distributed.
** You may use this file in accordance with the terms and conditions
** contained in the Technology Preview License Agreement accompanying
** this package.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file.  Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights.  These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** If you have questions regarding the use of this file, please contact
** Nokia at qt-info@nokia.com.
**
**
**
**
**
**
**
**
** $QT_END_LICENSE$
**
****************************************************************************/

#include "qdirectfbwindowsurface.h"
#include "qdirectfbscreen.h"
#include "qdirectfbpaintengine.h"

#include <private/qwidget_p.h>
#include <qwidget.h>
#include <qwindowsystem_qws.h>
#include <qpaintdevice.h>
#include <qvarlengtharray.h>

#ifndef QT_NO_QWS_DIRECTFB

QT_BEGIN_NAMESPACE

QDirectFBWindowSurface::QDirectFBWindowSurface(DFBSurfaceFlipFlags flip, QDirectFBScreen *scr)
    : QDirectFBPaintDevice(scr)
    , sibling(0)
#ifndef QT_NO_DIRECTFB_WM
    , dfbWindow(0)
#endif
    , flipFlags(flip)
    , boundingRectFlip(scr->directFBFlags() & QDirectFBScreen::BoundingRectFlip)
{
#ifdef QT_NO_DIRECTFB_WM
    mode = Offscreen;
#endif
    setSurfaceFlags(Opaque | Buffered);
#ifdef QT_DIRECTFB_TIMING
    frames = 0;
    timer.start();
#endif
}

QDirectFBWindowSurface::QDirectFBWindowSurface(DFBSurfaceFlipFlags flip, QDirectFBScreen *scr, QWidget *widget)
    : QWSWindowSurface(widget), QDirectFBPaintDevice(scr)
    , sibling(0)
#ifndef QT_NO_DIRECTFB_WM
    , dfbWindow(0)
#endif
    , flipFlags(flip)
    , boundingRectFlip(scr->directFBFlags() & QDirectFBScreen::BoundingRectFlip)
{
    SurfaceFlags flags = 0;
    if (!widget || widget->window()->windowOpacity() == 0xff)
        flags |= Opaque;
#ifdef QT_NO_DIRECTFB_WM
    if (widget && widget->testAttribute(Qt::WA_PaintOnScreen)) {
        flags = RegionReserved;
        mode = Primary;
    } else {
        mode = Offscreen;
        flags = Buffered;
    }
#else
    noSystemBackground = widget && widget->testAttribute(Qt::WA_NoSystemBackground);
    if (noSystemBackground)
        flags &= ~Opaque;
#endif
    setSurfaceFlags(flags);
#ifdef QT_DIRECTFB_TIMING
    frames = 0;
    timer.start();
#endif
}

QDirectFBWindowSurface::~QDirectFBWindowSurface()
{
    releaseSurface();
    // these are not tracked by QDirectFBScreen so we don't want QDirectFBPaintDevice to release it
}

bool QDirectFBWindowSurface::isValid() const
{
    return true;
}

#ifdef QT_DIRECTFB_WM
void QDirectFBWindowSurface::raise()
{
    if (IDirectFBWindow *window = directFBWindow()) {
        window->RaiseToTop(window);
    }
}

IDirectFBWindow *QDirectFBWindowSurface::directFBWindow() const
{
    return (dfbWindow ? dfbWindow : (sibling ? sibling->dfbWindow : 0));
}

void QDirectFBWindowSurface::createWindow(const QRect &rect)
{
    IDirectFBDisplayLayer *layer = screen->dfbDisplayLayer();
    if (!layer)
        qFatal("QDirectFBWindowSurface: Unable to get primary display layer!");

    DFBWindowDescription description;
    memset(&description, 0, sizeof(DFBWindowDescription));

    description.caps = DWCAPS_NODECORATION|DWCAPS_DOUBLEBUFFER;
    description.flags = DWDESC_CAPS|DWDESC_SURFACE_CAPS|DWDESC_PIXELFORMAT|DWDESC_HEIGHT|DWDESC_WIDTH|DWDESC_POSX|DWDESC_POSY;
#if (Q_DIRECTFB_VERSION >= 0x010200)
    description.flags |= DWDESC_OPTIONS;
#endif

    if (noSystemBackground) {
        description.caps |= DWCAPS_ALPHACHANNEL;
#if (Q_DIRECTFB_VERSION >= 0x010200)
        description.options |= DWOP_ALPHACHANNEL;
#endif
    }

    description.posx = rect.x();
    description.posy = rect.y();
    description.width = rect.width();
    description.height = rect.height();
    description.surface_caps = DSCAPS_NONE;
    if (screen->directFBFlags() & QDirectFBScreen::VideoOnly)
        description.surface_caps |= DSCAPS_VIDEOONLY;
    const QImage::Format format = (noSystemBackground ? screen->alphaPixmapFormat() : screen->pixelFormat());
    description.pixelformat = QDirectFBScreen::getSurfacePixelFormat(format);
    if (QDirectFBScreen::isPremultiplied(format))
        description.surface_caps = DSCAPS_PREMULTIPLIED;

    DFBResult result = layer->CreateWindow(layer, &description, &dfbWindow);

    if (result != DFB_OK)
        DirectFBErrorFatal("QDirectFBWindowSurface::createWindow", result);

    Q_ASSERT(!dfbSurface);
    dfbWindow->GetSurface(dfbWindow, &dfbSurface);
    updateFormat();
}

static DFBResult setWindowGeometry(IDirectFBWindow *dfbWindow, const QRect &old, const QRect &rect)
{
    DFBResult result = DFB_OK;
    const bool isMove = old.isEmpty() || rect.topLeft() != old.topLeft();
    const bool isResize = rect.size() != old.size();

#if (Q_DIRECTFB_VERSION >= 0x010000)
    if (isResize && isMove) {
        result = dfbWindow->SetBounds(dfbWindow, rect.x(), rect.y(),
                                      rect.width(), rect.height());
    } else if (isResize) {
        result = dfbWindow->Resize(dfbWindow,
                                   rect.width(), rect.height());
    } else if (isMove) {
        result = dfbWindow->MoveTo(dfbWindow, rect.x(), rect.y());
    }
#else
    if (isResize) {
        result = dfbWindow->Resize(dfbWindow,
                                   rect.width(), rect.height());
    }
    if (isMove) {
        result = dfbWindow->MoveTo(dfbWindow, rect.x(), rect.y());
    }
#endif
    return result;
}
#endif // QT_NO_DIRECTFB_WM

void QDirectFBWindowSurface::setGeometry(const QRect &rect)
{
    const QRect oldRect = geometry();
    if (oldRect == rect)
        return;

    IDirectFBSurface *oldSurface = dfbSurface;
    const bool sizeChanged = oldRect.size() != rect.size();
    if (sizeChanged) {
        delete engine;
        engine = 0;
        releaseSurface();
        Q_ASSERT(!dfbSurface);
    }

    if (rect.isNull()) {
#ifndef QT_NO_DIRECTFB_WM
        if (dfbWindow) {
            dfbWindow->Release(dfbWindow);
            dfbWindow = 0;
        }
#endif
        Q_ASSERT(!dfbSurface);
#ifdef QT_DIRECTFB_SUBSURFACE
        Q_ASSERT(!subSurface);
#endif
    } else {
#ifdef QT_DIRECTFB_WM
        if (!dfbWindow) {
            createWindow(rect);
        } else {
            setWindowGeometry(dfbWindow, oldRect, rect);
            Q_ASSERT(!sizeChanged || !dfbSurface);
            if (sizeChanged)
                dfbWindow->GetSurface(dfbWindow, &dfbSurface);
        }
#else
        IDirectFBSurface *primarySurface = screen->primarySurface();
        DFBResult result = DFB_OK;
        if (mode == Primary) {
            Q_ASSERT(primarySurface);
            if (rect == screen->region().boundingRect()) {
                dfbSurface = primarySurface;
            } else {
                const DFBRectangle r = { rect.x(), rect.y(),
                                         rect.width(), rect.height() };
                result = primarySurface->GetSubSurface(primarySurface, &r, &dfbSurface);
            }
        } else { // mode == Offscreen
            if (!dfbSurface) {
                dfbSurface = screen->createDFBSurface(rect.size(), screen->pixelFormat(), QDirectFBScreen::DontTrackSurface);
            }
        }
        if (result != DFB_OK)
            DirectFBErrorFatal("QDirectFBWindowSurface::setGeometry()", result);
#endif
    }
    if (oldSurface != dfbSurface)
        updateFormat();

    if (oldRect.size() != rect.size()) {
        QWSWindowSurface::setGeometry(rect);
    } else {
        QWindowSurface::setGeometry(rect);
    }
}

QByteArray QDirectFBWindowSurface::permanentState() const
{
    QByteArray state(sizeof(this), 0);
    *reinterpret_cast<const QDirectFBWindowSurface**>(state.data()) = this;
    return state;
}

void QDirectFBWindowSurface::setPermanentState(const QByteArray &state)
{
    if (state.size() == sizeof(this)) {
        sibling = *reinterpret_cast<QDirectFBWindowSurface *const*>(state.constData());
        Q_ASSERT(sibling);
        sibling->setSurfaceFlags(surfaceFlags());
    }
}

static inline void scrollSurface(IDirectFBSurface *surface, const QRect &r, int dx, int dy)
{
    const DFBRectangle rect = { r.x(), r.y(), r.width(), r.height() };
    surface->Blit(surface, surface, &rect, r.x() + dx, r.y() + dy);
    const DFBRegion region = { rect.x + dx, rect.y + dy, r.right() + dx, r.bottom() + dy };
    surface->Flip(surface, &region, DSFLIP_BLIT);
}

bool QDirectFBWindowSurface::scroll(const QRegion &region, int dx, int dy)
{
    if (!dfbSurface || !(flipFlags & DSFLIP_BLIT) || region.isEmpty())
        return false;
    dfbSurface->SetBlittingFlags(dfbSurface, DSBLIT_NOFX);
    if (region.numRects() == 1) {
        scrollSurface(dfbSurface, region.boundingRect(), dx, dy);
    } else {
        const QVector<QRect> rects = region.rects();
        const int n = rects.size();
        for (int i=0; i<n; ++i) {
            scrollSurface(dfbSurface, rects.at(i), dx, dy);
        }
    }
    return true;
}

bool QDirectFBWindowSurface::move(const QPoint &moveBy)
{
    setGeometry(geometry().translated(moveBy));
    return true;
}

void QDirectFBWindowSurface::setOpaque(bool opaque)
{
    SurfaceFlags flags = surfaceFlags();
    if (opaque != (flags & Opaque)) {
        if (opaque) {
            flags |= Opaque;
        } else {
            flags &= ~Opaque;
        }
        setSurfaceFlags(flags);
    }
}

void QDirectFBWindowSurface::flush(QWidget *widget, const QRegion &region,
                                   const QPoint &offset)
{
    QWidget *win = window();
    if (!win)
        return;

    QWExtra *extra = qt_widget_private(widget)->extraData();
    if (extra && extra->proxyWidget)
        return;

    const quint8 windowOpacity = quint8(win->windowOpacity() * 0xff);
    const QRect windowGeometry = geometry();
#ifdef QT_DIRECTFB_WM
    const bool wasNoSystemBackground = noSystemBackground;
    noSystemBackground = win->testAttribute(Qt::WA_NoSystemBackground);
    quint8 currentOpacity;
    Q_ASSERT(dfbWindow);
    dfbWindow->GetOpacity(dfbWindow, &currentOpacity);
    if (currentOpacity != windowOpacity) {
        dfbWindow->SetOpacity(dfbWindow, windowOpacity);
    }

    setOpaque(noSystemBackground || windowOpacity != 0xff);
    if (wasNoSystemBackground != noSystemBackground) {
        releaseSurface();
        dfbWindow->Release(dfbWindow);
        dfbWindow = 0;
        createWindow(windowGeometry);
        win->update();
        return;
    }
    screen->flipSurface(dfbSurface, flipFlags, region, offset);
    if (noSystemBackground) {
        dfbSurface->Clear(dfbSurface, 0, 0, 0, 0);
    }
#else
    setOpaque(windowOpacity != 0xff);
    if (mode == Offscreen) {
        screen->exposeRegion(region.translated(offset + geometry().topLeft()), 0);
    } else {
        screen->flipSurface(dfbSurface, flipFlags, region, offset);
    }
#endif

#ifdef QT_DIRECTFB_TIMING
    enum { Secs = 3 };
    ++frames;
    if (timer.elapsed() >= Secs * 1000) {
        qDebug("%d fps", int(double(frames) / double(Secs)));
        frames = 0;
        timer.restart();
    }
#endif
}

void QDirectFBWindowSurface::beginPaint(const QRegion &)
{
    if (!engine) {
        engine = new QDirectFBPaintEngine(this);
    }
}

void QDirectFBWindowSurface::endPaint(const QRegion &)
{
#ifdef QT_NO_DIRECTFB_SUBSURFACE
    unlockSurface();
#endif
}

IDirectFBSurface *QDirectFBWindowSurface::directFBSurface() const
{
    if (!dfbSurface && sibling && sibling->dfbSurface)
        return sibling->dfbSurface;
    return dfbSurface;
}

IDirectFBSurface *QDirectFBWindowSurface::surfaceForWidget(const QWidget *widget, QRect *rect) const
{
    Q_ASSERT(widget);
    if (!dfbSurface) {
        if (sibling && (!sibling->sibling || sibling->dfbSurface))
            return sibling->surfaceForWidget(widget, rect);
        return 0;
    }
    QWidget *win = window();
    Q_ASSERT(win);
    if (rect) {
        if (win == widget) {
            *rect = widget->rect();
        } else {
            *rect = QRect(widget->mapTo(win, QPoint(0, 0)), widget->size());
        }
    }

    Q_ASSERT(win == widget || win->isAncestorOf(widget));
    return dfbSurface;
}

void QDirectFBWindowSurface::updateFormat()
{
    imageFormat = dfbSurface ? QDirectFBScreen::getImageFormat(dfbSurface) : QImage::Format_Invalid;
}

void QDirectFBWindowSurface::releaseSurface()
{
    if (dfbSurface) {
#ifdef QT_DIRECTFB_SUBSURFACE
        releaseSubSurface();
#else
        unlockSurface();
#endif
#ifdef QT_NO_DIRECTFB_WM
        Q_ASSERT(screen->primarySurface());
        if (dfbSurface != screen->primarySurface())
#endif

            dfbSurface->Release(dfbSurface);
        dfbSurface = 0;
    }
}

QT_END_NAMESPACE

#endif // QT_NO_QWS_DIRECTFB

<|endoftext|>


<commit_before>#include "de_web_plugin.h"
#include "de_web_plugin_private.h"

#define ACTIVE_POWER                            0x050B
#define RMS_VOLTAGE                             0x0505
#define RMS_CURRENT                             0x0508
#define APPARENT_POWER                          0x050F

/*! Handle packets related to the ZCL electrical measurement cluster.
    \param ind the APS level data indication containing the ZCL packet
    \param zclFrame the actual ZCL frame which holds the electrical measurement cluster command or attribute
 */
void DeRestPluginPrivate::handleElectricalMeasurementClusterIndication(const deCONZ::ApsDataIndication &ind, const deCONZ::ZclFrame &zclFrame)
{
    if (zclFrame.isDefaultResponse())
    {
        return;
    }

    Sensor *sensor = getSensorNodeForAddressAndEndpoint(ind.srcAddress(), ind.srcEndpoint(), QLatin1String("ZHAPower"));

    if (!sensor)
    {
        DBG_Printf(DBG_INFO, "No power sensor found for 0x%016llX, endpoint: 0x%02X\n", ind.srcAddress().ext(), ind.srcEndpoint());
        return;
    }

    QDataStream stream(zclFrame.payload());
    stream.setByteOrder(QDataStream::LittleEndian);

    bool isReadAttr = false;
    bool isReporting = false;
    if (zclFrame.isProfileWideCommand() && zclFrame.commandId() == deCONZ::ZclReadAttributesResponseId)
    {
        isReadAttr = true;
    }
    if (zclFrame.isProfileWideCommand() && zclFrame.commandId() == deCONZ::ZclReportAttributesId)
    {
        isReporting = true;
    }

    // Read ZCL reporting and ZCL Read Attributes Response
    if (isReadAttr || isReporting)
    {
        const auto modelId = sensor->modelId();
        const NodeValue::UpdateType updateType = isReadAttr ? NodeValue::UpdateByZclRead : NodeValue::UpdateByZclReport;

        bool configUpdated = false;
        bool stateUpdated = false;

        while (!stream.atEnd())
        {
            quint16 attrId;
            quint8 attrTypeId;

            stream >> attrId;
            if (isReadAttr)
            {
                quint8 status;
                stream >> status;  // Read Attribute Response status
                if (status != deCONZ::ZclSuccessStatus)
                {
                    continue;
                }
            }
            stream >> attrTypeId;

            deCONZ::ZclAttribute attr(attrId, attrTypeId, QLatin1String(""), deCONZ::ZclRead, false);

            if (!attr.readFromStream(stream))
            {
                continue;
            }

            ResourceItem *item = nullptr;

            switch (attrId)
            {
            case ACTIVE_POWER:
            {
                qint16 power = attr.numericValue().s16;
                item = sensor->item(RStatePower);

                if (item && power != -32768)
                {
                    if (modelId == QLatin1String("SmartPlug") ||                              // Heiman
                        modelId.startsWith(QLatin1String("SKHMP30")) ||                       // GS smart plug
                        modelId.startsWith(QLatin1String("ROB_200")) ||                       // ROBB Smarrt micro dimmer
                        modelId.startsWith(QLatin1String("Micro Smart Dimmer")) ||            // Sunricher Micro Smart Dimmer
                        modelId.startsWith(QLatin1String("lumi.plug.maeu")) ||                // Xiaomi Aqara ZB3.0 smart plug
                        modelId == QLatin1String("RICI01") ||                                 // LifeControl Smart Plug
                        modelId.startsWith(QLatin1String("outlet")) ||                        // Samsung SmartThings IM6001-OTP/IM6001-OTP01
                        modelId == QLatin1String("3200-Sgb") ||                               // Samsung/Centralite smart outlet
                        modelId == QLatin1String("3200-de") ||                                // Samsung/Centralite smart outlet
                        modelId.startsWith(QLatin1String("lumi.switch.n0agl1")) ||            // Xiaomi Aqara Single Switch Module T1 (With Neutral)
                        modelId.startsWith(QLatin1String("lumi.switch.b1naus01")))            // Xiaomi ZB3.0 Smart Wall Switch
                    {
                        power = static_cast<qint16>(round((double)power / 10.0)); // 0.1W -> W
                    }
                    else if (modelId.startsWith(QLatin1String("Plug")) && sensor->manufacturer() == QLatin1String("OSRAM")) // OSRAM
                    {
                        power = power == 28000 ? 0 : power / 10;
                    }
                    else if (modelId.startsWith(QLatin1String("SZ-ESW01")))                   // Sercomm / Telstra smart plug
                    {
                        power = static_cast<qint16>(round(((double)power * 128) / 1000.0));
                    }
                    else if (modelId == QLatin1String("Connected socket outlet"))             // Niko smart socket
                    {
                        power = static_cast<qint16>(round(((double)power * 1123) / 10000.0));
                    }
                    else if (modelId.startsWith(QLatin1String("lumi.relay.c2acn")))           // Xiaomi relay
                    {
                        continue;   // Device seems to always report -1 via this cluster/attribute
                    }

                    if (item->toNumber() != power)
                    {
                        item->setValue(power); // in W
                        enqueueEvent(Event(RSensors, RStatePower, sensor->id(), item));
                    }
                }

                sensor->setZclValue(updateType, ind.srcEndpoint(), ELECTRICAL_MEASUREMENT_CLUSTER_ID, attrId, attr.numericValue());
                stateUpdated = true;
            }
                break;

            case RMS_VOLTAGE:
            {
                quint16 voltage = attr.numericValue().u16;
                item = sensor->item(RStateVoltage);

                if (item && voltage != 65535)
                {
                    if (modelId == QLatin1String("SmartPlug") ||                                       // Heiman
                        modelId.startsWith(QLatin1String("SPLZB-1")) ||                                // Develco smart plug
                        modelId.startsWith(QLatin1String("SMRZB-3")) ||                                // Develco smart relay
                        modelId.startsWith(QLatin1String("SMRZB-1")) ||                                // Develco smart cable
                        modelId.startsWith(QLatin1String("SKHMP30")) ||                                // GS smart plug
                        modelId == QLatin1String("Smart16ARelay51AU") ||                               // Aurora (Develco) smart plug
                        modelId == QLatin1String("PoP"))                                               // Apex Smart Plug
                    {
                        voltage = static_cast<quint16>(round((double)voltage / 100.0)); // 0.01V -> V
                    }
                    else if (modelId == QLatin1String("RICI01") ||                                     // LifeControl Smart Plug
                             modelId.startsWith(QLatin1String("outlet")) ||                            // Samsung SmartThings IM6001-OTP/IM6001-OTP01
                             modelId.startsWith(QLatin1String("ROB_200")) ||                           // ROBB Smarrt micro dimmer
                             modelId.startsWith(QLatin1String("Micro Smart Dimmer")) ||                // Sunricher Micro Smart Dimmer
                             modelId == QLatin1String("Connected socket outlet") ||                    // Niko smart socket
                             modelId.startsWith(QLatin1String("TH112")))                               // Sinope Thermostats
                    {
                        voltage = static_cast<quint16>(round((double)voltage / 10.0)); // 0.1V -> V
                    }
                    else if (modelId.startsWith(QLatin1String("SZ-ESW01")))                            // Sercomm / Telstra smart plug
                    {
                        voltage = static_cast<quint16>(round((double)voltage / 125.0)); // -> V
                    }

                    if (item->toNumber() != voltage)
                    {
                        item->setValue(voltage); // in V
                        enqueueEvent(Event(RSensors, RStateVoltage, sensor->id(), item));
                    }
                }

                sensor->setZclValue(updateType, ind.srcEndpoint(), ELECTRICAL_MEASUREMENT_CLUSTER_ID, attrId, attr.numericValue());
                stateUpdated = true;
            }
                break;

            case RMS_CURRENT:
            {
                quint16 current = attr.numericValue().u16;
                item = sensor->item(RStateCurrent);

                if (item && current != 65535)
                {
                    if (modelId == QLatin1String("SP 120") ||                                     // innr
                        modelId.startsWith(QLatin1String("outlet")) ||                            // Samsung SmartThings IM6001-OTP/IM6001-OTP01
                        modelId == QLatin1String("DoubleSocket50AU") ||                           // Aurora
                        modelId.startsWith(QLatin1String("SPLZB-1")) ||                           // Develco smart plug
                        modelId == QLatin1String("Smart16ARelay51AU") ||                          // Aurora (Develco) smart plug
                        modelId == QLatin1String("RICI01") ||                                     // LifeControl Smart Plug
                        modelId.startsWith(QLatin1String("SZ-ESW01")) ||                          // Sercomm / Telstra smart plug
                        modelId == QLatin1String("TS0121") ||                                     // Tuya smart plug
                        modelId.startsWith(QLatin1String("ROB_200")) ||                           // ROBB Smarrt micro dimmer
                        modelId.startsWith(QLatin1String("Micro Smart Dimmer")) ||                // Sunricher Micro Smart Dimmer
                        modelId == QLatin1String("Connected socket outlet") ||                    // Niko smart socket
                        modelId == QLatin1String("SMRZB-1") ||                                    // Develco smart cable
                        modelId.startsWith(QLatin1String("S1")) ||                                // Ubisys S1/S1-R
                        modelId.startsWith(QLatin1String("S2")) ||                                // Ubisys S2/S2-R
                        modelId.startsWith(QLatin1String("J1")) ||                                // Ubisys J1/J1-R
                        modelId.startsWith(QLatin1String("D1")))                                  // Ubisys D1/D1-R
                    {
                        // already in mA
                    }
                    else if (modelId == QLatin1String("SmartPlug") ||                             // Heiman
                             modelId.startsWith(QLatin1String("EMIZB-1")) ||                      // Develco EMI
                             modelId.startsWith(QLatin1String("SKHMP30")) ||                      // GS smart plug
                             modelId == QLatin1String("3200-Sgb") ||                              // Samsung smart outlet
                             modelId == QLatin1String("3200-de") ||                               // Samsung smart outlet
                             modelId.startsWith(QLatin1String("SPW35Z")) ||                       // RT-RK OBLO SPW35ZD0 smart plug
                             modelId == QLatin1String("TH1300ZB"))                                // Sinope thermostat
                    {
                        current *= 10; // 0.01A -> mA
                    }
                    else
                    {
                        current *= 1000; // A -> mA
                    }

                    if (item->toNumber() != current)
                    {
                        item->setValue(current); // in mA
                        enqueueEvent(Event(RSensors, RStateCurrent, sensor->id(), item));
                    }
                }

                sensor->setZclValue(updateType, ind.srcEndpoint(), ELECTRICAL_MEASUREMENT_CLUSTER_ID, attrId, attr.numericValue());
                stateUpdated = true;
            }
                break;

            case APPARENT_POWER:
            {
                quint16 power = attr.numericValue().u16;
                item = sensor->item(RStatePower);

                if (item && power != 65535)
                {
                    if (modelId == QLatin1String("TH1300ZB")) // Sinope thermostat
                    {
                        power = static_cast<quint16>(round((double)power / 1000.0)); // -> W
                    }

                    if (item->toNumber() != power)
                    {
                        item->setValue(power); // in W
                        enqueueEvent(Event(RSensors, RStatePower, sensor->id(), item));
                    }
                }

                sensor->setZclValue(updateType, ind.srcEndpoint(), ELECTRICAL_MEASUREMENT_CLUSTER_ID, attrId, attr.numericValue());
                stateUpdated = true;
            }
                break;

            default:
                break;
            }
        }

        if (stateUpdated)
        {
            sensor->updateStateTimestamp();
            enqueueEvent(Event(RSensors, RStateLastUpdated, sensor->id()));
        }

        if (configUpdated || stateUpdated)
        {
            updateSensorEtag(&*sensor);
            sensor->setNeedSaveDatabase(true);
            queSaveDb(DB_SENSORS, DB_SHORT_SAVE_DELAY);
        }
    }
}
<commit_msg>Correct Apex smart plug current readings<commit_after>#include "de_web_plugin.h"
#include "de_web_plugin_private.h"

#define ACTIVE_POWER                            0x050B
#define RMS_VOLTAGE                             0x0505
#define RMS_CURRENT                             0x0508
#define APPARENT_POWER                          0x050F

/*! Handle packets related to the ZCL electrical measurement cluster.
    \param ind the APS level data indication containing the ZCL packet
    \param zclFrame the actual ZCL frame which holds the electrical measurement cluster command or attribute
 */
void DeRestPluginPrivate::handleElectricalMeasurementClusterIndication(const deCONZ::ApsDataIndication &ind, const deCONZ::ZclFrame &zclFrame)
{
    if (zclFrame.isDefaultResponse())
    {
        return;
    }

    Sensor *sensor = getSensorNodeForAddressAndEndpoint(ind.srcAddress(), ind.srcEndpoint(), QLatin1String("ZHAPower"));

    if (!sensor)
    {
        DBG_Printf(DBG_INFO, "No power sensor found for 0x%016llX, endpoint: 0x%02X\n", ind.srcAddress().ext(), ind.srcEndpoint());
        return;
    }

    QDataStream stream(zclFrame.payload());
    stream.setByteOrder(QDataStream::LittleEndian);

    bool isReadAttr = false;
    bool isReporting = false;
    if (zclFrame.isProfileWideCommand() && zclFrame.commandId() == deCONZ::ZclReadAttributesResponseId)
    {
        isReadAttr = true;
    }
    if (zclFrame.isProfileWideCommand() && zclFrame.commandId() == deCONZ::ZclReportAttributesId)
    {
        isReporting = true;
    }

    // Read ZCL reporting and ZCL Read Attributes Response
    if (isReadAttr || isReporting)
    {
        const auto modelId = sensor->modelId();
        const NodeValue::UpdateType updateType = isReadAttr ? NodeValue::UpdateByZclRead : NodeValue::UpdateByZclReport;

        bool configUpdated = false;
        bool stateUpdated = false;

        while (!stream.atEnd())
        {
            quint16 attrId;
            quint8 attrTypeId;

            stream >> attrId;
            if (isReadAttr)
            {
                quint8 status;
                stream >> status;  // Read Attribute Response status
                if (status != deCONZ::ZclSuccessStatus)
                {
                    continue;
                }
            }
            stream >> attrTypeId;

            deCONZ::ZclAttribute attr(attrId, attrTypeId, QLatin1String(""), deCONZ::ZclRead, false);

            if (!attr.readFromStream(stream))
            {
                continue;
            }

            ResourceItem *item = nullptr;

            switch (attrId)
            {
            case ACTIVE_POWER:
            {
                qint16 power = attr.numericValue().s16;
                item = sensor->item(RStatePower);

                if (item && power != -32768)
                {
                    if (modelId == QLatin1String("SmartPlug") ||                              // Heiman
                        modelId.startsWith(QLatin1String("SKHMP30")) ||                       // GS smart plug
                        modelId.startsWith(QLatin1String("ROB_200")) ||                       // ROBB Smarrt micro dimmer
                        modelId.startsWith(QLatin1String("Micro Smart Dimmer")) ||            // Sunricher Micro Smart Dimmer
                        modelId.startsWith(QLatin1String("lumi.plug.maeu")) ||                // Xiaomi Aqara ZB3.0 smart plug
                        modelId == QLatin1String("RICI01") ||                                 // LifeControl Smart Plug
                        modelId.startsWith(QLatin1String("outlet")) ||                        // Samsung SmartThings IM6001-OTP/IM6001-OTP01
                        modelId == QLatin1String("3200-Sgb") ||                               // Samsung/Centralite smart outlet
                        modelId == QLatin1String("3200-de") ||                                // Samsung/Centralite smart outlet
                        modelId.startsWith(QLatin1String("lumi.switch.n0agl1")) ||            // Xiaomi Aqara Single Switch Module T1 (With Neutral)
                        modelId.startsWith(QLatin1String("lumi.switch.b1naus01")))            // Xiaomi ZB3.0 Smart Wall Switch
                    {
                        power = static_cast<qint16>(round((double)power / 10.0)); // 0.1W -> W
                    }
                    else if (modelId.startsWith(QLatin1String("Plug")) && sensor->manufacturer() == QLatin1String("OSRAM")) // OSRAM
                    {
                        power = power == 28000 ? 0 : power / 10;
                    }
                    else if (modelId.startsWith(QLatin1String("SZ-ESW01")))                   // Sercomm / Telstra smart plug
                    {
                        power = static_cast<qint16>(round(((double)power * 128) / 1000.0));
                    }
                    else if (modelId == QLatin1String("Connected socket outlet"))             // Niko smart socket
                    {
                        power = static_cast<qint16>(round(((double)power * 1123) / 10000.0));
                    }
                    else if (modelId.startsWith(QLatin1String("lumi.relay.c2acn")))           // Xiaomi relay
                    {
                        continue;   // Device seems to always report -1 via this cluster/attribute
                    }

                    if (item->toNumber() != power)
                    {
                        item->setValue(power); // in W
                        enqueueEvent(Event(RSensors, RStatePower, sensor->id(), item));
                    }
                }

                sensor->setZclValue(updateType, ind.srcEndpoint(), ELECTRICAL_MEASUREMENT_CLUSTER_ID, attrId, attr.numericValue());
                stateUpdated = true;
            }
                break;

            case RMS_VOLTAGE:
            {
                quint16 voltage = attr.numericValue().u16;
                item = sensor->item(RStateVoltage);

                if (item && voltage != 65535)
                {
                    if (modelId == QLatin1String("SmartPlug") ||                                       // Heiman
                        modelId.startsWith(QLatin1String("SPLZB-1")) ||                                // Develco smart plug
                        modelId.startsWith(QLatin1String("SMRZB-3")) ||                                // Develco smart relay
                        modelId.startsWith(QLatin1String("SMRZB-1")) ||                                // Develco smart cable
                        modelId.startsWith(QLatin1String("SKHMP30")) ||                                // GS smart plug
                        modelId == QLatin1String("Smart16ARelay51AU") ||                               // Aurora (Develco) smart plug
                        modelId == QLatin1String("PoP"))                                               // Apex Smart Plug
                    {
                        voltage = static_cast<quint16>(round((double)voltage / 100.0)); // 0.01V -> V
                    }
                    else if (modelId == QLatin1String("RICI01") ||                                     // LifeControl Smart Plug
                             modelId.startsWith(QLatin1String("outlet")) ||                            // Samsung SmartThings IM6001-OTP/IM6001-OTP01
                             modelId.startsWith(QLatin1String("ROB_200")) ||                           // ROBB Smarrt micro dimmer
                             modelId.startsWith(QLatin1String("Micro Smart Dimmer")) ||                // Sunricher Micro Smart Dimmer
                             modelId == QLatin1String("Connected socket outlet") ||                    // Niko smart socket
                             modelId.startsWith(QLatin1String("TH112")))                               // Sinope Thermostats
                    {
                        voltage = static_cast<quint16>(round((double)voltage / 10.0)); // 0.1V -> V
                    }
                    else if (modelId.startsWith(QLatin1String("SZ-ESW01")))                            // Sercomm / Telstra smart plug
                    {
                        voltage = static_cast<quint16>(round((double)voltage / 125.0)); // -> V
                    }

                    if (item->toNumber() != voltage)
                    {
                        item->setValue(voltage); // in V
                        enqueueEvent(Event(RSensors, RStateVoltage, sensor->id(), item));
                    }
                }

                sensor->setZclValue(updateType, ind.srcEndpoint(), ELECTRICAL_MEASUREMENT_CLUSTER_ID, attrId, attr.numericValue());
                stateUpdated = true;
            }
                break;

            case RMS_CURRENT:
            {
                quint16 current = attr.numericValue().u16;
                item = sensor->item(RStateCurrent);

                if (item && current != 65535)
                {
                    if (modelId == QLatin1String("SP 120") ||                                     // innr
                        modelId.startsWith(QLatin1String("outlet")) ||                            // Samsung SmartThings IM6001-OTP/IM6001-OTP01
                        modelId == QLatin1String("DoubleSocket50AU") ||                           // Aurora
                        modelId.startsWith(QLatin1String("SPLZB-1")) ||                           // Develco smart plug
                        modelId == QLatin1String("Smart16ARelay51AU") ||                          // Aurora (Develco) smart plug
                        modelId == QLatin1String("RICI01") ||                                     // LifeControl Smart Plug
                        modelId.startsWith(QLatin1String("SZ-ESW01")) ||                          // Sercomm / Telstra smart plug
                        modelId == QLatin1String("TS0121") ||                                     // Tuya smart plug
                        modelId.startsWith(QLatin1String("ROB_200")) ||                           // ROBB Smarrt micro dimmer
                        modelId.startsWith(QLatin1String("Micro Smart Dimmer")) ||                // Sunricher Micro Smart Dimmer
                        modelId == QLatin1String("Connected socket outlet") ||                    // Niko smart socket
                        modelId == QLatin1String("SMRZB-1") ||                                    // Develco smart cable
                        modelId == QLatin1String("PoP") ||                                        // Apex Smart Plug
                        modelId.startsWith(QLatin1String("S1")) ||                                // Ubisys S1/S1-R
                        modelId.startsWith(QLatin1String("S2")) ||                                // Ubisys S2/S2-R
                        modelId.startsWith(QLatin1String("J1")) ||                                // Ubisys J1/J1-R
                        modelId.startsWith(QLatin1String("D1")))                                  // Ubisys D1/D1-R
                    {
                        // already in mA
                    }
                    else if (modelId == QLatin1String("SmartPlug") ||                             // Heiman
                             modelId.startsWith(QLatin1String("EMIZB-1")) ||                      // Develco EMI
                             modelId.startsWith(QLatin1String("SKHMP30")) ||                      // GS smart plug
                             modelId == QLatin1String("3200-Sgb") ||                              // Samsung smart outlet
                             modelId == QLatin1String("3200-de") ||                               // Samsung smart outlet
                             modelId.startsWith(QLatin1String("SPW35Z")) ||                       // RT-RK OBLO SPW35ZD0 smart plug
                             modelId == QLatin1String("TH1300ZB"))                                // Sinope thermostat
                    {
                        current *= 10; // 0.01A -> mA
                    }
                    else
                    {
                        current *= 1000; // A -> mA
                    }

                    if (item->toNumber() != current)
                    {
                        item->setValue(current); // in mA
                        enqueueEvent(Event(RSensors, RStateCurrent, sensor->id(), item));
                    }
                }

                sensor->setZclValue(updateType, ind.srcEndpoint(), ELECTRICAL_MEASUREMENT_CLUSTER_ID, attrId, attr.numericValue());
                stateUpdated = true;
            }
                break;

            case APPARENT_POWER:
            {
                quint16 power = attr.numericValue().u16;
                item = sensor->item(RStatePower);

                if (item && power != 65535)
                {
                    if (modelId == QLatin1String("TH1300ZB")) // Sinope thermostat
                    {
                        power = static_cast<quint16>(round((double)power / 1000.0)); // -> W
                    }

                    if (item->toNumber() != power)
                    {
                        item->setValue(power); // in W
                        enqueueEvent(Event(RSensors, RStatePower, sensor->id(), item));
                    }
                }

                sensor->setZclValue(updateType, ind.srcEndpoint(), ELECTRICAL_MEASUREMENT_CLUSTER_ID, attrId, attr.numericValue());
                stateUpdated = true;
            }
                break;

            default:
                break;
            }
        }

        if (stateUpdated)
        {
            sensor->updateStateTimestamp();
            enqueueEvent(Event(RSensors, RStateLastUpdated, sensor->id()));
        }

        if (configUpdated || stateUpdated)
        {
            updateSensorEtag(&*sensor);
            sensor->setNeedSaveDatabase(true);
            queSaveDb(DB_SENSORS, DB_SHORT_SAVE_DELAY);
        }
    }
}
<|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 "remoting/host/chromoting_host_context.h"

#include <string>

#include "base/bind.h"
#include "base/threading/thread.h"
#include "remoting/host/url_request_context.h"
#include "remoting/jingle_glue/jingle_thread.h"

namespace remoting {

ChromotingHostContext::ChromotingHostContext(
    base::MessageLoopProxy* ui_message_loop)
    : main_thread_("ChromotingMainThread"),
      encode_thread_("ChromotingEncodeThread"),
      desktop_thread_("ChromotingDesktopThread"),
      io_thread_("ChromotingIOThread"),
      file_thread_("ChromotingFileIOThread"),
      ui_message_loop_(ui_message_loop) {
}

ChromotingHostContext::~ChromotingHostContext() {
}

bool ChromotingHostContext::Start() {
  // Start all the threads.
  bool started = main_thread_.Start() && encode_thread_.Start() &&
      jingle_thread_.Start() && desktop_thread_.Start() &&
      io_thread_.StartWithOptions(
          base::Thread::Options(MessageLoop::TYPE_IO, 0)) &&
      file_thread_.StartWithOptions(
          base::Thread::Options(MessageLoop::TYPE_IO, 0));
  if (!started)
    return false;

  url_request_context_getter_ = new URLRequestContextGetter(
      io_thread_.message_loop(), file_thread_.message_loop());
  return true;
}

JingleThread* ChromotingHostContext::jingle_thread() {
  return &jingle_thread_;
}

MessageLoop* ChromotingHostContext::main_message_loop() {
  return main_thread_.message_loop();
}

MessageLoop* ChromotingHostContext::encode_message_loop() {
  return encode_thread_.message_loop();
}

base::MessageLoopProxy* ChromotingHostContext::network_message_loop() {
  return jingle_thread_.message_loop_proxy();
}

MessageLoop* ChromotingHostContext::desktop_message_loop() {
  return desktop_thread_.message_loop();
}

base::MessageLoopProxy* ChromotingHostContext::ui_message_loop() {
  return ui_message_loop_;
}

base::MessageLoopProxy* ChromotingHostContext::io_message_loop() {
  return io_thread_.message_loop_proxy();
}

base::MessageLoopProxy* ChromotingHostContext::file_message_loop() {
  return file_thread_.message_loop_proxy();
}

const scoped_refptr<URLRequestContextGetter>&
ChromotingHostContext::url_request_context_getter() {
  return url_request_context_getter_;
}

}  // namespace remoting
<commit_msg>Fix crash initialising ChromotingHostContext in plugin.<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 "remoting/host/chromoting_host_context.h"

#include <string>

#include "base/bind.h"
#include "base/threading/thread.h"
#include "remoting/host/url_request_context.h"
#include "remoting/jingle_glue/jingle_thread.h"

namespace remoting {

ChromotingHostContext::ChromotingHostContext(
    base::MessageLoopProxy* ui_message_loop)
    : main_thread_("ChromotingMainThread"),
      encode_thread_("ChromotingEncodeThread"),
      desktop_thread_("ChromotingDesktopThread"),
      io_thread_("ChromotingIOThread"),
      file_thread_("ChromotingFileIOThread"),
      ui_message_loop_(ui_message_loop) {
}

ChromotingHostContext::~ChromotingHostContext() {
}

bool ChromotingHostContext::Start() {
  // Start all the threads.
  bool started = main_thread_.Start() && encode_thread_.Start() &&
      jingle_thread_.Start() && desktop_thread_.Start() &&
      io_thread_.StartWithOptions(
          base::Thread::Options(MessageLoop::TYPE_IO, 0)) &&
      file_thread_.StartWithOptions(
          base::Thread::Options(MessageLoop::TYPE_IO, 0));
  if (!started)
    return false;

  // net::ProxyService::CreateSystemProxyConfigService requires a UI thread.
  // TODO(jamiewalch): Clean up this dependency.
  MessageLoop* loop = MessageLoop::current();
  if (loop && loop->type() == MessageLoop::TYPE_UI) {
    url_request_context_getter_ = new URLRequestContextGetter(
        io_thread_.message_loop(), file_thread_.message_loop());
  }
  return true;
}

JingleThread* ChromotingHostContext::jingle_thread() {
  return &jingle_thread_;
}

MessageLoop* ChromotingHostContext::main_message_loop() {
  return main_thread_.message_loop();
}

MessageLoop* ChromotingHostContext::encode_message_loop() {
  return encode_thread_.message_loop();
}

base::MessageLoopProxy* ChromotingHostContext::network_message_loop() {
  return jingle_thread_.message_loop_proxy();
}

MessageLoop* ChromotingHostContext::desktop_message_loop() {
  return desktop_thread_.message_loop();
}

base::MessageLoopProxy* ChromotingHostContext::ui_message_loop() {
  return ui_message_loop_;
}

base::MessageLoopProxy* ChromotingHostContext::io_message_loop() {
  return io_thread_.message_loop_proxy();
}

base::MessageLoopProxy* ChromotingHostContext::file_message_loop() {
  return file_thread_.message_loop_proxy();
}

const scoped_refptr<URLRequestContextGetter>&
ChromotingHostContext::url_request_context_getter() {
  DCHECK(url_request_context_getter_.get());
  return url_request_context_getter_;
}

}  // namespace remoting
<|endoftext|>


<commit_before>#include "bct.h"
#include <gsl/gsl_matrix.h>

/*
 * Computes the connection density of the undirected graph whose
 * adjaceny matrix is m. The total number of possible connections
 * is given by the form N(N-1)/2. N is the number of nodes.
 */
double bct::density_und(const gsl_matrix* m) {
	int N,K;
	double kden;
	int nnz = 0;
	N = m->size1;
	K = bct::nnz(m);
	kden = (double)K/((double)(N*N-N)/2.0);
	return kden;
}

<commit_msg>fixed  missing triu<commit_after>#include "bct.h"
#include <gsl/gsl_matrix.h>

/*
 * Computes the connection density of the undirected graph whose
 * adjaceny matrix is m. The total number of possible connections
 * is given by the form N(N-1)/2. N is the number of nodes.
 */
double bct::density_und(const gsl_matrix* m) {
	int N,K;
	double kden;
	int nnz = 0;
	N = m->size1;
	gsl_matrix* triu_m = bct::triu(m,0);
	K = bct::nnz(triu_m);
	kden = (double)K/((double)(N*N-N)/2.0);
	return kden;
}

<|endoftext|>


<commit_before>/*

PICCANTE Examples
The hottest examples of Piccante:
http://vcg.isti.cnr.it/piccante

Copyright (C) 2014
Visual Computing Laboratory - ISTI CNR
http://vcg.isti.cnr.it
First author: Francesco Banterle

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

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

    See the GNU Lesser General Public License
    ( http://www.gnu.org/licenses/lgpl-3.0.html ) for more details.
*/

//This means that OpenGL acceleration layer is disabled
#define PIC_DISABLE_OPENGL

#include "piccante.hpp"

int main(int argc, char *argv[])
{
    printf("Reading a stack of LDR images...");
    //reading images and storing them with normalized values in [0,1]
    pic::Image img[3];
    img[0].Read("../data/input/stack_alignment/IMG_4209.jpg", pic::LT_NOR);
    img[1].Read("../data/input/stack_alignment/IMG_4210.jpg", pic::LT_NOR);
    img[2].Read("../data/input/stack_alignment/IMG_4211.jpg", pic::LT_NOR);

    printf("Ok\n");

    printf("Are these images valid? ");
    if(img[0].isValid() && img[1].isValid() && img[2].isValid()) {
        printf("Ok\n");

        printf("Aligning bright and dark exposure images to the well-exposed one... ");
        pic::Vec2i shift_dark;
        pic::Image *img_dark = pic::WardAlignment::execute(&img[0], &img[1], shift_dark);
        img_dark->Write("../data/output/stack_aligned_dark.png", pic::LT_NOR);

        pic::Vec2i shift_bright;
        pic::Image *img_bright = pic::WardAlignment::execute(&img[0], &img[2], shift_bright);
        img_bright->Write("../data/output/stack_aligned_bright.png", pic::LT_NOR);
        printf("Ok\n");

        printf("Fusing the aligned images... ");
        auto image_vec = pic::Double(img_bright, img_dark);
        pic::ExposureFusion ef(1.0f, 1.0f, 1.0f);
        pic::Image *imgOut = ef.ProcessStack(image_vec, NULL);

        printf("Ok\n");

        if(imgOut != NULL) {
            imgOut->Write("../data/output/stack_aligned.png", pic::LT_NOR);
        }

    } else {
        printf("No, the files are not valid!\n");
    }

    return 0;
}
<commit_msg>Update main.cpp<commit_after>/*

PICCANTE Examples
The hottest examples of Piccante:
http://vcg.isti.cnr.it/piccante

Copyright (C) 2014
Visual Computing Laboratory - ISTI CNR
http://vcg.isti.cnr.it
First author: Francesco Banterle

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

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

    See the GNU Lesser General Public License
    ( http://www.gnu.org/licenses/lgpl-3.0.html ) for more details.
*/

//This means that OpenGL acceleration layer is disabled
#define PIC_DISABLE_OPENGL

#include "piccante.hpp"

int main(int argc, char *argv[])
{
    printf("Reading a stack of LDR images...");
    //reading images and storing them with normalized values in [0,1]
    pic::Image img[3];
    img[0].Read("../data/input/stack_alignment/IMG_4209.jpg", pic::LT_NOR);
    img[1].Read("../data/input/stack_alignment/IMG_4210.jpg", pic::LT_NOR);
    img[2].Read("../data/input/stack_alignment/IMG_4211.jpg", pic::LT_NOR);

    printf("Ok\n");

    printf("Are these images valid? ");
    if(img[0].isValid() && img[1].isValid() && img[2].isValid()) {
        printf("Ok\n");

        printf("Aligning bright and dark exposure images to the well-exposed one... ");
        pic::Vec2i shift_dark;
        pic::Image *img_dark = pic::WardAlignment::execute(&img[0], &img[1], shift_dark);
        img_dark->Write("../data/output/stack_aligned_dark.png", pic::LT_NOR);

        pic::Vec2i shift_bright;
        pic::Image *img_bright = pic::WardAlignment::execute(&img[0], &img[2], shift_bright);
        img_bright->Write("../data/output/stack_aligned_bright.png", pic::LT_NOR);
        printf("Ok\n");

        printf("Fusing the aligned images... ");
        auto image_vec = pic::Triple(img_bright, &img[0], img_dark);
        pic::ExposureFusion ef(1.0f, 1.0f, 1.0f);
        pic::Image *imgOut = ef.ProcessStack(image_vec, NULL);

        printf("Ok\n");

        if(imgOut != NULL) {
            imgOut->Write("../data/output/stack_aligned.png", pic::LT_NOR);
        }

    } else {
        printf("No, the files are not valid!\n");
    }

    return 0;
}
<|endoftext|>


<commit_before>#include "coreBlocksFactory.h"

#include "details/initialBlock.h"
#include "details/finalBlock.h"
#include "details/nullificationEncoderBlock.h"

#include "details/enginesForwardBlock.h"
#include "details/enginesBackwardBlock.h"
#include "details/enginesStopBlock.h"

#include "details/timerBlock.h"
#include "details/functionBlock.h"

#include "details/loopBlock.h"
#include "details/forkBlock.h"
#include "details/ifBlock.h"
#include "details/commentBlock.h"
#include "details/subprogramBlock.h"

#include "details/waitForTouchSensorBlock.h"
#include "details/waitForSonarDistanceBlock.h"
#include "details/waitForColorBlock.h"
#include "details/waitForColorIntensityBlock.h"
#include "details/waitForLightSensorBlock.h"
#include "details/waitForSoundSensorBlock.h"
#include "details/waitforGyroscopeBlock.h"
#include "details/waitForAccelerometerBlock.h"
#include "details/waitForEncoderBlock.h"

using namespace interpreterCore::coreBlocks;

interpreterBase::blocksBase::Block *CoreBlocksFactory::produceBlock(qReal::Id const &element)
{
	if (elementMetatypeIs(element, "InitialNode")) {
		return new details::InitialBlock();
	} else if (elementMetatypeIs(element, "FinalNode")) {
		return new details::FinalBlock();
	} else if (elementMetatypeIs(element, "Timer")) {
		return new details::TimerBlock(mRobotModelManager->model());
	} else if (elementMetatypeIs(element, "EnginesForward")) {
		return new details::EnginesForwardBlock(mRobotModelManager->model());
	} else if (elementMetatypeIs(element, "EnginesBackward")) {
		return new details::EnginesBackwardBlock(mRobotModelManager->model());
	} else if (elementMetatypeIs(element, "EnginesStop")) {
		return new details::EnginesStopBlock(mRobotModelManager->model());
	} else if (elementMetatypeIs(element, "CommentBlock")) {
		return new details::CommentBlock;
	} else if (elementMetatypeIs(element, "IfBlock")) {
		return new IfBlock();
	} else if (elementMetatypeIs(element, "Loop")) {
		return new LoopBlock();
	} else if (elementMetatypeIs(element, "Fork")) {
		return new ForkBlock();
	} else if (elementMetatypeIs(element, "Subprogram")) {
		return new SubprogramBlock();
	} else if (elementMetatypeIs(element, "Function")) {
		return new FunctionBlock();
	} else if (elementMetatypeIs(element, "NullificationEncoder")) {
		return new details::NullificationEncoderBlock(mRobotModel);
	} else if (elementMetatypeIs(element, "WaitForTouchSensor")) {
		return new details::WaitForTouchSensorBlock(mRobotModelManager->model());
	} else if (elementMetatypeIs(element, "WaitForSonarDistance")) {
		return new details::WaitForSonarDistanceBlock(mRobotModelManager->model());
	} else if (elementMetatypeIs(element, "WaitForColor")) {
		return new details::WaitForColorBlock(mRobotModelManager->model());
	} else if (elementMetatypeIs(element, "WaitForColorIntensity")) {
		return new details::WaitForColorIntensityBlock(mRobotModelManager->model());
	} else if (elementMetatypeIs(element, "WaitForEncoder")) {
		return new details::WaitForEncoderBlock(mRobotModelManager->model());
	} else if (elementMetatypeIs(element, "WaitForLight")) {
		return new details::WaitForLightSensorBlock(mRobotModelManager->model());
	} else if (elementMetatypeIs(element, "WaitForSound")) {
		return new details::WaitForSoundSensorBlock(mRobotModelManager->model());
	} else if (elementMetatypeIs(element, "WaitForGyroscope")) {
		return new details::WaitForGyroscopeSensorBlock(mRobotModelManager->model());
	} else if (elementMetatypeIs(element, "WaitForAccelerometer")) {
		return new details::WaitForAccelerometerSensorBlock(mRobotModelManager->model());
	}

	return nullptr;
}

qReal::IdList CoreBlocksFactory::providedBlocks() const
{
	return {
		id("InitialNode")
		, id("FinalNode")
		, id("Timer")
		, id("EnginesForward")
		, id("EnginesBackward")
		, id("EnginesStop")
		, id("CommentBlock")
		, id("IfBlock")
		, id("Loop")
		, id("Fork")
		, id("Subprogram")
		, id("Function")
		, id("NullificationEncoder")
		, id("WaitForTouchSensor")
		, id("WaitForSonarDistance")
		, id("WaitForColor")
		, id("WaitForColorIntensity")
		, id("WaitForEncoder")
		, id("WaitForLight")
		, id("WaitForSound")
		, id("WaitForGyroscope")
		, id("WaitForAccelerometer")
	};
}
<commit_msg>Made it compilling<commit_after>#include "coreBlocksFactory.h"

#include "details/initialBlock.h"
#include "details/finalBlock.h"
#include "details/nullificationEncoderBlock.h"

#include "details/enginesForwardBlock.h"
#include "details/enginesBackwardBlock.h"
#include "details/enginesStopBlock.h"

#include "details/timerBlock.h"
#include "details/functionBlock.h"

#include "details/loopBlock.h"
#include "details/forkBlock.h"
#include "details/ifBlock.h"
#include "details/commentBlock.h"
#include "details/subprogramBlock.h"

#include "details/waitForTouchSensorBlock.h"
#include "details/waitForSonarDistanceBlock.h"
#include "details/waitForColorBlock.h"
#include "details/waitForColorIntensityBlock.h"
#include "details/waitForLightSensorBlock.h"
#include "details/waitForSoundSensorBlock.h"
#include "details/waitforGyroscopeBlock.h"
#include "details/waitForAccelerometerBlock.h"
#include "details/waitForEncoderBlock.h"

using namespace interpreterCore::coreBlocks;

interpreterBase::blocksBase::Block *CoreBlocksFactory::produceBlock(qReal::Id const &element)
{
	if (elementMetatypeIs(element, "InitialNode")) {
		return new details::InitialBlock();
	} else if (elementMetatypeIs(element, "FinalNode")) {
		return new details::FinalBlock();
	} else if (elementMetatypeIs(element, "Timer")) {
		return new details::TimerBlock(mRobotModelManager->model());
	} else if (elementMetatypeIs(element, "EnginesForward")) {
		return new details::EnginesForwardBlock(mRobotModelManager->model());
	} else if (elementMetatypeIs(element, "EnginesBackward")) {
		return new details::EnginesBackwardBlock(mRobotModelManager->model());
	} else if (elementMetatypeIs(element, "EnginesStop")) {
		return new details::EnginesStopBlock(mRobotModelManager->model());
	} else if (elementMetatypeIs(element, "CommentBlock")) {
		return new details::CommentBlock;
	} else if (elementMetatypeIs(element, "IfBlock")) {
		return new details::IfBlock();
	} else if (elementMetatypeIs(element, "Loop")) {
		return new details::LoopBlock();
	} else if (elementMetatypeIs(element, "Fork")) {
		return new details::ForkBlock();
	} else if (elementMetatypeIs(element, "Subprogram")) {
		return new details::SubprogramBlock();
	} else if (elementMetatypeIs(element, "Function")) {
		return new details::FunctionBlock();
	} else if (elementMetatypeIs(element, "NullificationEncoder")) {
		return new details::NullificationEncoderBlock(mRobotModelManager->model());
	} else if (elementMetatypeIs(element, "WaitForTouchSensor")) {
		return new details::WaitForTouchSensorBlock(mRobotModelManager->model());
	} else if (elementMetatypeIs(element, "WaitForSonarDistance")) {
		return new details::WaitForSonarDistanceBlock(mRobotModelManager->model());
	} else if (elementMetatypeIs(element, "WaitForColor")) {
		return new details::WaitForColorBlock(mRobotModelManager->model());
	} else if (elementMetatypeIs(element, "WaitForColorIntensity")) {
		return new details::WaitForColorIntensityBlock(mRobotModelManager->model());
	} else if (elementMetatypeIs(element, "WaitForEncoder")) {
		return new details::WaitForEncoderBlock(mRobotModelManager->model());
	} else if (elementMetatypeIs(element, "WaitForLight")) {
		return new details::WaitForLightSensorBlock(mRobotModelManager->model());
	} else if (elementMetatypeIs(element, "WaitForSound")) {
		return new details::WaitForSoundSensorBlock(mRobotModelManager->model());
	} else if (elementMetatypeIs(element, "WaitForGyroscope")) {
		return new details::WaitForGyroscopeSensorBlock(mRobotModelManager->model());
	} else if (elementMetatypeIs(element, "WaitForAccelerometer")) {
		return new details::WaitForAccelerometerSensorBlock(mRobotModelManager->model());
	}

	return nullptr;
}

qReal::IdList CoreBlocksFactory::providedBlocks() const
{
	return {
		id("InitialNode")
		, id("FinalNode")
		, id("Timer")
		, id("EnginesForward")
		, id("EnginesBackward")
		, id("EnginesStop")
		, id("CommentBlock")
		, id("IfBlock")
		, id("Loop")
		, id("Fork")
		, id("Subprogram")
		, id("Function")
		, id("NullificationEncoder")
		, id("WaitForTouchSensor")
		, id("WaitForSonarDistance")
		, id("WaitForColor")
		, id("WaitForColorIntensity")
		, id("WaitForEncoder")
		, id("WaitForLight")
		, id("WaitForSound")
		, id("WaitForGyroscope")
		, id("WaitForAccelerometer")
	};
}
<|endoftext|>