void Win8DeskDuplicationThread::processDirtyRects(size_t dirtyCount,
                                                  WinD3D11Texture2D *acquiredDesktopImage)
{
  _ASSERT(dirtyCount <= m_dirtyRects.size());

  Region changedRegion;

  Rect rect;
  Dimension stageDim(&m_targetRect);
  Rect stageRect = stageDim.getRect();
  for (size_t iRect = 0; iRect < dirtyCount; iRect++) {
    rect.fromWindowsRect(&m_dirtyRects[iRect]);

    if (!stageRect.isFullyContainRect(&rect)) {
      rect = rect.intersection(&stageRect);
      /* Disabled the followed throwing because it realy may happen and better is to see any picture
      // instead of a black screen.
      StringStorage errMess;
      errMess.format(_T("During processDirtyRects has been got a rect (%d, %d, %dx%d) which outside")
                     _T(" from the stage rect (%d, %d, %dx%d)"),
                     rect.left, rect.top, rect.getWidth(), rect.getHeight(),
                     stageRect.left, stageRect.top, stageRect.getWidth(), stageRect.getHeight());
      throw Exception(errMess.getString());
      */
    }

    m_device.copySubresourceRegion(m_stageTexture2D.getTexture(), rect.left, rect.top,
                                   acquiredDesktopImage->getTexture(), &rect, 0, 1);

    WinDxgiSurface surface(m_stageTexture2D.getTexture());
    WinAutoMapDxgiSurface autoMapSurface(&surface, DXGI_MAP_READ);

    Rect dstRect(rect);
    // Translate the rect to the frame buffer coordinates.
    dstRect.move(m_targetRect.left, m_targetRect.top);
    m_log->debug(_T("Destination dirty rect = %d, %d, %dx%d"), dstRect.left, dstRect.top, dstRect.getWidth(), dstRect.getHeight());

    stageDim.width = static_cast<int> (autoMapSurface.getStride() / 4);
    m_auxiliaryFrameBuffer.setPropertiesWithoutResize(&stageDim, &m_targetFb->getPixelFormat());
    m_auxiliaryFrameBuffer.setBuffer(autoMapSurface.getBuffer());
    m_targetFb->copyFrom(&dstRect, &m_auxiliaryFrameBuffer, rect.left, rect.top);
    m_auxiliaryFrameBuffer.setBuffer(0);

    changedRegion.addRect(&dstRect);
  }

  m_duplListener->onFrameBufferUpdate(&changedRegion);
}
Esempio n. 2
0
void ConsolePoller::execute()
{
  Log::info(_T("console poller thread id = %d"), getThreadId());

  Rect scanRect;
  Region region;
  while (!isTerminating()) {
    Rect conRect = getConsoleRect();
    if (!conRect.isEmpty()) {
      int pollHeight = m_pollingRect.getHeight();
      int pollWidth = m_pollingRect.getWidth();

      {
        AutoLock al(m_frameBufferMutex);
        Rect offsetFb = m_screenGrabber->getScreenRect();
        conRect.move(-offsetFb.left, -offsetFb.top);
        FrameBuffer *screenFrameBuffer = m_screenGrabber->getScreenBuffer();
        if (screenFrameBuffer->isEqualTo(m_backupFrameBuffer)) {
          m_screenGrabber->grab(&conRect);
          for (int iRow = conRect.top; iRow < conRect.bottom; iRow += pollHeight) {
            for (int iCol = conRect.left; iCol < conRect.right; iCol += pollWidth) {
              scanRect.setRect(iCol, iRow, min(iCol + pollWidth, conRect.right),
                               min(iRow + pollHeight, conRect.bottom));
              if (!screenFrameBuffer->cmpFrom(&scanRect, m_backupFrameBuffer,
                                              scanRect.left, scanRect.top)) {
                region.addRect(&scanRect);
              }
            }
          }
        }
      }

      if (!region.isEmpty()) {
        m_updateKeeper->addChangedRegion(&region);
        doUpdate();
      }
    }
    unsigned int pollInterval = 200;
    m_intervalWaiter.waitForEvent(pollInterval);
  }
}
Esempio n. 3
0
void RfbClient::onMouseEvent(UINT16 x, UINT16 y, UINT8 buttonMask)
{
  PixelFormat pfStub;
  Dimension fbDim;
  m_desktop->getFrameBufferProperties(&fbDim, &pfStub);

  Rect vp;
  bool shareApp;
  Region sharedRegion;
  getViewPortInfo(&fbDim, &vp, &shareApp, &sharedRegion);

  if (!shareApp) {
    sharedRegion.clear();
    sharedRegion.addRect(&vp);
  }
  bool pointInside = sharedRegion.isPointInside(x + vp.left, y + vp.top);

  if (pointInside) {
    m_updateSender->blockCursorPosSending();
    m_desktop->setMouseEvent(x + vp.left, y + vp.top, buttonMask);
  }
}
Esempio n. 4
0
void FbUpdateNotifier::execute()
{
  // Don't send any event to adapter, while adapter isn't set.
  {
    bool adapterIsNull = true;
    while (!isTerminating() && adapterIsNull) {
      // Wait event.
      m_eventUpdate.waitForEvent();

      // Check: now adapter is set?
      AutoLock al(&m_updateLock);
      if (m_adapter != 0) {
        adapterIsNull = false;
      }
    }
  }

  // Send event to adapter, while tread isn't terminated.
  while (!isTerminating()) {
    // If flag is set, then thread going to sleep (wait event).
    bool noUpdates = true;

    // Move updates to local variable with blocking notifier mutex "m_updateLock".
    bool isNewSize;
    bool isCursorChange;
    Region update;
    {
      AutoLock al(&m_updateLock);
      isNewSize = m_isNewSize;
      m_isNewSize = false;

      isCursorChange = m_isCursorChange;
      m_isCursorChange = false;

      update = m_update;
      m_update.clear();
    }

    // Send event "Change properties of frame buffer" to adapter
    // with blocking frame buffer mutex "m_fbLock".
    if (isNewSize) {
      noUpdates = false;
      m_logWriter->debug(_T("FbUpdateNotifier (event): new size of frame buffer"));
      try {
        AutoLock al(m_fbLock);
        m_adapter->onFrameBufferPropChange(m_frameBuffer);
        // FIXME: it's bad code. Must work without one next line, but not it.
        m_adapter->onFrameBufferUpdate(m_frameBuffer, &m_frameBuffer->getDimension().getRect());
      } catch (...) {
        m_logWriter->error(_T("FbUpdateNotifier (event): error in set new size"));
      }
    }

    // Update position on cursor and send frame buffer update event to adapter
    // with blocking frame buffer mutex "m_fbLock".
    if (isCursorChange || !update.isEmpty()) {
      noUpdates = false;

      AutoLock al(m_fbLock);
      Rect cursor = m_cursorPainter.showCursor();
      update.addRect(&cursor);
      update.addRect(&m_oldPosition);

      vector<Rect> updateList;
      update.getRectVector(&updateList);
      m_logWriter->detail(_T("FbUpdateNotifier (event): %u updates"), updateList.size());

      try {
        for (vector<Rect>::iterator i = updateList.begin(); i != updateList.end(); i++) {
          m_adapter->onFrameBufferUpdate(m_frameBuffer, &*i);
        }
      } catch (...) {
        m_logWriter->error(_T("FbUpdateNotifier (event): error in update"));
      }
      m_oldPosition = m_cursorPainter.hideCursor();
    }

    // Pause this thread, if there are no updates (cursor, frame buffer).
    if (noUpdates) {
      m_eventUpdate.waitForEvent();
    }
  }
}