Browse Source

Split out ServerParams from ConnParams

We need to track different things in the server and client, so
separate things to two independent structures to keep things more
clear.
tags/v1.9.90
Pierre Ossman 5 years ago
parent
commit
b14a6bc1aa

+ 16
- 15
common/rfb/CConnection.cxx View File

@@ -146,32 +146,33 @@ void CConnection::processVersionMsg()
throw Exception("reading version failed: not an RFB server?");
}

cp.setVersion(majorVersion, minorVersion);
server.setVersion(majorVersion, minorVersion);

vlog.info("Server supports RFB protocol version %d.%d",
cp.majorVersion, cp.minorVersion);
server.majorVersion, server.minorVersion);

// The only official RFB protocol versions are currently 3.3, 3.7 and 3.8
if (cp.beforeVersion(3,3)) {
if (server.beforeVersion(3,3)) {
vlog.error("Server gave unsupported RFB protocol version %d.%d",
cp.majorVersion, cp.minorVersion);
server.majorVersion, server.minorVersion);
state_ = RFBSTATE_INVALID;
throw Exception("Server gave unsupported RFB protocol version %d.%d",
cp.majorVersion, cp.minorVersion);
} else if (useProtocol3_3 || cp.beforeVersion(3,7)) {
cp.setVersion(3,3);
} else if (cp.afterVersion(3,8)) {
cp.setVersion(3,8);
server.majorVersion, server.minorVersion);
} else if (useProtocol3_3 || server.beforeVersion(3,7)) {
server.setVersion(3,3);
} else if (server.afterVersion(3,8)) {
server.setVersion(3,8);
}

sprintf(verStr, "RFB %03d.%03d\n", cp.majorVersion, cp.minorVersion);
sprintf(verStr, "RFB %03d.%03d\n",
server.majorVersion, server.minorVersion);
os->writeBytes(verStr, 12);
os->flush();

state_ = RFBSTATE_SECURITY_TYPES;

vlog.info("Using RFB protocol version %d.%d",
cp.majorVersion, cp.minorVersion);
server.majorVersion, server.minorVersion);
}


@@ -184,7 +185,7 @@ void CConnection::processSecurityTypesMsg()
std::list<rdr::U8> secTypes;
secTypes = security.GetEnabledSecTypes();

if (cp.isVersion(3,3)) {
if (server.isVersion(3,3)) {

// legacy 3.3 server may only offer "vnc authentication" or "none"

@@ -267,7 +268,7 @@ void CConnection::processSecurityResultMsg()
{
vlog.debug("processing security result message");
int result;
if (cp.beforeVersion(3,8) && csecurity->getType() == secTypeNone) {
if (server.beforeVersion(3,8) && csecurity->getType() == secTypeNone) {
result = secResultOK;
} else {
if (!is->checkNoWait(1)) return;
@@ -287,7 +288,7 @@ void CConnection::processSecurityResultMsg()
throw Exception("Unknown security result from server");
}
state_ = RFBSTATE_INVALID;
if (cp.beforeVersion(3,8))
if (server.beforeVersion(3,8))
throw AuthFailureException();
CharArray reason(is->readString());
throw AuthFailureException(reason.buf);
@@ -311,7 +312,7 @@ void CConnection::securityCompleted()
{
state_ = RFBSTATE_INITIALISATION;
reader_ = new CMsgReader(this, is);
writer_ = new CMsgWriter(&cp, os);
writer_ = new CMsgWriter(&server, os);
vlog.debug("Authentication success!");
authSuccess();
writer_->writeClientInit(shared);

+ 1
- 0
common/rfb/CMakeLists.txt View File

@@ -43,6 +43,7 @@ set(RFB_SOURCES
SMsgReader.cxx
SMsgWriter.cxx
ServerCore.cxx
ServerParams.cxx
Security.cxx
SecurityServer.cxx
SecurityClient.cxx

+ 9
- 9
common/rfb/CMsgHandler.cxx View File

@@ -34,44 +34,44 @@ CMsgHandler::~CMsgHandler()

void CMsgHandler::setDesktopSize(int width, int height)
{
cp.setDimensions(width, height);
server.setDimensions(width, height);
}

void CMsgHandler::setExtendedDesktopSize(unsigned reason, unsigned result,
int width, int height,
const ScreenSet& layout)
{
cp.supportsSetDesktopSize = true;
server.supportsSetDesktopSize = true;

if ((reason == reasonClient) && (result != resultSuccess))
return;

cp.setDimensions(width, height, layout);
server.setDimensions(width, height, layout);
}

void CMsgHandler::setPixelFormat(const PixelFormat& pf)
{
cp.setPF(pf);
server.setPF(pf);
}

void CMsgHandler::setName(const char* name)
{
cp.setName(name);
server.setName(name);
}

void CMsgHandler::fence(rdr::U32 flags, unsigned len, const char data[])
{
cp.supportsFence = true;
server.supportsFence = true;
}

void CMsgHandler::endOfContinuousUpdates()
{
cp.supportsContinuousUpdates = true;
server.supportsContinuousUpdates = true;
}

void CMsgHandler::supportsQEMUKeyEvent()
{
cp.supportsQEMUKeyEvent = true;
server.supportsQEMUKeyEvent = true;
}

void CMsgHandler::framebufferUpdateStart()
@@ -84,5 +84,5 @@ void CMsgHandler::framebufferUpdateEnd()

void CMsgHandler::setLEDState(unsigned int state)
{
cp.setLEDState(state);
server.setLEDState(state);
}

+ 3
- 3
common/rfb/CMsgHandler.h View File

@@ -26,7 +26,7 @@

#include <rdr/types.h>
#include <rfb/Pixel.h>
#include <rfb/ConnParams.h>
#include <rfb/ServerParams.h>
#include <rfb/Rect.h>
#include <rfb/ScreenSet.h>

@@ -43,7 +43,7 @@ namespace rfb {
// derived class should override these methods as desired. Note that for
// the setDesktopSize(), setExtendedDesktopSize(), setPixelFormat() and
// setName() methods, a derived class should call on to CMsgHandler's
// methods to set the members of cp appropriately.
// methods to set the members of "server" appropriately.

virtual void setDesktopSize(int w, int h);
virtual void setExtendedDesktopSize(unsigned reason, unsigned result,
@@ -72,7 +72,7 @@ namespace rfb {

virtual void setLEDState(unsigned int state);

ConnParams cp;
ServerParams server;
};
}
#endif

+ 9
- 8
common/rfb/CMsgReader.cxx View File

@@ -192,10 +192,11 @@ void CMsgReader::readFramebufferUpdate()

void CMsgReader::readRect(const Rect& r, int encoding)
{
if ((r.br.x > handler->cp.width()) || (r.br.y > handler->cp.height())) {
if ((r.br.x > handler->server.width()) ||
(r.br.y > handler->server.height())) {
fprintf(stderr, "Rect too big: %dx%d at %d,%d exceeds %dx%d\n",
r.width(), r.height(), r.tl.x, r.tl.y,
handler->cp.width(), handler->cp.height());
handler->server.width(), handler->server.height());
throw Exception("Rect too big");
}

@@ -269,7 +270,7 @@ void CMsgReader::readSetCursor(int width, int height, const Point& hotspot)
if (width > maxCursorSize || height > maxCursorSize)
throw Exception("Too big cursor");

int data_len = width * height * (handler->cp.pf().bpp/8);
int data_len = width * height * (handler->server.pf().bpp/8);
int mask_len = ((width+7)/8) * height;
rdr::U8Array data(data_len);
rdr::U8Array mask(mask_len);
@@ -290,14 +291,14 @@ void CMsgReader::readSetCursor(int width, int height, const Point& hotspot)
int byte = y * maskBytesPerRow + x / 8;
int bit = 7 - x % 8;

handler->cp.pf().rgbFromBuffer(out, in, 1);
handler->server.pf().rgbFromBuffer(out, in, 1);

if (mask.buf[byte] & (1 << bit))
out[3] = 255;
else
out[3] = 0;

in += handler->cp.pf().bpp/8;
in += handler->server.pf().bpp/8;
out += 4;
}
}
@@ -321,10 +322,10 @@ void CMsgReader::readSetCursorWithAlpha(int width, int height, const Point& hots

encoding = is->readS32();

origPF = handler->cp.pf();
handler->cp.setPF(rgbaPF);
origPF = handler->server.pf();
handler->server.setPF(rgbaPF);
handler->readAndDecodeRect(pb.getRect(), encoding, &pb);
handler->cp.setPF(origPF);
handler->server.setPF(origPF);

// On-wire data has pre-multiplied alpha, but we store it
// non-pre-multiplied

+ 18
- 18
common/rfb/CMsgWriter.cxx View File

@@ -25,14 +25,14 @@
#include <rfb/Exception.h>
#include <rfb/PixelFormat.h>
#include <rfb/Rect.h>
#include <rfb/ConnParams.h>
#include <rfb/ServerParams.h>
#include <rfb/Decoder.h>
#include <rfb/CMsgWriter.h>

using namespace rfb;

CMsgWriter::CMsgWriter(ConnParams* cp_, rdr::OutStream* os_)
: cp(cp_), os(os_)
CMsgWriter::CMsgWriter(ServerParams* server_, rdr::OutStream* os_)
: server(server_), os(os_)
{
}

@@ -72,18 +72,18 @@ void CMsgWriter::writeSetEncodings(int preferredEncoding, bool useCopyRect)
int nEncodings = 0;
rdr::U32 encodings[encodingMax+3];

if (cp->supportsLocalCursor) {
if (server->supportsLocalCursor) {
encodings[nEncodings++] = pseudoEncodingCursorWithAlpha;
encodings[nEncodings++] = pseudoEncodingCursor;
encodings[nEncodings++] = pseudoEncodingXCursor;
}
if (cp->supportsDesktopResize)
if (server->supportsDesktopResize)
encodings[nEncodings++] = pseudoEncodingDesktopSize;
if (cp->supportsExtendedDesktopSize)
if (server->supportsExtendedDesktopSize)
encodings[nEncodings++] = pseudoEncodingExtendedDesktopSize;
if (cp->supportsDesktopRename)
if (server->supportsDesktopRename)
encodings[nEncodings++] = pseudoEncodingDesktopName;
if (cp->supportsLEDState)
if (server->supportsLEDState)
encodings[nEncodings++] = pseudoEncodingLEDState;

encodings[nEncodings++] = pseudoEncodingLastRect;
@@ -132,10 +132,10 @@ void CMsgWriter::writeSetEncodings(int preferredEncoding, bool useCopyRect)
}
}

if (cp->compressLevel >= 0 && cp->compressLevel <= 9)
encodings[nEncodings++] = pseudoEncodingCompressLevel0 + cp->compressLevel;
if (cp->qualityLevel >= 0 && cp->qualityLevel <= 9)
encodings[nEncodings++] = pseudoEncodingQualityLevel0 + cp->qualityLevel;
if (server->compressLevel >= 0 && server->compressLevel <= 9)
encodings[nEncodings++] = pseudoEncodingCompressLevel0 + server->compressLevel;
if (server->qualityLevel >= 0 && server->qualityLevel <= 9)
encodings[nEncodings++] = pseudoEncodingQualityLevel0 + server->qualityLevel;

writeSetEncodings(nEncodings, encodings);
}
@@ -143,7 +143,7 @@ void CMsgWriter::writeSetEncodings(int preferredEncoding, bool useCopyRect)
void CMsgWriter::writeSetDesktopSize(int width, int height,
const ScreenSet& layout)
{
if (!cp->supportsSetDesktopSize)
if (!server->supportsSetDesktopSize)
throw Exception("Server does not support SetDesktopSize");

startMsg(msgTypeSetDesktopSize);
@@ -182,7 +182,7 @@ void CMsgWriter::writeFramebufferUpdateRequest(const Rect& r, bool incremental)
void CMsgWriter::writeEnableContinuousUpdates(bool enable,
int x, int y, int w, int h)
{
if (!cp->supportsContinuousUpdates)
if (!server->supportsContinuousUpdates)
throw Exception("Server does not support continuous updates");

startMsg(msgTypeEnableContinuousUpdates);
@@ -199,7 +199,7 @@ void CMsgWriter::writeEnableContinuousUpdates(bool enable,

void CMsgWriter::writeFence(rdr::U32 flags, unsigned len, const char data[])
{
if (!cp->supportsFence)
if (!server->supportsFence)
throw Exception("Server does not support fences");
if (len > 64)
throw Exception("Too large fence payload");
@@ -219,7 +219,7 @@ void CMsgWriter::writeFence(rdr::U32 flags, unsigned len, const char data[])

void CMsgWriter::writeKeyEvent(rdr::U32 keysym, rdr::U32 keycode, bool down)
{
if (!cp->supportsQEMUKeyEvent || !keycode) {
if (!server->supportsQEMUKeyEvent || !keycode) {
/* This event isn't meaningful without a valid keysym */
if (!keysym)
return;
@@ -245,8 +245,8 @@ void CMsgWriter::writePointerEvent(const Point& pos, int buttonMask)
Point p(pos);
if (p.x < 0) p.x = 0;
if (p.y < 0) p.y = 0;
if (p.x >= cp->width()) p.x = cp->width() - 1;
if (p.y >= cp->height()) p.y = cp->height() - 1;
if (p.x >= server->width()) p.x = server->width() - 1;
if (p.y >= server->height()) p.y = server->height() - 1;

startMsg(msgTypePointerEvent);
os->writeU8(buttonMask);

+ 3
- 3
common/rfb/CMsgWriter.h View File

@@ -30,14 +30,14 @@ namespace rdr { class OutStream; }
namespace rfb {

class PixelFormat;
class ConnParams;
class ServerParams;
struct ScreenSet;
struct Point;
struct Rect;

class CMsgWriter {
public:
CMsgWriter(ConnParams* cp, rdr::OutStream* os);
CMsgWriter(ServerParams* server, rdr::OutStream* os);
virtual ~CMsgWriter();

void writeClientInit(bool shared);
@@ -60,7 +60,7 @@ namespace rfb {
void startMsg(int type);
void endMsg();

ConnParams* cp;
ServerParams* server;
rdr::OutStream* os;
};
}

+ 4
- 4
common/rfb/CopyRectDecoder.cxx View File

@@ -32,7 +32,7 @@ CopyRectDecoder::~CopyRectDecoder()
}

void CopyRectDecoder::readRect(const Rect& r, rdr::InStream* is,
const ConnParams& cp, rdr::OutStream* os)
const ServerParams& server, rdr::OutStream* os)
{
os->copyBytes(is, 4);
}
@@ -41,21 +41,21 @@ void CopyRectDecoder::readRect(const Rect& r, rdr::InStream* is,
void CopyRectDecoder::getAffectedRegion(const Rect& rect,
const void* buffer,
size_t buflen,
const ConnParams& cp,
const ServerParams& server,
Region* region)
{
rdr::MemInStream is(buffer, buflen);
int srcX = is.readU16();
int srcY = is.readU16();

Decoder::getAffectedRegion(rect, buffer, buflen, cp, region);
Decoder::getAffectedRegion(rect, buffer, buflen, server, region);

region->assign_union(Region(rect.translate(Point(srcX-rect.tl.x,
srcY-rect.tl.y))));
}

void CopyRectDecoder::decodeRect(const Rect& r, const void* buffer,
size_t buflen, const ConnParams& cp,
size_t buflen, const ServerParams& server,
ModifiablePixelBuffer* pb)
{
rdr::MemInStream is(buffer, buflen);

+ 3
- 3
common/rfb/CopyRectDecoder.h View File

@@ -27,12 +27,12 @@ namespace rfb {
CopyRectDecoder();
virtual ~CopyRectDecoder();
virtual void readRect(const Rect& r, rdr::InStream* is,
const ConnParams& cp, rdr::OutStream* os);
const ServerParams& server, rdr::OutStream* os);
virtual void getAffectedRegion(const Rect& rect, const void* buffer,
size_t buflen, const ConnParams& cp,
size_t buflen, const ServerParams& server,
Region* region);
virtual void decodeRect(const Rect& r, const void* buffer,
size_t buflen, const ConnParams& cp,
size_t buflen, const ServerParams& server,
ModifiablePixelBuffer* pb);
};
}

+ 7
- 7
common/rfb/DecodeManager.cxx View File

@@ -132,9 +132,9 @@ void DecodeManager::decodeRect(const Rect& r, int encoding,
if (threads.empty()) {
bufferStream = freeBuffers.front();
bufferStream->clear();
decoder->readRect(r, conn->getInStream(), conn->cp, bufferStream);
decoder->readRect(r, conn->getInStream(), conn->server, bufferStream);
decoder->decodeRect(r, bufferStream->data(), bufferStream->length(),
conn->cp, pb);
conn->server, pb);
return;
}

@@ -155,7 +155,7 @@ void DecodeManager::decodeRect(const Rect& r, int encoding,

// Read the rect
bufferStream->clear();
decoder->readRect(r, conn->getInStream(), conn->cp, bufferStream);
decoder->readRect(r, conn->getInStream(), conn->server, bufferStream);

// Then try to put it on the queue
entry = new QueueEntry;
@@ -164,12 +164,12 @@ void DecodeManager::decodeRect(const Rect& r, int encoding,
entry->rect = r;
entry->encoding = encoding;
entry->decoder = decoder;
entry->cp = &conn->cp;
entry->server = &conn->server;
entry->pb = pb;
entry->bufferStream = bufferStream;

decoder->getAffectedRegion(r, bufferStream->data(),
bufferStream->length(), conn->cp,
bufferStream->length(), conn->server,
&entry->affectedRegion);

queueMutex->lock();
@@ -276,7 +276,7 @@ void DecodeManager::DecodeThread::worker()
try {
entry->decoder->decodeRect(entry->rect, entry->bufferStream->data(),
entry->bufferStream->length(),
*entry->cp, entry->pb);
*entry->server, entry->pb);
} catch (rdr::Exception& e) {
manager->setThreadException(e);
} catch(...) {
@@ -346,7 +346,7 @@ DecodeManager::QueueEntry* DecodeManager::DecodeThread::findEntry()
(*iter2)->rect,
(*iter2)->bufferStream->data(),
(*iter2)->bufferStream->length(),
*entry->cp))
*entry->server))
goto next;
}
}

+ 1
- 1
common/rfb/DecodeManager.h View File

@@ -65,7 +65,7 @@ namespace rfb {
Rect rect;
int encoding;
Decoder* decoder;
const ConnParams* cp;
const ServerParams* server;
ModifiablePixelBuffer* pb;
rdr::MemOutStream* bufferStream;
Region affectedRegion;

+ 2
- 2
common/rfb/Decoder.cxx View File

@@ -38,7 +38,7 @@ Decoder::~Decoder()
}

void Decoder::getAffectedRegion(const Rect& rect, const void* buffer,
size_t buflen, const ConnParams& cp,
size_t buflen, const ServerParams& server,
Region* region)
{
region->reset(rect);
@@ -47,7 +47,7 @@ void Decoder::getAffectedRegion(const Rect& rect, const void* buffer,
bool Decoder::doRectsConflict(const Rect& rectA, const void* bufferA,
size_t buflenA, const Rect& rectB,
const void* bufferB, size_t buflenB,
const ConnParams& cp)
const ServerParams& server)
{
return false;
}

+ 5
- 5
common/rfb/Decoder.h View File

@@ -25,7 +25,7 @@ namespace rdr {
}

namespace rfb {
class ConnParams;
class ServerParams;
class ModifiablePixelBuffer;
class Region;

@@ -53,7 +53,7 @@ namespace rfb {
// make it easier to decode. This function will always be called in
// a serial manner on the main thread.
virtual void readRect(const Rect& r, rdr::InStream* is,
const ConnParams& cp, rdr::OutStream* os)=0;
const ServerParams& server, rdr::OutStream* os)=0;

// These functions will be called from any of the worker threads.
// A lock will be held whilst these are called so it is safe to
@@ -63,7 +63,7 @@ namespace rfb {
// be either read from or written do when decoding this rect. The
// default implementation simply returns the given rectangle.
virtual void getAffectedRegion(const Rect& rect, const void* buffer,
size_t buflen, const ConnParams& cp,
size_t buflen, const ServerParams& server,
Region* region);

// doesRectsConflict() determines if two rectangles must be decoded
@@ -75,14 +75,14 @@ namespace rfb {
const Rect& rectB,
const void* bufferB,
size_t buflenB,
const ConnParams& cp);
const ServerParams& server);

// decodeRect() decodes the given rectangle with data from the
// given buffer, onto the ModifiablePixelBuffer. The PixelFormat of
// the PixelBuffer might not match the ConnParams and it is up to
// the decoder to do any necessary conversion.
virtual void decodeRect(const Rect& r, const void* buffer,
size_t buflen, const ConnParams& cp,
size_t buflen, const ServerParams& server,
ModifiablePixelBuffer* pb)=0;

public:

+ 5
- 5
common/rfb/HextileDecoder.cxx View File

@@ -20,7 +20,7 @@
#include <rdr/MemInStream.h>
#include <rdr/OutStream.h>

#include <rfb/ConnParams.h>
#include <rfb/ServerParams.h>
#include <rfb/PixelBuffer.h>
#include <rfb/HextileDecoder.h>

@@ -45,12 +45,12 @@ HextileDecoder::~HextileDecoder()
}

void HextileDecoder::readRect(const Rect& r, rdr::InStream* is,
const ConnParams& cp, rdr::OutStream* os)
const ServerParams& server, rdr::OutStream* os)
{
Rect t;
size_t bytesPerPixel;

bytesPerPixel = cp.pf().bpp/8;
bytesPerPixel = server.pf().bpp/8;

for (t.tl.y = r.tl.y; t.tl.y < r.br.y; t.tl.y += 16) {

@@ -91,11 +91,11 @@ void HextileDecoder::readRect(const Rect& r, rdr::InStream* is,
}

void HextileDecoder::decodeRect(const Rect& r, const void* buffer,
size_t buflen, const ConnParams& cp,
size_t buflen, const ServerParams& server,
ModifiablePixelBuffer* pb)
{
rdr::MemInStream is(buffer, buflen);
const PixelFormat& pf = cp.pf();
const PixelFormat& pf = server.pf();
switch (pf.bpp) {
case 8: hextileDecode8 (r, &is, pf, pb); break;
case 16: hextileDecode16(r, &is, pf, pb); break;

+ 2
- 2
common/rfb/HextileDecoder.h View File

@@ -27,9 +27,9 @@ namespace rfb {
HextileDecoder();
virtual ~HextileDecoder();
virtual void readRect(const Rect& r, rdr::InStream* is,
const ConnParams& cp, rdr::OutStream* os);
const ServerParams& server, rdr::OutStream* os);
virtual void decodeRect(const Rect& r, const void* buffer,
size_t buflen, const ConnParams& cp,
size_t buflen, const ServerParams& server,
ModifiablePixelBuffer* pb);
};
}

+ 5
- 5
common/rfb/RREDecoder.cxx View File

@@ -20,7 +20,7 @@
#include <rdr/MemInStream.h>
#include <rdr/OutStream.h>

#include <rfb/ConnParams.h>
#include <rfb/ServerParams.h>
#include <rfb/PixelBuffer.h>
#include <rfb/RREDecoder.h>

@@ -45,22 +45,22 @@ RREDecoder::~RREDecoder()
}

void RREDecoder::readRect(const Rect& r, rdr::InStream* is,
const ConnParams& cp, rdr::OutStream* os)
const ServerParams& server, rdr::OutStream* os)
{
rdr::U32 numRects;

numRects = is->readU32();
os->writeU32(numRects);

os->copyBytes(is, cp.pf().bpp/8 + numRects * (cp.pf().bpp/8 + 8));
os->copyBytes(is, server.pf().bpp/8 + numRects * (server.pf().bpp/8 + 8));
}

void RREDecoder::decodeRect(const Rect& r, const void* buffer,
size_t buflen, const ConnParams& cp,
size_t buflen, const ServerParams& server,
ModifiablePixelBuffer* pb)
{
rdr::MemInStream is(buffer, buflen);
const PixelFormat& pf = cp.pf();
const PixelFormat& pf = server.pf();
switch (pf.bpp) {
case 8: rreDecode8 (r, &is, pf, pb); break;
case 16: rreDecode16(r, &is, pf, pb); break;

+ 2
- 2
common/rfb/RREDecoder.h View File

@@ -27,9 +27,9 @@ namespace rfb {
RREDecoder();
virtual ~RREDecoder();
virtual void readRect(const Rect& r, rdr::InStream* is,
const ConnParams& cp, rdr::OutStream* os);
const ServerParams& server, rdr::OutStream* os);
virtual void decodeRect(const Rect& r, const void* buffer,
size_t buflen, const ConnParams& cp,
size_t buflen, const ServerParams& server,
ModifiablePixelBuffer* pb);
};
}

+ 6
- 6
common/rfb/RawDecoder.cxx View File

@@ -19,7 +19,7 @@
#include <assert.h>

#include <rdr/OutStream.h>
#include <rfb/ConnParams.h>
#include <rfb/ServerParams.h>
#include <rfb/PixelBuffer.h>
#include <rfb/RawDecoder.h>

@@ -34,15 +34,15 @@ RawDecoder::~RawDecoder()
}

void RawDecoder::readRect(const Rect& r, rdr::InStream* is,
const ConnParams& cp, rdr::OutStream* os)
const ServerParams& server, rdr::OutStream* os)
{
os->copyBytes(is, r.area() * (cp.pf().bpp/8));
os->copyBytes(is, r.area() * (server.pf().bpp/8));
}

void RawDecoder::decodeRect(const Rect& r, const void* buffer,
size_t buflen, const ConnParams& cp,
size_t buflen, const ServerParams& server,
ModifiablePixelBuffer* pb)
{
assert(buflen >= (size_t)r.area() * (cp.pf().bpp/8));
pb->imageRect(cp.pf(), r, buffer);
assert(buflen >= (size_t)r.area() * (server.pf().bpp/8));
pb->imageRect(server.pf(), r, buffer);
}

+ 2
- 2
common/rfb/RawDecoder.h View File

@@ -26,9 +26,9 @@ namespace rfb {
RawDecoder();
virtual ~RawDecoder();
virtual void readRect(const Rect& r, rdr::InStream* is,
const ConnParams& cp, rdr::OutStream* os);
const ServerParams& server, rdr::OutStream* os);
virtual void decodeRect(const Rect& r, const void* buffer,
size_t buflen, const ConnParams& cp,
size_t buflen, const ServerParams& server,
ModifiablePixelBuffer* pb);
};
}

+ 90
- 0
common/rfb/ServerParams.cxx View File

@@ -0,0 +1,90 @@
/* Copyright (C) 2002-2005 RealVNC Ltd. All Rights Reserved.
* Copyright (C) 2011 D. R. Commander. All Rights Reserved.
* Copyright 2014-2018 Pierre Ossman for Cendio AB
*
* This is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this software; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
* USA.
*/
#include <rfb/Exception.h>
#include <rfb/ledStates.h>
#include <rfb/ServerParams.h>

using namespace rfb;

ServerParams::ServerParams()
: majorVersion(0), minorVersion(0),
useCopyRect(false),
supportsLocalCursor(false), supportsLocalXCursor(false),
supportsLocalCursorWithAlpha(false),
supportsDesktopResize(false), supportsExtendedDesktopSize(false),
supportsDesktopRename(false), supportsLastRect(false),
supportsLEDState(false), supportsQEMUKeyEvent(false),
supportsSetDesktopSize(false), supportsFence(false),
supportsContinuousUpdates(false),
compressLevel(2), qualityLevel(-1),
width_(0), height_(0), name_(0),
ledState_(ledUnknown)
{
setName("");
cursor_ = new Cursor(0, 0, Point(), NULL);
}

ServerParams::~ServerParams()
{
delete [] name_;
delete cursor_;
}

void ServerParams::setDimensions(int width, int height)
{
ScreenSet layout;
layout.add_screen(rfb::Screen(0, 0, 0, width, height, 0));
setDimensions(width, height, layout);
}

void ServerParams::setDimensions(int width, int height, const ScreenSet& layout)
{
if (!layout.validate(width, height))
throw Exception("Attempted to configure an invalid screen layout");

width_ = width;
height_ = height;
screenLayout_ = layout;
}

void ServerParams::setPF(const PixelFormat& pf)
{
pf_ = pf;

if (pf.bpp != 8 && pf.bpp != 16 && pf.bpp != 32)
throw Exception("setPF: not 8, 16 or 32 bpp?");
}

void ServerParams::setName(const char* name)
{
delete [] name_;
name_ = strDup(name);
}

void ServerParams::setCursor(const Cursor& other)
{
delete cursor_;
cursor_ = new Cursor(other);
}

void ServerParams::setLEDState(unsigned int state)
{
ledState_ = state;
}

+ 103
- 0
common/rfb/ServerParams.h View File

@@ -0,0 +1,103 @@
/* Copyright (C) 2002-2005 RealVNC Ltd. All Rights Reserved.
* Copyright 2014-2018 Pierre Ossman for Cendio AB
*
* This is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this software; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
* USA.
*/
//
// ServerParams - structure describing the current state of the remote server
//

#ifndef __RFB_SERVERPARAMS_H__
#define __RFB_SERVERPARAMS_H__

#include <rfb/Cursor.h>
#include <rfb/PixelFormat.h>
#include <rfb/ScreenSet.h>

namespace rfb {

class ServerParams {
public:
ServerParams();
~ServerParams();

int majorVersion;
int minorVersion;

void setVersion(int major, int minor) {
majorVersion = major; minorVersion = minor;
}
bool isVersion(int major, int minor) const {
return majorVersion == major && minorVersion == minor;
}
bool beforeVersion(int major, int minor) const {
return (majorVersion < major ||
(majorVersion == major && minorVersion < minor));
}
bool afterVersion(int major, int minor) const {
return !beforeVersion(major,minor+1);
}

const int width() const { return width_; }
const int height() const { return height_; }
const ScreenSet& screenLayout() const { return screenLayout_; }
void setDimensions(int width, int height);
void setDimensions(int width, int height, const ScreenSet& layout);

const PixelFormat& pf() const { return pf_; }
void setPF(const PixelFormat& pf);

const char* name() const { return name_; }
void setName(const char* name);

const Cursor& cursor() const { return *cursor_; }
void setCursor(const Cursor& cursor);

unsigned int ledState() { return ledState_; }
void setLEDState(unsigned int state);

bool useCopyRect;

bool supportsLocalCursor;
bool supportsLocalXCursor;
bool supportsLocalCursorWithAlpha;
bool supportsDesktopResize;
bool supportsExtendedDesktopSize;
bool supportsDesktopRename;
bool supportsLastRect;
bool supportsLEDState;
bool supportsQEMUKeyEvent;

bool supportsSetDesktopSize;
bool supportsFence;
bool supportsContinuousUpdates;

int compressLevel;
int qualityLevel;

private:

int width_;
int height_;
ScreenSet screenLayout_;

PixelFormat pf_;
char* name_;
Cursor* cursor_;
unsigned int ledState_;
};
}
#endif

+ 12
- 12
common/rfb/TightDecoder.cxx View File

@@ -25,7 +25,7 @@
#include <rdr/MemInStream.h>
#include <rdr/OutStream.h>

#include <rfb/ConnParams.h>
#include <rfb/ServerParams.h>
#include <rfb/Exception.h>
#include <rfb/PixelBuffer.h>
#include <rfb/TightConstants.h>
@@ -55,7 +55,7 @@ TightDecoder::~TightDecoder()
}

void TightDecoder::readRect(const Rect& r, rdr::InStream* is,
const ConnParams& cp, rdr::OutStream* os)
const ServerParams& server, rdr::OutStream* os)
{
rdr::U8 comp_ctl;

@@ -66,10 +66,10 @@ void TightDecoder::readRect(const Rect& r, rdr::InStream* is,

// "Fill" compression type.
if (comp_ctl == tightFill) {
if (cp.pf().is888())
if (server.pf().is888())
os->copyBytes(is, 3);
else
os->copyBytes(is, cp.pf().bpp/8);
os->copyBytes(is, server.pf().bpp/8);
return;
}

@@ -106,13 +106,13 @@ void TightDecoder::readRect(const Rect& r, rdr::InStream* is,
palSize = is->readU8() + 1;
os->writeU8(palSize - 1);

if (cp.pf().is888())
if (server.pf().is888())
os->copyBytes(is, palSize * 3);
else
os->copyBytes(is, palSize * cp.pf().bpp/8);
os->copyBytes(is, palSize * server.pf().bpp/8);
break;
case tightFilterGradient:
if (cp.pf().bpp == 8)
if (server.pf().bpp == 8)
throw Exception("TightDecoder: invalid BPP for gradient filter");
break;
case tightFilterCopy:
@@ -129,10 +129,10 @@ void TightDecoder::readRect(const Rect& r, rdr::InStream* is,
rowSize = (r.width() + 7) / 8;
else
rowSize = r.width();
} else if (cp.pf().is888()) {
} else if (server.pf().is888()) {
rowSize = r.width() * 3;
} else {
rowSize = r.width() * cp.pf().bpp/8;
rowSize = r.width() * server.pf().bpp/8;
}

dataSize = r.height() * rowSize;
@@ -154,7 +154,7 @@ bool TightDecoder::doRectsConflict(const Rect& rectA,
const Rect& rectB,
const void* bufferB,
size_t buflenB,
const ConnParams& cp)
const ServerParams& server)
{
rdr::U8 comp_ctl_a, comp_ctl_b;

@@ -177,11 +177,11 @@ bool TightDecoder::doRectsConflict(const Rect& rectA,
}

void TightDecoder::decodeRect(const Rect& r, const void* buffer,
size_t buflen, const ConnParams& cp,
size_t buflen, const ServerParams& server,
ModifiablePixelBuffer* pb)
{
const rdr::U8* bufptr;
const PixelFormat& pf = cp.pf();
const PixelFormat& pf = server.pf();

rdr::U8 comp_ctl;


+ 3
- 3
common/rfb/TightDecoder.h View File

@@ -32,16 +32,16 @@ namespace rfb {
TightDecoder();
virtual ~TightDecoder();
virtual void readRect(const Rect& r, rdr::InStream* is,
const ConnParams& cp, rdr::OutStream* os);
const ServerParams& server, rdr::OutStream* os);
virtual bool doRectsConflict(const Rect& rectA,
const void* bufferA,
size_t buflenA,
const Rect& rectB,
const void* bufferB,
size_t buflenB,
const ConnParams& cp);
const ServerParams& server);
virtual void decodeRect(const Rect& r, const void* buffer,
size_t buflen, const ConnParams& cp,
size_t buflen, const ServerParams& server,
ModifiablePixelBuffer* pb);

private:

+ 4
- 4
common/rfb/ZRLEDecoder.cxx View File

@@ -21,7 +21,7 @@
#include <rdr/MemInStream.h>
#include <rdr/OutStream.h>

#include <rfb/ConnParams.h>
#include <rfb/ServerParams.h>
#include <rfb/PixelBuffer.h>
#include <rfb/ZRLEDecoder.h>

@@ -72,7 +72,7 @@ ZRLEDecoder::~ZRLEDecoder()
}

void ZRLEDecoder::readRect(const Rect& r, rdr::InStream* is,
const ConnParams& cp, rdr::OutStream* os)
const ServerParams& server, rdr::OutStream* os)
{
rdr::U32 len;

@@ -82,11 +82,11 @@ void ZRLEDecoder::readRect(const Rect& r, rdr::InStream* is,
}

void ZRLEDecoder::decodeRect(const Rect& r, const void* buffer,
size_t buflen, const ConnParams& cp,
size_t buflen, const ServerParams& server,
ModifiablePixelBuffer* pb)
{
rdr::MemInStream is(buffer, buflen);
const rfb::PixelFormat& pf = cp.pf();
const rfb::PixelFormat& pf = server.pf();
switch (pf.bpp) {
case 8: zrleDecode8 (r, &is, &zis, pf, pb); break;
case 16: zrleDecode16(r, &is, &zis, pf, pb); break;

+ 2
- 2
common/rfb/ZRLEDecoder.h View File

@@ -28,9 +28,9 @@ namespace rfb {
ZRLEDecoder();
virtual ~ZRLEDecoder();
virtual void readRect(const Rect& r, rdr::InStream* is,
const ConnParams& cp, rdr::OutStream* os);
const ServerParams& server, rdr::OutStream* os);
virtual void decodeRect(const Rect& r, const void* buffer,
size_t buflen, const ConnParams& cp,
size_t buflen, const ServerParams& server,
ModifiablePixelBuffer* pb);
private:
rdr::ZlibInStream zis;

+ 3
- 1
tests/decperf.cxx View File

@@ -85,7 +85,9 @@ void CConn::setDesktopSize(int w, int h)
{
CConnection::setDesktopSize(w, h);

setFramebuffer(new rfb::ManagedPixelBuffer(filePF, cp.width(), cp.height()));
setFramebuffer(new rfb::ManagedPixelBuffer(filePF,
server.width(),
server.height()));
}

void CConn::setPixelFormat(const rfb::PixelFormat& pf)

+ 2
- 2
tests/encperf.cxx View File

@@ -202,8 +202,8 @@ void CConn::setDesktopSize(int w, int h)

CConnection::setDesktopSize(w, h);

pb = new rfb::ManagedPixelBuffer((bool)translate ? fbPF : cp.pf(),
cp.width(), cp.height());
pb = new rfb::ManagedPixelBuffer((bool)translate ? fbPF : server.pf(),
server.width(), server.height());
setFramebuffer(pb);
}


+ 38
- 34
vncviewer/CConn.cxx View File

@@ -89,23 +89,23 @@ CConn::CConn(const char* vncServerName, network::Socket* socket=NULL)
if (encNum != -1)
currentEncoding = encNum;

cp.supportsLocalCursor = true;
server.supportsLocalCursor = true;

cp.supportsDesktopResize = true;
cp.supportsExtendedDesktopSize = true;
cp.supportsDesktopRename = true;
server.supportsDesktopResize = true;
server.supportsExtendedDesktopSize = true;
server.supportsDesktopRename = true;

cp.supportsLEDState = true;
server.supportsLEDState = true;

if (customCompressLevel)
cp.compressLevel = compressLevel;
server.compressLevel = compressLevel;
else
cp.compressLevel = -1;
server.compressLevel = -1;

if (!noJpeg)
cp.qualityLevel = qualityLevel;
server.qualityLevel = qualityLevel;
else
cp.qualityLevel = -1;
server.qualityLevel = -1;

if(sock == NULL) {
try {
@@ -181,7 +181,7 @@ const char *CConn::connectionInfo()
infoText[0] = '\0';

snprintf(scratch, sizeof(scratch),
_("Desktop name: %.80s"), cp.name());
_("Desktop name: %.80s"), server.name());
strcat(infoText, scratch);
strcat(infoText, "\n");

@@ -191,13 +191,13 @@ const char *CConn::connectionInfo()
strcat(infoText, "\n");

snprintf(scratch, sizeof(scratch),
_("Size: %d x %d"), cp.width(), cp.height());
_("Size: %d x %d"), server.width(), server.height());
strcat(infoText, scratch);
strcat(infoText, "\n");

// TRANSLATORS: Will be filled in with a string describing the
// protocol pixel format in a fairly language neutral way
cp.pf().print(pfStr, 100);
server.pf().print(pfStr, 100);
snprintf(scratch, sizeof(scratch),
_("Pixel format: %s"), pfStr);
strcat(infoText, scratch);
@@ -226,7 +226,7 @@ const char *CConn::connectionInfo()
strcat(infoText, "\n");

snprintf(scratch, sizeof(scratch),
_("Protocol version: %d.%d"), cp.majorVersion, cp.minorVersion);
_("Protocol version: %d.%d"), server.majorVersion, server.minorVersion);
strcat(infoText, scratch);
strcat(infoText, "\n");

@@ -319,13 +319,13 @@ void CConn::serverInit()

// If using AutoSelect with old servers, start in FullColor
// mode. See comment in autoSelectFormatAndEncoding.
if (cp.beforeVersion(3, 8) && autoSelect)
if (server.beforeVersion(3, 8) && autoSelect)
fullColour.setParam(true);

serverPF = cp.pf();
serverPF = server.pf();

desktop = new DesktopWindow(cp.width(), cp.height(),
cp.name(), serverPF, this);
desktop = new DesktopWindow(server.width(), server.height(),
server.name(), serverPF, this);
fullColourPF = desktop->getPreferredPF();

// Force a switch to the format and encoding we'd like
@@ -337,7 +337,7 @@ void CConn::serverInit()
// This initial update request is a bit of a corner case, so we need
// to help out setting the correct format here.
assert(pendingPFChange);
cp.setPF(pendingPF);
server.setPF(pendingPF);
pendingPFChange = false;
}

@@ -404,7 +404,7 @@ void CConn::framebufferUpdateEnd()
if (firstUpdate) {
// We need fences to make extra update requests and continuous
// updates "safe". See fence() for the next step.
if (cp.supportsFence)
if (server.supportsFence)
writer()->writeFence(fenceFlagRequest | fenceFlagSyncNext, 0, NULL);

firstUpdate = false;
@@ -413,7 +413,7 @@ void CConn::framebufferUpdateEnd()
// A format change has been scheduled and we are now past the update
// with the old format. Time to active the new one.
if (pendingPFChange) {
cp.setPF(pendingPF);
server.setPF(pendingPF);
pendingPFChange = false;
}

@@ -476,11 +476,12 @@ void CConn::fence(rdr::U32 flags, unsigned len, const char data[])
if (flags & fenceFlagSyncNext) {
supportsSyncFence = true;

if (cp.supportsContinuousUpdates) {
if (server.supportsContinuousUpdates) {
vlog.info(_("Enabling continuous updates"));
continuousUpdates = true;
writer()->writeEnableContinuousUpdates(true, 0, 0,
cp.width(), cp.height());
server.width(),
server.height());
}
}
} else {
@@ -490,7 +491,7 @@ void CConn::fence(rdr::U32 flags, unsigned len, const char data[])

pf.read(&memStream);

cp.setPF(pf);
server.setPF(pf);
}
}

@@ -511,9 +512,10 @@ void CConn::resizeFramebuffer()

if (continuousUpdates)
writer()->writeEnableContinuousUpdates(true, 0, 0,
cp.width(), cp.height());
server.width(),
server.height());

desktop->resizeFramebuffer(cp.width(), cp.height());
desktop->resizeFramebuffer(server.width(), server.height());
}

// autoSelectFormatAndEncoding() chooses the format and encoding appropriate
@@ -558,13 +560,13 @@ void CConn::autoSelectFormatAndEncoding()
if (newQualityLevel != qualityLevel) {
vlog.info(_("Throughput %d kbit/s - changing to quality %d"),
kbitsPerSecond, newQualityLevel);
cp.qualityLevel = newQualityLevel;
server.qualityLevel = newQualityLevel;
qualityLevel.setParam(newQualityLevel);
encodingChange = true;
}
}

if (cp.beforeVersion(3, 8)) {
if (server.beforeVersion(3, 8)) {
// Xvnc from TightVNC 1.2.9 sends out FramebufferUpdates with
// cursors "asynchronously". If this happens in the middle of a
// pixel format change, the server will encode the cursor with
@@ -650,7 +652,9 @@ void CConn::requestNewUpdate()

if (forceNonincremental || !continuousUpdates) {
pendingUpdate = true;
writer()->writeFramebufferUpdateRequest(Rect(0, 0, cp.width(), cp.height()),
writer()->writeFramebufferUpdateRequest(Rect(0, 0,
server.width(),
server.height()),
!forceNonincremental);
}
@@ -672,17 +676,17 @@ void CConn::handleOptions(void *data)
self->currentEncoding = encNum;
}

self->cp.supportsLocalCursor = true;
self->server.supportsLocalCursor = true;

if (customCompressLevel)
self->cp.compressLevel = compressLevel;
self->server.compressLevel = compressLevel;
else
self->cp.compressLevel = -1;
self->server.compressLevel = -1;

if (!noJpeg && !autoSelect)
self->cp.qualityLevel = qualityLevel;
self->server.qualityLevel = qualityLevel;
else
self->cp.qualityLevel = -1;
self->server.qualityLevel = -1;

self->encodingChange = true;

@@ -702,7 +706,7 @@ void CConn::handleOptions(void *data)
pf = mediumColourPF;
}

if (!pf.equal(self->cp.pf())) {
if (!pf.equal(self->server.pf())) {
self->formatChange = true;

// Without fences, we cannot safely trigger an update request directly

+ 13
- 13
vncviewer/DesktopWindow.cxx View File

@@ -235,7 +235,7 @@ void DesktopWindow::setName(const char *name)
void DesktopWindow::updateWindow()
{
if (firstUpdate) {
if (cc->cp.supportsSetDesktopSize) {
if (cc->server.supportsSetDesktopSize) {
// Hack: Wait until we're in the proper mode and position until
// resizing things, otherwise we might send the wrong thing.
if (delayedFullscreen)
@@ -487,7 +487,7 @@ void DesktopWindow::resize(int x, int y, int w, int h)
// d) We're not still waiting for startup fullscreen to kick in
//
if (not firstUpdate and not delayedFullscreen and
::remoteResize and cc->cp.supportsSetDesktopSize) {
::remoteResize and cc->server.supportsSetDesktopSize) {
// We delay updating the remote desktop as we tend to get a flood
// of resize events as the user is dragging the window.
Fl::remove_timeout(handleResizeTimeout, this);
@@ -1021,7 +1021,7 @@ void DesktopWindow::remoteResize(int width, int height)
// to scroll) we just report a single virtual screen that covers
// the entire framebuffer.

layout = cc->cp.screenLayout();
layout = cc->server.screenLayout();

// Not sure why we have no screens, but adding a new one should be
// safe as there is nothing to conflict with...
@@ -1077,8 +1077,8 @@ void DesktopWindow::remoteResize(int width, int height)
sy -= viewport_rect.tl.y;

// Look for perfectly matching existing screen...
for (iter = cc->cp.screenLayout().begin();
iter != cc->cp.screenLayout().end(); ++iter) {
for (iter = cc->server.screenLayout().begin();
iter != cc->server.screenLayout().end(); ++iter) {
if ((iter->dimensions.tl.x == sx) &&
(iter->dimensions.tl.y == sy) &&
(iter->dimensions.width() == sw) &&
@@ -1087,7 +1087,7 @@ void DesktopWindow::remoteResize(int width, int height)
}

// Found it?
if (iter != cc->cp.screenLayout().end()) {
if (iter != cc->server.screenLayout().end()) {
layout.add_screen(*iter);
continue;
}
@@ -1095,13 +1095,13 @@ void DesktopWindow::remoteResize(int width, int height)
// Need to add a new one, which means we need to find an unused id
while (true) {
id = rand();
for (iter = cc->cp.screenLayout().begin();
iter != cc->cp.screenLayout().end(); ++iter) {
for (iter = cc->server.screenLayout().begin();
iter != cc->server.screenLayout().end(); ++iter) {
if (iter->id == id)
break;
}

if (iter == cc->cp.screenLayout().end())
if (iter == cc->server.screenLayout().end())
break;
}

@@ -1115,14 +1115,14 @@ void DesktopWindow::remoteResize(int width, int height)
}

// Do we actually change anything?
if ((width == cc->cp.width()) &&
(height == cc->cp.height()) &&
(layout == cc->cp.screenLayout()))
if ((width == cc->server.width()) &&
(height == cc->server.height()) &&
(layout == cc->server.screenLayout()))
return;

char buffer[2048];
vlog.debug("Requesting framebuffer resize from %dx%d to %dx%d",
cc->cp.width(), cc->cp.height(), width, height);
cc->server.width(), cc->server.height(), width, height);
layout.print(buffer, sizeof(buffer));
vlog.debug("%s", buffer);


+ 5
- 5
vncviewer/Viewport.cxx View File

@@ -425,7 +425,7 @@ void Viewport::pushLEDState()
unsigned int state;

// Server support?
if (cc->cp.ledState() == ledUnknown)
if (cc->server.ledState() == ledUnknown)
return;

state = 0;
@@ -458,7 +458,7 @@ void Viewport::pushLEDState()
state |= ledNumLock;

// No support for Scroll Lock //
state |= (cc->cp.ledState() & ledScrollLock);
state |= (cc->server.ledState() & ledScrollLock);

#else
unsigned int mask;
@@ -484,17 +484,17 @@ void Viewport::pushLEDState()
state |= ledScrollLock;
#endif

if ((state & ledCapsLock) != (cc->cp.ledState() & ledCapsLock)) {
if ((state & ledCapsLock) != (cc->server.ledState() & ledCapsLock)) {
vlog.debug("Inserting fake CapsLock to get in sync with server");
handleKeyPress(0x3a, XK_Caps_Lock);
handleKeyRelease(0x3a);
}
if ((state & ledNumLock) != (cc->cp.ledState() & ledNumLock)) {
if ((state & ledNumLock) != (cc->server.ledState() & ledNumLock)) {
vlog.debug("Inserting fake NumLock to get in sync with server");
handleKeyPress(0x45, XK_Num_Lock);
handleKeyRelease(0x45);
}
if ((state & ledScrollLock) != (cc->cp.ledState() & ledScrollLock)) {
if ((state & ledScrollLock) != (cc->server.ledState() & ledScrollLock)) {
vlog.debug("Inserting fake ScrollLock to get in sync with server");
handleKeyPress(0x46, XK_Scroll_Lock);
handleKeyRelease(0x46);

Loading…
Cancel
Save