void RfbClient::sendUpdate(const UpdateContainer *updateContainer, const FrameBuffer *frameBuffer, const CursorShape *cursorShape) { Rect viewPortRect = getViewPortRect(&frameBuffer->getDimension()); m_updateSender->newUpdates(updateContainer, frameBuffer, cursorShape, &viewPortRect); }
void RfbClient::getViewPortInfo(const Dimension *fbDimension, Rect *resultRect, bool *shareApp, Region *shareAppRegion) { AutoLock al(&m_viewPortMutex); *resultRect = getViewPortRect(fbDimension); *shareApp = m_dynamicViewPort.getOnlyApplication(); if (*shareApp) { m_dynamicViewPort.getApplicationRegion(shareAppRegion); } }
void RfbClient::onMouseEvent(UINT16 x, UINT16 y, UINT8 buttonMask) { // Retrieve a view port rect. PixelFormat pfStub; Dimension fbDim; m_desktop->getFrameBufferProperties(&fbDim, &pfStub); Rect vp = getViewPortRect(&fbDim); m_updateSender->blockCursorPosSending(); m_desktop->setMouseEvent(x + vp.left, y + vp.top, buttonMask); }
void RfbClient::execute() { // Initialized by default message that will be logged on normal way // of disconnection. StringStorage peerStr; getPeerHost(&peerStr); StringStorage sysLogMessage; sysLogMessage.format(_T("The client %s has disconnected"), peerStr.getString()); ServerConfig *config = Configurator::getInstance()->getServerConfig(); WindowsEvent connClosingEvent; SocketStream sockStream(m_socket); RfbOutputGate output(&sockStream); RfbInputGate input(&sockStream); FileTransferRequestHandler *fileTransfer = 0; RfbInitializer rfbInitializer(&sockStream, m_extAuthListener, this, !m_isOutgoing); try { // First initialization phase try { m_log->info(_T("Entering RFB initialization phase 1")); rfbInitializer.authPhase(); setClientState(IN_AUTH); m_log->debug(_T("RFB initialization phase 1 completed")); m_shared = rfbInitializer.getSharedFlag(); m_log->debug(_T("Shared flag = %d"), (int)m_shared); m_viewOnlyAuth = rfbInitializer.getViewOnlyAuth(); m_log->debug(_T("Initial view-only state = %d"), (int)m_viewOnly); m_log->debug(_T("Authenticated with view-only password = %d"), (int)m_viewOnlyAuth); m_viewOnly = m_viewOnly || m_viewOnlyAuth; // Let RfbClientManager handle new authenticated connection. m_desktop = m_extAuthListener->onClientAuth(this); m_log->info(_T("View only = %d"), (int)m_viewOnly); } catch (Exception &e) { m_log->error(_T("Error during RFB initialization: %s"), e.getMessage()); throw; } _ASSERT(m_desktop != 0); m_constViewPort.initDesktopInterface(m_desktop); m_dynamicViewPort.initDesktopInterface(m_desktop); RfbDispatcher dispatcher(&input, &connClosingEvent); m_log->debug(_T("Dispatcher has been created")); CapContainer srvToClCaps, clToSrvCaps, encCaps; RfbCodeRegistrator codeRegtor(&dispatcher, &srvToClCaps, &clToSrvCaps, &encCaps); // Init modules // UpdateSender initialization m_updateSender = new UpdateSender(&codeRegtor, m_desktop, this, &output, m_id, m_desktop, m_log); m_log->debug(_T("UpdateSender has been created")); PixelFormat pf; Dimension fbDim; m_desktop->getFrameBufferProperties(&fbDim, &pf); Rect viewPort = getViewPortRect(&fbDim); m_updateSender->init(&Dimension(&viewPort), &pf); m_log->debug(_T("UpdateSender has been initialized")); // ClientInputHandler initialization m_clientInputHandler = new ClientInputHandler(&codeRegtor, this, m_viewOnly); m_log->debug(_T("ClientInputHandler has been created")); // ClipboardExchange initialization m_clipboardExchange = new ClipboardExchange(&codeRegtor, m_desktop, &output, m_viewOnly, m_log); m_log->debug(_T("ClipboardExchange has been created")); // FileTransfers initialization if (config->isFileTransfersEnabled() && rfbInitializer.getTightEnabledFlag()) { fileTransfer = new FileTransferRequestHandler(&codeRegtor, &output, m_desktop, m_log, !m_viewOnly); m_log->debug(_T("File transfer has been created")); } else { m_log->info(_T("File transfer is not allowed")); } // Second initialization phase // Send and receive initialization information between server and viewer m_log->debug(_T("View port: (%d,%d) (%dx%d)"), viewPort.left, viewPort.top, viewPort.getWidth(), viewPort.getHeight()); m_log->info(_T("Entering RFB initialization phase 2")); rfbInitializer.afterAuthPhase(&srvToClCaps, &clToSrvCaps, &encCaps, &Dimension(&viewPort), &pf); m_log->debug(_T("RFB initialization phase 2 completed")); // Start normal phase setClientState(IN_NORMAL_PHASE); m_log->info(_T("Entering normal phase of the RFB protocol")); dispatcher.resume(); connClosingEvent.waitForEvent(); } catch (Exception &e) { m_log->error(_T("Connection will be closed: %s"), e.getMessage()); sysLogMessage.format(_T("The client %s has been") _T(" disconnected for the reason: %s"), peerStr.getString(), e.getMessage()); } disconnect(); m_newConnectionEvents->onDisconnect(&sysLogMessage); // After this call, we are guaranteed not to be used by other threads. notifyAbStateChanging(IN_PENDING_TO_REMOVE); if (fileTransfer) delete fileTransfer; if (m_clipboardExchange) delete m_clipboardExchange; if (m_clientInputHandler) delete m_clientInputHandler; if (m_updateSender) delete m_updateSender; // Let the client manager remove us from the client lists. notifyAbStateChanging(IN_READY_TO_REMOVE); }