7#include <QtNetwork/QTcpSocket>
8#include <QtCore/QCoreApplication>
10#include <qpa/qwindowsysteminterface.h>
11#include <QtGui/qguiapplication.h>
21QVncClient::QVncClient(QTcpSocket *clientSocket, QVncServer *server)
24 , m_clientSocket(clientSocket)
28 , m_encodingsPending(0)
30 , m_supportHextile(
false)
32 , m_dirtyCursor(
false)
33 , m_updatePending(
false)
34 , m_protocolVersion(V3_3)
36 connect(m_clientSocket,SIGNAL(readyRead()),
this,SLOT(readClient()));
37 connect(m_clientSocket,SIGNAL(disconnected()),
this,SLOT(discardClient()));
40 const char *proto =
"RFB 003.003\n";
41 m_clientSocket->write(proto, 12);
52 return m_clientSocket;
57 m_dirtyRegion += region;
58 if (m_state == Connected &&
67#if Q_BYTE_ORDER == Q_BIG_ENDIAN
73 switch (screendepth) {
75 memcpy(dst, src, count *
sizeof(quint32));
82 memcpy(dst, src, count *
sizeof(quint16));
89 const int bytesPerPixel = (m_pixelFormat
.bitsPerPixel + 7) / 8;
91 for (
int i = 0; i < count; ++i) {
94 switch (screendepth) {
96 QRgb rgb = m_server->screen()->image()->colorTable()[
int(*src)];
104 quint16 p = *
reinterpret_cast<
const quint16*>(src);
105#if Q_BYTE_ORDER == Q_BIG_ENDIAN
107 p = ((p & 0xff) << 8) | ((p & 0xff00) >> 8);
109 r = (p >> 11) & 0x1f;
115 src +=
sizeof(quint16);
119 quint32 p = *
reinterpret_cast<
const quint32*>(src);
120 r = (p >> 16) & 0xff;
123 src +=
sizeof(quint32);
128 qWarning(
"QVNCServer: don't support %dbpp display", screendepth);
133#if Q_BYTE_ORDER == Q_BIG_ENDIAN
142 int pixel = (r << m_pixelFormat
.redShift) |
147 memcpy(dst, &pixel, bytesPerPixel);
148 dst += bytesPerPixel;
153 if (QSysInfo::ByteOrder == QSysInfo::BigEndian) {
156 pixel = (((pixel & 0x0000ff00) << 8) |
157 ((pixel & 0x000000ff) << 24));
160 pixel = (((pixel & 0xff000000) >> 24) |
161 ((pixel & 0x00ff0000) >> 8) |
162 ((pixel & 0x0000ff00) << 8) |
163 ((pixel & 0x000000ff) << 24));
166 qWarning(
"Cannot handle %d bpp client", m_pixelFormat
.bitsPerPixel);
171 pixel = (((pixel & 0xff000000) >> 8) |
172 ((pixel & 0x00ff0000) << 8));
175 pixel = (((pixel & 0xff000000) >> 24) |
176 ((pixel & 0x00ff0000) >> 8) |
177 ((pixel & 0x0000ff00) << 8) |
178 ((pixel & 0x000000ff) << 24));
181 qWarning(
"Cannot handle %d bpp client",
186 memcpy(dst, &pixel, bytesPerPixel);
187 dst += bytesPerPixel;
193 qCDebug(lcVnc) <<
"readClient" << m_state;
199 if (m_clientSocket->bytesAvailable() >= 12) {
201 m_clientSocket->read(proto, 12);
203 qCDebug(lcVnc,
"Client protocol version %s", proto);
204 if (!strcmp(proto,
"RFB 003.008\n")) {
205 m_protocolVersion = V3_8;
206 }
else if (!strcmp(proto,
"RFB 003.007\n")) {
207 m_protocolVersion = V3_7;
209 m_protocolVersion = V3_3;
212 if (m_protocolVersion == V3_3) {
214 quint32 auth = htonl(1);
215 m_clientSocket->write((
char *) &auth,
sizeof(auth));
224 if (m_clientSocket->bytesAvailable() >= 1) {
226 m_clientSocket->read((
char *) &shared, 1);
325 qWarning(
"QVNC cannot drive depth %d", m_server
->screen()->depth());
329 sim.width = m_server
->screen()->geometry().width();
330 sim.height = m_server
->screen()->geometry().height();
331 sim
.setName("Qt for Embedded Linux VNC Server");
340 m_clientSocket->read((
char *)&m_msgType, 1);
344 switch (m_msgType ) {
348 case FixColourMapEntries:
349 qWarning(
"Not supported: FixColourMapEntries");
355 case FramebufferUpdateRequest:
356 frameBufferUpdateRequest();
368 qWarning(
"Unknown message type: %d", (
int)m_msgType);
372 }
while (!m_handleMsg && m_clientSocket->bytesAvailable());
381 m_state = Disconnected;
391 m_server->screen()->clientCursor->write(
this);
392 m_dirtyCursor =
false;
393 m_wantUpdate =
false;
397 if (!m_dirtyRegion.isEmpty()) {
400 m_wantUpdate =
false;
401 m_dirtyRegion = QRegion();
407 if (!m_updatePending) {
408 m_updatePending =
true;
409 QCoreApplication::postEvent(
this,
new QEvent(QEvent::UpdateRequest));
415 if (event->type() == QEvent::UpdateRequest) {
416 m_updatePending =
false;
420 return QObject::event(event);
425 if (m_clientSocket->bytesAvailable() >= 19) {
427 m_clientSocket->read(buf, 3);
428 m_pixelFormat
.read(m_clientSocket
);
429 qCDebug(lcVnc,
"Want format: %d %d %d %d %d %d %d %d %d %d",
430 int(m_pixelFormat.bitsPerPixel),
431 int(m_pixelFormat.depth),
432 int(m_pixelFormat.bigEndian),
433 int(m_pixelFormat.trueColor),
434 int(m_pixelFormat.redBits),
435 int(m_pixelFormat.greenBits),
436 int(m_pixelFormat.blueBits),
437 int(m_pixelFormat.redShift),
438 int(m_pixelFormat.greenShift),
439 int(m_pixelFormat.blueShift));
441 qWarning(
"Can only handle true color clients");
445 m_sameEndian = (QSysInfo::ByteOrder == QSysInfo::BigEndian) == !!m_pixelFormat.bigEndian;
446 m_needConversion = pixelConversionNeeded();
447#if Q_BYTE_ORDER == Q_BIG_ENDIAN
457 if (!m_encodingsPending && enc
.read(m_clientSocket
)) {
458 m_encodingsPending = enc.count;
459 if (!m_encodingsPending)
479 if (m_encodingsPending && (
unsigned)m_clientSocket->bytesAvailable() >=
480 m_encodingsPending *
sizeof(quint32)) {
481 for (
int i = 0; i < m_encodingsPending; ++i) {
483 m_clientSocket->read((
char *)&enc,
sizeof(qint32));
485 qCDebug(lcVnc,
"QVncServer::setEncodings: %d", enc);
490 qCDebug(lcVnc,
"QVncServer::setEncodings: using raw");
494 m_supportCopyRect =
true;
500 m_supportCoRRE =
true;
503 m_supportHextile =
true;
508 m_supportZRLE =
true;
511 m_supportCursor =
true;
515 m_supportDesktopSize =
true;
522 m_encodingsPending = 0;
527 qCDebug(lcVnc,
"QVncServer::setEncodings: fallback using raw");
533 qCDebug(lcVnc) <<
"FramebufferUpdateRequest";
538 QRect r(ev.rect.x, ev.rect.y, ev.rect.w, ev.rect.h);
539 r.translate(m_server
->screen()->geometry().topLeft());
551 static int buttonState = Qt::NoButton;
553 const QPointF pos = m_server->screen()->geometry().topLeft() + QPoint(ev.x, ev.y);
554 int buttonStateChange = buttonState ^
int(ev.buttons);
555 QEvent::Type type = QEvent::MouseMove;
556 if (
int(ev.buttons) > buttonState)
557 type = QEvent::MouseButtonPress;
558 else if (
int(ev.buttons) < buttonState)
559 type = QEvent::MouseButtonRelease;
560 QWindowSystemInterface::handleMouseEvent(
nullptr, pos, pos, ev.buttons, Qt::MouseButton(buttonStateChange),
561 type, QGuiApplication::keyboardModifiers());
562 buttonState =
int(ev.buttons);
572 if (ev.keycode == Qt::Key_Shift)
573 m_keymod = ev.down ? m_keymod | Qt::ShiftModifier :
574 m_keymod & ~Qt::ShiftModifier;
575 else if (ev.keycode == Qt::Key_Control)
576 m_keymod = ev.down ? m_keymod | Qt::ControlModifier :
577 m_keymod & ~Qt::ControlModifier;
578 else if (ev.keycode == Qt::Key_Alt)
579 m_keymod = ev.down ? m_keymod | Qt::AltModifier :
580 m_keymod & ~Qt::AltModifier;
581 if (ev.unicode || ev.keycode)
582 QWindowSystemInterface::handleKeyEvent(
nullptr, ev.down ? QEvent::KeyPress : QEvent::KeyRelease, ev.keycode, m_keymod, QString(QChar::fromUcs2(ev.unicode)));
591 if (m_cutTextPending == 0 && ev
.read(m_clientSocket
)) {
592 m_cutTextPending = ev.length;
593 if (!m_cutTextPending)
597 if (m_cutTextPending && m_clientSocket->bytesAvailable() >= m_cutTextPending) {
598 char *text =
new char [m_cutTextPending+1];
599 m_clientSocket->read(text, m_cutTextPending);
601 m_cutTextPending = 0;
611#if Q_BYTE_ORDER == Q_BIG_ENDIAN
616 const int screendepth = m_server
->screen()->depth();
620 switch (screendepth) {
634#include "moc_qvncclient.cpp"
QRfbRawEncoder(QVncClient *s)
void setName(const char *n)
void write(QTcpSocket *s)
void convertPixels(char *dst, const char *src, int count, int depth) const
QTcpSocket * clientSocket() const
bool event(QEvent *event) override
This virtual function receives events to an object and should return true if the event e was recogniz...
void setDirty(const QRegion ®ion)
QVncServer * server() const
void enableClientCursor(QVncClient *client)
QVncScreen * screen() const
void discardClient(QVncClient *client)
QVncDirtyMap * dirtyMap() const