📄 qscreenvnc_qws.cpp
字号:
break; } default: return false; } SRC color = reinterpret_cast<const SRC*>(data)[0]; encoder->newBg |= (color != encoder->bg); encoder->bg = color; return true;}template <class SRC>void QRfbSingleColorHextile<SRC>::write(QTcpSocket *socket) const{ if (true || encoder->newBg) { const int bpp = encoder->server->clientBytesPerPixel(); const int padding = 3; QVarLengthArray<char> buffer(padding + 1 + bpp); buffer[padding] = 2; // BackgroundSpecified encoder->server->convertPixels(buffer.data() + padding + 1, reinterpret_cast<char*>(&encoder->bg), 1); socket->write(buffer.data() + padding, bpp + 1);// encoder->newBg = false; } else { char subenc = 0; socket->write(&subenc, 1); }}template <class SRC>bool QRfbDualColorHextile<SRC>::read(const uchar *data, int width, int height, int stride){ const SRC *ptr = reinterpret_cast<const SRC*>(data); const int linestep = (stride / sizeof(SRC)) - width; SRC c1; SRC c2 = 0; int n1 = 0; int n2 = 0; int x = 0; int y = 0; c1 = *ptr; // find second color while (y < height) { while (x < width) { if (*ptr == c1) { ++n1; } else { c2 = *ptr; goto found_second_color; } ++ptr; ++x; } x = 0; ptr += linestep; ++y; }found_second_color: // finish counting while (y < height) { while (x < width) { if (*ptr == c1) { ++n1; } else if (*ptr == c2) { ++n2; } else { return false; } ++ptr; ++x; } x = 0; ptr += linestep; ++y; } if (n2 > n1) { const quint32 tmpC = c1; c1 = c2; c2 = tmpC; } encoder->newBg |= (c1 != encoder->bg); encoder->newFg |= (c2 != encoder->fg); encoder->bg = c1; encoder->fg = c2; // create map bool inRect = false; numRects = 0; ptr = reinterpret_cast<const SRC*>(data); for (y = 0; y < height; ++y) { for (x = 0; x < width; ++x) { if (inRect && *ptr == encoder->bg) { // rect finished setWidth(x - lastx()); next(); inRect = false; } else if (!inRect && *ptr == encoder->fg) { // rect start setX(x); setY(y); setHeight(1); inRect = true; } ++ptr; } if (inRect) { // finish rect setWidth(width - lastx()); next(); inRect = false; } ptr += linestep; } return true;}template <class SRC>void QRfbDualColorHextile<SRC>::write(QTcpSocket *socket) const{ const int bpp = encoder->server->clientBytesPerPixel(); const int padding = 3; QVarLengthArray<char> buffer(padding + 2 * bpp + sizeof(char) + sizeof(numRects)); char &subenc = buffer[padding]; int n = padding + sizeof(subenc); subenc = 0x8; // AnySubrects if (encoder->newBg) { subenc |= 0x2; // Background encoder->server->convertPixels(buffer.data() + n, (char*)&encoder->bg, 1); n += bpp;// encoder->newBg = false; } if (encoder->newFg) { subenc |= 0x4; // Foreground encoder->server->convertPixels(buffer.data() + n, (char*)&encoder->fg, 1); n += bpp;// encoder->newFg = false; } buffer[n] = numRects; n += sizeof(numRects); socket->write(buffer.data() + padding, n - padding); socket->write((char*)rects, numRects * sizeof(Rect));}template <class SRC>void QRfbDualColorHextile<SRC>::next(){ for (int r = numRects - 1; r >= 0; --r) { if (recty(r) == lasty()) continue; if (recty(r) < lasty() - 1) // only search previous scanline break; if (rectx(r) == lastx() && width(r) == width(numRects)) { ++rects[r].wh; return; } } ++numRects;}template <class SRC>inline void QRfbMultiColorHextile<SRC>::setColor(SRC color){ encoder->server->convertPixels(reinterpret_cast<char*>(rect(numRects)), (const char*)&color, 1);}template <class SRC>inline bool QRfbMultiColorHextile<SRC>::beginRect(){ if ((rects.size() + bpp + 2) > maxRectsSize) return false; rects.resize(rects.size() + bpp + 2); return true;}template <class SRC>inline void QRfbMultiColorHextile<SRC>::endRect(){ setHeight(numRects, 1); ++numRects;}template <class SRC>bool QRfbMultiColorHextile<SRC>::read(const uchar *data, int width, int height, int stride){ const SRC *ptr = reinterpret_cast<const SRC*>(data); const int linestep = (stride / sizeof(SRC)) - width; bpp = encoder->server->clientBytesPerPixel(); if (encoder->newBg) encoder->bg = ptr[0]; const SRC bg = encoder->bg; SRC color = bg; bool inRect = false; numRects = 0; rects.clear(); for (int y = 0; y < height; ++y) { for (int x = 0; x < width; ++x) { if (inRect && *ptr != color) { // end rect setWidth(numRects, x - rectx(numRects)); endRect(); inRect = false; } if (!inRect && *ptr != bg) { // begin rect if (!beginRect()) return false; inRect = true; color = *ptr; setColor(color); setX(numRects, x); setY(numRects, y); } ++ptr; } if (inRect) { // end rect setWidth(numRects, width - rectx(numRects)); endRect(); inRect = false; } ptr += linestep; } return true;}template <class SRC>void QRfbMultiColorHextile<SRC>::write(QTcpSocket *socket) const{ const int padding = 3; QVarLengthArray<quint8> buffer(bpp + padding + sizeof(quint8) + sizeof(numRects)); quint8 &subenc = buffer[padding]; int n = padding + sizeof(quint8); subenc = 8 | 16; // AnySubrects | SubrectsColoured if (encoder->newBg) { subenc |= 0x2; // Background encoder->server->convertPixels(reinterpret_cast<char*>(buffer.data() + n), reinterpret_cast<const char*>(&encoder->bg), 1); n += bpp;// encoder->newBg = false; } buffer[n] = numRects; n += sizeof(numRects); socket->write(reinterpret_cast<const char*>(buffer.data() + padding), n - padding); socket->write(reinterpret_cast<const char*>(rects.constData()), rects.size());}bool QVNCServer::pixelConversionNeeded() const{ if (!sameEndian) return true;#if Q_BYTE_ORDER == Q_BIG_ENDIAN if (qvnc_screen->swapBytes()) return true;#endif const int screendepth = qvnc_screen->depth(); if (screendepth != pixelFormat.bitsPerPixel) return true; switch (screendepth) { case 32: return false; case 16: return (pixelFormat.redBits == 5 && pixelFormat.greenBits == 6 && pixelFormat.blueBits == 5); } return true;}// count: number of pixelsvoid QVNCServer::convertPixels(char *dst, const char *src, int count) const{ const int screendepth = qvnc_screen->depth(); // cutoffs#if Q_BYTE_ORDER == Q_BIG_ENDIAN if (!swapBytes)#endif if (sameEndian) { if (screendepth == pixelFormat.bitsPerPixel) { // memcpy cutoffs switch (screendepth) { case 32: memcpy(dst, src, count * sizeof(quint32)); return; case 16: if (pixelFormat.redBits == 5 && pixelFormat.greenBits == 6 && pixelFormat.blueBits == 5) { memcpy(dst, src, count * sizeof(quint16)); return; } } } else if (screendepth == 16 && pixelFormat.bitsPerPixel == 32) {#if defined(__i386__) // Currently fails on ARM if dst is not 4 byte aligned const quint32 *src32 = reinterpret_cast<const quint32*>(src); quint32 *dst32 = reinterpret_cast<quint32*>(dst); int count32 = count * sizeof(quint16) / sizeof(quint32); while (count32--) { const quint32 s = *src32++; quint32 result1; quint32 result2; // red result1 = ((s & 0xf8000000) | ((s & 0xe0000000) >> 5)) >> 8; result2 = ((s & 0x0000f800) | ((s & 0x0000e000) >> 5)) << 8; // green result1 |= ((s & 0x07e00000) | ((s & 0x06000000) >> 6)) >> 11; result2 |= ((s & 0x000007e0) | ((s & 0x00000600) >> 6)) << 5; // blue result1 |= ((s & 0x001f0000) | ((s & 0x001c0000) >> 5)) >> 13; result2 |= ((s & 0x0000001f) | ((s & 0x0000001c) >> 5)) << 3; *dst32++ = result2; *dst32++ = result1; } if (count & 0x1) { const quint16 *src16 = reinterpret_cast<const quint16*>(src); dst32[count - 1] = qt_conv16ToRgb(src16[count - 1]); } return;#endif } } const int bytesPerPixel = pixelFormat.bitsPerPixel / 8;// nibble = 0; for (int i = 0; i < count; ++i) { int r, g, b; switch (screendepth) {#if 0 case 4: { if (!nibble) { r = ((*src) & 0x0f) << 4; } else { r = (*src) & 0xf0; src++; } nibble = !nibble; g = b = r; break; }#endif case 8: { QRgb rgb = qvnc_screen->clut()[*src]; r = qRed(rgb); g = qGreen(rgb); b = qBlue(rgb); src++; break; } case 16: { quint16 p = *reinterpret_cast<const quint16*>(src);#if Q_BYTE_ORDER == Q_BIG_ENDIAN if (swapBytes) p = ((p & 0xff) << 8) | ((p & 0xff00) >> 8);#endif r = (p >> 11) & 0x1f; g = (p >> 5) & 0x3f; b = p & 0x1f; r <<= 3; g <<= 2; b <<= 3; src += sizeof(quint16); break; } case 32: { quint32 p = *reinterpret_cast<const quint32*>(src); r = (p >> 16) & 0xff; g = (p >> 8) & 0xff; b = p & 0xff; src += sizeof(quint32); break; } default: { r = g = b = 0; qDebug("QVNCServer: don't support %dbpp display", screendepth); return; } } r >>= (8 - pixelFormat.redBits); g >>= (8 - pixelFormat.greenBits); b >>= (8 - pixelFormat.blueBits); int pixel = (r << pixelFormat.redShift) | (g << pixelFormat.greenShift) | (b << pixelFormat.blueShift); if (sameEndian || pixelFormat.bitsPerPixel == 8) { memcpy(dst, &pixel, bytesPerPixel); // XXX: do a simple for-loop instead? dst += bytesPerPixel; continue; } if (QSysInfo::ByteOrder == QSysInfo::BigEndian) { switch (pixelFormat.bitsPerPixel) { case 16: pixel = (((pixel & 0x0000ff00) << 8) | ((pixel & 0x000000ff) << 24)); break; case 32: pixel = (((pixel & 0xff000000) >> 24) | ((pixel & 0x00ff0000) >> 8) | ((pixel & 0x0000ff00) << 8) | ((pixel & 0x000000ff) << 24)); break; default: qDebug("Cannot handle %d bpp client", pixelFormat.bitsPerPixel); } } else { // QSysInfo::ByteOrder == QSysInfo::LittleEndian switch (pixelFormat.bitsPerPixel) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -