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";
void sigUpdateRect(const QRect &r, const QImage &image)
通知视图,图像更新
virtual void slotClipBoardChanged()=0
当剪切板发生改变时调用
virtual OnStartReturnValue OnStart() override
初始化
virtual int OnStop() override
清理
virtual int WakeUp() override
唤醒后台线程。
virtual int OnProcess() override
插件连接的具体操作处理。因为此插件是非Qt事件,所以在此函数中等待。
void sigStop()
需要通知用户停止时触发。仅由插件触发。 当从插件中需要停止时触发。例如:对端断开连接、重置连接或者连接出错。
void sigShowMessageBox(const QString &szTitle, const QString &szMessage, const QMessageBox::Icon &icon=QMessageBox::Information)
从后台线程中触发在主线程中显示消息对话框(QMessageBox),不阻塞后台线程
void sigError(const int nError, const QString &szError=QString())
当有错误产生时触发
void sigBlockShowMessageBox(const QString &szTitle, const QString &szMessage, QMessageBox::StandardButtons buttons, QMessageBox::StandardButton &nRet, bool &checkBox, QString checkBoxContext=QString())
阻塞后台线程,并在前台线程中显示消息对话框(QMessageBox)
void sigRunning()
当插件开始成功后触发。仅由插件触发
void sigFinished()
停止成功信号。仅由插件触发
void sigSecurityLevel(CSecurityLevel::Levels level)
当安全级别改变时触发
void sigBlockShowWidget(const QString &className, int &nRet, void *pContext)
阻塞后台线程,并在前台线程中显示窗口。
CChannel(QTcpSocket *pSocket, QObject *parent=nullptr)
CChannel
static quint32 QtToRfbKey(int inkey, bool modifier)
CConvertKeyCode::QtToRfbKey
static CICE * Instance()
Single instance
virtual CParameterDesktop * GetParameter() const
Get parameter
@ OnlyPasswordX509None
Internet X.509 Public Key Infrastructure Certificate and Certificate Revocation List (CRL) Profile