4#include "OperateDesktop.h"
8#include "network/UnixSocket.h"
11#include <rfb/CMsgWriter.h>
12#include <rfb/Hostname.h>
13#include "rfb/LogWriter.h"
15#include <rfb/clipboardTypes.h>
16#include <rfb/LogWriter.h>
17#include <rfb/Logger_stdio.h>
18#include <rfb/fenceTypes.h>
20#include "FramePixelBuffer.h"
25#include <QApplication>
26#include <QLoggingCategory>
29#include <QNetworkProxy>
31#include <QInputDialog>
33#include "rfb/Security.h"
34#include "rfb/Exception.h"
36#include "rfb/CSecurityTLS.h"
41 #include "ChannelIce.h"
45 #include "ChannelSSHTunnel.h"
48#include "ConvertKeyCode.h"
50static Q_LOGGING_CATEGORY(log,
"VNC.Backend")
51static Q_LOGGING_CATEGORY(logVNC,
"VNC.Log")
52static Q_LOGGING_CATEGORY(logKey,
"VNC.Backend.Key")
53static Q_LOGGING_CATEGORY(logInputMethod,
"VNC.Backend.InputMethod")
54static Q_LOGGING_CATEGORY(logMouse,
"VNC.Backend.Mouse")
56class VncLogger: public rfb::Logger
59 VncLogger(
const char *name) : rfb::Logger(name)
61 void write(
int level,
const char *logname,
const char *text)
override
63 if (level >= rfb::LogWriter::LEVEL_DEBUG) {
64 qDebug(logVNC) << logname << text;
65 }
else if (level >= rfb::LogWriter::LEVEL_INFO) {
66 qInfo(logVNC) << logname << text;
67 }
else if (level >= rfb::LogWriter::LEVEL_STATUS) {
68 qWarning(logVNC) << logname << text;
70 qCritical(logVNC) << logname << text;
75static VncLogger g_logger(
"Rabbit");
78static const rfb::PixelFormat verylowColourPF(8, 3,
false,
true, 1, 1, 1, 2, 1, 0);
80static const rfb::PixelFormat lowColourPF(8, 6,
false,
true, 3, 3, 3, 4, 2, 0);
82static const rfb::PixelFormat mediumColourPF(8, 8,
false,
true, 7, 7, 3, 5, 2, 0);
85static const rfb::PixelFormat fullColourPF(32, 24,
false,
true, 255, 255, 255, 16, 8, 0);
88static const unsigned bpsEstimateWindow = 1000;
92 , m_pOperate(pOperate)
96 static bool initlog =
false;
99 g_logger.registerLogger();
100 rfb::LogWriter::setLogParams(
"*:Rabbit:100");
114 if(!m_pPara->GetLocalCursor())
116 emit sigUpdateCursor(QCursor(Qt::BlankCursor));
120CBackendVnc::~CBackendVnc()
122 qDebug(log) <<
"CConnectVnc::~CConnectVnc()";
125int CBackendVnc::SetPara()
127 QDir d(os::getvncconfigdir());
129 d.mkpath(os::getvncconfigdir());
130 QDir dstat(os::getvncstatedir());
132 dstat.mkpath(os::getvncstatedir());
133 QDir dvnc(os::getvncdatadir());
135 dvnc.mkpath(os::getvncdatadir());
137 setServerName(m_pPara->m_Net.GetHost().toStdString().c_str());
138 setShared(m_pPara->GetShared());
139 supportsLocalCursor = m_pPara->GetLocalCursor();
140 supportsCursorPosition = m_pPara->GetCursorPosition();
141 supportsDesktopResize = m_pPara->GetSupportsDesktopResize();
142 supportsLEDState = m_pPara->GetLedState();
144 std::list<uint32_t> sec;
145 switch(m_pPara->m_Net.m_User.GetUsedType()) {
146 case CParameterUser::TYPE::None:
147 sec.push_back(rfb::secTypeNone);
149 case CParameterUser::TYPE::OnlyPassword:
150 sec.push_back(rfb::secTypeVncAuth);
152 case CParameterUser::TYPE::UserPassword:
153 sec.push_back(rfb::secTypePlain);
156 sec.push_back(rfb::secTypeTLSVnc);
158 case CParameterUser::TYPE::OnlyPasswordX509:
159 sec.push_back(rfb::secTypeX509Vnc);
161 case CParameterUser::TYPE::UserPasswordX509None:
162 sec.push_back(rfb::secTypeTLSPlain);
164 case CParameterUser::TYPE::UserPasswordX509:
165 sec.push_back(rfb::secTypeX509Plain);
170 qDebug(log) <<
"secTypes:" << security.GetEnabledSecTypes() << security.ToString()
172 security.SetSecTypes(sec);
175 setPreferredEncoding(m_pPara->GetPreferredEncoding());
176 setCompressLevel(m_pPara->GetCompressLevel());
177 setQualityLevel(m_pPara->GetQualityLevel());
192 qDebug(log) <<
"CConnectVnc::OnStart()";
195 if(m_pPara->GetIce())
199 if(m_pPara->m_Proxy.GetUsedType() == CParameterProxy::TYPE::SSHTunnel) {
201 if(nRet)
return OnStartReturnValue::Fail;
202 return OnStartReturnValue::UseOnProcess;
207 if(nRet)
return OnStartReturnValue::Fail;
209 return OnStartReturnValue::NotUseOnProcess;
212int CBackendVnc::IceInit()
216 if(!pSignal || !pSignal->IsConnected())
218 qCritical(log) <<
"The g_pSignal is null. or signal don't connect server";
222 qInfo(log,
"Connected to signal server:%s:%d; user:%s",
223 CICE::Instance()->GetParameter()->getSignalServer().toStdString().c_str(),
225 CICE::Instance()->GetParameter()->getSignalUser().toStdString().c_str());
226 auto channel = QSharedPointer<CChannelIce>(
new CChannelIce(pSignal));
229 qCritical(log) <<
"new CDataChannelIce fail";
232 m_DataChannel = channel;
233 SetChannelConnect(channel);
235 rtc::Configuration config;
236 rtc::IceServer stun(
CICE::Instance()->GetParameter()->getStunServer().toStdString().c_str(),
238 rtc::IceServer turn(
CICE::Instance()->GetParameter()->getTurnServer().toStdString().c_str(),
240 CICE::Instance()->GetParameter()->getTurnUser().toStdString().c_str(),
241 CICE::Instance()->GetParameter()->getTurnPassword().toStdString().c_str());
242 config.iceServers.push_back(stun);
243 config.iceServers.push_back(turn);
244 channel->SetConfigure(config);
246 bool bRet = channel->open(
CICE::Instance()->GetParameter()->getSignalUser(),
247 m_pPara->GetPeerUser(),
true);
250 emit
sigError(-1,
"Open channel fail");
257int CBackendVnc::SocketInit()
261 QTcpSocket* pSock =
new QTcpSocket(
this);
264 m_DataChannel = QSharedPointer<CChannel>(
new CChannel(pSock));
266 qCritical(log) <<
"New CChannel fail";
270 SetChannelConnect(m_DataChannel);
272 if(!m_DataChannel->open(QIODevice::ReadWrite))
274 qCritical(log) <<
"Open channel fail";
278 QNetworkProxy::ProxyType type = QNetworkProxy::NoProxy;
280 switch(m_pPara->m_Proxy.GetUsedType())
282 case CParameterProxy::TYPE::SockesV5:
283 type = QNetworkProxy::Socks5Proxy;
285 case CParameterProxy::TYPE::System:
286 type = QNetworkProxy::DefaultProxy;
288 case CParameterProxy::TYPE::Http:
289 type = QNetworkProxy::HttpProxy;
291 case CParameterProxy::TYPE::None:
297 case QNetworkProxy::DefaultProxy:
299 pSock->setProxy(QNetworkProxy::applicationProxy());
302 case QNetworkProxy::HttpProxy:
303 case QNetworkProxy::Socks5Proxy:
306 auto net = &m_pPara->m_Proxy.m_SockesV5;
307 if(QNetworkProxy::HttpProxy == type) {
308 net = &m_pPara->m_Proxy.m_Http;
310 if(net->GetHost().isEmpty())
313 szErr = tr(
"The proxy server is empty, please input it");
314 qCritical(log) << szErr;
318 proxy.setHostName(net->GetHost());
319 proxy.setPort(net->GetPort());
320 auto &user = net->m_User;
321 if(((user.GetUsedType() == CParameterUser::TYPE::UserPassword)
322 && (user.GetPassword().isEmpty() || user.GetUser().isEmpty()))
323 || ((user.GetUsedType() == CParameterUser::TYPE::PublicKey)
324 && user.GetPassphrase().isEmpty())) {
325 int nRet = QDialog::Rejected;
327 if(QDialog::Accepted != nRet)
332 proxy.setUser(user.GetUser());
333 proxy.setPassword(user.GetPassword());
335 pSock->setProxy(proxy);
342 if(m_pPara->m_Net.GetHost().isEmpty())
345 szErr = tr(
"The server is empty, please input it");
346 qCritical(log) << szErr;
350 pSock->connectToHost(m_pPara->m_Net.GetHost(), m_pPara->m_Net.GetPort());
353 serverHost = pSock->peerName();
354 qDebug(log) <<
"Server Host:" << serverHost;
355 setServerName(serverHost.toStdString().c_str());
358 }
catch (rdr::Exception& e) {
359 qCritical(log) <<
"SocketInit exception:" << e.str();
366int CBackendVnc::SSHInit()
369 auto channel = QSharedPointer<CChannelSSHTunnel>(
370 new CChannelSSHTunnel(&m_pPara->m_Proxy.m_SSH, &m_pPara->m_Net,
this));
372 qCritical(log) <<
"New CChannelSSHTunnel fail";
375 m_DataChannel = channel;
376 SetChannelConnect(m_DataChannel);
377 if(!channel->open(QIODevice::ReadWrite))
380 szErr = tr(
"Failed to open SSH tunnel:");
381 szErr +=
"(" + m_pPara->m_Proxy.m_SSH.m_Net.GetHost();
383 szErr += QString::number(m_pPara->m_Proxy.m_SSH.m_Net.GetPort());
385 szErr += m_pPara->m_Net.GetHost();
387 szErr += QString::number(m_pPara->m_Net.GetPort()) +
")";
388 QString szMsg = szErr +
"\n" + channel->errorString();
392 m_SecurityLevel = CSecurityLevel::Level::Proxy;
397int CBackendVnc::SetChannelConnect(QSharedPointer<CChannel> channel)
400 check = connect(channel.data(), SIGNAL(sigConnected()),
401 this, SLOT(slotConnected()));
403 check = connect(channel.data(), SIGNAL(sigDisconnected()),
404 this, SLOT(slotDisConnected()));
406 check = connect(channel.data(), SIGNAL(readyRead()),
407 this, SLOT(slotReadyRead()));
409 check = connect(channel.data(), SIGNAL(
sigError(
int,
const QString&)),
410 this, SLOT(slotChannelError(
int,
const QString&)));
412 if(m_pOperate && m_pOperate->GetStats()) {
413 check = connect(channel.data(), SIGNAL(sigReceive(quint64)),
414 m_pOperate->GetStats(), SLOT(AddReceives(quint64)));
416 check = connect(channel.data(), SIGNAL(sigSend(quint64)),
417 m_pOperate->GetStats(), SLOT(AddSends(quint64)));
425 qDebug(log) <<
"CConnectVnc::OnStop()";
427 setStreams(
nullptr,
nullptr);
429 m_DataChannel->close();
452 if(m_pPara->m_Proxy.GetUsedType() == CParameterProxy::TYPE::SSHTunnel) {
465 if(m_pPara->m_Proxy.GetUsedType() == CParameterProxy::TYPE::SSHTunnel) {
474void CBackendVnc::slotConnected()
476 qDebug(log) << Q_FUNC_INFO;
477 if(m_pPara->GetIce())
478 qInfo(log) <<
"Connected to peer " + m_pPara->GetPeerUser();
480 auto &net = m_pPara->m_Net;
481 QString szInfo =
"Connected to "
482 + net.GetHost() +
":" + QString::number(net.GetPort());
484 if(CParameterProxy::TYPE::SSHTunnel == m_pPara->m_Proxy.GetUsedType())
486 auto &sshNet = m_pPara->m_Proxy.m_SSH.m_Net;
487 szInfo +=
" with ssh turnnel: " + sshNet.GetHost()
488 +
":" + QString::number(sshNet.GetPort());
491 qInfo(log) << szInfo;
493 int nRet = SetPara();
499 m_InStream = QSharedPointer<rdr::InStream>(
new CInStreamChannel(m_DataChannel.data()));
500 m_OutStream = QSharedPointer<rdr::OutStream>(
new COutStreamChannel(m_DataChannel.data()));
501 if(!(m_InStream && m_OutStream))
503 qCritical(log) <<
"m_InStream or m_OutStream is null";
507 setStreams(m_InStream.data(), m_OutStream.data());
508 initialiseProtocol();
511void CBackendVnc::slotDisConnected()
514 szInfo =
"CConnectVnc::slotDisConnected() from "
515 + m_pPara->m_Net.GetHost() +
":"
516 + QString::number(m_pPara->m_Net.GetPort());
518 if(CParameterProxy::TYPE::SSHTunnel == m_pPara->m_Proxy.GetUsedType())
520 auto &net = m_pPara->m_Proxy.m_SSH.m_Net;
521 szInfo +=
" with ssh turnnel: " + net.GetHost()
522 +
":" + QString::number(net.GetPort());
525 qInfo(log) << szInfo;
528void CBackendVnc::slotReadyRead()
531 QString szErr(
"processMsg exception: ");
534 getOutStream()->flush();
536 getOutStream()->cork(
true);
539 getOutStream()->cork(
false);
541 }
catch (rfb::AuthFailureException& e) {
542 szErr = tr(
"Logon to ");
543 szErr += m_pPara->m_Net.GetHost();
545 szErr += QString::number(m_pPara->m_Net.GetPort());
546 szErr += tr(
" fail.");
547 QString szMsg = szErr +
"\n" + tr(
"Please check that the username and password are correct.") +
"\n";
553 }
catch (rfb::ConnFailedException& e) {
555 szErr = tr(
"Connect to ");
556 szErr += m_pPara->m_Net.GetHost();
558 szErr += QString::number(m_pPara->m_Net.GetPort());
559 szErr += tr(
" fail.");
564 }
catch (rdr::EndOfStream& e) {
566 }
catch(rdr::GAIException &e) {
568 szErr +=
"[" + QString::number(e.err) +
"] " + e.str();
569 }
catch(rdr::SystemException &e) {
571 szErr +=
"[" + QString::number(e.err) +
"] " + e.str();
572 }
catch (rdr::Exception& e) {
574 }
catch (std::exception &e) {
577 szErr +=
"unknown exception";
579 qCritical(log) << szErr;
584void CBackendVnc::slotChannelError(
int nErr,
const QString& szErr)
586 qDebug(log) <<
"Channel error:" << nErr <<
"-" << szErr;
594void CBackendVnc::initDone()
597 qDebug(log,
"initDone: %s", ConnectInformation().toStdString().c_str());
599 emit sigSetDesktopSize(server.width(), server.height());
600 QString szName = QString::fromUtf8(server.name());
601 emit sigServerName(szName);
604 setFramebuffer(
new CFramePixelBuffer(server.width(), server.height()));
608 setPreferredEncoding(m_pPara->GetPreferredEncoding());
615void CBackendVnc::resizeFramebuffer()
617 rfb::ModifiablePixelBuffer* buffer = getFramebuffer();
619 qDebug(log) <<
"CConnectVnc::resizeFramebuffer: new:"
620 << server.width() << server.height()
621 <<
"old:" << buffer->width() << buffer->height();
623 if(server.width() == buffer->width() && server.height() == buffer->height())
627 setFramebuffer(
new CFramePixelBuffer(server.width(), server.height()));
628 emit sigSetDesktopSize(server.width(), server.height());
631void CBackendVnc::setColourMapEntries(
int firstColour,
int nColours, uint16_t *rgbs)
633 qCritical(log) <<
"Invalid SetColourMapEntries from server!";
636void CBackendVnc::bell()
641void CBackendVnc::setLEDState(
unsigned int state)
643 qDebug(log) <<
"CConnectVnc::setLEDState" << state;
644 CConnection::setLEDState(state);
645 emit sigUpdateLedState(state);
648void CBackendVnc::setCursor(
int width,
int height,
const rfb::Point &hotspot,
const uint8_t *data)
651 if ((width == 0) || (height == 0)) {
652 QImage cursor(1, 1, QImage::Format_ARGB32);
653 uint8_t *buffer = cursor.bits();
654 memset(buffer, 0, 4);
655 emit sigUpdateCursor(QCursor(QPixmap::fromImage(cursor), hotspot.x, hotspot.y));
657 QImage cursor(width, height, QImage::Format_ARGB32);
658 uint8_t *buffer = cursor.bits();
659 memcpy(buffer, data, width * height * 4);
660 emit sigUpdateCursor(QCursor(QPixmap::fromImage(cursor), hotspot.x, hotspot.y));
664void CBackendVnc::setCursorPos(
const rfb::Point &pos)
667 emit sigUpdateCursorPosition(QPoint(pos.x, pos.y));
670void CBackendVnc::fence(uint32_t flags,
unsigned int len,
const uint8_t data[])
673 CMsgHandler::fence(flags, len, data);
674 if (!(flags & rfb::fenceFlagRequest))
678 flags = flags & (rfb::fenceFlagBlockBefore | rfb::fenceFlagBlockAfter);
679 writer()->writeFence(flags, len, data);
683void CBackendVnc::getUserPasswd(
bool secure, std::string *user, std::string *password)
687 auto &user = m_pPara->m_Net.m_User;
688 *password = user.GetPassword().toStdString();
689 if(user.GetPassword().isEmpty())
691 int nRet = QDialog::Rejected;
692 auto *net = &m_pPara->m_Net;
694 if(QDialog::Accepted == nRet)
696 *password = user.GetPassword().toStdString();
699 if(!password->empty())
700 m_SecurityLevel |= CSecurityLevel::Level::Authentication;
704int CBackendVnc::getX509File(std::string *ca, std::string *crl)
706 auto &user = m_pPara->m_Net.m_User;
708 *ca = user.GetCAFile().toStdString().c_str();
710 *crl = user.GetCRLFile().toStdString().c_str();
714bool CBackendVnc::showMsgBox(rfb::MsgBoxFlags flags,
const char *title,
const char *text)
716 qDebug(log) << title << text;
717 QMessageBox::StandardButton nRet = QMessageBox::No;
718 QMessageBox::StandardButtons fgBtn = QMessageBox::No;
720 if((
int)flags & (
int)rfb::MsgBoxFlags::M_OK)
721 fgBtn |= QMessageBox::Ok;
723 if((
int)flags & (
int)rfb::MsgBoxFlags::M_OKCANCEL)
724 fgBtn |= QMessageBox::Ok | QMessageBox::Cancel;
725 if((
int)flags & (
int)rfb::MsgBoxFlags::M_YESNO)
726 fgBtn |= QMessageBox::Yes | QMessageBox::No;
729 fgBtn, nRet, bCheckBox);
730 if(QMessageBox::Ok == nRet
731 || QMessageBox::Yes == nRet)
737void CBackendVnc::setName(
const char *name)
739 qDebug(log) <<
"CConnectVnc::setName:" << name;
740 CConnection::setName(name);
741 QString szName = QString::fromUtf8(server.name());
742 emit sigServerName(szName);
749void CBackendVnc::framebufferUpdateStart()
752 CConnection::framebufferUpdateStart();
759void CBackendVnc::framebufferUpdateEnd()
762 rfb::CConnection::framebufferUpdateEnd();
766 const QImage& img =
dynamic_cast<CFramePixelBuffer*
>(getFramebuffer())->getImage();
773void CBackendVnc::updatePixelFormat()
780 switch (m_pPara->GetColorLevel()) {
781 case CParameterVnc::Full:
784 case CParameterVnc::Medium:
787 case CParameterVnc::Low:
790 case CParameterVnc::VeryLow:
791 pf = verylowColourPF;
797 qInfo(log) <<
"Update pixel format:" << str;
801void CBackendVnc::mousePressEvent(QMouseEvent *event)
803 if(!writer())
return;
804 if(m_pPara && m_pPara->GetOnlyView())
return;
807 if(event->button() & Qt::MouseButton::LeftButton)
809 if(event->button() & Qt::MouseButton::MiddleButton)
811 if(event->button() & Qt::MouseButton::RightButton)
813 if(event->button() & Qt::MouseButton::BackButton)
816 QPoint pos =
event->pos();
817 rfb::Point p(pos.x(), pos.y());
822 writer()->writePointerEvent(p, mask);
823 }
catch (rdr::Exception& e) {
828void CBackendVnc::mouseReleaseEvent(QMouseEvent *event)
830 if(!writer())
return;
831 if(m_pPara && m_pPara->GetOnlyView())
return;
833 QPoint pos =
event->pos();
834 rfb::Point p(pos.x(), pos.y());
837 writer()->writePointerEvent(p, mask);
838 }
catch (rdr::Exception& e) {
843void CBackendVnc::mouseMoveEvent(QMouseEvent *event)
845 if(!writer())
return;
846 if(m_pPara && m_pPara->GetOnlyView())
return;
848 QPoint pos =
event->pos();
849 rfb::Point p(pos.x(), pos.y());
851 if(event->buttons() & Qt::MouseButton::LeftButton)
853 if(event->buttons() & Qt::MouseButton::MiddleButton)
855 if(event->buttons() & Qt::MouseButton::RightButton)
857 if(event->buttons() & Qt::MouseButton::BackButton)
863 writer()->writePointerEvent(p, mask);
864 }
catch (rdr::Exception& e) {
870void CBackendVnc::wheelEvent(QWheelEvent *event)
872 if(!writer())
return;
873 if(m_pPara && m_pPara->GetOnlyView())
return;
875 if(event->buttons() & Qt::MouseButton::LeftButton)
877 if(event->buttons() & Qt::MouseButton::MiddleButton)
879 if(event->buttons() & Qt::MouseButton::RightButton)
881 if(event->buttons() & Qt::MouseButton::BackButton)
884 QPoint d =
event->angleDelta();
895#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
896 pos =
event->position();
901 rfb::Point p(pos.x(), pos.y());
910 writer()->writePointerEvent(p, mask);
911 }
catch (rdr::Exception& e) {
916void CBackendVnc::keyPressEvent(QKeyEvent *event)
918 if(!writer())
return;
919 if(m_pPara && m_pPara->GetOnlyView())
return;
920 bool modifier =
false;
921 if (event->modifiers() & Qt::ShiftModifier)
928 writer()->writeKeyEvent(k, 0,
true);
929 }
catch (rdr::Exception& e) {
934void CBackendVnc::keyReleaseEvent(QKeyEvent *event)
936 if(m_pPara && m_pPara->GetOnlyView())
return;
937 if(!writer())
return;
938 bool modifier =
false;
939 if (event->modifiers() & Qt::ShiftModifier)
946 writer()->writeKeyEvent(k, 0,
false);
947 }
catch (rdr::Exception& e) {
952void CBackendVnc::InputMethodEvent(QInputMethodEvent *event)
955 if (m_pPara && m_pPara->GetOnlyView())
return;
956 if (!writer())
return;
958 QString szText =
event->commitString();
959 if (szText.isEmpty())
964 QVector<uint32_t> ucs4 = szText.toUcs4();
965 foreach (uint32_t cp, ucs4) {
966 quint32 keysym =
static_cast<quint32
>(cp);
968 writer()->writeKeyEvent(keysym, 0,
true);
969 writer()->writeKeyEvent(keysym, 0,
false);
970 }
catch (rdr::Exception &e) {
976QString CBackendVnc::ConnectInformation()
981 szInfo = QString(
"Desktop name: ") + server.name() +
"\n";
982 szInfo += QString(
"Size: %1 x %2").arg(server.width()).arg(server.height()) +
"\n";
986 server.pf().print(buf, len);
987 szInfo += QString(
"Pixel format: ") + buf +
"\n";
988 szInfo += QString(
"Requested encoding: ") + rfb::encodingName(getPreferredEncoding()) +
"\n";
989 szInfo += QString(
"Protocol version: %1.%2").arg(server.majorVersion).arg(server.minorVersion) +
"\n";
990 szInfo += QString(
"Security method: ") + rfb::secTypeName(csecurity->getType()) +
"\n";
991 szInfo += QString(
"Support local cursor: %1").arg(supportsLocalCursor) +
"\n";
992 szInfo += QString(
"Support cursor position: %1").arg(supportsCursorPosition) +
"\n";
993 szInfo += QString(
"Support desktop resize: %1").arg(supportsDesktopResize) +
"\n";
994 szInfo += QString(
"Support LED state: %1").arg(supportsLEDState) +
"\n";
995 szInfo += QString(
"Led state: %1").arg(server.ledState()) +
"\n";
996 szInfo += QString(
"Supports QEMU KeyEvent: %1").arg(server.supportsQEMUKeyEvent) +
"\n";
997 szInfo += QString(
"Supports Set Desktop Size: %1").arg(server.supportsSetDesktopSize) +
"\n";
998 szInfo += QString(
"Support fance: %1").arg(server.supportsFence) +
"\n";
999 szInfo += QString(
"Support continue updates: %1").arg(server.supportsContinuousUpdates) +
"\n";
1007 if(!m_pPara->GetClipboard() || !getOutStream() || !writer())
return;
1008 QClipboard* pClip = QApplication::clipboard();
1009 if(pClip->ownsClipboard())
return;
1010 announceClipboard(
true);
1013void CBackendVnc::handleClipboardRequest()
1016 if(!m_pPara->GetClipboard() || !getOutStream() || !writer())
return;
1017 const QClipboard *clipboard = QApplication::clipboard();
1018 const QMimeData *mimeData = clipboard->mimeData();
1022if (mimeData->hasText()) {
1023 QString szText = mimeData->text();
1025 <<
"CConnectVnc::handleClipboardRequest:szText:" << szText;
1027 sendClipboardData(szText.toStdString().c_str());
1028 }
catch (rdr::Exception& e) {
1029 qCritical(log) <<
"sendClipboardData exception" << e.str();
1041 qCritical(log) <<
"Cannot display data";
1045void CBackendVnc::handleClipboardAnnounce(
bool available)
1048 if(!m_pPara->GetClipboard() || !getOutStream() || !writer())
return;
1050 this->requestClipboard();
1053void CBackendVnc::handleClipboardData(
const char *data)
1056 if(!m_pPara->GetClipboard() || !getOutStream() || !writer())
return;
1058 QMimeData* pData =
new QMimeData();
1059 pData->setText(QString::fromUtf8(data));
1060 emit sigSetClipboard(pData);
1063void CBackendVnc::authSuccess()
1065 qDebug(log) <<
"CConnectVnc::authSuccess";
Remote desktop interface.
void sigUpdateRect(const QRect &r, const QImage &image)
Notify the CFrmView update image.
virtual void slotClipBoardChanged()=0
Be called when the clip board change.
virtual OnStartReturnValue OnStart() override
Initialization.
virtual int OnStop() override
Clean.
virtual int WakeUp() override
Wake up backend thread(background thread).
virtual int OnProcess() override
Specific operation processing of plug-in connection.
void sigStop()
Notify the user to stop.
void sigShowMessageBox(const QString &szTitle, const QString &szMessage, const QMessageBox::Icon &icon=QMessageBox::Information)
Trigger the display of a message dialog (QMessageBox) in the main thread from a background thread wit...
void sigError(const int nError, const QString &szError=QString())
Triggered when an error is generated.
void sigBlockShowMessageBox(const QString &szTitle, const QString &szMessage, QMessageBox::StandardButtons buttons, QMessageBox::StandardButton &nRet, bool &checkBox, QString checkBoxContext=QString())
Block background threads and display message dialogs in foreground threads (QMessageBox).
void sigRunning()
Emitted when the plugin is successfully started.
void sigFinished()
Successful stopped signal.
void sigSecurityLevel(CSecurityLevel::Levels level)
Triggered when the security level changes.
void sigBlockShowWidget(const QString &className, int &nRet, void *pContext)
Blocks the background thread and displays the window in the foreground thread.
CChannel(QTcpSocket *pSocket, QObject *parent=nullptr)
CChannel.
static quint32 QtToRfbKey(int inkey, bool modifier)
CConvertKeyCode::QtToRfbKey.
static CICE * Instance()
Single instance.
The ICE signal interface class.
Remote desktop operate interface.
virtual CParameterDesktop * GetParameter() const
Get parameter.
@ OnlyPasswordX509None
Internet X.509 Public Key Infrastructure Certificate and Certificate Revocation List (CRL) Profile.