4#include <QNetworkProxy> 
    6#include <QLoggingCategory> 
    8#include "BackendLibVNCServer.h" 
   11static Q_LOGGING_CATEGORY(log, 
"LibVNCServer.Connect")
 
   12static Q_LOGGING_CATEGORY(logger, "LibVNCServer.Connect.log")
 
   13static Q_LOGGING_CATEGORY(logKey, "LibVNCServer.Connect.Key")
 
   14static Q_LOGGING_CATEGORY(logMouse, "LibVNCServer.Connect.Mouse")
 
   16const 
char* gThis = "This pointer";
 
   17#define LOG_BUFFER_LENGTH 1024 
   18static void rfbQtClientLog(
const char *format, ...)
 
   22    char buf[LOG_BUFFER_LENGTH];
 
   24    if(!rfbEnableClientLogging)
 
   27    va_start(args, format);    
 
   28    nRet = vsnprintf(buf, LOG_BUFFER_LENGTH, format, args);
 
   32        qCritical(log) << 
"vsnprintf fail";
 
   35    if(nRet >= LOG_BUFFER_LENGTH)
 
   37        qCritical(log) << 
"vsprintf buf is short," 
   38                                << nRet << 
">" <<  LOG_BUFFER_LENGTH
 
   39                                << 
". Truncated it:" << nRet - LOG_BUFFER_LENGTH;
 
   40        buf[LOG_BUFFER_LENGTH - 1] = 0;
 
   42    qDebug(logger) << buf;
 
   53    rfbClientLog = rfbQtClientLog;
 
   55    if(!m_pParameter->GetLocalCursor())
 
   57        emit sigUpdateCursor(QCursor(Qt::BlankCursor));
 
   61CBackendLibVNCServer::~CBackendLibVNCServer()
 
   63    qDebug(log) << 
"CConnectLibVNCServer::~CConnectLibVNCServer()";
 
   74    qDebug(log) << 
"CConnectLibVNCServer::OnInit()";
 
   75    if(m_pClient) Q_ASSERT(
false);
 
   77    m_pClient = rfbGetClient(8, 3, 4);
 
   81        szErr = tr(
"Protocol version error");
 
   83        qCritical(log) << 
"rfbGetClient fail";
 
   84        return OnInitReturnValue::Fail;
 
   88    m_pClient->programName = strdup(qApp->applicationName().toStdString().c_str());
 
   89    m_pClient->appData.shareDesktop = m_pParameter->GetShared();
 
   90    m_pClient->appData.viewOnly = m_pParameter->GetOnlyView();
 
   91    m_pClient->appData.useRemoteCursor = m_pParameter->GetLocalCursor();
 
  130    m_pClient->appData.enableJPEG = m_pParameter->GetJpeg();
 
  131    if(m_pClient->appData.enableJPEG)
 
  132        m_pClient->appData.qualityLevel = m_pParameter->GetQualityLevel();
 
  133    if(m_pParameter->GetEnableCompressLevel())
 
  134        m_pClient->appData.compressLevel = m_pParameter->GetCompressLevel();
 
  137    m_pClient->MallocFrameBuffer = cb_resize;
 
  138    m_pClient->GotFrameBufferUpdate = cb_update;
 
  139    m_pClient->HandleKeyboardLedState = cb_kbd_leds;
 
  140    m_pClient->Bell = cb_bell;
 
  141    m_pClient->HandleTextChat = cb_text_chat;
 
  142    m_pClient->GotXCutText = cb_got_selection;
 
  143    m_pClient->GetCredential = cb_get_credential;
 
  144    m_pClient->GetPassword = cb_get_password;
 
  145    m_pClient->HandleCursorPos = cb_cursor_pos;
 
  146    m_pClient->GotCursorShape = cb_got_cursor_shape;
 
  148    m_pClient->canHandleNewFBSize = TRUE;
 
  149    rfbClientSetClientData(m_pClient, (
void*)gThis, 
this);
 
  152    switch(m_pParameter->m_Proxy.GetUsedType())
 
  154    case CParameterProxy::TYPE::None:
 
  157        if(m_pParameter->m_Net.GetHost().isEmpty())
 
  160            szErr = tr(
"The server is empty, please input it");
 
  161            qCritical(log) << szErr;
 
  163            return OnInitReturnValue::Fail;
 
  165        auto &net = m_pParameter->m_Net;
 
  166        m_pClient->serverHost = strdup(net.GetHost().toStdString().c_str());
 
  167        m_pClient->serverPort = net.GetPort();
 
  169        if(!rfbInitClient(m_pClient, 
nullptr, 
nullptr))
 
  174            szErr = tr(
"Fail: Connect to %1:%2").arg(m_pParameter->m_Net.GetHost(),
 
  175                                                    QString::number(m_pParameter->m_Net.GetPort()));
 
  176            qCritical(log) <<  szErr;
 
  178            return OnInitReturnValue::Fail;
 
  181        QString szInfo = QString(
"Connected to ") + m_pClient->desktopName;
 
  182        qInfo(log) << szInfo;
 
  184        emit sigSetDesktopSize(m_pClient->width, m_pClient->height);
 
  185        emit sigServerName(m_pClient->desktopName);
 
  188        return OnInitReturnValue::UseOnProcess;
 
  234    case CParameterProxy::TYPE::SSHTunnel:
 
  240                &m_pParameter->m_Proxy.m_SSH, &m_pParameter->m_Net, 
this);
 
  243            return OnInitReturnValue::Fail;
 
  244        bool check = connect(m_pThread, SIGNAL(sigServer(QString, quint16)),
 
  247#if defined(HAVE_UNIX_DOMAIN_SOCKET) 
  248        check = connect(m_pThread, SIGNAL(sigServer(QString)),
 
  252        check = connect(m_pThread, SIGNAL(
sigError(
int,QString)),
 
  253                        this, SIGNAL(
sigError(
int,QString)));
 
  255        check = connect(m_pThread, SIGNAL(
sigStop()),
 
  260        return OnInitReturnValue::NotUseOnProcess;
 
  268    return OnInitReturnValue::UseOnProcess;
 
 
  273    qDebug(log) << 
"CConnectLibVNCServer::OnClean()";
 
  277        disconnect(m_pThread);
 
  285        rfbClientCleanup(m_pClient);
 
 
  314    struct timeval timeout = {0, DEFAULT_TIMEOUT};
 
  317    if(RFB_INVALID_SOCKET != m_pClient->sock)
 
  319        FD_SET(m_pClient->sock, &set);
 
  321    rfbSocket eventFd = m_Event.GetFd();
 
  322    if(RFB_INVALID_SOCKET != eventFd)
 
  324        FD_SET(eventFd, &set);
 
  326    rfbSocket fd = RFB_INVALID_SOCKET;
 
  327    fd = std::max(eventFd, m_pClient->sock);
 
  329    nRet = select(fd + 1, &set, NULL, NULL, &timeout);
 
  332        qCritical(log) << 
"select fail:" << nRet << 
"errno" << errno << strerror(errno);
 
  342    if(RFB_INVALID_SOCKET != eventFd && FD_ISSET(eventFd, &set))
 
  348    if(RFB_INVALID_SOCKET != m_pClient->sock
 
  349        && FD_ISSET(m_pClient->sock, &set)) {
 
  351        if(!HandleRFBServerMessage(m_pClient))
 
  353            qCritical(log) << 
"HandleRFBServerMessage fail";
 
 
  363    return m_Event.WakeUp();
 
 
  366void CBackendLibVNCServer::slotClipBoardChanged()
 
  368    if(!m_pParameter || !m_pParameter->GetClipboard() || !m_pClient) 
return;
 
  369    QClipboard* pClipboard = QApplication::clipboard();
 
  372        QString szText = pClipboard->text();
 
  373        if(!szText.isEmpty() && m_pClient)
 
  374            SendClientCutText(m_pClient,
 
  375                              (
char*)szText.toStdString().c_str(),
 
  376                              szText.toStdString().length());
 
  380rfbBool CBackendLibVNCServer::cb_resize(rfbClient* client)
 
  384    if(pThis->OnSize()) 
return FALSE;
 
  388void CBackendLibVNCServer::cb_update(rfbClient *client, 
int x, 
int y, 
int w, 
int h)
 
  394    QRect rect(x, y, w, h);
 
  395    QImage img = pThis->m_Image.copy(rect);
 
  399void CBackendLibVNCServer::cb_got_selection(rfbClient *client, 
const char *text, 
int len)
 
  403    if(!pThis->m_pParameter->GetClipboard()) 
return;
 
  404    QClipboard* pClipboard = QApplication::clipboard();
 
  406        pClipboard->setText(text);
 
  409void CBackendLibVNCServer::cb_kbd_leds(rfbClient *client, 
int value, 
int pad)
 
  411    qDebug(log) << 
"CConnectLibVnc::cb_kbd_leds";
 
  414void CBackendLibVNCServer::cb_bell(
struct _rfbClient *client)
 
  419void CBackendLibVNCServer::cb_text_chat(rfbClient *client, 
int value, 
char *text)
 
  421    qDebug(log) << 
"CConnectLibVnc::cb_text_chat";
 
  424rfbCredential* CBackendLibVNCServer::cb_get_credential(rfbClient *cl, 
int credentialType)
 
  426    qDebug(log) <<
"CConnectLibVnc::cb_get_credential";
 
  428    rfbCredential *c = (rfbCredential*)malloc(
sizeof(rfbCredential));
 
  429    c->userCredential.username = (
char*)malloc(RFB_BUF_SIZE);
 
  430    memset(c->userCredential.username, 0, RFB_BUF_SIZE);
 
  431    c->userCredential.password = (
char*)malloc(RFB_BUF_SIZE);
 
  432    memset(c->userCredential.password, 0, RFB_BUF_SIZE);
 
  434    if(credentialType != rfbCredentialTypeUser) {
 
  435        qCritical(log) << 
"something else than username and password required for authentication";
 
  439    qDebug(log) << 
"Username and password required for authentication!";
 
  441    memcpy(c->userCredential.username,
 
  442           pThis->m_pParameter->m_Net.
m_User.GetUser().toStdString().c_str(),
 
  443           pThis->m_pParameter->m_Net.
m_User.GetUser().toStdString().length());
 
  444    memcpy(c->userCredential.password,
 
  445           pThis->m_pParameter->m_Net.
m_User.GetPassword().toStdString().c_str(),
 
  446           pThis->m_pParameter->m_Net.
m_User.GetPassword().toStdString().length());
 
  451char* CBackendLibVNCServer::cb_get_password(rfbClient *client)
 
  454    QString szPassword = pThis->m_pParameter->m_Net.
m_User.GetPassword();
 
  455    if(szPassword.isEmpty())
 
  457        int nRet = QDialog::Rejected;
 
  458        auto *net = &pThis->m_pParameter->m_Net;
 
  460        if(QDialog::Accepted == nRet)
 
  462            szPassword = net->m_User.GetPassword();
 
  465    return strdup(szPassword.toStdString().c_str());
 
  468int CBackendLibVNCServer::OnSize()
 
  471    int nWidth = m_pClient->width;
 
  472    int nHeight = m_pClient->height;
 
  474    m_Image = QImage(nWidth, nHeight, QImage::Format_RGB32);
 
  476    m_pClient->frameBuffer = m_Image.bits();
 
  478    m_pClient->format.bitsPerPixel = 32;
 
  479    m_pClient->format.depth = m_Image.depth();
 
  480    m_pClient->format.redShift = 16;
 
  481    m_pClient->format.greenShift = 8;
 
  482    m_pClient->format.blueShift = 0;
 
  483    m_pClient->format.redMax = 255;
 
  484    m_pClient->format.greenMax = 255;
 
  485    m_pClient->format.blueMax = 255;
 
  486    SetFormatAndEncodings(m_pClient);
 
  488    emit sigSetDesktopSize(m_pClient->width, m_pClient->height);
 
  492rfbBool CBackendLibVNCServer::cb_cursor_pos(rfbClient *client, 
int x, 
int y)
 
  500void CBackendLibVNCServer::cb_got_cursor_shape(rfbClient *client,
 
  502                                         int width, 
int height,
 
  508    if(!client->rcSource)
 
  510        qCritical(log) << 
"client->rcSource is null";
 
  514    if ((width == 0) || (height == 0)) {
 
  515        QImage cursor(1, 1, QImage::Format_ARGB32);
 
  516        uchar* buffer = cursor.bits();
 
  517        memset(buffer, 0, 4);
 
  518        emit pThis->sigUpdateCursor(QCursor(QPixmap::fromImage(cursor), xhot, yhot));
 
  520        switch (bytesPerPixel) {
 
  523            QImage cursor(width, height, QImage::Format_ARGB32);
 
  524            uchar *buffer = cursor.bits();
 
  525            memcpy(buffer, client->rcSource, width * height * 4);
 
  526            uchar* pMask = client->rcMask;
 
  529                uchar* pDest = buffer;
 
  530                for(
int y = 0; y < height; y++)
 
  532                    for(
int w = 0; w < width; w++)
 
  538                            QColor c = cursor.pixel(w, y);
 
  540                            cursor.setPixelColor(w,y,c);
 
  543                            *((uint32_t*)pDest) = 0;
 
  549            emit pThis->sigUpdateCursor(QCursor(QPixmap::fromImage(cursor), xhot, yhot));
 
  558void CBackendLibVNCServer::mousePressEvent(QMouseEvent *event)
 
  560    if(!m_pClient) 
return;
 
  561    if(m_pParameter && m_pParameter->GetOnlyView()) 
return;
 
  563    unsigned char mask = 0;
 
  564    if(event->button() & Qt::MouseButton::LeftButton)
 
  566    if(event->button() & Qt::MouseButton::MiddleButton)
 
  568    if(event->button() & Qt::MouseButton::RightButton)
 
  570    if(event->button() & Qt::MouseButton::BackButton)
 
  572    QPoint pos = 
event->pos();
 
  574    qDebug(logMouse) << Q_FUNC_INFO << 
event->buttons() << 
event->button() << pos << mask;
 
  576    SendPointerEvent(m_pClient, pos.x(), pos.y(), mask);
 
  579void CBackendLibVNCServer::mouseReleaseEvent(QMouseEvent *event)
 
  581    if(!m_pClient) 
return;
 
  582    if(m_pParameter && m_pParameter->GetOnlyView()) 
return;
 
  584    QPoint pos = 
event->pos();
 
  585    qDebug(logMouse) << Q_FUNC_INFO << 
event->buttons() << 
event->button() << pos << mask;
 
  586    SendPointerEvent(m_pClient, pos.x(), pos.y(), mask);
 
  589void CBackendLibVNCServer::mouseMoveEvent(QMouseEvent *event)
 
  591    if(!m_pClient) 
return;
 
  592    if(m_pParameter && m_pParameter->GetOnlyView()) 
return;
 
  594    if(event->buttons() & Qt::MouseButton::LeftButton)
 
  596    if(event->buttons() & Qt::MouseButton::MiddleButton)
 
  598    if(event->buttons() & Qt::MouseButton::RightButton)
 
  600    if(event->buttons() & Qt::MouseButton::BackButton)
 
  602    QPoint pos = 
event->pos();
 
  603    qDebug(logMouse) << Q_FUNC_INFO << 
event->buttons() << 
event->button() << pos << mask;
 
  604    SendPointerEvent(m_pClient, pos.x(), pos.y(), mask);
 
  608void CBackendLibVNCServer::wheelEvent(QWheelEvent *event)
 
  610    if(!m_pClient) 
return;
 
  611    if(m_pParameter && m_pParameter->GetOnlyView()) 
return;
 
  613    if(event->buttons() & Qt::MouseButton::LeftButton)
 
  615    if(event->buttons() & Qt::MouseButton::MiddleButton)
 
  617    if(event->buttons() & Qt::MouseButton::RightButton)
 
  619    if(event->buttons() & Qt::MouseButton::BackButton)
 
  622    QPoint d = 
event->angleDelta();
 
  633#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) 
  634    pos = 
event->position();
 
  639    qDebug(logMouse) << Q_FUNC_INFO << 
event->buttons() << 
event->angleDelta() << pos;
 
  641    SendPointerEvent(m_pClient, pos.x(), pos.y(), mask);
 
  651uint32_t TranslateRfbKey(quint32 inkey, 
bool modifier)
 
  657    case Qt::Key_Backspace: k = XK_BackSpace; 
break;
 
  658    case Qt::Key_Tab: k = XK_Tab; 
break;
 
  659    case Qt::Key_Clear: k = XK_Clear; 
break;
 
  660    case Qt::Key_Return: k = XK_Return; 
break;
 
  661    case Qt::Key_Pause: k = XK_Pause; 
break;
 
  662    case Qt::Key_Escape: k = XK_Escape; 
break;
 
  663    case Qt::Key_Space: k = XK_space; 
break;
 
  664    case Qt::Key_Delete: k = XK_Delete; 
break;
 
  665    case Qt::Key_Period: k = XK_period; 
break;
 
  668    case Qt::Key_Multi_key: k = XK_Multi_key; 
break;
 
  669    case Qt::Key_SingleCandidate: k = XK_SingleCandidate; 
break;
 
  670    case Qt::Key_MultipleCandidate: k = XK_MultipleCandidate; 
break;     
 
  671    case Qt::Key_PreviousCandidate: k = XK_PreviousCandidate; 
break;
 
  674    case Qt::Key_Kanji: k = XK_Kanji; 
break;
 
  675    case Qt::Key_Muhenkan: k = XK_Muhenkan; 
break;
 
  676    case Qt::Key_Henkan: k = XK_Henkan; 
break;
 
  677    case Qt::Key_Romaji: k = XK_Romaji; 
break;   
 
  678    case Qt::Key_Hiragana: k = XK_Hiragana; 
break;
 
  679    case Qt::Key_Katakana: k = XK_Katakana; 
break;   
 
  680    case Qt::Key_Hiragana_Katakana: k = XK_Hiragana_Katakana;
break;
 
  681    case Qt::Key_Zenkaku: k = XK_Zenkaku; 
break;
 
  682    case Qt::Key_Hankaku: k = XK_Hankaku; 
break;
 
  683    case Qt::Key_Zenkaku_Hankaku: k = XK_Zenkaku_Hankaku; 
break;
 
  684    case Qt::Key_Touroku: k = XK_Touroku; 
break;
 
  685    case Qt::Key_Massyo: k = XK_Massyo; 
break;
 
  686    case Qt::Key_Kana_Lock: k = XK_Kana_Lock; 
break;
 
  687    case Qt::Key_Kana_Shift: k = XK_Kana_Shift; 
break;
 
  688    case Qt::Key_Eisu_Shift: k = XK_Eisu_Shift; 
break;
 
  689    case Qt::Key_Eisu_toggle: k = XK_Eisu_toggle; 
break;
 
  692    case Qt::Key_Exclam: k = XK_exclam; 
break; 
 
  693    case Qt::Key_QuoteDbl: k = XK_quotedbl; 
break; 
 
  694    case Qt::Key_NumberSign: k = XK_numbersign; 
break; 
 
  695    case Qt::Key_Percent: k = XK_percent; 
break; 
 
  696    case Qt::Key_Dollar: k = XK_dollar; 
break;   
 
  697    case Qt::Key_Ampersand: k = XK_ampersand; 
break; 
 
  698    case Qt::Key_Apostrophe: k = XK_apostrophe; 
break;
 
  699    case Qt::Key_ParenLeft: k = XK_parenleft; 
break; 
 
  700    case Qt::Key_ParenRight: k = XK_parenright; 
break; 
 
  702    case Qt::Key_Slash: k = XK_slash; 
break;    
 
  703    case Qt::Key_Asterisk: k = XK_asterisk; 
break;  
 
  704    case Qt::Key_Minus: k = XK_minus; 
break;    
 
  705    case Qt::Key_Plus: k = XK_plus; 
break;  
 
  706    case Qt::Key_Enter: k = XK_Return; 
break;   
 
  707    case Qt::Key_Equal: k = XK_equal; 
break;    
 
  708    case Qt::Key_Comma: 
return XK_comma; 
 
  710    case Qt::Key_Colon: k = XK_colon;
break; 
 
  711    case Qt::Key_Semicolon: k = XK_semicolon; 
break; 
 
  712    case Qt::Key_Less: k = XK_less; 
break; 
 
  713    case Qt::Key_Greater: k = XK_greater; 
break; 
 
  714    case Qt::Key_Question: k = XK_question; 
break; 
 
  715    case Qt::Key_At: k = XK_at; 
break; 
 
  717    case Qt::Key_BracketLeft: k = XK_bracketleft; 
break;
 
  718    case Qt::Key_Backslash: k = XK_backslash;
break;
 
  719    case Qt::Key_BracketRight: k = XK_bracketright;
break;
 
  720    case Qt::Key_AsciiCircum: k = XK_asciicircum;
break;
 
  721    case Qt::Key_Underscore: k = XK_underscore;
break;
 
  722    case Qt::Key_QuoteLeft: k = XK_quoteleft;
break;
 
  723    case Qt::Key_BraceLeft: k = XK_braceleft;
break;
 
  724    case Qt::Key_Bar: k = XK_bar; 
break;
 
  725    case Qt::Key_BraceRight: k = XK_braceright;
break;
 
  726    case Qt::Key_AsciiTilde: k = XK_asciitilde;
break;
 
  727    case Qt::Key_nobreakspace: k = XK_nobreakspace;
break;
 
  728    case Qt::Key_exclamdown: k = XK_exclamdown;
break;
 
  729    case Qt::Key_cent: k = XK_cent;
break;
 
  730    case Qt::Key_sterling: k = XK_sterling;
break;
 
  731    case Qt::Key_currency: k = XK_currency;
break;
 
  732    case Qt::Key_yen: k = XK_yen;
break;
 
  733    case Qt::Key_brokenbar: k = XK_brokenbar;
break;
 
  734    case Qt::Key_section: k = XK_section;
break;
 
  735    case Qt::Key_diaeresis: k = XK_diaeresis;
break;
 
  736    case Qt::Key_copyright: k = XK_copyright; 
break;
 
  737    case Qt::Key_ordfeminine: k = XK_ordfeminine; 
break;
 
  738    case Qt::Key_guillemotleft: k = XK_guillemotleft; 
break;
 
  739    case Qt::Key_guillemotright: k = XK_guillemotright; 
break;
 
  740    case Qt::Key_notsign: k = XK_notsign; 
break;
 
  741    case Qt::Key_hyphen: k = XK_hyphen; 
break;
 
  742    case Qt::Key_registered: k = XK_registered; 
break;
 
  744    case Qt::Key_Up: k = XK_Up; 
break;
 
  745    case Qt::Key_Down: k = XK_Down; 
break;
 
  746    case Qt::Key_Right: k = XK_Right; 
break;
 
  747    case Qt::Key_Left: k = XK_Left; 
break;
 
  748    case Qt::Key_Insert: k = XK_Insert; 
break;
 
  749    case Qt::Key_Home: k = XK_Home; 
break;
 
  750    case Qt::Key_End: k = XK_End; 
break;
 
  751    case Qt::Key_PageUp: k = XK_Page_Up; 
break;
 
  752    case Qt::Key_PageDown: k = XK_Page_Down; 
break;
 
  753    case Qt::Key_MediaPrevious: k = XK_Prior; 
break;
 
  754    case Qt::Key_MediaNext: k = XK_Next; 
break;
 
  755    case Qt::Key_MediaPlay: k = XK_Begin; 
break;
 
  758    case Qt::Key_Select: k = XK_Select; 
break;
 
  759    case Qt::Key_Printer: k = XK_Print; 
break;
 
  760    case Qt::Key_Execute: k = XK_Execute; 
break;
 
  761    case Qt::Key_Undo: k = XK_Undo; 
break;
 
  762    case Qt::Key_Redo: k = XK_Redo; 
break;
 
  763    case Qt::Key_Menu: k = XK_Menu;
break;
 
  764    case Qt::Key_Find: k = XK_Find; 
break;
 
  770    case Qt::Key_Mode_switch: k = XK_Mode_switch; 
break;
 
  772    case Qt::Key_F1: k = XK_F1; 
break;
 
  773    case Qt::Key_F2: k = XK_F2; 
break;
 
  774    case Qt::Key_F3: k = XK_F3; 
break;
 
  775    case Qt::Key_F4: k = XK_F4; 
break;
 
  776    case Qt::Key_F5: k = XK_F5; 
break;
 
  777    case Qt::Key_F6: k = XK_F6; 
break;
 
  778    case Qt::Key_F7: k = XK_F7; 
break;
 
  779    case Qt::Key_F8: k = XK_F8; 
break;
 
  780    case Qt::Key_F9: k = XK_F9; 
break;
 
  781    case Qt::Key_F10: k = XK_F10; 
break;
 
  782    case Qt::Key_F11: k = XK_F11; 
break;
 
  783    case Qt::Key_F12: k =  XK_F12; 
break;
 
  784    case Qt::Key_F13: k = XK_F13; 
break;
 
  785    case Qt::Key_F14: k = XK_F14; 
break;
 
  786    case Qt::Key_F15: k = XK_F15; 
break;
 
  787    case Qt::Key_F16: k = XK_F16; 
break;
 
  788    case Qt::Key_F17: k = XK_F17; 
break;
 
  789    case Qt::Key_F18: k = XK_F18; 
break;
 
  790    case Qt::Key_F19: k = XK_F19; 
break;
 
  791    case Qt::Key_F20: k = XK_F20; 
break;
 
  792    case Qt::Key_F21: k = XK_F21; 
break;
 
  793    case Qt::Key_F22: k = XK_F22; 
break;
 
  794    case Qt::Key_F23: k = XK_F23; 
break;
 
  795    case Qt::Key_F24: k = XK_F24; 
break;
 
  796    case Qt::Key_F25: k = XK_F25; 
break;
 
  797    case Qt::Key_F26: k = XK_F26; 
break;
 
  798    case Qt::Key_F27: k = XK_F27; 
break;
 
  799    case Qt::Key_F28: k = XK_F28; 
break;
 
  800    case Qt::Key_F29: k = XK_F29; 
break;
 
  801    case Qt::Key_F30: k = XK_F30; 
break;
 
  802    case Qt::Key_F31: k = XK_F31; 
break;
 
  803    case Qt::Key_F32: k = XK_F32; 
break;
 
  804    case Qt::Key_F33: k = XK_F33; 
break;
 
  805    case Qt::Key_F34: k = XK_F34; 
break;
 
  806    case Qt::Key_F35: k = XK_F35; 
break;
 
  808    case Qt::Key_NumLock: k = XK_Num_Lock; 
break;
 
  809    case Qt::Key_CapsLock: k = XK_Caps_Lock; 
break;
 
  810    case Qt::Key_ScrollLock: k = XK_Scroll_Lock; 
break;
 
  812    case Qt::Key_Shift: k = XK_Shift_R; 
break; 
 
  813    case Qt::Key_Control: k = XK_Control_R; 
break;
 
  814    case Qt::Key_Alt: k = XK_Alt_R; 
break;
 
  815    case Qt::Key_Meta: k = XK_Meta_R; 
break;
 
  817    case Qt::Key_Super_L: k = XK_Super_L; 
break;        
 
  818    case Qt::Key_Super_R: k = XK_Super_R; 
break;        
 
  820    case Qt::Key_Help: k = XK_Help; 
break;
 
  821    case Qt::Key_Print: k = XK_Print; 
break;
 
  822    case Qt::Key_SysReq: k = XK_Sys_Req; 
break;
 
  823    case Qt::Key_0: k = XK_0;
break;
 
  824    case Qt::Key_1: k = XK_1;
break;
 
  825    case Qt::Key_2: k = XK_2;
break;
 
  826    case Qt::Key_3: k = XK_3;
break;
 
  827    case Qt::Key_4: k = XK_4;
break;
 
  828    case Qt::Key_5: k = XK_5;
break;
 
  829    case Qt::Key_6: k = XK_6;
break;
 
  830    case Qt::Key_7: k = XK_7;
break;
 
  831    case Qt::Key_8: k = XK_8;
break;
 
  832    case Qt::Key_9: k = XK_9;
break;
 
  842            case Qt::Key_A: k = XK_a;
break;
 
  843            case Qt::Key_B: k = XK_b;
break;
 
  844            case Qt::Key_C: k = XK_c;
break;
 
  845            case Qt::Key_D: k = XK_d;
break;
 
  846            case Qt::Key_E: k = XK_e;
break;
 
  847            case Qt::Key_F: k = XK_f;
break;
 
  848            case Qt::Key_G: k = XK_g;
break;
 
  849            case Qt::Key_H: k = XK_h;
break;
 
  850            case Qt::Key_I: k = XK_i;
break;
 
  851            case Qt::Key_J: k = XK_j;
break;
 
  852            case Qt::Key_K: k = XK_k;
break;
 
  853            case Qt::Key_L: k = XK_l;
break;
 
  854            case Qt::Key_M: k = XK_m;
break;
 
  855            case Qt::Key_N: k = XK_n;
break;
 
  856            case Qt::Key_O: k = XK_o;
break;
 
  857            case Qt::Key_P: k = XK_p;
break;
 
  858            case Qt::Key_Q: k = XK_q;
break;
 
  859            case Qt::Key_R: k = XK_r;
break;
 
  860            case Qt::Key_S: k = XK_s;
break;
 
  861            case Qt::Key_T: k = XK_t;
break;
 
  862            case Qt::Key_U: k = XK_u;
break;
 
  863            case Qt::Key_V: k = XK_v;
break;
 
  864            case Qt::Key_W: k = XK_w;
break;
 
  865            case Qt::Key_X: k = XK_x;
break;
 
  866            case Qt::Key_Y: k = XK_y;
break;
 
  867            case Qt::Key_Z: k = XK_z;
break;
 
  874            case Qt::Key_A: k = XK_A;
break;
 
  875            case Qt::Key_B: k = XK_B;
break;
 
  876            case Qt::Key_C: k = XK_C;
break;
 
  877            case Qt::Key_D: k = XK_D;
break;
 
  878            case Qt::Key_E: k = XK_E;
break;
 
  879            case Qt::Key_F: k = XK_F;
break;
 
  880            case Qt::Key_G: k = XK_G;
break;
 
  881            case Qt::Key_H: k = XK_H;
break;
 
  882            case Qt::Key_I: k = XK_I;
break;
 
  883            case Qt::Key_J: k = XK_J;
break;
 
  884            case Qt::Key_K: k = XK_K;
break;
 
  885            case Qt::Key_L: k = XK_L;
break;
 
  886            case Qt::Key_M: k = XK_M;
break;
 
  887            case Qt::Key_N: k = XK_N;
break;
 
  888            case Qt::Key_O: k = XK_O;
break;
 
  889            case Qt::Key_P: k = XK_P;
break;
 
  890            case Qt::Key_Q: k = XK_Q;
break;
 
  891            case Qt::Key_R: k = XK_R;
break;
 
  892            case Qt::Key_S: k = XK_S;
break;
 
  893            case Qt::Key_T: k = XK_T;
break;
 
  894            case Qt::Key_U: k = XK_U;
break;
 
  895            case Qt::Key_V: k = XK_V;
break;
 
  896            case Qt::Key_W: k = XK_W;
break;
 
  897            case Qt::Key_X: k = XK_X;
break;
 
  898            case Qt::Key_Y: k = XK_Y;
break;
 
  899            case Qt::Key_Z: k = XK_Z;
break;
 
  907void CBackendLibVNCServer::keyPressEvent(QKeyEvent *event)
 
  909    if(!m_pClient) 
return;
 
  910    if(m_pParameter && m_pParameter->GetOnlyView()) 
return;
 
  911    bool modifier = 
false;
 
  912    if (event->modifiers() & Qt::ShiftModifier)
 
  914    uint32_t k = TranslateRfbKey(event->key(), modifier);
 
  915    qDebug(logKey) << Q_FUNC_INFO << 
event << k << modifier;
 
  916    SendKeyEvent(m_pClient, k, TRUE);
 
  919void CBackendLibVNCServer::keyReleaseEvent(QKeyEvent *event)
 
  921    if(!m_pClient) 
return;
 
  922    if(m_pParameter && m_pParameter->GetOnlyView()) 
return;
 
  923    bool modifier = 
false;
 
  924    if (event->modifiers() & Qt::ShiftModifier)
 
  926    uint32_t k = TranslateRfbKey(event->key(), modifier);
 
  927    qDebug(logKey) << Q_FUNC_INFO << 
event << k << modifier;
 
  928    SendKeyEvent(m_pClient, k, FALSE);
 
  935    auto &net = m_pParameter->m_Proxy.m_SSH.m_Net;
 
  938    m_pClient->serverHost = strdup(szHost.toStdString().c_str());
 
  939    m_pClient->serverPort = nPort;
 
  940    szErr = tr(
"Will connect to local socket server: %1:%2")
 
  941                .arg(m_pClient->serverHost,
 
  942                     QString::number(m_pClient->serverPort));
 
  943    qDebug(log) << szErr;
 
  944    if(!rfbInitClient(m_pClient, 
nullptr, 
nullptr))
 
  949        szErr = tr(
"Fail: Connect to %1:%2 <- %3:%4 <- %5:%6")
 
  950                    .arg(m_pParameter->m_Net.GetHost(),
 
  951                         QString::number(m_pParameter->m_Net.GetPort()),
 
  952                         net.GetHost(), QString::number(net.GetPort()),
 
  953                         szHost, QString::number(nPort)
 
  955        qCritical(log) << szErr;
 
  960    QString szInfo = QString(
"Connected to %1 <- %2:%3 <- %4:%5")
 
  961                         .arg(m_pClient->desktopName,
 
  962                              net.GetHost(), QString::number(net.GetPort()),
 
  963                              szHost, QString::number(nPort));
 
  964    qInfo(log) << szInfo;
 
  966    emit sigSetDesktopSize(m_pClient->width, m_pClient->height);
 
  967    emit sigServerName(m_pClient->desktopName);
 
 
  972#if defined(HAVE_UNIX_DOMAIN_SOCKET) 
  978    m_pClient->serverHost = strdup(szFile.toStdString().c_str());
 
  979    szErr = tr(
"Will connect to local socket server: ") + szFile;
 
  980    qDebug(log) << szErr;
 
  981    if(!rfbInitClient(m_pClient, 
nullptr, 
nullptr))
 
  986        szErr = tr(
"Fail: Connect to %1:%2 with %3")
 
  987                    .arg(m_pParameter->m_Net.GetHost(),
 
  988                         QString::number(m_pParameter->m_Net.GetPort()),
 
  990        qCritical(log) <<  szErr;
 
  995    QString szInfo = QString(
"Connected to ") + m_pClient->desktopName + 
" with " + szFile;
 
  996    qInfo(log) << szInfo;
 
  999    emit sigSetDesktopSize(m_pClient->width, m_pClient->height);
 
 1000    emit sigServerName(m_pClient->desktopName);
 
void sigUpdateRect(const QRect &r, const QImage &image)
通知视图,图像更新
 
virtual int OnClean() override
清理
 
void slotConnectProxyServer(QString szHost, quint16 nPort)
[connect local socket server]
 
virtual int WakeUp() override
唤醒后台线程
 
virtual OnInitReturnValue OnInit() override
 
virtual int OnProcess() override
插件连接的具体操作处理。因为此插件是非Qt事件,所以在此函数中等待。
 
void sigInformation(const QString &szInfo)
从后台线程中触发在主线程中显示信息,不阻塞后台线程
 
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 sigRunning()
当插件开始成功后触发。仅由插件触发
 
virtual void slotTimeOut()
一个非 Qt 事件处理,它调用 OnProcess(),并根据其返回值开始新的定时器。 如果是不是一个非 Qt 事件循环(就是普通的循环处理), 可以重载它,或者 OnInit() 返回值大于 0
 
void sigBlockShowWidget(const QString &className, int &nRet, void *pContext)
阻塞后台线程,并在前台线程中显示窗口。
 
CParameterUser m_User
[Instance user]
 
实现通过本地 SOCKET 与 SSH 隧道转发数据。适用于库没有实现传输层接口,只有 socket 的情况。