📄 qscreenvnc_qws.cpp
字号:
QVNCServer::QVNCServer(QVNCScreen *screen, int id) : qvnc_screen(screen){ init(5900 + id);}void QVNCServer::init(uint port){ handleMsg = false; client = 0; encodingsPending = 0; cutTextPending = 0; keymod = 0; state = Unconnected; refreshRate = 25; timer = new QTimer(this); timer->setSingleShot(true); connect(timer, SIGNAL(timeout()), this, SLOT(checkUpdate())); serverSocket = new QTcpServer(this); if (!serverSocket->listen(QHostAddress::Any, port)) qDebug() << "QVNCServer could not connect:" << serverSocket->errorString(); else qDebug("QVNCServer created on port %d", port); connect(serverSocket, SIGNAL(newConnection()), this, SLOT(newConnection())); encoder = 0;}QVNCServer::~QVNCServer(){ delete encoder; encoder = 0; delete client; client = 0;}void QVNCServer::setDirty(){ if (state == Connected && !timer->isActive() && dirtyMap()->numDirty > 0) timer->start();}void QVNCServer::newConnection(){ if (client) delete client; client = serverSocket->nextPendingConnection(); connect(client,SIGNAL(readyRead()),this,SLOT(readClient())); connect(client,SIGNAL(disconnected()),this,SLOT(discardClient())); handleMsg = false; encodingsPending = 0; cutTextPending = 0; supportHextile = false; wantUpdate = false; timer->start(1000 / refreshRate); dirtyMap()->reset(); // send protocol version const char *proto = "RFB 003.003\n"; client->write(proto, 12); state = Protocol; if (!qvnc_screen->d_ptr->subscreen) QWSServer::instance()->enablePainting(true);}void QVNCServer::readClient(){ switch (state) { case Protocol: if (client->bytesAvailable() >= 12) { char proto[13]; client->read(proto, 12); proto[12] = '\0'; qDebug("Client protocol version %s", proto); // No authentication quint32 auth = htonl(1); client->write((char *) &auth, sizeof(auth)); state = Init; } break; case Init: if (client->bytesAvailable() >= 1) { quint8 shared; client->read((char *) &shared, 1); // Server Init msg QRfbServerInit sim; QRfbPixelFormat &format = sim.format; switch (qvnc_screen->depth()) { case 32: format.bitsPerPixel = 32; format.depth = 32; format.bigEndian = 0; format.trueColor = true; format.redBits = 8; format.greenBits = 8; format.blueBits = 8; format.redShift = 16; format.greenShift = 8; format.blueShift = 0; break; case 16: format.bitsPerPixel = 16; format.depth = 16; format.bigEndian = 0; format.trueColor = true; format.redBits = 5; format.greenBits = 6; format.blueBits = 5; format.redShift = 11; format.greenShift = 5; format.blueShift = 0; break; case 8: case 4: format.bitsPerPixel = 8; format.depth = 8; format.bigEndian = 0; format.trueColor = false; format.redBits = 0; format.greenBits = 0; format.blueBits = 0; format.redShift = 0; format.greenShift = 0; format.blueShift = 0; break; default: qDebug("QVNC cannot drive depth %d", qvnc_screen->depth()); discardClient(); return; } sim.width = qvnc_screen->deviceWidth(); sim.height = qvnc_screen->deviceHeight(); sim.setName("Qtopia Core VNC Server"); sim.write(client); state = Connected; } break; case Connected: do { if (!handleMsg) { client->read((char *)&msgType, 1); handleMsg = true; } if (handleMsg) { switch (msgType ) { case SetPixelFormat: setPixelFormat(); break; case FixColourMapEntries: qDebug("Not supported: FixColourMapEntries"); handleMsg = false; break; case SetEncodings: setEncodings(); break; case FramebufferUpdateRequest: frameBufferUpdateRequest(); break; case KeyEvent: keyEvent(); break; case PointerEvent: pointerEvent(); break; case ClientCutText: clientCutText(); break; default: qDebug("Unknown message type: %d", (int)msgType); handleMsg = false; } } } while (!handleMsg && client->bytesAvailable()); break; default: break; }}#if Q_BYTE_ORDER == Q_BIG_ENDIANbool QVNCScreen::swapBytes() const{ if (depth() != 16) return false; if (d_ptr->subscreen) return d_ptr->subscreen->frameBufferLittleEndian(); return frameBufferLittleEndian();}#endifvoid QVNCServer::setPixelFormat(){ if (client->bytesAvailable() >= 19) { char buf[3]; client->read(buf, 3); // just padding pixelFormat.read(client);#ifdef QT_QWS_VNC_DEBUG qDebug("Want format: %d %d %d %d %d %d %d %d %d %d", int(pixelFormat.bitsPerPixel), int(pixelFormat.depth), int(pixelFormat.bigEndian), int(pixelFormat.trueColor), int(pixelFormat.redBits), int(pixelFormat.greenBits), int(pixelFormat.blueBits), int(pixelFormat.redShift), int(pixelFormat.greenShift), int(pixelFormat.blueShift));#endif if (!pixelFormat.trueColor) { qDebug("Can only handle true color clients"); discardClient(); } handleMsg = false; sameEndian = (QSysInfo::ByteOrder == QSysInfo::BigEndian) == !!pixelFormat.bigEndian; needConversion = pixelConversionNeeded();#if Q_BYTE_ORDER == Q_BIG_ENDIAN swapBytes = qvnc_screen->swapBytes();#endif }}void QVNCServer::setEncodings(){ QRfbSetEncodings enc; if (!encodingsPending && enc.read(client)) { encodingsPending = enc.count; if (!encodingsPending) handleMsg = false; } if (encoder) { delete encoder; encoder = 0; } enum Encodings { Raw = 0, CopyRect = 1, RRE = 2, CoRRE = 4, Hextile = 5, ZRLE = 16, Cursor = -239, DesktopSize = -223 }; if (encodingsPending && (unsigned)client->bytesAvailable() >= encodingsPending * sizeof(quint32)) { for (int i = 0; i < encodingsPending; ++i) { qint32 enc; client->read((char *)&enc, sizeof(qint32)); enc = ntohl(enc);#ifdef QT_QWS_VNC_DEBUG qDebug("QVNCServer::setEncodings: %d", enc);#endif switch (enc) { case Raw: if (!encoder) { encoder = new QRfbRawEncoder(this);#ifdef QT_QWS_VNC_DEBUG qDebug("QVNCServer::setEncodings: using raw");#endif } break; case CopyRect: supportCopyRect = true; break; case RRE: supportRRE = true; break; case CoRRE: supportCoRRE = true; break; case Hextile: supportHextile = true; if (encoder) break; switch (qvnc_screen->depth()) {#ifdef QT_QWS_DEPTH_8 case 8: encoder = new QRfbHextileEncoder<quint8>(this); break;#endif#ifdef QT_QWS_DEPTH_16 case 16: encoder = new QRfbHextileEncoder<quint16>(this); break;#endif#ifdef QT_QWS_DEPTH_32 case 32: encoder = new QRfbHextileEncoder<quint32>(this); break;#endif default: break; }#ifdef QT_QWS_VNC_DEBUG qDebug("QVNCServer::setEncodings: using hextile");#endif break; case ZRLE: supportZRLE = true; break; case Cursor: supportCursor = true; break; case DesktopSize: supportDesktopSize = true; break; default: break; } } handleMsg = false; encodingsPending = 0; } if (!encoder) { encoder = new QRfbRawEncoder(this);#ifdef QT_QWS_VNC_DEBUG qDebug("QVNCServer::setEncodings: fallback using raw");#endif }}void QVNCServer::frameBufferUpdateRequest(){ QRfbFrameBufferUpdateRequest ev; if (ev.read(client)) { if (!ev.incremental) { QRect r(ev.rect.x, ev.rect.y, ev.rect.w, ev.rect.h); r.translated(qvnc_screen->offset()); qvnc_screen->d_ptr->setDirty(r, true); } wantUpdate = true; checkUpdate(); handleMsg = false; }}void QVNCServer::pointerEvent(){ QRfbPointerEvent ev; if (ev.read(client)) { const QPoint offset = qvnc_screen->offset(); QWSServer::sendMouseEvent(offset + QPoint(ev.x, ev.y), ev.buttons); handleMsg = false; }}void QVNCServer::keyEvent(){ QRfbKeyEvent ev; if (ev.read(client)) { if (ev.keycode == Qt::Key_Shift) keymod = ev.down ? keymod | Qt::ShiftModifier : keymod & ~Qt::ShiftModifier; else if (ev.keycode == Qt::Key_Control) keymod = ev.down ? keymod | Qt::ControlModifier : keymod & ~Qt::ControlModifier; else if (ev.keycode == Qt::Key_Alt) keymod = ev.down ? keymod | Qt::AltModifier : keymod & ~Qt::AltModifier; if (ev.unicode || ev.keycode) QWSServer::sendKeyEvent(ev.unicode, ev.keycode, keymod, ev.down, false); handleMsg = false; }}void QVNCServer::clientCutText(){ QRfbClientCutText ev; if (ev.read(client)) { cutTextPending = ev.length; if (!cutTextPending) handleMsg = false; } if (cutTextPending && client->bytesAvailable() >= cutTextPending) { char *text = new char [cutTextPending+1]; client->read(text, cutTextPending); delete [] text; cutTextPending = 0; handleMsg = false; }}// stride in bytestemplate <class SRC>bool QRfbSingleColorHextile<SRC>::read(const uchar *data, int width, int height, int stride){ const int depth = encoder->server->screen()->depth(); if (width % (depth / 8)) // hw: should rather fallback to simple loop return false; static int alwaysFalse = qgetenv("QT_VNC_NOCHECKFILL").toInt(); if (alwaysFalse) return false; switch (depth) { case 4: { const quint8 *data8 = reinterpret_cast<const quint8*>(data); if ((data8[0] & 0xf) != (data8[0] >> 4)) return false; width /= 2; } // fallthrough case 8: { const quint8 *data8 = reinterpret_cast<const quint8*>(data); if (data8[0] != data8[1]) return false; width /= 2; } // fallthrough case 16: { const quint16 *data16 = reinterpret_cast<const quint16*>(data); if (data16[0] != data16[1]) return false; width /= 2; } // fallthrough case 32: { const quint32 *data32 = reinterpret_cast<const quint32*>(data); const quint32 first = data32[0]; const int linestep = (stride / sizeof(quint32)) - width; for (int y = 0; y < height; ++y) { for (int x = 0; x < width; ++x) { if (*(data32++) != first) return false; } data32 += linestep; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -