aboutsummaryrefslogtreecommitdiffstats
path: root/common/rfb
diff options
context:
space:
mode:
authorPierre Ossman <ossman@cendio.se>2023-03-02 11:09:57 +0100
committerPierre Ossman <ossman@cendio.se>2023-03-02 11:09:57 +0100
commit15a0da6157d5d34362e68591124324ba5a77ad66 (patch)
treeeb5aa106e2b64fd5845d4a38370383ca0181814c /common/rfb
parentcbed625888eb1ef87272dac39472b67dccf677b4 (diff)
parent4c9b0ba913e77d295e8047181fc7fe0d029a27a7 (diff)
downloadtigervnc-15a0da6157d5d34362e68591124324ba5a77ad66.tar.gz
tigervnc-15a0da6157d5d34362e68591124324ba5a77ad66.zip
Merge branch 'types' of https://github.com/CendioOssman/tigervnc
Diffstat (limited to 'common/rfb')
-rw-r--r--common/rfb/Blacklist.cxx13
-rw-r--r--common/rfb/Blacklist.h9
-rw-r--r--common/rfb/CConnection.cxx77
-rw-r--r--common/rfb/CConnection.h24
-rw-r--r--common/rfb/CMakeLists.txt2
-rw-r--r--common/rfb/CMsgHandler.cxx18
-rw-r--r--common/rfb/CMsgHandler.h22
-rw-r--r--common/rfb/CMsgReader.cxx152
-rw-r--r--common/rfb/CMsgReader.h6
-rw-r--r--common/rfb/CMsgWriter.cxx22
-rw-r--r--common/rfb/CMsgWriter.h20
-rw-r--r--common/rfb/CSecurityDH.cxx53
-rw-r--r--common/rfb/CSecurityMSLogonII.cxx41
-rw-r--r--common/rfb/CSecurityPlain.cxx15
-rw-r--r--common/rfb/CSecurityRSAAES.cxx115
-rw-r--r--common/rfb/CSecurityRSAAES.h22
-rw-r--r--common/rfb/CSecurityTLS.cxx119
-rw-r--r--common/rfb/CSecurityTLS.h2
-rw-r--r--common/rfb/CSecurityVeNCrypt.cxx11
-rw-r--r--common/rfb/CSecurityVeNCrypt.h11
-rw-r--r--common/rfb/CSecurityVncAuth.cxx15
-rw-r--r--common/rfb/ClientParams.cxx14
-rw-r--r--common/rfb/ClientParams.h24
-rw-r--r--common/rfb/ComparingUpdateTracker.cxx46
-rw-r--r--common/rfb/Configuration.cxx111
-rw-r--r--common/rfb/Configuration.h57
-rw-r--r--common/rfb/Congestion.cxx1
-rw-r--r--common/rfb/Cursor.cxx73
-rw-r--r--common/rfb/Cursor.h16
-rw-r--r--common/rfb/DecodeManager.cxx23
-rw-r--r--common/rfb/EncodeManager.cxx161
-rw-r--r--common/rfb/EncodeManager.h34
-rw-r--r--common/rfb/EncodeManagerBPP.cxx98
-rw-r--r--common/rfb/Encoder.cxx24
-rw-r--r--common/rfb/Encoder.h5
-rw-r--r--common/rfb/H264Decoder.cxx8
-rw-r--r--common/rfb/H264DecoderContext.h9
-rw-r--r--common/rfb/H264LibavDecoderContext.cxx14
-rw-r--r--common/rfb/H264LibavDecoderContext.h8
-rw-r--r--common/rfb/H264WinDecoderContext.cxx10
-rw-r--r--common/rfb/H264WinDecoderContext.h16
-rw-r--r--common/rfb/HextileDecoder.cxx102
-rw-r--r--common/rfb/HextileDecoder.h10
-rw-r--r--common/rfb/HextileEncoder.cxx524
-rw-r--r--common/rfb/HextileEncoder.h18
-rw-r--r--common/rfb/Hostname.h16
-rw-r--r--common/rfb/InputHandler.h6
-rw-r--r--common/rfb/JpegCompressor.cxx18
-rw-r--r--common/rfb/JpegCompressor.h2
-rw-r--r--common/rfb/JpegDecompressor.cxx20
-rw-r--r--common/rfb/JpegDecompressor.h2
-rw-r--r--common/rfb/KeyRemapper.cxx7
-rw-r--r--common/rfb/KeyRemapper.h7
-rw-r--r--common/rfb/LogWriter.cxx32
-rw-r--r--common/rfb/Logger.cxx1
-rw-r--r--common/rfb/Logger_file.cxx35
-rw-r--r--common/rfb/Logger_file.h4
-rw-r--r--common/rfb/Logger_syslog.cxx1
-rw-r--r--common/rfb/Palette.h21
-rw-r--r--common/rfb/Password.h47
-rw-r--r--common/rfb/PixelBuffer.cxx54
-rw-r--r--common/rfb/PixelBuffer.h18
-rw-r--r--common/rfb/PixelFormat.cxx234
-rw-r--r--common/rfb/PixelFormat.h71
-rw-r--r--common/rfb/PixelFormat.inl16
-rw-r--r--common/rfb/PixelFormatBPP.cxx155
-rw-r--r--common/rfb/RREDecoder.cxx54
-rw-r--r--common/rfb/RREDecoder.h9
-rw-r--r--common/rfb/RREEncoder.cxx114
-rw-r--r--common/rfb/RREEncoder.h9
-rw-r--r--common/rfb/RawEncoder.cxx4
-rw-r--r--common/rfb/RawEncoder.h2
-rw-r--r--common/rfb/Rect.h30
-rw-r--r--common/rfb/Region.cxx6
-rw-r--r--common/rfb/Region.h14
-rw-r--r--common/rfb/SConnection.cxx66
-rw-r--r--common/rfb/SConnection.h25
-rw-r--r--common/rfb/SDesktop.h8
-rw-r--r--common/rfb/SMsgHandler.cxx18
-rw-r--r--common/rfb/SMsgHandler.h19
-rw-r--r--common/rfb/SMsgReader.cxx50
-rw-r--r--common/rfb/SMsgReader.h4
-rw-r--r--common/rfb/SMsgWriter.cxx56
-rw-r--r--common/rfb/SMsgWriter.h37
-rw-r--r--common/rfb/SSecurity.h3
-rw-r--r--common/rfb/SSecurityPlain.cxx45
-rw-r--r--common/rfb/SSecurityPlain.h8
-rw-r--r--common/rfb/SSecurityRSAAES.cxx137
-rw-r--r--common/rfb/SSecurityRSAAES.h28
-rw-r--r--common/rfb/SSecurityTLS.cxx8
-rw-r--r--common/rfb/SSecurityTLS.h1
-rw-r--r--common/rfb/SSecurityVeNCrypt.cxx12
-rw-r--r--common/rfb/SSecurityVeNCrypt.h4
-rw-r--r--common/rfb/SSecurityVncAuth.cxx56
-rw-r--r--common/rfb/SSecurityVncAuth.h14
-rw-r--r--common/rfb/ScreenSet.h14
-rw-r--r--common/rfb/Security.cxx45
-rw-r--r--common/rfb/Security.h59
-rw-r--r--common/rfb/SecurityClient.cxx2
-rw-r--r--common/rfb/SecurityClient.h2
-rw-r--r--common/rfb/SecurityServer.cxx2
-rw-r--r--common/rfb/SecurityServer.h2
-rw-r--r--common/rfb/ServerCore.cxx1
-rw-r--r--common/rfb/ServerCore.h1
-rw-r--r--common/rfb/ServerParams.cxx10
-rw-r--r--common/rfb/ServerParams.h16
-rw-r--r--common/rfb/TightDecoder.cxx231
-rw-r--r--common/rfb/TightDecoder.h26
-rw-r--r--common/rfb/TightEncoder.cxx179
-rw-r--r--common/rfb/TightEncoder.h26
-rw-r--r--common/rfb/TightEncoderBPP.cxx165
-rw-r--r--common/rfb/TightJPEGEncoder.cxx8
-rw-r--r--common/rfb/TightJPEGEncoder.h4
-rw-r--r--common/rfb/UnixPasswordValidator.cxx3
-rw-r--r--common/rfb/UserPasswdGetter.h10
-rw-r--r--common/rfb/VNCSConnectionST.cxx33
-rw-r--r--common/rfb/VNCSConnectionST.h18
-rw-r--r--common/rfb/VNCServer.h2
-rw-r--r--common/rfb/VNCServerST.cxx36
-rw-r--r--common/rfb/VNCServerST.h8
-rw-r--r--common/rfb/WinPasswdValidator.cxx10
-rw-r--r--common/rfb/ZRLEDecoder.cxx246
-rw-r--r--common/rfb/ZRLEDecoder.h10
-rw-r--r--common/rfb/ZRLEEncoder.cxx162
-rw-r--r--common/rfb/ZRLEEncoder.h28
-rw-r--r--common/rfb/ZRLEEncoderBPP.cxx128
-rw-r--r--common/rfb/encodings.cxx1
-rw-r--r--common/rfb/fenceTypes.h12
-rw-r--r--common/rfb/hextileDecode.h111
-rw-r--r--common/rfb/hextileEncode.h223
-rw-r--r--common/rfb/hextileEncodeBetter.h346
-rw-r--r--common/rfb/obfuscate.cxx (renamed from common/rfb/Password.cxx)65
-rw-r--r--common/rfb/obfuscate.h (renamed from common/rfb/Pixel.h)17
-rw-r--r--common/rfb/rreDecode.h64
-rw-r--r--common/rfb/rreEncode.h124
-rw-r--r--common/rfb/tightDecode.h187
-rw-r--r--common/rfb/util.cxx318
-rw-r--r--common/rfb/util.h89
-rw-r--r--common/rfb/zrleDecode.h196
139 files changed, 3229 insertions, 3794 deletions
diff --git a/common/rfb/Blacklist.cxx b/common/rfb/Blacklist.cxx
index f052eafb..12a54c45 100644
--- a/common/rfb/Blacklist.cxx
+++ b/common/rfb/Blacklist.cxx
@@ -45,11 +45,6 @@ Blacklist::Blacklist() {
}
Blacklist::~Blacklist() {
- // Free the map keys
- BlacklistMap::iterator i;
- for (i=blm.begin(); i!=blm.end(); i++) {
- strFree((char*)(*i).first);
- }
}
bool Blacklist::isBlackmarked(const char* name) {
@@ -65,7 +60,7 @@ bool Blacklist::isBlackmarked(const char* name) {
bi.marks = 1;
bi.blockUntil = 0;
bi.blockTimeout = initialTimeout;
- blm[strDup(name)] = bi;
+ blm[name] = bi;
i = blm.find(name);
}
@@ -92,9 +87,5 @@ bool Blacklist::isBlackmarked(const char* name) {
}
void Blacklist::clearBlackmark(const char* name) {
- BlacklistMap::iterator i = blm.find(name);
- if (i != blm.end()) {
- strFree((char*)(*i).first);
- blm.erase(i);
- }
+ blm.erase(name);
}
diff --git a/common/rfb/Blacklist.h b/common/rfb/Blacklist.h
index 45e36a0e..c1699f29 100644
--- a/common/rfb/Blacklist.h
+++ b/common/rfb/Blacklist.h
@@ -30,9 +30,9 @@
#include <string.h>
#include <time.h>
#include <map>
+#include <string>
#include <rfb/Configuration.h>
-#include <rfb/util.h>
namespace rfb {
@@ -68,17 +68,12 @@ namespace rfb {
void clearBlackmark(const char* name);
protected:
- struct ltStr {
- bool operator()(const char* s1, const char* s2) const {
- return strcmp(s1, s2) < 0;
- };
- };
struct BlacklistInfo {
int marks;
time_t blockUntil;
unsigned int blockTimeout;
};
- typedef std::map<const char*,BlacklistInfo,ltStr> BlacklistMap;
+ typedef std::map<std::string,BlacklistInfo> BlacklistMap;
BlacklistMap blm;
};
diff --git a/common/rfb/CConnection.cxx b/common/rfb/CConnection.cxx
index 27942764..521649ac 100644
--- a/common/rfb/CConnection.cxx
+++ b/common/rfb/CConnection.cxx
@@ -52,14 +52,14 @@ CConnection::CConnection()
supportsDesktopResize(false), supportsLEDState(false),
is(0), os(0), reader_(0), writer_(0),
shared(false),
- state_(RFBSTATE_UNINITIALISED), serverName(strDup("")),
+ state_(RFBSTATE_UNINITIALISED),
pendingPFChange(false), preferredEncoding(encodingTight),
compressLevel(2), qualityLevel(-1),
formatChange(false), encodingChange(false),
firstUpdate(true), pendingUpdate(false), continuousUpdates(false),
forceNonincremental(true),
framebuffer(NULL), decoder(this),
- serverClipboard(NULL), hasLocalClipboard(false)
+ hasRemoteClipboard(false), hasLocalClipboard(false)
{
}
@@ -72,7 +72,7 @@ void CConnection::setServerName(const char* name_)
{
if (name_ == NULL)
name_ = "";
- serverName.replaceBuf(strDup(name_));
+ serverName = name_;
}
void CConnection::setStreams(rdr::InStream* is_, rdr::OutStream* os_)
@@ -93,10 +93,10 @@ void CConnection::setFramebuffer(ModifiablePixelBuffer* fb)
if ((framebuffer != NULL) && (fb != NULL)) {
Rect rect;
- const rdr::U8* data;
+ const uint8_t* data;
int stride;
- const rdr::U8 black[4] = { 0, 0, 0, 0 };
+ const uint8_t black[4] = { 0, 0, 0, 0 };
// Copy still valid area
@@ -210,7 +210,7 @@ bool CConnection::processSecurityTypesMsg()
int secType = secTypeInvalid;
- std::list<rdr::U8> secTypes;
+ std::list<uint8_t> secTypes;
secTypes = security.GetEnabledSecTypes();
if (server.isVersion(3,3)) {
@@ -225,7 +225,7 @@ bool CConnection::processSecurityTypesMsg()
state_ = RFBSTATE_SECURITY_REASON;
return true;
} else if (secType == secTypeNone || secType == secTypeVncAuth) {
- std::list<rdr::U8>::iterator i;
+ std::list<uint8_t>::iterator i;
for (i = secTypes.begin(); i != secTypes.end(); i++)
if (*i == secType) {
secType = *i;
@@ -259,10 +259,10 @@ bool CConnection::processSecurityTypesMsg()
return true;
}
- std::list<rdr::U8>::iterator j;
+ std::list<uint8_t>::iterator j;
for (int i = 0; i < nServerSecTypes; i++) {
- rdr::U8 serverSecType = is->readU8();
+ uint8_t serverSecType = is->readU8();
vlog.debug("Server offers security type %s(%d)",
secTypeName(serverSecType), serverSecType);
@@ -355,17 +355,17 @@ bool CConnection::processSecurityReasonMsg()
is->setRestorePoint();
- rdr::U32 len = is->readU32();
+ uint32_t len = is->readU32();
if (!is->hasDataOrRestore(len))
return false;
is->clearRestorePoint();
- CharArray reason(len + 1);
- is->readBytes(reason.buf, len);
- reason.buf[len] = '\0';
+ std::vector<char> reason(len + 1);
+ is->readBytes(reason.data(), len);
+ reason[len] = '\0';
state_ = RFBSTATE_INVALID;
- throw AuthFailureException(reason.buf);
+ throw AuthFailureException(reason.data());
}
bool CConnection::processInitMsg()
@@ -405,8 +405,6 @@ void CConnection::close()
reader_ = NULL;
delete writer_;
writer_ = NULL;
- strFree(serverClipboard);
- serverClipboard = NULL;
}
void CConnection::setDesktopSize(int w, int h)
@@ -545,18 +543,16 @@ void CConnection::serverCutText(const char* str)
{
hasLocalClipboard = false;
- strFree(serverClipboard);
- serverClipboard = NULL;
-
serverClipboard = latin1ToUTF8(str);
+ hasRemoteClipboard = true;
handleClipboardAnnounce(true);
}
-void CConnection::handleClipboardCaps(rdr::U32 flags,
- const rdr::U32* lengths)
+void CConnection::handleClipboardCaps(uint32_t flags,
+ const uint32_t* lengths)
{
- rdr::U32 sizes[] = { 0 };
+ uint32_t sizes[] = { 0 };
CMsgHandler::handleClipboardCaps(flags, lengths);
@@ -568,7 +564,7 @@ void CConnection::handleClipboardCaps(rdr::U32 flags,
sizes);
}
-void CConnection::handleClipboardRequest(rdr::U32 flags)
+void CConnection::handleClipboardRequest(uint32_t flags)
{
if (!(flags & rfb::clipboardUTF8)) {
vlog.debug("Ignoring clipboard request for unsupported formats 0x%x", flags);
@@ -587,10 +583,9 @@ void CConnection::handleClipboardPeek()
writer()->writeClipboardNotify(hasLocalClipboard ? rfb::clipboardUTF8 : 0);
}
-void CConnection::handleClipboardNotify(rdr::U32 flags)
+void CConnection::handleClipboardNotify(uint32_t flags)
{
- strFree(serverClipboard);
- serverClipboard = NULL;
+ hasRemoteClipboard = false;
if (flags & rfb::clipboardUTF8) {
hasLocalClipboard = false;
@@ -600,22 +595,20 @@ void CConnection::handleClipboardNotify(rdr::U32 flags)
}
}
-void CConnection::handleClipboardProvide(rdr::U32 flags,
+void CConnection::handleClipboardProvide(uint32_t flags,
const size_t* lengths,
- const rdr::U8* const* data)
+ const uint8_t* const* data)
{
if (!(flags & rfb::clipboardUTF8)) {
vlog.debug("Ignoring clipboard provide with unsupported formats 0x%x", flags);
return;
}
- strFree(serverClipboard);
- serverClipboard = NULL;
-
serverClipboard = convertLF((const char*)data[0], lengths[0]);
+ hasRemoteClipboard = true;
// FIXME: Should probably verify that this data was actually requested
- handleClipboardData(serverClipboard);
+ handleClipboardData(serverClipboard.c_str());
}
void CConnection::authSuccess()
@@ -645,8 +638,8 @@ void CConnection::handleClipboardData(const char* /*data*/)
void CConnection::requestClipboard()
{
- if (serverClipboard != NULL) {
- handleClipboardData(serverClipboard);
+ if (hasRemoteClipboard) {
+ handleClipboardData(serverClipboard.c_str());
return;
}
@@ -681,9 +674,9 @@ void CConnection::announceClipboard(bool available)
void CConnection::sendClipboardData(const char* data)
{
if (server.clipboardFlags() & rfb::clipboardProvide) {
- CharArray filtered(convertCRLF(data));
- size_t sizes[1] = { strlen(filtered.buf) + 1 };
- const rdr::U8* data[1] = { (const rdr::U8*)filtered.buf };
+ std::string filtered(convertCRLF(data));
+ size_t sizes[1] = { filtered.size() + 1 };
+ const uint8_t* data[1] = { (const uint8_t*)filtered.c_str() };
if (unsolicitedClipboardAttempt) {
unsolicitedClipboardAttempt = false;
@@ -697,9 +690,9 @@ void CConnection::sendClipboardData(const char* data)
writer()->writeClipboardProvide(rfb::clipboardUTF8, sizes, data);
} else {
- CharArray latin1(utf8ToLatin1(data));
+ std::string latin1(utf8ToLatin1(data));
- writer()->writeClientCutText(latin1.buf);
+ writer()->writeClientCutText(latin1.c_str());
}
}
@@ -747,14 +740,14 @@ void CConnection::setQualityLevel(int level)
void CConnection::setPF(const PixelFormat& pf)
{
- if (server.pf().equal(pf) && !formatChange)
+ if (server.pf() == pf && !formatChange)
return;
nextPF = pf;
formatChange = true;
}
-void CConnection::fence(rdr::U32 flags, unsigned len, const char data[])
+void CConnection::fence(uint32_t flags, unsigned len, const char data[])
{
CMsgHandler::fence(flags, len, data);
@@ -819,7 +812,7 @@ void CConnection::requestNewUpdate()
void CConnection::updateEncodings()
{
- std::list<rdr::U32> encodings;
+ std::list<uint32_t> encodings;
if (supportsLocalCursor) {
encodings.push_back(pseudoEncodingCursorWithAlpha);
diff --git a/common/rfb/CConnection.h b/common/rfb/CConnection.h
index f6818628..71da175e 100644
--- a/common/rfb/CConnection.h
+++ b/common/rfb/CConnection.h
@@ -24,10 +24,11 @@
#ifndef __RFB_CCONNECTION_H__
#define __RFB_CCONNECTION_H__
+#include <string>
+
#include <rfb/CMsgHandler.h>
#include <rfb/DecodeManager.h>
#include <rfb/SecurityClient.h>
-#include <rfb/util.h>
namespace rfb {
@@ -116,14 +117,14 @@ namespace rfb {
virtual void serverCutText(const char* str);
- virtual void handleClipboardCaps(rdr::U32 flags,
- const rdr::U32* lengths);
- virtual void handleClipboardRequest(rdr::U32 flags);
+ virtual void handleClipboardCaps(uint32_t flags,
+ const uint32_t* lengths);
+ virtual void handleClipboardRequest(uint32_t flags);
virtual void handleClipboardPeek();
- virtual void handleClipboardNotify(rdr::U32 flags);
- virtual void handleClipboardProvide(rdr::U32 flags,
+ virtual void handleClipboardNotify(uint32_t flags);
+ virtual void handleClipboardProvide(uint32_t flags,
const size_t* lengths,
- const rdr::U8* const* data);
+ const uint8_t* const* data);
// Methods to be overridden in a derived class
@@ -206,7 +207,7 @@ namespace rfb {
// Access method used by SSecurity implementations that can verify servers'
// Identities, to determine the unique(ish) name of the server.
- const char* getServerName() const { return serverName.buf; }
+ const char* getServerName() const { return serverName.c_str(); }
bool isSecure() const { return csecurity ? csecurity->isSecure() : false; }
@@ -248,7 +249,7 @@ namespace rfb {
// responds to requests, stating no support for synchronisation.
// When overriding, call CMsgHandler::fence() directly in order to
// state correct support for fence flags.
- virtual void fence(rdr::U32 flags, unsigned len, const char data[]);
+ virtual void fence(uint32_t flags, unsigned len, const char data[]);
private:
bool processVersionMsg();
@@ -271,7 +272,7 @@ namespace rfb {
bool shared;
stateEnum state_;
- CharArray serverName;
+ std::string serverName;
bool pendingPFChange;
rfb::PixelFormat pendingPF;
@@ -293,7 +294,8 @@ namespace rfb {
ModifiablePixelBuffer* framebuffer;
DecodeManager decoder;
- char* serverClipboard;
+ std::string serverClipboard;
+ bool hasRemoteClipboard;
bool hasLocalClipboard;
bool unsolicitedClipboardAttempt;
};
diff --git a/common/rfb/CMakeLists.txt b/common/rfb/CMakeLists.txt
index e18cff34..85cdc2db 100644
--- a/common/rfb/CMakeLists.txt
+++ b/common/rfb/CMakeLists.txt
@@ -32,7 +32,6 @@ add_library(rfb STATIC
Logger.cxx
Logger_file.cxx
Logger_stdio.cxx
- Password.cxx
PixelBuffer.cxx
PixelFormat.cxx
RREEncoder.cxx
@@ -64,6 +63,7 @@ add_library(rfb STATIC
ZRLEEncoder.cxx
ZRLEDecoder.cxx
encodings.cxx
+ obfuscate.cxx
util.cxx)
target_link_libraries(rfb os rdr)
diff --git a/common/rfb/CMsgHandler.cxx b/common/rfb/CMsgHandler.cxx
index f4f785b2..e37811f9 100644
--- a/common/rfb/CMsgHandler.cxx
+++ b/common/rfb/CMsgHandler.cxx
@@ -28,6 +28,7 @@
#include <rfb/CMsgHandler.h>
#include <rfb/clipboardTypes.h>
#include <rfb/screenTypes.h>
+#include <rfb/util.h>
static rfb::LogWriter vlog("CMsgHandler");
@@ -68,7 +69,7 @@ void CMsgHandler::setName(const char* name)
server.setName(name);
}
-void CMsgHandler::fence(rdr::U32 /*flags*/, unsigned /*len*/,
+void CMsgHandler::fence(uint32_t /*flags*/, unsigned /*len*/,
const char /*data*/ [])
{
server.supportsFence = true;
@@ -106,7 +107,7 @@ void CMsgHandler::setLEDState(unsigned int state)
server.setLEDState(state);
}
-void CMsgHandler::handleClipboardCaps(rdr::U32 flags, const rdr::U32* lengths)
+void CMsgHandler::handleClipboardCaps(uint32_t flags, const uint32_t* lengths)
{
int i;
@@ -139,11 +140,8 @@ void CMsgHandler::handleClipboardCaps(rdr::U32 flags, const rdr::U32* lengths)
if (lengths[i] == 0)
vlog.debug(" %s (only notify)", type);
else {
- char bytes[1024];
-
- iecPrefix(lengths[i], "B", bytes, sizeof(bytes));
vlog.debug(" %s (automatically send up to %s)",
- type, bytes);
+ type, iecPrefix(lengths[i], "B").c_str());
}
}
}
@@ -151,7 +149,7 @@ void CMsgHandler::handleClipboardCaps(rdr::U32 flags, const rdr::U32* lengths)
server.setClipboardCaps(flags, lengths);
}
-void CMsgHandler::handleClipboardRequest(rdr::U32 /*flags*/)
+void CMsgHandler::handleClipboardRequest(uint32_t /*flags*/)
{
}
@@ -159,12 +157,12 @@ void CMsgHandler::handleClipboardPeek()
{
}
-void CMsgHandler::handleClipboardNotify(rdr::U32 /*flags*/)
+void CMsgHandler::handleClipboardNotify(uint32_t /*flags*/)
{
}
-void CMsgHandler::handleClipboardProvide(rdr::U32 /*flags*/,
+void CMsgHandler::handleClipboardProvide(uint32_t /*flags*/,
const size_t* /*lengths*/,
- const rdr::U8* const* /*data*/)
+ const uint8_t* const* /*data*/)
{
}
diff --git a/common/rfb/CMsgHandler.h b/common/rfb/CMsgHandler.h
index e358a4f4..c427749f 100644
--- a/common/rfb/CMsgHandler.h
+++ b/common/rfb/CMsgHandler.h
@@ -24,8 +24,8 @@
#ifndef __RFB_CMSGHANDLER_H__
#define __RFB_CMSGHANDLER_H__
-#include <rdr/types.h>
-#include <rfb/Pixel.h>
+#include <stdint.h>
+
#include <rfb/ServerParams.h>
#include <rfb/Rect.h>
#include <rfb/ScreenSet.h>
@@ -51,11 +51,11 @@ namespace rfb {
int w, int h,
const ScreenSet& layout);
virtual void setCursor(int width, int height, const Point& hotspot,
- const rdr::U8* data) = 0;
+ const uint8_t* data) = 0;
virtual void setCursorPos(const Point& pos) = 0;
virtual void setPixelFormat(const PixelFormat& pf);
virtual void setName(const char* name);
- virtual void fence(rdr::U32 flags, unsigned len, const char data[]);
+ virtual void fence(uint32_t flags, unsigned len, const char data[]);
virtual void endOfContinuousUpdates();
virtual void supportsQEMUKeyEvent();
virtual void serverInit(int width, int height,
@@ -70,20 +70,20 @@ namespace rfb {
virtual bool dataRect(const Rect& r, int encoding) = 0;
virtual void setColourMapEntries(int firstColour, int nColours,
- rdr::U16* rgbs) = 0;
+ uint16_t* rgbs) = 0;
virtual void bell() = 0;
virtual void serverCutText(const char* str) = 0;
virtual void setLEDState(unsigned int state);
- virtual void handleClipboardCaps(rdr::U32 flags,
- const rdr::U32* lengths);
- virtual void handleClipboardRequest(rdr::U32 flags);
+ virtual void handleClipboardCaps(uint32_t flags,
+ const uint32_t* lengths);
+ virtual void handleClipboardRequest(uint32_t flags);
virtual void handleClipboardPeek();
- virtual void handleClipboardNotify(rdr::U32 flags);
- virtual void handleClipboardProvide(rdr::U32 flags,
+ virtual void handleClipboardNotify(uint32_t flags);
+ virtual void handleClipboardProvide(uint32_t flags,
const size_t* lengths,
- const rdr::U8* const* data);
+ const uint8_t* const* data);
ServerParams server;
};
diff --git a/common/rfb/CMsgReader.cxx b/common/rfb/CMsgReader.cxx
index 1c175584..be5133cf 100644
--- a/common/rfb/CMsgReader.cxx
+++ b/common/rfb/CMsgReader.cxx
@@ -24,14 +24,16 @@
#include <assert.h>
#include <stdio.h>
+#include <vector>
+
#include <rdr/InStream.h>
#include <rdr/ZlibInStream.h>
#include <rfb/msgTypes.h>
#include <rfb/clipboardTypes.h>
+#include <rfb/util.h>
#include <rfb/Exception.h>
#include <rfb/LogWriter.h>
-#include <rfb/util.h>
#include <rfb/CMsgHandler.h>
#include <rfb/CMsgReader.h>
@@ -54,7 +56,7 @@ CMsgReader::~CMsgReader()
bool CMsgReader::readServerInit()
{
int width, height;
- rdr::U32 len;
+ uint32_t len;
if (!is->hasData(2 + 2 + 16 + 4))
return false;
@@ -71,10 +73,10 @@ bool CMsgReader::readServerInit()
if (!is->hasDataOrRestore(len))
return false;
is->clearRestorePoint();
- CharArray name(len + 1);
- is->readBytes(name.buf, len);
- name.buf[len] = '\0';
- handler->serverInit(width, height, pf, name.buf);
+ std::vector<char> name(len + 1);
+ is->readBytes(name.data(), len);
+ name[len] = '\0';
+ handler->serverInit(width, height, pf, name.data());
return true;
}
@@ -228,10 +230,10 @@ bool CMsgReader::readSetColourMapEntries()
return false;
is->clearRestorePoint();
- rdr::U16Array rgbs(nColours * 3);
- for (int i = 0; i < nColours * 3; i++)
- rgbs.buf[i] = is->readU16();
- handler->setColourMapEntries(firstColour, nColours, rgbs.buf);
+ std::vector<uint16_t> rgbs(nColours * 3);
+ for (size_t i = 0; i < rgbs.size(); i++)
+ rgbs[i] = is->readU16();
+ handler->setColourMapEntries(firstColour, nColours, rgbs.data());
return true;
}
@@ -250,10 +252,10 @@ bool CMsgReader::readServerCutText()
is->setRestorePoint();
is->skip(3);
- rdr::U32 len = is->readU32();
+ uint32_t len = is->readU32();
if (len & 0x80000000) {
- rdr::S32 slen = len;
+ int32_t slen = len;
slen = -slen;
if (readExtendedClipboard(slen)) {
is->clearRestorePoint();
@@ -273,18 +275,18 @@ bool CMsgReader::readServerCutText()
vlog.error("cut text too long (%d bytes) - ignoring",len);
return true;
}
- CharArray ca(len);
- is->readBytes(ca.buf, len);
- CharArray filtered(convertLF(ca.buf, len));
- handler->serverCutText(filtered.buf);
+ std::vector<char> ca(len);
+ is->readBytes(ca.data(), len);
+ std::string filtered(convertLF(ca.data(), len));
+ handler->serverCutText(filtered.c_str());
return true;
}
-bool CMsgReader::readExtendedClipboard(rdr::S32 len)
+bool CMsgReader::readExtendedClipboard(int32_t len)
{
- rdr::U32 flags;
- rdr::U32 action;
+ uint32_t flags;
+ uint32_t action;
if (!is->hasData(len))
return false;
@@ -303,7 +305,7 @@ bool CMsgReader::readExtendedClipboard(rdr::S32 len)
if (action & clipboardCaps) {
int i;
size_t num;
- rdr::U32 lengths[16];
+ uint32_t lengths[16];
num = 0;
for (i = 0;i < 16;i++) {
@@ -311,7 +313,7 @@ bool CMsgReader::readExtendedClipboard(rdr::S32 len)
num++;
}
- if (len < (rdr::S32)(4 + 4*num))
+ if (len < (int32_t)(4 + 4*num))
throw Exception("Invalid extended clipboard message");
num = 0;
@@ -327,7 +329,7 @@ bool CMsgReader::readExtendedClipboard(rdr::S32 len)
int i;
size_t num;
size_t lengths[16];
- rdr::U8* buffers[16];
+ uint8_t* buffers[16];
zis.setUnderlying(is, len - 4);
@@ -368,7 +370,7 @@ bool CMsgReader::readExtendedClipboard(rdr::S32 len)
if (!zis.hasData(lengths[num]))
throw Exception("Extended clipboard decode error");
- buffers[num] = new rdr::U8[lengths[num]];
+ buffers[num] = new uint8_t[lengths[num]];
zis.readBytes(buffers[num], lengths[num]);
num++;
}
@@ -405,8 +407,8 @@ bool CMsgReader::readExtendedClipboard(rdr::S32 len)
bool CMsgReader::readFence()
{
- rdr::U32 flags;
- rdr::U8 len;
+ uint32_t flags;
+ uint8_t len;
char data[64];
if (!is->hasData(3 + 4 + 1))
@@ -476,18 +478,18 @@ bool CMsgReader::readSetXCursor(int width, int height, const Point& hotspot)
if (width > maxCursorSize || height > maxCursorSize)
throw Exception("Too big cursor");
- rdr::U8Array rgba(width*height*4);
+ std::vector<uint8_t> rgba(width*height*4);
if (width * height > 0) {
- rdr::U8 pr, pg, pb;
- rdr::U8 sr, sg, sb;
+ uint8_t pr, pg, pb;
+ uint8_t sr, sg, sb;
int data_len = ((width+7)/8) * height;
int mask_len = ((width+7)/8) * height;
- rdr::U8Array data(data_len);
- rdr::U8Array mask(mask_len);
+ std::vector<uint8_t> data(data_len);
+ std::vector<uint8_t> mask(mask_len);
int x, y;
- rdr::U8* out;
+ uint8_t* out;
if (!is->hasData(3 + 3 + data_len + mask_len))
return false;
@@ -500,17 +502,17 @@ bool CMsgReader::readSetXCursor(int width, int height, const Point& hotspot)
sg = is->readU8();
sb = is->readU8();
- is->readBytes(data.buf, data_len);
- is->readBytes(mask.buf, mask_len);
+ is->readBytes(data.data(), data.size());
+ is->readBytes(mask.data(), mask.size());
int maskBytesPerRow = (width+7)/8;
- out = rgba.buf;
+ out = rgba.data();
for (y = 0;y < height;y++) {
for (x = 0;x < width;x++) {
int byte = y * maskBytesPerRow + x / 8;
int bit = 7 - x % 8;
- if (data.buf[byte] & (1 << bit)) {
+ if (data[byte] & (1 << bit)) {
out[0] = pr;
out[1] = pg;
out[2] = pb;
@@ -520,7 +522,7 @@ bool CMsgReader::readSetXCursor(int width, int height, const Point& hotspot)
out[2] = sb;
}
- if (mask.buf[byte] & (1 << bit))
+ if (mask[byte] & (1 << bit))
out[3] = 255;
else
out[3] = 0;
@@ -530,7 +532,7 @@ bool CMsgReader::readSetXCursor(int width, int height, const Point& hotspot)
}
}
- handler->setCursor(width, height, hotspot, rgba.buf);
+ handler->setCursor(width, height, hotspot, rgba.data());
return true;
}
@@ -542,23 +544,23 @@ bool CMsgReader::readSetCursor(int width, int height, const Point& hotspot)
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);
+ std::vector<uint8_t> data(data_len);
+ std::vector<uint8_t> mask(mask_len);
int x, y;
- rdr::U8Array rgba(width*height*4);
- rdr::U8* in;
- rdr::U8* out;
+ std::vector<uint8_t> rgba(width*height*4);
+ uint8_t* in;
+ uint8_t* out;
if (!is->hasData(data_len + mask_len))
return false;
- is->readBytes(data.buf, data_len);
- is->readBytes(mask.buf, mask_len);
+ is->readBytes(data.data(), data.size());
+ is->readBytes(mask.data(), mask.size());
int maskBytesPerRow = (width+7)/8;
- in = data.buf;
- out = rgba.buf;
+ in = data.data();
+ out = rgba.data();
for (y = 0;y < height;y++) {
for (x = 0;x < width;x++) {
int byte = y * maskBytesPerRow + x / 8;
@@ -566,7 +568,7 @@ bool CMsgReader::readSetCursor(int width, int height, const Point& hotspot)
handler->server.pf().rgbFromBuffer(out, in, 1);
- if (mask.buf[byte] & (1 << bit))
+ if (mask[byte] & (1 << bit))
out[3] = 255;
else
out[3] = 0;
@@ -576,7 +578,7 @@ bool CMsgReader::readSetCursor(int width, int height, const Point& hotspot)
}
}
- handler->setCursor(width, height, hotspot, rgba.buf);
+ handler->setCursor(width, height, hotspot, rgba.data());
return true;
}
@@ -592,7 +594,7 @@ bool CMsgReader::readSetCursorWithAlpha(int width, int height, const Point& hots
bool ret;
- rdr::U8* buf;
+ uint8_t* buf;
int stride;
// We can't use restore points as the decoder likely wants to as well, so
@@ -621,7 +623,7 @@ bool CMsgReader::readSetCursorWithAlpha(int width, int height, const Point& hots
assert(stride == width);
for (int i = 0;i < pb.area();i++) {
- rdr::U8 alpha;
+ uint8_t alpha;
alpha = buf[3];
if (alpha == 0)
@@ -647,7 +649,7 @@ bool CMsgReader::readSetVMwareCursor(int width, int height, const Point& hotspot
if (width > maxCursorSize || height > maxCursorSize)
throw Exception("Too big cursor");
- rdr::U8 type;
+ uint8_t type;
if (!is->hasData(1 + 1))
return false;
@@ -659,26 +661,26 @@ bool CMsgReader::readSetVMwareCursor(int width, int height, const Point& hotspot
if (type == 0) {
int len = width * height * (handler->server.pf().bpp/8);
- rdr::U8Array andMask(len);
- rdr::U8Array xorMask(len);
+ std::vector<uint8_t> andMask(len);
+ std::vector<uint8_t> xorMask(len);
- rdr::U8Array data(width*height*4);
+ std::vector<uint8_t> data(width*height*4);
- rdr::U8* andIn;
- rdr::U8* xorIn;
- rdr::U8* out;
+ uint8_t* andIn;
+ uint8_t* xorIn;
+ uint8_t* out;
int Bpp;
if (!is->hasDataOrRestore(len + len))
return false;
is->clearRestorePoint();
- is->readBytes(andMask.buf, len);
- is->readBytes(xorMask.buf, len);
+ is->readBytes(andMask.data(), andMask.size());
+ is->readBytes(xorMask.data(), xorMask.size());
- andIn = andMask.buf;
- xorIn = xorMask.buf;
- out = data.buf;
+ andIn = andMask.data();
+ xorIn = xorMask.data();
+ out = data.data();
Bpp = handler->server.pf().bpp/8;
for (int y = 0;y < height;y++) {
for (int x = 0;x < width;x++) {
@@ -690,7 +692,7 @@ bool CMsgReader::readSetVMwareCursor(int width, int height, const Point& hotspot
xorIn += Bpp;
if (andPixel == 0) {
- rdr::U8 r, g, b;
+ uint8_t r, g, b;
// Opaque pixel
@@ -726,18 +728,18 @@ bool CMsgReader::readSetVMwareCursor(int width, int height, const Point& hotspot
}
}
- handler->setCursor(width, height, hotspot, data.buf);
+ handler->setCursor(width, height, hotspot, data.data());
} else if (type == 1) {
- rdr::U8Array data(width*height*4);
+ std::vector<uint8_t> data(width*height*4);
if (!is->hasDataOrRestore(width*height*4))
return false;
is->clearRestorePoint();
// FIXME: Is alpha premultiplied?
- is->readBytes(data.buf, width*height*4);
+ is->readBytes(data.data(), data.size());
- handler->setCursor(width, height, hotspot, data.buf);
+ handler->setCursor(width, height, hotspot, data.data());
} else {
throw Exception("Unknown cursor type");
}
@@ -747,7 +749,7 @@ bool CMsgReader::readSetVMwareCursor(int width, int height, const Point& hotspot
bool CMsgReader::readSetDesktopName(int x, int y, int w, int h)
{
- rdr::U32 len;
+ uint32_t len;
if (!is->hasData(4))
return false;
@@ -760,14 +762,14 @@ bool CMsgReader::readSetDesktopName(int x, int y, int w, int h)
return false;
is->clearRestorePoint();
- CharArray name(len + 1);
- is->readBytes(name.buf, len);
- name.buf[len] = '\0';
+ std::vector<char> name(len + 1);
+ is->readBytes(name.data(), len);
+ name[len] = '\0';
if (x || y || w || h) {
vlog.error("Ignoring DesktopName rect with non-zero position/size");
} else {
- handler->setName(name.buf);
+ handler->setName(name.data());
}
return true;
@@ -776,7 +778,7 @@ bool CMsgReader::readSetDesktopName(int x, int y, int w, int h)
bool CMsgReader::readExtendedDesktopSize(int x, int y, int w, int h)
{
unsigned int screens, i;
- rdr::U32 id, flags;
+ uint32_t id, flags;
int sx, sy, sw, sh;
ScreenSet layout;
@@ -810,7 +812,7 @@ bool CMsgReader::readExtendedDesktopSize(int x, int y, int w, int h)
bool CMsgReader::readLEDState()
{
- rdr::U8 state;
+ uint8_t state;
if (!is->hasData(1))
return false;
@@ -824,7 +826,7 @@ bool CMsgReader::readLEDState()
bool CMsgReader::readVMwareLEDState()
{
- rdr::U32 state;
+ uint32_t state;
if (!is->hasData(4))
return false;
diff --git a/common/rfb/CMsgReader.h b/common/rfb/CMsgReader.h
index ab55aed8..3b1c0ddb 100644
--- a/common/rfb/CMsgReader.h
+++ b/common/rfb/CMsgReader.h
@@ -24,7 +24,7 @@
#ifndef __RFB_CMSGREADER_H__
#define __RFB_CMSGREADER_H__
-#include <rdr/types.h>
+#include <stdint.h>
#include <rfb/Rect.h>
#include <rfb/encodings.h>
@@ -53,7 +53,7 @@ namespace rfb {
bool readSetColourMapEntries();
bool readBell();
bool readServerCutText();
- bool readExtendedClipboard(rdr::S32 len);
+ bool readExtendedClipboard(int32_t len);
bool readFence();
bool readEndOfContinuousUpdates();
@@ -83,7 +83,7 @@ namespace rfb {
stateEnum state;
- rdr::U8 currentMsgType;
+ uint8_t currentMsgType;
int nUpdateRectsLeft;
Rect dataRect;
int rectEncoding;
diff --git a/common/rfb/CMsgWriter.cxx b/common/rfb/CMsgWriter.cxx
index 0ac1bd73..246c5dbe 100644
--- a/common/rfb/CMsgWriter.cxx
+++ b/common/rfb/CMsgWriter.cxx
@@ -62,9 +62,9 @@ void CMsgWriter::writeSetPixelFormat(const PixelFormat& pf)
endMsg();
}
-void CMsgWriter::writeSetEncodings(const std::list<rdr::U32> encodings)
+void CMsgWriter::writeSetEncodings(const std::list<uint32_t> encodings)
{
- std::list<rdr::U32>::const_iterator iter;
+ std::list<uint32_t>::const_iterator iter;
startMsg(msgTypeSetEncodings);
os->pad(1);
os->writeU16(encodings.size());
@@ -130,7 +130,7 @@ void CMsgWriter::writeEnableContinuousUpdates(bool enable,
endMsg();
}
-void CMsgWriter::writeFence(rdr::U32 flags, unsigned len, const char data[])
+void CMsgWriter::writeFence(uint32_t flags, unsigned len, const char data[])
{
if (!server->supportsFence)
throw Exception("Server does not support fences");
@@ -150,7 +150,7 @@ void CMsgWriter::writeFence(rdr::U32 flags, unsigned len, const char data[])
endMsg();
}
-void CMsgWriter::writeKeyEvent(rdr::U32 keysym, rdr::U32 keycode, bool down)
+void CMsgWriter::writeKeyEvent(uint32_t keysym, uint32_t keycode, bool down)
{
if (!server->supportsQEMUKeyEvent || !keycode) {
/* This event isn't meaningful without a valid keysym */
@@ -204,8 +204,8 @@ void CMsgWriter::writeClientCutText(const char* str)
endMsg();
}
-void CMsgWriter::writeClipboardCaps(rdr::U32 caps,
- const rdr::U32* lengths)
+void CMsgWriter::writeClipboardCaps(uint32_t caps,
+ const uint32_t* lengths)
{
size_t i, count;
@@ -233,7 +233,7 @@ void CMsgWriter::writeClipboardCaps(rdr::U32 caps,
endMsg();
}
-void CMsgWriter::writeClipboardRequest(rdr::U32 flags)
+void CMsgWriter::writeClipboardRequest(uint32_t flags)
{
if (!(server->clipboardFlags() & clipboardRequest))
throw Exception("Server does not support clipboard \"request\" action");
@@ -245,7 +245,7 @@ void CMsgWriter::writeClipboardRequest(rdr::U32 flags)
endMsg();
}
-void CMsgWriter::writeClipboardPeek(rdr::U32 flags)
+void CMsgWriter::writeClipboardPeek(uint32_t flags)
{
if (!(server->clipboardFlags() & clipboardPeek))
throw Exception("Server does not support clipboard \"peek\" action");
@@ -257,7 +257,7 @@ void CMsgWriter::writeClipboardPeek(rdr::U32 flags)
endMsg();
}
-void CMsgWriter::writeClipboardNotify(rdr::U32 flags)
+void CMsgWriter::writeClipboardNotify(uint32_t flags)
{
if (!(server->clipboardFlags() & clipboardNotify))
throw Exception("Server does not support clipboard \"notify\" action");
@@ -269,9 +269,9 @@ void CMsgWriter::writeClipboardNotify(rdr::U32 flags)
endMsg();
}
-void CMsgWriter::writeClipboardProvide(rdr::U32 flags,
+void CMsgWriter::writeClipboardProvide(uint32_t flags,
const size_t* lengths,
- const rdr::U8* const* data)
+ const uint8_t* const* data)
{
rdr::MemOutStream mos;
rdr::ZlibOutStream zos;
diff --git a/common/rfb/CMsgWriter.h b/common/rfb/CMsgWriter.h
index 7b839393..7e7a9a17 100644
--- a/common/rfb/CMsgWriter.h
+++ b/common/rfb/CMsgWriter.h
@@ -25,7 +25,7 @@
#include <list>
-#include <rdr/types.h>
+#include <stdint.h>
namespace rdr { class OutStream; }
@@ -45,25 +45,25 @@ namespace rfb {
void writeClientInit(bool shared);
void writeSetPixelFormat(const PixelFormat& pf);
- void writeSetEncodings(const std::list<rdr::U32> encodings);
+ void writeSetEncodings(const std::list<uint32_t> encodings);
void writeSetDesktopSize(int width, int height, const ScreenSet& layout);
void writeFramebufferUpdateRequest(const Rect& r,bool incremental);
void writeEnableContinuousUpdates(bool enable, int x, int y, int w, int h);
- void writeFence(rdr::U32 flags, unsigned len, const char data[]);
+ void writeFence(uint32_t flags, unsigned len, const char data[]);
- void writeKeyEvent(rdr::U32 keysym, rdr::U32 keycode, bool down);
+ void writeKeyEvent(uint32_t keysym, uint32_t keycode, bool down);
void writePointerEvent(const Point& pos, int buttonMask);
void writeClientCutText(const char* str);
- void writeClipboardCaps(rdr::U32 caps, const rdr::U32* lengths);
- void writeClipboardRequest(rdr::U32 flags);
- void writeClipboardPeek(rdr::U32 flags);
- void writeClipboardNotify(rdr::U32 flags);
- void writeClipboardProvide(rdr::U32 flags, const size_t* lengths,
- const rdr::U8* const* data);
+ void writeClipboardCaps(uint32_t caps, const uint32_t* lengths);
+ void writeClipboardRequest(uint32_t flags);
+ void writeClipboardPeek(uint32_t flags);
+ void writeClipboardNotify(uint32_t flags);
+ void writeClipboardProvide(uint32_t flags, const size_t* lengths,
+ const uint8_t* const* data);
protected:
void startMsg(int type);
diff --git a/common/rfb/CSecurityDH.cxx b/common/rfb/CSecurityDH.cxx
index d9b09bfb..9e67885c 100644
--- a/common/rfb/CSecurityDH.cxx
+++ b/common/rfb/CSecurityDH.cxx
@@ -83,7 +83,7 @@ bool CSecurityDH::readKey()
if (!is->hasData(4))
return false;
is->setRestorePoint();
- rdr::U16 gen = is->readU16();
+ uint16_t gen = is->readU16();
keyLength = is->readU16();
if (keyLength < MinKeyLength)
throw AuthFailureException("DH key is too short");
@@ -93,38 +93,39 @@ bool CSecurityDH::readKey()
return false;
is->clearRestorePoint();
mpz_set_ui(g, gen);
- rdr::U8Array pBytes(keyLength);
- rdr::U8Array ABytes(keyLength);
- is->readBytes(pBytes.buf, keyLength);
- is->readBytes(ABytes.buf, keyLength);
- nettle_mpz_set_str_256_u(p, keyLength, pBytes.buf);
- nettle_mpz_set_str_256_u(A, keyLength, ABytes.buf);
+ std::vector<uint8_t> pBytes(keyLength);
+ std::vector<uint8_t> ABytes(keyLength);
+ is->readBytes(pBytes.data(), pBytes.size());
+ is->readBytes(ABytes.data(), ABytes.size());
+ nettle_mpz_set_str_256_u(p, pBytes.size(), pBytes.data());
+ nettle_mpz_set_str_256_u(A, ABytes.size(), ABytes.data());
return true;
}
void CSecurityDH::writeCredentials()
{
- CharArray username;
- CharArray password;
+ std::string username;
+ std::string password;
rdr::RandomStream rs;
- (CSecurity::upg)->getUserPasswd(isSecure(), &username.buf, &password.buf);
- rdr::U8Array bBytes(keyLength);
+ (CSecurity::upg)->getUserPasswd(isSecure(), &username, &password);
+
+ std::vector<uint8_t> bBytes(keyLength);
if (!rs.hasData(keyLength))
throw ConnFailedException("failed to generate DH private key");
- rs.readBytes(bBytes.buf, keyLength);
- nettle_mpz_set_str_256_u(b, keyLength, bBytes.buf);
+ rs.readBytes(bBytes.data(), bBytes.size());
+ nettle_mpz_set_str_256_u(b, bBytes.size(), bBytes.data());
mpz_powm(k, A, b, p);
mpz_powm(B, g, b, p);
- rdr::U8Array sharedSecret(keyLength);
- rdr::U8Array BBytes(keyLength);
- nettle_mpz_get_str_256(keyLength, sharedSecret.buf, k);
- nettle_mpz_get_str_256(keyLength, BBytes.buf, B);
- rdr::U8 key[16];
+ std::vector<uint8_t> sharedSecret(keyLength);
+ std::vector<uint8_t> BBytes(keyLength);
+ nettle_mpz_get_str_256(sharedSecret.size(), sharedSecret.data(), k);
+ nettle_mpz_get_str_256(BBytes.size(), BBytes.data(), B);
+ uint8_t key[16];
struct md5_ctx md5Ctx;
md5_init(&md5Ctx);
- md5_update(&md5Ctx, keyLength, sharedSecret.buf);
+ md5_update(&md5Ctx, sharedSecret.size(), sharedSecret.data());
md5_digest(&md5Ctx, 16, key);
struct aes128_ctx aesCtx;
aes128_set_encrypt_key(&aesCtx, key);
@@ -133,18 +134,16 @@ void CSecurityDH::writeCredentials()
if (!rs.hasData(128))
throw ConnFailedException("failed to generate random padding");
rs.readBytes(buf, 128);
- size_t len = strlen(username.buf);
- if (len >= 64)
+ if (username.size() >= 64)
throw AuthFailureException("username is too long");
- memcpy(buf, username.buf, len + 1);
- len = strlen(password.buf);
- if (len >= 64)
+ memcpy(buf, username.c_str(), username.size() + 1);
+ if (password.size() >= 64)
throw AuthFailureException("password is too long");
- memcpy(buf + 64, password.buf, len + 1);
- aes128_encrypt(&aesCtx, 128, (rdr::U8 *)buf, (rdr::U8 *)buf);
+ memcpy(buf + 64, password.c_str(), password.size() + 1);
+ aes128_encrypt(&aesCtx, 128, (uint8_t *)buf, (uint8_t *)buf);
rdr::OutStream* os = cc->getOutStream();
os->writeBytes(buf, 128);
- os->writeBytes(BBytes.buf, keyLength);
+ os->writeBytes(BBytes.data(), BBytes.size());
os->flush();
}
diff --git a/common/rfb/CSecurityMSLogonII.cxx b/common/rfb/CSecurityMSLogonII.cxx
index a1faab85..d7e23715 100644
--- a/common/rfb/CSecurityMSLogonII.cxx
+++ b/common/rfb/CSecurityMSLogonII.cxx
@@ -79,9 +79,9 @@ bool CSecurityMSLogonII::readKey()
rdr::InStream* is = cc->getInStream();
if (!is->hasData(24))
return false;
- rdr::U8 gBytes[8];
- rdr::U8 pBytes[8];
- rdr::U8 ABytes[8];
+ uint8_t gBytes[8];
+ uint8_t pBytes[8];
+ uint8_t ABytes[8];
is->readBytes(gBytes, 8);
is->readBytes(pBytes, 8);
is->readBytes(ABytes, 8);
@@ -93,28 +93,29 @@ bool CSecurityMSLogonII::readKey()
void CSecurityMSLogonII::writeCredentials()
{
- CharArray username;
- CharArray password;
+ std::string username;
+ std::string password;
rdr::RandomStream rs;
- (CSecurity::upg)->getUserPasswd(isSecure(), &username.buf, &password.buf);
- rdr::U8Array bBytes(8);
+ (CSecurity::upg)->getUserPasswd(isSecure(), &username, &password);
+
+ std::vector<uint8_t> bBytes(8);
if (!rs.hasData(8))
throw ConnFailedException("failed to generate DH private key");
- rs.readBytes(bBytes.buf, 8);
- nettle_mpz_set_str_256_u(b, 8, bBytes.buf);
+ rs.readBytes(bBytes.data(), bBytes.size());
+ nettle_mpz_set_str_256_u(b, bBytes.size(), bBytes.data());
mpz_powm(k, A, b, p);
mpz_powm(B, g, b, p);
- rdr::U8 key[8];
- rdr::U8 reversedKey[8];
- rdr::U8 BBytes[8];
- rdr::U8 user[256];
- rdr::U8 pass[64];
+ uint8_t key[8];
+ uint8_t reversedKey[8];
+ uint8_t BBytes[8];
+ uint8_t user[256];
+ uint8_t pass[64];
nettle_mpz_get_str_256(8, key, k);
nettle_mpz_get_str_256(8, BBytes, B);
for (int i = 0; i < 8; ++i) {
- rdr::U8 x = 0;
+ uint8_t x = 0;
for (int j = 0; j < 8; ++j) {
x |= ((key[i] >> j) & 1) << (7 - j);
}
@@ -125,14 +126,12 @@ void CSecurityMSLogonII::writeCredentials()
throw ConnFailedException("failed to generate random padding");
rs.readBytes(user, 256);
rs.readBytes(pass, 64);
- size_t len = strlen(username.buf);
- if (len >= 256)
+ if (username.size() >= 256)
throw AuthFailureException("username is too long");
- memcpy(user, username.buf, len + 1);
- len = strlen(password.buf);
- if (len >= 64)
+ memcpy(user, username.c_str(), username.size() + 1);
+ if (password.size() >= 64)
throw AuthFailureException("password is too long");
- memcpy(pass, password.buf, len + 1);
+ memcpy(pass, password.c_str(), password.size() + 1);
// DES-CBC with the original key as IV, and the reversed one as the DES key
struct CBC_CTX(struct des_ctx, DES_BLOCK_SIZE) ctx;
diff --git a/common/rfb/CSecurityPlain.cxx b/common/rfb/CSecurityPlain.cxx
index 464dfcb5..7b75ef86 100644
--- a/common/rfb/CSecurityPlain.cxx
+++ b/common/rfb/CSecurityPlain.cxx
@@ -24,7 +24,6 @@
#include <rfb/CConnection.h>
#include <rfb/CSecurityPlain.h>
#include <rfb/UserPasswdGetter.h>
-#include <rfb/util.h>
#include <rdr/OutStream.h>
@@ -34,16 +33,16 @@ bool CSecurityPlain::processMsg()
{
rdr::OutStream* os = cc->getOutStream();
- CharArray username;
- CharArray password;
+ std::string username;
+ std::string password;
- (CSecurity::upg)->getUserPasswd(cc->isSecure(), &username.buf, &password.buf);
+ (CSecurity::upg)->getUserPasswd(cc->isSecure(), &username, &password);
// Return the response to the server
- os->writeU32(strlen(username.buf));
- os->writeU32(strlen(password.buf));
- os->writeBytes(username.buf,strlen(username.buf));
- os->writeBytes(password.buf,strlen(password.buf));
+ os->writeU32(username.size());
+ os->writeU32(password.size());
+ os->writeBytes(username.data(), username.size());
+ os->writeBytes(password.data(), password.size());
os->flush();
return true;
}
diff --git a/common/rfb/CSecurityRSAAES.cxx b/common/rfb/CSecurityRSAAES.cxx
index c84422b6..6194caab 100644
--- a/common/rfb/CSecurityRSAAES.cxx
+++ b/common/rfb/CSecurityRSAAES.cxx
@@ -39,6 +39,7 @@
#include <rfb/LogWriter.h>
#include <rfb/Exception.h>
#include <rfb/UserMsgBox.h>
+#include <rfb/util.h>
#include <rdr/AESInStream.h>
#include <rdr/AESOutStream.h>
#include <os/os.h>
@@ -55,7 +56,7 @@ const int MaxKeyLength = 8192;
using namespace rfb;
-CSecurityRSAAES::CSecurityRSAAES(CConnection* cc, rdr::U32 _secType,
+CSecurityRSAAES::CSecurityRSAAES(CConnection* cc, uint32_t _secType,
int _keySize, bool _isAllEncrypted)
: CSecurity(cc), state(ReadPublicKey),
keySize(_keySize), isAllEncrypted(_isAllEncrypted), secType(_secType),
@@ -155,8 +156,8 @@ void CSecurityRSAAES::writePublicKey()
if (!rsa_generate_keypair(&clientPublicKey, &clientKey,
&rs, random_func, NULL, NULL, clientKeyLength, 0))
throw AuthFailureException("failed to generate key");
- clientKeyN = new rdr::U8[rsaKeySize];
- clientKeyE = new rdr::U8[rsaKeySize];
+ clientKeyN = new uint8_t[rsaKeySize];
+ clientKeyE = new uint8_t[rsaKeySize];
nettle_mpz_get_str_256(rsaKeySize, clientKeyN, clientPublicKey.n);
nettle_mpz_get_str_256(rsaKeySize, clientKeyE, clientPublicKey.e);
os->writeU32(clientKeyLength);
@@ -180,8 +181,8 @@ bool CSecurityRSAAES::readPublicKey()
if (!is->hasDataOrRestore(size * 2))
return false;
is->clearRestorePoint();
- serverKeyE = new rdr::U8[size];
- serverKeyN = new rdr::U8[size];
+ serverKeyE = new uint8_t[size];
+ serverKeyN = new uint8_t[size];
is->readBytes(serverKeyN, size);
is->readBytes(serverKeyE, size);
rsa_public_key_init(&serverKey);
@@ -194,13 +195,13 @@ bool CSecurityRSAAES::readPublicKey()
void CSecurityRSAAES::verifyServer()
{
- rdr::U8 lenServerKey[4] = {
- (rdr::U8)((serverKeyLength & 0xff000000) >> 24),
- (rdr::U8)((serverKeyLength & 0xff0000) >> 16),
- (rdr::U8)((serverKeyLength & 0xff00) >> 8),
- (rdr::U8)(serverKeyLength & 0xff)
+ uint8_t lenServerKey[4] = {
+ (uint8_t)((serverKeyLength & 0xff000000) >> 24),
+ (uint8_t)((serverKeyLength & 0xff0000) >> 16),
+ (uint8_t)((serverKeyLength & 0xff00) >> 8),
+ (uint8_t)(serverKeyLength & 0xff)
};
- rdr::U8 f[8];
+ uint8_t f[8];
struct sha1_ctx ctx;
sha1_init(&ctx);
sha1_update(&ctx, 4, lenServerKey);
@@ -208,13 +209,12 @@ void CSecurityRSAAES::verifyServer()
sha1_update(&ctx, serverKey.size, serverKeyE);
sha1_digest(&ctx, sizeof(f), f);
const char *title = "Server key fingerprint";
- CharArray text;
- text.format(
+ std::string text = format(
"The server has provided the following identifying information:\n"
"Fingerprint: %02x-%02x-%02x-%02x-%02x-%02x-%02x-%02x\n"
"Please verify that the information is correct and press \"Yes\". "
"Otherwise press \"No\"", f[0], f[1], f[2], f[3], f[4], f[5], f[6], f[7]);
- if (!msg->showMsgBox(UserMsgBox::M_YESNO, title, text.buf))
+ if (!msg->showMsgBox(UserMsgBox::M_YESNO, title, text.c_str()))
throw AuthFailureException("server key mismatch");
}
@@ -238,7 +238,7 @@ void CSecurityRSAAES::writeRandom()
mpz_clear(x);
throw AuthFailureException("failed to encrypt random");
}
- rdr::U8* buffer = new rdr::U8[serverKey.size];
+ uint8_t* buffer = new uint8_t[serverKey.size];
nettle_mpz_get_str_256(serverKey.size, buffer, x);
mpz_clear(x);
os->writeU16(serverKey.size);
@@ -259,7 +259,7 @@ bool CSecurityRSAAES::readRandom()
if (!is->hasDataOrRestore(size))
return false;
is->clearRestorePoint();
- rdr::U8* buffer = new rdr::U8[size];
+ uint8_t* buffer = new uint8_t[size];
is->readBytes(buffer, size);
size_t randomSize = keySize / 8;
mpz_t x;
@@ -278,7 +278,7 @@ void CSecurityRSAAES::setCipher()
{
rawis = cc->getInStream();
rawos = cc->getOutStream();
- rdr::U8 key[32];
+ uint8_t key[32];
if (keySize == 128) {
struct sha1_ctx ctx;
sha1_init(&ctx);
@@ -310,20 +310,20 @@ void CSecurityRSAAES::setCipher()
void CSecurityRSAAES::writeHash()
{
- rdr::U8 hash[32];
+ uint8_t hash[32];
size_t len = serverKeyLength;
- rdr::U8 lenServerKey[4] = {
- (rdr::U8)((len & 0xff000000) >> 24),
- (rdr::U8)((len & 0xff0000) >> 16),
- (rdr::U8)((len & 0xff00) >> 8),
- (rdr::U8)(len & 0xff)
+ uint8_t lenServerKey[4] = {
+ (uint8_t)((len & 0xff000000) >> 24),
+ (uint8_t)((len & 0xff0000) >> 16),
+ (uint8_t)((len & 0xff00) >> 8),
+ (uint8_t)(len & 0xff)
};
len = clientKeyLength;
- rdr::U8 lenClientKey[4] = {
- (rdr::U8)((len & 0xff000000) >> 24),
- (rdr::U8)((len & 0xff0000) >> 16),
- (rdr::U8)((len & 0xff00) >> 8),
- (rdr::U8)(len & 0xff)
+ uint8_t lenClientKey[4] = {
+ (uint8_t)((len & 0xff000000) >> 24),
+ (uint8_t)((len & 0xff0000) >> 16),
+ (uint8_t)((len & 0xff00) >> 8),
+ (uint8_t)(len & 0xff)
};
int hashSize;
if (keySize == 128) {
@@ -355,25 +355,25 @@ void CSecurityRSAAES::writeHash()
bool CSecurityRSAAES::readHash()
{
- rdr::U8 hash[32];
- rdr::U8 realHash[32];
+ uint8_t hash[32];
+ uint8_t realHash[32];
int hashSize = keySize == 128 ? 20 : 32;
if (!rais->hasData(hashSize))
return false;
rais->readBytes(hash, hashSize);
size_t len = serverKeyLength;
- rdr::U8 lenServerKey[4] = {
- (rdr::U8)((len & 0xff000000) >> 24),
- (rdr::U8)((len & 0xff0000) >> 16),
- (rdr::U8)((len & 0xff00) >> 8),
- (rdr::U8)(len & 0xff)
+ uint8_t lenServerKey[4] = {
+ (uint8_t)((len & 0xff000000) >> 24),
+ (uint8_t)((len & 0xff0000) >> 16),
+ (uint8_t)((len & 0xff00) >> 8),
+ (uint8_t)(len & 0xff)
};
len = clientKeyLength;
- rdr::U8 lenClientKey[4] = {
- (rdr::U8)((len & 0xff000000) >> 24),
- (rdr::U8)((len & 0xff0000) >> 16),
- (rdr::U8)((len & 0xff00) >> 8),
- (rdr::U8)(len & 0xff)
+ uint8_t lenClientKey[4] = {
+ (uint8_t)((len & 0xff000000) >> 24),
+ (uint8_t)((len & 0xff0000) >> 16),
+ (uint8_t)((len & 0xff00) >> 8),
+ (uint8_t)(len & 0xff)
};
if (keySize == 128) {
struct sha1_ctx ctx;
@@ -433,29 +433,26 @@ bool CSecurityRSAAES::readSubtype()
void CSecurityRSAAES::writeCredentials()
{
- CharArray username;
- CharArray password;
+ std::string username;
+ std::string password;
- (CSecurity::upg)->getUserPasswd(
- isSecure(),
- subtype == secTypeRA2UserPass ? &username.buf : NULL, &password.buf
- );
- size_t len;
- if (username.buf) {
- len = strlen(username.buf);
- if (len > 255)
+ if (subtype == secTypeRA2UserPass)
+ (CSecurity::upg)->getUserPasswd(isSecure(), &username, &password);
+ else
+ (CSecurity::upg)->getUserPasswd(isSecure(), NULL, &password);
+
+ if (subtype == secTypeRA2UserPass) {
+ if (username.size() > 255)
throw AuthFailureException("username is too long");
- raos->writeU8(len);
- if (len)
- raos->writeBytes(username.buf, len);
+ raos->writeU8(username.size());
+ raos->writeBytes(username.data(), username.size());
} else {
raos->writeU8(0);
}
- len = strlen(password.buf);
- if (len > 255)
+
+ if (password.size() > 255)
throw AuthFailureException("password is too long");
- raos->writeU8(len);
- if (len)
- raos->writeBytes(password.buf, len);
+ raos->writeU8(password.size());
+ raos->writeBytes(password.data(), password.size());
raos->flush();
-} \ No newline at end of file
+}
diff --git a/common/rfb/CSecurityRSAAES.h b/common/rfb/CSecurityRSAAES.h
index f58bb87f..543b0152 100644
--- a/common/rfb/CSecurityRSAAES.h
+++ b/common/rfb/CSecurityRSAAES.h
@@ -36,7 +36,7 @@ namespace rfb {
class UserMsgBox;
class CSecurityRSAAES : public CSecurity {
public:
- CSecurityRSAAES(CConnection* cc, rdr::U32 secType,
+ CSecurityRSAAES(CConnection* cc, uint32_t secType,
int keySize, bool isAllEncrypted);
virtual ~CSecurityRSAAES();
virtual bool processMsg();
@@ -62,19 +62,19 @@ namespace rfb {
int state;
int keySize;
bool isAllEncrypted;
- rdr::U32 secType;
- rdr::U8 subtype;
+ uint32_t secType;
+ uint8_t subtype;
struct rsa_private_key clientKey;
struct rsa_public_key clientPublicKey;
struct rsa_public_key serverKey;
- rdr::U32 serverKeyLength;
- rdr::U8* serverKeyN;
- rdr::U8* serverKeyE;
- rdr::U32 clientKeyLength;
- rdr::U8* clientKeyN;
- rdr::U8* clientKeyE;
- rdr::U8 serverRandom[32];
- rdr::U8 clientRandom[32];
+ uint32_t serverKeyLength;
+ uint8_t* serverKeyN;
+ uint8_t* serverKeyE;
+ uint32_t clientKeyLength;
+ uint8_t* clientKeyN;
+ uint8_t* clientKeyE;
+ uint8_t serverRandom[32];
+ uint8_t clientRandom[32];
rdr::InStream* rais;
rdr::OutStream* raos;
diff --git a/common/rfb/CSecurityTLS.cxx b/common/rfb/CSecurityTLS.cxx
index ca1c919b..e24f9d71 100644
--- a/common/rfb/CSecurityTLS.cxx
+++ b/common/rfb/CSecurityTLS.cxx
@@ -39,6 +39,7 @@
#include <rfb/LogWriter.h>
#include <rfb/Exception.h>
#include <rfb/UserMsgBox.h>
+#include <rfb/util.h>
#include <rdr/TLSInStream.h>
#include <rdr/TLSOutStream.h>
#include <os/os.h>
@@ -76,14 +77,13 @@ static LogWriter vlog("TLS");
static const char* homedirfn(const char* fn)
{
static char full_path[PATH_MAX];
- char* homedir = NULL;
+ const char* homedir;
- if (getvnchomedir(&homedir) == -1)
+ homedir = os::getvnchomedir();
+ if (homedir == NULL)
return "";
- snprintf(full_path, sizeof(full_path), "%s%s", homedir, fn);
-
- delete [] homedir;
+ snprintf(full_path, sizeof(full_path), "%s/%s", homedir, fn);
return full_path;
}
@@ -92,9 +92,6 @@ CSecurityTLS::CSecurityTLS(CConnection* cc, bool _anon)
: CSecurity(cc), session(NULL), anon_cred(NULL), cert_cred(NULL),
anon(_anon), tlsis(NULL), tlsos(NULL), rawis(NULL), rawos(NULL)
{
- cafile = X509CA.getData();
- crlfile = X509CRL.getData();
-
if (gnutls_global_init() != GNUTLS_E_SUCCESS)
throw AuthFailureException("gnutls_global_init failed");
}
@@ -146,9 +143,6 @@ CSecurityTLS::~CSecurityTLS()
{
shutdown();
- delete[] cafile;
- delete[] crlfile;
-
gnutls_global_deinit();
}
@@ -287,10 +281,10 @@ void CSecurityTLS::setParam()
if (gnutls_certificate_set_x509_system_trust(cert_cred) < 1)
vlog.error("Could not load system certificate trust store");
- if (*cafile && gnutls_certificate_set_x509_trust_file(cert_cred,cafile,GNUTLS_X509_FMT_PEM) < 0)
+ if (gnutls_certificate_set_x509_trust_file(cert_cred, X509CA, GNUTLS_X509_FMT_PEM) < 0)
vlog.error("Could not load user specified certificate authority");
- if (*crlfile && gnutls_certificate_set_x509_crl_file(cert_cred,crlfile,GNUTLS_X509_FMT_PEM) < 0)
+ if (gnutls_certificate_set_x509_crl_file(cert_cred, X509CRL, GNUTLS_X509_FMT_PEM) < 0)
vlog.error("Could not load user specified certificate revocation list");
if (gnutls_credentials_set(session, GNUTLS_CRD_CERTIFICATE, cert_cred) != GNUTLS_E_SUCCESS)
@@ -316,7 +310,7 @@ void CSecurityTLS::checkSession()
unsigned int cert_list_size = 0;
int err;
- char *homeDir;
+ const char *homeDir;
gnutls_datum_t info;
size_t len;
@@ -361,12 +355,14 @@ void CSecurityTLS::checkSession()
throw AuthFailureException("decoding of certificate failed");
if (gnutls_x509_crt_check_hostname(crt, client->getServerName()) == 0) {
- CharArray text;
+ std::string text;
vlog.debug("hostname mismatch");
- text.format("Hostname (%s) does not match the server certificate, "
- "do you want to continue?", client->getServerName());
+ text = format("Hostname (%s) does not match the server "
+ "certificate, do you want to continue?",
+ client->getServerName());
if (!msg->showMsgBox(UserMsgBox::M_YESNO,
- "Certificate hostname mismatch", text.buf))
+ "Certificate hostname mismatch",
+ text.c_str()))
throw AuthFailureException("Certificate hostname mismatch");
}
@@ -396,17 +392,16 @@ void CSecurityTLS::checkSession()
/* Certificate is fine, except we don't know the issuer, so TOFU time */
- homeDir = NULL;
- if (getvnchomedir(&homeDir) == -1) {
+ homeDir = os::getvnchomedir();
+ if (homeDir == NULL) {
throw AuthFailureException("Could not obtain VNC home directory "
"path for known hosts storage");
}
- CharArray dbPath(strlen(homeDir) + 16 + 1);
- sprintf(dbPath.buf, "%sx509_known_hosts", homeDir);
- delete [] homeDir;
+ std::string dbPath;
+ dbPath = (std::string)homeDir + "/x509_known_hosts";
- err = gnutls_verify_stored_pubkey(dbPath.buf, NULL,
+ err = gnutls_verify_stored_pubkey(dbPath.c_str(), NULL,
client->getServerName(), NULL,
GNUTLS_CRT_X509, &cert_list[0], 0);
@@ -433,73 +428,93 @@ void CSecurityTLS::checkSession()
/* New host */
if (err == GNUTLS_E_NO_CERTIFICATE_FOUND) {
- CharArray text;
+ std::string text;
vlog.debug("Server host not previously known");
vlog.debug("%s", info.data);
if (status & (GNUTLS_CERT_SIGNER_NOT_FOUND |
GNUTLS_CERT_SIGNER_NOT_CA)) {
- text.format("This certificate has been signed by an unknown "
- "authority:\n\n%s\n\nSomeone could be trying to "
- "impersonate the site and you should not "
- "continue.\n\nDo you want to make an exception "
- "for this server?", info.data);
+ text = format("This certificate has been signed by an unknown "
+ "authority:\n"
+ "\n"
+ "%s\n"
+ "\n"
+ "Someone could be trying to impersonate the site "
+ "and you should not continue.\n"
+ "\n"
+ "Do you want to make an exception for this "
+ "server?", info.data);
if (!msg->showMsgBox(UserMsgBox::M_YESNO,
"Unknown certificate issuer",
- text.buf))
+ text.c_str()))
throw AuthFailureException("Unknown certificate issuer");
}
if (status & GNUTLS_CERT_EXPIRED) {
- text.format("This certificate has expired:\n\n%s\n\nSomeone "
- "could be trying to impersonate the site and you "
- "should not continue.\n\nDo you want to make an "
- "exception for this server?", info.data);
+ text = format("This certificate has expired:\n"
+ "\n"
+ "%s\n"
+ "\n"
+ "Someone could be trying to impersonate the site "
+ "and you should not continue.\n"
+ "\n"
+ "Do you want to make an exception for this "
+ "server?", info.data);
if (!msg->showMsgBox(UserMsgBox::M_YESNO,
"Expired certificate",
- text.buf))
+ text.c_str()))
throw AuthFailureException("Expired certificate");
}
} else if (err == GNUTLS_E_CERTIFICATE_KEY_MISMATCH) {
- CharArray text;
+ std::string text;
vlog.debug("Server host key mismatch");
vlog.debug("%s", info.data);
if (status & (GNUTLS_CERT_SIGNER_NOT_FOUND |
GNUTLS_CERT_SIGNER_NOT_CA)) {
- text.format("This host is previously known with a different "
- "certificate, and the new certificate has been "
- "signed by an unknown authority:\n\n%s\n\nSomeone "
- "could be trying to impersonate the site and you "
- "should not continue.\n\nDo you want to make an "
- "exception for this server?", info.data);
+ text = format("This host is previously known with a different "
+ "certificate, and the new certificate has been "
+ "signed by an unknown authority:\n"
+ "\n"
+ "%s\n"
+ "\n"
+ "Someone could be trying to impersonate the site "
+ "and you should not continue.\n"
+ "\n"
+ "Do you want to make an exception for this "
+ "server?", info.data);
if (!msg->showMsgBox(UserMsgBox::M_YESNO,
"Unexpected server certificate",
- text.buf))
+ text.c_str()))
throw AuthFailureException("Unexpected server certificate");
}
if (status & GNUTLS_CERT_EXPIRED) {
- text.format("This host is previously known with a different "
- "certificate, and the new certificate has expired:"
- "\n\n%s\n\nSomeone could be trying to impersonate "
- "the site and you should not continue.\n\nDo you "
- "want to make an exception for this server?",
- info.data);
+ text = format("This host is previously known with a different "
+ "certificate, and the new certificate has "
+ "expired:\n"
+ "\n"
+ "%s\n"
+ "\n"
+ "Someone could be trying to impersonate the site "
+ "and you should not continue.\n"
+ "\n"
+ "Do you want to make an exception for this "
+ "server?", info.data);
if (!msg->showMsgBox(UserMsgBox::M_YESNO,
"Unexpected server certificate",
- text.buf))
+ text.c_str()))
throw AuthFailureException("Unexpected server certificate");
}
}
- if (gnutls_store_pubkey(dbPath.buf, NULL, client->getServerName(),
+ if (gnutls_store_pubkey(dbPath.c_str(), NULL, client->getServerName(),
NULL, GNUTLS_CRT_X509, &cert_list[0], 0, 0))
vlog.error("Failed to store server certificate to known hosts database");
diff --git a/common/rfb/CSecurityTLS.h b/common/rfb/CSecurityTLS.h
index fb317748..b9c345cf 100644
--- a/common/rfb/CSecurityTLS.h
+++ b/common/rfb/CSecurityTLS.h
@@ -58,8 +58,6 @@ namespace rfb {
gnutls_certificate_credentials_t cert_cred;
bool anon;
- char *cafile, *crlfile;
-
rdr::InStream* tlsis;
rdr::OutStream* tlsos;
diff --git a/common/rfb/CSecurityVeNCrypt.cxx b/common/rfb/CSecurityVeNCrypt.cxx
index 046cd8d0..59be49a0 100644
--- a/common/rfb/CSecurityVeNCrypt.cxx
+++ b/common/rfb/CSecurityVeNCrypt.cxx
@@ -86,7 +86,8 @@ bool CSecurityVeNCrypt::processMsg()
}
/* major version in upper 8 bits and minor version in lower 8 bits */
- U16 Version = (((U16) majorVersion) << 8) | ((U16) minorVersion);
+ uint16_t Version = (((uint16_t) majorVersion) << 8) |
+ ((uint16_t) minorVersion);
if (!haveSentVersion) {
/* Currently we don't support former VeNCrypt 0.1 */
@@ -131,7 +132,7 @@ bool CSecurityVeNCrypt::processMsg()
if (!nAvailableTypes)
throw AuthFailureException("The server reported no VeNCrypt sub-types");
- availableTypes = new rdr::U32[nAvailableTypes];
+ availableTypes = new uint32_t[nAvailableTypes];
haveNumberOfTypes = true;
}
@@ -154,9 +155,9 @@ bool CSecurityVeNCrypt::processMsg()
/* make a choice and send it to the server, meanwhile set up the stack */
if (!haveChosenType) {
chosenType = secTypeInvalid;
- U8 i;
- list<U32>::iterator j;
- list<U32> secTypes;
+ uint8_t i;
+ list<uint32_t>::iterator j;
+ list<uint32_t> secTypes;
secTypes = security->GetEnabledExtSecTypes();
diff --git a/common/rfb/CSecurityVeNCrypt.h b/common/rfb/CSecurityVeNCrypt.h
index d087b2a4..476bf813 100644
--- a/common/rfb/CSecurityVeNCrypt.h
+++ b/common/rfb/CSecurityVeNCrypt.h
@@ -25,9 +25,10 @@
#ifndef __CSECURITYVENCRYPT_H__
#define __CSECURITYVENCRYPT_H__
+#include <stdint.h>
+
#include <rfb/CSecurity.h>
#include <rfb/SecurityClient.h>
-#include <rdr/types.h>
namespace rfb {
@@ -50,10 +51,10 @@ namespace rfb {
bool haveListOfTypes;
bool haveNumberOfTypes;
bool haveChosenType;
- rdr::U8 majorVersion, minorVersion;
- rdr::U32 chosenType;
- rdr::U8 nAvailableTypes;
- rdr::U32 *availableTypes;
+ uint8_t majorVersion, minorVersion;
+ uint32_t chosenType;
+ uint8_t nAvailableTypes;
+ uint32_t *availableTypes;
};
}
#endif
diff --git a/common/rfb/CSecurityVncAuth.cxx b/common/rfb/CSecurityVncAuth.cxx
index a899b5e7..f6a5e07a 100644
--- a/common/rfb/CSecurityVncAuth.cxx
+++ b/common/rfb/CSecurityVncAuth.cxx
@@ -29,9 +29,7 @@
#include <stdio.h>
#include <rfb/CConnection.h>
-#include <rfb/Password.h>
#include <rfb/CSecurityVncAuth.h>
-#include <rfb/util.h>
#include <rfb/Security.h>
extern "C" {
#include <rfb/d3des.h>
@@ -53,16 +51,15 @@ bool CSecurityVncAuth::processMsg()
return false;
// Read the challenge & obtain the user's password
- rdr::U8 challenge[vncAuthChallengeSize];
+ uint8_t challenge[vncAuthChallengeSize];
is->readBytes(challenge, vncAuthChallengeSize);
- PlainPasswd passwd;
- (CSecurity::upg)->getUserPasswd(cc->isSecure(), 0, &passwd.buf);
+ std::string passwd;
+ (CSecurity::upg)->getUserPasswd(cc->isSecure(), 0, &passwd);
// Calculate the correct response
- rdr::U8 key[8];
- int pwdLen = strlen(passwd.buf);
- for (int i=0; i<8; i++)
- key[i] = i<pwdLen ? passwd.buf[i] : 0;
+ uint8_t key[8];
+ for (size_t i=0; i<8; i++)
+ key[i] = i<passwd.size() ? passwd[i] : 0;
deskey(key, EN0);
for (int j = 0; j < vncAuthChallengeSize; j += 8)
des(challenge+j, challenge+j);
diff --git a/common/rfb/ClientParams.cxx b/common/rfb/ClientParams.cxx
index d933aa34..ade99018 100644
--- a/common/rfb/ClientParams.cxx
+++ b/common/rfb/ClientParams.cxx
@@ -34,7 +34,7 @@ ClientParams::ClientParams()
: majorVersion(0), minorVersion(0),
compressLevel(2), qualityLevel(-1), fineQualityLevel(-1),
subsampling(subsampleUndefined),
- width_(0), height_(0), name_(0),
+ width_(0), height_(0),
cursorPos_(0, 0), ledState_(ledUnknown)
{
setName("");
@@ -49,7 +49,6 @@ ClientParams::ClientParams()
ClientParams::~ClientParams()
{
- delete [] name_;
delete cursor_;
}
@@ -80,8 +79,7 @@ void ClientParams::setPF(const PixelFormat& pf)
void ClientParams::setName(const char* name)
{
- delete [] name_;
- name_ = strDup(name);
+ name_ = name;
}
void ClientParams::setCursor(const Cursor& other)
@@ -95,12 +93,12 @@ void ClientParams::setCursorPos(const Point& pos)
cursorPos_ = pos;
}
-bool ClientParams::supportsEncoding(rdr::S32 encoding) const
+bool ClientParams::supportsEncoding(int32_t encoding) const
{
return encodings_.count(encoding) != 0;
}
-void ClientParams::setEncodings(int nEncodings, const rdr::S32* encodings)
+void ClientParams::setEncodings(int nEncodings, const int32_t* encodings)
{
compressLevel = -1;
qualityLevel = -1;
@@ -153,7 +151,7 @@ void ClientParams::setLEDState(unsigned int state)
ledState_ = state;
}
-rdr::U32 ClientParams::clipboardSize(unsigned int format) const
+uint32_t ClientParams::clipboardSize(unsigned int format) const
{
int i;
@@ -165,7 +163,7 @@ rdr::U32 ClientParams::clipboardSize(unsigned int format) const
throw Exception("Invalid clipboard format 0x%x", format);
}
-void ClientParams::setClipboardCaps(rdr::U32 flags, const rdr::U32* lengths)
+void ClientParams::setClipboardCaps(uint32_t flags, const uint32_t* lengths)
{
int i, num;
diff --git a/common/rfb/ClientParams.h b/common/rfb/ClientParams.h
index a78ad14c..ea86ea78 100644
--- a/common/rfb/ClientParams.h
+++ b/common/rfb/ClientParams.h
@@ -24,8 +24,10 @@
#define __RFB_CLIENTPARAMS_H__
#include <set>
+#include <string>
+
+#include <stdint.h>
-#include <rdr/types.h>
#include <rfb/Cursor.h>
#include <rfb/PixelFormat.h>
#include <rfb/ScreenSet.h>
@@ -71,7 +73,7 @@ namespace rfb {
const PixelFormat& pf() const { return pf_; }
void setPF(const PixelFormat& pf);
- const char* name() const { return name_; }
+ const char* name() const { return name_.c_str(); }
void setName(const char* name);
const Cursor& cursor() const { return *cursor_; }
@@ -80,16 +82,16 @@ namespace rfb {
const Point& cursorPos() const { return cursorPos_; }
void setCursorPos(const Point& pos);
- bool supportsEncoding(rdr::S32 encoding) const;
+ bool supportsEncoding(int32_t encoding) const;
- void setEncodings(int nEncodings, const rdr::S32* encodings);
+ void setEncodings(int nEncodings, const int32_t* encodings);
unsigned int ledState() { return ledState_; }
void setLEDState(unsigned int state);
- rdr::U32 clipboardFlags() const { return clipFlags; }
- rdr::U32 clipboardSize(unsigned int format) const;
- void setClipboardCaps(rdr::U32 flags, const rdr::U32* lengths);
+ uint32_t clipboardFlags() const { return clipFlags; }
+ uint32_t clipboardSize(unsigned int format) const;
+ void setClipboardCaps(uint32_t flags, const uint32_t* lengths);
// Wrappers to check for functionality rather than specific
// encodings
@@ -112,13 +114,13 @@ namespace rfb {
ScreenSet screenLayout_;
PixelFormat pf_;
- char* name_;
+ std::string name_;
Cursor* cursor_;
Point cursorPos_;
- std::set<rdr::S32> encodings_;
+ std::set<int32_t> encodings_;
unsigned int ledState_;
- rdr::U32 clipFlags;
- rdr::U32 clipSizes[16];
+ uint32_t clipFlags;
+ uint32_t clipSizes[16];
};
}
#endif
diff --git a/common/rfb/ComparingUpdateTracker.cxx b/common/rfb/ComparingUpdateTracker.cxx
index e0964ac2..dab5e6aa 100644
--- a/common/rfb/ComparingUpdateTracker.cxx
+++ b/common/rfb/ComparingUpdateTracker.cxx
@@ -23,9 +23,11 @@
#include <stdio.h>
#include <string.h>
#include <vector>
-#include <rdr/types.h>
+
#include <rfb/Exception.h>
#include <rfb/LogWriter.h>
+#include <rfb/util.h>
+
#include <rfb/ComparingUpdateTracker.h>
using namespace rfb;
@@ -62,7 +64,7 @@ bool ComparingUpdateTracker::compare()
for (int y=0; y<fb->height(); y+=BLOCK_SIZE) {
Rect pos(0, y, fb->width(), __rfbmin(fb->height(), y+BLOCK_SIZE));
int srcStride;
- const rdr::U8* srcData = fb->getBuffer(pos, &srcStride);
+ const uint8_t* srcData = fb->getBuffer(pos, &srcStride);
oldFb.imageRect(pos, srcData, srcStride);
}
@@ -88,7 +90,7 @@ bool ComparingUpdateTracker::compare()
for (i = rects.begin(); i != rects.end(); i++)
missedPixels += i->area();
- if (changed.equals(newChanged))
+ if (changed == newChanged)
return false;
changed = newChanged;
@@ -122,7 +124,7 @@ void ComparingUpdateTracker::compareRect(const Rect& r, Region* newChanged)
int bytesPerPixel = fb->getPF().bpp/8;
int oldStride;
- rdr::U8* oldData = oldFb.getBufferRW(r, &oldStride);
+ uint8_t* oldData = oldFb.getBufferRW(r, &oldStride);
int oldStrideBytes = oldStride * bytesPerPixel;
// Used to efficiently crop the left and right of the change rectangle
@@ -134,16 +136,16 @@ void ComparingUpdateTracker::compareRect(const Rect& r, Region* newChanged)
// Get a strip of the source buffer
Rect pos(r.tl.x, blockTop, r.br.x, __rfbmin(r.br.y, blockTop+BLOCK_SIZE));
int fbStride;
- const rdr::U8* newBlockPtr = fb->getBuffer(pos, &fbStride);
+ const uint8_t* newBlockPtr = fb->getBuffer(pos, &fbStride);
int newStrideBytes = fbStride * bytesPerPixel;
- rdr::U8* oldBlockPtr = oldData;
+ uint8_t* oldBlockPtr = oldData;
int blockBottom = __rfbmin(blockTop+BLOCK_SIZE, r.br.y);
for (int blockLeft = r.tl.x; blockLeft < r.br.x; blockLeft += BLOCK_SIZE)
{
- const rdr::U8* newPtr = newBlockPtr;
- rdr::U8* oldPtr = oldBlockPtr;
+ const uint8_t* newPtr = newBlockPtr;
+ uint8_t* oldPtr = oldBlockPtr;
int blockRight = __rfbmin(blockLeft+BLOCK_SIZE, r.br.x);
int blockWidthInBytes = (blockRight-blockLeft) * bytesPerPixel;
@@ -160,8 +162,8 @@ void ComparingUpdateTracker::compareRect(const Rect& r, Region* newChanged)
// For every unchanged row at the bottom of the block, decrement change height
{
- const rdr::U8* newRowPtr = newPtr + ((changeHeight - 1) * newStrideBytes);
- const rdr::U8* oldRowPtr = oldPtr + ((changeHeight - 1) * oldStrideBytes);
+ const uint8_t* newRowPtr = newPtr + ((changeHeight - 1) * newStrideBytes);
+ const uint8_t* oldRowPtr = oldPtr + ((changeHeight - 1) * oldStrideBytes);
while (changeHeight > 1 && memcmp(oldRowPtr, newRowPtr, blockWidthInBytes) == 0)
{
newRowPtr -= newStrideBytes;
@@ -173,12 +175,12 @@ void ComparingUpdateTracker::compareRect(const Rect& r, Region* newChanged)
// For every unchanged column at the left of the block, increment change left
{
- const rdr::U8* newColumnPtr = newPtr;
- const rdr::U8* oldColumnPtr = oldPtr;
+ const uint8_t* newColumnPtr = newPtr;
+ const uint8_t* oldColumnPtr = oldPtr;
while (changeLeft + minCompareWidthInPixels < changeRight)
{
- const rdr::U8* newRowPtr = newColumnPtr;
- const rdr::U8* oldRowPtr = oldColumnPtr;
+ const uint8_t* newRowPtr = newColumnPtr;
+ const uint8_t* oldRowPtr = oldColumnPtr;
for (int row = 0; row < changeHeight; row++)
{
if (memcmp(oldRowPtr, newRowPtr, minCompareWidthInBytes) != 0)
@@ -198,15 +200,15 @@ void ComparingUpdateTracker::compareRect(const Rect& r, Region* newChanged)
// For every unchanged column at the right of the block, decrement change right
{
- const rdr::U8* newColumnPtr = newPtr + blockWidthInBytes;
- const rdr::U8* oldColumnPtr = oldPtr + blockWidthInBytes;
+ const uint8_t* newColumnPtr = newPtr + blockWidthInBytes;
+ const uint8_t* oldColumnPtr = oldPtr + blockWidthInBytes;
while (changeLeft + minCompareWidthInPixels < changeRight)
{
newColumnPtr -= minCompareWidthInBytes;
oldColumnPtr -= minCompareWidthInBytes;
- const rdr::U8* newRowPtr = newColumnPtr;
- const rdr::U8* oldRowPtr = oldColumnPtr;
+ const uint8_t* newRowPtr = newColumnPtr;
+ const uint8_t* oldRowPtr = oldColumnPtr;
for (int row = 0; row < changeHeight; row++)
{
if (memcmp(oldRowPtr, newRowPtr, minCompareWidthInBytes) != 0)
@@ -253,14 +255,12 @@ void ComparingUpdateTracker::compareRect(const Rect& r, Region* newChanged)
void ComparingUpdateTracker::logStats()
{
double ratio;
- char a[1024], b[1024];
-
- siPrefix(totalPixels, "pixels", a, sizeof(a));
- siPrefix(missedPixels, "pixels", b, sizeof(b));
ratio = (double)totalPixels / missedPixels;
- vlog.info("%s in / %s out", a, b);
+ vlog.info("%s in / %s out",
+ siPrefix(totalPixels, "pixels").c_str(),
+ siPrefix(missedPixels, "pixels").c_str());
vlog.info("(1:%g ratio)", ratio);
totalPixels = missedPixels = 0;
diff --git a/common/rfb/Configuration.cxx b/common/rfb/Configuration.cxx
index 8848e08d..1c215c7f 100644
--- a/common/rfb/Configuration.cxx
+++ b/common/rfb/Configuration.cxx
@@ -1,6 +1,7 @@
/* Copyright (C) 2002-2005 RealVNC Ltd. All Rights Reserved.
* Copyright 2004-2005 Cendio AB.
* Copyright 2017 Peter Astrand <astrand@cendio.se> for Cendio AB
+ * Copyright 2011-2022 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
@@ -24,6 +25,7 @@
#include <config.h>
#endif
+#include <assert.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
@@ -131,9 +133,9 @@ VoidParameter* Configuration::get(const char* param)
void Configuration::list(int width, int nameWidth) {
VoidParameter* current = head;
- fprintf(stderr, "%s Parameters:\n", name.buf);
+ fprintf(stderr, "%s Parameters:\n", name.c_str());
while (current) {
- char* def_str = current->getDefaultStr();
+ std::string def_str = current->getDefaultStr();
const char* desc = current->getDescription();
fprintf(stderr," %-*s -", nameWidth, current->getName());
int column = strlen(current->getName());
@@ -155,11 +157,10 @@ void Configuration::list(int width, int nameWidth) {
if (!s) break;
}
- if (def_str) {
- if (column + (int)strlen(def_str) + 11 > width)
+ if (!def_str.empty()) {
+ if (column + (int)def_str.size() + 11 > width)
fprintf(stderr,"\n%*s",nameWidth+4,"");
- fprintf(stderr," (default=%s)\n",def_str);
- strFree(def_str);
+ fprintf(stderr," (default=%s)\n",def_str.c_str());
} else {
fprintf(stderr,"\n");
}
@@ -255,12 +256,11 @@ bool AliasParameter::setParam() {
return param->setParam();
}
-char*
-AliasParameter::getDefaultStr() const {
- return 0;
+std::string AliasParameter::getDefaultStr() const {
+ return "";
}
-char* AliasParameter::getValueStr() const {
+std::string AliasParameter::getValueStr() const {
return param->getValueStr();
}
@@ -288,16 +288,15 @@ BoolParameter::setParam(const char* v) {
if (*v == 0 || strcasecmp(v, "1") == 0 || strcasecmp(v, "on") == 0
|| strcasecmp(v, "true") == 0 || strcasecmp(v, "yes") == 0)
- value = 1;
+ setParam(true);
else if (strcasecmp(v, "0") == 0 || strcasecmp(v, "off") == 0
|| strcasecmp(v, "false") == 0 || strcasecmp(v, "no") == 0)
- value = 0;
+ setParam(false);
else {
vlog.error("Bool parameter %s: invalid value '%s'", getName(), v);
return false;
}
- vlog.debug("set %s(Bool) to %s(%d)", getName(), v, value);
return true;
}
@@ -312,13 +311,12 @@ void BoolParameter::setParam(bool b) {
vlog.debug("set %s(Bool) to %d", getName(), value);
}
-char*
-BoolParameter::getDefaultStr() const {
- return strDup(def_value ? "1" : "0");
+std::string BoolParameter::getDefaultStr() const {
+ return def_value ? "1" : "0";
}
-char* BoolParameter::getValueStr() const {
- return strDup(value ? "1" : "0");
+std::string BoolParameter::getValueStr() const {
+ return value ? "1" : "0";
}
bool BoolParameter::isBool() const {
@@ -341,12 +339,7 @@ IntParameter::IntParameter(const char* name_, const char* desc_, int v,
bool
IntParameter::setParam(const char* v) {
if (immutable) return true;
- vlog.debug("set %s(Int) to %s", getName(), v);
- int i = strtol(v, NULL, 0);
- if (i < minValue || i > maxValue)
- return false;
- value = i;
- return true;
+ return setParam(strtol(v, NULL, 0));
}
bool
@@ -359,15 +352,14 @@ IntParameter::setParam(int v) {
return true;
}
-char*
-IntParameter::getDefaultStr() const {
- char* result = new char[16];
+std::string IntParameter::getDefaultStr() const {
+ char result[16];
sprintf(result, "%d", def_value);
return result;
}
-char* IntParameter::getValueStr() const {
- char* result = new char[16];
+std::string IntParameter::getValueStr() const {
+ char result[16];
sprintf(result, "%d", value);
return result;
}
@@ -380,7 +372,7 @@ IntParameter::operator int() const {
StringParameter::StringParameter(const char* name_, const char* desc_,
const char* v, ConfigurationObject co)
- : VoidParameter(name_, desc_, co), value(strDup(v)), def_value(strDup(v))
+ : VoidParameter(name_, desc_, co), value(v), def_value(v)
{
if (!v) {
vlog.error("Default value <null> for %s not allowed",name_);
@@ -389,8 +381,6 @@ StringParameter::StringParameter(const char* name_, const char* desc_,
}
StringParameter::~StringParameter() {
- strFree(value);
- strFree(def_value);
}
bool StringParameter::setParam(const char* v) {
@@ -399,34 +389,34 @@ bool StringParameter::setParam(const char* v) {
if (!v)
throw rfb::Exception("setParam(<null>) not allowed");
vlog.debug("set %s(String) to %s", getName(), v);
- CharArray oldValue(value);
- value = strDup(v);
- return value != 0;
+ value = v;
+ return true;
}
-char* StringParameter::getDefaultStr() const {
- return strDup(def_value);
+std::string StringParameter::getDefaultStr() const {
+ return def_value;
}
-char* StringParameter::getValueStr() const {
+std::string StringParameter::getValueStr() const {
LOCK_CONFIG;
- return strDup(value);
+ return value;
}
StringParameter::operator const char *() const {
- return value;
+ return value.c_str();
}
// -=- BinaryParameter
BinaryParameter::BinaryParameter(const char* name_, const char* desc_,
- const void* v, size_t l, ConfigurationObject co)
+ const uint8_t* v, size_t l, ConfigurationObject co)
: VoidParameter(name_, desc_, co), value(0), length(0), def_value(0), def_length(0) {
if (l) {
- value = new char[l];
+ assert(v);
+ value = new uint8_t[l];
length = l;
memcpy(value, v, l);
- def_value = new char[l];
+ def_value = new uint8_t[l];
def_length = l;
memcpy(def_value, v, l);
}
@@ -437,38 +427,41 @@ BinaryParameter::~BinaryParameter() {
}
bool BinaryParameter::setParam(const char* v) {
- LOCK_CONFIG;
if (immutable) return true;
- vlog.debug("set %s(Binary) to %s", getName(), v);
- return rdr::HexInStream::hexStrToBin(v, &value, &length);
+ std::vector<uint8_t> newValue = hexToBin(v, strlen(v));
+ if (newValue.empty() && strlen(v) > 0)
+ return false;
+ setParam(newValue.data(), newValue.size());
+ return true;
}
-void BinaryParameter::setParam(const void* v, size_t len) {
+void BinaryParameter::setParam(const uint8_t* v, size_t len) {
LOCK_CONFIG;
if (immutable) return;
vlog.debug("set %s(Binary)", getName());
- delete [] value; value = 0;
+ delete [] value;
+ value = NULL;
+ length = 0;
if (len) {
- value = new char[len];
+ assert(v);
+ value = new uint8_t[len];
length = len;
memcpy(value, v, len);
}
}
-char* BinaryParameter::getDefaultStr() const {
- return rdr::HexOutStream::binToHexStr(def_value, def_length);
+std::string BinaryParameter::getDefaultStr() const {
+ return binToHex(def_value, def_length);
}
-char* BinaryParameter::getValueStr() const {
+std::string BinaryParameter::getValueStr() const {
LOCK_CONFIG;
- return rdr::HexOutStream::binToHexStr(value, length);
+ return binToHex(value, length);
}
-void BinaryParameter::getData(void** data_, size_t* length_) const {
+std::vector<uint8_t> BinaryParameter::getData() const {
LOCK_CONFIG;
- if (length_) *length_ = length;
- if (data_) {
- *data_ = new char[length];
- memcpy(*data_, value, length);
- }
+ std::vector<uint8_t> out(length);
+ memcpy(out.data(), value, length);
+ return out;
}
diff --git a/common/rfb/Configuration.h b/common/rfb/Configuration.h
index 396e40dd..d73d8005 100644
--- a/common/rfb/Configuration.h
+++ b/common/rfb/Configuration.h
@@ -1,4 +1,5 @@
/* Copyright (C) 2002-2005 RealVNC Ltd. All Rights Reserved.
+ * Copyright 2011-2022 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
@@ -43,7 +44,11 @@
#ifndef __RFB_CONFIGURATION_H__
#define __RFB_CONFIGURATION_H__
-#include <rfb/util.h>
+#include <limits.h>
+#include <stdint.h>
+
+#include <string>
+#include <vector>
namespace os { class Mutex; }
@@ -59,10 +64,10 @@ namespace rfb {
class Configuration {
public:
// - Create a new Configuration object
- Configuration(const char* name_) : name(strDup(name_)), head(0), _next(0) {}
+ Configuration(const char* name_) : name(name_), head(0), _next(0) {}
// - Return the buffer containing the Configuration's name
- const char* getName() const { return name.buf; }
+ const char* getName() const { return name.c_str(); }
// - Set named parameter to value
bool set(const char* param, const char* value, bool immutable=false);
@@ -128,7 +133,7 @@ namespace rfb {
friend struct ParameterIterator;
// Name for this Configuration
- CharArray name;
+ std::string name;
// - Pointer to first Parameter in this group
VoidParameter* head;
@@ -168,8 +173,8 @@ namespace rfb {
virtual bool setParam(const char* value) = 0;
virtual bool setParam();
- virtual char* getDefaultStr() const = 0;
- virtual char* getValueStr() const = 0;
+ virtual std::string getDefaultStr() const = 0;
+ virtual std::string getValueStr() const = 0;
virtual bool isBool() const;
virtual void setImmutable();
@@ -192,8 +197,8 @@ namespace rfb {
ConfigurationObject co=ConfGlobal);
virtual bool setParam(const char* value);
virtual bool setParam();
- virtual char* getDefaultStr() const;
- virtual char* getValueStr() const;
+ virtual std::string getDefaultStr() const;
+ virtual std::string getValueStr() const;
virtual bool isBool() const;
virtual void setImmutable();
private:
@@ -207,8 +212,8 @@ namespace rfb {
virtual bool setParam(const char* value);
virtual bool setParam();
virtual void setParam(bool b);
- virtual char* getDefaultStr() const;
- virtual char* getValueStr() const;
+ virtual std::string getDefaultStr() const;
+ virtual std::string getValueStr() const;
virtual bool isBool() const;
operator bool() const;
protected:
@@ -224,8 +229,8 @@ namespace rfb {
using VoidParameter::setParam;
virtual bool setParam(const char* value);
virtual bool setParam(int v);
- virtual char* getDefaultStr() const;
- virtual char* getValueStr() const;
+ virtual std::string getDefaultStr() const;
+ virtual std::string getValueStr() const;
operator int() const;
protected:
int value;
@@ -241,38 +246,32 @@ namespace rfb {
ConfigurationObject co=ConfGlobal);
virtual ~StringParameter();
virtual bool setParam(const char* value);
- virtual char* getDefaultStr() const;
- virtual char* getValueStr() const;
+ virtual std::string getDefaultStr() const;
+ virtual std::string getValueStr() const;
operator const char*() const;
-
- // getData() returns a copy of the data - it must be delete[]d by the
- // caller.
- char* getData() const { return getValueStr(); }
protected:
- char* value;
- char* def_value;
+ std::string value;
+ std::string def_value;
};
class BinaryParameter : public VoidParameter {
public:
BinaryParameter(const char* name_, const char* desc_,
- const void* v, size_t l,
+ const uint8_t* v, size_t l,
ConfigurationObject co=ConfGlobal);
using VoidParameter::setParam;
virtual ~BinaryParameter();
virtual bool setParam(const char* value);
- virtual void setParam(const void* v, size_t l);
- virtual char* getDefaultStr() const;
- virtual char* getValueStr() const;
+ virtual void setParam(const uint8_t* v, size_t l);
+ virtual std::string getDefaultStr() const;
+ virtual std::string getValueStr() const;
- // getData() will return length zero if there is no data
- // NB: data may be set to zero, OR set to a zero-length buffer
- void getData(void** data, size_t* length) const;
+ std::vector<uint8_t> getData() const;
protected:
- char* value;
+ uint8_t* value;
size_t length;
- char* def_value;
+ uint8_t* def_value;
size_t def_length;
};
diff --git a/common/rfb/Congestion.cxx b/common/rfb/Congestion.cxx
index f642752e..1e252165 100644
--- a/common/rfb/Congestion.cxx
+++ b/common/rfb/Congestion.cxx
@@ -38,6 +38,7 @@
#endif
#include <assert.h>
+#include <string.h>
#include <sys/time.h>
#ifdef __linux__
diff --git a/common/rfb/Cursor.cxx b/common/rfb/Cursor.cxx
index 425cc8c4..f0c72eed 100644
--- a/common/rfb/Cursor.cxx
+++ b/common/rfb/Cursor.cxx
@@ -1,5 +1,5 @@
/* Copyright (C) 2002-2005 RealVNC Ltd. All Rights Reserved.
- * Copyright 2014-2017 Pierre Ossman for Cendio AB
+ * Copyright 2014-2023 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
@@ -23,6 +23,7 @@
#include <assert.h>
#include <string.h>
+
#include <rfb/Cursor.h>
#include <rfb/LogWriter.h>
#include <rfb/Exception.h>
@@ -32,10 +33,10 @@ using namespace rfb;
static LogWriter vlog("Cursor");
Cursor::Cursor(int width, int height, const Point& hotspot,
- const rdr::U8* data) :
+ const uint8_t* data) :
width_(width), height_(height), hotspot_(hotspot)
{
- this->data = new rdr::U8[width_*height_*4];
+ this->data = new uint8_t[width_*height_*4];
memcpy(this->data, data, width_*height_*4);
}
@@ -43,7 +44,7 @@ Cursor::Cursor(const Cursor& other) :
width_(other.width_), height_(other.height_),
hotspot_(other.hotspot_)
{
- data = new rdr::U8[width_*height_*4];
+ data = new uint8_t[width_*height_*4];
memcpy(data, other.data, width_*height_*4);
}
@@ -81,7 +82,7 @@ static unsigned short srgb_to_lin(unsigned char srgb)
}
// Floyd-Steinberg dithering
-static void dither(int width, int height, rdr::S32* data)
+static void dither(int width, int height, int32_t* data)
{
for (int y = 0; y < height; y++) {
for (int x_ = 0; x_ < width; x_++) {
@@ -124,21 +125,21 @@ static void dither(int width, int height, rdr::S32* data)
}
}
-rdr::U8* Cursor::getBitmap() const
+std::vector<uint8_t> Cursor::getBitmap() const
{
// First step is converting to luminance
- rdr::S32Array luminance(width()*height());
- rdr::S32 *lum_ptr = luminance.buf;
- const rdr::U8 *data_ptr = data;
+ std::vector<int32_t> luminance(width()*height());
+ int32_t *lum_ptr = luminance.data();
+ const uint8_t *data_ptr = data;
for (int y = 0; y < height(); y++) {
for (int x = 0; x < width(); x++) {
- rdr::S32 lum;
+ int32_t lum;
// Use BT.709 coefficients for grayscale
lum = 0;
- lum += (rdr::U32)srgb_to_lin(data_ptr[0]) * 6947; // 0.2126
- lum += (rdr::U32)srgb_to_lin(data_ptr[1]) * 23436; // 0.7152
- lum += (rdr::U32)srgb_to_lin(data_ptr[2]) * 2366; // 0.0722
+ lum += (uint32_t)srgb_to_lin(data_ptr[0]) * 6947; // 0.2126
+ lum += (uint32_t)srgb_to_lin(data_ptr[1]) * 23436; // 0.7152
+ lum += (uint32_t)srgb_to_lin(data_ptr[2]) * 2366; // 0.0722
lum /= 32768;
*lum_ptr++ = lum;
@@ -147,62 +148,62 @@ rdr::U8* Cursor::getBitmap() const
}
// Then diterhing
- dither(width(), height(), luminance.buf);
+ dither(width(), height(), luminance.data());
// Then conversion to a bit mask
- rdr::U8Array source((width()+7)/8*height());
- memset(source.buf, 0, (width()+7)/8*height());
+ std::vector<uint8_t> source((width()+7)/8*height());
+ memset(source.data(), 0, source.size());
int maskBytesPerRow = (width() + 7) / 8;
- lum_ptr = luminance.buf;
+ lum_ptr = luminance.data();
data_ptr = data;
for (int y = 0; y < height(); y++) {
for (int x = 0; x < width(); x++) {
int byte = y * maskBytesPerRow + x / 8;
int bit = 7 - x % 8;
if (*lum_ptr > 32767)
- source.buf[byte] |= (1 << bit);
+ source[byte] |= (1 << bit);
lum_ptr++;
data_ptr += 4;
}
}
- return source.takeBuf();
+ return source;
}
-rdr::U8* Cursor::getMask() const
+std::vector<uint8_t> Cursor::getMask() const
{
// First step is converting to integer array
- rdr::S32Array alpha(width()*height());
- rdr::S32 *alpha_ptr = alpha.buf;
- const rdr::U8 *data_ptr = data;
+ std::vector<int32_t> alpha(width()*height());
+ int32_t *alpha_ptr = alpha.data();
+ const uint8_t *data_ptr = data;
for (int y = 0; y < height(); y++) {
for (int x = 0; x < width(); x++) {
- *alpha_ptr++ = (rdr::U32)data_ptr[3] * 65535 / 255;
+ *alpha_ptr++ = (uint32_t)data_ptr[3] * 65535 / 255;
data_ptr += 4;
}
}
// Then diterhing
- dither(width(), height(), alpha.buf);
+ dither(width(), height(), alpha.data());
// Then conversion to a bit mask
- rdr::U8Array mask((width()+7)/8*height());
- memset(mask.buf, 0, (width()+7)/8*height());
+ std::vector<uint8_t> mask((width()+7)/8*height());
+ memset(mask.data(), 0, mask.size());
int maskBytesPerRow = (width() + 7) / 8;
- alpha_ptr = alpha.buf;
+ alpha_ptr = alpha.data();
data_ptr = data;
for (int y = 0; y < height(); y++) {
for (int x = 0; x < width(); x++) {
int byte = y * maskBytesPerRow + x / 8;
int bit = 7 - x % 8;
if (*alpha_ptr > 32767)
- mask.buf[byte] |= (1 << bit);
+ mask[byte] |= (1 << bit);
alpha_ptr++;
data_ptr += 4;
}
}
- return mask.takeBuf();
+ return mask;
}
// crop() determines the "busy" rectangle for the cursor - the minimum bounding
@@ -217,7 +218,7 @@ void Cursor::crop()
busy = busy.intersect(Rect(hotspot_.x, hotspot_.y,
hotspot_.x+1, hotspot_.y+1));
int x, y;
- rdr::U8 *data_ptr = data;
+ uint8_t *data_ptr = data;
for (y = 0; y < height(); y++) {
for (x = 0; x < width(); x++) {
if (data_ptr[3] > 0) {
@@ -234,7 +235,7 @@ void Cursor::crop()
// Copy the pixel data
int newDataLen = busy.area() * 4;
- rdr::U8* newData = new rdr::U8[newDataLen];
+ uint8_t* newData = new uint8_t[newDataLen];
data_ptr = newData;
for (y = busy.tl.y; y < busy.br.y; y++) {
memcpy(data_ptr, data + y*width()*4 + busy.tl.x*4, busy.width()*4);
@@ -253,7 +254,7 @@ RenderedCursor::RenderedCursor()
{
}
-const rdr::U8* RenderedCursor::getBuffer(const Rect& _r, int* stride) const
+const uint8_t* RenderedCursor::getBuffer(const Rect& _r, int* stride) const
{
Rect r;
@@ -270,7 +271,7 @@ void RenderedCursor::update(PixelBuffer* framebuffer,
Point rawOffset, diff;
Rect clippedRect;
- const rdr::U8* data;
+ const uint8_t* data;
int stride;
assert(framebuffer);
@@ -300,8 +301,8 @@ void RenderedCursor::update(PixelBuffer* framebuffer,
for (int y = 0;y < buffer.height();y++) {
for (int x = 0;x < buffer.width();x++) {
size_t idx;
- rdr::U8 bg[4], fg[4];
- rdr::U8 rgb[3];
+ uint8_t bg[4], fg[4];
+ uint8_t rgb[3];
idx = (y+diff.y)*cursor->width() + (x+diff.x);
memcpy(fg, cursor->getBuffer() + idx*4, 4);
diff --git a/common/rfb/Cursor.h b/common/rfb/Cursor.h
index 6c6db7ee..31d6fda9 100644
--- a/common/rfb/Cursor.h
+++ b/common/rfb/Cursor.h
@@ -1,5 +1,5 @@
/* Copyright (C) 2002-2005 RealVNC Ltd. All Rights Reserved.
- * Copyright 2014-2017 Pierre Ossman for Cendio AB
+ * Copyright 2014-2023 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
@@ -24,25 +24,27 @@
#ifndef __RFB_CURSOR_H__
#define __RFB_CURSOR_H__
+#include <vector>
+
#include <rfb/PixelBuffer.h>
namespace rfb {
class Cursor {
public:
- Cursor(int width, int height, const Point& hotspot, const rdr::U8* data);
+ Cursor(int width, int height, const Point& hotspot, const uint8_t* data);
Cursor(const Cursor& other);
~Cursor();
int width() const { return width_; };
int height() const { return height_; };
const Point& hotspot() const { return hotspot_; };
- const rdr::U8* getBuffer() const { return data; };
+ const uint8_t* getBuffer() const { return data; };
// getBitmap() returns a monochrome version of the cursor
- rdr::U8* getBitmap() const;
+ std::vector<uint8_t> getBitmap() const;
// getMask() returns a simple mask version of the alpha channel
- rdr::U8* getMask() const;
+ std::vector<uint8_t> getMask() const;
// crop() crops the cursor down to the smallest possible size, based on the
// mask.
@@ -51,7 +53,7 @@ namespace rfb {
protected:
int width_, height_;
Point hotspot_;
- rdr::U8* data;
+ uint8_t* data;
};
class RenderedCursor : public PixelBuffer {
@@ -60,7 +62,7 @@ namespace rfb {
Rect getEffectiveRect() const { return buffer.getRect(offset); }
- virtual const rdr::U8* getBuffer(const Rect& r, int* stride) const;
+ virtual const uint8_t* getBuffer(const Rect& r, int* stride) const;
void update(PixelBuffer* framebuffer, Cursor* cursor, const Point& pos);
diff --git a/common/rfb/DecodeManager.cxx b/common/rfb/DecodeManager.cxx
index b9faf689..e39a3943 100644
--- a/common/rfb/DecodeManager.cxx
+++ b/common/rfb/DecodeManager.cxx
@@ -28,8 +28,8 @@
#include <rfb/Decoder.h>
#include <rfb/Exception.h>
#include <rfb/Region.h>
-
#include <rfb/LogWriter.h>
+#include <rfb/util.h>
#include <rdr/Exception.h>
#include <rdr/MemOutStream.h>
@@ -211,8 +211,6 @@ void DecodeManager::logStats()
double ratio;
- char a[1024], b[1024];
-
rects = 0;
pixels = bytes = equivalent = 0;
@@ -228,22 +226,21 @@ void DecodeManager::logStats()
ratio = (double)stats[i].equivalent / stats[i].bytes;
- siPrefix(stats[i].rects, "rects", a, sizeof(a));
- siPrefix(stats[i].pixels, "pixels", b, sizeof(b));
- vlog.info(" %s: %s, %s", encodingName(i), a, b);
- iecPrefix(stats[i].bytes, "B", a, sizeof(a));
+ vlog.info(" %s: %s, %s", encodingName(i),
+ siPrefix(stats[i].rects, "rects").c_str(),
+ siPrefix(stats[i].pixels, "pixels").c_str());
vlog.info(" %*s %s (1:%g ratio)",
(int)strlen(encodingName(i)), "",
- a, ratio);
+ iecPrefix(stats[i].bytes, "B").c_str(), ratio);
}
ratio = (double)equivalent / bytes;
- siPrefix(rects, "rects", a, sizeof(a));
- siPrefix(pixels, "pixels", b, sizeof(b));
- vlog.info(" Total: %s, %s", a, b);
- iecPrefix(bytes, "B", a, sizeof(a));
- vlog.info(" %s (1:%g ratio)", a, ratio);
+ vlog.info(" Total: %s, %s",
+ siPrefix(rects, "rects").c_str(),
+ siPrefix(pixels, "pixels").c_str());
+ vlog.info(" %s (1:%g ratio)",
+ iecPrefix(bytes, "B").c_str(), ratio);
}
void DecodeManager::setThreadException(const rdr::Exception& e)
diff --git a/common/rfb/EncodeManager.cxx b/common/rfb/EncodeManager.cxx
index 6a78939e..bc15e74a 100644
--- a/common/rfb/EncodeManager.cxx
+++ b/common/rfb/EncodeManager.cxx
@@ -1,6 +1,6 @@
/* Copyright (C) 2000-2003 Constantin Kaplinsky. All Rights Reserved.
* Copyright (C) 2011 D. R. Commander. All Rights Reserved.
- * Copyright 2014-2018 Pierre Ossman for Cendio AB
+ * Copyright 2014-2022 Pierre Ossman for Cendio AB
* Copyright 2018 Peter Astrand for Cendio AB
*
* This is free software; you can redistribute it and/or modify
@@ -33,6 +33,7 @@
#include <rfb/UpdateTracker.h>
#include <rfb/LogWriter.h>
#include <rfb/Exception.h>
+#include <rfb/util.h>
#include <rfb/RawEncoder.h>
#include <rfb/RREEncoder.h>
@@ -177,8 +178,6 @@ void EncodeManager::logStats()
double ratio;
- char a[1024], b[1024];
-
rects = 0;
pixels = bytes = equivalent = 0;
@@ -194,13 +193,12 @@ void EncodeManager::logStats()
ratio = (double)copyStats.equivalent / copyStats.bytes;
- siPrefix(copyStats.rects, "rects", a, sizeof(a));
- siPrefix(copyStats.pixels, "pixels", b, sizeof(b));
- vlog.info(" %s: %s, %s", "Copies", a, b);
- iecPrefix(copyStats.bytes, "B", a, sizeof(a));
+ vlog.info(" %s: %s, %s", "Copies",
+ siPrefix(copyStats.rects, "rects").c_str(),
+ siPrefix(copyStats.pixels, "pixels").c_str());
vlog.info(" %*s %s (1:%g ratio)",
(int)strlen("Copies"), "",
- a, ratio);
+ iecPrefix(copyStats.bytes, "B").c_str(), ratio);
}
for (i = 0;i < stats.size();i++) {
@@ -225,23 +223,22 @@ void EncodeManager::logStats()
ratio = (double)stats[i][j].equivalent / stats[i][j].bytes;
- siPrefix(stats[i][j].rects, "rects", a, sizeof(a));
- siPrefix(stats[i][j].pixels, "pixels", b, sizeof(b));
- vlog.info(" %s: %s, %s", encoderTypeName((EncoderType)j), a, b);
- iecPrefix(stats[i][j].bytes, "B", a, sizeof(a));
+ vlog.info(" %s: %s, %s", encoderTypeName((EncoderType)j),
+ siPrefix(stats[i][j].rects, "rects").c_str(),
+ siPrefix(stats[i][j].pixels, "pixels").c_str());
vlog.info(" %*s %s (1:%g ratio)",
(int)strlen(encoderTypeName((EncoderType)j)), "",
- a, ratio);
+ iecPrefix(stats[i][j].bytes, "B").c_str(), ratio);
}
}
ratio = (double)equivalent / bytes;
- siPrefix(rects, "rects", a, sizeof(a));
- siPrefix(pixels, "pixels", b, sizeof(b));
- vlog.info(" Total: %s, %s", a, b);
- iecPrefix(bytes, "B", a, sizeof(a));
- vlog.info(" %s (1:%g ratio)", a, ratio);
+ vlog.info(" Total: %s, %s",
+ siPrefix(rects, "rects").c_str(),
+ siPrefix(pixels, "pixels").c_str());
+ vlog.info(" %s (1:%g ratio)",
+ iecPrefix(bytes, "B").c_str(), ratio);
}
bool EncodeManager::supported(int encoding)
@@ -377,7 +374,7 @@ void EncodeManager::prepareEncoders(bool allowLossy)
bool allowJPEG;
- rdr::S32 preferred;
+ int32_t preferred;
std::vector<int>::iterator iter;
@@ -678,8 +675,8 @@ void EncodeManager::findSolidRect(const Rect& rect, Region *changed,
for (dx = rect.tl.x; dx < rect.br.x; dx += SolidSearchBlock) {
// We define it like this to guarantee alignment
- rdr::U32 _buffer;
- rdr::U8* colourValue = (rdr::U8*)&_buffer;
+ uint32_t _buffer;
+ uint8_t* colourValue = (uint8_t*)&_buffer;
dw = SolidSearchBlock;
if (dx + dw > rect.br.x)
@@ -700,7 +697,7 @@ void EncodeManager::findSolidRect(const Rect& rect, Region *changed,
extendSolidAreaByBlock(sr, colourValue, pb, &erb);
// Did we end up getting the entire rectangle?
- if (erb.equals(rect))
+ if (erb == rect)
erp = erb;
else {
// Don't bother with sending tiny rectangles
@@ -718,8 +715,8 @@ void EncodeManager::findSolidRect(const Rect& rect, Region *changed,
encoder->writeSolidRect(erp.width(), erp.height(),
pb->getPF(), colourValue);
} else {
- rdr::U32 _buffer2;
- rdr::U8* converted = (rdr::U8*)&_buffer2;
+ uint32_t _buffer2;
+ uint8_t* converted = (uint8_t*)&_buffer2;
conn->client.pf().bufferFromBuffer(converted, pb->getPF(),
colourValue, 1);
@@ -886,21 +883,21 @@ void EncodeManager::writeSubRect(const Rect& rect, const PixelBuffer *pb)
endRect();
}
-bool EncodeManager::checkSolidTile(const Rect& r, const rdr::U8* colourValue,
+bool EncodeManager::checkSolidTile(const Rect& r, const uint8_t* colourValue,
const PixelBuffer *pb)
{
switch (pb->getPF().bpp) {
case 32:
- return checkSolidTile(r, *(const rdr::U32*)colourValue, pb);
+ return checkSolidTile(r, *(const uint32_t*)colourValue, pb);
case 16:
- return checkSolidTile(r, *(const rdr::U16*)colourValue, pb);
+ return checkSolidTile(r, *(const uint16_t*)colourValue, pb);
default:
- return checkSolidTile(r, *(const rdr::U8*)colourValue, pb);
+ return checkSolidTile(r, *(const uint8_t*)colourValue, pb);
}
}
void EncodeManager::extendSolidAreaByBlock(const Rect& r,
- const rdr::U8* colourValue,
+ const uint8_t* colourValue,
const PixelBuffer *pb, Rect* er)
{
int dx, dy, dw, dh;
@@ -956,7 +953,7 @@ void EncodeManager::extendSolidAreaByBlock(const Rect& r,
}
void EncodeManager::extendSolidAreaByPixel(const Rect& r, const Rect& sr,
- const rdr::U8* colourValue,
+ const uint8_t* colourValue,
const PixelBuffer *pb, Rect* er)
{
int cx, cy;
@@ -999,11 +996,11 @@ PixelBuffer* EncodeManager::preparePixelBuffer(const Rect& rect,
const PixelBuffer *pb,
bool convert)
{
- const rdr::U8* buffer;
+ const uint8_t* buffer;
int stride;
// Do wo need to convert the data?
- if (convert && !conn->client.pf().equal(pb->getPF())) {
+ if (convert && conn->client.pf() != pb->getPF()) {
convertedPixelBuffer.setPF(conn->client.pf());
convertedPixelBuffer.setSize(rect.width(), rect.height());
@@ -1029,7 +1026,7 @@ PixelBuffer* EncodeManager::preparePixelBuffer(const Rect& rect,
bool EncodeManager::analyseRect(const PixelBuffer *pb,
struct RectInfo *info, int maxColours)
{
- const rdr::U8* buffer;
+ const uint8_t* buffer;
int stride;
buffer = pb->getBuffer(pb->getRect(), &stride);
@@ -1037,42 +1034,106 @@ bool EncodeManager::analyseRect(const PixelBuffer *pb,
switch (pb->getPF().bpp) {
case 32:
return analyseRect(pb->width(), pb->height(),
- (const rdr::U32*)buffer, stride,
+ (const uint32_t*)buffer, stride,
info, maxColours);
case 16:
return analyseRect(pb->width(), pb->height(),
- (const rdr::U16*)buffer, stride,
+ (const uint16_t*)buffer, stride,
info, maxColours);
default:
return analyseRect(pb->width(), pb->height(),
- (const rdr::U8*)buffer, stride,
+ (const uint8_t*)buffer, stride,
info, maxColours);
}
}
void EncodeManager::OffsetPixelBuffer::update(const PixelFormat& pf,
int width, int height,
- const rdr::U8* data_,
+ const uint8_t* data_,
int stride_)
{
format = pf;
// Forced cast. We never write anything though, so it should be safe.
- setBuffer(width, height, (rdr::U8*)data_, stride_);
+ setBuffer(width, height, (uint8_t*)data_, stride_);
}
-rdr::U8* EncodeManager::OffsetPixelBuffer::getBufferRW(const Rect& /*r*/, int* /*stride*/)
+uint8_t* EncodeManager::OffsetPixelBuffer::getBufferRW(const Rect& /*r*/, int* /*stride*/)
{
throw rfb::Exception("Invalid write attempt to OffsetPixelBuffer");
}
-// Preprocessor generated, optimised methods
-
-#define BPP 8
-#include "EncodeManagerBPP.cxx"
-#undef BPP
-#define BPP 16
-#include "EncodeManagerBPP.cxx"
-#undef BPP
-#define BPP 32
-#include "EncodeManagerBPP.cxx"
-#undef BPP
+template<class T>
+inline bool EncodeManager::checkSolidTile(const Rect& r,
+ const T colourValue,
+ const PixelBuffer *pb)
+{
+ int w, h;
+ const T* buffer;
+ int stride, pad;
+
+ w = r.width();
+ h = r.height();
+
+ buffer = (const T*)pb->getBuffer(r, &stride);
+ pad = stride - w;
+
+ while (h--) {
+ int w_ = w;
+ while (w_--) {
+ if (*buffer != colourValue)
+ return false;
+ buffer++;
+ }
+ buffer += pad;
+ }
+
+ return true;
+}
+
+template<class T>
+inline bool EncodeManager::analyseRect(int width, int height,
+ const T* buffer, int stride,
+ struct RectInfo *info, int maxColours)
+{
+ int pad;
+
+ T colour;
+ int count;
+
+ info->rleRuns = 0;
+ info->palette.clear();
+
+ pad = stride - width;
+
+ // For efficiency, we only update the palette on changes in colour
+ colour = buffer[0];
+ count = 0;
+ while (height--) {
+ int w_ = width;
+ while (w_--) {
+ if (*buffer != colour) {
+ if (!info->palette.insert(colour, count))
+ return false;
+ if (info->palette.size() > maxColours)
+ return false;
+
+ // FIXME: This doesn't account for switching lines
+ info->rleRuns++;
+
+ colour = *buffer;
+ count = 0;
+ }
+ buffer++;
+ count++;
+ }
+ buffer += pad;
+ }
+
+ // Make sure the final pixels also get counted
+ if (!info->palette.insert(colour, count))
+ return false;
+ if (info->palette.size() > maxColours)
+ return false;
+
+ return true;
+}
diff --git a/common/rfb/EncodeManager.h b/common/rfb/EncodeManager.h
index f8201c34..f2fd4ca4 100644
--- a/common/rfb/EncodeManager.h
+++ b/common/rfb/EncodeManager.h
@@ -1,6 +1,6 @@
/* Copyright (C) 2000-2003 Constantin Kaplinsky. All Rights Reserved.
* Copyright (C) 2011 D. R. Commander. All Rights Reserved.
- * Copyright 2014-2018 Pierre Ossman for Cendio AB
+ * Copyright 2014-2022 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
@@ -22,7 +22,8 @@
#include <vector>
-#include <rdr/types.h>
+#include <stdint.h>
+
#include <rfb/PixelBuffer.h>
#include <rfb/Region.h>
#include <rfb/Timer.h>
@@ -82,12 +83,12 @@ namespace rfb {
void writeSubRect(const Rect& rect, const PixelBuffer *pb);
- bool checkSolidTile(const Rect& r, const rdr::U8* colourValue,
+ bool checkSolidTile(const Rect& r, const uint8_t* colourValue,
const PixelBuffer *pb);
- void extendSolidAreaByBlock(const Rect& r, const rdr::U8* colourValue,
+ void extendSolidAreaByBlock(const Rect& r, const uint8_t* colourValue,
const PixelBuffer *pb, Rect* er);
void extendSolidAreaByPixel(const Rect& r, const Rect& sr,
- const rdr::U8* colourValue,
+ const uint8_t* colourValue,
const PixelBuffer *pb, Rect* er);
PixelBuffer* preparePixelBuffer(const Rect& rect,
@@ -97,22 +98,13 @@ namespace rfb {
struct RectInfo *info, int maxColours);
protected:
- // Preprocessor generated, optimised methods
- inline bool checkSolidTile(const Rect& r, rdr::U8 colourValue,
- const PixelBuffer *pb);
- inline bool checkSolidTile(const Rect& r, rdr::U16 colourValue,
+ // Templated, optimised methods
+ template<class T>
+ inline bool checkSolidTile(const Rect& r, const T,
const PixelBuffer *pb);
- inline bool checkSolidTile(const Rect& r, rdr::U32 colourValue,
- const PixelBuffer *pb);
-
- inline bool analyseRect(int width, int height,
- const rdr::U8* buffer, int stride,
- struct RectInfo *info, int maxColours);
- inline bool analyseRect(int width, int height,
- const rdr::U16* buffer, int stride,
- struct RectInfo *info, int maxColours);
+ template<class T>
inline bool analyseRect(int width, int height,
- const rdr::U32* buffer, int stride,
+ const T* buffer, int stride,
struct RectInfo *info, int maxColours);
protected:
@@ -147,10 +139,10 @@ namespace rfb {
virtual ~OffsetPixelBuffer() {}
void update(const PixelFormat& pf, int width, int height,
- const rdr::U8* data_, int stride);
+ const uint8_t* data_, int stride);
private:
- virtual rdr::U8* getBufferRW(const Rect& r, int* stride);
+ virtual uint8_t* getBufferRW(const Rect& r, int* stride);
};
OffsetPixelBuffer offsetPixelBuffer;
diff --git a/common/rfb/EncodeManagerBPP.cxx b/common/rfb/EncodeManagerBPP.cxx
deleted file mode 100644
index 03612914..00000000
--- a/common/rfb/EncodeManagerBPP.cxx
+++ /dev/null
@@ -1,98 +0,0 @@
-/* Copyright (C) 2000-2003 Constantin Kaplinsky. All Rights Reserved.
- * Copyright (C) 2011 D. R. Commander. All Rights Reserved.
- * Copyright 2014 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.
- */
-
-#define CONCAT2(a,b) a##b
-#define CONCAT2E(a,b) CONCAT2(a,b)
-
-#define UBPP CONCAT2E(U,BPP)
-
-inline bool EncodeManager::checkSolidTile(const Rect& r,
- rdr::UBPP colourValue,
- const PixelBuffer *pb)
-{
- int w, h;
- const rdr::UBPP* buffer;
- int stride, pad;
-
- w = r.width();
- h = r.height();
-
- buffer = (const rdr::UBPP*)pb->getBuffer(r, &stride);
- pad = stride - w;
-
- while (h--) {
- int w_ = w;
- while (w_--) {
- if (*buffer != colourValue)
- return false;
- buffer++;
- }
- buffer += pad;
- }
-
- return true;
-}
-
-inline bool EncodeManager::analyseRect(int width, int height,
- const rdr::UBPP* buffer, int stride,
- struct RectInfo *info, int maxColours)
-{
- int pad;
-
- rdr::UBPP colour;
- int count;
-
- info->rleRuns = 0;
- info->palette.clear();
-
- pad = stride - width;
-
- // For efficiency, we only update the palette on changes in colour
- colour = buffer[0];
- count = 0;
- while (height--) {
- int w_ = width;
- while (w_--) {
- if (*buffer != colour) {
- if (!info->palette.insert(colour, count))
- return false;
- if (info->palette.size() > maxColours)
- return false;
-
- // FIXME: This doesn't account for switching lines
- info->rleRuns++;
-
- colour = *buffer;
- count = 0;
- }
- buffer++;
- count++;
- }
- buffer += pad;
- }
-
- // Make sure the final pixels also get counted
- if (!info->palette.insert(colour, count))
- return false;
- if (info->palette.size() > maxColours)
- return false;
-
- return true;
-}
diff --git a/common/rfb/Encoder.cxx b/common/rfb/Encoder.cxx
index d6d4a81d..35aa3d05 100644
--- a/common/rfb/Encoder.cxx
+++ b/common/rfb/Encoder.cxx
@@ -41,12 +41,12 @@ Encoder::~Encoder()
}
void Encoder::writeSolidRect(int width, int height,
- const PixelFormat& pf, const rdr::U8* colour)
+ const PixelFormat& pf, const uint8_t* colour)
{
ManagedPixelBuffer buffer(pf, width, height);
Palette palette;
- rdr::U32 palcol;
+ uint32_t palcol;
buffer.fillRect(buffer.getRect(), colour);
@@ -59,27 +59,27 @@ void Encoder::writeSolidRect(int width, int height,
void Encoder::writeSolidRect(const PixelBuffer* pb, const Palette& palette)
{
- rdr::U32 col32;
- rdr::U16 col16;
- rdr::U8 col8;
+ uint32_t col32;
+ uint16_t col16;
+ uint8_t col8;
- rdr::U8* buffer;
+ uint8_t* buffer;
assert(palette.size() == 1);
// The Palette relies on implicit up and down conversion
switch (pb->getPF().bpp) {
case 32:
- col32 = (rdr::U32)palette.getColour(0);
- buffer = (rdr::U8*)&col32;
+ col32 = (uint32_t)palette.getColour(0);
+ buffer = (uint8_t*)&col32;
break;
case 16:
- col16 = (rdr::U16)palette.getColour(0);
- buffer = (rdr::U8*)&col16;
+ col16 = (uint16_t)palette.getColour(0);
+ buffer = (uint8_t*)&col16;
break;
default:
- col8 = (rdr::U8)palette.getColour(0);
- buffer = (rdr::U8*)&col8;
+ col8 = (uint8_t)palette.getColour(0);
+ buffer = (uint8_t*)&col8;
break;
}
diff --git a/common/rfb/Encoder.h b/common/rfb/Encoder.h
index 76079930..5e066323 100644
--- a/common/rfb/Encoder.h
+++ b/common/rfb/Encoder.h
@@ -20,7 +20,8 @@
#ifndef __RFB_ENCODER_H__
#define __RFB_ENCODER_H__
-#include <rdr/types.h>
+#include <stdint.h>
+
#include <rfb/Rect.h>
namespace rfb {
@@ -83,7 +84,7 @@ namespace rfb {
// efficient short cut.
virtual void writeSolidRect(int width, int height,
const PixelFormat& pf,
- const rdr::U8* colour)=0;
+ const uint8_t* colour)=0;
protected:
// Helper method for redirecting a single colour palette to the
diff --git a/common/rfb/H264Decoder.cxx b/common/rfb/H264Decoder.cxx
index 92231fcd..9de73422 100644
--- a/common/rfb/H264Decoder.cxx
+++ b/common/rfb/H264Decoder.cxx
@@ -70,7 +70,7 @@ bool H264Decoder::readRect(const Rect& /*r*/,
const ServerParams& /*server*/,
rdr::OutStream* os)
{
- rdr::U32 len;
+ uint32_t len;
if (!is->hasData(8))
return false;
@@ -79,7 +79,7 @@ bool H264Decoder::readRect(const Rect& /*r*/,
len = is->readU32();
os->writeU32(len);
- rdr::U32 flags = is->readU32();
+ uint32_t flags = is->readU32();
os->writeU32(flags);
@@ -99,8 +99,8 @@ void H264Decoder::decodeRect(const Rect& r, const void* buffer,
ModifiablePixelBuffer* pb)
{
rdr::MemInStream is(buffer, buflen);
- rdr::U32 len = is.readU32();
- rdr::U32 flags = is.readU32();
+ uint32_t len = is.readU32();
+ uint32_t flags = is.readU32();
H264DecoderContext* ctx = NULL;
if (flags & resetAllContexts)
diff --git a/common/rfb/H264DecoderContext.h b/common/rfb/H264DecoderContext.h
index f261f4f2..88c2396c 100644
--- a/common/rfb/H264DecoderContext.h
+++ b/common/rfb/H264DecoderContext.h
@@ -21,8 +21,9 @@
#ifndef __RFB_H264DECODERCONTEXT_H__
#define __RFB_H264DECODERCONTEXT_H__
+#include <stdint.h>
+
#include <os/Mutex.h>
-#include <rdr/types.h>
#include <rfb/Rect.h>
#include <rfb/Decoder.h>
@@ -33,12 +34,12 @@ namespace rfb {
virtual ~H264DecoderContext() = 0;
- virtual void decode(const rdr::U8* /*h264_buffer*/,
- rdr::U32 /*len*/,
+ virtual void decode(const uint8_t* /*h264_buffer*/,
+ uint32_t /*len*/,
ModifiablePixelBuffer* /*pb*/) {}
void reset();
- inline bool isEqualRect(const Rect &r) const { return r.equals(rect); }
+ inline bool isEqualRect(const Rect &r) const { return r == rect; }
bool isReady();
protected:
diff --git a/common/rfb/H264LibavDecoderContext.cxx b/common/rfb/H264LibavDecoderContext.cxx
index 67c14991..8697a5a5 100644
--- a/common/rfb/H264LibavDecoderContext.cxx
+++ b/common/rfb/H264LibavDecoderContext.cxx
@@ -110,13 +110,13 @@ void H264LibavDecoderContext::freeCodec() {
// We need to reallocate buffer because AVPacket uses non-const pointer.
// We don't want to const_cast our buffer somewhere. So we would rather to maintain context's own buffer
// Also avcodec requires a right padded buffer
-rdr::U8* H264LibavDecoderContext::makeH264WorkBuffer(const rdr::U8* buffer, rdr::U32 len)
+uint8_t* H264LibavDecoderContext::makeH264WorkBuffer(const uint8_t* buffer, uint32_t len)
{
- rdr::U32 reserve_len = len + len % AV_INPUT_BUFFER_PADDING_SIZE;
+ uint32_t reserve_len = len + len % AV_INPUT_BUFFER_PADDING_SIZE;
if (!h264WorkBuffer || reserve_len > h264WorkBufferLength)
{
- h264WorkBuffer = (rdr::U8*)realloc(h264WorkBuffer, reserve_len);
+ h264WorkBuffer = (uint8_t*)realloc(h264WorkBuffer, reserve_len);
if (h264WorkBuffer == NULL) {
throw Exception("H264LibavDecoderContext: Unable to allocate memory");
}
@@ -128,13 +128,13 @@ rdr::U8* H264LibavDecoderContext::makeH264WorkBuffer(const rdr::U8* buffer, rdr:
return h264WorkBuffer;
}
-void H264LibavDecoderContext::decode(const rdr::U8* h264_in_buffer,
- rdr::U32 len,
+void H264LibavDecoderContext::decode(const uint8_t* h264_in_buffer,
+ uint32_t len,
ModifiablePixelBuffer* pb) {
os::AutoMutex lock(&mutex);
if (!initialized)
return;
- rdr::U8* h264_work_buffer = makeH264WorkBuffer(h264_in_buffer, len);
+ uint8_t* h264_work_buffer = makeH264WorkBuffer(h264_in_buffer, len);
#ifdef FFMPEG_INIT_PACKET_DEPRECATED
AVPacket *packet = av_packet_alloc();
@@ -154,7 +154,7 @@ void H264LibavDecoderContext::decode(const rdr::U8* h264_in_buffer,
break;
}
// We need to slap on tv to make it work here (don't ask me why)
- if (!packet->size && len == static_cast<rdr::U32>(ret))
+ if (!packet->size && len == static_cast<uint32_t>(ret))
ret = av_parser_parse2(parser, avctx, &packet->data, &packet->size, h264_work_buffer, len, AV_NOPTS_VALUE, AV_NOPTS_VALUE, 0);
if (ret < 0)
{
diff --git a/common/rfb/H264LibavDecoderContext.h b/common/rfb/H264LibavDecoderContext.h
index 1f005e4b..148ba1ad 100644
--- a/common/rfb/H264LibavDecoderContext.h
+++ b/common/rfb/H264LibavDecoderContext.h
@@ -34,7 +34,7 @@ namespace rfb {
H264LibavDecoderContext(const Rect &r) : H264DecoderContext(r) {}
~H264LibavDecoderContext() { freeCodec(); }
- virtual void decode(const rdr::U8* h264_buffer, rdr::U32 len,
+ virtual void decode(const uint8_t* h264_buffer, uint32_t len,
ModifiablePixelBuffer* pb);
protected:
@@ -42,15 +42,15 @@ namespace rfb {
virtual void freeCodec();
private:
- rdr::U8* makeH264WorkBuffer(const rdr::U8* buffer, rdr::U32 len);
+ uint8_t* makeH264WorkBuffer(const uint8_t* buffer, uint32_t len);
AVCodecContext *avctx;
AVCodecParserContext *parser;
AVFrame* frame;
SwsContext* sws;
uint8_t* swsBuffer;
- rdr::U8* h264WorkBuffer;
- rdr::U32 h264WorkBufferLength;
+ uint8_t* h264WorkBuffer;
+ uint32_t h264WorkBufferLength;
};
}
diff --git a/common/rfb/H264WinDecoderContext.cxx b/common/rfb/H264WinDecoderContext.cxx
index a6855c0d..bb29edb6 100644
--- a/common/rfb/H264WinDecoderContext.cxx
+++ b/common/rfb/H264WinDecoderContext.cxx
@@ -154,8 +154,8 @@ void H264WinDecoderContext::freeCodec() {
initialized = false;
}
-void H264WinDecoderContext::decode(const rdr::U8* h264_buffer,
- rdr::U32 len,
+void H264WinDecoderContext::decode(const uint8_t* h264_buffer,
+ uint32_t len,
ModifiablePixelBuffer* pb) {
os::AutoMutex lock(&mutex);
if (!initialized)
@@ -351,7 +351,7 @@ void H264WinDecoderContext::decode(const rdr::U8* h264_buffer,
}
// "7.3.2.1.1 Sequence parameter set data syntax" on page 66 of https://www.itu.int/rec/T-REC-H.264-202108-I/en
-void H264WinDecoderContext::ParseSPS(const rdr::U8* buffer, int length)
+void H264WinDecoderContext::ParseSPS(const uint8_t* buffer, int length)
{
#define EXPECT(cond) if (!(cond)) return;
@@ -404,14 +404,14 @@ void H264WinDecoderContext::ParseSPS(const rdr::U8* buffer, int length)
// NAL unit type
EXPECT(length > 1);
- rdr::U8 type = buffer[0];
+ uint8_t type = buffer[0];
EXPECT((type & 0x80) == 0); // forbidden zero bit
EXPECT((type & 0x1f) == 7); // SPS NAL unit type
buffer++;
length--;
int available = 0;
- rdr::U8 byte = 0;
+ uint8_t byte = 0;
unsigned profile_idc;
unsigned seq_parameter_set_id;
diff --git a/common/rfb/H264WinDecoderContext.h b/common/rfb/H264WinDecoderContext.h
index 96e7bf00..de51576c 100644
--- a/common/rfb/H264WinDecoderContext.h
+++ b/common/rfb/H264WinDecoderContext.h
@@ -33,7 +33,7 @@ namespace rfb {
H264WinDecoderContext(const Rect &r) : H264DecoderContext(r) {};
~H264WinDecoderContext() { freeCodec(); }
- virtual void decode(const rdr::U8* h264_buffer, rdr::U32 len,
+ virtual void decode(const uint8_t* h264_buffer, uint32_t len,
ModifiablePixelBuffer* pb);
protected:
@@ -42,12 +42,12 @@ namespace rfb {
private:
LONG stride;
- rdr::U32 full_width = 0;
- rdr::U32 full_height = 0;
- rdr::U32 crop_width = 0;
- rdr::U32 crop_height = 0;
- rdr::U32 offset_x = 0;
- rdr::U32 offset_y = 0;
+ uint32_t full_width = 0;
+ uint32_t full_height = 0;
+ uint32_t crop_width = 0;
+ uint32_t crop_height = 0;
+ uint32_t offset_x = 0;
+ uint32_t offset_y = 0;
IMFTransform *decoder = NULL;
IMFTransform *converter = NULL;
IMFSample *input_sample = NULL;
@@ -57,7 +57,7 @@ namespace rfb {
IMFMediaBuffer *decoded_buffer = NULL;
IMFMediaBuffer *converted_buffer = NULL;
- void ParseSPS(const rdr::U8* buffer, int length);
+ void ParseSPS(const uint8_t* buffer, int length);
};
}
diff --git a/common/rfb/HextileDecoder.cxx b/common/rfb/HextileDecoder.cxx
index 73655da0..f7cbc46a 100644
--- a/common/rfb/HextileDecoder.cxx
+++ b/common/rfb/HextileDecoder.cxx
@@ -1,4 +1,5 @@
/* Copyright (C) 2002-2005 RealVNC Ltd. All Rights Reserved.
+ * Copyright 2014-2022 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
@@ -24,22 +25,14 @@
#include <rdr/MemInStream.h>
#include <rdr/OutStream.h>
+#include <rfb/Exception.h>
#include <rfb/ServerParams.h>
#include <rfb/PixelBuffer.h>
#include <rfb/HextileDecoder.h>
+#include <rfb/hextileConstants.h>
using namespace rfb;
-#define BPP 8
-#include <rfb/hextileDecode.h>
-#undef BPP
-#define BPP 16
-#include <rfb/hextileDecode.h>
-#undef BPP
-#define BPP 32
-#include <rfb/hextileDecode.h>
-#undef BPP
-
HextileDecoder::HextileDecoder() : Decoder(DecoderPlain)
{
}
@@ -63,7 +56,7 @@ bool HextileDecoder::readRect(const Rect& r, rdr::InStream* is,
t.br.y = __rfbmin(r.br.y, t.tl.y + 16);
for (t.tl.x = r.tl.x; t.tl.x < r.br.x; t.tl.x += 16) {
- rdr::U8 tileType;
+ uint8_t tileType;
t.br.x = __rfbmin(r.br.x, t.tl.x + 16);
@@ -94,7 +87,7 @@ bool HextileDecoder::readRect(const Rect& r, rdr::InStream* is,
}
if (tileType & hextileAnySubrects) {
- rdr::U8 nSubrects;
+ uint8_t nSubrects;
if (!is->hasDataOrRestore(1))
return false;
@@ -127,8 +120,87 @@ void HextileDecoder::decodeRect(const Rect& r, const void* buffer,
rdr::MemInStream is(buffer, buflen);
const PixelFormat& pf = server.pf();
switch (pf.bpp) {
- case 8: hextileDecode8 (r, &is, pf, pb); break;
- case 16: hextileDecode16(r, &is, pf, pb); break;
- case 32: hextileDecode32(r, &is, pf, pb); break;
+ case 8: hextileDecode<uint8_t >(r, &is, pf, pb); break;
+ case 16: hextileDecode<uint16_t>(r, &is, pf, pb); break;
+ case 32: hextileDecode<uint32_t>(r, &is, pf, pb); break;
+ }
+}
+
+template<class T>
+inline T HextileDecoder::readPixel(rdr::InStream* is)
+{
+ if (sizeof(T) == 1)
+ return is->readOpaque8();
+ if (sizeof(T) == 2)
+ return is->readOpaque16();
+ if (sizeof(T) == 4)
+ return is->readOpaque32();
+}
+
+template<class T>
+void HextileDecoder::hextileDecode(const Rect& r, rdr::InStream* is,
+ const PixelFormat& pf,
+ ModifiablePixelBuffer* pb)
+{
+ Rect t;
+ T bg = 0;
+ T fg = 0;
+ T buf[16 * 16];
+
+ for (t.tl.y = r.tl.y; t.tl.y < r.br.y; t.tl.y += 16) {
+
+ t.br.y = __rfbmin(r.br.y, t.tl.y + 16);
+
+ for (t.tl.x = r.tl.x; t.tl.x < r.br.x; t.tl.x += 16) {
+
+ t.br.x = __rfbmin(r.br.x, t.tl.x + 16);
+
+ int tileType = is->readU8();
+
+ if (tileType & hextileRaw) {
+ is->readBytes(buf, t.area() * sizeof(T));
+ pb->imageRect(pf, t, buf);
+ continue;
+ }
+
+ if (tileType & hextileBgSpecified)
+ bg = readPixel<T>(is);
+
+ int len = t.area();
+ T* ptr = buf;
+ while (len-- > 0) *ptr++ = bg;
+
+ if (tileType & hextileFgSpecified)
+ fg = readPixel<T>(is);
+
+ if (tileType & hextileAnySubrects) {
+ int nSubrects = is->readU8();
+
+ for (int i = 0; i < nSubrects; i++) {
+
+ if (tileType & hextileSubrectsColoured)
+ fg = readPixel<T>(is);
+
+ int xy = is->readU8();
+ int wh = is->readU8();
+
+ int x = ((xy >> 4) & 15);
+ int y = (xy & 15);
+ int w = ((wh >> 4) & 15) + 1;
+ int h = (wh & 15) + 1;
+ if (x + w > 16 || y + h > 16) {
+ throw rfb::Exception("HEXTILE_DECODE: Hextile out of bounds");
+ }
+ T* ptr = buf + y * t.width() + x;
+ int rowAdd = t.width() - w;
+ while (h-- > 0) {
+ int len = w;
+ while (len-- > 0) *ptr++ = fg;
+ ptr += rowAdd;
+ }
+ }
+ }
+ pb->imageRect(pf, t, buf);
+ }
}
}
diff --git a/common/rfb/HextileDecoder.h b/common/rfb/HextileDecoder.h
index 2c42be54..e8961d73 100644
--- a/common/rfb/HextileDecoder.h
+++ b/common/rfb/HextileDecoder.h
@@ -1,4 +1,5 @@
/* Copyright (C) 2002-2005 RealVNC Ltd. All Rights Reserved.
+ * Copyright 2014-2022 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
@@ -22,6 +23,8 @@
namespace rfb {
+ class PixelFormat;
+
class HextileDecoder : public Decoder {
public:
HextileDecoder();
@@ -31,6 +34,13 @@ namespace rfb {
virtual void decodeRect(const Rect& r, const void* buffer,
size_t buflen, const ServerParams& server,
ModifiablePixelBuffer* pb);
+ private:
+ template<class T>
+ inline T readPixel(rdr::InStream* is);
+ template<class T>
+ void hextileDecode(const Rect& r, rdr::InStream* is,
+ const PixelFormat& pf,
+ ModifiablePixelBuffer* pb);
};
}
#endif
diff --git a/common/rfb/HextileEncoder.cxx b/common/rfb/HextileEncoder.cxx
index f9db06b8..90e59962 100644
--- a/common/rfb/HextileEncoder.cxx
+++ b/common/rfb/HextileEncoder.cxx
@@ -1,6 +1,6 @@
/* Copyright (C) 2002-2005 RealVNC Ltd. All Rights Reserved.
* Copyright (C) 2005 Constantin Kaplinsky. All Rights Reserved.
- * Copyright 2014 Pierre Ossman for Cendio AB
+ * Copyright 2014-2022 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
@@ -25,8 +25,10 @@
#include <rfb/encodings.h>
#include <rfb/SConnection.h>
#include <rfb/HextileEncoder.h>
+#include <rfb/Palette.h>
#include <rfb/PixelBuffer.h>
#include <rfb/Configuration.h>
+#include <rfb/hextileConstants.h>
using namespace rfb;
@@ -36,19 +38,6 @@ BoolParameter improvedHextile("ImprovedHextile",
"ratios by the cost of using more CPU time",
true);
-#define BPP 8
-#include <rfb/hextileEncode.h>
-#include <rfb/hextileEncodeBetter.h>
-#undef BPP
-#define BPP 16
-#include <rfb/hextileEncode.h>
-#include <rfb/hextileEncodeBetter.h>
-#undef BPP
-#define BPP 32
-#include <rfb/hextileEncode.h>
-#include <rfb/hextileEncodeBetter.h>
-#undef BPP
-
HextileEncoder::HextileEncoder(SConnection* conn) :
Encoder(conn, encodingHextile, EncoderPlain)
{
@@ -70,23 +59,23 @@ void HextileEncoder::writeRect(const PixelBuffer* pb,
switch (pb->getPF().bpp) {
case 8:
if (improvedHextile) {
- hextileEncodeBetter8(os, pb);
+ hextileEncodeBetter<uint8_t>(os, pb);
} else {
- hextileEncode8(os, pb);
+ hextileEncode<uint8_t>(os, pb);
}
break;
case 16:
if (improvedHextile) {
- hextileEncodeBetter16(os, pb);
+ hextileEncodeBetter<uint16_t>(os, pb);
} else {
- hextileEncode16(os, pb);
+ hextileEncode<uint16_t>(os, pb);
}
break;
case 32:
if (improvedHextile) {
- hextileEncodeBetter32(os, pb);
+ hextileEncodeBetter<uint32_t>(os, pb);
} else {
- hextileEncode32(os, pb);
+ hextileEncode<uint32_t>(os, pb);
}
break;
}
@@ -94,7 +83,7 @@ void HextileEncoder::writeRect(const PixelBuffer* pb,
void HextileEncoder::writeSolidRect(int width, int height,
const PixelFormat& pf,
- const rdr::U8* colour)
+ const uint8_t* colour)
{
rdr::OutStream* os;
int tiles;
@@ -110,3 +99,496 @@ void HextileEncoder::writeSolidRect(int width, int height,
while (tiles--)
os->writeU8(0);
}
+
+template<class T>
+inline void HextileEncoder::writePixel(rdr::OutStream* os, T pixel)
+{
+ if (sizeof(T) == 1)
+ os->writeOpaque8(pixel);
+ else if (sizeof(T) == 2)
+ os->writeOpaque16(pixel);
+ else if (sizeof(T) == 4)
+ os->writeOpaque32(pixel);
+}
+
+template<class T>
+void HextileEncoder::hextileEncode(rdr::OutStream* os,
+ const PixelBuffer* pb)
+{
+ Rect t;
+ T buf[256];
+ T oldBg = 0, oldFg = 0;
+ bool oldBgValid = false;
+ bool oldFgValid = false;
+ uint8_t encoded[256*sizeof(T)];
+
+ for (t.tl.y = 0; t.tl.y < pb->height(); t.tl.y += 16) {
+
+ t.br.y = __rfbmin(pb->height(), t.tl.y + 16);
+
+ for (t.tl.x = 0; t.tl.x < pb->width(); t.tl.x += 16) {
+
+ t.br.x = __rfbmin(pb->width(), t.tl.x + 16);
+
+ pb->getImage(buf, t);
+
+ T bg = 0, fg = 0;
+ int tileType = testTileType(buf, t.width(), t.height(), &bg, &fg);
+
+ if (!oldBgValid || oldBg != bg) {
+ tileType |= hextileBgSpecified;
+ oldBg = bg;
+ oldBgValid = true;
+ }
+
+ int encodedLen = 0;
+
+ if (tileType & hextileAnySubrects) {
+
+ if (tileType & hextileSubrectsColoured) {
+ oldFgValid = false;
+ } else {
+ if (!oldFgValid || oldFg != fg) {
+ tileType |= hextileFgSpecified;
+ oldFg = fg;
+ oldFgValid = true;
+ }
+ }
+
+ encodedLen = hextileEncodeTile(buf, t.width(), t.height(),
+ tileType, encoded, bg);
+
+ if (encodedLen < 0) {
+ pb->getImage(buf, t);
+ os->writeU8(hextileRaw);
+ os->writeBytes(buf, t.width() * t.height() * sizeof(T));
+ oldBgValid = oldFgValid = false;
+ continue;
+ }
+ }
+
+ os->writeU8(tileType);
+ if (tileType & hextileBgSpecified) writePixel(os, bg);
+ if (tileType & hextileFgSpecified) writePixel(os, fg);
+ if (tileType & hextileAnySubrects) os->writeBytes(encoded, encodedLen);
+ }
+ }
+}
+
+template<class T>
+int HextileEncoder::hextileEncodeTile(T* data, int w, int h,
+ int tileType, uint8_t* encoded,
+ T bg)
+{
+ uint8_t* nSubrectsPtr = encoded;
+ *nSubrectsPtr = 0;
+ encoded++;
+
+ for (int y = 0; y < h; y++)
+ {
+ int x = 0;
+ while (x < w) {
+ if (*data == bg) {
+ x++;
+ data++;
+ continue;
+ }
+
+ // Find horizontal subrect first
+ T* ptr = data+1;
+ T* eol = data+w-x;
+ while (ptr < eol && *ptr == *data) ptr++;
+ int sw = ptr - data;
+
+ ptr = data + w;
+ int sh = 1;
+ while (sh < h-y) {
+ eol = ptr + sw;
+ while (ptr < eol)
+ if (*ptr++ != *data) goto endOfSubrect;
+ ptr += w - sw;
+ sh++;
+ }
+ endOfSubrect:
+
+ (*nSubrectsPtr)++;
+
+ if (tileType & hextileSubrectsColoured) {
+ if (encoded - nSubrectsPtr + sizeof(T) > w*h*sizeof(T))
+ return -1;
+
+ if (sizeof(T) == 1) {
+ *encoded++ = *data;
+ } else if (sizeof(T) == 2) {
+ *encoded++ = ((uint8_t*)data)[0];
+ *encoded++ = ((uint8_t*)data)[1];
+ } else if (sizeof(T) == 4) {
+ *encoded++ = ((uint8_t*)data)[0];
+ *encoded++ = ((uint8_t*)data)[1];
+ *encoded++ = ((uint8_t*)data)[2];
+ *encoded++ = ((uint8_t*)data)[3];
+ }
+ }
+
+ if ((size_t)(encoded - nSubrectsPtr + 2) > w*h*sizeof(T))
+ return -1;
+ *encoded++ = (x << 4) | y;
+ *encoded++ = ((sw-1) << 4) | (sh-1);
+
+ ptr = data+w;
+ T* eor = data+w*sh;
+ while (ptr < eor) {
+ eol = ptr + sw;
+ while (ptr < eol) *ptr++ = bg;
+ ptr += w - sw;
+ }
+ x += sw;
+ data += sw;
+ }
+ }
+ return encoded - nSubrectsPtr;
+}
+
+template<class T>
+int HextileEncoder::testTileType(T* data, int w, int h, T* bg, T* fg)
+{
+ T pix1 = *data;
+ T* end = data + w * h;
+
+ T* ptr = data + 1;
+ while (ptr < end && *ptr == pix1)
+ ptr++;
+
+ if (ptr == end) {
+ *bg = pix1;
+ return 0; // solid-color tile
+ }
+
+ int count1 = ptr - data;
+ int count2 = 1;
+ T pix2 = *ptr++;
+ int tileType = hextileAnySubrects;
+
+ for (; ptr < end; ptr++) {
+ if (*ptr == pix1) {
+ count1++;
+ } else if (*ptr == pix2) {
+ count2++;
+ } else {
+ tileType |= hextileSubrectsColoured;
+ break;
+ }
+ }
+
+ if (count1 >= count2) {
+ *bg = pix1; *fg = pix2;
+ } else {
+ *bg = pix2; *fg = pix1;
+ }
+ return tileType;
+}
+
+//
+// This class analyzes a separate tile and encodes its subrectangles.
+//
+
+template<class T>
+class HextileTile {
+
+ public:
+
+ HextileTile ();
+
+ //
+ // Initialize existing object instance with new tile data.
+ //
+ void newTile(const T *src, int w, int h);
+
+ //
+ // Flags can include: hextileRaw, hextileAnySubrects and
+ // hextileSubrectsColoured. Note that if hextileRaw is set, other
+ // flags make no sense. Also, hextileSubrectsColoured is meaningful
+ // only when hextileAnySubrects is set as well.
+ //
+ int getFlags() const { return m_flags; }
+
+ //
+ // Returns the size of encoded subrects data, including subrect count.
+ // The size is zero if flags do not include hextileAnySubrects.
+ //
+ size_t getSize() const { return m_size; }
+
+ //
+ // Return optimal background.
+ //
+ int getBackground() const { return m_background; }
+
+ //
+ // Return foreground if flags include hextileSubrectsColoured.
+ //
+ int getForeground() const { return m_foreground; }
+
+ //
+ // Encode subrects. This function may be called only if
+ // hextileAnySubrects bit is set in flags. The buffer size should be
+ // big enough to store at least the number of bytes returned by the
+ // getSize() method.
+ //
+ void encode(uint8_t* dst) const;
+
+ protected:
+
+ //
+ // Analyze the tile pixels, fill in all the data fields.
+ //
+ void analyze();
+
+ const T *m_tile;
+ int m_width;
+ int m_height;
+
+ size_t m_size;
+ int m_flags;
+ T m_background;
+ T m_foreground;
+
+ int m_numSubrects;
+ uint8_t m_coords[256 * 2];
+ T m_colors[256];
+
+ private:
+
+ bool m_processed[16][16];
+ Palette m_pal;
+};
+
+template<class T>
+HextileTile<T>::HextileTile()
+ : m_tile(NULL), m_width(0), m_height(0),
+ m_size(0), m_flags(0), m_background(0), m_foreground(0),
+ m_numSubrects(0)
+{
+}
+
+template<class T>
+void HextileTile<T>::newTile(const T *src, int w, int h)
+{
+ m_tile = src;
+ m_width = w;
+ m_height = h;
+
+ analyze();
+}
+
+template<class T>
+void HextileTile<T>::analyze()
+{
+ assert(m_tile && m_width && m_height);
+
+ const T *ptr = m_tile;
+ const T *end = &m_tile[m_width * m_height];
+ T color = *ptr++;
+ while (ptr != end && *ptr == color)
+ ptr++;
+
+ // Handle solid tile
+ if (ptr == end) {
+ m_background = m_tile[0];
+ m_flags = 0;
+ m_size = 0;
+ return;
+ }
+
+ // Compute number of complete rows of the same color, at the top
+ int y = (ptr - m_tile) / m_width;
+
+ T *colorsPtr = m_colors;
+ uint8_t *coordsPtr = m_coords;
+ m_pal.clear();
+ m_numSubrects = 0;
+
+ // Have we found the first subrect already?
+ if (y > 0) {
+ *colorsPtr++ = color;
+ *coordsPtr++ = 0;
+ *coordsPtr++ = (uint8_t)(((m_width - 1) << 4) | ((y - 1) & 0x0F));
+ m_pal.insert(color, 1);
+ m_numSubrects++;
+ }
+
+ memset(m_processed, 0, 16 * 16 * sizeof(bool));
+
+ int x, sx, sy, sw, sh, max_x;
+
+ for (; y < m_height; y++) {
+ for (x = 0; x < m_width; x++) {
+ // Skip pixels that were processed earlier
+ if (m_processed[y][x]) {
+ continue;
+ }
+ // Determine dimensions of the horizontal subrect
+ color = m_tile[y * m_width + x];
+ for (sx = x + 1; sx < m_width; sx++) {
+ if (m_tile[y * m_width + sx] != color)
+ break;
+ }
+ sw = sx - x;
+ max_x = sx;
+ for (sy = y + 1; sy < m_height; sy++) {
+ for (sx = x; sx < max_x; sx++) {
+ if (m_tile[sy * m_width + sx] != color)
+ goto done;
+ }
+ }
+ done:
+ sh = sy - y;
+
+ // Save properties of this subrect
+ *colorsPtr++ = color;
+ *coordsPtr++ = (uint8_t)((x << 4) | (y & 0x0F));
+ *coordsPtr++ = (uint8_t)(((sw - 1) << 4) | ((sh - 1) & 0x0F));
+
+ if (!m_pal.insert(color, 1) ||
+ ((size_t)m_pal.size() > (48 + 2 * sizeof(T)*8))) {
+ // Handle palette overflow
+ m_flags = hextileRaw;
+ m_size = 0;
+ return;
+ }
+
+ m_numSubrects++;
+
+ // Mark pixels of this subrect as processed, below this row
+ for (sy = y + 1; sy < y + sh; sy++) {
+ for (sx = x; sx < x + sw; sx++)
+ m_processed[sy][sx] = true;
+ }
+
+ // Skip processed pixels of this row
+ x += (sw - 1);
+ }
+ }
+
+ // Save number of colors in this tile (should be no less than 2)
+ int numColors = m_pal.size();
+ assert(numColors >= 2);
+
+ m_background = (T)m_pal.getColour(0);
+ m_flags = hextileAnySubrects;
+ int numSubrects = m_numSubrects - m_pal.getCount(0);
+
+ if (numColors == 2) {
+ // Monochrome tile
+ m_foreground = (T)m_pal.getColour(1);
+ m_size = 1 + 2 * numSubrects;
+ } else {
+ // Colored tile
+ m_flags |= hextileSubrectsColoured;
+ m_size = 1 + (2 + sizeof(T)) * numSubrects;
+ }
+}
+
+template<class T>
+void HextileTile<T>::encode(uint8_t *dst) const
+{
+ assert(m_numSubrects && (m_flags & hextileAnySubrects));
+
+ // Zero subrects counter
+ uint8_t *numSubrectsPtr = dst;
+ *dst++ = 0;
+
+ for (int i = 0; i < m_numSubrects; i++) {
+ if (m_colors[i] == m_background)
+ continue;
+
+ if (m_flags & hextileSubrectsColoured) {
+ if (sizeof(T) == 1) {
+ *dst++ = m_colors[i];
+ } else if (sizeof(T) == 2) {
+ *dst++ = ((uint8_t*)&m_colors[i])[0];
+ *dst++ = ((uint8_t*)&m_colors[i])[1];
+ } else if (sizeof(T) == 4) {
+ *dst++ = ((uint8_t*)&m_colors[i])[0];
+ *dst++ = ((uint8_t*)&m_colors[i])[1];
+ *dst++ = ((uint8_t*)&m_colors[i])[2];
+ *dst++ = ((uint8_t*)&m_colors[i])[3];
+ }
+ }
+ *dst++ = m_coords[i * 2];
+ *dst++ = m_coords[i * 2 + 1];
+
+ (*numSubrectsPtr)++;
+ }
+
+ assert((size_t)(dst - numSubrectsPtr) == m_size);
+}
+
+//
+// Main encoding function.
+//
+
+template<class T>
+void HextileEncoder::hextileEncodeBetter(rdr::OutStream* os,
+ const PixelBuffer* pb)
+{
+ Rect t;
+ T buf[256];
+ T oldBg = 0, oldFg = 0;
+ bool oldBgValid = false;
+ bool oldFgValid = false;
+ uint8_t encoded[256*sizeof(T)];
+
+ HextileTile<T> tile;
+
+ for (t.tl.y = 0; t.tl.y < pb->height(); t.tl.y += 16) {
+
+ t.br.y = __rfbmin(pb->height(), t.tl.y + 16);
+
+ for (t.tl.x = 0; t.tl.x < pb->width(); t.tl.x += 16) {
+
+ t.br.x = __rfbmin(pb->width(), t.tl.x + 16);
+
+ pb->getImage(buf, t);
+
+ tile.newTile(buf, t.width(), t.height());
+ int tileType = tile.getFlags();
+ size_t encodedLen = tile.getSize();
+
+ if ( (tileType & hextileRaw) != 0 ||
+ encodedLen >= t.width() * t.height() * sizeof(T)) {
+ os->writeU8(hextileRaw);
+ os->writeBytes(buf, t.width() * t.height() * sizeof(T));
+ oldBgValid = oldFgValid = false;
+ continue;
+ }
+
+ T bg = tile.getBackground();
+ T fg = 0;
+
+ if (!oldBgValid || oldBg != bg) {
+ tileType |= hextileBgSpecified;
+ oldBg = bg;
+ oldBgValid = true;
+ }
+
+ if (tileType & hextileAnySubrects) {
+ if (tileType & hextileSubrectsColoured) {
+ oldFgValid = false;
+ } else {
+ fg = tile.getForeground();
+ if (!oldFgValid || oldFg != fg) {
+ tileType |= hextileFgSpecified;
+ oldFg = fg;
+ oldFgValid = true;
+ }
+ }
+ tile.encode(encoded);
+ }
+
+ os->writeU8(tileType);
+ if (tileType & hextileBgSpecified) writePixel(os, bg);
+ if (tileType & hextileFgSpecified) writePixel(os, fg);
+ if (tileType & hextileAnySubrects) os->writeBytes(encoded, encodedLen);
+ }
+ }
+}
diff --git a/common/rfb/HextileEncoder.h b/common/rfb/HextileEncoder.h
index 393ab23b..20721b7c 100644
--- a/common/rfb/HextileEncoder.h
+++ b/common/rfb/HextileEncoder.h
@@ -1,5 +1,5 @@
/* Copyright (C) 2002-2005 RealVNC Ltd. All Rights Reserved.
- * Copyright 2014 Pierre Ossman for Cendio AB
+ * Copyright 2014-2022 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
@@ -31,7 +31,21 @@ namespace rfb {
virtual void writeRect(const PixelBuffer* pb, const Palette& palette);
virtual void writeSolidRect(int width, int height,
const PixelFormat& pf,
- const rdr::U8* colour);
+ const uint8_t* colour);
+ private:
+ template<class T>
+ inline void writePixel(rdr::OutStream* os, T pixel);
+
+ template<class T>
+ void hextileEncode(rdr::OutStream* os, const PixelBuffer* pb);
+ template<class T>
+ int hextileEncodeTile(T* data, int w, int h, int tileType,
+ uint8_t* encoded, T bg);
+ template<class T>
+ int testTileType(T* data, int w, int h, T* bg, T* fg);
+
+ template<class T>
+ void hextileEncodeBetter(rdr::OutStream* os, const PixelBuffer* pb);
};
}
#endif
diff --git a/common/rfb/Hostname.h b/common/rfb/Hostname.h
index 341f69e1..1971e343 100644
--- a/common/rfb/Hostname.h
+++ b/common/rfb/Hostname.h
@@ -22,6 +22,7 @@
#include <assert.h>
#include <ctype.h>
#include <stdlib.h>
+#include <string.h>
#include <rdr/Exception.h>
#include <rfb/util.h>
@@ -38,7 +39,9 @@ namespace rfb {
return true;
}
- static void getHostAndPort(const char* hi, char** host, int* port, int basePort=5900) {
+ static void getHostAndPort(const char* hi, std::string* host,
+ int* port, int basePort=5900)
+ {
const char* hostStart;
const char* hostEnd;
const char* portStart;
@@ -86,14 +89,9 @@ namespace rfb {
hostEnd--;
if (hostStart == hostEnd)
- *host = strDup("localhost");
- else {
- size_t len;
- len = hostEnd - hostStart + 1;
- *host = new char[len];
- strncpy(*host, hostStart, len-1);
- (*host)[len-1] = '\0';
- }
+ *host = "localhost";
+ else
+ *host = std::string(hostStart, hostEnd - hostStart);
if (portStart == NULL)
*port = basePort;
diff --git a/common/rfb/InputHandler.h b/common/rfb/InputHandler.h
index 4719eca0..ad6c4be5 100644
--- a/common/rfb/InputHandler.h
+++ b/common/rfb/InputHandler.h
@@ -23,16 +23,16 @@
#ifndef __RFB_INPUTHANDLER_H__
#define __RFB_INPUTHANDLER_H__
-#include <rdr/types.h>
+#include <stdint.h>
+
#include <rfb/Rect.h>
-#include <rfb/util.h>
namespace rfb {
class InputHandler {
public:
virtual ~InputHandler() {}
- virtual void keyEvent(rdr::U32 /*keysym*/, rdr::U32 /*keycode*/,
+ virtual void keyEvent(uint32_t /*keysym*/, uint32_t /*keycode*/,
bool /*down*/) { }
virtual void pointerEvent(const Point& /*pos*/,
int /*buttonMask*/) { }
diff --git a/common/rfb/JpegCompressor.cxx b/common/rfb/JpegCompressor.cxx
index efb26a77..d5c5fd0d 100644
--- a/common/rfb/JpegCompressor.cxx
+++ b/common/rfb/JpegCompressor.cxx
@@ -155,14 +155,14 @@ JpegCompressor::~JpegCompressor(void)
delete cinfo;
}
-void JpegCompressor::compress(const rdr::U8 *buf, volatile int stride,
+void JpegCompressor::compress(const uint8_t *buf, volatile int stride,
const Rect& r, const PixelFormat& pf,
int quality, int subsamp)
{
int w = r.width();
int h = r.height();
int pixelsize;
- rdr::U8 * volatile srcBuf = NULL;
+ uint8_t * volatile srcBuf = NULL;
volatile bool srcBufIsTemp = false;
JSAMPROW * volatile rowPointer = NULL;
@@ -182,17 +182,17 @@ void JpegCompressor::compress(const rdr::U8 *buf, volatile int stride,
#ifdef JCS_EXTENSIONS
// Try to have libjpeg output directly to our native format
// libjpeg can only handle some "standard" formats
- if (pfRGBX.equal(pf))
+ if (pfRGBX == pf)
cinfo->in_color_space = JCS_EXT_RGBX;
- else if (pfBGRX.equal(pf))
+ else if (pfBGRX == pf)
cinfo->in_color_space = JCS_EXT_BGRX;
- else if (pfXRGB.equal(pf))
+ else if (pfXRGB == pf)
cinfo->in_color_space = JCS_EXT_XRGB;
- else if (pfXBGR.equal(pf))
+ else if (pfXBGR == pf)
cinfo->in_color_space = JCS_EXT_XBGR;
if (cinfo->in_color_space != JCS_RGB) {
- srcBuf = (rdr::U8 *)buf;
+ srcBuf = (uint8_t *)buf;
pixelsize = 4;
}
#endif
@@ -201,9 +201,9 @@ void JpegCompressor::compress(const rdr::U8 *buf, volatile int stride,
stride = w;
if (cinfo->in_color_space == JCS_RGB) {
- srcBuf = new rdr::U8[w * h * pixelsize];
+ srcBuf = new uint8_t[w * h * pixelsize];
srcBufIsTemp = true;
- pf.rgbFromBuffer(srcBuf, (const rdr::U8 *)buf, w, stride, h);
+ pf.rgbFromBuffer(srcBuf, (const uint8_t *)buf, w, stride, h);
stride = w;
}
diff --git a/common/rfb/JpegCompressor.h b/common/rfb/JpegCompressor.h
index de201732..d4978fdf 100644
--- a/common/rfb/JpegCompressor.h
+++ b/common/rfb/JpegCompressor.h
@@ -43,7 +43,7 @@ namespace rfb {
JpegCompressor(int bufferLen = 128*1024);
virtual ~JpegCompressor();
- void compress(const rdr::U8 *, int, const Rect&, const PixelFormat&, int, int);
+ void compress(const uint8_t *, int, const Rect&, const PixelFormat&, int, int);
void writeBytes(const void*, int);
diff --git a/common/rfb/JpegDecompressor.cxx b/common/rfb/JpegDecompressor.cxx
index ea148b94..44c54fb2 100644
--- a/common/rfb/JpegDecompressor.cxx
+++ b/common/rfb/JpegDecompressor.cxx
@@ -150,8 +150,8 @@ JpegDecompressor::~JpegDecompressor(void)
delete dinfo;
}
-void JpegDecompressor::decompress(const rdr::U8 *jpegBuf,
- int jpegBufLen, rdr::U8 *buf,
+void JpegDecompressor::decompress(const uint8_t *jpegBuf,
+ int jpegBufLen, uint8_t *buf,
volatile int stride,
const Rect& r, const PixelFormat& pf)
{
@@ -159,7 +159,7 @@ void JpegDecompressor::decompress(const rdr::U8 *jpegBuf,
int h = r.height();
int pixelsize;
int dstBufStride;
- rdr::U8 * volatile dstBuf = NULL;
+ uint8_t * volatile dstBuf = NULL;
volatile bool dstBufIsTemp = false;
JSAMPROW * volatile rowPointer = NULL;
@@ -184,23 +184,23 @@ void JpegDecompressor::decompress(const rdr::U8 *jpegBuf,
#ifdef JCS_EXTENSIONS
// Try to have libjpeg output directly to our native format
// libjpeg can only handle some "standard" formats
- if (pfRGBX.equal(pf))
+ if (pfRGBX == pf)
dinfo->out_color_space = JCS_EXT_RGBX;
- else if (pfBGRX.equal(pf))
+ else if (pfBGRX == pf)
dinfo->out_color_space = JCS_EXT_BGRX;
- else if (pfXRGB.equal(pf))
+ else if (pfXRGB == pf)
dinfo->out_color_space = JCS_EXT_XRGB;
- else if (pfXBGR.equal(pf))
+ else if (pfXBGR == pf)
dinfo->out_color_space = JCS_EXT_XBGR;
if (dinfo->out_color_space != JCS_RGB) {
- dstBuf = (rdr::U8 *)buf;
+ dstBuf = (uint8_t *)buf;
pixelsize = 4;
}
#endif
if (dinfo->out_color_space == JCS_RGB) {
- dstBuf = new rdr::U8[w * h * pixelsize];
+ dstBuf = new uint8_t[w * h * pixelsize];
dstBufIsTemp = true;
dstBufStride = w;
}
@@ -226,7 +226,7 @@ void JpegDecompressor::decompress(const rdr::U8 *jpegBuf,
}
if (dinfo->out_color_space == JCS_RGB)
- pf.bufferFromRGB((rdr::U8*)buf, dstBuf, w, stride, h);
+ pf.bufferFromRGB((uint8_t*)buf, dstBuf, w, stride, h);
jpeg_finish_decompress(dinfo);
diff --git a/common/rfb/JpegDecompressor.h b/common/rfb/JpegDecompressor.h
index ed367786..5d4f0c21 100644
--- a/common/rfb/JpegDecompressor.h
+++ b/common/rfb/JpegDecompressor.h
@@ -43,7 +43,7 @@ namespace rfb {
JpegDecompressor(void);
virtual ~JpegDecompressor();
- void decompress(const rdr::U8 *, int, rdr::U8 *, int, const Rect&,
+ void decompress(const uint8_t *, int, uint8_t *, int, const Rect&,
const PixelFormat&);
private:
diff --git a/common/rfb/KeyRemapper.cxx b/common/rfb/KeyRemapper.cxx
index 1431a21e..762eb413 100644
--- a/common/rfb/KeyRemapper.cxx
+++ b/common/rfb/KeyRemapper.cxx
@@ -21,6 +21,7 @@
#endif
#include <stdio.h>
+#include <string.h>
#include <os/Mutex.h>
@@ -72,10 +73,10 @@ void KeyRemapper::setMapping(const char* m) {
}
}
-rdr::U32 KeyRemapper::remapKey(rdr::U32 key) const {
+uint32_t KeyRemapper::remapKey(uint32_t key) const {
os::AutoMutex a(mutex);
- std::map<rdr::U32,rdr::U32>::const_iterator i = mapping.find(key);
+ std::map<uint32_t,uint32_t>::const_iterator i = mapping.find(key);
if (i != mapping.end())
return i->second;
return key;
@@ -86,7 +87,7 @@ class KeyMapParameter : public StringParameter {
public:
KeyMapParameter()
: StringParameter("RemapKeys", "Comma-separated list of incoming keysyms to remap. Mappings are expressed as two hex values, prefixed by 0x, and separated by ->", "") {
- setParam(value);
+ KeyRemapper::defInstance.setMapping("");
}
bool setParam(const char* v) {
KeyRemapper::defInstance.setMapping(v);
diff --git a/common/rfb/KeyRemapper.h b/common/rfb/KeyRemapper.h
index 1406bad2..89853721 100644
--- a/common/rfb/KeyRemapper.h
+++ b/common/rfb/KeyRemapper.h
@@ -20,7 +20,8 @@
#define __RFB_KEYREMAPPER_H__
#include <map>
-#include <rdr/types.h>
+
+#include <stdint.h>
namespace os { class Mutex; }
@@ -31,10 +32,10 @@ namespace rfb {
KeyRemapper(const char* m="");
~KeyRemapper();
void setMapping(const char* m);
- rdr::U32 remapKey(rdr::U32 key) const;
+ uint32_t remapKey(uint32_t key) const;
static KeyRemapper defInstance;
private:
- std::map<rdr::U32,rdr::U32> mapping;
+ std::map<uint32_t,uint32_t> mapping;
os::Mutex* mutex;
};
diff --git a/common/rfb/LogWriter.cxx b/common/rfb/LogWriter.cxx
index 6df82d8e..dc9db9d1 100644
--- a/common/rfb/LogWriter.cxx
+++ b/common/rfb/LogWriter.cxx
@@ -76,19 +76,20 @@ LogWriter::getLogWriter(const char* name) {
}
bool LogWriter::setLogParams(const char* params) {
- CharArray logwriterName, loggerName, logLevel;
- if (!strSplit(params, ':', &logwriterName.buf, &loggerName.buf) ||
- !strSplit(loggerName.buf, ':', &loggerName.buf, &logLevel.buf)) {
+ std::vector<std::string> parts;
+ parts = split(params, ':');
+ if (parts.size() != 3) {
fprintf(stderr,"failed to parse log params:%s\n",params);
return false;
}
- int level = atoi(logLevel.buf);
+ int level = atoi(parts[2].c_str());
Logger* logger = 0;
- if (strcmp("", loggerName.buf) != 0) {
- logger = Logger::getLogger(loggerName.buf);
- if (!logger) fprintf(stderr,"no logger found! %s\n",loggerName.buf);
+ if (!parts[1].empty()) {
+ logger = Logger::getLogger(parts[1].c_str());
+ if (!logger)
+ fprintf(stderr, "no logger found! %s\n", parts[1].c_str());
}
- if (strcmp("*", logwriterName.buf) == 0) {
+ if (parts[0] == "*") {
LogWriter* current = log_writers;
while (current) {
current->setLog(logger);
@@ -97,9 +98,9 @@ bool LogWriter::setLogParams(const char* params) {
}
return true;
} else {
- LogWriter* logwriter = getLogWriter(logwriterName.buf);
+ LogWriter* logwriter = getLogWriter(parts[0].c_str());
if (!logwriter) {
- fprintf(stderr,"no logwriter found! %s\n",logwriterName.buf);
+ fprintf(stderr, "no logwriter found! %s\n", parts[0].c_str());
} else {
logwriter->setLog(logger);
logwriter->setLevel(level);
@@ -122,11 +123,12 @@ bool LogParameter::setParam(const char* v) {
if (immutable) return true;
LogWriter::setLogParams("*::0");
StringParameter::setParam(v);
- CharArray logParam;
- CharArray params(getData());
- while (params.buf) {
- strSplit(params.buf, ',', &logParam.buf, &params.buf);
- if (strlen(logParam.buf) && !LogWriter::setLogParams(logParam.buf))
+ std::vector<std::string> parts;
+ parts = split(v, ',');
+ for (size_t i = 0; i < parts.size(); i++) {
+ if (parts[i].empty())
+ continue;
+ if (!LogWriter::setLogParams(parts[i].c_str()))
return false;
}
return true;
diff --git a/common/rfb/Logger.cxx b/common/rfb/Logger.cxx
index e815dad4..7e0895e4 100644
--- a/common/rfb/Logger.cxx
+++ b/common/rfb/Logger.cxx
@@ -28,7 +28,6 @@
#include <rfb/Logger.h>
#include <rfb/LogWriter.h>
-#include <rfb/util.h>
using namespace rfb;
diff --git a/common/rfb/Logger_file.cxx b/common/rfb/Logger_file.cxx
index 684614cc..9859eb04 100644
--- a/common/rfb/Logger_file.cxx
+++ b/common/rfb/Logger_file.cxx
@@ -22,20 +22,21 @@
#include <config.h>
#endif
+#include <limits.h>
#include <stdlib.h>
#include <string.h>
#include <os/Mutex.h>
-#include <rfb/util.h>
#include <rfb/Logger_file.h>
using namespace rfb;
Logger_File::Logger_File(const char* loggerName)
- : Logger(loggerName), indent(13), width(79), m_filename(0), m_file(0),
+ : Logger(loggerName), indent(13), width(79), m_file(0),
m_lastLogTime(0)
{
+ m_filename[0] = '\0';
mutex = new os::Mutex();
}
@@ -50,11 +51,16 @@ void Logger_File::write(int /*level*/, const char *logname, const char *message)
os::AutoMutex a(mutex);
if (!m_file) {
- if (!m_filename) return;
- CharArray bakFilename(strlen(m_filename) + 1 + 4);
- sprintf(bakFilename.buf, "%s.bak", m_filename);
- remove(bakFilename.buf);
- rename(m_filename, bakFilename.buf);
+ if (m_filename[0] == '\0')
+ return;
+ char bakFilename[PATH_MAX];
+ if (snprintf(bakFilename, sizeof(bakFilename),
+ "%s.bak", m_filename) >= (int)sizeof(bakFilename)) {
+ remove(m_filename);
+ } else {
+ remove(bakFilename);
+ rename(m_filename, bakFilename);
+ }
m_file = fopen(m_filename, "w+");
if (!m_file) return;
}
@@ -93,7 +99,10 @@ void Logger_File::write(int /*level*/, const char *logname, const char *message)
void Logger_File::setFilename(const char* filename)
{
closeFile();
- m_filename = strDup(filename);
+ m_filename[0] = '\0';
+ if (strlen(filename) >= sizeof(filename))
+ return;
+ strcpy(m_filename, filename);
}
void Logger_File::setFile(FILE* file)
@@ -104,13 +113,9 @@ void Logger_File::setFile(FILE* file)
void Logger_File::closeFile()
{
- if (m_filename) {
- if (m_file) {
- fclose(m_file);
- m_file = 0;
- }
- strFree(m_filename);
- m_filename = 0;
+ if (m_file) {
+ fclose(m_file);
+ m_file = 0;
}
}
diff --git a/common/rfb/Logger_file.h b/common/rfb/Logger_file.h
index 5b5c34e1..4542d23c 100644
--- a/common/rfb/Logger_file.h
+++ b/common/rfb/Logger_file.h
@@ -22,6 +22,8 @@
#define __RFB_LOGGER_FILE_H__
#include <time.h>
+#include <limits.h>
+
#include <rfb/Logger.h>
namespace os { class Mutex; }
@@ -42,7 +44,7 @@ namespace rfb {
protected:
void closeFile();
- char* m_filename;
+ char m_filename[PATH_MAX];
FILE* m_file;
time_t m_lastLogTime;
os::Mutex* mutex;
diff --git a/common/rfb/Logger_syslog.cxx b/common/rfb/Logger_syslog.cxx
index 0f5c8423..320ab4b0 100644
--- a/common/rfb/Logger_syslog.cxx
+++ b/common/rfb/Logger_syslog.cxx
@@ -26,7 +26,6 @@
#include <string.h>
#include <syslog.h>
-#include <rfb/util.h>
#include <rfb/Logger_syslog.h>
#include <rfb/LogWriter.h>
diff --git a/common/rfb/Palette.h b/common/rfb/Palette.h
index a9003354..6b8cc57e 100644
--- a/common/rfb/Palette.h
+++ b/common/rfb/Palette.h
@@ -22,8 +22,7 @@
#include <assert.h>
#include <string.h>
-
-#include <rdr/types.h>
+#include <stdint.h>
namespace rfb {
class Palette {
@@ -35,13 +34,13 @@ namespace rfb {
void clear() { numColours = 0; memset(hash, 0, sizeof(hash)); }
- inline bool insert(rdr::U32 colour, int numPixels);
- inline unsigned char lookup(rdr::U32 colour) const;
- inline rdr::U32 getColour(unsigned char index) const;
+ inline bool insert(uint32_t colour, int numPixels);
+ inline unsigned char lookup(uint32_t colour) const;
+ inline uint32_t getColour(unsigned char index) const;
inline int getCount(unsigned char index) const;
protected:
- inline unsigned char genHash(rdr::U32 colour) const;
+ inline unsigned char genHash(uint32_t colour) const;
protected:
int numColours;
@@ -49,7 +48,7 @@ namespace rfb {
struct PaletteListNode {
PaletteListNode *next;
unsigned char idx;
- rdr::U32 colour;
+ uint32_t colour;
};
struct PaletteEntry {
@@ -67,7 +66,7 @@ namespace rfb {
};
}
-inline bool rfb::Palette::insert(rdr::U32 colour, int numPixels)
+inline bool rfb::Palette::insert(uint32_t colour, int numPixels)
{
PaletteListNode* pnode;
PaletteListNode* prev_pnode;
@@ -145,7 +144,7 @@ inline bool rfb::Palette::insert(rdr::U32 colour, int numPixels)
return true;
}
-inline unsigned char rfb::Palette::lookup(rdr::U32 colour) const
+inline unsigned char rfb::Palette::lookup(uint32_t colour) const
{
unsigned char hash_key;
PaletteListNode* pnode;
@@ -165,7 +164,7 @@ inline unsigned char rfb::Palette::lookup(rdr::U32 colour) const
return 0;
}
-inline rdr::U32 rfb::Palette::getColour(unsigned char index) const
+inline uint32_t rfb::Palette::getColour(unsigned char index) const
{
return entry[index].listNode->colour;
}
@@ -175,7 +174,7 @@ inline int rfb::Palette::getCount(unsigned char index) const
return entry[index].numPixels;
}
-inline unsigned char rfb::Palette::genHash(rdr::U32 colour) const
+inline unsigned char rfb::Palette::genHash(uint32_t colour) const
{
unsigned char hash_key;
diff --git a/common/rfb/Password.h b/common/rfb/Password.h
deleted file mode 100644
index 712bc813..00000000
--- a/common/rfb/Password.h
+++ /dev/null
@@ -1,47 +0,0 @@
-/* Copyright (C) 2002-2005 RealVNC Ltd. All Rights Reserved.
- *
- * 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.
- */
-#ifndef __RFB_PASSWORD_H__
-#define __RFB_PASSWORD_H__
-
-#include <rfb/util.h>
-
-namespace rfb {
-
- class ObfuscatedPasswd;
-
- class PlainPasswd : public CharArray {
- public:
- PlainPasswd();
- PlainPasswd(char* pwd);
- PlainPasswd(size_t len);
- PlainPasswd(const ObfuscatedPasswd& obfPwd);
- ~PlainPasswd();
- void replaceBuf(char* b);
- };
-
- class ObfuscatedPasswd : public CharArray {
- public:
- ObfuscatedPasswd();
- ObfuscatedPasswd(size_t l);
- ObfuscatedPasswd(const PlainPasswd& plainPwd);
- ~ObfuscatedPasswd();
- size_t length;
- };
-
-}
-#endif
diff --git a/common/rfb/PixelBuffer.cxx b/common/rfb/PixelBuffer.cxx
index 1b534b7b..c8b5f3d7 100644
--- a/common/rfb/PixelBuffer.cxx
+++ b/common/rfb/PixelBuffer.cxx
@@ -26,6 +26,8 @@
#include <config.h>
#endif
+#include <string.h>
+
#include <rfb/Exception.h>
#include <rfb/LogWriter.h>
#include <rfb/PixelBuffer.h>
@@ -63,10 +65,10 @@ void
PixelBuffer::getImage(void* imageBuf, const Rect& r, int outStride) const
{
int inStride;
- const U8* data;
+ const uint8_t* data;
int bytesPerPixel, inBytesPerRow, outBytesPerRow, bytesPerMemCpy;
- U8* imageBufPos;
- const U8* end;
+ uint8_t* imageBufPos;
+ const uint8_t* end;
if (!r.enclosed_by(getRect()))
throw rfb::Exception("Source rect %dx%d at %d,%d exceeds framebuffer %dx%d",
@@ -83,7 +85,7 @@ PixelBuffer::getImage(void* imageBuf, const Rect& r, int outStride) const
outBytesPerRow = outStride * bytesPerPixel;
bytesPerMemCpy = r.width() * bytesPerPixel;
- imageBufPos = (U8*)imageBuf;
+ imageBufPos = (uint8_t*)imageBuf;
end = data + (inBytesPerRow * r.height());
while (data < end) {
@@ -96,10 +98,10 @@ PixelBuffer::getImage(void* imageBuf, const Rect& r, int outStride) const
void PixelBuffer::getImage(const PixelFormat& pf, void* imageBuf,
const Rect& r, int stride) const
{
- const rdr::U8* srcBuffer;
+ const uint8_t* srcBuffer;
int srcStride;
- if (format.equal(pf)) {
+ if (format == pf) {
getImage(imageBuf, r, stride);
return;
}
@@ -114,8 +116,8 @@ void PixelBuffer::getImage(const PixelFormat& pf, void* imageBuf,
srcBuffer = getBuffer(r, &srcStride);
- pf.bufferFromBuffer((U8*)imageBuf, format, srcBuffer, r.width(), r.height(),
- stride, srcStride);
+ pf.bufferFromBuffer((uint8_t*)imageBuf, format, srcBuffer,
+ r.width(), r.height(), stride, srcStride);
}
void PixelBuffer::setSize(int width, int height)
@@ -148,7 +150,7 @@ ModifiablePixelBuffer::~ModifiablePixelBuffer()
void ModifiablePixelBuffer::fillRect(const Rect& r, const void* pix)
{
int stride;
- U8 *buf;
+ uint8_t *buf;
int w, h, b;
if (!r.enclosed_by(getRect()))
@@ -166,11 +168,11 @@ void ModifiablePixelBuffer::fillRect(const Rect& r, const void* pix)
if (b == 1) {
while (h--) {
- memset(buf, *(const U8*)pix, w);
+ memset(buf, *(const uint8_t*)pix, w);
buf += stride * b;
}
} else {
- U8 *start;
+ uint8_t *start;
int w1;
start = buf;
@@ -195,11 +197,11 @@ void ModifiablePixelBuffer::fillRect(const Rect& r, const void* pix)
void ModifiablePixelBuffer::imageRect(const Rect& r,
const void* pixels, int srcStride)
{
- U8* dest;
+ uint8_t* dest;
int destStride;
int bytesPerPixel, bytesPerDestRow, bytesPerSrcRow, bytesPerFill;
- const U8* src;
- U8* end;
+ const uint8_t* src;
+ uint8_t* end;
if (!r.enclosed_by(getRect()))
throw rfb::Exception("Destination rect %dx%d at %d,%d exceeds framebuffer %dx%d",
@@ -217,7 +219,7 @@ void ModifiablePixelBuffer::imageRect(const Rect& r,
bytesPerSrcRow = bytesPerPixel * srcStride;
bytesPerFill = bytesPerPixel * r.width();
- src = (const U8*)pixels;
+ src = (const uint8_t*)pixels;
end = dest + (bytesPerDestRow * r.height());
while (dest < end) {
@@ -234,8 +236,8 @@ void ModifiablePixelBuffer::copyRect(const Rect &rect,
{
int srcStride, dstStride;
int bytesPerPixel;
- const U8* srcData;
- U8* dstData;
+ const uint8_t* srcData;
+ uint8_t* dstData;
Rect drect, srect;
@@ -290,15 +292,15 @@ void ModifiablePixelBuffer::copyRect(const Rect &rect,
void ModifiablePixelBuffer::fillRect(const PixelFormat& pf, const Rect &dest,
const void* pix)
{
- rdr::U8 buf[4];
- format.bufferFromBuffer(buf, pf, (const rdr::U8*)pix, 1);
+ uint8_t buf[4];
+ format.bufferFromBuffer(buf, pf, (const uint8_t*)pix, 1);
fillRect(dest, buf);
}
void ModifiablePixelBuffer::imageRect(const PixelFormat& pf, const Rect &dest,
const void* pixels, int stride)
{
- rdr::U8* dstBuffer;
+ uint8_t* dstBuffer;
int dstStride;
if (!dest.enclosed_by(getRect()))
@@ -310,7 +312,7 @@ void ModifiablePixelBuffer::imageRect(const PixelFormat& pf, const Rect &dest,
stride = dest.width();
dstBuffer = getBufferRW(dest, &dstStride);
- format.bufferFromBuffer(dstBuffer, pf, (const rdr::U8*)pixels,
+ format.bufferFromBuffer(dstBuffer, pf, (const uint8_t*)pixels,
dest.width(), dest.height(),
dstStride, stride);
commitBufferRW(dest);
@@ -319,7 +321,7 @@ void ModifiablePixelBuffer::imageRect(const PixelFormat& pf, const Rect &dest,
// -=- Simple pixel buffer with a continuous block of memory
FullFramePixelBuffer::FullFramePixelBuffer(const PixelFormat& pf, int w, int h,
- rdr::U8* data_, int stride_)
+ uint8_t* data_, int stride_)
: ModifiablePixelBuffer(pf, w, h), data(data_), stride(stride_)
{
}
@@ -328,7 +330,7 @@ FullFramePixelBuffer::FullFramePixelBuffer() : data(0) {}
FullFramePixelBuffer::~FullFramePixelBuffer() {}
-rdr::U8* FullFramePixelBuffer::getBufferRW(const Rect& r, int* stride_)
+uint8_t* FullFramePixelBuffer::getBufferRW(const Rect& r, int* stride_)
{
if (!r.enclosed_by(getRect()))
throw rfb::Exception("Pixel buffer request %dx%d at %d,%d exceeds framebuffer %dx%d",
@@ -343,7 +345,7 @@ void FullFramePixelBuffer::commitBufferRW(const Rect& /*r*/)
{
}
-const rdr::U8* FullFramePixelBuffer::getBuffer(const Rect& r, int* stride_) const
+const uint8_t* FullFramePixelBuffer::getBuffer(const Rect& r, int* stride_) const
{
if (!r.enclosed_by(getRect()))
throw rfb::Exception("Pixel buffer request %dx%d at %d,%d exceeds framebuffer %dx%d",
@@ -355,7 +357,7 @@ const rdr::U8* FullFramePixelBuffer::getBuffer(const Rect& r, int* stride_) cons
}
void FullFramePixelBuffer::setBuffer(int width, int height,
- rdr::U8* data_, int stride_)
+ uint8_t* data_, int stride_)
{
if ((width < 0) || (width > maxPixelBufferWidth))
throw rfb::Exception("Invalid PixelBuffer width of %d pixels requested", width);
@@ -415,7 +417,7 @@ void ManagedPixelBuffer::setSize(int w, int h)
datasize = 0;
}
if (new_datasize) {
- data_ = new U8[new_datasize];
+ data_ = new uint8_t[new_datasize];
datasize = new_datasize;
}
}
diff --git a/common/rfb/PixelBuffer.h b/common/rfb/PixelBuffer.h
index b12a734e..33a9c7ae 100644
--- a/common/rfb/PixelBuffer.h
+++ b/common/rfb/PixelBuffer.h
@@ -27,8 +27,6 @@
#include <rfb/PixelFormat.h>
#include <rfb/Rect.h>
-#include <rfb/Pixel.h>
-#include <rfb/util.h>
namespace rfb {
@@ -66,7 +64,7 @@ namespace rfb {
// Get a pointer into the buffer
// The pointer is to the top-left pixel of the specified Rect.
// The buffer stride (in pixels) is returned.
- virtual const rdr::U8* getBuffer(const Rect& r, int* stride) const = 0;
+ virtual const uint8_t* getBuffer(const Rect& r, int* stride) const = 0;
// Get pixel data for a given part of the buffer
// Data is copied into the supplied buffer, with the specified
@@ -112,7 +110,7 @@ namespace rfb {
// Get a writeable pointer into the buffer
// Like getBuffer(), the pointer is to the top-left pixel of the
// specified Rect and the stride in pixels is returned.
- virtual rdr::U8* getBufferRW(const Rect& r, int* stride) = 0;
+ virtual uint8_t* getBufferRW(const Rect& r, int* stride) = 0;
// Commit the modified contents
// Ensures that the changes to the specified Rect is properly
// stored away and any temporary buffers are freed. The Rect given
@@ -149,23 +147,23 @@ namespace rfb {
class FullFramePixelBuffer : public ModifiablePixelBuffer {
public:
FullFramePixelBuffer(const PixelFormat& pf, int width, int height,
- rdr::U8* data_, int stride);
+ uint8_t* data_, int stride);
virtual ~FullFramePixelBuffer();
public:
- virtual const rdr::U8* getBuffer(const Rect& r, int* stride) const;
- virtual rdr::U8* getBufferRW(const Rect& r, int* stride);
+ virtual const uint8_t* getBuffer(const Rect& r, int* stride) const;
+ virtual uint8_t* getBufferRW(const Rect& r, int* stride);
virtual void commitBufferRW(const Rect& r);
protected:
FullFramePixelBuffer();
- virtual void setBuffer(int width, int height, rdr::U8* data, int stride);
+ virtual void setBuffer(int width, int height, uint8_t* data, int stride);
private:
virtual void setSize(int w, int h);
private:
- rdr::U8* data;
+ uint8_t* data;
int stride;
};
@@ -183,7 +181,7 @@ namespace rfb {
virtual void setSize(int w, int h);
private:
- rdr::U8* data_; // Mirrors FullFramePixelBuffer::data
+ uint8_t* data_; // Mirrors FullFramePixelBuffer::data
unsigned long datasize;
};
diff --git a/common/rfb/PixelFormat.cxx b/common/rfb/PixelFormat.cxx
index 0abf53b6..b90fc206 100644
--- a/common/rfb/PixelFormat.cxx
+++ b/common/rfb/PixelFormat.cxx
@@ -1,6 +1,6 @@
/* Copyright (C) 2002-2005 RealVNC Ltd. All Rights Reserved.
* Copyright (C) 2011 D. R. Commander. All Rights Reserved.
- * Copyright 2009-2014 Pierre Ossman for Cendio AB
+ * Copyright 2009-2022 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
@@ -30,7 +30,6 @@
#include <rdr/OutStream.h>
#include <rfb/Exception.h>
#include <rfb/PixelFormat.h>
-#include <rfb/util.h>
#ifdef _WIN32
#define strcasecmp _stricmp
@@ -38,8 +37,8 @@
using namespace rfb;
-rdr::U8 PixelFormat::upconvTable[256*8];
-rdr::U8 PixelFormat::downconvTable[256*8];
+uint8_t PixelFormat::upconvTable[256*8];
+uint8_t PixelFormat::downconvTable[256*8];
class PixelFormat::Init {
public:
@@ -59,8 +58,8 @@ PixelFormat::Init::Init()
for (bits = 1;bits <= 8;bits++) {
int i, maxVal;
- rdr::U8 *subUpTable;
- rdr::U8 *subDownTable;
+ uint8_t *subUpTable;
+ uint8_t *subDownTable;
maxVal = (1 << bits) - 1;
subUpTable = &upconvTable[(bits-1)*256];
@@ -100,7 +99,7 @@ PixelFormat::PixelFormat()
updateState();
}
-bool PixelFormat::equal(const PixelFormat& other) const
+bool PixelFormat::operator==(const PixelFormat& other) const
{
if (bpp != other.bpp || depth != other.depth)
return false;
@@ -149,6 +148,11 @@ bool PixelFormat::equal(const PixelFormat& other) const
return true;
}
+bool PixelFormat::operator!=(const PixelFormat& other) const
+{
+ return !(*this == other);
+}
+
void PixelFormat::read(rdr::InStream* is)
{
bpp = is->readU8();
@@ -234,17 +238,17 @@ bool PixelFormat::isLittleEndian(void) const
}
-void PixelFormat::bufferFromRGB(rdr::U8 *dst, const rdr::U8* src, int pixels) const
+void PixelFormat::bufferFromRGB(uint8_t *dst, const uint8_t* src, int pixels) const
{
bufferFromRGB(dst, src, pixels, pixels, 1);
}
-void PixelFormat::bufferFromRGB(rdr::U8 *dst, const rdr::U8* src,
+void PixelFormat::bufferFromRGB(uint8_t *dst, const uint8_t* src,
int w, int stride, int h) const
{
if (is888()) {
// Optimised common case
- rdr::U8 *r, *g, *b, *x;
+ uint8_t *r, *g, *b, *x;
if (bigEndian) {
r = dst + (24 - redShift)/8;
@@ -283,7 +287,7 @@ void PixelFormat::bufferFromRGB(rdr::U8 *dst, const rdr::U8* src,
int w_ = w;
while (w_--) {
Pixel p;
- rdr::U8 r, g, b;
+ uint8_t r, g, b;
r = *(src++);
g = *(src++);
@@ -300,18 +304,18 @@ void PixelFormat::bufferFromRGB(rdr::U8 *dst, const rdr::U8* src,
}
-void PixelFormat::rgbFromBuffer(rdr::U8* dst, const rdr::U8* src, int pixels) const
+void PixelFormat::rgbFromBuffer(uint8_t* dst, const uint8_t* src, int pixels) const
{
rgbFromBuffer(dst, src, pixels, pixels, 1);
}
-void PixelFormat::rgbFromBuffer(rdr::U8* dst, const rdr::U8* src,
+void PixelFormat::rgbFromBuffer(uint8_t* dst, const uint8_t* src,
int w, int stride, int h) const
{
if (is888()) {
// Optimised common case
- const rdr::U8 *r, *g, *b;
+ const uint8_t *r, *g, *b;
if (bigEndian) {
r = src + (24 - redShift)/8;
@@ -345,7 +349,7 @@ void PixelFormat::rgbFromBuffer(rdr::U8* dst, const rdr::U8* src,
int w_ = w;
while (w_--) {
Pixel p;
- rdr::U8 r, g, b;
+ uint8_t r, g, b;
p = pixelFromBuffer(src);
@@ -364,25 +368,25 @@ void PixelFormat::rgbFromBuffer(rdr::U8* dst, const rdr::U8* src,
Pixel PixelFormat::pixelFromPixel(const PixelFormat &srcPF, Pixel src) const
{
- rdr::U16 r, g, b;
+ uint16_t r, g, b;
srcPF.rgbFromPixel(src, &r, &g, &b);
return pixelFromRGB(r, g, b);
}
-void PixelFormat::bufferFromBuffer(rdr::U8* dst, const PixelFormat &srcPF,
- const rdr::U8* src, int pixels) const
+void PixelFormat::bufferFromBuffer(uint8_t* dst, const PixelFormat &srcPF,
+ const uint8_t* src, int pixels) const
{
bufferFromBuffer(dst, srcPF, src, pixels, 1, pixels, pixels);
}
#define IS_ALIGNED(v, a) (((intptr_t)v & (a-1)) == 0)
-void PixelFormat::bufferFromBuffer(rdr::U8* dst, const PixelFormat &srcPF,
- const rdr::U8* src, int w, int h,
+void PixelFormat::bufferFromBuffer(uint8_t* dst, const PixelFormat &srcPF,
+ const uint8_t* src, int w, int h,
int dstStride, int srcStride) const
{
- if (equal(srcPF)) {
+ if (*this == srcPF) {
// Trivial case
while (h--) {
memcpy(dst, src, w * bpp/8);
@@ -391,7 +395,7 @@ void PixelFormat::bufferFromBuffer(rdr::U8* dst, const PixelFormat &srcPF,
}
} else if (is888() && srcPF.is888()) {
// Optimised common case A: byte shuffling (e.g. endian conversion)
- rdr::U8 *d[4], *s[4];
+ uint8_t *d[4], *s[4];
int dstPad, srcPad;
if (bigEndian) {
@@ -442,15 +446,15 @@ void PixelFormat::bufferFromBuffer(rdr::U8* dst, const PixelFormat &srcPF,
// Optimised common case B: 888 source
switch (bpp) {
case 8:
- directBufferFromBufferFrom888((rdr::U8*)dst, srcPF, src,
+ directBufferFromBufferFrom888((uint8_t*)dst, srcPF, src,
w, h, dstStride, srcStride);
break;
case 16:
- directBufferFromBufferFrom888((rdr::U16*)dst, srcPF, src,
+ directBufferFromBufferFrom888((uint16_t*)dst, srcPF, src,
w, h, dstStride, srcStride);
break;
case 32:
- directBufferFromBufferFrom888((rdr::U32*)dst, srcPF, src,
+ directBufferFromBufferFrom888((uint32_t*)dst, srcPF, src,
w, h, dstStride, srcStride);
break;
}
@@ -458,15 +462,15 @@ void PixelFormat::bufferFromBuffer(rdr::U8* dst, const PixelFormat &srcPF,
// Optimised common case C: 888 destination
switch (srcPF.bpp) {
case 8:
- directBufferFromBufferTo888(dst, srcPF, (rdr::U8*)src,
+ directBufferFromBufferTo888(dst, srcPF, (uint8_t*)src,
w, h, dstStride, srcStride);
break;
case 16:
- directBufferFromBufferTo888(dst, srcPF, (rdr::U16*)src,
+ directBufferFromBufferTo888(dst, srcPF, (uint16_t*)src,
w, h, dstStride, srcStride);
break;
case 32:
- directBufferFromBufferTo888(dst, srcPF, (rdr::U32*)src,
+ directBufferFromBufferTo888(dst, srcPF, (uint32_t*)src,
w, h, dstStride, srcStride);
break;
}
@@ -478,7 +482,7 @@ void PixelFormat::bufferFromBuffer(rdr::U8* dst, const PixelFormat &srcPF,
int w_ = w;
while (w_--) {
Pixel p;
- rdr::U8 r, g, b;
+ uint8_t r, g, b;
p = srcPF.pixelFromBuffer(src);
srcPF.rgbFromPixel(p, &r, &g, &b);
@@ -579,8 +583,8 @@ bool PixelFormat::parse(const char* str)
depth = bits1 + bits2 + bits3;
bpp = depth <= 8 ? 8 : ((depth <= 16) ? 16 : 32);
trueColour = true;
- rdr::U32 endianTest = 1;
- bigEndian = (*(rdr::U8*)&endianTest == 0);
+ uint32_t endianTest = 1;
+ bigEndian = (*(uint8_t*)&endianTest == 0);
greenShift = bits3;
greenMax = (1 << bits2) - 1;
@@ -607,7 +611,7 @@ bool PixelFormat::parse(const char* str)
}
-static int bits(rdr::U16 value)
+static int bits(uint16_t value)
{
int bits;
@@ -710,41 +714,133 @@ bool PixelFormat::isSane(void)
return true;
}
-// Preprocessor generated, optimised methods
-
-#define INBPP 8
-#define OUTBPP 8
-#include "PixelFormatBPP.cxx"
-#undef OUTBPP
-#define OUTBPP 16
-#include "PixelFormatBPP.cxx"
-#undef OUTBPP
-#define OUTBPP 32
-#include "PixelFormatBPP.cxx"
-#undef OUTBPP
-#undef INBPP
-
-#define INBPP 16
-#define OUTBPP 8
-#include "PixelFormatBPP.cxx"
-#undef OUTBPP
-#define OUTBPP 16
-#include "PixelFormatBPP.cxx"
-#undef OUTBPP
-#define OUTBPP 32
-#include "PixelFormatBPP.cxx"
-#undef OUTBPP
-#undef INBPP
-
-#define INBPP 32
-#define OUTBPP 8
-#include "PixelFormatBPP.cxx"
-#undef OUTBPP
-#define OUTBPP 16
-#include "PixelFormatBPP.cxx"
-#undef OUTBPP
-#define OUTBPP 32
-#include "PixelFormatBPP.cxx"
-#undef OUTBPP
-#undef INBPP
+static inline uint8_t swap(uint8_t n)
+{
+ return n;
+}
+
+static inline uint16_t swap(uint16_t n)
+{
+ return (((n) & 0xff) << 8) | (((n) >> 8) & 0xff);
+}
+
+static inline uint32_t swap(uint32_t n)
+{
+ return ((n) >> 24) | (((n) & 0x00ff0000) >> 8) |
+ (((n) & 0x0000ff00) << 8) | ((n) << 24);
+}
+
+template<class T>
+void PixelFormat::directBufferFromBufferFrom888(T* dst,
+ const PixelFormat &srcPF,
+ const uint8_t* src,
+ int w, int h,
+ int dstStride,
+ int srcStride) const
+{
+ const uint8_t *r, *g, *b;
+ int dstPad, srcPad;
+
+ const uint8_t *redDownTable, *greenDownTable, *blueDownTable;
+
+ redDownTable = &downconvTable[(redBits-1)*256];
+ greenDownTable = &downconvTable[(greenBits-1)*256];
+ blueDownTable = &downconvTable[(blueBits-1)*256];
+
+ if (srcPF.bigEndian) {
+ r = src + (24 - srcPF.redShift)/8;
+ g = src + (24 - srcPF.greenShift)/8;
+ b = src + (24 - srcPF.blueShift)/8;
+ } else {
+ r = src + srcPF.redShift/8;
+ g = src + srcPF.greenShift/8;
+ b = src + srcPF.blueShift/8;
+ }
+
+ dstPad = (dstStride - w);
+ srcPad = (srcStride - w) * 4;
+ while (h--) {
+ int w_ = w;
+ while (w_--) {
+ T d;
+
+ d = redDownTable[*r] << redShift;
+ d |= greenDownTable[*g] << greenShift;
+ d |= blueDownTable[*b] << blueShift;
+
+ if (endianMismatch)
+ d = swap(d);
+
+ *dst = d;
+
+ dst++;
+ r += 4;
+ g += 4;
+ b += 4;
+ }
+ dst += dstPad;
+ r += srcPad;
+ g += srcPad;
+ b += srcPad;
+ }
+}
+
+template<class T>
+void PixelFormat::directBufferFromBufferTo888(uint8_t* dst,
+ const PixelFormat &srcPF,
+ const T* src,
+ int w, int h,
+ int dstStride,
+ int srcStride) const
+{
+ uint8_t *r, *g, *b, *x;
+ int dstPad, srcPad;
+
+ const uint8_t *redUpTable, *greenUpTable, *blueUpTable;
+
+ redUpTable = &upconvTable[(srcPF.redBits-1)*256];
+ greenUpTable = &upconvTable[(srcPF.greenBits-1)*256];
+ blueUpTable = &upconvTable[(srcPF.blueBits-1)*256];
+ if (bigEndian) {
+ r = dst + (24 - redShift)/8;
+ g = dst + (24 - greenShift)/8;
+ b = dst + (24 - blueShift)/8;
+ x = dst + (24 - (48 - redShift - greenShift - blueShift))/8;
+ } else {
+ r = dst + redShift/8;
+ g = dst + greenShift/8;
+ b = dst + blueShift/8;
+ x = dst + (48 - redShift - greenShift - blueShift)/8;
+ }
+
+ dstPad = (dstStride - w) * 4;
+ srcPad = (srcStride - w);
+ while (h--) {
+ int w_ = w;
+ while (w_--) {
+ T s;
+
+ s = *src;
+
+ if (srcPF.endianMismatch)
+ s = swap(s);
+
+ *r = redUpTable[(s >> srcPF.redShift) & 0xff];
+ *g = greenUpTable[(s >> srcPF.greenShift) & 0xff];
+ *b = blueUpTable[(s >> srcPF.blueShift) & 0xff];
+ *x = 0;
+
+ r += 4;
+ g += 4;
+ b += 4;
+ x += 4;
+ src++;
+ }
+ r += dstPad;
+ g += dstPad;
+ b += dstPad;
+ x += dstPad;
+ src += srcPad;
+ }
+}
diff --git a/common/rfb/PixelFormat.h b/common/rfb/PixelFormat.h
index 5b4b6332..f0a16767 100644
--- a/common/rfb/PixelFormat.h
+++ b/common/rfb/PixelFormat.h
@@ -1,6 +1,6 @@
/* Copyright (C) 2002-2005 RealVNC Ltd. All Rights Reserved.
* Copyright (C) 2011 D. R. Commander. All Rights Reserved.
- * Copyright 2009-2014 Pierre Ossman for Cendio AB
+ * Copyright 2009-2022 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
@@ -34,12 +34,14 @@
#ifndef __RFB_PIXELFORMAT_H__
#define __RFB_PIXELFORMAT_H__
-#include <rfb/Pixel.h>
+#include <stdint.h>
namespace rdr { class InStream; class OutStream; }
namespace rfb {
+ typedef uint32_t Pixel; // must be big enough to hold any pixel value
+
class PixelFormat {
public:
PixelFormat(int b, int d, bool e, bool t,
@@ -49,7 +51,8 @@ namespace rfb {
// Checks if the formats have identical buffer representation.
// They might still have different pixel representation, endianness
// or true colour state.
- bool equal(const PixelFormat& other) const;
+ bool operator==(const PixelFormat& other) const;
+ bool operator!=(const PixelFormat& other) const;
void read(rdr::InStream* is);
void write(rdr::OutStream* os) const;
@@ -58,29 +61,29 @@ namespace rfb {
bool isBigEndian(void) const;
bool isLittleEndian(void) const;
- inline Pixel pixelFromBuffer(const rdr::U8* buffer) const;
- inline void bufferFromPixel(rdr::U8* buffer, Pixel pixel) const;
+ inline Pixel pixelFromBuffer(const uint8_t* buffer) const;
+ inline void bufferFromPixel(uint8_t* buffer, Pixel pixel) const;
- inline Pixel pixelFromRGB(rdr::U16 red, rdr::U16 green, rdr::U16 blue) const;
- inline Pixel pixelFromRGB(rdr::U8 red, rdr::U8 green, rdr::U8 blue) const;
+ inline Pixel pixelFromRGB(uint16_t red, uint16_t green, uint16_t blue) const;
+ inline Pixel pixelFromRGB(uint8_t red, uint8_t green, uint8_t blue) const;
- void bufferFromRGB(rdr::U8 *dst, const rdr::U8* src, int pixels) const;
- void bufferFromRGB(rdr::U8 *dst, const rdr::U8* src,
+ void bufferFromRGB(uint8_t *dst, const uint8_t* src, int pixels) const;
+ void bufferFromRGB(uint8_t *dst, const uint8_t* src,
int w, int stride, int h) const;
- inline void rgbFromPixel(Pixel pix, rdr::U16 *r, rdr::U16 *g, rdr::U16 *b) const;
- inline void rgbFromPixel(Pixel pix, rdr::U8 *r, rdr::U8 *g, rdr::U8 *b) const;
+ inline void rgbFromPixel(Pixel pix, uint16_t *r, uint16_t *g, uint16_t *b) const;
+ inline void rgbFromPixel(Pixel pix, uint8_t *r, uint8_t *g, uint8_t *b) const;
- void rgbFromBuffer(rdr::U8* dst, const rdr::U8* src, int pixels) const;
- void rgbFromBuffer(rdr::U8* dst, const rdr::U8* src,
+ void rgbFromBuffer(uint8_t* dst, const uint8_t* src, int pixels) const;
+ void rgbFromBuffer(uint8_t* dst, const uint8_t* src,
int w, int stride, int h) const;
Pixel pixelFromPixel(const PixelFormat &srcPF, Pixel src) const;
- void bufferFromBuffer(rdr::U8* dst, const PixelFormat &srcPF,
- const rdr::U8* src, int pixels) const;
- void bufferFromBuffer(rdr::U8* dst, const PixelFormat &srcPF,
- const rdr::U8* src, int w, int h,
+ void bufferFromBuffer(uint8_t* dst, const PixelFormat &srcPF,
+ const uint8_t* src, int pixels) const;
+ void bufferFromBuffer(uint8_t* dst, const PixelFormat &srcPF,
+ const uint8_t* src, int w, int h,
int dstStride, int srcStride) const;
void print(char* str, int len) const;
@@ -91,26 +94,14 @@ namespace rfb {
bool isSane(void);
private:
- // Preprocessor generated, optimised methods
-
- void directBufferFromBufferFrom888(rdr::U8* dst, const PixelFormat &srcPF,
- const rdr::U8* src, int w, int h,
- int dstStride, int srcStride) const;
- void directBufferFromBufferFrom888(rdr::U16* dst, const PixelFormat &srcPF,
- const rdr::U8* src, int w, int h,
- int dstStride, int srcStride) const;
- void directBufferFromBufferFrom888(rdr::U32* dst, const PixelFormat &srcPF,
- const rdr::U8* src, int w, int h,
+ // Templated, optimised methods
+ template<class T>
+ void directBufferFromBufferFrom888(T* dst, const PixelFormat &srcPF,
+ const uint8_t* src, int w, int h,
int dstStride, int srcStride) const;
-
- void directBufferFromBufferTo888(rdr::U8* dst, const PixelFormat &srcPF,
- const rdr::U8* src, int w, int h,
- int dstStride, int srcStride) const;
- void directBufferFromBufferTo888(rdr::U8* dst, const PixelFormat &srcPF,
- const rdr::U16* src, int w, int h,
- int dstStride, int srcStride) const;
- void directBufferFromBufferTo888(rdr::U8* dst, const PixelFormat &srcPF,
- const rdr::U32* src, int w, int h,
+ template<class T>
+ void directBufferFromBufferTo888(uint8_t* dst, const PixelFormat &srcPF,
+ const T* src, int w, int h,
int dstStride, int srcStride) const;
public:
@@ -136,18 +127,18 @@ namespace rfb {
int maxBits, minBits;
bool endianMismatch;
- static rdr::U8 upconvTable[256*8];
- static rdr::U8 downconvTable[256*8];
+ static uint8_t upconvTable[256*8];
+ static uint8_t downconvTable[256*8];
class Init;
friend class Init;
static Init _init;
/* Only for testing this class */
- friend void makePixel(const rfb::PixelFormat &, rdr::U8 *);
+ friend void makePixel(const rfb::PixelFormat &, uint8_t *);
friend bool verifyPixel(const rfb::PixelFormat &,
const rfb::PixelFormat &,
- const rdr::U8 *);
+ const uint8_t *);
};
}
diff --git a/common/rfb/PixelFormat.inl b/common/rfb/PixelFormat.inl
index 3a0bfe49..beec096a 100644
--- a/common/rfb/PixelFormat.inl
+++ b/common/rfb/PixelFormat.inl
@@ -19,7 +19,7 @@
namespace rfb {
-inline Pixel PixelFormat::pixelFromBuffer(const rdr::U8* buffer) const
+inline Pixel PixelFormat::pixelFromBuffer(const uint8_t* buffer) const
{
Pixel p;
@@ -52,7 +52,7 @@ inline Pixel PixelFormat::pixelFromBuffer(const rdr::U8* buffer) const
}
-inline void PixelFormat::bufferFromPixel(rdr::U8* buffer, Pixel p) const
+inline void PixelFormat::bufferFromPixel(uint8_t* buffer, Pixel p) const
{
if (bigEndian) {
switch (bpp) {
@@ -79,7 +79,7 @@ inline void PixelFormat::bufferFromPixel(rdr::U8* buffer, Pixel p) const
}
-inline Pixel PixelFormat::pixelFromRGB(rdr::U16 red, rdr::U16 green, rdr::U16 blue) const
+inline Pixel PixelFormat::pixelFromRGB(uint16_t red, uint16_t green, uint16_t blue) const
{
Pixel p;
@@ -91,7 +91,7 @@ inline Pixel PixelFormat::pixelFromRGB(rdr::U16 red, rdr::U16 green, rdr::U16 bl
}
-inline Pixel PixelFormat::pixelFromRGB(rdr::U8 red, rdr::U8 green, rdr::U8 blue) const
+inline Pixel PixelFormat::pixelFromRGB(uint8_t red, uint8_t green, uint8_t blue) const
{
Pixel p;
@@ -103,9 +103,9 @@ inline Pixel PixelFormat::pixelFromRGB(rdr::U8 red, rdr::U8 green, rdr::U8 blue)
}
-inline void PixelFormat::rgbFromPixel(Pixel p, rdr::U16 *r, rdr::U16 *g, rdr::U16 *b) const
+inline void PixelFormat::rgbFromPixel(Pixel p, uint16_t *r, uint16_t *g, uint16_t *b) const
{
- rdr::U8 _r, _g, _b;
+ uint8_t _r, _g, _b;
_r = p >> redShift;
_g = p >> greenShift;
@@ -121,9 +121,9 @@ inline void PixelFormat::rgbFromPixel(Pixel p, rdr::U16 *r, rdr::U16 *g, rdr::U1
}
-inline void PixelFormat::rgbFromPixel(Pixel p, rdr::U8 *r, rdr::U8 *g, rdr::U8 *b) const
+inline void PixelFormat::rgbFromPixel(Pixel p, uint8_t *r, uint8_t *g, uint8_t *b) const
{
- rdr::U8 _r, _g, _b;
+ uint8_t _r, _g, _b;
_r = p >> redShift;
_g = p >> greenShift;
diff --git a/common/rfb/PixelFormatBPP.cxx b/common/rfb/PixelFormatBPP.cxx
deleted file mode 100644
index c8e432df..00000000
--- a/common/rfb/PixelFormatBPP.cxx
+++ /dev/null
@@ -1,155 +0,0 @@
-/* Copyright 2014 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.
- */
-
-#define CONCAT2(a,b) a##b
-#define CONCAT2E(a,b) CONCAT2(a,b)
-
-#define UIN CONCAT2E(U,INBPP)
-#define UOUT CONCAT2E(U,OUTBPP)
-
-#define SWAP16(n) ((((n) & 0xff) << 8) | (((n) >> 8) & 0xff))
-#define SWAP32(n) (((n) >> 24) | (((n) & 0x00ff0000) >> 8) | \
- (((n) & 0x0000ff00) << 8) | ((n) << 24))
-
-#define SWAPIN CONCAT2E(SWAP,INBPP)
-#define SWAPOUT CONCAT2E(SWAP,OUTBPP)
-
-#if INBPP == 32
-
-void PixelFormat::directBufferFromBufferFrom888(rdr::UOUT* dst,
- const PixelFormat &srcPF,
- const rdr::U8* src,
- int w, int h,
- int dstStride,
- int srcStride) const
-{
- const rdr::U8 *r, *g, *b;
- int dstPad, srcPad;
-
- const rdr::U8 *redDownTable, *greenDownTable, *blueDownTable;
-
- redDownTable = &downconvTable[(redBits-1)*256];
- greenDownTable = &downconvTable[(greenBits-1)*256];
- blueDownTable = &downconvTable[(blueBits-1)*256];
-
- if (srcPF.bigEndian) {
- r = src + (24 - srcPF.redShift)/8;
- g = src + (24 - srcPF.greenShift)/8;
- b = src + (24 - srcPF.blueShift)/8;
- } else {
- r = src + srcPF.redShift/8;
- g = src + srcPF.greenShift/8;
- b = src + srcPF.blueShift/8;
- }
-
- dstPad = (dstStride - w);
- srcPad = (srcStride - w) * 4;
- while (h--) {
- int w_ = w;
- while (w_--) {
- rdr::UOUT d;
-
- d = redDownTable[*r] << redShift;
- d |= greenDownTable[*g] << greenShift;
- d |= blueDownTable[*b] << blueShift;
-
-#if OUTBPP != 8
- if (endianMismatch)
- d = SWAPOUT(d);
-#endif
-
- *dst = d;
-
- dst++;
- r += 4;
- g += 4;
- b += 4;
- }
- dst += dstPad;
- r += srcPad;
- g += srcPad;
- b += srcPad;
- }
-}
-
-#endif /* INBPP == 32 */
-
-#if OUTBPP == 32
-
-void PixelFormat::directBufferFromBufferTo888(rdr::U8* dst,
- const PixelFormat &srcPF,
- const rdr::UIN* src,
- int w, int h,
- int dstStride,
- int srcStride) const
-{
- rdr::U8 *r, *g, *b, *x;
- int dstPad, srcPad;
-
- const rdr::U8 *redUpTable, *greenUpTable, *blueUpTable;
-
- redUpTable = &upconvTable[(srcPF.redBits-1)*256];
- greenUpTable = &upconvTable[(srcPF.greenBits-1)*256];
- blueUpTable = &upconvTable[(srcPF.blueBits-1)*256];
-
- if (bigEndian) {
- r = dst + (24 - redShift)/8;
- g = dst + (24 - greenShift)/8;
- b = dst + (24 - blueShift)/8;
- x = dst + (24 - (48 - redShift - greenShift - blueShift))/8;
- } else {
- r = dst + redShift/8;
- g = dst + greenShift/8;
- b = dst + blueShift/8;
- x = dst + (48 - redShift - greenShift - blueShift)/8;
- }
-
- dstPad = (dstStride - w) * 4;
- srcPad = (srcStride - w);
- while (h--) {
- int w_ = w;
- while (w_--) {
- rdr::UIN s;
-
- s = *src;
-
-#if INBPP != 8
- if (srcPF.endianMismatch)
- s = SWAPIN(s);
-#endif
-
- *r = redUpTable[(s >> srcPF.redShift) & 0xff];
- *g = greenUpTable[(s >> srcPF.greenShift) & 0xff];
- *b = blueUpTable[(s >> srcPF.blueShift) & 0xff];
- *x = 0;
-
- r += 4;
- g += 4;
- b += 4;
- x += 4;
- src++;
- }
- r += dstPad;
- g += dstPad;
- b += dstPad;
- x += dstPad;
- src += srcPad;
- }
-}
-
-#endif /* OUTBPP == 32 */
diff --git a/common/rfb/RREDecoder.cxx b/common/rfb/RREDecoder.cxx
index a01cbe74..c85c015c 100644
--- a/common/rfb/RREDecoder.cxx
+++ b/common/rfb/RREDecoder.cxx
@@ -1,4 +1,5 @@
/* Copyright (C) 2002-2005 RealVNC Ltd. All Rights Reserved.
+ * Copyright 2014-2022 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
@@ -24,22 +25,13 @@
#include <rdr/MemInStream.h>
#include <rdr/OutStream.h>
+#include <rfb/Exception.h>
#include <rfb/ServerParams.h>
#include <rfb/PixelBuffer.h>
#include <rfb/RREDecoder.h>
using namespace rfb;
-#define BPP 8
-#include <rfb/rreDecode.h>
-#undef BPP
-#define BPP 16
-#include <rfb/rreDecode.h>
-#undef BPP
-#define BPP 32
-#include <rfb/rreDecode.h>
-#undef BPP
-
RREDecoder::RREDecoder() : Decoder(DecoderPlain)
{
}
@@ -51,7 +43,7 @@ RREDecoder::~RREDecoder()
bool RREDecoder::readRect(const Rect& /*r*/, rdr::InStream* is,
const ServerParams& server, rdr::OutStream* os)
{
- rdr::U32 numRects;
+ uint32_t numRects;
size_t len;
if (!is->hasData(4))
@@ -81,8 +73,42 @@ void RREDecoder::decodeRect(const Rect& r, const void* buffer,
rdr::MemInStream is(buffer, buflen);
const PixelFormat& pf = server.pf();
switch (pf.bpp) {
- case 8: rreDecode8 (r, &is, pf, pb); break;
- case 16: rreDecode16(r, &is, pf, pb); break;
- case 32: rreDecode32(r, &is, pf, pb); break;
+ case 8: rreDecode<uint8_t >(r, &is, pf, pb); break;
+ case 16: rreDecode<uint16_t>(r, &is, pf, pb); break;
+ case 32: rreDecode<uint32_t>(r, &is, pf, pb); break;
+ }
+}
+
+template<class T>
+inline T RREDecoder::readPixel(rdr::InStream* is)
+{
+ if (sizeof(T) == 1)
+ return is->readOpaque8();
+ if (sizeof(T) == 2)
+ return is->readOpaque16();
+ if (sizeof(T) == 4)
+ return is->readOpaque32();
+}
+
+template<class T>
+void RREDecoder::rreDecode(const Rect& r, rdr::InStream* is,
+ const PixelFormat& pf,
+ ModifiablePixelBuffer* pb)
+{
+ int nSubrects = is->readU32();
+ T bg = readPixel<T>(is);
+ pb->fillRect(pf, r, &bg);
+
+ for (int i = 0; i < nSubrects; i++) {
+ T pix = readPixel<T>(is);
+ int x = is->readU16();
+ int y = is->readU16();
+ int w = is->readU16();
+ int h = is->readU16();
+
+ if (((x+w) > r.width()) || ((y+h) > r.height()))
+ throw Exception ("RRE decode error");
+
+ pb->fillRect(pf, Rect(r.tl.x+x, r.tl.y+y, r.tl.x+x+w, r.tl.y+y+h), &pix);
}
}
diff --git a/common/rfb/RREDecoder.h b/common/rfb/RREDecoder.h
index b8ec18f6..05acbc24 100644
--- a/common/rfb/RREDecoder.h
+++ b/common/rfb/RREDecoder.h
@@ -1,4 +1,5 @@
/* Copyright (C) 2002-2005 RealVNC Ltd. All Rights Reserved.
+ * Copyright 2014-2022 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
@@ -22,6 +23,8 @@
namespace rfb {
+ class PixelFormat;
+
class RREDecoder : public Decoder {
public:
RREDecoder();
@@ -31,6 +34,12 @@ namespace rfb {
virtual void decodeRect(const Rect& r, const void* buffer,
size_t buflen, const ServerParams& server,
ModifiablePixelBuffer* pb);
+ private:
+ template<class T>
+ inline T readPixel(rdr::InStream* is);
+ template<class T>
+ void rreDecode(const Rect& r, rdr::InStream* is,
+ const PixelFormat& pf, ModifiablePixelBuffer* pb);
};
}
#endif
diff --git a/common/rfb/RREEncoder.cxx b/common/rfb/RREEncoder.cxx
index 31f94e7c..e73a23bf 100644
--- a/common/rfb/RREEncoder.cxx
+++ b/common/rfb/RREEncoder.cxx
@@ -1,5 +1,5 @@
/* Copyright (C) 2002-2005 RealVNC Ltd. All Rights Reserved.
- * Copyright 2014 Pierre Ossman for Cendio AB
+ * Copyright 2014-2022 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
@@ -31,16 +31,6 @@
using namespace rfb;
-#define BPP 8
-#include <rfb/rreEncode.h>
-#undef BPP
-#define BPP 16
-#include <rfb/rreEncode.h>
-#undef BPP
-#define BPP 32
-#include <rfb/rreEncode.h>
-#undef BPP
-
RREEncoder::RREEncoder(SConnection* conn) :
Encoder(conn, encodingRRE, EncoderPlain)
{
@@ -57,9 +47,9 @@ bool RREEncoder::isSupported()
void RREEncoder::writeRect(const PixelBuffer* pb, const Palette& palette)
{
- rdr::U8* imageBuf;
+ uint8_t* imageBuf;
int stride;
- rdr::U32 bg;
+ uint32_t bg;
int w = pb->width();
int h = pb->height();
@@ -89,13 +79,13 @@ void RREEncoder::writeRect(const PixelBuffer* pb, const Palette& palette)
int nSubrects = -1;
switch (pb->getPF().bpp) {
case 8:
- nSubrects = rreEncode8((rdr::U8*)imageBuf, w, h, &mos, bg);
+ nSubrects = rreEncode<uint8_t>((uint8_t*)imageBuf, w, h, &mos, bg);
break;
case 16:
- nSubrects = rreEncode16((rdr::U16*)imageBuf, w, h, &mos, bg);
+ nSubrects = rreEncode<uint16_t>((uint16_t*)imageBuf, w, h, &mos, bg);
break;
case 32:
- nSubrects = rreEncode32((rdr::U32*)imageBuf, w, h, &mos, bg);
+ nSubrects = rreEncode<uint32_t>((uint32_t*)imageBuf, w, h, &mos, bg);
break;
}
@@ -109,7 +99,7 @@ void RREEncoder::writeRect(const PixelBuffer* pb, const Palette& palette)
void RREEncoder::writeSolidRect(int /*width*/, int /*height*/,
const PixelFormat& pf,
- const rdr::U8* colour)
+ const uint8_t* colour)
{
rdr::OutStream* os;
@@ -118,3 +108,93 @@ void RREEncoder::writeSolidRect(int /*width*/, int /*height*/,
os->writeU32(0);
os->writeBytes(colour, pf.bpp/8);
}
+
+template<class T>
+inline void RREEncoder::writePixel(rdr::OutStream* os, T pixel)
+{
+ if (sizeof(T) == 1)
+ os->writeOpaque8(pixel);
+ else if (sizeof(T) == 2)
+ os->writeOpaque16(pixel);
+ else if (sizeof(T) == 4)
+ os->writeOpaque32(pixel);
+}
+
+template<class T>
+int RREEncoder::rreEncode(T* data, int w, int h,
+ rdr::OutStream* os, T bg)
+{
+ writePixel(os, bg);
+
+ int nSubrects = 0;
+
+ for (int y = 0; y < h; y++)
+ {
+ int x = 0;
+ while (x < w) {
+ if (*data == bg) {
+ x++;
+ data++;
+ continue;
+ }
+
+ // Find horizontal subrect first
+ T* ptr = data+1;
+ T* eol = data+w-x;
+ while (ptr < eol && *ptr == *data) ptr++;
+ int sw = ptr - data;
+
+ ptr = data + w;
+ int sh = 1;
+ while (sh < h-y) {
+ eol = ptr + sw;
+ while (ptr < eol)
+ if (*ptr++ != *data) goto endOfHorizSubrect;
+ ptr += w - sw;
+ sh++;
+ }
+ endOfHorizSubrect:
+
+ // Find vertical subrect
+ int vh;
+ for (vh = sh; vh < h-y; vh++)
+ if (data[vh*w] != *data) break;
+
+ if (vh != sh) {
+ ptr = data+1;
+ int vw;
+ for (vw = 1; vw < sw; vw++) {
+ for (int i = 0; i < vh; i++)
+ if (ptr[i*w] != *data) goto endOfVertSubrect;
+ ptr++;
+ }
+ endOfVertSubrect:
+
+ // If vertical subrect bigger than horizontal then use that.
+ if (sw*sh < vw*vh) {
+ sw = vw;
+ sh = vh;
+ }
+ }
+
+ nSubrects++;
+ writePixel(os, *data);
+ os->writeU16(x);
+ os->writeU16(y);
+ os->writeU16(sw);
+ os->writeU16(sh);
+
+ ptr = data+w;
+ T* eor = data+w*sh;
+ while (ptr < eor) {
+ eol = ptr + sw;
+ while (ptr < eol) *ptr++ = bg;
+ ptr += w - sw;
+ }
+ x += sw;
+ data += sw;
+ }
+ }
+
+ return nSubrects;
+}
diff --git a/common/rfb/RREEncoder.h b/common/rfb/RREEncoder.h
index c0de9995..b13135b4 100644
--- a/common/rfb/RREEncoder.h
+++ b/common/rfb/RREEncoder.h
@@ -1,5 +1,5 @@
/* Copyright (C) 2002-2005 RealVNC Ltd. All Rights Reserved.
- * Copyright 2014 Pierre Ossman for Cendio AB
+ * Copyright 2014-2022 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
@@ -33,7 +33,12 @@ namespace rfb {
virtual void writeRect(const PixelBuffer* pb, const Palette& palette);
virtual void writeSolidRect(int width, int height,
const PixelFormat& pf,
- const rdr::U8* colour);
+ const uint8_t* colour);
+ private:
+ template<class T>
+ inline void writePixel(rdr::OutStream* os, T pixel);
+ template<class T>
+ int rreEncode(T* data, int w, int h, rdr::OutStream* os, T bg);
private:
rdr::MemOutStream mos;
ManagedPixelBuffer bufferCopy;
diff --git a/common/rfb/RawEncoder.cxx b/common/rfb/RawEncoder.cxx
index 28115588..2fa1af36 100644
--- a/common/rfb/RawEncoder.cxx
+++ b/common/rfb/RawEncoder.cxx
@@ -47,7 +47,7 @@ bool RawEncoder::isSupported()
void RawEncoder::writeRect(const PixelBuffer* pb,
const Palette& /*palette*/)
{
- const rdr::U8* buffer;
+ const uint8_t* buffer;
int stride;
rdr::OutStream* os;
@@ -68,7 +68,7 @@ void RawEncoder::writeRect(const PixelBuffer* pb,
void RawEncoder::writeSolidRect(int width, int height,
const PixelFormat& pf,
- const rdr::U8* colour)
+ const uint8_t* colour)
{
rdr::OutStream* os;
int pixels, pixel_size;
diff --git a/common/rfb/RawEncoder.h b/common/rfb/RawEncoder.h
index ee98d4ad..76da4c5b 100644
--- a/common/rfb/RawEncoder.h
+++ b/common/rfb/RawEncoder.h
@@ -31,7 +31,7 @@ namespace rfb {
virtual void writeRect(const PixelBuffer* pb, const Palette& palette);
virtual void writeSolidRect(int width, int height,
const PixelFormat& pf,
- const rdr::U8* colour);
+ const uint8_t* colour);
};
}
#endif
diff --git a/common/rfb/Rect.h b/common/rfb/Rect.h
index b5ae2548..b82ed274 100644
--- a/common/rfb/Rect.h
+++ b/common/rfb/Rect.h
@@ -47,10 +47,17 @@ namespace rfb {
struct Point {
Point() : x(0), y(0) {}
Point(int x_, int y_) : x(x_), y(y_) {}
- inline Point negate() const {return Point(-x, -y);}
- inline bool equals(const Point &p) const {return x==p.x && y==p.y;}
- inline Point translate(const Point &p) const {return Point(x+p.x, y+p.y);}
- inline Point subtract(const Point &p) const {return Point(x-p.x, y-p.y);}
+ inline Point negate() const
+ __attribute__ ((warn_unused_result))
+ {return Point(-x, -y);}
+ inline bool operator==(const Point &p) const {return x==p.x && y==p.y;}
+ inline bool operator!=(const Point &p) const {return x!=p.x || y!=p.y;}
+ inline Point translate(const Point &p) const
+ __attribute__ ((warn_unused_result))
+ {return Point(x+p.x, y+p.y);}
+ inline Point subtract(const Point &p) const
+ __attribute__ ((warn_unused_result))
+ {return Point(x-p.x, y-p.y);}
int x, y;
};
@@ -72,7 +79,9 @@ namespace rfb {
inline void setXYWH(int x, int y, int w, int h) {
tl.x = x; tl.y = y; br.x = x+w; br.y = y+h;
}
- inline Rect intersect(const Rect &r) const {
+ inline Rect intersect(const Rect &r) const
+ __attribute__ ((warn_unused_result))
+ {
Rect result;
result.tl.x = __rfbmax(tl.x, r.tl.x);
result.tl.y = __rfbmax(tl.y, r.tl.y);
@@ -80,7 +89,9 @@ namespace rfb {
result.br.y = __rfbmax(__rfbmin(br.y, r.br.y), result.tl.y);
return result;
}
- inline Rect union_boundary(const Rect &r) const {
+ inline Rect union_boundary(const Rect &r) const
+ __attribute__ ((warn_unused_result))
+ {
if (r.is_empty()) return *this;
if (is_empty()) return r;
Rect result;
@@ -90,10 +101,13 @@ namespace rfb {
result.br.y = __rfbmax(br.y, r.br.y);
return result;
}
- inline Rect translate(const Point &p) const {
+ inline Rect translate(const Point &p) const
+ __attribute__ ((warn_unused_result))
+ {
return Rect(tl.translate(p), br.translate(p));
}
- inline bool equals(const Rect &r) const {return r.tl.equals(tl) && r.br.equals(br);}
+ inline bool operator==(const Rect &r) const {return r.tl == tl && r.br == br;}
+ inline bool operator!=(const Rect &r) const {return r.tl != tl || r.br != br;}
inline bool is_empty() const {return (tl.x >= br.x) || (tl.y >= br.y);}
inline void clear() {tl = Point(); br = Point();}
inline bool enclosed_by(const Rect &r) const {
diff --git a/common/rfb/Region.cxx b/common/rfb/Region.cxx
index fecc881e..cfdf0ca2 100644
--- a/common/rfb/Region.cxx
+++ b/common/rfb/Region.cxx
@@ -101,10 +101,14 @@ rfb::Region rfb::Region::subtract(const rfb::Region& r) const {
return ret;
}
-bool rfb::Region::equals(const rfb::Region& r) const {
+bool rfb::Region::operator==(const rfb::Region& r) const {
return pixman_region_equal(rgn, r.rgn);
}
+bool rfb::Region::operator!=(const rfb::Region& r) const {
+ return !pixman_region_equal(rgn, r.rgn);
+}
+
int rfb::Region::numRects() const {
return pixman_region_n_rects(rgn);
}
diff --git a/common/rfb/Region.h b/common/rfb/Region.h
index 6ac3a75b..38de67ce 100644
--- a/common/rfb/Region.h
+++ b/common/rfb/Region.h
@@ -53,11 +53,15 @@ namespace rfb {
// the following three operations return a new region:
- Region intersect(const Region& r) const;
- Region union_(const Region& r) const;
- Region subtract(const Region& r) const;
-
- bool equals(const Region& b) const;
+ Region intersect(const Region& r) const
+ __attribute__ ((warn_unused_result));
+ Region union_(const Region& r) const
+ __attribute__ ((warn_unused_result));
+ Region subtract(const Region& r) const
+ __attribute__ ((warn_unused_result));
+
+ bool operator==(const Region& b) const;
+ bool operator!=(const Region& b) const;
int numRects() const;
bool is_empty() const { return numRects() == 0; }
diff --git a/common/rfb/SConnection.cxx b/common/rfb/SConnection.cxx
index 0bb8e4a9..e5d40e9d 100644
--- a/common/rfb/SConnection.cxx
+++ b/common/rfb/SConnection.cxx
@@ -35,6 +35,7 @@
#include <rfb/encodings.h>
#include <rfb/EncodeManager.h>
#include <rfb/SSecurity.h>
+#include <rfb/util.h>
#include <rfb/LogWriter.h>
@@ -59,7 +60,8 @@ SConnection::SConnection()
is(0), os(0), reader_(0), writer_(0), ssecurity(0),
authFailureTimer(this, &SConnection::handleAuthFailureTimeout),
state_(RFBSTATE_UNINITIALISED), preferredEncoding(encodingRaw),
- accessRights(0x0000), clientClipboard(NULL), hasLocalClipboard(false),
+ accessRights(0x0000), hasRemoteClipboard(false),
+ hasLocalClipboard(false),
unsolicitedClipboardAttempt(false)
{
defaultMajorVersion = 3;
@@ -160,8 +162,8 @@ bool SConnection::processVersionMsg()
versionReceived();
- std::list<rdr::U8> secTypes;
- std::list<rdr::U8>::iterator i;
+ std::list<uint8_t> secTypes;
+ std::list<uint8_t>::iterator i;
secTypes = security.GetEnabledSecTypes();
if (client.isVersion(3,3)) {
@@ -215,8 +217,8 @@ bool SConnection::processSecurityTypeMsg()
void SConnection::processSecurityType(int secType)
{
// Verify that the requested security type should be offered
- std::list<rdr::U8> secTypes;
- std::list<rdr::U8>::iterator i;
+ std::list<uint8_t> secTypes;
+ std::list<uint8_t>::iterator i;
secTypes = security.GetEnabledSecTypes();
for (i=secTypes.begin(); i!=secTypes.end(); i++)
@@ -246,7 +248,7 @@ bool SConnection::processSecurityMsg()
state_ = RFBSTATE_SECURITY_FAILURE;
// Introduce a slight delay of the authentication failure response
// to make it difficult to brute force a password
- authFailureMsg.replaceBuf(strDup(e.str()));
+ authFailureMsg = e.str();
authFailureTimer.start(100);
return true;
}
@@ -295,9 +297,8 @@ bool SConnection::handleAuthFailureTimeout(Timer* /*t*/)
try {
os->writeU32(secResultFailed);
if (!client.beforeVersion(3,8)) { // 3.8 onwards have failure message
- const char* reason = authFailureMsg.buf;
- os->writeU32(strlen(reason));
- os->writeBytes(reason, strlen(reason));
+ os->writeU32(authFailureMsg.size());
+ os->writeBytes(authFailureMsg.data(), authFailureMsg.size());
}
os->flush();
} catch (rdr::Exception& e) {
@@ -305,7 +306,7 @@ bool SConnection::handleAuthFailureTimeout(Timer* /*t*/)
return false;
}
- close(authFailureMsg.buf);
+ close(authFailureMsg.c_str());
return false;
}
@@ -352,7 +353,7 @@ bool SConnection::accessCheck(AccessRights ar) const
return (accessRights & ar) == ar;
}
-void SConnection::setEncodings(int nEncodings, const rdr::S32* encodings)
+void SConnection::setEncodings(int nEncodings, const int32_t* encodings)
{
int i;
@@ -367,7 +368,7 @@ void SConnection::setEncodings(int nEncodings, const rdr::S32* encodings)
SMsgHandler::setEncodings(nEncodings, encodings);
if (client.supportsEncoding(pseudoEncodingExtendedClipboard)) {
- rdr::U32 sizes[] = { 0 };
+ uint32_t sizes[] = { 0 };
writer()->writeClipboardCaps(rfb::clipboardUTF8 |
rfb::clipboardRequest |
rfb::clipboardPeek |
@@ -381,15 +382,13 @@ void SConnection::clientCutText(const char* str)
{
hasLocalClipboard = false;
- strFree(clientClipboard);
- clientClipboard = NULL;
-
clientClipboard = latin1ToUTF8(str);
+ hasRemoteClipboard = true;
handleClipboardAnnounce(true);
}
-void SConnection::handleClipboardRequest(rdr::U32 flags)
+void SConnection::handleClipboardRequest(uint32_t flags)
{
if (!(flags & rfb::clipboardUTF8)) {
vlog.debug("Ignoring clipboard request for unsupported formats 0x%x", flags);
@@ -408,10 +407,9 @@ void SConnection::handleClipboardPeek()
writer()->writeClipboardNotify(hasLocalClipboard ? rfb::clipboardUTF8 : 0);
}
-void SConnection::handleClipboardNotify(rdr::U32 flags)
+void SConnection::handleClipboardNotify(uint32_t flags)
{
- strFree(clientClipboard);
- clientClipboard = NULL;
+ hasRemoteClipboard = false;
if (flags & rfb::clipboardUTF8) {
hasLocalClipboard = false;
@@ -421,22 +419,20 @@ void SConnection::handleClipboardNotify(rdr::U32 flags)
}
}
-void SConnection::handleClipboardProvide(rdr::U32 flags,
+void SConnection::handleClipboardProvide(uint32_t flags,
const size_t* lengths,
- const rdr::U8* const* data)
+ const uint8_t* const* data)
{
if (!(flags & rfb::clipboardUTF8)) {
vlog.debug("Ignoring clipboard provide with unsupported formats 0x%x", flags);
return;
}
- strFree(clientClipboard);
- clientClipboard = NULL;
-
clientClipboard = convertLF((const char*)data[0], lengths[0]);
+ hasRemoteClipboard = true;
// FIXME: Should probably verify that this data was actually requested
- handleClipboardData(clientClipboard);
+ handleClipboardData(clientClipboard.c_str());
}
void SConnection::supportsQEMUKeyEvent()
@@ -523,7 +519,7 @@ void SConnection::framebufferUpdateRequest(const Rect& /*r*/,
}
}
-void SConnection::fence(rdr::U32 flags, unsigned len, const char data[])
+void SConnection::fence(uint32_t flags, unsigned len, const char data[])
{
if (!(flags & fenceFlagRequest))
return;
@@ -554,8 +550,8 @@ void SConnection::handleClipboardData(const char* /*data*/)
void SConnection::requestClipboard()
{
- if (clientClipboard != NULL) {
- handleClipboardData(clientClipboard);
+ if (hasRemoteClipboard) {
+ handleClipboardData(clientClipboard.c_str());
return;
}
@@ -594,9 +590,9 @@ void SConnection::sendClipboardData(const char* data)
{
if (client.supportsEncoding(pseudoEncodingExtendedClipboard) &&
(client.clipboardFlags() & rfb::clipboardProvide)) {
- CharArray filtered(convertCRLF(data));
- size_t sizes[1] = { strlen(filtered.buf) + 1 };
- const rdr::U8* data[1] = { (const rdr::U8*)filtered.buf };
+ std::string filtered(convertCRLF(data));
+ size_t sizes[1] = { filtered.size() + 1 };
+ const uint8_t* data[1] = { (const uint8_t*)filtered.c_str() };
if (unsolicitedClipboardAttempt) {
unsolicitedClipboardAttempt = false;
@@ -610,9 +606,9 @@ void SConnection::sendClipboardData(const char* data)
writer()->writeClipboardProvide(rfb::clipboardUTF8, sizes, data);
} else {
- CharArray latin1(utf8ToLatin1(data));
+ std::string latin1(utf8ToLatin1(data));
- writer()->writeServerCutText(latin1.buf);
+ writer()->writeServerCutText(latin1.c_str());
}
}
@@ -624,14 +620,12 @@ void SConnection::cleanup()
reader_ = NULL;
delete writer_;
writer_ = NULL;
- strFree(clientClipboard);
- clientClipboard = NULL;
}
void SConnection::writeFakeColourMap(void)
{
int i;
- rdr::U16 red[256], green[256], blue[256];
+ uint16_t red[256], green[256], blue[256];
for (i = 0;i < 256;i++)
client.pf().rgbFromPixel(i, &red[i], &green[i], &blue[i]);
diff --git a/common/rfb/SConnection.h b/common/rfb/SConnection.h
index b7e30c6a..08574069 100644
--- a/common/rfb/SConnection.h
+++ b/common/rfb/SConnection.h
@@ -24,6 +24,8 @@
#ifndef __RFB_SCONNECTION_H__
#define __RFB_SCONNECTION_H__
+#include <string>
+
#include <rdr/InStream.h>
#include <rdr/OutStream.h>
@@ -80,16 +82,16 @@ namespace rfb {
// Overridden from SMsgHandler
- virtual void setEncodings(int nEncodings, const rdr::S32* encodings);
+ virtual void setEncodings(int nEncodings, const int32_t* encodings);
virtual void clientCutText(const char* str);
- virtual void handleClipboardRequest(rdr::U32 flags);
+ virtual void handleClipboardRequest(uint32_t flags);
virtual void handleClipboardPeek();
- virtual void handleClipboardNotify(rdr::U32 flags);
- virtual void handleClipboardProvide(rdr::U32 flags,
+ virtual void handleClipboardNotify(uint32_t flags);
+ virtual void handleClipboardProvide(uint32_t flags,
const size_t* lengths,
- const rdr::U8* const* data);
+ const uint8_t* const* data);
virtual void supportsQEMUKeyEvent();
@@ -130,7 +132,7 @@ namespace rfb {
// it responds directly to requests (stating it doesn't support any
// synchronisation) and drops responses. Override to implement more proper
// support.
- virtual void fence(rdr::U32 flags, unsigned len, const char data[]);
+ virtual void fence(uint32_t flags, unsigned len, const char data[]);
// enableContinuousUpdates() is called when the client wants to enable
// or disable continuous updates, or change the active area.
@@ -177,7 +179,7 @@ namespace rfb {
// of a SConnection to the server. How the access rights are treated
// is up to the derived class.
- typedef rdr::U16 AccessRights;
+ typedef uint16_t AccessRights;
static const AccessRights AccessView; // View display contents
static const AccessRights AccessKeyEvents; // Send key events
static const AccessRights AccessPtrEvents; // Send pointer events
@@ -216,7 +218,7 @@ namespace rfb {
stateEnum state() { return state_; }
- rdr::S32 getPreferredEncoding() { return preferredEncoding; }
+ int32_t getPreferredEncoding() { return preferredEncoding; }
protected:
// throwConnFailedException() prints a message to the log, sends a conn
@@ -257,13 +259,14 @@ namespace rfb {
SSecurity* ssecurity;
MethodTimer<SConnection> authFailureTimer;
- CharArray authFailureMsg;
+ std::string authFailureMsg;
stateEnum state_;
- rdr::S32 preferredEncoding;
+ int32_t preferredEncoding;
AccessRights accessRights;
- char* clientClipboard;
+ std::string clientClipboard;
+ bool hasRemoteClipboard;
bool hasLocalClipboard;
bool unsolicitedClipboardAttempt;
};
diff --git a/common/rfb/SDesktop.h b/common/rfb/SDesktop.h
index 6d2a5dd8..9db08116 100644
--- a/common/rfb/SDesktop.h
+++ b/common/rfb/SDesktop.h
@@ -41,16 +41,12 @@
#include <rfb/PixelBuffer.h>
#include <rfb/VNCServer.h>
#include <rfb/InputHandler.h>
-#include <rfb/Exception.h>
#include <rfb/screenTypes.h>
-#include <rfb/util.h>
namespace network { class Socket; }
namespace rfb {
- class VNCServer;
-
class SDesktop : public InputHandler {
public:
// start() is called by the server when the first client authenticates
@@ -125,13 +121,13 @@ namespace rfb {
public:
SStaticDesktop(const Point& size) : server(0), buffer(0) {
PixelFormat pf;
- const rdr::U8 black[4] = { 0, 0, 0, 0 };
+ const uint8_t black[4] = { 0, 0, 0, 0 };
buffer = new ManagedPixelBuffer(pf, size.x, size.y);
if (buffer)
buffer->fillRect(buffer->getRect(), black);
}
SStaticDesktop(const Point& size, const PixelFormat& pf) : buffer(0) {
- const rdr::U8 black[4] = { 0, 0, 0, 0 };
+ const uint8_t black[4] = { 0, 0, 0, 0 };
buffer = new ManagedPixelBuffer(pf, size.x, size.y);
if (buffer)
buffer->fillRect(buffer->getRect(), black);
diff --git a/common/rfb/SMsgHandler.cxx b/common/rfb/SMsgHandler.cxx
index 4f008039..4ecfc2b2 100644
--- a/common/rfb/SMsgHandler.cxx
+++ b/common/rfb/SMsgHandler.cxx
@@ -27,6 +27,7 @@
#include <rfb/ScreenSet.h>
#include <rfb/clipboardTypes.h>
#include <rfb/encodings.h>
+#include <rfb/util.h>
using namespace rfb;
@@ -49,7 +50,7 @@ void SMsgHandler::setPixelFormat(const PixelFormat& pf)
client.setPF(pf);
}
-void SMsgHandler::setEncodings(int nEncodings, const rdr::S32* encodings)
+void SMsgHandler::setEncodings(int nEncodings, const int32_t* encodings)
{
bool firstFence, firstContinuousUpdates, firstLEDState,
firstQEMUKeyEvent;
@@ -73,7 +74,7 @@ void SMsgHandler::setEncodings(int nEncodings, const rdr::S32* encodings)
supportsQEMUKeyEvent();
}
-void SMsgHandler::handleClipboardCaps(rdr::U32 flags, const rdr::U32* lengths)
+void SMsgHandler::handleClipboardCaps(uint32_t flags, const uint32_t* lengths)
{
int i;
@@ -106,11 +107,8 @@ void SMsgHandler::handleClipboardCaps(rdr::U32 flags, const rdr::U32* lengths)
if (lengths[i] == 0)
vlog.debug(" %s (only notify)", type);
else {
- char bytes[1024];
-
- iecPrefix(lengths[i], "B", bytes, sizeof(bytes));
vlog.debug(" %s (automatically send up to %s)",
- type, bytes);
+ type, iecPrefix(lengths[i], "B").c_str());
}
}
}
@@ -118,7 +116,7 @@ void SMsgHandler::handleClipboardCaps(rdr::U32 flags, const rdr::U32* lengths)
client.setClipboardCaps(flags, lengths);
}
-void SMsgHandler::handleClipboardRequest(rdr::U32 /*flags*/)
+void SMsgHandler::handleClipboardRequest(uint32_t /*flags*/)
{
}
@@ -126,13 +124,13 @@ void SMsgHandler::handleClipboardPeek()
{
}
-void SMsgHandler::handleClipboardNotify(rdr::U32 /*flags*/)
+void SMsgHandler::handleClipboardNotify(uint32_t /*flags*/)
{
}
-void SMsgHandler::handleClipboardProvide(rdr::U32 /*flags*/,
+void SMsgHandler::handleClipboardProvide(uint32_t /*flags*/,
const size_t* /*lengths*/,
- const rdr::U8* const* /*data*/)
+ const uint8_t* const* /*data*/)
{
}
diff --git a/common/rfb/SMsgHandler.h b/common/rfb/SMsgHandler.h
index 274a1c3c..ec8040d2 100644
--- a/common/rfb/SMsgHandler.h
+++ b/common/rfb/SMsgHandler.h
@@ -23,7 +23,8 @@
#ifndef __RFB_SMSGHANDLER_H__
#define __RFB_SMSGHANDLER_H__
-#include <rdr/types.h>
+#include <stdint.h>
+
#include <rfb/PixelFormat.h>
#include <rfb/ClientParams.h>
#include <rfb/InputHandler.h>
@@ -46,22 +47,22 @@ namespace rfb {
virtual void clientInit(bool shared);
virtual void setPixelFormat(const PixelFormat& pf);
- virtual void setEncodings(int nEncodings, const rdr::S32* encodings);
+ virtual void setEncodings(int nEncodings, const int32_t* encodings);
virtual void framebufferUpdateRequest(const Rect& r, bool incremental) = 0;
virtual void setDesktopSize(int fb_width, int fb_height,
const ScreenSet& layout) = 0;
- virtual void fence(rdr::U32 flags, unsigned len, const char data[]) = 0;
+ virtual void fence(uint32_t flags, unsigned len, const char data[]) = 0;
virtual void enableContinuousUpdates(bool enable,
int x, int y, int w, int h) = 0;
- virtual void handleClipboardCaps(rdr::U32 flags,
- const rdr::U32* lengths);
- virtual void handleClipboardRequest(rdr::U32 flags);
+ virtual void handleClipboardCaps(uint32_t flags,
+ const uint32_t* lengths);
+ virtual void handleClipboardRequest(uint32_t flags);
virtual void handleClipboardPeek();
- virtual void handleClipboardNotify(rdr::U32 flags);
- virtual void handleClipboardProvide(rdr::U32 flags,
+ virtual void handleClipboardNotify(uint32_t flags);
+ virtual void handleClipboardProvide(uint32_t flags,
const size_t* lengths,
- const rdr::U8* const* data);
+ const uint8_t* const* data);
// InputHandler interface
// The InputHandler methods will be called for the corresponding messages.
diff --git a/common/rfb/SMsgReader.cxx b/common/rfb/SMsgReader.cxx
index e7c78c4e..8cd8d147 100644
--- a/common/rfb/SMsgReader.cxx
+++ b/common/rfb/SMsgReader.cxx
@@ -23,6 +23,8 @@
#include <stdio.h>
+#include <vector>
+
#include <rdr/InStream.h>
#include <rdr/ZlibInStream.h>
@@ -30,11 +32,11 @@
#include <rfb/qemuTypes.h>
#include <rfb/clipboardTypes.h>
#include <rfb/Exception.h>
-#include <rfb/util.h>
#include <rfb/SMsgHandler.h>
#include <rfb/SMsgReader.h>
#include <rfb/Configuration.h>
#include <rfb/LogWriter.h>
+#include <rfb/util.h>
using namespace rfb;
@@ -140,11 +142,11 @@ bool SMsgReader::readSetEncodings()
return false;
is->clearRestorePoint();
- rdr::S32Array encodings(nEncodings);
- for (int i = 0; i < nEncodings; i++)
- encodings.buf[i] = is->readU32();
+ std::vector<int32_t> encodings(nEncodings);
+ for (size_t i = 0; i < encodings.size(); i++)
+ encodings[i] = is->readU32();
- handler->setEncodings(nEncodings, encodings.buf);
+ handler->setEncodings(nEncodings, encodings.data());
return true;
}
@@ -153,7 +155,7 @@ bool SMsgReader::readSetDesktopSize()
{
int width, height;
int screens, i;
- rdr::U32 id, flags;
+ uint32_t id, flags;
int sx, sy, sw, sh;
ScreenSet layout;
@@ -225,8 +227,8 @@ bool SMsgReader::readEnableContinuousUpdates()
bool SMsgReader::readFence()
{
- rdr::U32 flags;
- rdr::U8 len;
+ uint32_t flags;
+ uint8_t len;
char data[64];
if (!is->hasData(3 + 4 + 1))
@@ -263,7 +265,7 @@ bool SMsgReader::readKeyEvent()
return false;
bool down = is->readU8();
is->skip(2);
- rdr::U32 key = is->readU32();
+ uint32_t key = is->readU32();
handler->keyEvent(key, 0, down);
return true;
}
@@ -288,10 +290,10 @@ bool SMsgReader::readClientCutText()
is->setRestorePoint();
is->skip(3);
- rdr::U32 len = is->readU32();
+ uint32_t len = is->readU32();
if (len & 0x80000000) {
- rdr::S32 slen = len;
+ int32_t slen = len;
slen = -slen;
if (readExtendedClipboard(slen)) {
is->clearRestorePoint();
@@ -312,18 +314,18 @@ bool SMsgReader::readClientCutText()
return true;
}
- CharArray ca(len);
- is->readBytes(ca.buf, len);
- CharArray filtered(convertLF(ca.buf, len));
- handler->clientCutText(filtered.buf);
+ std::vector<char> ca(len);
+ is->readBytes(ca.data(), len);
+ std::string filtered(convertLF(ca.data(), len));
+ handler->clientCutText(filtered.c_str());
return true;
}
-bool SMsgReader::readExtendedClipboard(rdr::S32 len)
+bool SMsgReader::readExtendedClipboard(int32_t len)
{
- rdr::U32 flags;
- rdr::U32 action;
+ uint32_t flags;
+ uint32_t action;
if (!is->hasData(len))
return false;
@@ -342,7 +344,7 @@ bool SMsgReader::readExtendedClipboard(rdr::S32 len)
if (action & clipboardCaps) {
int i;
size_t num;
- rdr::U32 lengths[16];
+ uint32_t lengths[16];
num = 0;
for (i = 0;i < 16;i++) {
@@ -350,7 +352,7 @@ bool SMsgReader::readExtendedClipboard(rdr::S32 len)
num++;
}
- if (len < (rdr::S32)(4 + 4*num))
+ if (len < (int32_t)(4 + 4*num))
throw Exception("Invalid extended clipboard message");
num = 0;
@@ -366,7 +368,7 @@ bool SMsgReader::readExtendedClipboard(rdr::S32 len)
int i;
size_t num;
size_t lengths[16];
- rdr::U8* buffers[16];
+ uint8_t* buffers[16];
zis.setUnderlying(is, len - 4);
@@ -407,7 +409,7 @@ bool SMsgReader::readExtendedClipboard(rdr::S32 len)
if (!zis.hasData(lengths[num]))
throw Exception("Extended clipboard decode error");
- buffers[num] = new rdr::U8[lengths[num]];
+ buffers[num] = new uint8_t[lengths[num]];
zis.readBytes(buffers[num], lengths[num]);
num++;
}
@@ -476,8 +478,8 @@ bool SMsgReader::readQEMUKeyEvent()
if (!is->hasData(2 + 4 + 4))
return false;
bool down = is->readU16();
- rdr::U32 keysym = is->readU32();
- rdr::U32 keycode = is->readU32();
+ uint32_t keysym = is->readU32();
+ uint32_t keycode = is->readU32();
if (!keycode) {
vlog.error("Key event without keycode - ignoring");
return true;
diff --git a/common/rfb/SMsgReader.h b/common/rfb/SMsgReader.h
index acc872ed..f99b6627 100644
--- a/common/rfb/SMsgReader.h
+++ b/common/rfb/SMsgReader.h
@@ -54,7 +54,7 @@ namespace rfb {
bool readKeyEvent();
bool readPointerEvent();
bool readClientCutText();
- bool readExtendedClipboard(rdr::S32 len);
+ bool readExtendedClipboard(int32_t len);
bool readQEMUMessage();
bool readQEMUKeyEvent();
@@ -70,7 +70,7 @@ namespace rfb {
stateEnum state;
- rdr::U8 currentMsgType;
+ uint8_t currentMsgType;
};
}
#endif
diff --git a/common/rfb/SMsgWriter.cxx b/common/rfb/SMsgWriter.cxx
index c8b50b67..1172ac4d 100644
--- a/common/rfb/SMsgWriter.cxx
+++ b/common/rfb/SMsgWriter.cxx
@@ -56,7 +56,7 @@ SMsgWriter::~SMsgWriter()
{
}
-void SMsgWriter::writeServerInit(rdr::U16 width, rdr::U16 height,
+void SMsgWriter::writeServerInit(uint16_t width, uint16_t height,
const PixelFormat& pf, const char* name)
{
os->writeU16(width);
@@ -68,9 +68,9 @@ void SMsgWriter::writeServerInit(rdr::U16 width, rdr::U16 height,
}
void SMsgWriter::writeSetColourMapEntries(int firstColour, int nColours,
- const rdr::U16 red[],
- const rdr::U16 green[],
- const rdr::U16 blue[])
+ const uint16_t red[],
+ const uint16_t green[],
+ const uint16_t blue[])
{
startMsg(msgTypeSetColourMapEntries);
os->pad(1);
@@ -105,8 +105,8 @@ void SMsgWriter::writeServerCutText(const char* str)
endMsg();
}
-void SMsgWriter::writeClipboardCaps(rdr::U32 caps,
- const rdr::U32* lengths)
+void SMsgWriter::writeClipboardCaps(uint32_t caps,
+ const uint32_t* lengths)
{
size_t i, count;
@@ -134,7 +134,7 @@ void SMsgWriter::writeClipboardCaps(rdr::U32 caps,
endMsg();
}
-void SMsgWriter::writeClipboardRequest(rdr::U32 flags)
+void SMsgWriter::writeClipboardRequest(uint32_t flags)
{
if (!client->supportsEncoding(pseudoEncodingExtendedClipboard))
throw Exception("Client does not support extended clipboard");
@@ -148,7 +148,7 @@ void SMsgWriter::writeClipboardRequest(rdr::U32 flags)
endMsg();
}
-void SMsgWriter::writeClipboardPeek(rdr::U32 flags)
+void SMsgWriter::writeClipboardPeek(uint32_t flags)
{
if (!client->supportsEncoding(pseudoEncodingExtendedClipboard))
throw Exception("Client does not support extended clipboard");
@@ -162,7 +162,7 @@ void SMsgWriter::writeClipboardPeek(rdr::U32 flags)
endMsg();
}
-void SMsgWriter::writeClipboardNotify(rdr::U32 flags)
+void SMsgWriter::writeClipboardNotify(uint32_t flags)
{
if (!client->supportsEncoding(pseudoEncodingExtendedClipboard))
throw Exception("Client does not support extended clipboard");
@@ -176,9 +176,9 @@ void SMsgWriter::writeClipboardNotify(rdr::U32 flags)
endMsg();
}
-void SMsgWriter::writeClipboardProvide(rdr::U32 flags,
+void SMsgWriter::writeClipboardProvide(uint32_t flags,
const size_t* lengths,
- const rdr::U8* const* data)
+ const uint8_t* const* data)
{
rdr::MemOutStream mos;
rdr::ZlibOutStream zos;
@@ -211,7 +211,7 @@ void SMsgWriter::writeClipboardProvide(rdr::U32 flags,
endMsg();
}
-void SMsgWriter::writeFence(rdr::U32 flags, unsigned len, const char data[])
+void SMsgWriter::writeFence(uint32_t flags, unsigned len, const char data[])
{
if (!client->supportsEncoding(pseudoEncodingFence))
throw Exception("Client does not support fences");
@@ -242,7 +242,7 @@ void SMsgWriter::writeEndOfContinuousUpdates()
endMsg();
}
-void SMsgWriter::writeDesktopSize(rdr::U16 reason, rdr::U16 result)
+void SMsgWriter::writeDesktopSize(uint16_t reason, uint16_t result)
{
ExtendedDesktopSizeMsg msg;
@@ -442,14 +442,16 @@ void SMsgWriter::writePseudoRects()
cursor.hotspot().x, cursor.hotspot().y,
cursor.getBuffer());
} else if (client->supportsEncoding(pseudoEncodingCursor)) {
- rdr::U8Array data(cursor.width()*cursor.height() * (client->pf().bpp/8));
- rdr::U8Array mask(cursor.getMask());
+ size_t data_len = cursor.width()*cursor.height() *
+ (client->pf().bpp/8);
+ std::vector<uint8_t> data(data_len);
+ std::vector<uint8_t> mask(cursor.getMask());
- const rdr::U8* in;
- rdr::U8* out;
+ const uint8_t* in;
+ uint8_t* out;
in = cursor.getBuffer();
- out = data.buf;
+ out = data.data();
for (int i = 0;i < cursor.width()*cursor.height();i++) {
client->pf().bufferFromRGB(out, in, 1);
in += 4;
@@ -458,14 +460,14 @@ void SMsgWriter::writePseudoRects()
writeSetCursorRect(cursor.width(), cursor.height(),
cursor.hotspot().x, cursor.hotspot().y,
- data.buf, mask.buf);
+ data.data(), mask.data());
} else if (client->supportsEncoding(pseudoEncodingXCursor)) {
- rdr::U8Array bitmap(cursor.getBitmap());
- rdr::U8Array mask(cursor.getMask());
+ std::vector<uint8_t> bitmap(cursor.getBitmap());
+ std::vector<uint8_t> mask(cursor.getMask());
writeSetXCursorRect(cursor.width(), cursor.height(),
cursor.hotspot().x, cursor.hotspot().y,
- bitmap.buf, mask.buf);
+ bitmap.data(), mask.data());
} else {
throw Exception("Client does not support local cursor");
}
@@ -538,8 +540,8 @@ void SMsgWriter::writeSetDesktopSizeRect(int width, int height)
os->writeU32(pseudoEncodingDesktopSize);
}
-void SMsgWriter::writeExtendedDesktopSizeRect(rdr::U16 reason,
- rdr::U16 result,
+void SMsgWriter::writeExtendedDesktopSizeRect(uint16_t reason,
+ uint16_t result,
int fb_width,
int fb_height,
const ScreenSet& layout)
@@ -632,7 +634,7 @@ void SMsgWriter::writeSetXCursorRect(int width, int height,
void SMsgWriter::writeSetCursorWithAlphaRect(int width, int height,
int hotspotX, int hotspotY,
- const rdr::U8* data)
+ const uint8_t* data)
{
if (!client->supportsEncoding(pseudoEncodingCursorWithAlpha))
throw Exception("Client does not support local cursors");
@@ -660,7 +662,7 @@ void SMsgWriter::writeSetCursorWithAlphaRect(int width, int height,
void SMsgWriter::writeSetVMwareCursorRect(int width, int height,
int hotspotX, int hotspotY,
- const rdr::U8* data)
+ const uint8_t* data)
{
if (!client->supportsEncoding(pseudoEncodingVMwareCursor))
throw Exception("Client does not support local cursors");
@@ -694,7 +696,7 @@ void SMsgWriter::writeSetVMwareCursorPositionRect(int hotspotX, int hotspotY)
os->writeU32(pseudoEncodingVMwareCursorPosition);
}
-void SMsgWriter::writeLEDStateRect(rdr::U8 state)
+void SMsgWriter::writeLEDStateRect(uint8_t state)
{
if (!client->supportsEncoding(pseudoEncodingLEDState) &&
!client->supportsEncoding(pseudoEncodingVMwareLEDState))
diff --git a/common/rfb/SMsgWriter.h b/common/rfb/SMsgWriter.h
index 49381bad..07f7cf23 100644
--- a/common/rfb/SMsgWriter.h
+++ b/common/rfb/SMsgWriter.h
@@ -23,7 +23,8 @@
#ifndef __RFB_SMSGWRITER_H__
#define __RFB_SMSGWRITER_H__
-#include <rdr/types.h>
+#include <stdint.h>
+
#include <rfb/encodings.h>
#include <rfb/ScreenSet.h>
@@ -42,7 +43,7 @@ namespace rfb {
// writeServerInit() must only be called at the appropriate time in the
// protocol initialisation.
- void writeServerInit(rdr::U16 width, rdr::U16 height,
+ void writeServerInit(uint16_t width, uint16_t height,
const PixelFormat& pf, const char* name);
// Methods to write normal protocol messages
@@ -50,24 +51,24 @@ namespace rfb {
// writeSetColourMapEntries() writes a setColourMapEntries message, using
// the given colour entries.
void writeSetColourMapEntries(int firstColour, int nColours,
- const rdr::U16 red[],
- const rdr::U16 green[],
- const rdr::U16 blue[]);
+ const uint16_t red[],
+ const uint16_t green[],
+ const uint16_t blue[]);
// writeBell() does the obvious thing.
void writeBell();
void writeServerCutText(const char* str);
- void writeClipboardCaps(rdr::U32 caps, const rdr::U32* lengths);
- void writeClipboardRequest(rdr::U32 flags);
- void writeClipboardPeek(rdr::U32 flags);
- void writeClipboardNotify(rdr::U32 flags);
- void writeClipboardProvide(rdr::U32 flags, const size_t* lengths,
- const rdr::U8* const* data);
+ void writeClipboardCaps(uint32_t caps, const uint32_t* lengths);
+ void writeClipboardRequest(uint32_t flags);
+ void writeClipboardPeek(uint32_t flags);
+ void writeClipboardNotify(uint32_t flags);
+ void writeClipboardProvide(uint32_t flags, const size_t* lengths,
+ const uint8_t* const* data);
// writeFence() sends a new fence request or response to the client.
- void writeFence(rdr::U32 flags, unsigned len, const char data[]);
+ void writeFence(uint32_t flags, unsigned len, const char data[]);
// writeEndOfContinuousUpdates() indicates that we have left continuous
// updates mode.
@@ -75,7 +76,7 @@ namespace rfb {
// writeDesktopSize() won't actually write immediately, but will
// write the relevant pseudo-rectangle as part of the next update.
- void writeDesktopSize(rdr::U16 reason, rdr::U16 result=0);
+ void writeDesktopSize(uint16_t reason, uint16_t result=0);
void writeSetDesktopName();
@@ -128,7 +129,7 @@ namespace rfb {
void writeNoDataRects();
void writeSetDesktopSizeRect(int width, int height);
- void writeExtendedDesktopSizeRect(rdr::U16 reason, rdr::U16 result,
+ void writeExtendedDesktopSizeRect(uint16_t reason, uint16_t result,
int fb_width, int fb_height,
const ScreenSet& layout);
void writeSetDesktopNameRect(const char *name);
@@ -140,12 +141,12 @@ namespace rfb {
const void* data, const void* mask);
void writeSetCursorWithAlphaRect(int width, int height,
int hotspotX, int hotspotY,
- const rdr::U8* data);
+ const uint8_t* data);
void writeSetVMwareCursorRect(int width, int height,
int hotspotX, int hotspotY,
- const rdr::U8* data);
+ const uint8_t* data);
void writeSetVMwareCursorPositionRect(int hotspotX, int hotspotY);
- void writeLEDStateRect(rdr::U8 state);
+ void writeLEDStateRect(uint8_t state);
void writeQEMUKeyEventRect();
ClientParams* client;
@@ -161,7 +162,7 @@ namespace rfb {
bool needQEMUKeyEvent;
typedef struct {
- rdr::U16 reason, result;
+ uint16_t reason, result;
} ExtendedDesktopSizeMsg;
std::list<ExtendedDesktopSizeMsg> extendedDesktopSizeMsgs;
diff --git a/common/rfb/SSecurity.h b/common/rfb/SSecurity.h
index cef2027f..fbc3de6f 100644
--- a/common/rfb/SSecurity.h
+++ b/common/rfb/SSecurity.h
@@ -43,9 +43,8 @@
#ifndef __RFB_SSECURITY_H__
#define __RFB_SSECURITY_H__
-#include <rdr/types.h>
#include <rfb/SConnection.h>
-#include <rfb/util.h>
+
#include <list>
namespace rfb {
diff --git a/common/rfb/SSecurityPlain.cxx b/common/rfb/SSecurityPlain.cxx
index 6f65e87a..e65b6d3b 100644
--- a/common/rfb/SSecurityPlain.cxx
+++ b/common/rfb/SSecurityPlain.cxx
@@ -24,6 +24,7 @@
#include <rfb/SSecurityPlain.h>
#include <rfb/SConnection.h>
#include <rfb/Exception.h>
+#include <rfb/util.h>
#include <rdr/InStream.h>
#if !defined(WIN32) && !defined(__APPLE__)
#include <rfb/UnixPasswordValidator.h>
@@ -45,21 +46,15 @@ StringParameter PasswordValidator::plainUsers
bool PasswordValidator::validUser(const char* username)
{
- CharArray users(plainUsers.getValueStr()), user;
+ std::vector<std::string> users;
- while (users.buf) {
- strSplit(users.buf, ',', &user.buf, &users.buf);
-#ifdef WIN32
- if (0 == stricmp(user.buf, "*"))
- return true;
- if (0 == stricmp(user.buf, username))
- return true;
-#else
- if (!strcmp(user.buf, "*"))
- return true;
- if (!strcmp(user.buf, username))
- return true;
-#endif
+ users = split(plainUsers, ',');
+
+ for (size_t i = 0; i < users.size(); i++) {
+ if (users[i] == "*")
+ return true;
+ if (users[i] == username)
+ return true;
}
return false;
}
@@ -80,9 +75,7 @@ SSecurityPlain::SSecurityPlain(SConnection* sc) : SSecurity(sc)
bool SSecurityPlain::processMsg()
{
rdr::InStream* is = sc->getInStream();
- char* pw;
- char *uname;
- CharArray password;
+ char password[1024];
if (!valid)
throw AuthFailureException("No password validator configured");
@@ -92,11 +85,11 @@ bool SSecurityPlain::processMsg()
return false;
ulen = is->readU32();
- if (ulen > MaxSaneUsernameLength)
+ if (ulen >= sizeof(username))
throw AuthFailureException("Too long username");
plen = is->readU32();
- if (plen > MaxSanePasswordLength)
+ if (plen >= sizeof(password))
throw AuthFailureException("Too long password");
state = 1;
@@ -106,16 +99,12 @@ bool SSecurityPlain::processMsg()
if (!is->hasData(ulen + plen))
return false;
state = 2;
- pw = new char[plen + 1];
- uname = new char[ulen + 1];
- username.replaceBuf(uname);
- password.replaceBuf(pw);
- is->readBytes(uname, ulen);
- is->readBytes(pw, plen);
- pw[plen] = 0;
- uname[ulen] = 0;
+ is->readBytes(username, ulen);
+ is->readBytes(password, plen);
+ password[plen] = 0;
+ username[ulen] = 0;
plen = 0;
- if (!valid->validate(sc, uname, pw))
+ if (!valid->validate(sc, username, password))
throw AuthFailureException("invalid password or username");
}
diff --git a/common/rfb/SSecurityPlain.h b/common/rfb/SSecurityPlain.h
index 1a81adda..4ca72781 100644
--- a/common/rfb/SSecurityPlain.h
+++ b/common/rfb/SSecurityPlain.h
@@ -23,7 +23,6 @@
#include <rfb/SConnection.h>
#include <rfb/SSecurity.h>
#include <rfb/SSecurityVeNCrypt.h>
-#include <rfb/util.h>
#include <rfb/Configuration.h>
namespace rfb {
@@ -46,17 +45,14 @@ namespace rfb {
SSecurityPlain(SConnection* sc);
virtual bool processMsg();
virtual int getType() const { return secTypePlain; };
- virtual const char* getUserName() const { return username.buf; }
+ virtual const char* getUserName() const { return username; }
virtual ~SSecurityPlain() { }
private:
PasswordValidator* valid;
unsigned int ulen, plen, state;
- CharArray username;
-
- static const unsigned int MaxSaneUsernameLength = 1024;
- static const unsigned int MaxSanePasswordLength = 1024;
+ char username[1024];
};
}
diff --git a/common/rfb/SSecurityRSAAES.cxx b/common/rfb/SSecurityRSAAES.cxx
index 3211f12f..042e4838 100644
--- a/common/rfb/SSecurityRSAAES.cxx
+++ b/common/rfb/SSecurityRSAAES.cxx
@@ -28,6 +28,8 @@
#include <stdlib.h>
#include <assert.h>
+#include <vector>
+
#include <nettle/bignum.h>
#include <nettle/sha1.h>
#include <nettle/sha2.h>
@@ -68,7 +70,7 @@ BoolParameter SSecurityRSAAES::requireUsername
("RequireUsername", "Require username for the RSA-AES security types",
false, ConfServer);
-SSecurityRSAAES::SSecurityRSAAES(SConnection* sc, rdr::U32 _secType,
+SSecurityRSAAES::SSecurityRSAAES(SConnection* sc, uint32_t _secType,
int _keySize, bool _isAllEncrypted)
: SSecurity(sc), state(SendPublicKey),
keySize(_keySize), isAllEncrypted(_isAllEncrypted), secType(_secType),
@@ -107,7 +109,7 @@ void SSecurityRSAAES::cleanup()
delete raos;
}
-static inline ssize_t findSubstr(rdr::U8* data, size_t size, const char *pattern)
+static inline ssize_t findSubstr(uint8_t* data, size_t size, const char *pattern)
{
size_t patternLength = strlen(pattern);
for (size_t i = 0; i + patternLength < size; ++i) {
@@ -121,8 +123,8 @@ next:
return -1;
}
-static bool loadPEM(rdr::U8* data, size_t size, const char *begin,
- const char *end, rdr::U8** der, size_t *derSize)
+static bool loadPEM(uint8_t* data, size_t size, const char *begin,
+ const char *end, std::vector<uint8_t> *der)
{
ssize_t pos1 = findSubstr(data, size, begin);
if (pos1 == -1)
@@ -134,19 +136,23 @@ static bool loadPEM(rdr::U8* data, size_t size, const char *begin,
char *derBase64 = (char *)data + pos1;
if (!base64Size)
return false;
- *der = new rdr::U8[BASE64_DECODE_LENGTH(base64Size)];
+ der->resize(BASE64_DECODE_LENGTH(base64Size));
struct base64_decode_ctx ctx;
+ size_t derSize;
base64_decode_init(&ctx);
- if (!base64_decode_update(&ctx, derSize, *der, base64Size, derBase64))
+ if (!base64_decode_update(&ctx, &derSize, der->data(),
+ base64Size, derBase64))
return false;
if (!base64_decode_final(&ctx))
return false;
+ assert(derSize <= der->size());
+ der->resize(derSize);
return true;
}
void SSecurityRSAAES::loadPrivateKey()
{
- FILE* file = fopen(keyFile.getData(), "rb");
+ FILE* file = fopen(keyFile, "rb");
if (!file)
throw ConnFailedException("failed to open key file");
fseek(file, 0, SEEK_END);
@@ -156,31 +162,30 @@ void SSecurityRSAAES::loadPrivateKey()
throw ConnFailedException("size of key file is zero or too big");
}
fseek(file, 0, SEEK_SET);
- rdr::U8Array data(size);
- if (fread(data.buf, 1, size, file) != size) {
+ std::vector<uint8_t> data(size);
+ if (fread(data.data(), 1, data.size(), file) != size) {
fclose(file);
throw ConnFailedException("failed to read key");
}
fclose(file);
- rdr::U8Array der;
- size_t derSize;
- if (loadPEM(data.buf, size, "-----BEGIN RSA PRIVATE KEY-----\n",
- "-----END RSA PRIVATE KEY-----", &der.buf, &derSize)) {
- loadPKCS1Key(der.buf, derSize);
+ std::vector<uint8_t> der;
+ if (loadPEM(data.data(), data.size(),
+ "-----BEGIN RSA PRIVATE KEY-----\n",
+ "-----END RSA PRIVATE KEY-----", &der)) {
+ loadPKCS1Key(der.data(), der.size());
return;
}
- if (der.buf)
- delete[] der.takeBuf();
- if (loadPEM(data.buf, size, "-----BEGIN PRIVATE KEY-----\n",
- "-----END PRIVATE KEY-----", &der.buf, &derSize)) {
- loadPKCS8Key(der.buf, derSize);
+ if (loadPEM(data.data(), data.size(),
+ "-----BEGIN PRIVATE KEY-----\n",
+ "-----END PRIVATE KEY-----", &der)) {
+ loadPKCS8Key(der.data(), der.size());
return;
}
throw ConnFailedException("failed to import key");
}
-void SSecurityRSAAES::loadPKCS1Key(const rdr::U8* data, size_t size)
+void SSecurityRSAAES::loadPKCS1Key(const uint8_t* data, size_t size)
{
struct rsa_public_key pub;
rsa_private_key_init(&serverKey);
@@ -191,14 +196,14 @@ void SSecurityRSAAES::loadPKCS1Key(const rdr::U8* data, size_t size)
throw ConnFailedException("failed to import key");
}
serverKeyLength = serverKey.size * 8;
- serverKeyN = new rdr::U8[serverKey.size];
- serverKeyE = new rdr::U8[serverKey.size];
+ serverKeyN = new uint8_t[serverKey.size];
+ serverKeyE = new uint8_t[serverKey.size];
nettle_mpz_get_str_256(serverKey.size, serverKeyN, pub.n);
nettle_mpz_get_str_256(serverKey.size, serverKeyE, pub.e);
rsa_public_key_clear(&pub);
}
-void SSecurityRSAAES::loadPKCS8Key(const rdr::U8* data, size_t size)
+void SSecurityRSAAES::loadPKCS8Key(const uint8_t* data, size_t size)
{
struct asn1_der_iterator i, j;
uint32_t version;
@@ -296,8 +301,8 @@ bool SSecurityRSAAES::readPublicKey()
if (!is->hasDataOrRestore(size * 2))
return false;
is->clearRestorePoint();
- clientKeyE = new rdr::U8[size];
- clientKeyN = new rdr::U8[size];
+ clientKeyE = new uint8_t[size];
+ clientKeyN = new uint8_t[size];
is->readBytes(clientKeyN, size);
is->readBytes(clientKeyE, size);
rsa_public_key_init(&clientKey);
@@ -336,7 +341,7 @@ void SSecurityRSAAES::writeRandom()
mpz_clear(x);
throw ConnFailedException("failed to encrypt random");
}
- rdr::U8* buffer = new rdr::U8[clientKey.size];
+ uint8_t* buffer = new uint8_t[clientKey.size];
nettle_mpz_get_str_256(clientKey.size, buffer, x);
mpz_clear(x);
os->writeU16(clientKey.size);
@@ -357,7 +362,7 @@ bool SSecurityRSAAES::readRandom()
if (!is->hasDataOrRestore(size))
return false;
is->clearRestorePoint();
- rdr::U8* buffer = new rdr::U8[size];
+ uint8_t* buffer = new uint8_t[size];
is->readBytes(buffer, size);
size_t randomSize = keySize / 8;
mpz_t x;
@@ -376,7 +381,7 @@ void SSecurityRSAAES::setCipher()
{
rawis = sc->getInStream();
rawos = sc->getOutStream();
- rdr::U8 key[32];
+ uint8_t key[32];
if (keySize == 128) {
struct sha1_ctx ctx;
sha1_init(&ctx);
@@ -408,20 +413,20 @@ void SSecurityRSAAES::setCipher()
void SSecurityRSAAES::writeHash()
{
- rdr::U8 hash[32];
+ uint8_t hash[32];
size_t len = serverKeyLength;
- rdr::U8 lenServerKey[4] = {
- (rdr::U8)((len & 0xff000000) >> 24),
- (rdr::U8)((len & 0xff0000) >> 16),
- (rdr::U8)((len & 0xff00) >> 8),
- (rdr::U8)(len & 0xff)
+ uint8_t lenServerKey[4] = {
+ (uint8_t)((len & 0xff000000) >> 24),
+ (uint8_t)((len & 0xff0000) >> 16),
+ (uint8_t)((len & 0xff00) >> 8),
+ (uint8_t)(len & 0xff)
};
len = clientKeyLength;
- rdr::U8 lenClientKey[4] = {
- (rdr::U8)((len & 0xff000000) >> 24),
- (rdr::U8)((len & 0xff0000) >> 16),
- (rdr::U8)((len & 0xff00) >> 8),
- (rdr::U8)(len & 0xff)
+ uint8_t lenClientKey[4] = {
+ (uint8_t)((len & 0xff000000) >> 24),
+ (uint8_t)((len & 0xff0000) >> 16),
+ (uint8_t)((len & 0xff00) >> 8),
+ (uint8_t)(len & 0xff)
};
int hashSize;
if (keySize == 128) {
@@ -453,25 +458,25 @@ void SSecurityRSAAES::writeHash()
bool SSecurityRSAAES::readHash()
{
- rdr::U8 hash[32];
- rdr::U8 realHash[32];
+ uint8_t hash[32];
+ uint8_t realHash[32];
int hashSize = keySize == 128 ? 20 : 32;
if (!rais->hasData(hashSize))
return false;
rais->readBytes(hash, hashSize);
size_t len = serverKeyLength;
- rdr::U8 lenServerKey[4] = {
- (rdr::U8)((len & 0xff000000) >> 24),
- (rdr::U8)((len & 0xff0000) >> 16),
- (rdr::U8)((len & 0xff00) >> 8),
- (rdr::U8)(len & 0xff)
+ uint8_t lenServerKey[4] = {
+ (uint8_t)((len & 0xff000000) >> 24),
+ (uint8_t)((len & 0xff0000) >> 16),
+ (uint8_t)((len & 0xff00) >> 8),
+ (uint8_t)(len & 0xff)
};
len = clientKeyLength;
- rdr::U8 lenClientKey[4] = {
- (rdr::U8)((len & 0xff000000) >> 24),
- (rdr::U8)((len & 0xff0000) >> 16),
- (rdr::U8)((len & 0xff00) >> 8),
- (rdr::U8)(len & 0xff)
+ uint8_t lenClientKey[4] = {
+ (uint8_t)((len & 0xff000000) >> 24),
+ (uint8_t)((len & 0xff0000) >> 16),
+ (uint8_t)((len & 0xff00) >> 8),
+ (uint8_t)(len & 0xff)
};
if (keySize == 128) {
struct sha1_ctx ctx;
@@ -531,22 +536,16 @@ bool SSecurityRSAAES::readCredentials()
rais->setRestorePoint();
if (!rais->hasData(1))
return false;
- rdr::U8 lenUsername = rais->readU8();
+ uint8_t lenUsername = rais->readU8();
if (!rais->hasDataOrRestore(lenUsername + 1))
return false;
- if (!username.buf) {
- username.replaceBuf(new char[lenUsername + 1]);
- rais->readBytes(username.buf, lenUsername);
- username.buf[lenUsername] = 0;
- } else {
- rais->skip(lenUsername);
- }
- rdr::U8 lenPassword = rais->readU8();
+ rais->readBytes(username, lenUsername);
+ username[lenUsername] = 0;
+ uint8_t lenPassword = rais->readU8();
if (!rais->hasDataOrRestore(lenPassword))
return false;
- password.replaceBuf(new char[lenPassword + 1]);
- rais->readBytes(password.buf, lenPassword);
- password.buf[lenPassword] = 0;
+ rais->readBytes(password, lenPassword);
+ password[lenPassword] = 0;
rais->clearRestorePoint();
return true;
}
@@ -559,7 +558,7 @@ void SSecurityRSAAES::verifyUserPass()
#elif !defined(__APPLE__)
UnixPasswordValidator *valid = new UnixPasswordValidator();
#endif
- if (!valid->validate(sc, username.buf, password.buf)) {
+ if (!valid->validate(sc, username, password)) {
delete valid;
throw AuthFailureException("invalid password or username");
}
@@ -572,18 +571,18 @@ void SSecurityRSAAES::verifyUserPass()
void SSecurityRSAAES::verifyPass()
{
VncAuthPasswdGetter* pg = &SSecurityVncAuth::vncAuthPasswd;
- PlainPasswd passwd, passwdReadOnly;
+ std::string passwd, passwdReadOnly;
pg->getVncAuthPasswd(&passwd, &passwdReadOnly);
- if (!passwd.buf)
+ if (passwd.empty())
throw AuthFailureException("No password configured for VNC Auth");
- if (strcmp(password.buf, passwd.buf) == 0) {
+ if (password == passwd) {
accessRights = SConnection::AccessDefault;
return;
}
- if (passwdReadOnly.buf && strcmp(password.buf, passwdReadOnly.buf) == 0) {
+ if (!passwdReadOnly.empty() && password == passwdReadOnly) {
accessRights = SConnection::AccessView;
return;
}
@@ -593,5 +592,5 @@ void SSecurityRSAAES::verifyPass()
const char* SSecurityRSAAES::getUserName() const
{
- return username.buf;
+ return username;
}
diff --git a/common/rfb/SSecurityRSAAES.h b/common/rfb/SSecurityRSAAES.h
index 17e0d407..eaeb13a1 100644
--- a/common/rfb/SSecurityRSAAES.h
+++ b/common/rfb/SSecurityRSAAES.h
@@ -33,7 +33,7 @@ namespace rfb {
class SSecurityRSAAES : public SSecurity {
public:
- SSecurityRSAAES(SConnection* sc, rdr::U32 secType,
+ SSecurityRSAAES(SConnection* sc, uint32_t secType,
int keySize, bool isAllEncrypted);
virtual ~SSecurityRSAAES();
virtual bool processMsg();
@@ -50,8 +50,8 @@ namespace rfb {
private:
void cleanup();
void loadPrivateKey();
- void loadPKCS1Key(const rdr::U8* data, size_t size);
- void loadPKCS8Key(const rdr::U8* data, size_t size);
+ void loadPKCS1Key(const uint8_t* data, size_t size);
+ void loadPKCS8Key(const uint8_t* data, size_t size);
void writePublicKey();
bool readPublicKey();
void writeRandom();
@@ -68,20 +68,20 @@ namespace rfb {
int state;
int keySize;
bool isAllEncrypted;
- rdr::U32 secType;
+ uint32_t secType;
struct rsa_private_key serverKey;
struct rsa_public_key clientKey;
- rdr::U32 serverKeyLength;
- rdr::U8* serverKeyN;
- rdr::U8* serverKeyE;
- rdr::U32 clientKeyLength;
- rdr::U8* clientKeyN;
- rdr::U8* clientKeyE;
- rdr::U8 serverRandom[32];
- rdr::U8 clientRandom[32];
+ uint32_t serverKeyLength;
+ uint8_t* serverKeyN;
+ uint8_t* serverKeyE;
+ uint32_t clientKeyLength;
+ uint8_t* clientKeyN;
+ uint8_t* clientKeyE;
+ uint8_t serverRandom[32];
+ uint8_t clientRandom[32];
- CharArray username;
- CharArray password;
+ char username[256];
+ char password[256];
SConnection::AccessRights accessRights;
rdr::InStream* rais;
diff --git a/common/rfb/SSecurityTLS.cxx b/common/rfb/SSecurityTLS.cxx
index f3d58ae0..1abfd774 100644
--- a/common/rfb/SSecurityTLS.cxx
+++ b/common/rfb/SSecurityTLS.cxx
@@ -75,9 +75,6 @@ SSecurityTLS::SSecurityTLS(SConnection* sc, bool _anon)
dh_params = NULL;
#endif
- certfile = X509_CertFile.getData();
- keyfile = X509_KeyFile.getData();
-
if (gnutls_global_init() != GNUTLS_E_SUCCESS)
throw AuthFailureException("gnutls_global_init failed");
}
@@ -136,9 +133,6 @@ SSecurityTLS::~SSecurityTLS()
{
shutdown();
- delete[] keyfile;
- delete[] certfile;
-
gnutls_global_deinit();
}
@@ -293,7 +287,7 @@ void SSecurityTLS::setParams(gnutls_session_t session)
gnutls_certificate_set_dh_params(cert_cred, dh_params);
#endif
- switch (gnutls_certificate_set_x509_key_file(cert_cred, certfile, keyfile, GNUTLS_X509_FMT_PEM)) {
+ switch (gnutls_certificate_set_x509_key_file(cert_cred, X509_CertFile, X509_KeyFile, GNUTLS_X509_FMT_PEM)) {
case GNUTLS_E_SUCCESS:
break;
case GNUTLS_E_CERTIFICATE_KEY_MISMATCH:
diff --git a/common/rfb/SSecurityTLS.h b/common/rfb/SSecurityTLS.h
index 4e06d6ba..d0f735fe 100644
--- a/common/rfb/SSecurityTLS.h
+++ b/common/rfb/SSecurityTLS.h
@@ -63,7 +63,6 @@ namespace rfb {
#endif
gnutls_anon_server_credentials_t anon_cred;
gnutls_certificate_credentials_t cert_cred;
- char *keyfile, *certfile;
bool anon;
diff --git a/common/rfb/SSecurityVeNCrypt.cxx b/common/rfb/SSecurityVeNCrypt.cxx
index 70d50d20..c126d82f 100644
--- a/common/rfb/SSecurityVeNCrypt.cxx
+++ b/common/rfb/SSecurityVeNCrypt.cxx
@@ -64,7 +64,7 @@ bool SSecurityVeNCrypt::processMsg()
{
rdr::InStream* is = sc->getInStream();
rdr::OutStream* os = sc->getOutStream();
- rdr::U8 i;
+ uint8_t i;
/* VeNCrypt initialization */
@@ -93,7 +93,7 @@ bool SSecurityVeNCrypt::processMsg()
haveRecvdMinorVersion = true;
/* WORD value with major version in upper 8 bits and minor version in lower 8 bits */
- U16 Version = (((U16)majorVersion) << 8) | ((U16)minorVersion);
+ uint16_t Version = (((uint16_t)majorVersion) << 8) | ((uint16_t)minorVersion);
switch (Version) {
case 0x0000: /* 0.0 - The client cannot support us! */
@@ -115,16 +115,16 @@ bool SSecurityVeNCrypt::processMsg()
}
/*
- * send number of supported VeNCrypt authentication types (U8) followed
- * by authentication types (U32s)
+ * send number of supported VeNCrypt authentication types (uint8_t)
+ * followed by authentication types (uint32_t:s)
*/
if (!haveSentTypes) {
- list<U32> listSubTypes;
+ list<uint32_t> listSubTypes;
listSubTypes = security->GetEnabledExtSecTypes();
numTypes = listSubTypes.size();
- subTypes = new U32[numTypes];
+ subTypes = new uint32_t[numTypes];
for (i = 0; i < numTypes; i++) {
subTypes[i] = listSubTypes.front();
diff --git a/common/rfb/SSecurityVeNCrypt.h b/common/rfb/SSecurityVeNCrypt.h
index afbf7247..86cf420a 100644
--- a/common/rfb/SSecurityVeNCrypt.h
+++ b/common/rfb/SSecurityVeNCrypt.h
@@ -44,8 +44,8 @@ namespace rfb {
SecurityServer *security;
bool haveSentVersion, haveRecvdMajorVersion, haveRecvdMinorVersion;
bool haveSentTypes, haveChosenType;
- rdr::U8 majorVersion, minorVersion, numTypes;
- rdr::U32 *subTypes, chosenType;
+ uint8_t majorVersion, minorVersion, numTypes;
+ uint32_t *subTypes, chosenType;
};
}
#endif
diff --git a/common/rfb/SSecurityVncAuth.cxx b/common/rfb/SSecurityVncAuth.cxx
index a19404d3..cbd0ccd2 100644
--- a/common/rfb/SSecurityVncAuth.cxx
+++ b/common/rfb/SSecurityVncAuth.cxx
@@ -28,11 +28,11 @@
#include <rfb/SSecurityVncAuth.h>
#include <rdr/RandomStream.h>
#include <rfb/SConnection.h>
-#include <rfb/Password.h>
#include <rfb/Configuration.h>
#include <rfb/LogWriter.h>
-#include <rfb/util.h>
#include <rfb/Exception.h>
+#include <rfb/obfuscate.h>
+#include <assert.h>
#include <string.h>
#include <stdio.h>
extern "C" {
@@ -58,15 +58,15 @@ SSecurityVncAuth::SSecurityVncAuth(SConnection* sc)
{
}
-bool SSecurityVncAuth::verifyResponse(const PlainPasswd &password)
+bool SSecurityVncAuth::verifyResponse(const char* password)
{
- rdr::U8 expectedResponse[vncAuthChallengeSize];
+ uint8_t expectedResponse[vncAuthChallengeSize];
// Calculate the expected response
- rdr::U8 key[8];
- int pwdLen = strlen(password.buf);
+ uint8_t key[8];
+ int pwdLen = strlen(password);
for (int i=0; i<8; i++)
- key[i] = i<pwdLen ? password.buf[i] : 0;
+ key[i] = i<pwdLen ? password[i] : 0;
deskey(key, EN0);
for (int j = 0; j < vncAuthChallengeSize; j += 8)
des(challenge+j, expectedResponse+j);
@@ -96,18 +96,19 @@ bool SSecurityVncAuth::processMsg()
is->readBytes(response, vncAuthChallengeSize);
- PlainPasswd passwd, passwdReadOnly;
+ std::string passwd, passwdReadOnly;
pg->getVncAuthPasswd(&passwd, &passwdReadOnly);
- if (!passwd.buf)
+ if (passwd.empty())
throw AuthFailureException("No password configured for VNC Auth");
- if (verifyResponse(passwd)) {
+ if (verifyResponse(passwd.c_str())) {
accessRights = SConnection::AccessDefault;
return true;
}
- if (passwdReadOnly.buf && verifyResponse(passwdReadOnly)) {
+ if (!passwdReadOnly.empty() &&
+ verifyResponse(passwdReadOnly.c_str())) {
accessRights = SConnection::AccessView;
return true;
}
@@ -121,40 +122,41 @@ VncAuthPasswdParameter::VncAuthPasswdParameter(const char* name,
: BinaryParameter(name, desc, 0, 0, ConfServer), passwdFile(passwdFile_) {
}
-void VncAuthPasswdParameter::getVncAuthPasswd(PlainPasswd *password, PlainPasswd *readOnlyPassword) {
- ObfuscatedPasswd obfuscated, obfuscatedReadOnly;
- getData((void**)&obfuscated.buf, &obfuscated.length);
+void VncAuthPasswdParameter::getVncAuthPasswd(std::string *password, std::string *readOnlyPassword) {
+ std::vector<uint8_t> obfuscated, obfuscatedReadOnly;
+ obfuscated = getData();
- if (obfuscated.length == 0) {
+ if (obfuscated.size() == 0) {
if (passwdFile) {
- CharArray fname(passwdFile->getData());
- if (!fname.buf[0]) {
+ const char *fname = *passwdFile;
+ if (!fname[0]) {
vlog.info("neither %s nor %s params set", getName(), passwdFile->getName());
return;
}
- FILE* fp = fopen(fname.buf, "r");
+ FILE* fp = fopen(fname, "r");
if (!fp) {
- vlog.error("opening password file '%s' failed",fname.buf);
+ vlog.error("opening password file '%s' failed", fname);
return;
}
vlog.debug("reading password file");
- obfuscated.buf = new char[8];
- obfuscated.length = fread(obfuscated.buf, 1, 8, fp);
- obfuscatedReadOnly.buf = new char[8];
- obfuscatedReadOnly.length = fread(obfuscatedReadOnly.buf, 1, 8, fp);
+ obfuscated.resize(8);
+ obfuscated.resize(fread(obfuscated.data(), 1, 8, fp));
+ obfuscatedReadOnly.resize(8);
+ obfuscatedReadOnly.resize(fread(obfuscatedReadOnly.data(), 1, 8, fp));
fclose(fp);
} else {
vlog.info("%s parameter not set", getName());
}
}
+ assert(password != NULL);
+ assert(readOnlyPassword != NULL);
+
try {
- PlainPasswd plainPassword(obfuscated);
- password->replaceBuf(plainPassword.takeBuf());
- PlainPasswd plainPasswordReadOnly(obfuscatedReadOnly);
- readOnlyPassword->replaceBuf(plainPasswordReadOnly.takeBuf());
+ *password = deobfuscate(obfuscated.data(), obfuscated.size());
+ *readOnlyPassword = deobfuscate(obfuscatedReadOnly.data(), obfuscatedReadOnly.size());
} catch (...) {
}
}
diff --git a/common/rfb/SSecurityVncAuth.h b/common/rfb/SSecurityVncAuth.h
index 94d5aaf2..2bd27791 100644
--- a/common/rfb/SSecurityVncAuth.h
+++ b/common/rfb/SSecurityVncAuth.h
@@ -24,11 +24,11 @@
#ifndef __RFB_SSECURITYVNCAUTH_H__
#define __RFB_SSECURITYVNCAUTH_H__
+#include <stdint.h>
+
#include <rfb/Configuration.h>
-#include <rfb/Password.h>
#include <rfb/SSecurity.h>
#include <rfb/Security.h>
-#include <rdr/types.h>
namespace rfb {
@@ -36,7 +36,7 @@ namespace rfb {
public:
// getVncAuthPasswd() fills buffer of given password and readOnlyPassword.
// If there was no read only password in the file, readOnlyPassword buffer is null.
- virtual void getVncAuthPasswd(PlainPasswd *password, PlainPasswd *readOnlyPassword)=0;
+ virtual void getVncAuthPasswd(std::string *password, std::string *readOnlyPassword)=0;
virtual ~VncAuthPasswdGetter() { }
};
@@ -44,7 +44,7 @@ namespace rfb {
class VncAuthPasswdParameter : public VncAuthPasswdGetter, BinaryParameter {
public:
VncAuthPasswdParameter(const char* name, const char* desc, StringParameter* passwdFile_);
- virtual void getVncAuthPasswd(PlainPasswd *password, PlainPasswd *readOnlyPassword);
+ virtual void getVncAuthPasswd(std::string *password, std::string *readOnlyPassword);
protected:
StringParameter* passwdFile;
};
@@ -59,10 +59,10 @@ namespace rfb {
static StringParameter vncAuthPasswdFile;
static VncAuthPasswdParameter vncAuthPasswd;
private:
- bool verifyResponse(const PlainPasswd &password);
+ bool verifyResponse(const char* password);
enum {vncAuthChallengeSize = 16};
- rdr::U8 challenge[vncAuthChallengeSize];
- rdr::U8 response[vncAuthChallengeSize];
+ uint8_t challenge[vncAuthChallengeSize];
+ uint8_t response[vncAuthChallengeSize];
bool sentChallenge;
VncAuthPasswdGetter* pg;
SConnection::AccessRights accessRights;
diff --git a/common/rfb/ScreenSet.h b/common/rfb/ScreenSet.h
index 9680b6e7..fb93e5c2 100644
--- a/common/rfb/ScreenSet.h
+++ b/common/rfb/ScreenSet.h
@@ -23,8 +23,8 @@
#include <stdio.h>
#include <string.h>
+#include <stdint.h>
-#include <rdr/types.h>
#include <rfb/Rect.h>
#include <list>
#include <set>
@@ -38,22 +38,22 @@ namespace rfb {
struct Screen {
Screen(void) : id(0), flags(0) {};
- Screen(rdr::U32 id_, int x_, int y_, int w_, int h_, rdr::U32 flags_) :
+ Screen(uint32_t id_, int x_, int y_, int w_, int h_, uint32_t flags_) :
id(id_), dimensions(x_, y_, x_+w_, y_+h_), flags(flags_) {};
inline bool operator==(const Screen& r) const {
if (id != r.id)
return false;
- if (!dimensions.equals(r.dimensions))
+ if (dimensions != r.dimensions)
return false;
if (flags != r.flags)
return false;
return true;
}
- rdr::U32 id;
+ uint32_t id;
Rect dimensions;
- rdr::U32 flags;
+ uint32_t flags;
};
// rfb::ScreenSet
@@ -75,7 +75,7 @@ namespace rfb {
inline int num_screens(void) const { return screens.size(); };
inline void add_screen(const Screen screen) { screens.push_back(screen); };
- inline void remove_screen(rdr::U32 id) {
+ inline void remove_screen(uint32_t id) {
std::list<Screen>::iterator iter, nextiter;
for (iter = screens.begin();iter != screens.end();iter = nextiter) {
nextiter = iter; nextiter++;
@@ -86,7 +86,7 @@ namespace rfb {
inline bool validate(int fb_width, int fb_height) const {
std::list<Screen>::const_iterator iter;
- std::set<rdr::U32> seen_ids;
+ std::set<uint32_t> seen_ids;
Rect fb_rect;
if (screens.empty())
diff --git a/common/rfb/Security.cxx b/common/rfb/Security.cxx
index efed0cd0..caf6420f 100644
--- a/common/rfb/Security.cxx
+++ b/common/rfb/Security.cxx
@@ -61,18 +61,13 @@ Security::Security()
Security::Security(StringParameter &secTypes)
{
- char *secTypesStr;
-
- secTypesStr = secTypes.getData();
- enabledSecTypes = parseSecTypes(secTypesStr);
-
- delete [] secTypesStr;
+ enabledSecTypes = parseSecTypes(secTypes);
}
-const std::list<rdr::U8> Security::GetEnabledSecTypes(void)
+const std::list<uint8_t> Security::GetEnabledSecTypes(void)
{
- list<rdr::U8> result;
- list<U32>::iterator i;
+ list<uint8_t> result;
+ list<uint32_t>::iterator i;
/* Partial workaround for Vino's stupid behaviour. It doesn't allow
* the basic authentication types as part of the VeNCrypt handshake,
@@ -93,10 +88,10 @@ const std::list<rdr::U8> Security::GetEnabledSecTypes(void)
return result;
}
-const std::list<rdr::U32> Security::GetEnabledExtSecTypes(void)
+const std::list<uint32_t> Security::GetEnabledExtSecTypes(void)
{
- list<rdr::U32> result;
- list<U32>::iterator i;
+ list<uint32_t> result;
+ list<uint32_t>::iterator i;
for (i = enabledSecTypes.begin(); i != enabledSecTypes.end(); i++)
if (*i != secTypeVeNCrypt) /* Do not include VeNCrypt type to avoid loops */
@@ -105,9 +100,9 @@ const std::list<rdr::U32> Security::GetEnabledExtSecTypes(void)
return result;
}
-void Security::EnableSecType(U32 secType)
+void Security::EnableSecType(uint32_t secType)
{
- list<U32>::iterator i;
+ list<uint32_t>::iterator i;
for (i = enabledSecTypes.begin(); i != enabledSecTypes.end(); i++)
if (*i == secType)
@@ -116,9 +111,9 @@ void Security::EnableSecType(U32 secType)
enabledSecTypes.push_back(secType);
}
-bool Security::IsSupported(U32 secType)
+bool Security::IsSupported(uint32_t secType)
{
- list<U32>::iterator i;
+ list<uint32_t>::iterator i;
for (i = enabledSecTypes.begin(); i != enabledSecTypes.end(); i++)
if (*i == secType)
@@ -131,7 +126,7 @@ bool Security::IsSupported(U32 secType)
char *Security::ToString(void)
{
- list<U32>::iterator i;
+ list<uint32_t>::iterator i;
static char out[128]; /* Should be enough */
bool firstpass = true;
const char *name;
@@ -153,7 +148,7 @@ char *Security::ToString(void)
return out;
}
-rdr::U32 rfb::secTypeNum(const char* name)
+uint32_t rfb::secTypeNum(const char* name)
{
if (strcasecmp(name, "None") == 0) return secTypeNone;
if (strcasecmp(name, "VncAuth") == 0) return secTypeVncAuth;
@@ -180,7 +175,7 @@ rdr::U32 rfb::secTypeNum(const char* name)
return secTypeInvalid;
}
-const char* rfb::secTypeName(rdr::U32 num)
+const char* rfb::secTypeName(uint32_t num)
{
switch (num) {
case secTypeNone: return "None";
@@ -208,13 +203,13 @@ const char* rfb::secTypeName(rdr::U32 num)
}
}
-std::list<rdr::U32> rfb::parseSecTypes(const char* types_)
+std::list<uint32_t> rfb::parseSecTypes(const char* types_)
{
- std::list<rdr::U32> result;
- CharArray types(strDup(types_)), type;
- while (types.buf) {
- strSplit(types.buf, ',', &type.buf, &types.buf);
- rdr::U32 typeNum = secTypeNum(type.buf);
+ std::list<uint32_t> result;
+ std::vector<std::string> types;
+ types = split(types_, ',');
+ for (size_t i = 0; i < types.size(); i++) {
+ uint32_t typeNum = secTypeNum(types[i].c_str());
if (typeNum != secTypeInvalid)
result.push_back(typeNum);
}
diff --git a/common/rfb/Security.h b/common/rfb/Security.h
index 57800ffd..430a1d89 100644
--- a/common/rfb/Security.h
+++ b/common/rfb/Security.h
@@ -22,33 +22,34 @@
#ifndef __RFB_SECTYPES_H__
#define __RFB_SECTYPES_H__
-#include <rdr/types.h>
+#include <stdint.h>
+
#include <rfb/Configuration.h>
#include <list>
namespace rfb {
- const rdr::U8 secTypeInvalid = 0;
- const rdr::U8 secTypeNone = 1;
- const rdr::U8 secTypeVncAuth = 2;
+ const uint8_t secTypeInvalid = 0;
+ const uint8_t secTypeNone = 1;
+ const uint8_t secTypeVncAuth = 2;
- const rdr::U8 secTypeRA2 = 5;
- const rdr::U8 secTypeRA2ne = 6;
+ const uint8_t secTypeRA2 = 5;
+ const uint8_t secTypeRA2ne = 6;
- const rdr::U8 secTypeSSPI = 7;
- const rdr::U8 secTypeSSPIne = 8;
+ const uint8_t secTypeSSPI = 7;
+ const uint8_t secTypeSSPIne = 8;
- const rdr::U8 secTypeTight = 16;
- const rdr::U8 secTypeUltra = 17;
- const rdr::U8 secTypeTLS = 18;
- const rdr::U8 secTypeVeNCrypt = 19;
+ const uint8_t secTypeTight = 16;
+ const uint8_t secTypeUltra = 17;
+ const uint8_t secTypeTLS = 18;
+ const uint8_t secTypeVeNCrypt = 19;
- const rdr::U8 secTypeDH = 30;
+ const uint8_t secTypeDH = 30;
- const rdr::U8 secTypeMSLogonII = 113;
+ const uint8_t secTypeMSLogonII = 113;
- const rdr::U8 secTypeRA256 = 129;
- const rdr::U8 secTypeRAne256 = 130;
+ const uint8_t secTypeRA256 = 129;
+ const uint8_t secTypeRAne256 = 130;
/* VeNCrypt subtypes */
const int secTypePlain = 256;
@@ -65,9 +66,9 @@ namespace rfb {
// result types
- const rdr::U32 secResultOK = 0;
- const rdr::U32 secResultFailed = 1;
- const rdr::U32 secResultTooMany = 2; // deprecated
+ const uint32_t secResultOK = 0;
+ const uint32_t secResultFailed = 1;
+ const uint32_t secResultTooMany = 2; // deprecated
class Security {
public:
@@ -87,18 +88,18 @@ namespace rfb {
*/
/* Enable/Disable certain security type */
- void EnableSecType(rdr::U32 secType);
- void DisableSecType(rdr::U32 secType) { enabledSecTypes.remove(secType); }
+ void EnableSecType(uint32_t secType);
+ void DisableSecType(uint32_t secType) { enabledSecTypes.remove(secType); }
- void SetSecTypes(std::list<rdr::U32> &secTypes) { enabledSecTypes = secTypes; }
+ void SetSecTypes(std::list<uint32_t> &secTypes) { enabledSecTypes = secTypes; }
/* Check if certain type is supported */
- bool IsSupported(rdr::U32 secType);
+ bool IsSupported(uint32_t secType);
/* Get list of enabled security types without VeNCrypt subtypes */
- const std::list<rdr::U8> GetEnabledSecTypes(void);
+ const std::list<uint8_t> GetEnabledSecTypes(void);
/* Get list of enabled VeNCrypt subtypes */
- const std::list<rdr::U32> GetEnabledExtSecTypes(void);
+ const std::list<uint32_t> GetEnabledExtSecTypes(void);
/* Output char* is stored in static array */
char *ToString(void);
@@ -108,12 +109,12 @@ namespace rfb {
#endif
private:
- std::list<rdr::U32> enabledSecTypes;
+ std::list<uint32_t> enabledSecTypes;
};
- const char* secTypeName(rdr::U32 num);
- rdr::U32 secTypeNum(const char* name);
- std::list<rdr::U32> parseSecTypes(const char* types);
+ const char* secTypeName(uint32_t num);
+ uint32_t secTypeNum(const char* name);
+ std::list<uint32_t> parseSecTypes(const char* types);
}
#endif
diff --git a/common/rfb/SecurityClient.cxx b/common/rfb/SecurityClient.cxx
index 80165f57..1350640d 100644
--- a/common/rfb/SecurityClient.cxx
+++ b/common/rfb/SecurityClient.cxx
@@ -65,7 +65,7 @@ StringParameter SecurityClient::secTypes
"VncAuth,None",
ConfViewer);
-CSecurity* SecurityClient::GetCSecurity(CConnection* cc, U32 secType)
+CSecurity* SecurityClient::GetCSecurity(CConnection* cc, uint32_t secType)
{
assert (CSecurity::upg != NULL); /* (upg == NULL) means bug in the viewer */
#if defined(HAVE_GNUTLS) || defined(HAVE_NETTLE)
diff --git a/common/rfb/SecurityClient.h b/common/rfb/SecurityClient.h
index b13afa42..b86fcb35 100644
--- a/common/rfb/SecurityClient.h
+++ b/common/rfb/SecurityClient.h
@@ -33,7 +33,7 @@ namespace rfb {
SecurityClient(void) : Security(secTypes) {}
/* Create client side CSecurity class instance */
- CSecurity* GetCSecurity(CConnection* cc, rdr::U32 secType);
+ CSecurity* GetCSecurity(CConnection* cc, uint32_t secType);
static StringParameter secTypes;
};
diff --git a/common/rfb/SecurityServer.cxx b/common/rfb/SecurityServer.cxx
index 1d1150ad..3e23a89d 100644
--- a/common/rfb/SecurityServer.cxx
+++ b/common/rfb/SecurityServer.cxx
@@ -54,7 +54,7 @@ StringParameter SecurityServer::secTypes
"VncAuth",
ConfServer);
-SSecurity* SecurityServer::GetSSecurity(SConnection* sc, U32 secType)
+SSecurity* SecurityServer::GetSSecurity(SConnection* sc, uint32_t secType)
{
if (!IsSupported(secType))
goto bail;
diff --git a/common/rfb/SecurityServer.h b/common/rfb/SecurityServer.h
index 354f6420..a51ee23c 100644
--- a/common/rfb/SecurityServer.h
+++ b/common/rfb/SecurityServer.h
@@ -33,7 +33,7 @@ namespace rfb {
SecurityServer(void) : Security(secTypes) {}
/* Create server side SSecurity class instance */
- SSecurity* GetSSecurity(SConnection* sc, rdr::U32 secType);
+ SSecurity* GetSSecurity(SConnection* sc, uint32_t secType);
static StringParameter secTypes;
};
diff --git a/common/rfb/ServerCore.cxx b/common/rfb/ServerCore.cxx
index 274458fa..5bb6b9c9 100644
--- a/common/rfb/ServerCore.cxx
+++ b/common/rfb/ServerCore.cxx
@@ -26,7 +26,6 @@
#endif
#include <string.h>
-#include <rfb/util.h>
#include <rfb/ServerCore.h>
rfb::IntParameter rfb::Server::idleTimeout
diff --git a/common/rfb/ServerCore.h b/common/rfb/ServerCore.h
index 20a740a8..69cad39f 100644
--- a/common/rfb/ServerCore.h
+++ b/common/rfb/ServerCore.h
@@ -25,7 +25,6 @@
#define __RFB_SERVER_CORE_H__
#include <rfb/Configuration.h>
-#include <rfb/util.h>
namespace rfb {
diff --git a/common/rfb/ServerParams.cxx b/common/rfb/ServerParams.cxx
index 729b3cfb..6af446c2 100644
--- a/common/rfb/ServerParams.cxx
+++ b/common/rfb/ServerParams.cxx
@@ -33,7 +33,7 @@ ServerParams::ServerParams()
supportsQEMUKeyEvent(false),
supportsSetDesktopSize(false), supportsFence(false),
supportsContinuousUpdates(false),
- width_(0), height_(0), name_(0),
+ width_(0), height_(0),
ledState_(ledUnknown)
{
setName("");
@@ -46,7 +46,6 @@ ServerParams::ServerParams()
ServerParams::~ServerParams()
{
- delete [] name_;
delete cursor_;
}
@@ -77,8 +76,7 @@ void ServerParams::setPF(const PixelFormat& pf)
void ServerParams::setName(const char* name)
{
- delete [] name_;
- name_ = strDup(name);
+ name_ = name;
}
void ServerParams::setCursor(const Cursor& other)
@@ -92,7 +90,7 @@ void ServerParams::setLEDState(unsigned int state)
ledState_ = state;
}
-rdr::U32 ServerParams::clipboardSize(unsigned int format) const
+uint32_t ServerParams::clipboardSize(unsigned int format) const
{
int i;
@@ -104,7 +102,7 @@ rdr::U32 ServerParams::clipboardSize(unsigned int format) const
throw Exception("Invalid clipboard format 0x%x", format);
}
-void ServerParams::setClipboardCaps(rdr::U32 flags, const rdr::U32* lengths)
+void ServerParams::setClipboardCaps(uint32_t flags, const uint32_t* lengths)
{
int i, num;
diff --git a/common/rfb/ServerParams.h b/common/rfb/ServerParams.h
index dba8b9a1..791e3e7f 100644
--- a/common/rfb/ServerParams.h
+++ b/common/rfb/ServerParams.h
@@ -23,6 +23,8 @@
#ifndef __RFB_SERVERPARAMS_H__
#define __RFB_SERVERPARAMS_H__
+#include <string>
+
#include <rfb/Cursor.h>
#include <rfb/PixelFormat.h>
#include <rfb/ScreenSet.h>
@@ -60,7 +62,7 @@ namespace rfb {
const PixelFormat& pf() const { return pf_; }
void setPF(const PixelFormat& pf);
- const char* name() const { return name_; }
+ const char* name() const { return name_.c_str(); }
void setName(const char* name);
const Cursor& cursor() const { return *cursor_; }
@@ -69,9 +71,9 @@ namespace rfb {
unsigned int ledState() { return ledState_; }
void setLEDState(unsigned int state);
- rdr::U32 clipboardFlags() const { return clipFlags; }
- rdr::U32 clipboardSize(unsigned int format) const;
- void setClipboardCaps(rdr::U32 flags, const rdr::U32* lengths);
+ uint32_t clipboardFlags() const { return clipFlags; }
+ uint32_t clipboardSize(unsigned int format) const;
+ void setClipboardCaps(uint32_t flags, const uint32_t* lengths);
bool supportsQEMUKeyEvent;
bool supportsSetDesktopSize;
@@ -85,11 +87,11 @@ namespace rfb {
ScreenSet screenLayout_;
PixelFormat pf_;
- char* name_;
+ std::string name_;
Cursor* cursor_;
unsigned int ledState_;
- rdr::U32 clipFlags;
- rdr::U32 clipSizes[16];
+ uint32_t clipFlags;
+ uint32_t clipSizes[16];
};
}
#endif
diff --git a/common/rfb/TightDecoder.cxx b/common/rfb/TightDecoder.cxx
index 69971dbc..acc9d5a5 100644
--- a/common/rfb/TightDecoder.cxx
+++ b/common/rfb/TightDecoder.cxx
@@ -1,6 +1,6 @@
/* Copyright (C) 2000-2003 Constantin Kaplinsky. All Rights Reserved.
* Copyright 2004-2005 Cendio AB.
- * Copyright 2009-2015 Pierre Ossman for Cendio AB
+ * Copyright 2009-2022 Pierre Ossman for Cendio AB
* Copyright (C) 2011 D. R. Commander. All Rights Reserved.
*
* This is free software; you can redistribute it and/or modify
@@ -25,6 +25,8 @@
#include <assert.h>
+#include <vector>
+
#include <rdr/InStream.h>
#include <rdr/MemInStream.h>
#include <rdr/OutStream.h>
@@ -40,16 +42,6 @@ using namespace rfb;
static const int TIGHT_MAX_WIDTH = 2048;
static const int TIGHT_MIN_TO_COMPRESS = 12;
-#define BPP 8
-#include <rfb/tightDecode.h>
-#undef BPP
-#define BPP 16
-#include <rfb/tightDecode.h>
-#undef BPP
-#define BPP 32
-#include <rfb/tightDecode.h>
-#undef BPP
-
TightDecoder::TightDecoder() : Decoder(DecoderPartiallyOrdered)
{
}
@@ -61,7 +53,7 @@ TightDecoder::~TightDecoder()
bool TightDecoder::readRect(const Rect& r, rdr::InStream* is,
const ServerParams& server, rdr::OutStream* os)
{
- rdr::U8 comp_ctl;
+ uint8_t comp_ctl;
if (!is->hasData(1))
return false;
@@ -90,7 +82,7 @@ bool TightDecoder::readRect(const Rect& r, rdr::InStream* is,
// "JPEG" compression type.
if (comp_ctl == tightJpeg) {
- rdr::U32 len;
+ uint32_t len;
// FIXME: Might be less than 3 bytes
if (!is->hasDataOrRestore(3))
@@ -122,7 +114,7 @@ bool TightDecoder::readRect(const Rect& r, rdr::InStream* is,
// Possible palette
if ((comp_ctl & tightExplicitFilter) != 0) {
- rdr::U8 filterId;
+ uint8_t filterId;
if (!is->hasDataOrRestore(1))
return false;
@@ -179,7 +171,7 @@ bool TightDecoder::readRect(const Rect& r, rdr::InStream* is,
return false;
os->copyBytes(is, dataSize);
} else {
- rdr::U32 len;
+ uint32_t len;
// FIXME: Might be less than 3 bytes
if (!is->hasDataOrRestore(3))
@@ -207,13 +199,13 @@ bool TightDecoder::doRectsConflict(const Rect& /*rectA*/,
size_t buflenB,
const ServerParams& /*server*/)
{
- rdr::U8 comp_ctl_a, comp_ctl_b;
+ uint8_t comp_ctl_a, comp_ctl_b;
assert(buflenA >= 1);
assert(buflenB >= 1);
- comp_ctl_a = *(const rdr::U8*)bufferA;
- comp_ctl_b = *(const rdr::U8*)bufferB;
+ comp_ctl_a = *(const uint8_t*)bufferA;
+ comp_ctl_b = *(const uint8_t*)bufferB;
// Resets or use of zlib pose the same problem, so merge them
if ((comp_ctl_a & 0x80) == 0x00)
@@ -231,12 +223,12 @@ void TightDecoder::decodeRect(const Rect& r, const void* buffer,
size_t buflen, const ServerParams& server,
ModifiablePixelBuffer* pb)
{
- const rdr::U8* bufptr;
+ const uint8_t* bufptr;
const PixelFormat& pf = server.pf();
- rdr::U8 comp_ctl;
+ uint8_t comp_ctl;
- bufptr = (const rdr::U8*)buffer;
+ bufptr = (const uint8_t*)buffer;
assert(buflen >= 1);
@@ -255,7 +247,7 @@ void TightDecoder::decodeRect(const Rect& r, const void* buffer,
// "Fill" compression type.
if (comp_ctl == tightFill) {
if (pf.is888()) {
- rdr::U8 pix[4];
+ uint8_t pix[4];
assert(buflen >= 3);
@@ -270,10 +262,10 @@ void TightDecoder::decodeRect(const Rect& r, const void* buffer,
// "JPEG" compression type.
if (comp_ctl == tightJpeg) {
- rdr::U32 len;
+ uint32_t len;
int stride;
- rdr::U8 *buf;
+ uint8_t *buf;
JpegDecompressor jd;
@@ -296,11 +288,11 @@ void TightDecoder::decodeRect(const Rect& r, const void* buffer,
// "Basic" compression type.
int palSize = 0;
- rdr::U8 palette[256 * 4];
+ uint8_t palette[256 * 4];
bool useGradient = false;
if ((comp_ctl & tightExplicitFilter) != 0) {
- rdr::U8 filterId;
+ uint8_t filterId;
assert(buflen >= 1);
@@ -318,15 +310,15 @@ void TightDecoder::decodeRect(const Rect& r, const void* buffer,
if (pf.is888()) {
size_t len = palSize * 3;
- rdr::U8Array tightPalette(len);
+ std::vector<uint8_t> tightPalette(len);
assert(buflen >= len);
- memcpy(tightPalette.buf, bufptr, len);
+ memcpy(tightPalette.data(), bufptr, len);
bufptr += len;
buflen -= len;
- pf.bufferFromRGB(palette, tightPalette.buf, palSize);
+ pf.bufferFromRGB(palette, tightPalette.data(), palSize);
} else {
size_t len;
@@ -351,7 +343,7 @@ void TightDecoder::decodeRect(const Rect& r, const void* buffer,
// Determine if the data should be decompressed or just copied.
size_t rowSize, dataSize;
- rdr::U8* netbuf;
+ uint8_t* netbuf;
netbuf = NULL;
@@ -371,7 +363,7 @@ void TightDecoder::decodeRect(const Rect& r, const void* buffer,
if (dataSize < TIGHT_MIN_TO_COMPRESS)
assert(buflen >= dataSize);
else {
- rdr::U32 len;
+ uint32_t len;
int streamId;
rdr::MemInStream* ms;
@@ -388,7 +380,7 @@ void TightDecoder::decodeRect(const Rect& r, const void* buffer,
zis[streamId].setUnderlying(ms, len);
// Allocate buffer and decompress the data
- netbuf = new rdr::U8[dataSize];
+ netbuf = new uint8_t[dataSize];
if (!zis[streamId].hasData(dataSize))
throw Exception("Tight decode error");
@@ -405,10 +397,10 @@ void TightDecoder::decodeRect(const Rect& r, const void* buffer,
// Time to decode the actual data
bool directDecode;
- rdr::U8* outbuf;
+ uint8_t* outbuf;
int stride;
- if (pb->getPF().equal(pf)) {
+ if (pb->getPF() == pf) {
// Decode directly into the framebuffer (fast path)
directDecode = true;
} else {
@@ -419,7 +411,7 @@ void TightDecoder::decodeRect(const Rect& r, const void* buffer,
if (directDecode)
outbuf = pb->getBufferRW(r, &stride);
else {
- outbuf = new rdr::U8[r.area() * (pf.bpp/8)];
+ outbuf = new uint8_t[r.area() * (pf.bpp/8)];
stride = r.width();
}
@@ -427,24 +419,24 @@ void TightDecoder::decodeRect(const Rect& r, const void* buffer,
// Truecolor data
if (useGradient) {
if (pf.is888())
- FilterGradient24(bufptr, pf, (rdr::U32*)outbuf, stride, r);
+ FilterGradient24(bufptr, pf, (uint32_t*)outbuf, stride, r);
else {
switch (pf.bpp) {
case 8:
assert(false);
break;
case 16:
- FilterGradient(bufptr, pf, (rdr::U16*)outbuf, stride, r);
+ FilterGradient(bufptr, pf, (uint16_t*)outbuf, stride, r);
break;
case 32:
- FilterGradient(bufptr, pf, (rdr::U32*)outbuf, stride, r);
+ FilterGradient(bufptr, pf, (uint32_t*)outbuf, stride, r);
break;
}
}
} else {
// Copy
- rdr::U8* ptr = outbuf;
- const rdr::U8* srcPtr = bufptr;
+ uint8_t* ptr = outbuf;
+ const uint8_t* srcPtr = bufptr;
int w = r.width();
int h = r.height();
if (pf.is888()) {
@@ -467,16 +459,16 @@ void TightDecoder::decodeRect(const Rect& r, const void* buffer,
// Indexed color
switch (pf.bpp) {
case 8:
- FilterPalette((const rdr::U8*)palette, palSize,
- bufptr, (rdr::U8*)outbuf, stride, r);
+ FilterPalette((const uint8_t*)palette, palSize,
+ bufptr, (uint8_t*)outbuf, stride, r);
break;
case 16:
- FilterPalette((const rdr::U16*)palette, palSize,
- bufptr, (rdr::U16*)outbuf, stride, r);
+ FilterPalette((const uint16_t*)palette, palSize,
+ bufptr, (uint16_t*)outbuf, stride, r);
break;
case 32:
- FilterPalette((const rdr::U32*)palette, palSize,
- bufptr, (rdr::U32*)outbuf, stride, r);
+ FilterPalette((const uint32_t*)palette, palSize,
+ bufptr, (uint32_t*)outbuf, stride, r);
break;
}
}
@@ -491,10 +483,10 @@ void TightDecoder::decodeRect(const Rect& r, const void* buffer,
delete [] netbuf;
}
-rdr::U32 TightDecoder::readCompact(rdr::InStream* is)
+uint32_t TightDecoder::readCompact(rdr::InStream* is)
{
- rdr::U8 b;
- rdr::U32 result;
+ uint8_t b;
+ uint32_t result;
b = is->readU8();
result = (int)b & 0x7F;
@@ -509,3 +501,144 @@ rdr::U32 TightDecoder::readCompact(rdr::InStream* is)
return result;
}
+
+void
+TightDecoder::FilterGradient24(const uint8_t *inbuf,
+ const PixelFormat& pf, uint32_t* outbuf,
+ int stride, const Rect& r)
+{
+ int x, y, c;
+ uint8_t prevRow[TIGHT_MAX_WIDTH*3];
+ uint8_t thisRow[TIGHT_MAX_WIDTH*3];
+ uint8_t pix[3];
+ int est[3];
+
+ memset(prevRow, 0, sizeof(prevRow));
+
+ // Set up shortcut variables
+ int rectHeight = r.height();
+ int rectWidth = r.width();
+
+ for (y = 0; y < rectHeight; y++) {
+ for (x = 0; x < rectWidth; x++) {
+ /* First pixel in a row */
+ if (x == 0) {
+ for (c = 0; c < 3; c++) {
+ pix[c] = inbuf[y*rectWidth*3+c] + prevRow[c];
+ thisRow[c] = pix[c];
+ }
+ pf.bufferFromRGB((uint8_t*)&outbuf[y*stride], pix, 1);
+ continue;
+ }
+
+ for (c = 0; c < 3; c++) {
+ est[c] = prevRow[x*3+c] + pix[c] - prevRow[(x-1)*3+c];
+ if (est[c] > 0xff) {
+ est[c] = 0xff;
+ } else if (est[c] < 0) {
+ est[c] = 0;
+ }
+ pix[c] = inbuf[(y*rectWidth+x)*3+c] + est[c];
+ thisRow[x*3+c] = pix[c];
+ }
+ pf.bufferFromRGB((uint8_t*)&outbuf[y*stride+x], pix, 1);
+ }
+
+ memcpy(prevRow, thisRow, sizeof(prevRow));
+ }
+}
+
+template<class T>
+void TightDecoder::FilterGradient(const uint8_t* inbuf,
+ const PixelFormat& pf, T* outbuf,
+ int stride, const Rect& r)
+{
+ int x, y, c;
+ static uint8_t prevRow[TIGHT_MAX_WIDTH*3];
+ static uint8_t thisRow[TIGHT_MAX_WIDTH*3];
+ uint8_t pix[3];
+ int est[3];
+
+ memset(prevRow, 0, sizeof(prevRow));
+
+ // Set up shortcut variables
+ int rectHeight = r.height();
+ int rectWidth = r.width();
+
+ for (y = 0; y < rectHeight; y++) {
+ for (x = 0; x < rectWidth; x++) {
+ /* First pixel in a row */
+ if (x == 0) {
+ pf.rgbFromBuffer(pix, &inbuf[y*rectWidth], 1);
+ for (c = 0; c < 3; c++)
+ pix[c] += prevRow[c];
+
+ memcpy(thisRow, pix, sizeof(pix));
+
+ pf.bufferFromRGB((uint8_t*)&outbuf[y*stride], pix, 1);
+
+ continue;
+ }
+
+ for (c = 0; c < 3; c++) {
+ est[c] = prevRow[x*3+c] + pix[c] - prevRow[(x-1)*3+c];
+ if (est[c] > 255) {
+ est[c] = 255;
+ } else if (est[c] < 0) {
+ est[c] = 0;
+ }
+ }
+
+ pf.rgbFromBuffer(pix, &inbuf[y*rectWidth+x], 1);
+ for (c = 0; c < 3; c++)
+ pix[c] += est[c];
+
+ memcpy(&thisRow[x*3], pix, sizeof(pix));
+
+ pf.bufferFromRGB((uint8_t*)&outbuf[y*stride+x], pix, 1);
+ }
+
+ memcpy(prevRow, thisRow, sizeof(prevRow));
+ }
+}
+
+template<class T>
+void TightDecoder::FilterPalette(const T* palette, int palSize,
+ const uint8_t* inbuf, T* outbuf,
+ int stride, const Rect& r)
+{
+ // Indexed color
+ int x, h = r.height(), w = r.width(), b, pad = stride - w;
+ T* ptr = outbuf;
+ uint8_t bits;
+ const uint8_t* srcPtr = inbuf;
+ if (palSize <= 2) {
+ // 2-color palette
+ while (h > 0) {
+ for (x = 0; x < w / 8; x++) {
+ bits = *srcPtr++;
+ for (b = 7; b >= 0; b--) {
+ *ptr++ = palette[bits >> b & 1];
+ }
+ }
+ if (w % 8 != 0) {
+ bits = *srcPtr++;
+ for (b = 7; b >= 8 - w % 8; b--) {
+ *ptr++ = palette[bits >> b & 1];
+ }
+ }
+ ptr += pad;
+ h--;
+ }
+ } else {
+ // 256-color palette
+ while (h > 0) {
+ T *endOfRow = ptr + w;
+ while (ptr < endOfRow) {
+ *ptr++ = palette[*srcPtr++];
+ }
+ ptr += pad;
+ h--;
+ }
+ }
+}
diff --git a/common/rfb/TightDecoder.h b/common/rfb/TightDecoder.h
index 763c82d6..03b61daf 100644
--- a/common/rfb/TightDecoder.h
+++ b/common/rfb/TightDecoder.h
@@ -1,6 +1,6 @@
/* Copyright (C) 2000-2003 Constantin Kaplinsky. All Rights Reserved.
* Copyright (C) 2011 D. R. Commander. All Rights Reserved.
- * Copyright 2009-2015 Pierre Ossman for Cendio AB
+ * Copyright 2009-2022 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
@@ -45,24 +45,18 @@ namespace rfb {
ModifiablePixelBuffer* pb);
private:
- rdr::U32 readCompact(rdr::InStream* is);
+ uint32_t readCompact(rdr::InStream* is);
- void FilterGradient24(const rdr::U8* inbuf, const PixelFormat& pf,
- rdr::U32* outbuf, int stride, const Rect& r);
+ void FilterGradient24(const uint8_t* inbuf, const PixelFormat& pf,
+ uint32_t* outbuf, int stride, const Rect& r);
- void FilterGradient(const rdr::U8* inbuf, const PixelFormat& pf,
- rdr::U16* outbuf, int stride, const Rect& r);
- void FilterGradient(const rdr::U8* inbuf, const PixelFormat& pf,
- rdr::U32* outbuf, int stride, const Rect& r);
+ template<class T>
+ void FilterGradient(const uint8_t* inbuf, const PixelFormat& pf,
+ T* outbuf, int stride, const Rect& r);
- void FilterPalette(const rdr::U8* palette, int palSize,
- const rdr::U8* inbuf, rdr::U8* outbuf,
- int stride, const Rect& r);
- void FilterPalette(const rdr::U16* palette, int palSize,
- const rdr::U8* inbuf, rdr::U16* outbuf,
- int stride, const Rect& r);
- void FilterPalette(const rdr::U32* palette, int palSize,
- const rdr::U8* inbuf, rdr::U32* outbuf,
+ template<class T>
+ void FilterPalette(const T* palette, int palSize,
+ const uint8_t* inbuf, T* outbuf,
int stride, const Rect& r);
private:
diff --git a/common/rfb/TightEncoder.cxx b/common/rfb/TightEncoder.cxx
index 94acd3d1..1a169a3d 100644
--- a/common/rfb/TightEncoder.cxx
+++ b/common/rfb/TightEncoder.cxx
@@ -1,6 +1,6 @@
/* Copyright (C) 2000-2003 Constantin Kaplinsky. All Rights Reserved.
* Copyright (C) 2011 D. R. Commander. All Rights Reserved.
- * Copyright 2014 Pierre Ossman for Cendio AB
+ * Copyright 2014-2022 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
@@ -104,7 +104,7 @@ void TightEncoder::writeRect(const PixelBuffer* pb, const Palette& palette)
void TightEncoder::writeSolidRect(int /*width*/, int /*height*/,
const PixelFormat& pf,
- const rdr::U8* colour)
+ const uint8_t* colour)
{
rdr::OutStream* os;
@@ -116,40 +116,40 @@ void TightEncoder::writeSolidRect(int /*width*/, int /*height*/,
void TightEncoder::writeMonoRect(const PixelBuffer* pb, const Palette& palette)
{
- const rdr::U8* buffer;
+ const uint8_t* buffer;
int stride;
buffer = pb->getBuffer(pb->getRect(), &stride);
switch (pb->getPF().bpp) {
case 32:
- writeMonoRect(pb->width(), pb->height(), (rdr::U32*)buffer, stride,
+ writeMonoRect(pb->width(), pb->height(), (uint32_t*)buffer, stride,
pb->getPF(), palette);
break;
case 16:
- writeMonoRect(pb->width(), pb->height(), (rdr::U16*)buffer, stride,
+ writeMonoRect(pb->width(), pb->height(), (uint16_t*)buffer, stride,
pb->getPF(), palette);
break;
default:
- writeMonoRect(pb->width(), pb->height(), (rdr::U8*)buffer, stride,
+ writeMonoRect(pb->width(), pb->height(), (uint8_t*)buffer, stride,
pb->getPF(), palette);
}
}
void TightEncoder::writeIndexedRect(const PixelBuffer* pb, const Palette& palette)
{
- const rdr::U8* buffer;
+ const uint8_t* buffer;
int stride;
buffer = pb->getBuffer(pb->getRect(), &stride);
switch (pb->getPF().bpp) {
case 32:
- writeIndexedRect(pb->width(), pb->height(), (rdr::U32*)buffer, stride,
+ writeIndexedRect(pb->width(), pb->height(), (uint32_t*)buffer, stride,
pb->getPF(), palette);
break;
case 16:
- writeIndexedRect(pb->width(), pb->height(), (rdr::U16*)buffer, stride,
+ writeIndexedRect(pb->width(), pb->height(), (uint16_t*)buffer, stride,
pb->getPF(), palette);
break;
default:
@@ -166,7 +166,7 @@ void TightEncoder::writeFullColourRect(const PixelBuffer* pb)
rdr::OutStream* zos;
int length;
- const rdr::U8* buffer;
+ const uint8_t* buffer;
int stride, h;
os = conn->getOutStream();
@@ -194,10 +194,10 @@ void TightEncoder::writeFullColourRect(const PixelBuffer* pb)
flushZlibOutStream(zos);
}
-void TightEncoder::writePixels(const rdr::U8* buffer, const PixelFormat& pf,
+void TightEncoder::writePixels(const uint8_t* buffer, const PixelFormat& pf,
unsigned int count, rdr::OutStream* os)
{
- rdr::U8 rgb[2048];
+ uint8_t rgb[2048];
if ((pf.bpp != 32) || !pf.is888()) {
os->writeBytes(buffer, count * pf.bpp/8);
@@ -219,9 +219,9 @@ void TightEncoder::writePixels(const rdr::U8* buffer, const PixelFormat& pf,
}
}
-void TightEncoder::writeCompact(rdr::OutStream* os, rdr::U32 value)
+void TightEncoder::writeCompact(rdr::OutStream* os, uint32_t value)
{
- rdr::U8 b;
+ uint8_t b;
b = value & 0x7F;
if (value <= 0x7F) {
os->writeU8(b);
@@ -274,16 +274,143 @@ void TightEncoder::flushZlibOutStream(rdr::OutStream* os_)
memStream.clear();
}
-//
-// Including BPP-dependent implementation of the encoder.
-//
+template<class T>
+void TightEncoder::writeMonoRect(int width, int height,
+ const T* buffer, int stride,
+ const PixelFormat& pf,
+ const Palette& palette)
+{
+ rdr::OutStream* os;
+
+ const int streamId = 1;
+ T pal[2];
+
+ int length;
+ rdr::OutStream* zos;
+
+ assert(palette.size() == 2);
+
+ os = conn->getOutStream();
+
+ os->writeU8((streamId | tightExplicitFilter) << 4);
+ os->writeU8(tightFilterPalette);
-#define BPP 8
-#include <rfb/TightEncoderBPP.cxx>
-#undef BPP
-#define BPP 16
-#include <rfb/TightEncoderBPP.cxx>
-#undef BPP
-#define BPP 32
-#include <rfb/TightEncoderBPP.cxx>
-#undef BPP
+ // Write the palette
+ pal[0] = (T)palette.getColour(0);
+ pal[1] = (T)palette.getColour(1);
+
+ os->writeU8(1);
+ writePixels((uint8_t*)pal, pf, 2, os);
+
+ // Set up compression
+ length = (width + 7)/8 * height;
+ zos = getZlibOutStream(streamId, monoZlibLevel, length);
+
+ // Encode the data
+ T bg;
+ unsigned int value, mask;
+ int pad, aligned_width;
+ int x, y, bg_bits;
+
+ bg = pal[0];
+ aligned_width = width - width % 8;
+ pad = stride - width;
+
+ for (y = 0; y < height; y++) {
+ for (x = 0; x < aligned_width; x += 8) {
+ for (bg_bits = 0; bg_bits < 8; bg_bits++) {
+ if (*buffer++ != bg)
+ break;
+ }
+ if (bg_bits == 8) {
+ zos->writeU8(0);
+ continue;
+ }
+ mask = 0x80 >> bg_bits;
+ value = mask;
+ for (bg_bits++; bg_bits < 8; bg_bits++) {
+ mask >>= 1;
+ if (*buffer++ != bg) {
+ value |= mask;
+ }
+ }
+ zos->writeU8(value);
+ }
+
+ if (x < width) {
+ mask = 0x80;
+ value = 0;
+
+ for (; x < width; x++) {
+ if (*buffer++ != bg) {
+ value |= mask;
+ }
+ mask >>= 1;
+ }
+ zos->writeU8(value);
+ }
+
+ buffer += pad;
+ }
+
+ // Finish the zlib stream
+ flushZlibOutStream(zos);
+}
+
+template<class T>
+void TightEncoder::writeIndexedRect(int width, int height,
+ const T* buffer, int stride,
+ const PixelFormat& pf,
+ const Palette& palette)
+{
+ rdr::OutStream* os;
+
+ const int streamId = 2;
+ T pal[256];
+
+ rdr::OutStream* zos;
+
+ int pad;
+ T prevColour;
+ unsigned char idx;
+
+ assert(palette.size() > 0);
+ assert(palette.size() <= 256);
+
+ os = conn->getOutStream();
+
+ os->writeU8((streamId | tightExplicitFilter) << 4);
+ os->writeU8(tightFilterPalette);
+
+ // Write the palette
+ for (int i = 0; i < palette.size(); i++)
+ pal[i] = (T)palette.getColour(i);
+
+ os->writeU8(palette.size() - 1);
+ writePixels((uint8_t*)pal, pf, palette.size(), os);
+
+ // Set up compression
+ zos = getZlibOutStream(streamId, idxZlibLevel, width * height);
+
+ // Encode the data
+ pad = stride - width;
+
+ prevColour = *buffer;
+ idx = palette.lookup(*buffer);
+
+ while (height--) {
+ int w = width;
+ while (w--) {
+ if (*buffer != prevColour) {
+ prevColour = *buffer;
+ idx = palette.lookup(*buffer);
+ }
+ zos->writeU8(idx);
+ buffer++;
+ }
+ buffer += pad;
+ }
+
+ // Finish the zlib stream
+ flushZlibOutStream(zos);
+}
diff --git a/common/rfb/TightEncoder.h b/common/rfb/TightEncoder.h
index b96bc4c6..0608eb09 100644
--- a/common/rfb/TightEncoder.h
+++ b/common/rfb/TightEncoder.h
@@ -1,6 +1,6 @@
/* Copyright (C) 2000-2003 Constantin Kaplinsky. All Rights Reserved.
* Copyright (C) 2011 D. R. Commander
- * Copyright 2014 Pierre Ossman for Cendio AB
+ * Copyright 2014-2022 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
@@ -38,38 +38,30 @@ namespace rfb {
virtual void writeRect(const PixelBuffer* pb, const Palette& palette);
virtual void writeSolidRect(int width, int height,
const PixelFormat& pf,
- const rdr::U8* colour);
+ const uint8_t* colour);
protected:
void writeMonoRect(const PixelBuffer* pb, const Palette& palette);
void writeIndexedRect(const PixelBuffer* pb, const Palette& palette);
void writeFullColourRect(const PixelBuffer* pb);
- void writePixels(const rdr::U8* buffer, const PixelFormat& pf,
+ void writePixels(const uint8_t* buffer, const PixelFormat& pf,
unsigned int count, rdr::OutStream* os);
- void writeCompact(rdr::OutStream* os, rdr::U32 value);
+ void writeCompact(rdr::OutStream* os, uint32_t value);
rdr::OutStream* getZlibOutStream(int streamId, int level, size_t length);
void flushZlibOutStream(rdr::OutStream* os);
protected:
- // Preprocessor generated, optimised methods
+ // Templated, optimised methods
+ template<class T>
void writeMonoRect(int width, int height,
- const rdr::U8* buffer, int stride,
+ const T* buffer, int stride,
const PixelFormat& pf, const Palette& palette);
- void writeMonoRect(int width, int height,
- const rdr::U16* buffer, int stride,
- const PixelFormat& pf, const Palette& palette);
- void writeMonoRect(int width, int height,
- const rdr::U32* buffer, int stride,
- const PixelFormat& pf, const Palette& palette);
-
- void writeIndexedRect(int width, int height,
- const rdr::U16* buffer, int stride,
- const PixelFormat& pf, const Palette& palette);
+ template<class T>
void writeIndexedRect(int width, int height,
- const rdr::U32* buffer, int stride,
+ const T* buffer, int stride,
const PixelFormat& pf, const Palette& palette);
rdr::ZlibOutStream zlibStreams[4];
diff --git a/common/rfb/TightEncoderBPP.cxx b/common/rfb/TightEncoderBPP.cxx
deleted file mode 100644
index 8874662c..00000000
--- a/common/rfb/TightEncoderBPP.cxx
+++ /dev/null
@@ -1,165 +0,0 @@
-/* Copyright (C) 2000-2003 Constantin Kaplinsky. All Rights Reserved.
- * Copyright (C) 2011 D. R. Commander. All Rights Reserved.
- * Copyright 2014 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.
- */
-
-#define CONCAT2(a,b) a##b
-#define CONCAT2E(a,b) CONCAT2(a,b)
-
-#define UBPP CONCAT2E(U,BPP)
-
-void TightEncoder::writeMonoRect(int width, int height,
- const rdr::UBPP* buffer, int stride,
- const PixelFormat& pf,
- const Palette& palette)
-{
- rdr::OutStream* os;
-
- const int streamId = 1;
- rdr::UBPP pal[2];
-
- int length;
- rdr::OutStream* zos;
-
- assert(palette.size() == 2);
-
- os = conn->getOutStream();
-
- os->writeU8((streamId | tightExplicitFilter) << 4);
- os->writeU8(tightFilterPalette);
-
- // Write the palette
- pal[0] = (rdr::UBPP)palette.getColour(0);
- pal[1] = (rdr::UBPP)palette.getColour(1);
-
- os->writeU8(1);
- writePixels((rdr::U8*)pal, pf, 2, os);
-
- // Set up compression
- length = (width + 7)/8 * height;
- zos = getZlibOutStream(streamId, monoZlibLevel, length);
-
- // Encode the data
- rdr::UBPP bg;
- unsigned int value, mask;
- int pad, aligned_width;
- int x, y, bg_bits;
-
- bg = pal[0];
- aligned_width = width - width % 8;
- pad = stride - width;
-
- for (y = 0; y < height; y++) {
- for (x = 0; x < aligned_width; x += 8) {
- for (bg_bits = 0; bg_bits < 8; bg_bits++) {
- if (*buffer++ != bg)
- break;
- }
- if (bg_bits == 8) {
- zos->writeU8(0);
- continue;
- }
- mask = 0x80 >> bg_bits;
- value = mask;
- for (bg_bits++; bg_bits < 8; bg_bits++) {
- mask >>= 1;
- if (*buffer++ != bg) {
- value |= mask;
- }
- }
- zos->writeU8(value);
- }
-
- if (x < width) {
- mask = 0x80;
- value = 0;
-
- for (; x < width; x++) {
- if (*buffer++ != bg) {
- value |= mask;
- }
- mask >>= 1;
- }
- zos->writeU8(value);
- }
-
- buffer += pad;
- }
-
- // Finish the zlib stream
- flushZlibOutStream(zos);
-}
-
-#if (BPP != 8)
-void TightEncoder::writeIndexedRect(int width, int height,
- const rdr::UBPP* buffer, int stride,
- const PixelFormat& pf,
- const Palette& palette)
-{
- rdr::OutStream* os;
-
- const int streamId = 2;
- rdr::UBPP pal[256];
-
- rdr::OutStream* zos;
-
- int pad;
- rdr::UBPP prevColour;
- unsigned char idx;
-
- assert(palette.size() > 0);
- assert(palette.size() <= 256);
-
- os = conn->getOutStream();
-
- os->writeU8((streamId | tightExplicitFilter) << 4);
- os->writeU8(tightFilterPalette);
-
- // Write the palette
- for (int i = 0; i < palette.size(); i++)
- pal[i] = (rdr::UBPP)palette.getColour(i);
-
- os->writeU8(palette.size() - 1);
- writePixels((rdr::U8*)pal, pf, palette.size(), os);
-
- // Set up compression
- zos = getZlibOutStream(streamId, idxZlibLevel, width * height);
-
- // Encode the data
- pad = stride - width;
-
- prevColour = *buffer;
- idx = palette.lookup(*buffer);
-
- while (height--) {
- int w = width;
- while (w--) {
- if (*buffer != prevColour) {
- prevColour = *buffer;
- idx = palette.lookup(*buffer);
- }
- zos->writeU8(idx);
- buffer++;
- }
- buffer += pad;
- }
-
- // Finish the zlib stream
- flushZlibOutStream(zos);
-}
-#endif // #if (BPP != 8)
diff --git a/common/rfb/TightJPEGEncoder.cxx b/common/rfb/TightJPEGEncoder.cxx
index 976601f7..5c8706ee 100644
--- a/common/rfb/TightJPEGEncoder.cxx
+++ b/common/rfb/TightJPEGEncoder.cxx
@@ -115,7 +115,7 @@ int TightJPEGEncoder::getQualityLevel()
void TightJPEGEncoder::writeRect(const PixelBuffer* pb,
const Palette& /*palette*/)
{
- const rdr::U8* buffer;
+ const uint8_t* buffer;
int stride;
int quality, subsampling;
@@ -152,17 +152,17 @@ void TightJPEGEncoder::writeRect(const PixelBuffer* pb,
void TightJPEGEncoder::writeSolidRect(int width, int height,
const PixelFormat& pf,
- const rdr::U8* colour)
+ const uint8_t* colour)
{
// FIXME: Add a shortcut in the JPEG compressor to handle this case
// without having to use the default fallback which is very slow.
Encoder::writeSolidRect(width, height, pf, colour);
}
-void TightJPEGEncoder::writeCompact(rdr::U32 value, rdr::OutStream* os)
+void TightJPEGEncoder::writeCompact(uint32_t value, rdr::OutStream* os)
{
// Copied from TightEncoder as it's overkill to inherit just for this
- rdr::U8 b;
+ uint8_t b;
b = value & 0x7F;
if (value <= 0x7F) {
diff --git a/common/rfb/TightJPEGEncoder.h b/common/rfb/TightJPEGEncoder.h
index 3d8fa8c1..002deabb 100644
--- a/common/rfb/TightJPEGEncoder.h
+++ b/common/rfb/TightJPEGEncoder.h
@@ -40,10 +40,10 @@ namespace rfb {
virtual void writeRect(const PixelBuffer* pb, const Palette& palette);
virtual void writeSolidRect(int width, int height,
const PixelFormat& pf,
- const rdr::U8* colour);
+ const uint8_t* colour);
protected:
- void writeCompact(rdr::U32 value, rdr::OutStream* os);
+ void writeCompact(uint32_t value, rdr::OutStream* os);
protected:
JpegCompressor jc;
diff --git a/common/rfb/UnixPasswordValidator.cxx b/common/rfb/UnixPasswordValidator.cxx
index fa1513a4..57fa9b39 100644
--- a/common/rfb/UnixPasswordValidator.cxx
+++ b/common/rfb/UnixPasswordValidator.cxx
@@ -41,6 +41,5 @@ bool UnixPasswordValidator::validateInternal(SConnection * /*sc*/,
const char *username,
const char *password)
{
- CharArray service(strDup(pamService.getData()));
- return do_pam_auth(service.buf, username, password);
+ return do_pam_auth(pamService, username, password);
}
diff --git a/common/rfb/UserPasswdGetter.h b/common/rfb/UserPasswdGetter.h
index 27775cc3..db7df396 100644
--- a/common/rfb/UserPasswdGetter.h
+++ b/common/rfb/UserPasswdGetter.h
@@ -17,16 +17,20 @@
*/
#ifndef __RFB_USERPASSWDGETTER_H__
#define __RFB_USERPASSWDGETTER_H__
+
+#include <string>
+
namespace rfb {
class UserPasswdGetter {
public:
// getUserPasswd gets the username and password. This might involve a
// dialog, getpass(), etc. The user buffer pointer can be null, in which
- // case no user name will be retrieved. The caller MUST delete [] the
- // result(s).
- virtual void getUserPasswd(bool secure, char** user, char** password)=0;
+ // case no user name will be retrieved.
+ virtual void getUserPasswd(bool secure, std::string* user,
+ std::string* password)=0;
virtual ~UserPasswdGetter() {}
};
}
+
#endif
diff --git a/common/rfb/VNCSConnectionST.cxx b/common/rfb/VNCSConnectionST.cxx
index 23024c5e..5d047e6a 100644
--- a/common/rfb/VNCSConnectionST.cxx
+++ b/common/rfb/VNCSConnectionST.cxx
@@ -26,6 +26,7 @@
#include <rfb/ComparingUpdateTracker.h>
#include <rfb/Encoder.h>
+#include <rfb/Exception.h>
#include <rfb/KeyRemapper.h>
#include <rfb/LogWriter.h>
#include <rfb/Security.h>
@@ -40,6 +41,7 @@
#define XK_MISCELLANY
#define XK_XKB_KEYS
#include <rfb/keysymdef.h>
+#include <rfb/util.h>
using namespace rfb;
@@ -59,7 +61,7 @@ VNCSConnectionST::VNCSConnectionST(VNCServerST* server_, network::Socket *s,
pointerEventTime(0), clientHasCursor(false)
{
setStreams(&sock->inStream(), &sock->outStream());
- peerEndpoint.buf = sock->getPeerEndpoint();
+ peerEndpoint = sock->getPeerEndpoint();
// Kick off the idle timer
if (rfb::Server::idleTimeout) {
@@ -75,12 +77,13 @@ VNCSConnectionST::VNCSConnectionST(VNCServerST* server_, network::Socket *s,
VNCSConnectionST::~VNCSConnectionST()
{
// If we reach here then VNCServerST is deleting us!
- if (closeReason.buf)
- vlog.info("closing %s: %s", peerEndpoint.buf, closeReason.buf);
+ if (!closeReason.empty())
+ vlog.info("closing %s: %s", peerEndpoint.c_str(),
+ closeReason.c_str());
// Release any keys the client still had pressed
while (!pressedKeys.empty()) {
- rdr::U32 keysym, keycode;
+ uint32_t keysym, keycode;
keysym = pressedKeys.begin()->second;
keycode = pressedKeys.begin()->first;
@@ -112,10 +115,10 @@ void VNCSConnectionST::close(const char* reason)
SConnection::close(reason);
// Log the reason for the close
- if (!closeReason.buf)
- closeReason.buf = strDup(reason);
+ if (closeReason.empty())
+ closeReason = reason;
else
- vlog.debug("second close: %s (%s)", peerEndpoint.buf, reason);
+ vlog.debug("second close: %s (%s)", peerEndpoint.c_str(), reason);
try {
if (sock->outStream().hasBufferedData()) {
@@ -261,7 +264,7 @@ void VNCSConnectionST::writeFramebufferUpdateOrClose()
}
}
-void VNCSConnectionST::screenLayoutChangeOrClose(rdr::U16 reason)
+void VNCSConnectionST::screenLayoutChangeOrClose(uint16_t reason)
{
try {
screenLayoutChange(reason);
@@ -400,7 +403,7 @@ bool VNCSConnectionST::needRenderedCursor()
if (!client.supportsLocalCursor())
return true;
- if (!server->getCursorPos().equals(pointerEventPos) &&
+ if ((server->getCursorPos() != pointerEventPos) &&
(time(0) - pointerEventTime) > 0)
return true;
@@ -502,8 +505,8 @@ public:
// keyEvent() - record in the pressedKeys which keys were pressed. Allow
// multiple down events (for autorepeat), but only allow a single up event.
-void VNCSConnectionST::keyEvent(rdr::U32 keysym, rdr::U32 keycode, bool down) {
- rdr::U32 lookup;
+void VNCSConnectionST::keyEvent(uint32_t keysym, uint32_t keycode, bool down) {
+ uint32_t lookup;
if (rfb::Server::idleTimeout)
idleTimer.start(secsToMillis(rfb::Server::idleTimeout));
@@ -669,9 +672,9 @@ void VNCSConnectionST::setDesktopSize(int fb_width, int fb_height,
writer()->writeDesktopSize(reasonClient, result);
}
-void VNCSConnectionST::fence(rdr::U32 flags, unsigned len, const char data[])
+void VNCSConnectionST::fence(uint32_t flags, unsigned len, const char data[])
{
- rdr::U8 type;
+ uint8_t type;
if (flags & fenceFlagRequest) {
if (flags & fenceFlagSyncNext) {
@@ -808,7 +811,7 @@ bool VNCSConnectionST::handleTimeout(Timer* t)
bool VNCSConnectionST::isShiftPressed()
{
- std::map<rdr::U32, rdr::U32>::const_iterator iter;
+ std::map<uint32_t, uint32_t>::const_iterator iter;
for (iter = pressedKeys.begin(); iter != pressedKeys.end(); ++iter) {
if (iter->second == XK_Shift_L)
@@ -1108,7 +1111,7 @@ void VNCSConnectionST::writeLosslessRefresh()
}
-void VNCSConnectionST::screenLayoutChange(rdr::U16 reason)
+void VNCSConnectionST::screenLayoutChange(uint16_t reason)
{
if (!authenticated())
return;
diff --git a/common/rfb/VNCSConnectionST.h b/common/rfb/VNCSConnectionST.h
index 72b0c529..79f0b4fe 100644
--- a/common/rfb/VNCSConnectionST.h
+++ b/common/rfb/VNCSConnectionST.h
@@ -71,7 +71,7 @@ namespace rfb {
// Wrappers to make these methods "safe" for VNCServerST.
void writeFramebufferUpdateOrClose();
- void screenLayoutChangeOrClose(rdr::U16 reason);
+ void screenLayoutChangeOrClose(uint16_t reason);
void setCursorOrClose();
void bellOrClose();
void setDesktopNameOrClose(const char *name);
@@ -112,7 +112,7 @@ namespace rfb {
updates.add_copied(dest, delta);
}
- const char* getPeerEndpoint() const {return peerEndpoint.buf;}
+ const char* getPeerEndpoint() const {return peerEndpoint.c_str();}
private:
// SConnection callbacks
@@ -124,11 +124,11 @@ namespace rfb {
virtual void clientInit(bool shared);
virtual void setPixelFormat(const PixelFormat& pf);
virtual void pointerEvent(const Point& pos, int buttonMask);
- virtual void keyEvent(rdr::U32 keysym, rdr::U32 keycode, bool down);
+ virtual void keyEvent(uint32_t keysym, uint32_t keycode, bool down);
virtual void framebufferUpdateRequest(const Rect& r, bool incremental);
virtual void setDesktopSize(int fb_width, int fb_height,
const ScreenSet& layout);
- virtual void fence(rdr::U32 flags, unsigned len, const char data[]);
+ virtual void fence(uint32_t flags, unsigned len, const char data[]);
virtual void enableContinuousUpdates(bool enable,
int x, int y, int w, int h);
virtual void handleClipboardRequest();
@@ -158,7 +158,7 @@ namespace rfb {
void writeDataUpdate();
void writeLosslessRefresh();
- void screenLayoutChange(rdr::U16 reason);
+ void screenLayoutChange(uint16_t reason);
void setCursor();
void setCursorPos();
void setDesktopName(const char *name);
@@ -166,13 +166,13 @@ namespace rfb {
private:
network::Socket* sock;
- CharArray peerEndpoint;
+ std::string peerEndpoint;
bool reverseConnection;
bool inProcessMessages;
bool pendingSyncFence, syncFence;
- rdr::U32 fenceFlags;
+ uint32_t fenceFlags;
unsigned fenceDataLen;
char *fenceData;
@@ -189,7 +189,7 @@ namespace rfb {
Region cuRegion;
EncodeManager encodeManager;
- std::map<rdr::U32, rdr::U32> pressedKeys;
+ std::map<uint32_t, uint32_t> pressedKeys;
Timer idleTimer;
@@ -197,7 +197,7 @@ namespace rfb {
Point pointerEventPos;
bool clientHasCursor;
- CharArray closeReason;
+ std::string closeReason;
};
}
#endif
diff --git a/common/rfb/VNCServer.h b/common/rfb/VNCServer.h
index 4535b562..3f97634b 100644
--- a/common/rfb/VNCServer.h
+++ b/common/rfb/VNCServer.h
@@ -95,7 +95,7 @@ namespace rfb {
// cursorData argument contains width*height rgba quadruplets with
// non-premultiplied alpha.
virtual void setCursor(int width, int height, const Point& hotspot,
- const rdr::U8* cursorData) = 0;
+ const uint8_t* cursorData) = 0;
// setCursorPos() tells the server the current position of the cursor, and
// whether the server initiated that change (e.g. through another X11
diff --git a/common/rfb/VNCServerST.cxx b/common/rfb/VNCServerST.cxx
index 411cfd5e..5f5ee34a 100644
--- a/common/rfb/VNCServerST.cxx
+++ b/common/rfb/VNCServerST.cxx
@@ -56,6 +56,7 @@
#include <stdlib.h>
#include <rfb/ComparingUpdateTracker.h>
+#include <rfb/Exception.h>
#include <rfb/KeyRemapper.h>
#include <rfb/LogWriter.h>
#include <rfb/Security.h>
@@ -65,7 +66,6 @@
#include <rfb/util.h>
#include <rfb/ledStates.h>
-#include <rdr/types.h>
using namespace rfb;
@@ -81,14 +81,14 @@ static LogWriter connectionsLog("Connections");
VNCServerST::VNCServerST(const char* name_, SDesktop* desktop_)
: blHosts(&blacklist), desktop(desktop_), desktopStarted(false),
blockCounter(0), pb(0), ledState(ledUnknown),
- name(strDup(name_)), pointerClient(0), clipboardClient(0),
+ name(name_), pointerClient(0), clipboardClient(0),
comparer(0), cursor(new Cursor(0, 0, Point(), NULL)),
renderedCursorInvalid(false),
keyRemapper(&KeyRemapper::defInstance),
idleTimer(this), disconnectTimer(this), connectTimer(this),
frameTimer(this)
{
- slog.debug("creating single-threaded server %s", name.buf);
+ slog.debug("creating single-threaded server %s", name.c_str());
// FIXME: Do we really want to kick off these right away?
if (rfb::Server::maxIdleTime)
@@ -99,7 +99,7 @@ VNCServerST::VNCServerST(const char* name_, SDesktop* desktop_)
VNCServerST::~VNCServerST()
{
- slog.debug("shutting down server %s", name.buf);
+ slog.debug("shutting down server %s", name.c_str());
// Close any active clients, with appropriate logging & cleanup
closeClients("Server shutdown");
@@ -132,9 +132,9 @@ void VNCServerST::addSocket(network::Socket* sock, bool outgoing)
{
// - Check the connection isn't black-marked
// *** do this in getSecurity instead?
- CharArray address(sock->getPeerAddress());
- if (blHosts->isBlackmarked(address.buf)) {
- connectionsLog.error("blacklisted: %s", address.buf);
+ const char *address = sock->getPeerAddress();
+ if (blHosts->isBlackmarked(address)) {
+ connectionsLog.error("blacklisted: %s", address);
try {
rdr::OutStream& os = sock->outStream();
@@ -152,9 +152,7 @@ void VNCServerST::addSocket(network::Socket* sock, bool outgoing)
return;
}
- CharArray name;
- name.buf = sock->getPeerEndpoint();
- connectionsLog.status("accepted: %s", name.buf);
+ connectionsLog.status("accepted: %s", sock->getPeerEndpoint());
// Adjust the exit timers
if (rfb::Server::maxConnectionTime && clients.empty())
@@ -178,14 +176,14 @@ void VNCServerST::removeSocket(network::Socket* sock) {
handleClipboardAnnounce(*ci, false);
clipboardRequestors.remove(*ci);
- CharArray name(strDup((*ci)->getPeerEndpoint()));
+ std::string name((*ci)->getPeerEndpoint());
// - Delete the per-Socket resources
delete *ci;
clients.remove(*ci);
- connectionsLog.status("closed: %s", name.buf);
+ connectionsLog.status("closed: %s", name.c_str());
// - Check that the desktop object is still required
if (authClientCount() == 0)
@@ -389,7 +387,7 @@ void VNCServerST::bell()
void VNCServerST::setName(const char* name_)
{
- name.replaceBuf(strDup(name_));
+ name = name_;
std::list<VNCSConnectionST*>::iterator ci, ci_next;
for (ci = clients.begin(); ci != clients.end(); ci = ci_next) {
ci_next = ci; ci_next++;
@@ -416,7 +414,7 @@ void VNCServerST::add_copied(const Region& dest, const Point& delta)
}
void VNCServerST::setCursor(int width, int height, const Point& newHotspot,
- const rdr::U8* data)
+ const uint8_t* data)
{
delete cursor;
cursor = new Cursor(width, height, newHotspot, data);
@@ -434,7 +432,7 @@ void VNCServerST::setCursor(int width, int height, const Point& newHotspot,
void VNCServerST::setCursorPos(const Point& pos, bool warped)
{
- if (!cursorPos.equals(pos)) {
+ if (cursorPos != pos) {
cursorPos = pos;
renderedCursorInvalid = true;
std::list<VNCSConnectionST*>::iterator ci;
@@ -463,14 +461,14 @@ void VNCServerST::setLEDState(unsigned int state)
// Event handlers
-void VNCServerST::keyEvent(rdr::U32 keysym, rdr::U32 keycode, bool down)
+void VNCServerST::keyEvent(uint32_t keysym, uint32_t keycode, bool down)
{
if (rfb::Server::maxIdleTime)
idleTimer.start(secsToMillis(rfb::Server::maxIdleTime));
// Remap the key if required
if (keyRemapper) {
- rdr::U32 newkey;
+ uint32_t newkey;
newkey = keyRemapper->remapKey(keysym);
if (newkey != keysym) {
slog.debug("Key remapped to 0x%x", newkey);
@@ -652,9 +650,7 @@ void VNCServerST::queryConnection(VNCSConnectionST* client,
const char* userName)
{
// - Authentication succeeded - clear from blacklist
- CharArray name;
- name.buf = client->getSock()->getPeerAddress();
- blHosts->clearBlackmark(name.buf);
+ blHosts->clearBlackmark(client->getSock()->getPeerAddress());
// - Prepare the desktop for that the client will start requiring
// resources after this
diff --git a/common/rfb/VNCServerST.h b/common/rfb/VNCServerST.h
index 159e3a4b..028903c9 100644
--- a/common/rfb/VNCServerST.h
+++ b/common/rfb/VNCServerST.h
@@ -98,7 +98,7 @@ namespace rfb {
virtual void add_changed(const Region &region);
virtual void add_copied(const Region &dest, const Point &delta);
virtual void setCursor(int width, int height, const Point& hotspot,
- const rdr::U8* data);
+ const uint8_t* data);
virtual void setCursorPos(const Point& p, bool warped);
virtual void setName(const char* name_);
virtual void setLEDState(unsigned state);
@@ -112,11 +112,11 @@ namespace rfb {
const ScreenSet& getScreenLayout() const { return screenLayout; }
const Cursor* getCursor() const { return cursor; }
const Point& getCursorPos() const { return cursorPos; }
- const char* getName() const { return name.buf; }
+ const char* getName() const { return name.c_str(); }
unsigned getLEDState() const { return ledState; }
// Event handlers
- void keyEvent(rdr::U32 keysym, rdr::U32 keycode, bool down);
+ void keyEvent(uint32_t keysym, uint32_t keycode, bool down);
void pointerEvent(VNCSConnectionST* client, const Point& pos, int buttonMask);
void handleClipboardRequest(VNCSConnectionST* client);
@@ -183,7 +183,7 @@ namespace rfb {
ScreenSet screenLayout;
unsigned int ledState;
- CharArray name;
+ std::string name;
std::list<VNCSConnectionST*> clients;
VNCSConnectionST* pointerClient;
diff --git a/common/rfb/WinPasswdValidator.cxx b/common/rfb/WinPasswdValidator.cxx
index f07c27e8..84832e81 100644
--- a/common/rfb/WinPasswdValidator.cxx
+++ b/common/rfb/WinPasswdValidator.cxx
@@ -24,7 +24,6 @@
#include <rfb/WinPasswdValidator.h>
#include <windows.h>
-#include <tchar.h>
using namespace rfb;
@@ -33,17 +32,10 @@ bool WinPasswdValidator::validateInternal(rfb::SConnection* /*sc*/,
const char* username,
const char* password)
{
- TCHAR* user = (TCHAR*) strDup(username);
- TCHAR* pass = (TCHAR*) strDup(password);
- TCHAR* domain = (TCHAR*) strDup(".");
HANDLE handle;
- BOOL ret = LogonUser(user, domain, pass, LOGON32_LOGON_NETWORK,
+ BOOL ret = LogonUser(username, ".", password, LOGON32_LOGON_NETWORK,
LOGON32_PROVIDER_DEFAULT, &handle);
- delete [] user;
- delete [] pass;
- delete [] domain;
-
if (ret != 0) {
CloseHandle(handle);
return true;
diff --git a/common/rfb/ZRLEDecoder.cxx b/common/rfb/ZRLEDecoder.cxx
index f5120e9c..6dad55f4 100644
--- a/common/rfb/ZRLEDecoder.cxx
+++ b/common/rfb/ZRLEDecoder.cxx
@@ -1,5 +1,5 @@
/* Copyright (C) 2002-2005 RealVNC Ltd. All Rights Reserved.
- * Copyright 2009-2017 Pierre Ossman for Cendio AB
+ * Copyright 2009-2022 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
@@ -32,46 +32,41 @@
using namespace rfb;
-static inline rdr::U32 readOpaque24A(rdr::InStream* is)
+static inline uint32_t readOpaque24A(rdr::InStream* is)
{
- rdr::U32 r=0;
- ((rdr::U8*)&r)[0] = is->readU8();
- ((rdr::U8*)&r)[1] = is->readU8();
- ((rdr::U8*)&r)[2] = is->readU8();
+ uint32_t r=0;
+ ((uint8_t*)&r)[0] = is->readU8();
+ ((uint8_t*)&r)[1] = is->readU8();
+ ((uint8_t*)&r)[2] = is->readU8();
return r;
}
-static inline rdr::U32 readOpaque24B(rdr::InStream* is)
+static inline uint32_t readOpaque24B(rdr::InStream* is)
{
- rdr::U32 r=0;
- ((rdr::U8*)&r)[1] = is->readU8();
- ((rdr::U8*)&r)[2] = is->readU8();
- ((rdr::U8*)&r)[3] = is->readU8();
+ uint32_t r=0;
+ ((uint8_t*)&r)[1] = is->readU8();
+ ((uint8_t*)&r)[2] = is->readU8();
+ ((uint8_t*)&r)[3] = is->readU8();
return r;
}
+template<class T>
+static inline T readPixel(rdr::ZlibInStream* zis)
+{
+ if (sizeof(T) == 1)
+ return zis->readOpaque8();
+ if (sizeof(T) == 2)
+ return zis->readOpaque16();
+ if (sizeof(T) == 4)
+ return zis->readOpaque32();
+}
+
static inline void zlibHasData(rdr::ZlibInStream* zis, size_t length)
{
if (!zis->hasData(length))
throw Exception("ZRLE decode error");
}
-#define BPP 8
-#include <rfb/zrleDecode.h>
-#undef BPP
-#define BPP 16
-#include <rfb/zrleDecode.h>
-#undef BPP
-#define BPP 32
-#include <rfb/zrleDecode.h>
-#define CPIXEL 24A
-#include <rfb/zrleDecode.h>
-#undef CPIXEL
-#define CPIXEL 24B
-#include <rfb/zrleDecode.h>
-#undef CPIXEL
-#undef BPP
-
ZRLEDecoder::ZRLEDecoder() : Decoder(DecoderOrdered)
{
}
@@ -84,7 +79,7 @@ bool ZRLEDecoder::readRect(const Rect& /*r*/, rdr::InStream* is,
const ServerParams& /*server*/,
rdr::OutStream* os)
{
- rdr::U32 len;
+ uint32_t len;
if (!is->hasData(4))
return false;
@@ -111,32 +106,185 @@ void ZRLEDecoder::decodeRect(const Rect& r, const void* buffer,
rdr::MemInStream is(buffer, buflen);
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;
- case 32:
- {
- if (pf.depth <= 24) {
- Pixel maxPixel = pf.pixelFromRGB((rdr::U16)-1, (rdr::U16)-1, (rdr::U16)-1);
- bool fitsInLS3Bytes = maxPixel < (1<<24);
- bool fitsInMS3Bytes = (maxPixel & 0xff) == 0;
-
- if ((fitsInLS3Bytes && pf.isLittleEndian()) ||
- (fitsInMS3Bytes && pf.isBigEndian()))
- {
- zrleDecode24A(r, &is, &zis, pf, pb);
- break;
+ case 8: zrleDecode<uint8_t>(r, &is, &zis, pf, pb); break;
+ case 16: zrleDecode<uint16_t>(r, &is, &zis, pf, pb); break;
+ case 32: zrleDecode<uint32_t>(r, &is, &zis, pf, pb); break;
+ }
+}
+
+template<class T>
+void ZRLEDecoder::zrleDecode(const Rect& r, rdr::InStream* is,
+ rdr::ZlibInStream* zis,
+ const PixelFormat& pf,
+ ModifiablePixelBuffer* pb)
+{
+ int length = is->readU32();
+ zis->setUnderlying(is, length);
+ Rect t;
+ T buf[64 * 64];
+
+ Pixel maxPixel = pf.pixelFromRGB((uint16_t)-1, (uint16_t)-1, (uint16_t)-1);
+ bool fitsInLS3Bytes = maxPixel < (1<<24);
+ bool fitsInMS3Bytes = (maxPixel & 0xff) == 0;
+ bool isLowCPixel = (sizeof(T) == 4) &&
+ ((fitsInLS3Bytes && pf.isLittleEndian()) ||
+ (fitsInMS3Bytes && pf.isBigEndian()));
+ bool isHighCPixel = (sizeof(T) == 4) &&
+ ((fitsInLS3Bytes && pf.isBigEndian()) ||
+ (fitsInMS3Bytes && pf.isLittleEndian()));
+
+ for (t.tl.y = r.tl.y; t.tl.y < r.br.y; t.tl.y += 64) {
+
+ t.br.y = __rfbmin(r.br.y, t.tl.y + 64);
+
+ for (t.tl.x = r.tl.x; t.tl.x < r.br.x; t.tl.x += 64) {
+
+ t.br.x = __rfbmin(r.br.x, t.tl.x + 64);
+
+ zlibHasData(zis, 1);
+ int mode = zis->readU8();
+ bool rle = mode & 128;
+ int palSize = mode & 127;
+ T palette[128];
+
+ if (isLowCPixel || isHighCPixel)
+ zlibHasData(zis, 3 * palSize);
+ else
+ zlibHasData(zis, sizeof(T) * palSize);
+
+ for (int i = 0; i < palSize; i++) {
+ if (isLowCPixel)
+ palette[i] = readOpaque24A(zis);
+ else if (isHighCPixel)
+ palette[i] = readOpaque24B(zis);
+ else
+ palette[i] = readPixel<T>(zis);
+ }
+
+ if (palSize == 1) {
+ T pix = palette[0];
+ pb->fillRect(pf, t, &pix);
+ continue;
+ }
+
+ if (!rle) {
+ if (palSize == 0) {
+
+ // raw
+
+ if (isLowCPixel || isHighCPixel)
+ zlibHasData(zis, 3 * t.area());
+ else
+ zlibHasData(zis, sizeof(T) * t.area());
+
+ if (isLowCPixel || isHighCPixel) {
+ for (T* ptr = buf; ptr < buf+t.area(); ptr++) {
+ if (isLowCPixel)
+ *ptr = readOpaque24A(zis);
+ else
+ *ptr = readOpaque24B(zis);
+ }
+ } else {
+ zis->readBytes(buf, t.area() * sizeof(T));
+ }
+
+ } else {
+
+ // packed pixels
+ int bppp = ((palSize > 16) ? 8 :
+ ((palSize > 4) ? 4 : ((palSize > 2) ? 2 : 1)));
+
+ T* ptr = buf;
+
+ for (int i = 0; i < t.height(); i++) {
+ T* eol = ptr + t.width();
+ uint8_t byte = 0;
+ uint8_t nbits = 0;
+
+ while (ptr < eol) {
+ if (nbits == 0) {
+ zlibHasData(zis, 1);
+ byte = zis->readU8();
+ nbits = 8;
+ }
+ nbits -= bppp;
+ uint8_t index = (byte >> nbits) & ((1 << bppp) - 1) & 127;
+ *ptr++ = palette[index];
+ }
+ }
}
- if ((fitsInLS3Bytes && pf.isBigEndian()) ||
- (fitsInMS3Bytes && pf.isLittleEndian()))
- {
- zrleDecode24B(r, &is, &zis, pf, pb);
- break;
+ } else {
+
+ if (palSize == 0) {
+
+ // plain RLE
+
+ T* ptr = buf;
+ T* end = ptr + t.area();
+ while (ptr < end) {
+ T pix;
+ if (isLowCPixel || isHighCPixel)
+ zlibHasData(zis, 3);
+ else
+ zlibHasData(zis, sizeof(T));
+ if (isLowCPixel)
+ pix = readOpaque24A(zis);
+ else if (isHighCPixel)
+ pix = readOpaque24B(zis);
+ else
+ pix = readPixel<T>(zis);
+ int len = 1;
+ int b;
+ do {
+ zlibHasData(zis, 1);
+ b = zis->readU8();
+ len += b;
+ } while (b == 255);
+
+ if (end - ptr < len) {
+ throw Exception ("ZRLE decode error");
+ }
+
+ while (len-- > 0) *ptr++ = pix;
+
+ }
+ } else {
+
+ // palette RLE
+
+ T* ptr = buf;
+ T* end = ptr + t.area();
+ while (ptr < end) {
+ zlibHasData(zis, 1);
+ int index = zis->readU8();
+ int len = 1;
+ if (index & 128) {
+ int b;
+ do {
+ zlibHasData(zis, 1);
+ b = zis->readU8();
+ len += b;
+ } while (b == 255);
+
+ if (end - ptr < len) {
+ throw Exception ("ZRLE decode error");
+ }
+ }
+
+ index &= 127;
+
+ T pix = palette[index];
+
+ while (len-- > 0) *ptr++ = pix;
+ }
}
}
- zrleDecode32(r, &is, &zis, pf, pb);
- break;
+ pb->imageRect(pf, t, buf);
}
}
+
+ zis->flushUnderlying();
+ zis->setUnderlying(NULL, 0);
}
diff --git a/common/rfb/ZRLEDecoder.h b/common/rfb/ZRLEDecoder.h
index 115f8fb8..3885124a 100644
--- a/common/rfb/ZRLEDecoder.h
+++ b/common/rfb/ZRLEDecoder.h
@@ -1,4 +1,5 @@
/* Copyright (C) 2002-2005 RealVNC Ltd. All Rights Reserved.
+ * Copyright 2014-2022 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
@@ -23,6 +24,8 @@
namespace rfb {
+ class PixelFormat;
+
class ZRLEDecoder : public Decoder {
public:
ZRLEDecoder();
@@ -32,6 +35,13 @@ namespace rfb {
virtual void decodeRect(const Rect& r, const void* buffer,
size_t buflen, const ServerParams& server,
ModifiablePixelBuffer* pb);
+
+ private:
+ template<class T>
+ void zrleDecode(const Rect& r, rdr::InStream* is,
+ rdr::ZlibInStream* zis,
+ const PixelFormat& pf, ModifiablePixelBuffer* pb);
+
private:
rdr::ZlibInStream zis;
};
diff --git a/common/rfb/ZRLEEncoder.cxx b/common/rfb/ZRLEEncoder.cxx
index 7d985401..4e25d49f 100644
--- a/common/rfb/ZRLEEncoder.cxx
+++ b/common/rfb/ZRLEEncoder.cxx
@@ -1,5 +1,5 @@
/* Copyright (C) 2002-2005 RealVNC Ltd. All Rights Reserved.
- * Copyright 2014 Pierre Ossman for Cendio AB
+ * Copyright 2014-2022 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
@@ -96,7 +96,7 @@ void ZRLEEncoder::writeRect(const PixelBuffer* pb, const Palette& palette)
void ZRLEEncoder::writeSolidRect(int width, int height,
const PixelFormat& pf,
- const rdr::U8* colour)
+ const uint8_t* colour)
{
int tiles;
@@ -122,7 +122,7 @@ void ZRLEEncoder::writeSolidRect(int width, int height,
void ZRLEEncoder::writePaletteTile(const Rect& tile, const PixelBuffer* pb,
const Palette& palette)
{
- const rdr::U8* buffer;
+ const uint8_t* buffer;
int stride;
buffer = pb->getBuffer(tile, &stride);
@@ -130,17 +130,17 @@ void ZRLEEncoder::writePaletteTile(const Rect& tile, const PixelBuffer* pb,
switch (pb->getPF().bpp) {
case 32:
writePaletteTile(tile.width(), tile.height(),
- (rdr::U32*)buffer, stride,
+ (uint32_t*)buffer, stride,
pb->getPF(), palette);
break;
case 16:
writePaletteTile(tile.width(), tile.height(),
- (rdr::U16*)buffer, stride,
+ (uint16_t*)buffer, stride,
pb->getPF(), palette);
break;
default:
writePaletteTile(tile.width(), tile.height(),
- (rdr::U8*)buffer, stride,
+ (uint8_t*)buffer, stride,
pb->getPF(), palette);
}
}
@@ -148,7 +148,7 @@ void ZRLEEncoder::writePaletteTile(const Rect& tile, const PixelBuffer* pb,
void ZRLEEncoder::writePaletteRLETile(const Rect& tile, const PixelBuffer* pb,
const Palette& palette)
{
- const rdr::U8* buffer;
+ const uint8_t* buffer;
int stride;
buffer = pb->getBuffer(tile, &stride);
@@ -156,24 +156,24 @@ void ZRLEEncoder::writePaletteRLETile(const Rect& tile, const PixelBuffer* pb,
switch (pb->getPF().bpp) {
case 32:
writePaletteRLETile(tile.width(), tile.height(),
- (rdr::U32*)buffer, stride,
+ (uint32_t*)buffer, stride,
pb->getPF(), palette);
break;
case 16:
writePaletteRLETile(tile.width(), tile.height(),
- (rdr::U16*)buffer, stride,
+ (uint16_t*)buffer, stride,
pb->getPF(), palette);
break;
default:
writePaletteRLETile(tile.width(), tile.height(),
- (rdr::U8*)buffer, stride,
+ (uint8_t*)buffer, stride,
pb->getPF(), palette);
}
}
void ZRLEEncoder::writeRawTile(const Rect& tile, const PixelBuffer* pb)
{
- const rdr::U8* buffer;
+ const uint8_t* buffer;
int stride;
int w, h, stride_bytes;
@@ -193,22 +193,22 @@ void ZRLEEncoder::writeRawTile(const Rect& tile, const PixelBuffer* pb)
void ZRLEEncoder::writePalette(const PixelFormat& pf, const Palette& palette)
{
- rdr::U8 buffer[256*4];
+ uint8_t buffer[256*4];
int i;
if (pf.bpp == 32) {
- rdr::U32* buf;
- buf = (rdr::U32*)buffer;
+ uint32_t* buf;
+ buf = (uint32_t*)buffer;
for (i = 0;i < palette.size();i++)
*buf++ = palette.getColour(i);
} else if (pf.bpp == 16) {
- rdr::U16* buf;
- buf = (rdr::U16*)buffer;
+ uint16_t* buf;
+ buf = (uint16_t*)buffer;
for (i = 0;i < palette.size();i++)
*buf++ = palette.getColour(i);
} else {
- rdr::U8* buf;
- buf = (rdr::U8*)buffer;
+ uint8_t* buf;
+ buf = (uint8_t*)buffer;
for (i = 0;i < palette.size();i++)
*buf++ = palette.getColour(i);
}
@@ -216,13 +216,13 @@ void ZRLEEncoder::writePalette(const PixelFormat& pf, const Palette& palette)
writePixels(buffer, pf, palette.size());
}
-void ZRLEEncoder::writePixels(const rdr::U8* buffer, const PixelFormat& pf,
+void ZRLEEncoder::writePixels(const uint8_t* buffer, const PixelFormat& pf,
unsigned int count)
{
Pixel maxPixel;
- rdr::U8 pixBuf[4];
+ uint8_t pixBuf[4];
- maxPixel = pf.pixelFromRGB((rdr::U16)-1, (rdr::U16)-1, (rdr::U16)-1);
+ maxPixel = pf.pixelFromRGB((uint16_t)-1, (uint16_t)-1, (uint16_t)-1);
pf.bufferFromPixel(pixBuf, maxPixel);
if ((pf.bpp != 32) || ((pixBuf[0] != 0) && (pixBuf[3] != 0))) {
@@ -239,16 +239,110 @@ void ZRLEEncoder::writePixels(const rdr::U8* buffer, const PixelFormat& pf,
}
}
-//
-// Including BPP-dependent implementation of the encoder.
-//
-
-#define BPP 8
-#include <rfb/ZRLEEncoderBPP.cxx>
-#undef BPP
-#define BPP 16
-#include <rfb/ZRLEEncoderBPP.cxx>
-#undef BPP
-#define BPP 32
-#include <rfb/ZRLEEncoderBPP.cxx>
-#undef BPP
+template<class T>
+void ZRLEEncoder::writePaletteTile(int width, int height,
+ const T* buffer, int stride,
+ const PixelFormat& pf,
+ const Palette& palette)
+{
+ const int bitsPerPackedPixel[] = {
+ 0, 1, 2, 2, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4
+ };
+
+ int bppp;
+ int pad;
+
+ assert(palette.size() > 1);
+ assert(palette.size() <= 16);
+
+ zos.writeU8(palette.size());
+ writePalette(pf, palette);
+
+ bppp = bitsPerPackedPixel[palette.size()-1];
+ pad = stride - width;
+
+ for (int i = 0; i < height; i++) {
+ int w;
+
+ uint8_t nbits = 0;
+ uint8_t byte = 0;
+
+ w = width;
+ while (w--) {
+ T pix = *buffer++;
+ uint8_t index = palette.lookup(pix);
+ byte = (byte << bppp) | index;
+ nbits += bppp;
+ if (nbits >= 8) {
+ zos.writeU8(byte);
+ nbits = 0;
+ }
+ }
+ if (nbits > 0) {
+ byte <<= 8 - nbits;
+ zos.writeU8(byte);
+ }
+
+ buffer += pad;
+ }
+}
+
+template<class T>
+void ZRLEEncoder::writePaletteRLETile(int width, int height,
+ const T* buffer, int stride,
+ const PixelFormat& pf,
+ const Palette& palette)
+{
+ int pad;
+
+ T prevColour;
+ int runLength;
+
+ assert(palette.size() > 1);
+ assert(palette.size() <= 127);
+
+ zos.writeU8(palette.size() | 0x80);
+ writePalette(pf, palette);
+
+ pad = stride - width;
+
+ prevColour = *buffer;
+ runLength = 0;
+
+ while (height--) {
+ int w = width;
+ while (w--) {
+ if (prevColour != *buffer) {
+ if (runLength == 1)
+ zos.writeU8(palette.lookup(prevColour));
+ else {
+ zos.writeU8(palette.lookup(prevColour) | 0x80);
+
+ while (runLength > 255) {
+ zos.writeU8(255);
+ runLength -= 255;
+ }
+ zos.writeU8(runLength - 1);
+ }
+
+ prevColour = *buffer;
+ runLength = 0;
+ }
+
+ runLength++;
+ buffer++;
+ }
+ buffer += pad;
+ }
+ if (runLength == 1)
+ zos.writeU8(palette.lookup(prevColour));
+ else {
+ zos.writeU8(palette.lookup(prevColour) | 0x80);
+
+ while (runLength > 255) {
+ zos.writeU8(255);
+ runLength -= 255;
+ }
+ zos.writeU8(runLength - 1);
+ }
+}
diff --git a/common/rfb/ZRLEEncoder.h b/common/rfb/ZRLEEncoder.h
index 37a3be2d..4cfff75d 100644
--- a/common/rfb/ZRLEEncoder.h
+++ b/common/rfb/ZRLEEncoder.h
@@ -1,5 +1,5 @@
/* Copyright (C) 2002-2005 RealVNC Ltd. All Rights Reserved.
- * Copyright 2014 Pierre Ossman for Cendio AB
+ * Copyright 2014-2022 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
@@ -35,7 +35,7 @@ namespace rfb {
virtual void writeRect(const PixelBuffer* pb, const Palette& palette);
virtual void writeSolidRect(int width, int height,
const PixelFormat& pf,
- const rdr::U8* colour);
+ const uint8_t* colour);
protected:
void writePaletteTile(const Rect& tile, const PixelBuffer* pb,
@@ -46,30 +46,18 @@ namespace rfb {
void writePalette(const PixelFormat& pf, const Palette& palette);
- void writePixels(const rdr::U8* buffer, const PixelFormat& pf,
+ void writePixels(const uint8_t* buffer, const PixelFormat& pf,
unsigned int count);
protected:
- // Preprocessor generated, optimised methods
-
- void writePaletteTile(int width, int height,
- const rdr::U8* buffer, int stride,
- const PixelFormat& pf, const Palette& palette);
- void writePaletteTile(int width, int height,
- const rdr::U16* buffer, int stride,
- const PixelFormat& pf, const Palette& palette);
+ // Templated, optimised methods
+ template<class T>
void writePaletteTile(int width, int height,
- const rdr::U32* buffer, int stride,
+ const T* buffer, int stride,
const PixelFormat& pf, const Palette& palette);
-
- void writePaletteRLETile(int width, int height,
- const rdr::U8* buffer, int stride,
- const PixelFormat& pf, const Palette& palette);
- void writePaletteRLETile(int width, int height,
- const rdr::U16* buffer, int stride,
- const PixelFormat& pf, const Palette& palette);
+ template<class T>
void writePaletteRLETile(int width, int height,
- const rdr::U32* buffer, int stride,
+ const T* buffer, int stride,
const PixelFormat& pf, const Palette& palette);
protected:
diff --git a/common/rfb/ZRLEEncoderBPP.cxx b/common/rfb/ZRLEEncoderBPP.cxx
deleted file mode 100644
index 90f395b3..00000000
--- a/common/rfb/ZRLEEncoderBPP.cxx
+++ /dev/null
@@ -1,128 +0,0 @@
-/* Copyright (C) 2002-2005 RealVNC Ltd. All Rights Reserved.
- *
- * 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.
- */
-
-#define CONCAT2(a,b) a##b
-#define CONCAT2E(a,b) CONCAT2(a,b)
-
-#define UBPP CONCAT2E(U,BPP)
-
-void ZRLEEncoder::writePaletteTile(int width, int height,
- const rdr::UBPP* buffer, int stride,
- const PixelFormat& pf,
- const Palette& palette)
-{
- const int bitsPerPackedPixel[] = {
- 0, 1, 2, 2, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4
- };
-
- int bppp;
- int pad;
-
- assert(palette.size() > 1);
- assert(palette.size() <= 16);
-
- zos.writeU8(palette.size());
- writePalette(pf, palette);
-
- bppp = bitsPerPackedPixel[palette.size()-1];
- pad = stride - width;
-
- for (int i = 0; i < height; i++) {
- int w;
-
- rdr::U8 nbits = 0;
- rdr::U8 byte = 0;
-
- w = width;
- while (w--) {
- rdr::UBPP pix = *buffer++;
- rdr::U8 index = palette.lookup(pix);
- byte = (byte << bppp) | index;
- nbits += bppp;
- if (nbits >= 8) {
- zos.writeU8(byte);
- nbits = 0;
- }
- }
- if (nbits > 0) {
- byte <<= 8 - nbits;
- zos.writeU8(byte);
- }
-
- buffer += pad;
- }
-}
-
-void ZRLEEncoder::writePaletteRLETile(int width, int height,
- const rdr::UBPP* buffer, int stride,
- const PixelFormat& pf,
- const Palette& palette)
-{
- int pad;
-
- rdr::UBPP prevColour;
- int runLength;
-
- assert(palette.size() > 1);
- assert(palette.size() <= 127);
-
- zos.writeU8(palette.size() | 0x80);
- writePalette(pf, palette);
-
- pad = stride - width;
-
- prevColour = *buffer;
- runLength = 0;
-
- while (height--) {
- int w = width;
- while (w--) {
- if (prevColour != *buffer) {
- if (runLength == 1)
- zos.writeU8(palette.lookup(prevColour));
- else {
- zos.writeU8(palette.lookup(prevColour) | 0x80);
-
- while (runLength > 255) {
- zos.writeU8(255);
- runLength -= 255;
- }
- zos.writeU8(runLength - 1);
- }
-
- prevColour = *buffer;
- runLength = 0;
- }
-
- runLength++;
- buffer++;
- }
- buffer += pad;
- }
- if (runLength == 1)
- zos.writeU8(palette.lookup(prevColour));
- else {
- zos.writeU8(palette.lookup(prevColour) | 0x80);
-
- while (runLength > 255) {
- zos.writeU8(255);
- runLength -= 255;
- }
- zos.writeU8(runLength - 1);
- }
-}
diff --git a/common/rfb/encodings.cxx b/common/rfb/encodings.cxx
index b33dc6df..4acb569e 100644
--- a/common/rfb/encodings.cxx
+++ b/common/rfb/encodings.cxx
@@ -22,7 +22,6 @@
#include <string.h>
#include <rfb/encodings.h>
-#include <rfb/util.h>
int rfb::encodingNum(const char* name)
{
diff --git a/common/rfb/fenceTypes.h b/common/rfb/fenceTypes.h
index 41778602..fa507472 100644
--- a/common/rfb/fenceTypes.h
+++ b/common/rfb/fenceTypes.h
@@ -18,16 +18,16 @@
#ifndef __RFB_FENCETYPES_H__
#define __RFB_FENCETYPES_H__
-#include <rdr/types.h>
+#include <stdint.h>
namespace rfb {
- const rdr::U32 fenceFlagBlockBefore = 1<<0;
- const rdr::U32 fenceFlagBlockAfter = 1<<1;
- const rdr::U32 fenceFlagSyncNext = 1<<2;
+ const uint32_t fenceFlagBlockBefore = 1<<0;
+ const uint32_t fenceFlagBlockAfter = 1<<1;
+ const uint32_t fenceFlagSyncNext = 1<<2;
- const rdr::U32 fenceFlagRequest = 1<<31;
+ const uint32_t fenceFlagRequest = 1<<31;
- const rdr::U32 fenceFlagsSupported = (fenceFlagBlockBefore |
+ const uint32_t fenceFlagsSupported = (fenceFlagBlockBefore |
fenceFlagBlockAfter |
fenceFlagSyncNext |
fenceFlagRequest);
diff --git a/common/rfb/hextileDecode.h b/common/rfb/hextileDecode.h
deleted file mode 100644
index 402cd031..00000000
--- a/common/rfb/hextileDecode.h
+++ /dev/null
@@ -1,111 +0,0 @@
-/* Copyright (C) 2002-2005 RealVNC Ltd. All Rights Reserved.
- *
- * 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.
- */
-//
-// Hextile decoding function.
-//
-// This file is #included after having set the following macro:
-// BPP - 8, 16 or 32
-
-#include <rdr/InStream.h>
-#include <rfb/Exception.h>
-#include <rfb/hextileConstants.h>
-
-namespace rfb {
-
-// CONCAT2E concatenates its arguments, expanding them if they are macros
-
-#ifndef CONCAT2E
-#define CONCAT2(a,b) a##b
-#define CONCAT2E(a,b) CONCAT2(a,b)
-#endif
-
-#define PIXEL_T rdr::CONCAT2E(U,BPP)
-#define READ_PIXEL CONCAT2E(readOpaque,BPP)
-#define HEXTILE_DECODE CONCAT2E(hextileDecode,BPP)
-
-static void HEXTILE_DECODE (const Rect& r, rdr::InStream* is,
- const PixelFormat& pf,
- ModifiablePixelBuffer* pb)
-{
- Rect t;
- PIXEL_T bg = 0;
- PIXEL_T fg = 0;
- PIXEL_T buf[16 * 16];
-
- for (t.tl.y = r.tl.y; t.tl.y < r.br.y; t.tl.y += 16) {
-
- t.br.y = __rfbmin(r.br.y, t.tl.y + 16);
-
- for (t.tl.x = r.tl.x; t.tl.x < r.br.x; t.tl.x += 16) {
-
- t.br.x = __rfbmin(r.br.x, t.tl.x + 16);
-
- int tileType = is->readU8();
-
- if (tileType & hextileRaw) {
- is->readBytes(buf, t.area() * (BPP/8));
- pb->imageRect(pf, t, buf);
- continue;
- }
-
- if (tileType & hextileBgSpecified)
- bg = is->READ_PIXEL();
-
- int len = t.area();
- PIXEL_T* ptr = buf;
- while (len-- > 0) *ptr++ = bg;
-
- if (tileType & hextileFgSpecified)
- fg = is->READ_PIXEL();
-
- if (tileType & hextileAnySubrects) {
- int nSubrects = is->readU8();
-
- for (int i = 0; i < nSubrects; i++) {
-
- if (tileType & hextileSubrectsColoured)
- fg = is->READ_PIXEL();
-
- int xy = is->readU8();
- int wh = is->readU8();
-
- int x = ((xy >> 4) & 15);
- int y = (xy & 15);
- int w = ((wh >> 4) & 15) + 1;
- int h = (wh & 15) + 1;
- if (x + w > 16 || y + h > 16) {
- throw rfb::Exception("HEXTILE_DECODE: Hextile out of bounds");
- }
- PIXEL_T* ptr = buf + y * t.width() + x;
- int rowAdd = t.width() - w;
- while (h-- > 0) {
- int len = w;
- while (len-- > 0) *ptr++ = fg;
- ptr += rowAdd;
- }
- }
- }
- pb->imageRect(pf, t, buf);
- }
- }
-}
-
-#undef PIXEL_T
-#undef READ_PIXEL
-#undef HEXTILE_DECODE
-}
diff --git a/common/rfb/hextileEncode.h b/common/rfb/hextileEncode.h
deleted file mode 100644
index aa5926cc..00000000
--- a/common/rfb/hextileEncode.h
+++ /dev/null
@@ -1,223 +0,0 @@
-/* Copyright (C) 2002-2005 RealVNC Ltd. All Rights Reserved.
- * Copyright (C) 2005 Constantin Kaplinsky. All Rights Reserved.
- *
- * 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.
- */
-//
-// Hextile encoding function.
-//
-// This file is #included after having set the following macro:
-// BPP - 8, 16 or 32
-
-#include <rdr/OutStream.h>
-#include <rfb/hextileConstants.h>
-
-namespace rfb {
-
-// CONCAT2E concatenates its arguments, expanding them if they are macros
-
-#ifndef CONCAT2E
-#define CONCAT2(a,b) a##b
-#define CONCAT2E(a,b) CONCAT2(a,b)
-#endif
-
-#define PIXEL_T rdr::CONCAT2E(U,BPP)
-#define WRITE_PIXEL CONCAT2E(writeOpaque,BPP)
-#define HEXTILE_ENCODE CONCAT2E(hextileEncode,BPP)
-#define HEXTILE_ENCODE_TILE CONCAT2E(hextileEncodeTile,BPP)
-#define TEST_TILE_TYPE CONCAT2E(hextileTestTileType,BPP)
-
-int TEST_TILE_TYPE (PIXEL_T* data, int w, int h, PIXEL_T* bg, PIXEL_T* fg);
-int HEXTILE_ENCODE_TILE (PIXEL_T* data, int w, int h, int tileType,
- rdr::U8* encoded, PIXEL_T bg);
-
-void HEXTILE_ENCODE(rdr::OutStream* os, const PixelBuffer* pb)
-{
- Rect t;
- PIXEL_T buf[256];
- PIXEL_T oldBg = 0, oldFg = 0;
- bool oldBgValid = false;
- bool oldFgValid = false;
- rdr::U8 encoded[256*(BPP/8)];
-
- for (t.tl.y = 0; t.tl.y < pb->height(); t.tl.y += 16) {
-
- t.br.y = __rfbmin(pb->height(), t.tl.y + 16);
-
- for (t.tl.x = 0; t.tl.x < pb->width(); t.tl.x += 16) {
-
- t.br.x = __rfbmin(pb->width(), t.tl.x + 16);
-
- pb->getImage(buf, t);
-
- PIXEL_T bg = 0, fg = 0;
- int tileType = TEST_TILE_TYPE(buf, t.width(), t.height(), &bg, &fg);
-
- if (!oldBgValid || oldBg != bg) {
- tileType |= hextileBgSpecified;
- oldBg = bg;
- oldBgValid = true;
- }
-
- int encodedLen = 0;
-
- if (tileType & hextileAnySubrects) {
-
- if (tileType & hextileSubrectsColoured) {
- oldFgValid = false;
- } else {
- if (!oldFgValid || oldFg != fg) {
- tileType |= hextileFgSpecified;
- oldFg = fg;
- oldFgValid = true;
- }
- }
-
- encodedLen = HEXTILE_ENCODE_TILE(buf, t.width(), t.height(), tileType,
- encoded, bg);
-
- if (encodedLen < 0) {
- pb->getImage(buf, t);
- os->writeU8(hextileRaw);
- os->writeBytes(buf, t.width() * t.height() * (BPP/8));
- oldBgValid = oldFgValid = false;
- continue;
- }
- }
-
- os->writeU8(tileType);
- if (tileType & hextileBgSpecified) os->WRITE_PIXEL(bg);
- if (tileType & hextileFgSpecified) os->WRITE_PIXEL(fg);
- if (tileType & hextileAnySubrects) os->writeBytes(encoded, encodedLen);
- }
- }
-}
-
-
-int HEXTILE_ENCODE_TILE (PIXEL_T* data, int w, int h, int tileType,
- rdr::U8* encoded, PIXEL_T bg)
-{
- rdr::U8* nSubrectsPtr = encoded;
- *nSubrectsPtr = 0;
- encoded++;
-
- for (int y = 0; y < h; y++)
- {
- int x = 0;
- while (x < w) {
- if (*data == bg) {
- x++;
- data++;
- continue;
- }
-
- // Find horizontal subrect first
- PIXEL_T* ptr = data+1;
- PIXEL_T* eol = data+w-x;
- while (ptr < eol && *ptr == *data) ptr++;
- int sw = ptr - data;
-
- ptr = data + w;
- int sh = 1;
- while (sh < h-y) {
- eol = ptr + sw;
- while (ptr < eol)
- if (*ptr++ != *data) goto endOfSubrect;
- ptr += w - sw;
- sh++;
- }
- endOfSubrect:
-
- (*nSubrectsPtr)++;
-
- if (tileType & hextileSubrectsColoured) {
- if (encoded - nSubrectsPtr + (BPP/8) > w*h*(BPP/8)) return -1;
-#if (BPP == 8)
- *encoded++ = *data;
-#elif (BPP == 16)
- *encoded++ = ((rdr::U8*)data)[0];
- *encoded++ = ((rdr::U8*)data)[1];
-#elif (BPP == 32)
- *encoded++ = ((rdr::U8*)data)[0];
- *encoded++ = ((rdr::U8*)data)[1];
- *encoded++ = ((rdr::U8*)data)[2];
- *encoded++ = ((rdr::U8*)data)[3];
-#endif
- }
-
- if (encoded - nSubrectsPtr + 2 > w*h*(BPP/8)) return -1;
- *encoded++ = (x << 4) | y;
- *encoded++ = ((sw-1) << 4) | (sh-1);
-
- ptr = data+w;
- PIXEL_T* eor = data+w*sh;
- while (ptr < eor) {
- eol = ptr + sw;
- while (ptr < eol) *ptr++ = bg;
- ptr += w - sw;
- }
- x += sw;
- data += sw;
- }
- }
- return encoded - nSubrectsPtr;
-}
-
-
-int TEST_TILE_TYPE (PIXEL_T* data, int w, int h, PIXEL_T* bg, PIXEL_T* fg)
-{
- PIXEL_T pix1 = *data;
- PIXEL_T* end = data + w * h;
-
- PIXEL_T* ptr = data + 1;
- while (ptr < end && *ptr == pix1)
- ptr++;
-
- if (ptr == end) {
- *bg = pix1;
- return 0; // solid-color tile
- }
-
- int count1 = ptr - data;
- int count2 = 1;
- PIXEL_T pix2 = *ptr++;
- int tileType = hextileAnySubrects;
-
- for (; ptr < end; ptr++) {
- if (*ptr == pix1) {
- count1++;
- } else if (*ptr == pix2) {
- count2++;
- } else {
- tileType |= hextileSubrectsColoured;
- break;
- }
- }
-
- if (count1 >= count2) {
- *bg = pix1; *fg = pix2;
- } else {
- *bg = pix2; *fg = pix1;
- }
- return tileType;
-}
-
-#undef PIXEL_T
-#undef WRITE_PIXEL
-#undef HEXTILE_ENCODE
-#undef HEXTILE_ENCODE_TILE
-#undef TEST_TILE_TYPE
-}
diff --git a/common/rfb/hextileEncodeBetter.h b/common/rfb/hextileEncodeBetter.h
deleted file mode 100644
index bc9dcaca..00000000
--- a/common/rfb/hextileEncodeBetter.h
+++ /dev/null
@@ -1,346 +0,0 @@
-/* Copyright (C) 2002-2003 RealVNC Ltd. All Rights Reserved.
- * Copyright (C) 2005 Constantin Kaplinsky. All Rights Reserved.
- *
- * 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.
- */
-//
-// Hextile encoding function.
-//
-// This file is #included after having set the following macro:
-// BPP - 8, 16 or 32
-
-#include <rdr/OutStream.h>
-#include <rfb/hextileConstants.h>
-#include <rfb/Palette.h>
-
-#include <assert.h>
-
-namespace rfb {
-
-// CONCAT2E concatenates its arguments, expanding them if they are macros
-
-#ifndef CONCAT2E
-#define CONCAT2(a,b) a##b
-#define CONCAT2E(a,b) CONCAT2(a,b)
-#endif
-
-#define PIXEL_T rdr::CONCAT2E(U,BPP)
-#define WRITE_PIXEL CONCAT2E(writeOpaque,BPP)
-#define HEXTILE_TILE CONCAT2E(HextileTile,BPP)
-#define HEXTILE_ENCODE CONCAT2E(hextileEncodeBetter,BPP)
-
-//
-// This class analyzes a separate tile and encodes its subrectangles.
-//
-
-class HEXTILE_TILE {
-
- public:
-
- HEXTILE_TILE ();
-
- //
- // Initialize existing object instance with new tile data.
- //
- void newTile(const PIXEL_T *src, int w, int h);
-
- //
- // Flags can include: hextileRaw, hextileAnySubrects and
- // hextileSubrectsColoured. Note that if hextileRaw is set, other
- // flags make no sense. Also, hextileSubrectsColoured is meaningful
- // only when hextileAnySubrects is set as well.
- //
- int getFlags() const { return m_flags; }
-
- //
- // Returns the size of encoded subrects data, including subrect count.
- // The size is zero if flags do not include hextileAnySubrects.
- //
- int getSize() const { return m_size; }
-
- //
- // Return optimal background.
- //
- int getBackground() const { return m_background; }
-
- //
- // Return foreground if flags include hextileSubrectsColoured.
- //
- int getForeground() const { return m_foreground; }
-
- //
- // Encode subrects. This function may be called only if
- // hextileAnySubrects bit is set in flags. The buffer size should be
- // big enough to store at least the number of bytes returned by the
- // getSize() method.
- //
- void encode(rdr::U8* dst) const;
-
- protected:
-
- //
- // Analyze the tile pixels, fill in all the data fields.
- //
- void analyze();
-
- const PIXEL_T *m_tile;
- int m_width;
- int m_height;
-
- int m_size;
- int m_flags;
- PIXEL_T m_background;
- PIXEL_T m_foreground;
-
- int m_numSubrects;
- rdr::U8 m_coords[256 * 2];
- PIXEL_T m_colors[256];
-
- private:
-
- bool m_processed[16][16];
- Palette m_pal;
-};
-
-HEXTILE_TILE::HEXTILE_TILE()
- : m_tile(NULL), m_width(0), m_height(0),
- m_size(0), m_flags(0), m_background(0), m_foreground(0),
- m_numSubrects(0)
-{
-}
-
-void HEXTILE_TILE::newTile(const PIXEL_T *src, int w, int h)
-{
- m_tile = src;
- m_width = w;
- m_height = h;
-
- analyze();
-}
-
-void HEXTILE_TILE::analyze()
-{
- assert(m_tile && m_width && m_height);
-
- const PIXEL_T *ptr = m_tile;
- const PIXEL_T *end = &m_tile[m_width * m_height];
- PIXEL_T color = *ptr++;
- while (ptr != end && *ptr == color)
- ptr++;
-
- // Handle solid tile
- if (ptr == end) {
- m_background = m_tile[0];
- m_flags = 0;
- m_size = 0;
- return;
- }
-
- // Compute number of complete rows of the same color, at the top
- int y = (ptr - m_tile) / m_width;
-
- PIXEL_T *colorsPtr = m_colors;
- rdr::U8 *coordsPtr = m_coords;
- m_pal.clear();
- m_numSubrects = 0;
-
- // Have we found the first subrect already?
- if (y > 0) {
- *colorsPtr++ = color;
- *coordsPtr++ = 0;
- *coordsPtr++ = (rdr::U8)(((m_width - 1) << 4) | ((y - 1) & 0x0F));
- m_pal.insert(color, 1);
- m_numSubrects++;
- }
-
- memset(m_processed, 0, 16 * 16 * sizeof(bool));
-
- int x, sx, sy, sw, sh, max_x;
-
- for (; y < m_height; y++) {
- for (x = 0; x < m_width; x++) {
- // Skip pixels that were processed earlier
- if (m_processed[y][x]) {
- continue;
- }
- // Determine dimensions of the horizontal subrect
- color = m_tile[y * m_width + x];
- for (sx = x + 1; sx < m_width; sx++) {
- if (m_tile[y * m_width + sx] != color)
- break;
- }
- sw = sx - x;
- max_x = sx;
- for (sy = y + 1; sy < m_height; sy++) {
- for (sx = x; sx < max_x; sx++) {
- if (m_tile[sy * m_width + sx] != color)
- goto done;
- }
- }
- done:
- sh = sy - y;
-
- // Save properties of this subrect
- *colorsPtr++ = color;
- *coordsPtr++ = (rdr::U8)((x << 4) | (y & 0x0F));
- *coordsPtr++ = (rdr::U8)(((sw - 1) << 4) | ((sh - 1) & 0x0F));
-
- if (!m_pal.insert(color, 1) || (m_pal.size() > (48 + 2 * BPP))) {
- // Handle palette overflow
- m_flags = hextileRaw;
- m_size = 0;
- return;
- }
-
- m_numSubrects++;
-
- // Mark pixels of this subrect as processed, below this row
- for (sy = y + 1; sy < y + sh; sy++) {
- for (sx = x; sx < x + sw; sx++)
- m_processed[sy][sx] = true;
- }
-
- // Skip processed pixels of this row
- x += (sw - 1);
- }
- }
-
- // Save number of colors in this tile (should be no less than 2)
- int numColors = m_pal.size();
- assert(numColors >= 2);
-
- m_background = (PIXEL_T)m_pal.getColour(0);
- m_flags = hextileAnySubrects;
- int numSubrects = m_numSubrects - m_pal.getCount(0);
-
- if (numColors == 2) {
- // Monochrome tile
- m_foreground = (PIXEL_T)m_pal.getColour(1);
- m_size = 1 + 2 * numSubrects;
- } else {
- // Colored tile
- m_flags |= hextileSubrectsColoured;
- m_size = 1 + (2 + (BPP/8)) * numSubrects;
- }
-}
-
-void HEXTILE_TILE::encode(rdr::U8 *dst) const
-{
- assert(m_numSubrects && (m_flags & hextileAnySubrects));
-
- // Zero subrects counter
- rdr::U8 *numSubrectsPtr = dst;
- *dst++ = 0;
-
- for (int i = 0; i < m_numSubrects; i++) {
- if (m_colors[i] == m_background)
- continue;
-
- if (m_flags & hextileSubrectsColoured) {
-#if (BPP == 8)
- *dst++ = m_colors[i];
-#elif (BPP == 16)
- *dst++ = ((rdr::U8*)&m_colors[i])[0];
- *dst++ = ((rdr::U8*)&m_colors[i])[1];
-#elif (BPP == 32)
- *dst++ = ((rdr::U8*)&m_colors[i])[0];
- *dst++ = ((rdr::U8*)&m_colors[i])[1];
- *dst++ = ((rdr::U8*)&m_colors[i])[2];
- *dst++ = ((rdr::U8*)&m_colors[i])[3];
-#endif
- }
- *dst++ = m_coords[i * 2];
- *dst++ = m_coords[i * 2 + 1];
-
- (*numSubrectsPtr)++;
- }
-
- assert(dst - numSubrectsPtr == m_size);
-}
-
-//
-// Main encoding function.
-//
-
-void HEXTILE_ENCODE(rdr::OutStream* os, const PixelBuffer* pb)
-{
- Rect t;
- PIXEL_T buf[256];
- PIXEL_T oldBg = 0, oldFg = 0;
- bool oldBgValid = false;
- bool oldFgValid = false;
- rdr::U8 encoded[256*(BPP/8)];
-
- HEXTILE_TILE tile;
-
- for (t.tl.y = 0; t.tl.y < pb->height(); t.tl.y += 16) {
-
- t.br.y = __rfbmin(pb->height(), t.tl.y + 16);
-
- for (t.tl.x = 0; t.tl.x < pb->width(); t.tl.x += 16) {
-
- t.br.x = __rfbmin(pb->width(), t.tl.x + 16);
-
- pb->getImage(buf, t);
-
- tile.newTile(buf, t.width(), t.height());
- int tileType = tile.getFlags();
- int encodedLen = tile.getSize();
-
- if ( (tileType & hextileRaw) != 0 ||
- encodedLen >= t.width() * t.height() * (BPP/8)) {
- os->writeU8(hextileRaw);
- os->writeBytes(buf, t.width() * t.height() * (BPP/8));
- oldBgValid = oldFgValid = false;
- continue;
- }
-
- PIXEL_T bg = tile.getBackground();
- PIXEL_T fg = 0;
-
- if (!oldBgValid || oldBg != bg) {
- tileType |= hextileBgSpecified;
- oldBg = bg;
- oldBgValid = true;
- }
-
- if (tileType & hextileAnySubrects) {
- if (tileType & hextileSubrectsColoured) {
- oldFgValid = false;
- } else {
- fg = tile.getForeground();
- if (!oldFgValid || oldFg != fg) {
- tileType |= hextileFgSpecified;
- oldFg = fg;
- oldFgValid = true;
- }
- }
- tile.encode(encoded);
- }
-
- os->writeU8(tileType);
- if (tileType & hextileBgSpecified) os->WRITE_PIXEL(bg);
- if (tileType & hextileFgSpecified) os->WRITE_PIXEL(fg);
- if (tileType & hextileAnySubrects) os->writeBytes(encoded, encodedLen);
- }
- }
-}
-
-#undef PIXEL_T
-#undef WRITE_PIXEL
-#undef HEXTILE_TILE
-#undef HEXTILE_ENCODE
-}
diff --git a/common/rfb/Password.cxx b/common/rfb/obfuscate.cxx
index a7aaeccc..1f785893 100644
--- a/common/rfb/Password.cxx
+++ b/common/rfb/obfuscate.cxx
@@ -1,4 +1,5 @@
/* Copyright (C) 2002-2005 RealVNC Ltd. All Rights Reserved.
+ * Copyright 2023 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
@@ -24,61 +25,45 @@
#include <config.h>
#endif
+#include <assert.h>
#include <string.h>
+
extern "C" {
#include <rfb/d3des.h>
}
-#include <rdr/types.h>
-#include <rdr/Exception.h>
-#include <rfb/Password.h>
-using namespace rfb;
+#include <rdr/Exception.h>
+#include <rfb/obfuscate.h>
static unsigned char d3desObfuscationKey[] = {23,82,107,6,35,78,88,7};
+std::vector<uint8_t> rfb::obfuscate(const char *str)
+{
+ std::vector<uint8_t> buf(8);
-PlainPasswd::PlainPasswd() {}
-
-PlainPasswd::PlainPasswd(char* pwd) : CharArray(pwd) {
-}
-
-PlainPasswd::PlainPasswd(size_t len) : CharArray(len) {
-}
-
-PlainPasswd::PlainPasswd(const ObfuscatedPasswd& obfPwd) : CharArray(9) {
- if (obfPwd.length < 8)
- throw rdr::Exception("bad obfuscated password length");
- deskey(d3desObfuscationKey, DE1);
- des((rdr::U8*)obfPwd.buf, (rdr::U8*)buf);
- buf[8] = 0;
-}
+ assert(str != NULL);
-PlainPasswd::~PlainPasswd() {
- replaceBuf(0);
-}
+ size_t l = strlen(str), i;
+ for (i=0; i<8; i++)
+ buf[i] = i<l ? str[i] : 0;
+ deskey(d3desObfuscationKey, EN0);
+ des(buf.data(), buf.data());
-void PlainPasswd::replaceBuf(char* b) {
- if (buf)
- memset(buf, 0, strlen(buf));
- CharArray::replaceBuf(b);
+ return buf;
}
+std::string rfb::deobfuscate(const uint8_t *data, size_t len)
+{
+ char buf[9];
-ObfuscatedPasswd::ObfuscatedPasswd() : length(0) {
-}
+ assert(data != NULL);
-ObfuscatedPasswd::ObfuscatedPasswd(size_t len) : CharArray(len), length(len) {
-}
+ if (len != 8)
+ throw rdr::Exception("bad obfuscated password length");
-ObfuscatedPasswd::ObfuscatedPasswd(const PlainPasswd& plainPwd) : CharArray(8), length(8) {
- size_t l = strlen(plainPwd.buf), i;
- for (i=0; i<8; i++)
- buf[i] = i<l ? plainPwd.buf[i] : 0;
- deskey(d3desObfuscationKey, EN0);
- des((rdr::U8*)buf, (rdr::U8*)buf);
-}
+ deskey(d3desObfuscationKey, DE1);
+ des((uint8_t*)data, (uint8_t*)buf);
+ buf[8] = 0;
-ObfuscatedPasswd::~ObfuscatedPasswd() {
- if (buf)
- memset(buf, 0, length);
+ return buf;
}
diff --git a/common/rfb/Pixel.h b/common/rfb/obfuscate.h
index 4e9d1644..96a90e44 100644
--- a/common/rfb/Pixel.h
+++ b/common/rfb/obfuscate.h
@@ -1,4 +1,5 @@
/* Copyright (C) 2002-2005 RealVNC Ltd. All Rights Reserved.
+ * Copyright 2023 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
@@ -15,12 +16,20 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
* USA.
*/
-#ifndef __RFB_PIXEL_H__
-#define __RFB_PIXEL_H__
-#include <rdr/types.h>
+#ifndef __RFB_OBFUSCATE_H__
+#define __RFB_OBFUSCATE_H__
+
+#include <stdint.h>
+
+#include <string>
+#include <vector>
namespace rfb {
- typedef rdr::U32 Pixel; // must be big enough to hold any pixel value
+
+ std::vector<uint8_t> obfuscate(const char *str);
+ std::string deobfuscate(const uint8_t *data, size_t len);
+
}
+
#endif
diff --git a/common/rfb/rreDecode.h b/common/rfb/rreDecode.h
deleted file mode 100644
index f9fdcfc9..00000000
--- a/common/rfb/rreDecode.h
+++ /dev/null
@@ -1,64 +0,0 @@
-/* Copyright (C) 2002-2005 RealVNC Ltd. All Rights Reserved.
- *
- * 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.
- */
-//
-// RRE decoding function.
-//
-// This file is #included after having set the following macro:
-// BPP - 8, 16 or 32
-
-#include <rdr/InStream.h>
-#include <rfb/Exception.h>
-
-namespace rfb {
-
-// CONCAT2E concatenates its arguments, expanding them if they are macros
-
-#ifndef CONCAT2E
-#define CONCAT2(a,b) a##b
-#define CONCAT2E(a,b) CONCAT2(a,b)
-#endif
-
-#define PIXEL_T rdr::CONCAT2E(U,BPP)
-#define READ_PIXEL CONCAT2E(readOpaque,BPP)
-#define RRE_DECODE CONCAT2E(rreDecode,BPP)
-
-void RRE_DECODE (const Rect& r, rdr::InStream* is,
- const PixelFormat& pf, ModifiablePixelBuffer* pb)
-{
- int nSubrects = is->readU32();
- PIXEL_T bg = is->READ_PIXEL();
- pb->fillRect(pf, r, &bg);
-
- for (int i = 0; i < nSubrects; i++) {
- PIXEL_T pix = is->READ_PIXEL();
- int x = is->readU16();
- int y = is->readU16();
- int w = is->readU16();
- int h = is->readU16();
-
- if (((x+w) > r.width()) || ((y+h) > r.height()))
- throw Exception ("RRE decode error");
-
- pb->fillRect(pf, Rect(r.tl.x+x, r.tl.y+y, r.tl.x+x+w, r.tl.y+y+h), &pix);
- }
-}
-
-#undef PIXEL_T
-#undef READ_PIXEL
-#undef RRE_DECODE
-}
diff --git a/common/rfb/rreEncode.h b/common/rfb/rreEncode.h
deleted file mode 100644
index c8bbee7a..00000000
--- a/common/rfb/rreEncode.h
+++ /dev/null
@@ -1,124 +0,0 @@
-/* Copyright (C) 2002-2005 RealVNC Ltd. All Rights Reserved.
- *
- * 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.
- */
-//
-// RRE encoding function.
-//
-// This file is #included after having set the following macro:
-// BPP - 8, 16 or 32
-//
-// The data argument to RRE_ENCODE contains the pixel data, and it writes the
-// encoded version to the given OutStream. If the encoded version exceeds w*h
-// it aborts and returns -1, otherwise it returns the number of subrectangles.
-//
-
-#include <rdr/OutStream.h>
-
-namespace rfb {
-
-// CONCAT2E concatenates its arguments, expanding them if they are macros
-
-#ifndef CONCAT2E
-#define CONCAT2(a,b) a##b
-#define CONCAT2E(a,b) CONCAT2(a,b)
-#endif
-
-#define PIXEL_T rdr::CONCAT2E(U,BPP)
-#define WRITE_PIXEL CONCAT2E(writeOpaque,BPP)
-#define RRE_ENCODE CONCAT2E(rreEncode,BPP)
-
-int RRE_ENCODE (PIXEL_T* data, int w, int h, rdr::OutStream* os, PIXEL_T bg)
-{
- os->WRITE_PIXEL(bg);
-
- int nSubrects = 0;
-
- for (int y = 0; y < h; y++)
- {
- int x = 0;
- while (x < w) {
- if (*data == bg) {
- x++;
- data++;
- continue;
- }
-
- // Find horizontal subrect first
- PIXEL_T* ptr = data+1;
- PIXEL_T* eol = data+w-x;
- while (ptr < eol && *ptr == *data) ptr++;
- int sw = ptr - data;
-
- ptr = data + w;
- int sh = 1;
- while (sh < h-y) {
- eol = ptr + sw;
- while (ptr < eol)
- if (*ptr++ != *data) goto endOfHorizSubrect;
- ptr += w - sw;
- sh++;
- }
- endOfHorizSubrect:
-
- // Find vertical subrect
- int vh;
- for (vh = sh; vh < h-y; vh++)
- if (data[vh*w] != *data) break;
-
- if (vh != sh) {
- ptr = data+1;
- int vw;
- for (vw = 1; vw < sw; vw++) {
- for (int i = 0; i < vh; i++)
- if (ptr[i*w] != *data) goto endOfVertSubrect;
- ptr++;
- }
- endOfVertSubrect:
-
- // If vertical subrect bigger than horizontal then use that.
- if (sw*sh < vw*vh) {
- sw = vw;
- sh = vh;
- }
- }
-
- nSubrects++;
- os->WRITE_PIXEL(*data);
- os->writeU16(x);
- os->writeU16(y);
- os->writeU16(sw);
- os->writeU16(sh);
-
- ptr = data+w;
- PIXEL_T* eor = data+w*sh;
- while (ptr < eor) {
- eol = ptr + sw;
- while (ptr < eol) *ptr++ = bg;
- ptr += w - sw;
- }
- x += sw;
- data += sw;
- }
- }
-
- return nSubrects;
-}
-
-#undef PIXEL_T
-#undef WRITE_PIXEL
-#undef RRE_ENCODE
-}
diff --git a/common/rfb/tightDecode.h b/common/rfb/tightDecode.h
deleted file mode 100644
index 8f77aebd..00000000
--- a/common/rfb/tightDecode.h
+++ /dev/null
@@ -1,187 +0,0 @@
-/* Copyright (C) 2000-2003 Constantin Kaplinsky. All Rights Reserved.
- * Copyright 2004-2005 Cendio AB.
- * Copyright 2009-2015 Pierre Ossman for Cendio AB
- * Copyright (C) 2011 D. R. Commander. All Rights Reserved.
- *
- * 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.
- */
-
-//
-// Tight decoding functions.
-//
-// This file is #included after having set the following macro:
-// BPP - 8, 16 or 32
-
-namespace rfb {
-
-// CONCAT2E concatenates its arguments, expanding them if they are macros
-
-#ifndef CONCAT2E
-#define CONCAT2(a,b) a##b
-#define CONCAT2E(a,b) CONCAT2(a,b)
-#endif
-
-#define PIXEL_T rdr::CONCAT2E(U,BPP)
-
-#if BPP == 32
-
-void
-TightDecoder::FilterGradient24(const rdr::U8 *inbuf,
- const PixelFormat& pf, PIXEL_T* outbuf,
- int stride, const Rect& r)
-{
- int x, y, c;
- rdr::U8 prevRow[TIGHT_MAX_WIDTH*3];
- rdr::U8 thisRow[TIGHT_MAX_WIDTH*3];
- rdr::U8 pix[3];
- int est[3];
-
- memset(prevRow, 0, sizeof(prevRow));
-
- // Set up shortcut variables
- int rectHeight = r.height();
- int rectWidth = r.width();
-
- for (y = 0; y < rectHeight; y++) {
- for (x = 0; x < rectWidth; x++) {
- /* First pixel in a row */
- if (x == 0) {
- for (c = 0; c < 3; c++) {
- pix[c] = inbuf[y*rectWidth*3+c] + prevRow[c];
- thisRow[c] = pix[c];
- }
- pf.bufferFromRGB((rdr::U8*)&outbuf[y*stride], pix, 1);
- continue;
- }
-
- for (c = 0; c < 3; c++) {
- est[c] = prevRow[x*3+c] + pix[c] - prevRow[(x-1)*3+c];
- if (est[c] > 0xff) {
- est[c] = 0xff;
- } else if (est[c] < 0) {
- est[c] = 0;
- }
- pix[c] = inbuf[(y*rectWidth+x)*3+c] + est[c];
- thisRow[x*3+c] = pix[c];
- }
- pf.bufferFromRGB((rdr::U8*)&outbuf[y*stride+x], pix, 1);
- }
-
- memcpy(prevRow, thisRow, sizeof(prevRow));
- }
-}
-
-#endif
-
-#if BPP != 8
-
-void TightDecoder::FilterGradient(const rdr::U8* inbuf,
- const PixelFormat& pf, PIXEL_T* outbuf,
- int stride, const Rect& r)
-{
- int x, y, c;
- static rdr::U8 prevRow[TIGHT_MAX_WIDTH*3];
- static rdr::U8 thisRow[TIGHT_MAX_WIDTH*3];
- rdr::U8 pix[3];
- int est[3];
-
- memset(prevRow, 0, sizeof(prevRow));
-
- // Set up shortcut variables
- int rectHeight = r.height();
- int rectWidth = r.width();
-
- for (y = 0; y < rectHeight; y++) {
- for (x = 0; x < rectWidth; x++) {
- /* First pixel in a row */
- if (x == 0) {
- pf.rgbFromBuffer(pix, &inbuf[y*rectWidth], 1);
- for (c = 0; c < 3; c++)
- pix[c] += prevRow[c];
-
- memcpy(thisRow, pix, sizeof(pix));
-
- pf.bufferFromRGB((rdr::U8*)&outbuf[y*stride], pix, 1);
-
- continue;
- }
-
- for (c = 0; c < 3; c++) {
- est[c] = prevRow[x*3+c] + pix[c] - prevRow[(x-1)*3+c];
- if (est[c] > 255) {
- est[c] = 255;
- } else if (est[c] < 0) {
- est[c] = 0;
- }
- }
-
- pf.rgbFromBuffer(pix, &inbuf[y*rectWidth+x], 1);
- for (c = 0; c < 3; c++)
- pix[c] += est[c];
-
- memcpy(&thisRow[x*3], pix, sizeof(pix));
-
- pf.bufferFromRGB((rdr::U8*)&outbuf[y*stride+x], pix, 1);
- }
-
- memcpy(prevRow, thisRow, sizeof(prevRow));
- }
-}
-
-#endif
-
-void TightDecoder::FilterPalette(const PIXEL_T* palette, int palSize,
- const rdr::U8* inbuf, PIXEL_T* outbuf,
- int stride, const Rect& r)
-{
- // Indexed color
- int x, h = r.height(), w = r.width(), b, pad = stride - w;
- PIXEL_T* ptr = outbuf;
- rdr::U8 bits;
- const rdr::U8* srcPtr = inbuf;
- if (palSize <= 2) {
- // 2-color palette
- while (h > 0) {
- for (x = 0; x < w / 8; x++) {
- bits = *srcPtr++;
- for (b = 7; b >= 0; b--) {
- *ptr++ = palette[bits >> b & 1];
- }
- }
- if (w % 8 != 0) {
- bits = *srcPtr++;
- for (b = 7; b >= 8 - w % 8; b--) {
- *ptr++ = palette[bits >> b & 1];
- }
- }
- ptr += pad;
- h--;
- }
- } else {
- // 256-color palette
- while (h > 0) {
- PIXEL_T *endOfRow = ptr + w;
- while (ptr < endOfRow) {
- *ptr++ = palette[*srcPtr++];
- }
- ptr += pad;
- h--;
- }
- }
-}
-
-#undef PIXEL_T
-}
diff --git a/common/rfb/util.cxx b/common/rfb/util.cxx
index 649eb0ba..c5c00bbd 100644
--- a/common/rfb/util.cxx
+++ b/common/rfb/util.cxx
@@ -1,5 +1,5 @@
/* Copyright (C) 2002-2005 RealVNC Ltd. All Rights Reserved.
- * Copyright 2011-2019 Pierre Ossman for Cendio AB
+ * Copyright 2011-2023 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
@@ -21,110 +21,148 @@
#include <config.h>
#endif
+#include <assert.h>
+#include <ctype.h>
#include <stdarg.h>
#include <stdio.h>
+#include <string.h>
#include <sys/time.h>
#include <rfb/util.h>
namespace rfb {
- void CharArray::format(const char *fmt, ...) {
+ std::string format(const char *fmt, ...)
+ {
va_list ap;
int len;
+ char *buf;
+ std::string out;
va_start(ap, fmt);
len = vsnprintf(NULL, 0, fmt, ap);
va_end(ap);
- delete [] buf;
-
- if (len < 0) {
- buf = new char[1];
- buf[0] = '\0';
- return;
- }
+ if (len < 0)
+ return "";
buf = new char[len+1];
va_start(ap, fmt);
vsnprintf(buf, len+1, fmt, ap);
va_end(ap);
+
+ out = buf;
+
+ delete [] buf;
+
+ return out;
}
- char* strDup(const char* s) {
- if (!s) return 0;
- int l = strlen(s);
- char* r = new char[l+1];
- memcpy(r, s, l+1);
- return r;
- };
+ std::vector<std::string> split(const char* src,
+ const char delimiter)
+ {
+ std::vector<std::string> out;
+ const char *start, *stop;
+
+ start = src;
+ do {
+ stop = strchr(start, delimiter);
+ if (stop == NULL) {
+ out.push_back(start);
+ } else {
+ out.push_back(std::string(start, stop-start));
+ start = stop + 1;
+ }
+ } while (stop != NULL);
- void strFree(char* s) {
- delete [] s;
+ return out;
}
- void strFree(wchar_t* s) {
- delete [] s;
+ static char intToHex(uint8_t i) {
+ if (i<=9)
+ return '0'+i;
+ else if ((i>=10) && (i<=15))
+ return 'a'+(i-10);
+ assert(false);
+ return '\0';
}
+ void binToHex(const uint8_t* in, size_t inlen,
+ char* out, size_t outlen) {
+ if (inlen > outlen/2)
+ inlen = outlen/2;
- bool strSplit(const char* src, const char limiter, char** out1, char** out2, bool fromEnd) {
- CharArray out1old, out2old;
- if (out1) out1old.buf = *out1;
- if (out2) out2old.buf = *out2;
- int len = strlen(src);
- int i=0, increment=1, limit=len;
- if (fromEnd) {
- i=len-1; increment = -1; limit = -1;
+ if (inlen > 0) {
+ assert(in);
+ assert(out);
}
- while (i!=limit) {
- if (src[i] == limiter) {
- if (out1) {
- *out1 = new char[i+1];
- if (i) memcpy(*out1, src, i);
- (*out1)[i] = 0;
- }
- if (out2) {
- *out2 = new char[len-i];
- if (len-i-1) memcpy(*out2, &src[i+1], len-i-1);
- (*out2)[len-i-1] = 0;
- }
- return true;
- }
- i+=increment;
+
+ for (size_t i=0; i<inlen; i++) {
+ out[i*2] = intToHex((in[i] >> 4) & 15);
+ out[i*2+1] = intToHex((in[i] & 15));
}
- if (out1) *out1 = strDup(src);
- if (out2) *out2 = 0;
- return false;
}
- bool strContains(const char* src, char c) {
- int l=strlen(src);
- for (int i=0; i<l; i++)
- if (src[i] == c) return true;
- return false;
+ std::string binToHex(const uint8_t* in, size_t inlen) {
+ char* buffer = new char[inlen*2+1]();
+ std::string out;
+ binToHex(in, inlen, buffer, inlen*2);
+ out = buffer;
+ delete [] buffer;
+ return out;
+ }
+
+ static bool readHexAndShift(char c, uint8_t* v) {
+ c=tolower(c);
+ if ((c >= '0') && (c <= '9'))
+ *v = (*v << 4) + (c - '0');
+ else if ((c >= 'a') && (c <= 'f'))
+ *v = (*v << 4) + (c - 'a' + 10);
+ else
+ return false;
+ return true;
}
- void strCopy(char* dest, const char* src, int destlen) {
- if (src)
- strncpy(dest, src, destlen-1);
- dest[src ? destlen-1 : 0] = 0;
+ bool hexToBin(const char* in, size_t inlen,
+ uint8_t* out, size_t outlen) {
+ assert(in);
+ assert(out);
+
+ if (inlen & 1)
+ return false;
+
+ if (inlen > outlen*2)
+ inlen = outlen*2;
+
+ for(size_t i=0; i<inlen; i+=2) {
+ uint8_t byte = 0;
+ if (!readHexAndShift(in[i], &byte) ||
+ !readHexAndShift(in[i+1], &byte))
+ return false;
+ out[i/2] = byte;
+ }
+
+ return true;
}
- char* convertLF(const char* src, size_t bytes)
+ std::vector<uint8_t> hexToBin(const char* in, size_t inlen) {
+ std::vector<uint8_t> out(inlen/2);
+ if (!hexToBin(in, inlen, out.data(), inlen/2))
+ return std::vector<uint8_t>();
+ return out;
+ }
+
+ std::string convertLF(const char* src, size_t bytes)
{
- char* buffer;
size_t sz;
+ std::string out;
- char* out;
const char* in;
size_t in_len;
- // Always include space for a NULL
- sz = 1;
-
// Compute output size
+ sz = 0;
in = src;
in_len = bytes;
while ((in_len > 0) && (*in != '\0')) {
@@ -142,44 +180,39 @@ namespace rfb {
in_len--;
}
- // Alloc
- buffer = new char[sz];
- memset(buffer, 0, sz);
+ // Reserve space
+ out.reserve(sz);
// And convert
- out = buffer;
in = src;
in_len = bytes;
while ((in_len > 0) && (*in != '\0')) {
if (*in != '\r') {
- *out++ = *in++;
+ out += *in++;
in_len--;
continue;
}
if ((in_len < 2) || (*(in+1) != '\n'))
- *out++ = '\n';
+ out += '\n';
in++;
in_len--;
}
- return buffer;
+ return out;
}
- char* convertCRLF(const char* src, size_t bytes)
+ std::string convertCRLF(const char* src, size_t bytes)
{
- char* buffer;
+ std::string out;
size_t sz;
- char* out;
const char* in;
size_t in_len;
- // Always include space for a NULL
- sz = 1;
-
// Compute output size
+ sz = 0;
in = src;
in_len = bytes;
while ((in_len > 0) && (*in != '\0')) {
@@ -197,38 +230,33 @@ namespace rfb {
in_len--;
}
- // Alloc
- buffer = new char[sz];
- memset(buffer, 0, sz);
+ // Reserve space
+ out.reserve(sz);
// And convert
- out = buffer;
in = src;
in_len = bytes;
while ((in_len > 0) && (*in != '\0')) {
if (*in == '\n') {
if ((in == src) || (*(in-1) != '\r'))
- *out++ = '\r';
+ out += '\r';
}
- *out = *in;
+ out += *in;
if (*in == '\r') {
- if ((in_len < 2) || (*(in+1) != '\n')) {
- out++;
- *out = '\n';
- }
+ if ((in_len < 2) || (*(in+1) != '\n'))
+ out += '\n';
}
- out++;
in++;
in_len--;
}
- return buffer;
+ return out;
}
- size_t ucs4ToUTF8(unsigned src, char* dst) {
+ size_t ucs4ToUTF8(unsigned src, char dst[5]) {
if (src < 0x80) {
*dst++ = src;
*dst++ = '\0';
@@ -309,7 +337,7 @@ namespace rfb {
return consumed;
}
- size_t ucs4ToUTF16(unsigned src, wchar_t* dst) {
+ size_t ucs4ToUTF16(unsigned src, wchar_t dst[3]) {
if ((src < 0xd800) || ((src >= 0xe000) && (src < 0x10000))) {
*dst++ = src;
*dst++ = L'\0';
@@ -365,18 +393,15 @@ namespace rfb {
return 2;
}
- char* latin1ToUTF8(const char* src, size_t bytes) {
- char* buffer;
+ std::string latin1ToUTF8(const char* src, size_t bytes) {
+ std::string out;
size_t sz;
- char* out;
const char* in;
size_t in_len;
- // Always include space for a NULL
- sz = 1;
-
// Compute output size
+ sz = 0;
in = src;
in_len = bytes;
while ((in_len > 0) && (*in != '\0')) {
@@ -386,35 +411,32 @@ namespace rfb {
in_len--;
}
- // Alloc
- buffer = new char[sz];
- memset(buffer, 0, sz);
+ // Reserve space
+ out.reserve(sz);
// And convert
- out = buffer;
in = src;
in_len = bytes;
while ((in_len > 0) && (*in != '\0')) {
- out += ucs4ToUTF8(*(const unsigned char*)in, out);
+ char buf[5];
+ ucs4ToUTF8(*(const unsigned char*)in, buf);
+ out += buf;
in++;
in_len--;
}
- return buffer;
+ return out;
}
- char* utf8ToLatin1(const char* src, size_t bytes) {
- char* buffer;
+ std::string utf8ToLatin1(const char* src, size_t bytes) {
+ std::string out;
size_t sz;
- char* out;
const char* in;
size_t in_len;
- // Always include space for a NULL
- sz = 1;
-
// Compute output size
+ sz = 0;
in = src;
in_len = bytes;
while ((in_len > 0) && (*in != '\0')) {
@@ -427,12 +449,10 @@ namespace rfb {
sz++;
}
- // Alloc
- buffer = new char[sz];
- memset(buffer, 0, sz);
+ // Reserve space
+ out.reserve(sz);
// And convert
- out = buffer;
in = src;
in_len = bytes;
while ((in_len > 0) && (*in != '\0')) {
@@ -444,27 +464,24 @@ namespace rfb {
in_len -= len;
if (ucs > 0xff)
- *out++ = '?';
+ out += '?';
else
- *out++ = (unsigned char)ucs;
+ out += (unsigned char)ucs;
}
- return buffer;
+ return out;
}
- char* utf16ToUTF8(const wchar_t* src, size_t units)
+ std::string utf16ToUTF8(const wchar_t* src, size_t units)
{
- char* buffer;
+ std::string out;
size_t sz;
- char* out;
const wchar_t* in;
size_t in_len;
- // Always include space for a NULL
- sz = 1;
-
// Compute output size
+ sz = 0;
in = src;
in_len = units;
while ((in_len > 0) && (*in != '\0')) {
@@ -479,41 +496,38 @@ namespace rfb {
sz += ucs4ToUTF8(ucs, buf);
}
- // Alloc
- buffer = new char[sz];
- memset(buffer, 0, sz);
+ // Reserve space
+ out.reserve(sz);
// And convert
- out = buffer;
in = src;
in_len = units;
while ((in_len > 0) && (*in != '\0')) {
size_t len;
unsigned ucs;
+ char buf[5];
len = utf16ToUCS4(in, in_len, &ucs);
in += len;
in_len -= len;
- out += ucs4ToUTF8(ucs, out);
+ ucs4ToUTF8(ucs, buf);
+ out += buf;
}
- return buffer;
+ return out;
}
- wchar_t* utf8ToUTF16(const char* src, size_t bytes)
+ std::wstring utf8ToUTF16(const char* src, size_t bytes)
{
- wchar_t* buffer;
+ std::wstring out;
size_t sz;
- wchar_t* out;
const char* in;
size_t in_len;
- // Always include space for a NULL
- sz = 1;
-
// Compute output size
+ sz = 0;
in = src;
in_len = bytes;
while ((in_len > 0) && (*in != '\0')) {
@@ -528,26 +542,26 @@ namespace rfb {
sz += ucs4ToUTF16(ucs, buf);
}
- // Alloc
- buffer = new wchar_t[sz];
- memset(buffer, 0, sz * sizeof(wchar_t));
+ // Reserve space
+ out.reserve(sz);
// And convert
- out = buffer;
in = src;
in_len = bytes;
while ((in_len > 0) && (*in != '\0')) {
size_t len;
unsigned ucs;
+ wchar_t buf[3];
len = utf8ToUCS4(in, in_len, &ucs);
in += len;
in_len -= len;
- out += ucs4ToUTF16(ucs, out);
+ ucs4ToUTF16(ucs, buf);
+ out += buf;
}
- return buffer;
+ return out;
}
unsigned msBetween(const struct timeval *first,
@@ -584,12 +598,12 @@ namespace rfb {
return false;
}
- static size_t doPrefix(long long value, const char *unit,
- char *buffer, size_t maxlen,
- unsigned divisor, const char **prefixes,
- size_t prefixCount, int precision) {
+ static std::string doPrefix(long long value, const char *unit,
+ unsigned divisor, const char **prefixes,
+ size_t prefixCount, int precision) {
+ char buffer[256];
double newValue;
- size_t prefix, len;
+ size_t prefix;
newValue = value;
prefix = 0;
@@ -600,11 +614,11 @@ namespace rfb {
prefix++;
}
- len = snprintf(buffer, maxlen, "%.*g %s%s", precision, newValue,
- (prefix == 0) ? "" : prefixes[prefix-1], unit);
- buffer[maxlen-1] = '\0';
+ snprintf(buffer, sizeof(buffer), "%.*g %s%s", precision, newValue,
+ (prefix == 0) ? "" : prefixes[prefix-1], unit);
+ buffer[sizeof(buffer)-1] = '\0';
- return len;
+ return buffer;
}
static const char *siPrefixes[] =
@@ -612,16 +626,16 @@ namespace rfb {
static const char *iecPrefixes[] =
{ "Ki", "Mi", "Gi", "Ti", "Pi", "Ei", "Zi", "Yi" };
- size_t siPrefix(long long value, const char *unit,
- char *buffer, size_t maxlen, int precision) {
- return doPrefix(value, unit, buffer, maxlen, 1000, siPrefixes,
+ std::string siPrefix(long long value, const char *unit,
+ int precision) {
+ return doPrefix(value, unit, 1000, siPrefixes,
sizeof(siPrefixes)/sizeof(*siPrefixes),
precision);
}
- size_t iecPrefix(long long value, const char *unit,
- char *buffer, size_t maxlen, int precision) {
- return doPrefix(value, unit, buffer, maxlen, 1024, iecPrefixes,
+ std::string iecPrefix(long long value, const char *unit,
+ int precision) {
+ return doPrefix(value, unit, 1024, iecPrefixes,
sizeof(iecPrefixes)/sizeof(*iecPrefixes),
precision);
}
diff --git a/common/rfb/util.h b/common/rfb/util.h
index 99d350e3..34811e3f 100644
--- a/common/rfb/util.h
+++ b/common/rfb/util.h
@@ -1,5 +1,5 @@
/* Copyright (C) 2002-2005 RealVNC Ltd. All Rights Reserved.
- * Copyright 2011-2019 Pierre Ossman for Cendio AB
+ * Copyright 2011-2023 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
@@ -25,73 +25,48 @@
#define __RFB_UTIL_H__
#include <limits.h>
-#include <string.h>
+#include <stdint.h>
+
+#include <string>
+#include <vector>
struct timeval;
namespace rfb {
- // -=- Class to handle cleanup of arrays of characters
- class CharArray {
- public:
- CharArray() : buf(0) {}
- CharArray(char* str) : buf(str) {} // note: assumes ownership
- CharArray(size_t len) {
- buf = new char[len]();
- memset(buf, 0, len);
- }
- ~CharArray() {
- delete [] buf;
- }
- void format(const char *fmt, ...)
- __attribute__((__format__ (__printf__, 2, 3)));
- // Get the buffer pointer & clear it (i.e. caller takes ownership)
- char* takeBuf() {char* tmp = buf; buf = 0; return tmp;}
- void replaceBuf(char* b) {delete [] buf; buf = b;}
- char* buf;
- private:
- CharArray(const CharArray&);
- CharArray& operator=(const CharArray&);
- };
-
- char* strDup(const char* s);
- void strFree(char* s);
- void strFree(wchar_t* s);
-
- // Returns true if split successful. Returns false otherwise.
- // ALWAYS *copies* first part of string to out1 buffer.
- // If limiter not found, leaves out2 alone (null) and just copies to out1.
- // If out1 or out2 non-zero, calls strFree and zeroes them.
- // If fromEnd is true, splits at end of string rather than beginning.
- // Either out1 or out2 may be null, in which case the split will not return
- // that part of the string. Obviously, setting both to 0 is not useful...
- bool strSplit(const char* src, const char limiter, char** out1, char** out2, bool fromEnd=false);
-
- // Returns true if src contains c
- bool strContains(const char* src, char c);
-
- // Copies src to dest, up to specified length-1, and guarantees termination
- void strCopy(char* dest, const char* src, int destlen);
+ // Formats according to printf(), with a dynamic allocation
+ std::string format(const char *fmt, ...)
+ __attribute__((__format__ (__printf__, 1, 2)));
+
+ // Splits a string with the specified delimiter
+ std::vector<std::string> split(const char* src,
+ const char delimiter);
+
+ // Conversion to and from a hex string
+
+ void binToHex(const uint8_t* in, size_t inlen, char* out, size_t outlen);
+ std::string binToHex(const uint8_t* in, size_t inlen);
+ bool hexToBin(const char* in, size_t inlen, uint8_t* out, size_t outlen);
+ std::vector<uint8_t> hexToBin(const char* in, size_t inlen);
// Makes sure line endings are in a certain format
- char* convertLF(const char* src, size_t bytes = (size_t)-1);
- char* convertCRLF(const char* src, size_t bytes = (size_t)-1);
+ std::string convertLF(const char* src, size_t bytes = (size_t)-1);
+ std::string convertCRLF(const char* src, size_t bytes = (size_t)-1);
- // Convertions between various Unicode formats. The returned strings are
- // always null terminated and must be freed using strFree().
+ // Convertions between various Unicode formats
- size_t ucs4ToUTF8(unsigned src, char* dst);
+ size_t ucs4ToUTF8(unsigned src, char dst[5]);
size_t utf8ToUCS4(const char* src, size_t max, unsigned* dst);
- size_t ucs4ToUTF16(unsigned src, wchar_t* dst);
+ size_t ucs4ToUTF16(unsigned src, wchar_t dst[3]);
size_t utf16ToUCS4(const wchar_t* src, size_t max, unsigned* dst);
- char* latin1ToUTF8(const char* src, size_t bytes = (size_t)-1);
- char* utf8ToLatin1(const char* src, size_t bytes = (size_t)-1);
+ std::string latin1ToUTF8(const char* src, size_t bytes = (size_t)-1);
+ std::string utf8ToLatin1(const char* src, size_t bytes = (size_t)-1);
- char* utf16ToUTF8(const wchar_t* src, size_t units = (size_t)-1);
- wchar_t* utf8ToUTF16(const char* src, size_t bytes = (size_t)-1);
+ std::string utf16ToUTF8(const wchar_t* src, size_t units = (size_t)-1);
+ std::wstring utf8ToUTF16(const char* src, size_t bytes = (size_t)-1);
// HELPER functions for timeout handling
@@ -119,10 +94,10 @@ namespace rfb {
bool isBefore(const struct timeval *first,
const struct timeval *second);
- size_t siPrefix(long long value, const char *unit,
- char *buffer, size_t maxlen, int precision=6);
- size_t iecPrefix(long long value, const char *unit,
- char *buffer, size_t maxlen, int precision=6);
+ std::string siPrefix(long long value, const char *unit,
+ int precision=6);
+ std::string iecPrefix(long long value, const char *unit,
+ int precision=6);
}
// Some platforms (e.g. Windows) include max() and min() macros in their
diff --git a/common/rfb/zrleDecode.h b/common/rfb/zrleDecode.h
deleted file mode 100644
index 998e51ed..00000000
--- a/common/rfb/zrleDecode.h
+++ /dev/null
@@ -1,196 +0,0 @@
-/* Copyright (C) 2002-2005 RealVNC Ltd. All Rights Reserved.
- *
- * 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.
- */
-
-//
-// ZRLE decoding function.
-//
-// This file is #included after having set the following macro:
-// BPP - 8, 16 or 32
-
-namespace rfb {
-
-// CONCAT2E concatenates its arguments, expanding them if they are macros
-
-#ifndef CONCAT2E
-#define CONCAT2(a,b) a##b
-#define CONCAT2E(a,b) CONCAT2(a,b)
-#endif
-
-#ifdef CPIXEL
-#define PIXEL_T rdr::CONCAT2E(U,BPP)
-#define READ_PIXEL(is) CONCAT2E(readOpaque,CPIXEL)(is)
-#define ZRLE_DECODE CONCAT2E(zrleDecode,CPIXEL)
-#else
-#define PIXEL_T rdr::CONCAT2E(U,BPP)
-#define READ_PIXEL(is) is->CONCAT2E(readOpaque,BPP)()
-#define ZRLE_DECODE CONCAT2E(zrleDecode,BPP)
-#endif
-
-void ZRLE_DECODE (const Rect& r, rdr::InStream* is,
- rdr::ZlibInStream* zis,
- const PixelFormat& pf, ModifiablePixelBuffer* pb)
-{
- int length = is->readU32();
- zis->setUnderlying(is, length);
- Rect t;
- PIXEL_T buf[64 * 64];
-
- for (t.tl.y = r.tl.y; t.tl.y < r.br.y; t.tl.y += 64) {
-
- t.br.y = __rfbmin(r.br.y, t.tl.y + 64);
-
- for (t.tl.x = r.tl.x; t.tl.x < r.br.x; t.tl.x += 64) {
-
- t.br.x = __rfbmin(r.br.x, t.tl.x + 64);
-
- zlibHasData(zis, 1);
- int mode = zis->readU8();
- bool rle = mode & 128;
- int palSize = mode & 127;
- PIXEL_T palette[128];
-
-#ifdef CPIXEL
- zlibHasData(zis, 3 * palSize);
-#else
- zlibHasData(zis, BPP/8 * palSize);
-#endif
- for (int i = 0; i < palSize; i++) {
- palette[i] = READ_PIXEL(zis);
- }
-
- if (palSize == 1) {
- PIXEL_T pix = palette[0];
- pb->fillRect(pf, t, &pix);
- continue;
- }
-
- if (!rle) {
- if (palSize == 0) {
-
- // raw
-
-#ifdef CPIXEL
- zlibHasData(zis, 3 * t.area());
- for (PIXEL_T* ptr = buf; ptr < buf+t.area(); ptr++) {
- *ptr = READ_PIXEL(zis);
- }
-#else
- zlibHasData(zis, BPP/8 * t.area());
- zis->readBytes(buf, t.area() * (BPP / 8));
-#endif
-
- } else {
-
- // packed pixels
- int bppp = ((palSize > 16) ? 8 :
- ((palSize > 4) ? 4 : ((palSize > 2) ? 2 : 1)));
-
- PIXEL_T* ptr = buf;
-
- for (int i = 0; i < t.height(); i++) {
- PIXEL_T* eol = ptr + t.width();
- rdr::U8 byte = 0;
- rdr::U8 nbits = 0;
-
- while (ptr < eol) {
- if (nbits == 0) {
- zlibHasData(zis, 1);
- byte = zis->readU8();
- nbits = 8;
- }
- nbits -= bppp;
- rdr::U8 index = (byte >> nbits) & ((1 << bppp) - 1) & 127;
- *ptr++ = palette[index];
- }
- }
- }
-
- } else {
-
- if (palSize == 0) {
-
- // plain RLE
-
- PIXEL_T* ptr = buf;
- PIXEL_T* end = ptr + t.area();
- while (ptr < end) {
-#ifdef CPIXEL
- zlibHasData(zis, 3);
-#else
- zlibHasData(zis, BPP/8);
-#endif
- PIXEL_T pix = READ_PIXEL(zis);
- int len = 1;
- int b;
- do {
- zlibHasData(zis, 1);
- b = zis->readU8();
- len += b;
- } while (b == 255);
-
- if (end - ptr < len) {
- throw Exception ("ZRLE decode error");
- }
-
- while (len-- > 0) *ptr++ = pix;
-
- }
- } else {
-
- // palette RLE
-
- PIXEL_T* ptr = buf;
- PIXEL_T* end = ptr + t.area();
- while (ptr < end) {
- zlibHasData(zis, 1);
- int index = zis->readU8();
- int len = 1;
- if (index & 128) {
- int b;
- do {
- zlibHasData(zis, 1);
- b = zis->readU8();
- len += b;
- } while (b == 255);
-
- if (end - ptr < len) {
- throw Exception ("ZRLE decode error");
- }
- }
-
- index &= 127;
-
- PIXEL_T pix = palette[index];
-
- while (len-- > 0) *ptr++ = pix;
- }
- }
- }
-
- pb->imageRect(pf, t, buf);
- }
- }
-
- zis->flushUnderlying();
- zis->setUnderlying(NULL, 0);
-}
-
-#undef ZRLE_DECODE
-#undef READ_PIXEL
-#undef PIXEL_T
-}