Rabbit Remote Control 0.0.30
Loading...
Searching...
No Matches
ConnectLibVNCServer.cpp
1
2#include <QApplication>
3#include <QImage>
4#include <QClipboard>
5#include <QNetworkProxy>
6#include <QInputDialog>
7#include <QLoggingCategory>
8
9#include "ConnectLibVNCServer.h"
10
11static Q_LOGGING_CATEGORY(log, "LibVNCServer.Connect")
12static Q_LOGGING_CATEGORY(logger, "LibVNCServer.Connect.log")
13
14const char* gThis = "This pointer";
15#define LOG_BUFFER_LENGTH 1024
16static void rfbQtClientLog(const char *format, ...)
17{
18 int nRet = 0;
19 va_list args;
20 char buf[LOG_BUFFER_LENGTH];
21
22 if(!rfbEnableClientLogging)
23 return;
24
25 va_start(args, format);
26 nRet = vsnprintf(buf, LOG_BUFFER_LENGTH, format, args);
27 va_end(args);
28 if(nRet < 0)
29 {
30 qCritical(log) << "vsnprintf fail";
31 return;
32 }
33 if(nRet >= LOG_BUFFER_LENGTH)
34 {
35 qCritical(log) << "vsprintf buf is short,"
36 << nRet << ">" << LOG_BUFFER_LENGTH
37 << ". Truncated it:" << nRet - LOG_BUFFER_LENGTH;
38 buf[LOG_BUFFER_LENGTH - 1] = 0;
39 }
40 qDebug(logger) << buf;
41}
42
43CConnectLibVNCServer::CConnectLibVNCServer(CConnecterLibVNCServer *pConnecter)
44 : CConnectDesktop(pConnecter),
45 m_pClient(nullptr),
46 m_pParameter(dynamic_cast<CParameterLibVNCServer*>(pConnecter->GetParameter()))
47#ifdef HAVE_LIBSSH
48 ,m_pThread(nullptr)
49#endif
50{
51 rfbClientLog = rfbQtClientLog;
52
53 if(!m_pParameter->GetLocalCursor())
54 {
55 emit sigUpdateCursor(QCursor(Qt::BlankCursor));
56 }
57}
58
59CConnectLibVNCServer::~CConnectLibVNCServer()
60{
61 qDebug(log) << "CConnectLibVNCServer::~CConnectLibVNCServer()";
62}
63
64/*
65 * \return
66 * \li OnInitReturnValue::Fail: error
67 * \li OnInitReturnValue::UseOnProcess: Use OnProcess (non-Qt event loop)
68 * \li OnInitReturnValue::NotUseOnProcess: Don't use OnProcess (qt event loop)
69 */
70CConnect::OnInitReturnValue CConnectLibVNCServer::OnInit()
71{
72 qDebug(log) << "CConnectLibVNCServer::OnInit()";
73 if(m_pClient) Q_ASSERT(false);
74
75 m_pClient = rfbGetClient(8, 3, 4);
76 if(!m_pClient)
77 {
78 QString szErr;
79 szErr = tr("Protocol version error");
80 emit sigShowMessageBox(tr("Error"), szErr, QMessageBox::Critical);
81 qCritical(log) << "rfbGetClient fail";
82 return OnInitReturnValue::Fail;
83 }
84
85 // Set parameters
86 m_pClient->programName = strdup(qApp->applicationName().toStdString().c_str());
87 m_pClient->appData.shareDesktop = m_pParameter->GetShared();
88 m_pClient->appData.viewOnly = m_pParameter->GetOnlyView();
89 m_pClient->appData.useRemoteCursor = m_pParameter->GetLocalCursor();
90
91 //Qt is support QImage::Format_RGB32, so we use default format QImage::Format_RGB32 in OnSize()
92 // m_pClient->appData.requestedDepth = m_pPara->nColorLevel;
93 // m_pClient->format.depth = m_pPara->nColorLevel;
94 // switch (m_pClient->format.depth) {
95 // case 8:
96 // m_pClient->format.depth = 8;
97 // m_pClient->format.bitsPerPixel = 8;
98 // m_pClient->format.blueMax = 3;
99 // m_pClient->format.blueShift = 6;
100 // m_pClient->format.greenMax = 7;
101 // m_pClient->format.greenShift = 3;
102 // m_pClient->format.redMax = 7;
103 // m_pClient->format.redShift = 0;
104 // break;
105 // case 16:
106 // m_pClient->format.depth = 15;
107 // m_pClient->format.bitsPerPixel = 16;
108 // m_pClient->format.redShift = 11;
109 // m_pClient->format.greenShift = 6;
110 // m_pClient->format.blueShift = 1;
111 // m_pClient->format.redMax = 31;
112 // m_pClient->format.greenMax = 31;
113 // m_pClient->format.blueMax = 31;
114 // break;
115 // case 32:
116 // default:
117 // m_pClient->format.depth = 24;
118 // m_pClient->format.bitsPerPixel = 32;
119 // m_pClient->format.blueShift = 0;
120 // m_pClient->format.redShift = 16;
121 // m_pClient->format.greenShift = 8;
122 // m_pClient->format.blueMax = 0xff;
123 // m_pClient->format.redMax = 0xff;
124 // m_pClient->format.greenMax = 0xff;
125 // break;
126 // }
127
128 m_pClient->appData.enableJPEG = m_pParameter->GetJpeg();
129 if(m_pClient->appData.enableJPEG)
130 m_pClient->appData.qualityLevel = m_pParameter->GetQualityLevel();
131 if(m_pParameter->GetEnableCompressLevel())
132 m_pClient->appData.compressLevel = m_pParameter->GetCompressLevel();
133
134 // Set callback function
135 m_pClient->MallocFrameBuffer = cb_resize;
136 m_pClient->GotFrameBufferUpdate = cb_update;
137 m_pClient->HandleKeyboardLedState = cb_kbd_leds;
138 m_pClient->Bell = cb_bell;
139 m_pClient->HandleTextChat = cb_text_chat;
140 m_pClient->GotXCutText = cb_got_selection;
141 m_pClient->GetCredential = cb_get_credential;
142 m_pClient->GetPassword = cb_get_password;
143 m_pClient->HandleCursorPos = cb_cursor_pos;
144 m_pClient->GotCursorShape = cb_got_cursor_shape;
145
146 m_pClient->canHandleNewFBSize = TRUE;
147 rfbClientSetClientData(m_pClient, (void*)gThis, this);
148
149 // Set sock
150 switch(m_pParameter->m_Proxy.GetUsedType())
151 {
152 case CParameterProxy::TYPE::None:
153 {
154 // Set server ip and port
155 if(m_pParameter->m_Net.GetHost().isEmpty())
156 {
157 QString szErr;
158 szErr = tr("The server is empty, please input it");
159 qCritical(log) << szErr;
160 emit sigShowMessageBox(tr("Error"), szErr, QMessageBox::Critical);
161 return OnInitReturnValue::Fail;
162 }
163 auto &net = m_pParameter->m_Net;
164 m_pClient->serverHost = strdup(net.GetHost().toStdString().c_str());
165 m_pClient->serverPort = net.GetPort();
166
167 if(!rfbInitClient(m_pClient, nullptr, nullptr))
168 {
169 QString szErr;
170 szErr = tr("Connect to %1:%2 fail").arg(m_pParameter->m_Net.GetHost(),
171 QString::number(m_pParameter->m_Net.GetPort()));
172 qCritical(log) << szErr;
173 emit sigShowMessageBox(tr("Error"), szErr, QMessageBox::Critical);
174 return OnInitReturnValue::Fail;
175 }
176
177 QString szInfo = QString("Connect to ") + m_pClient->desktopName;
178 qInfo(log) << szInfo;
179
180 emit sigSetDesktopSize(m_pClient->width, m_pClient->height);
181 emit sigServerName(m_pClient->desktopName);
182 emit sigInformation(szInfo);
183 emit sigConnected();
184 return OnInitReturnValue::UseOnProcess;
185 }
186 /*case CParameterProxy::TYPE::SockesV5:
187 {
188 QNetworkProxy proxy;
189 proxy.setType(QNetworkProxy::Socks5Proxy);
190 auto &net = m_pParameter->m_Proxy.m_SockesV5;
191 proxy.setHostName(net.GetHost());
192 if(net.GetHost().isEmpty())
193 {
194 QString szErr;
195 szErr = tr("The proxy server is empty, please input it");
196 qCritical(log) << szErr;
197 emit sigShowMessageBox(tr("Error"), szErr, QMessageBox::Critical);
198 return OnInitReturnValue::Fail;
199 }
200 proxy.setPort(net.GetPort());
201 auto &user = net.m_User;
202 proxy.setUser(user.GetUser());
203 proxy.setPassword(user.GetPassword());
204 m_tcpSocket.setProxy(proxy);
205 m_tcpSocket.connectToHost(m_pClient->serverHost, m_pClient->serverPort);
206 if (!m_tcpSocket.waitForConnected(3000))
207 return OnInitReturnValue::Fail;
208 //TODO: The is fail
209 m_pClient->sock = m_tcpSocket.socketDescriptor();
210 if(!rfbInitClient(m_pClient, nullptr, nullptr))
211 {
212 QString szErr;
213 szErr = tr("Connect to %1:%2 fail").arg(m_pParameter->m_Net.GetHost(),
214 QString::number(m_pParameter->m_Net.GetPort()));
215 qCritical(log) << szErr;
216 emit sigShowMessageBox(tr("Error"), szErr, QMessageBox::Critical);
217 return OnInitReturnValue::Fail;
218 }
219 break;
220 }//*/
221 /*TODO: add UltraVncRepeater
222 case (CParameterConnecter::emProxy) CParameterLibVNCServer::emVncProxy::UltraVncRepeater:
223 m_pClient->destHost = strdup(m_pPara->GetProxyHost().toStdString().c_str());
224 m_pClient->destPort = m_pPara->GetProxyPort();//*/
225
227#ifdef HAVE_LIBSSH
228 case CParameterProxy::TYPE::SSHTunnel:
229 {
230 // Set SSH parameters
231 QSharedPointer<CParameterChannelSSH> parameter(new CParameterChannelSSH());
232 auto &ssh = m_pParameter->m_Proxy.m_SSH;
233 parameter->setServer(ssh.GetHost());
234 parameter->setPort(ssh.GetPort());
235 auto &user = ssh.m_User;
236 parameter->SetUser(user.GetUser());
237 parameter->SetUseSystemFile(user.GetUseSystemFile());
238 if(CParameterUser::TYPE::UserPassword == user.GetUsedType()) {
239 parameter->SetAuthenticationMethod(SSH_AUTH_METHOD_PASSWORD);
240 parameter->SetPassword(user.GetPassword());
241 }
242 if(CParameterUser::TYPE::PublicKey == user.GetUsedType()) {
243 parameter->SetAuthenticationMethod(SSH_AUTH_METHOD_PUBLICKEY);
244 parameter->SetPublicKeyFile(user.GetPublicKeyFile());
245 parameter->SetPrivateKeyFile(user.GetPrivateKeyFile());
246 parameter->SetPassphrase(user.GetPassphrase());
247 }
248 auto &net = m_pParameter->m_Net;
249 parameter->SetRemoteHost(net.GetHost());
250 parameter->SetRemotePort(net.GetPort());
251
252 // Start ssh thread
253 if(!m_pThread)
254 m_pThread = new CSSHTunnelThread(parameter);
255 if(!m_pThread)
256 return OnInitReturnValue::Fail;
257 bool check = connect(m_pThread, SIGNAL(sigServer(QString, quint16)),
258 this, SLOT(slotConnectProxyServer(QString, quint16)));
259 Q_ASSERT(check);
260#if defined(HAVE_UNIX_DOMAIN_SOCKET) && defined(Q_OS_UNIX)
261 check = connect(m_pThread, SIGNAL(sigServer(QString)),
262 this, SLOT(slotConnectProxyServer(QString)));
263 Q_ASSERT(check);
264#endif
265 check = connect(m_pThread, SIGNAL(sigError(int,QString)),
266 this, SIGNAL(sigError(int,QString)));
267 Q_ASSERT(check);
268 check = connect(m_pThread, SIGNAL(sigDisconnect()),
269 this, SIGNAL(sigDisconnect()));
270 Q_ASSERT(check);
271 m_pThread->start();
272
273 return OnInitReturnValue::UseOnProcess;
274 }
275#endif
277 default:
278 break;
279 }
280
281 return OnInitReturnValue::UseOnProcess;
282}
283
285{
286 qDebug(log) << "CConnectLibVNCServer::OnClean()";
287 if(m_pThread)
288 {
289 m_pThread->Exit();
290 m_pThread = nullptr;
291 }
292 if(m_pClient)
293 {
294 m_tcpSocket.close();
295 //m_pClient->sock = -1; //RFB_INVALID_SOCKET;
296 rfbClientCleanup(m_pClient);
297 m_pClient = nullptr;
298 }
299 return 0;
300}
301
316{
317 //LOG_MODEL_DEBUG("CConnectLibVNCServer", "CConnectLibVNCServer::Process()");
318 int nRet = 0;
319 if(!m_pClient)
320 {
321 Q_ASSERT(m_pClient);
322 return -1;
323 }
324
325 struct timeval timeout = {0, 50000};
326 fd_set set;
327 FD_ZERO(&set);
328 if(RFB_INVALID_SOCKET != m_pClient->sock)
329 {
330 FD_SET(m_pClient->sock, &set);
331 }
332 rfbSocket eventFd = m_Event.GetFd();
333 if(RFB_INVALID_SOCKET != eventFd)
334 {
335 FD_SET(eventFd, &set);
336 }
337 rfbSocket fd = RFB_INVALID_SOCKET;
338 fd = std::max(eventFd, m_pClient->sock);
339 //qDebug(log) << "fd:" << fd << "select m_pClient->sock:" << (int)m_pClient->sock << "event:" << eventFd;
340 nRet = select(fd + 1, &set, NULL, NULL, &timeout);
341 //qDebug(log) << "select end";
342 if (nRet < 0) {
343 qCritical(log) << "select fail:" << nRet << "errno" << errno << strerror(errno);
344 return nRet;
345 }
346
347 /*if(0 == nRet)
348 {
349 //qDebug(log) << "Time out";
350 return 0;
351 }//*/
352
353 if(RFB_INVALID_SOCKET != eventFd && FD_ISSET(eventFd, &set))
354 {
355 //qDebug(log) << "fires event";
356 m_Event.Reset();
357 }
358
359 if(RFB_INVALID_SOCKET != m_pClient->sock
360 && FD_ISSET(m_pClient->sock, &set)) {
361 //qDebug(log) << "HandleRFBServerMessage";
362 if(!HandleRFBServerMessage(m_pClient))
363 {
364 qCritical(log) << "HandleRFBServerMessage fail";
365 return -2;
366 }
367 }
368
369 return 0;
370}
371
373{
374 return m_Event.WakeUp();
375}
376
377void CConnectLibVNCServer::slotClipBoardChanged()
378{
379 if(!m_pParameter || !m_pParameter->GetClipboard() || !m_pClient) return;
380 QClipboard* pClipboard = QApplication::clipboard();
381 if(pClipboard)
382 {
383 QString szText = pClipboard->text();
384 if(!szText.isEmpty() && m_pClient)
385 SendClientCutText(m_pClient,
386 (char*)szText.toStdString().c_str(),
387 szText.toStdString().length());
388 }
389}
390
391rfbBool CConnectLibVNCServer::cb_resize(rfbClient* client)
392{
393 //qDebug(log) << "CConnectLibVnc::cb_resize:" << client->width << client->height;
394 CConnectLibVNCServer* pThis = (CConnectLibVNCServer*)rfbClientGetClientData(client, (void*)gThis);
395 if(pThis->OnSize()) return FALSE;
396 return TRUE;
397}
398
399void CConnectLibVNCServer::cb_update(rfbClient *client, int x, int y, int w, int h)
400{
401 if(0 == w || 0 == h)
402 return;
403 //qDebug(LibVNCServer, "CConnectLibVnc::cb_update:(%d, %d, %d, %d)", x, y, w, h);
404 CConnectLibVNCServer* pThis = (CConnectLibVNCServer*)rfbClientGetClientData(client, (void*)gThis);
405 QRect rect(x, y, w, h);
406 QImage img = pThis->m_Image.copy(rect);
407 emit pThis->sigUpdateRect(rect, img);
408}
409
410void CConnectLibVNCServer::cb_got_selection(rfbClient *client, const char *text, int len)
411{
412 //qDebug(LibVNCServer, "CConnectLibVnc::cb_got_selection:%s", text);
413 CConnectLibVNCServer* pThis = (CConnectLibVNCServer*)rfbClientGetClientData(client, (void*)gThis);
414 if(!pThis->m_pParameter->GetClipboard()) return;
415 QClipboard* pClipboard = QApplication::clipboard();
416 if(pClipboard)
417 pClipboard->setText(text);
418}
419
420void CConnectLibVNCServer::cb_kbd_leds(rfbClient *client, int value, int pad)
421{
422 qDebug(log) << "CConnectLibVnc::cb_kbd_leds";
423}
424
425void CConnectLibVNCServer::cb_bell(struct _rfbClient *client)
426{
427 qApp->beep();
428}
429
430void CConnectLibVNCServer::cb_text_chat(rfbClient *client, int value, char *text)
431{
432 qDebug(log) << "CConnectLibVnc::cb_text_chat";
433}
434
435rfbCredential* CConnectLibVNCServer::cb_get_credential(rfbClient *cl, int credentialType)
436{
437 qDebug(log) <<"CConnectLibVnc::cb_get_credential";
438 CConnectLibVNCServer* pThis = (CConnectLibVNCServer*)rfbClientGetClientData(cl, (void*)gThis);
439 rfbCredential *c = (rfbCredential*)malloc(sizeof(rfbCredential));
440 c->userCredential.username = (char*)malloc(RFB_BUF_SIZE);
441 memset(c->userCredential.username, 0, RFB_BUF_SIZE);
442 c->userCredential.password = (char*)malloc(RFB_BUF_SIZE);
443 memset(c->userCredential.password, 0, RFB_BUF_SIZE);
444
445 if(credentialType != rfbCredentialTypeUser) {
446 qCritical(log) << "something else than username and password required for authentication";
447 return NULL;
448 }
449
450 qDebug(log) << "Username and password required for authentication!";
451
452 memcpy(c->userCredential.username,
453 pThis->m_pParameter->m_Net.m_User.GetUser().toStdString().c_str(),
454 pThis->m_pParameter->m_Net.m_User.GetUser().toStdString().length());
455 memcpy(c->userCredential.password,
456 pThis->m_pParameter->m_Net.m_User.GetPassword().toStdString().c_str(),
457 pThis->m_pParameter->m_Net.m_User.GetPassword().toStdString().length());
458
459 return c;
460}
461
462char* CConnectLibVNCServer::cb_get_password(rfbClient *client)
463{
464 //LOG_MODEL_ERROR("LibVNCServer", "CConnectLibVnc::cb_get_password");
465 CConnectLibVNCServer* pThis = (CConnectLibVNCServer*)rfbClientGetClientData(client, (void*)gThis);
466 QString szPassword = pThis->m_pParameter->m_Net.m_User.GetPassword();
467 if(szPassword.isEmpty())
468 {
469 int nRet = QDialog::Rejected;
470 emit pThis->sigBlockShowWidget("CDlgLibVNCServerPassword", nRet, pThis->m_pParameter);
471 if(QDialog::Accepted == nRet)
472 {
473 szPassword = pThis->m_pParameter->m_Net.m_User.GetPassword();
474 }
475 if(szPassword.isEmpty())
476 return nullptr;
477 }
478 return strdup(szPassword.toStdString().c_str());
479}
480
481int CConnectLibVNCServer::OnSize()
482{
483 int nRet = 0;
484 int nWidth = m_pClient->width;
485 int nHeight = m_pClient->height;
486
487 m_Image = QImage(nWidth, nHeight, QImage::Format_RGB32);
488
489 m_pClient->frameBuffer = m_Image.bits();
490
491 m_pClient->format.bitsPerPixel = 32;
492 m_pClient->format.depth = m_Image.depth();
493 m_pClient->format.redShift = 16;
494 m_pClient->format.greenShift = 8;
495 m_pClient->format.blueShift = 0;
496 m_pClient->format.redMax = 255;
497 m_pClient->format.greenMax = 255;
498 m_pClient->format.blueMax = 255;
499 SetFormatAndEncodings(m_pClient);
500
501 emit sigSetDesktopSize(m_pClient->width, m_pClient->height);
502 return nRet;
503}
504
505rfbBool CConnectLibVNCServer::cb_cursor_pos(rfbClient *client, int x, int y)
506{
507 //qDebug(LibVNCServer, "CConnectLibVnc::cb_cursor_pos:%d,%d", x, y);
508 rfbBool bRet = true;
509
510 return bRet;
511}
512
513void CConnectLibVNCServer::cb_got_cursor_shape(rfbClient *client,
514 int xhot, int yhot,
515 int width, int height,
516 int bytesPerPixel)
517{
518 /*
519 qDebug(LibVNCServer, "CConnectLibVnc::cb_got_cursor_shape:x:%d, y:%d, width:%d, height:%d, bytesPerPixel:%d",
520 xhot, yhot, width, height, bytesPerPixel);//*/
521 if(!client->rcSource)
522 {
523 qCritical(log) << "client->rcSource is null";
524 return;
525 }
526 CConnectLibVNCServer* pThis = (CConnectLibVNCServer*)rfbClientGetClientData(client, (void*)gThis);
527 if ((width == 0) || (height == 0)) {
528 QImage cursor(1, 1, QImage::Format_ARGB32);
529 uchar* buffer = cursor.bits();
530 memset(buffer, 0, 4);
531 emit pThis->sigUpdateCursor(QCursor(QPixmap::fromImage(cursor), xhot, yhot));
532 } else {
533 switch (bytesPerPixel) {
534 case 4:
535 {
536 QImage cursor(width, height, QImage::Format_ARGB32);
537 uchar *buffer = cursor.bits();
538 memcpy(buffer, client->rcSource, width * height * 4);
539 uchar* pMask = client->rcMask;
540 if(pMask)
541 {
542 uchar* pDest = buffer;
543 for(int y = 0; y < height; y++)
544 {
545 for(int w = 0; w < width; w++)
546 {
547 if(*pMask++)
548 {
549 // NOTE: Do not manipulate the memory,
550 // because the host byte order may be different
551 QColor c = cursor.pixel(w, y);
552 c.setAlpha(0xff);
553 cursor.setPixelColor(w,y,c);
554 }
555 else
556 *((uint32_t*)pDest) = 0;
557
558 pDest += 4;
559 }
560 }
561 }
562 emit pThis->sigUpdateCursor(QCursor(QPixmap::fromImage(cursor), xhot, yhot));
563 break;
564 }
565 default:
566 break;
567 }
568 }
569}
570
571void CConnectLibVNCServer::mousePressEvent(QMouseEvent *event)
572{
573 if(!m_pClient) return;
574 if(m_pParameter && m_pParameter->GetOnlyView()) return;
575 //qDebug(log) << "CConnectLibVnc::slotMousePressEvent" << e->button() << e->buttons();
576 unsigned char mask = 0;
577 if(event->button() & Qt::MouseButton::LeftButton)
578 mask |= 0x1;
579 if(event->button() & Qt::MouseButton::MiddleButton)
580 mask |= 0x2;
581 if(event->button() & Qt::MouseButton::RightButton)
582 mask |= 0x4;
583
584 QPoint pos = event->pos();
585 SendPointerEvent(m_pClient, pos.x(), pos.y(), mask);
586}
587
588void CConnectLibVNCServer::mouseReleaseEvent(QMouseEvent *event)
589{
590 if(!m_pClient) return;
591 if(m_pParameter && m_pParameter->GetOnlyView()) return;
592 int mask = 0;
593 QPoint pos = event->pos();
594 SendPointerEvent(m_pClient, pos.x(), pos.y(), mask);
595}
596
597void CConnectLibVNCServer::mouseMoveEvent(QMouseEvent *event)
598{
599 //qDebug(log) << "CConnectLibVnc::slotMouseMoveEvent" << buttons << pos;
600 if(!m_pClient) return;
601 if(m_pParameter && m_pParameter->GetOnlyView()) return;
602 int mask = 0;
603 if(event->buttons() & Qt::MouseButton::LeftButton)
604 mask |= 0x1;
605 if(event->buttons() & Qt::MouseButton::MiddleButton)
606 mask |= 0x2;
607 if(event->buttons() & Qt::MouseButton::RightButton)
608 mask |= 0x4;
609 QPoint pos = event->pos();
610 SendPointerEvent(m_pClient, pos.x(), pos.y(), mask);
611}
612
613void CConnectLibVNCServer::wheelEvent(QWheelEvent *event)
614{
615 //qDebug(log) << "CConnectLibVnc::slotWheelEvent" << buttons << pos << angleDelta;
616 if(!m_pClient) return;
617 if(m_pParameter && m_pParameter->GetOnlyView()) return;
618 int mask = 0;
619 if(event->buttons() & Qt::MouseButton::LeftButton)
620 mask |= 0x1;
621 if(event->buttons() & Qt::MouseButton::MiddleButton)
622 mask |= 0x2;
623 if(event->buttons() & Qt::MouseButton::RightButton)
624 mask |= 0x4;
625
626 QPoint d = event->angleDelta();
627 if(d.y() > 0)
628 mask |= 0x8;
629 if(d.y() < 0)
630 mask |= 0x10;
631 if(d.x() < 0)
632 mask |= 0x20;
633 if(d.x() > 0)
634 mask |= 0x40;
635
636 QPointF pos;
637#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
638 pos = event->position();
639#else
640 pos = event->pos();
641#endif
642
643 SendPointerEvent(m_pClient, pos.x(), pos.y(), mask);
644}
645
653uint32_t TranslateRfbKey(quint32 inkey, bool modifier)
654{
655 quint32 k = 5000;
656
657 switch (inkey)
658 {
659 case Qt::Key_Backspace: k = XK_BackSpace; break;
660 case Qt::Key_Tab: k = XK_Tab; break;
661 case Qt::Key_Clear: k = XK_Clear; break;
662 case Qt::Key_Return: k = XK_Return; break;
663 case Qt::Key_Pause: k = XK_Pause; break;
664 case Qt::Key_Escape: k = XK_Escape; break;
665 case Qt::Key_Space: k = XK_space; break;
666 case Qt::Key_Delete: k = XK_Delete; break;
667 case Qt::Key_Period: k = XK_period; break;
668
669 /* International & multi-key character composition */
670 case Qt::Key_Multi_key: k = XK_Multi_key; break;
671 case Qt::Key_SingleCandidate: k = XK_SingleCandidate; break;
672 case Qt::Key_MultipleCandidate: k = XK_MultipleCandidate; break;
673 case Qt::Key_PreviousCandidate: k = XK_PreviousCandidate; break;
674
675 /* Japanese keyboard support */
676 case Qt::Key_Kanji: k = XK_Kanji; break;
677 case Qt::Key_Muhenkan: k = XK_Muhenkan; break;
678 case Qt::Key_Henkan: k = XK_Henkan; break;
679 case Qt::Key_Romaji: k = XK_Romaji; break;
680 case Qt::Key_Hiragana: k = XK_Hiragana; break;
681 case Qt::Key_Katakana: k = XK_Katakana; break;
682 case Qt::Key_Hiragana_Katakana: k = XK_Hiragana_Katakana;break;
683 case Qt::Key_Zenkaku: k = XK_Zenkaku; break;
684 case Qt::Key_Hankaku: k = XK_Hankaku; break;
685 case Qt::Key_Zenkaku_Hankaku: k = XK_Zenkaku_Hankaku; break;
686 case Qt::Key_Touroku: k = XK_Touroku; break;
687 case Qt::Key_Massyo: k = XK_Massyo; break;
688 case Qt::Key_Kana_Lock: k = XK_Kana_Lock; break;
689 case Qt::Key_Kana_Shift: k = XK_Kana_Shift; break;
690 case Qt::Key_Eisu_Shift: k = XK_Eisu_Shift; break;
691 case Qt::Key_Eisu_toggle: k = XK_Eisu_toggle; break;
692
693 //special keyboard char
694 case Qt::Key_Exclam: k = XK_exclam; break;
695 case Qt::Key_QuoteDbl: k = XK_quotedbl; break; //"
696 case Qt::Key_NumberSign: k = XK_numbersign; break; //#
697 case Qt::Key_Percent: k = XK_percent; break; //%
698 case Qt::Key_Dollar: k = XK_dollar; break; //$
699 case Qt::Key_Ampersand: k = XK_ampersand; break; //&
700 case Qt::Key_Apostrophe: k = XK_apostrophe; break;
701 case Qt::Key_ParenLeft: k = XK_parenleft; break; // (
702 case Qt::Key_ParenRight: k = XK_parenright; break; // )
703
704 case Qt::Key_Slash: k = XK_slash; break; // /
705 case Qt::Key_Asterisk: k = XK_asterisk; break; //*
706 case Qt::Key_Minus: k = XK_minus; break; //-
707 case Qt::Key_Plus: k = XK_plus; break; //+
708 case Qt::Key_Enter: k = XK_Return; break; //
709 case Qt::Key_Equal: k = XK_equal; break; //=
710 case Qt::Key_Comma: return XK_comma; //,
711
712 case Qt::Key_Colon: k = XK_colon;break; // :
713 case Qt::Key_Semicolon: k = XK_semicolon; break; //;
714 case Qt::Key_Less: k = XK_less; break; // <
715 case Qt::Key_Greater: k = XK_greater; break; // >
716 case Qt::Key_Question: k = XK_question; break; //?
717 case Qt::Key_At: k = XK_at; break; //@
718
719 case Qt::Key_BracketLeft: k = XK_bracketleft; break;
720 case Qt::Key_Backslash: k = XK_backslash;break;
721 case Qt::Key_BracketRight: k = XK_bracketright;break;
722 case Qt::Key_AsciiCircum: k = XK_asciicircum;break;
723 case Qt::Key_Underscore: k = XK_underscore;break;
724 case Qt::Key_QuoteLeft: k = XK_quoteleft;break;
725 case Qt::Key_BraceLeft: k = XK_braceleft;break;
726 case Qt::Key_Bar: k = XK_bar; break;
727 case Qt::Key_BraceRight: k = XK_braceright;break;
728 case Qt::Key_AsciiTilde: k = XK_asciitilde;break;
729 case Qt::Key_nobreakspace: k = XK_nobreakspace;break;
730 case Qt::Key_exclamdown: k = XK_exclamdown;break;
731 case Qt::Key_cent: k = XK_cent;break;
732 case Qt::Key_sterling: k = XK_sterling;break;
733 case Qt::Key_currency: k = XK_currency;break;
734 case Qt::Key_yen: k = XK_yen;break;
735 case Qt::Key_brokenbar: k = XK_brokenbar;break;
736 case Qt::Key_section: k = XK_section;break;
737 case Qt::Key_diaeresis: k = XK_diaeresis;break;
738 case Qt::Key_copyright: k = XK_copyright; break;
739 case Qt::Key_ordfeminine: k = XK_ordfeminine; break;
740 case Qt::Key_guillemotleft: k = XK_guillemotleft; break;
741 case Qt::Key_guillemotright: k = XK_guillemotright; break;
742 case Qt::Key_notsign: k = XK_notsign; break;
743 case Qt::Key_hyphen: k = XK_hyphen; break;
744 case Qt::Key_registered: k = XK_registered; break;
745
746 case Qt::Key_Up: k = XK_Up; break;
747 case Qt::Key_Down: k = XK_Down; break;
748 case Qt::Key_Right: k = XK_Right; break;
749 case Qt::Key_Left: k = XK_Left; break;
750 case Qt::Key_Insert: k = XK_Insert; break;
751 case Qt::Key_Home: k = XK_Home; break;
752 case Qt::Key_End: k = XK_End; break;
753 case Qt::Key_PageUp: k = XK_Page_Up; break;
754 case Qt::Key_PageDown: k = XK_Page_Down; break;
755 case Qt::Key_MediaPrevious: k = XK_Prior; break;
756 case Qt::Key_MediaNext: k = XK_Next; break;
757 case Qt::Key_MediaPlay: k = XK_Begin; break;
758
759 /* Misc Functions */
760 case Qt::Key_Select: k = XK_Select; break;
761 case Qt::Key_Printer: k = XK_Print; break;
762 case Qt::Key_Execute: k = XK_Execute; break;
763 case Qt::Key_Undo: k = XK_Undo; break;
764 case Qt::Key_Redo: k = XK_Redo; break;
765 case Qt::Key_Menu: k = XK_Menu;break;
766 case Qt::Key_Find: k = XK_Find; break;
767 case Qt::Key_Exit:
768 case Qt::Key_Cancel:
769 case Qt::Key_Stop:
770 k = XK_Cancel;
771 break;
772 case Qt::Key_Mode_switch: k = XK_Mode_switch; break;
773
774 case Qt::Key_F1: k = XK_F1; break;
775 case Qt::Key_F2: k = XK_F2; break;
776 case Qt::Key_F3: k = XK_F3; break;
777 case Qt::Key_F4: k = XK_F4; break;
778 case Qt::Key_F5: k = XK_F5; break;
779 case Qt::Key_F6: k = XK_F6; break;
780 case Qt::Key_F7: k = XK_F7; break;
781 case Qt::Key_F8: k = XK_F8; break;
782 case Qt::Key_F9: k = XK_F9; break;
783 case Qt::Key_F10: k = XK_F10; break;
784 case Qt::Key_F11: k = XK_F11; break;
785 case Qt::Key_F12: k = XK_F12; break;
786 case Qt::Key_F13: k = XK_F13; break;
787 case Qt::Key_F14: k = XK_F14; break;
788 case Qt::Key_F15: k = XK_F15; break;
789 case Qt::Key_F16: k = XK_F16; break;
790 case Qt::Key_F17: k = XK_F17; break;
791 case Qt::Key_F18: k = XK_F18; break;
792 case Qt::Key_F19: k = XK_F19; break;
793 case Qt::Key_F20: k = XK_F20; break;
794 case Qt::Key_F21: k = XK_F21; break;
795 case Qt::Key_F22: k = XK_F22; break;
796 case Qt::Key_F23: k = XK_F23; break;
797 case Qt::Key_F24: k = XK_F24; break;
798 case Qt::Key_F25: k = XK_F25; break;
799 case Qt::Key_F26: k = XK_F26; break;
800 case Qt::Key_F27: k = XK_F27; break;
801 case Qt::Key_F28: k = XK_F28; break;
802 case Qt::Key_F29: k = XK_F29; break;
803 case Qt::Key_F30: k = XK_F30; break;
804 case Qt::Key_F31: k = XK_F31; break;
805 case Qt::Key_F32: k = XK_F32; break;
806 case Qt::Key_F33: k = XK_F33; break;
807 case Qt::Key_F34: k = XK_F34; break;
808 case Qt::Key_F35: k = XK_F35; break;
809
810 case Qt::Key_NumLock: k = XK_Num_Lock; break;
811 case Qt::Key_CapsLock: k = XK_Caps_Lock; break;
812 case Qt::Key_ScrollLock: k = XK_Scroll_Lock; break;
813
814 case Qt::Key_Shift: k = XK_Shift_R; break; //k = XK_Shift_L; break;
815 case Qt::Key_Control: k = XK_Control_R; break;// k = XK_Control_L; break;
816 case Qt::Key_Alt: k = XK_Alt_R; break;//k = XK_Alt_L; break;
817 case Qt::Key_Meta: k = XK_Meta_R; break;//k = XK_Meta_L; break;*/
818
819 case Qt::Key_Super_L: k = XK_Super_L; break; /* left "windows" key */
820 case Qt::Key_Super_R: k = XK_Super_R; break; /* right "windows" key */
821
822 case Qt::Key_Help: k = XK_Help; break;
823 case Qt::Key_Print: k = XK_Print; break;
824 case Qt::Key_SysReq: k = XK_Sys_Req; break;
825 case Qt::Key_0: k = XK_0;break;
826 case Qt::Key_1: k = XK_1;break;
827 case Qt::Key_2: k = XK_2;break;
828 case Qt::Key_3: k = XK_3;break;
829 case Qt::Key_4: k = XK_4;break;
830 case Qt::Key_5: k = XK_5;break;
831 case Qt::Key_6: k = XK_6;break;
832 case Qt::Key_7: k = XK_7;break;
833 case Qt::Key_8: k = XK_8;break;
834 case Qt::Key_9: k = XK_9;break;
835 }
836
837 if (k == 5000)
838 {
839
840 if (!modifier)
841 {
842 switch (inkey)
843 {
844 case Qt::Key_A: k = XK_a;break;
845 case Qt::Key_B: k = XK_b;break;
846 case Qt::Key_C: k = XK_c;break;
847 case Qt::Key_D: k = XK_d;break;
848 case Qt::Key_E: k = XK_e;break;
849 case Qt::Key_F: k = XK_f;break;
850 case Qt::Key_G: k = XK_g;break;
851 case Qt::Key_H: k = XK_h;break;
852 case Qt::Key_I: k = XK_i;break;
853 case Qt::Key_J: k = XK_j;break;
854 case Qt::Key_K: k = XK_k;break;
855 case Qt::Key_L: k = XK_l;break;
856 case Qt::Key_M: k = XK_m;break;
857 case Qt::Key_N: k = XK_n;break;
858 case Qt::Key_O: k = XK_o;break;
859 case Qt::Key_P: k = XK_p;break;
860 case Qt::Key_Q: k = XK_q;break;
861 case Qt::Key_R: k = XK_r;break;
862 case Qt::Key_S: k = XK_s;break;
863 case Qt::Key_T: k = XK_t;break;
864 case Qt::Key_U: k = XK_u;break;
865 case Qt::Key_V: k = XK_v;break;
866 case Qt::Key_W: k = XK_w;break;
867 case Qt::Key_X: k = XK_x;break;
868 case Qt::Key_Y: k = XK_y;break;
869 case Qt::Key_Z: k = XK_z;break;
870 }
871 }
872 else
873 {
874 switch (inkey)
875 {
876 case Qt::Key_A: k = XK_A;break;
877 case Qt::Key_B: k = XK_B;break;
878 case Qt::Key_C: k = XK_C;break;
879 case Qt::Key_D: k = XK_D;break;
880 case Qt::Key_E: k = XK_E;break;
881 case Qt::Key_F: k = XK_F;break;
882 case Qt::Key_G: k = XK_G;break;
883 case Qt::Key_H: k = XK_H;break;
884 case Qt::Key_I: k = XK_I;break;
885 case Qt::Key_J: k = XK_J;break;
886 case Qt::Key_K: k = XK_K;break;
887 case Qt::Key_L: k = XK_L;break;
888 case Qt::Key_M: k = XK_M;break;
889 case Qt::Key_N: k = XK_N;break;
890 case Qt::Key_O: k = XK_O;break;
891 case Qt::Key_P: k = XK_P;break;
892 case Qt::Key_Q: k = XK_Q;break;
893 case Qt::Key_R: k = XK_R;break;
894 case Qt::Key_S: k = XK_S;break;
895 case Qt::Key_T: k = XK_T;break;
896 case Qt::Key_U: k = XK_U;break;
897 case Qt::Key_V: k = XK_V;break;
898 case Qt::Key_W: k = XK_W;break;
899 case Qt::Key_X: k = XK_X;break;
900 case Qt::Key_Y: k = XK_Y;break;
901 case Qt::Key_Z: k = XK_Z;break;
902 }
903 }
904 }
905
906 return k;
907}
908
909void CConnectLibVNCServer::keyPressEvent(QKeyEvent *event)
910{
911 if(!m_pClient) return;
912 if(m_pParameter && m_pParameter->GetOnlyView()) return;
913 bool modifier = false;
914 if (event->modifiers() & Qt::ShiftModifier)
915 modifier = true;
916 uint32_t k = TranslateRfbKey(event->key(), modifier);
917 SendKeyEvent(m_pClient, k, TRUE);
918}
919
920void CConnectLibVNCServer::keyReleaseEvent(QKeyEvent *event)
921{
922 if(!m_pClient) return;
923 if(m_pParameter && m_pParameter->GetOnlyView()) return;
924 bool modifier = false;
925 if (event->modifiers() & Qt::ShiftModifier)
926 modifier = true;
927 uint32_t k = TranslateRfbKey(event->key(), modifier);
928 SendKeyEvent(m_pClient, k, FALSE);
929}
930
932void CConnectLibVNCServer::slotConnectProxyServer(QString szHost, quint16 nPort)
933{
934 QString szErr;
935 qDebug(log) << "CConnectLibVNCServer::slotConnectServer" << nPort;
936 // Set server ip and port
937 m_pClient->serverHost = strdup(szHost.toStdString().c_str());
938 m_pClient->serverPort = nPort;
939 szErr = tr("Connect to local socket server %1:%2")
940 .arg(m_pClient->serverHost,
941 QString::number(m_pClient->serverPort));
942 qDebug(log) << szErr;
943 if(!rfbInitClient(m_pClient, nullptr, nullptr))
944 {
945 szErr += tr(" fail");
946 qCritical(log) << szErr;
947 //emit sigShowMessageBox(tr("Error"), szErr, QMessageBox::Critical);
948 return;
949 }
950
951 QString szInfo = QString("Connect to ") + m_pClient->desktopName;
952 qInfo(log) << szInfo;
953
954 emit sigSetDesktopSize(m_pClient->width, m_pClient->height);
955 emit sigServerName(m_pClient->desktopName);
956 emit sigInformation(szInfo);
957 emit sigConnected();
958}
959
960#if defined(HAVE_UNIX_DOMAIN_SOCKET) && defined(Q_OS_UNIX)
962{
963 QString szErr;
964 qDebug(log) << "CConnectLibVNCServer::slotConnectServer" << szFile;
965 // Set server ip and port
966 m_pClient->serverHost = strdup(szFile.toStdString().c_str());
967 szErr = tr("Connect to local socket server ") + szFile;
968 qDebug(log) << szErr;
969 if(!rfbInitClient(m_pClient, nullptr, nullptr))
970 {
971 szErr += + " " + tr("fail");
972 qCritical(log) << szErr;
973 //emit sigShowMessageBox(tr("Error"), szErr, QMessageBox::Critical);
974 return;
975 }
976
977 QString szInfo = QString("Connect to ") + m_pClient->desktopName;
978 qInfo(log) << szInfo;
979
980 emit sigSetDesktopSize(m_pClient->width, m_pClient->height);
981 emit sigServerName(m_pClient->desktopName);
982 emit sigInformation(szInfo);
983 emit sigConnected();
984}
985#endif
Remote desktop connect interface.
void sigUpdateRect(const QRect &r, const QImage &image)
Notify the CFrmView update image.
void slotConnectProxyServer(QString szHost, quint16 nPort)
[connect local socket server]
virtual int OnProcess() override
Specific operation processing of plug-in connection.
virtual int WakeUp() override
Wake up Connect thread(background thread)
virtual OnInitReturnValue OnInit() override
Specific plug-in realizes connection initialization.
virtual int OnClean() override
Clean.
void sigError(const int nError, const QString &szError=QString())
Triggered when an error is generated.
void sigInformation(const QString &szInfo)
Triggering from a background thread displays information in the main thread without blocking the back...
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 sigConnected()
Emitted when the plugin is successfully connected.
void sigDisconnect()
Notify the user to call disconnect.
void sigBlockShowWidget(const QString &className, int &nRet, void *pContext)
Blocks the background thread and displays the window in the foreground thread.
CParameterUser m_User
[Instance user]
Data is forwarded over a local socket and SSH tunnel.