mirror of
https://github.com/kasmtech/KasmVNC.git
synced 2025-06-28 05:31:49 +02:00
Merge branch 'bugfix/KASM-5417_watermark_zlib_incomplete' into 'master'
Watermark refactoring, don't handle changes, only send when necessary Closes KASM-5417 See merge request kasm-technologies/internal/KasmVNC!120
This commit is contained in:
commit
fddaab5124
@ -423,9 +423,6 @@ void EncodeManager::doUpdate(bool allowLossy, const Region& changed_,
|
|||||||
nRects++;
|
nRects++;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (watermarkData)
|
|
||||||
packWatermark(changed);
|
|
||||||
|
|
||||||
conn->writer()->writeFramebufferUpdateStart(nRects);
|
conn->writer()->writeFramebufferUpdateStart(nRects);
|
||||||
|
|
||||||
writeCopyRects(copied, copyDelta);
|
writeCopyRects(copied, copyDelta);
|
||||||
@ -443,7 +440,7 @@ void EncodeManager::doUpdate(bool allowLossy, const Region& changed_,
|
|||||||
if (!videoDetected) // In case detection happened between the calls
|
if (!videoDetected) // In case detection happened between the calls
|
||||||
writeRects(cursorRegion, renderedCursor);
|
writeRects(cursorRegion, renderedCursor);
|
||||||
|
|
||||||
if (watermarkData) {
|
if (watermarkData && conn->sendWatermark()) {
|
||||||
beforeLength = conn->getOutStream(conn->cp.supportsUdp)->length();
|
beforeLength = conn->getOutStream(conn->cp.supportsUdp)->length();
|
||||||
|
|
||||||
const Rect rect(0, 0, pb->width(), pb->height());
|
const Rect rect(0, 0, pb->width(), pb->height());
|
||||||
|
@ -198,6 +198,10 @@ namespace rfb {
|
|||||||
std::vector<unsigned char> data;
|
std::vector<unsigned char> data;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
virtual bool sendWatermark() const {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void setState(stateEnum s) { state_ = s; }
|
void setState(stateEnum s) { state_ = s; }
|
||||||
|
|
||||||
|
@ -215,6 +215,10 @@ namespace rfb {
|
|||||||
virtual void sendUnixRelayData(const char name[], const unsigned char *buf,
|
virtual void sendUnixRelayData(const char name[], const unsigned char *buf,
|
||||||
const unsigned len);
|
const unsigned len);
|
||||||
|
|
||||||
|
bool sendWatermark() const {
|
||||||
|
return server->sendWatermark;
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// SConnection callbacks
|
// SConnection callbacks
|
||||||
|
|
||||||
|
@ -135,7 +135,7 @@ VNCServerST::VNCServerST(const char* name_, SDesktop* desktop_)
|
|||||||
queryConnectionHandler(0), keyRemapper(&KeyRemapper::defInstance),
|
queryConnectionHandler(0), keyRemapper(&KeyRemapper::defInstance),
|
||||||
lastConnectionTime(0), disableclients(false),
|
lastConnectionTime(0), disableclients(false),
|
||||||
frameTimer(this), apimessager(NULL), trackingFrameStats(0),
|
frameTimer(this), apimessager(NULL), trackingFrameStats(0),
|
||||||
clipboardId(0)
|
clipboardId(0), sendWatermark(false)
|
||||||
{
|
{
|
||||||
lastUserInputTime = lastDisconnectTime = time(0);
|
lastUserInputTime = lastDisconnectTime = time(0);
|
||||||
slog.debug("creating single-threaded server %s", name.buf);
|
slog.debug("creating single-threaded server %s", name.buf);
|
||||||
@ -223,6 +223,9 @@ VNCServerST::VNCServerST(const char* name_, SDesktop* desktop_)
|
|||||||
|
|
||||||
trackingClient[0] = 0;
|
trackingClient[0] = 0;
|
||||||
|
|
||||||
|
if (watermarkData)
|
||||||
|
sendWatermark = true;
|
||||||
|
|
||||||
if (Server::selfBench)
|
if (Server::selfBench)
|
||||||
SelfBench();
|
SelfBench();
|
||||||
}
|
}
|
||||||
@ -279,6 +282,9 @@ void VNCServerST::addSocket(network::Socket* sock, bool outgoing)
|
|||||||
|
|
||||||
VNCSConnectionST* client = new VNCSConnectionST(this, sock, outgoing);
|
VNCSConnectionST* client = new VNCSConnectionST(this, sock, outgoing);
|
||||||
client->init();
|
client->init();
|
||||||
|
|
||||||
|
if (watermarkData)
|
||||||
|
sendWatermark = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void VNCServerST::removeSocket(network::Socket* sock) {
|
void VNCServerST::removeSocket(network::Socket* sock) {
|
||||||
@ -975,8 +981,8 @@ void VNCServerST::writeUpdate()
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (watermarkData && Server::DLP_WatermarkText[0] && watermarkTextNeedsUpdate(true)) {
|
if (watermarkData && Server::DLP_WatermarkText[0] && watermarkTextNeedsUpdate(true)) {
|
||||||
// If using a text watermark, we have to mark everything as changed...
|
// The text may have changed
|
||||||
refreshClients();
|
sendWatermark = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
comparer->getUpdateInfo(&ui, pb->getRect());
|
comparer->getUpdateInfo(&ui, pb->getRect());
|
||||||
@ -1104,6 +1110,8 @@ void VNCServerST::writeUpdate()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sendWatermark = false; // the client now caches it, only send once
|
||||||
|
|
||||||
if (trackingFrameStats) {
|
if (trackingFrameStats) {
|
||||||
if (enctime) {
|
if (enctime) {
|
||||||
const unsigned totalMs = msSince(&start);
|
const unsigned totalMs = msSince(&start);
|
||||||
|
@ -290,6 +290,8 @@ namespace rfb {
|
|||||||
|
|
||||||
void checkAPIMessages(network::GetAPIMessager *apimessager,
|
void checkAPIMessages(network::GetAPIMessager *apimessager,
|
||||||
rdr::U8 &trackingFrameStats, char trackingClient[]);
|
rdr::U8 &trackingFrameStats, char trackingClient[]);
|
||||||
|
|
||||||
|
bool sendWatermark;
|
||||||
};
|
};
|
||||||
|
|
||||||
};
|
};
|
||||||
|
@ -279,6 +279,31 @@ bool watermarkInit() {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void packWatermark() {
|
||||||
|
// Take the expanded 4-bit data, filter it by the changed rects, pack
|
||||||
|
// to shared bytes, and compress with zlib
|
||||||
|
|
||||||
|
uint16_t x, y;
|
||||||
|
uint8_t pix[2], cur = 0;
|
||||||
|
uint8_t *dst = watermarkTmp;
|
||||||
|
|
||||||
|
for (y = 0; y < rh; y++) {
|
||||||
|
for (x = 0; x < rw; x++) {
|
||||||
|
pix[cur] = watermarkUnpacked[y * rw + x];
|
||||||
|
if (cur || (y == rh - 1 && x == rw - 1))
|
||||||
|
*dst++ = pix[0] | (pix[1] << 4);
|
||||||
|
|
||||||
|
cur ^= 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
uLong destLen = MAXW * MAXH / 2;
|
||||||
|
if (compress2(watermarkData, &destLen, watermarkTmp, rw * rh / 2 + 1, 1) != Z_OK)
|
||||||
|
vlog.error("Zlib compression error");
|
||||||
|
|
||||||
|
watermarkDataLen = destLen;
|
||||||
|
}
|
||||||
|
|
||||||
// update the screen-size rendered watermark whenever the screen is resized
|
// update the screen-size rendered watermark whenever the screen is resized
|
||||||
// or if using text, every frame
|
// or if using text, every frame
|
||||||
void VNCServerST::updateWatermark() {
|
void VNCServerST::updateWatermark() {
|
||||||
@ -359,48 +384,10 @@ void VNCServerST::updateWatermark() {
|
|||||||
rw - sx);
|
rw - sx);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
void packWatermark(const Region &changed) {
|
packWatermark();
|
||||||
// Take the expanded 4-bit data, filter it by the changed rects, pack
|
|
||||||
// to shared bytes, and compress with zlib
|
|
||||||
|
|
||||||
uint16_t x, y;
|
sendWatermark = true;
|
||||||
uint8_t pix[2], cur = 0;
|
|
||||||
uint8_t *dst = watermarkTmp;
|
|
||||||
|
|
||||||
const Rect &bounding = changed.get_bounding_rect();
|
|
||||||
|
|
||||||
for (y = 0; y < rh; y++) {
|
|
||||||
// Is the entire line outside the changed area?
|
|
||||||
if (bounding.tl.y > y || bounding.br.y < y) {
|
|
||||||
for (x = 0; x < rw; x++) {
|
|
||||||
pix[cur] = 0;
|
|
||||||
|
|
||||||
if (cur || (y == rh - 1 && x == rw - 1))
|
|
||||||
*dst++ = pix[0] | (pix[1] << 4);
|
|
||||||
|
|
||||||
cur ^= 1;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
for (x = 0; x < rw; x++) {
|
|
||||||
pix[cur] = 0;
|
|
||||||
if (bounding.contains(Point(x, y)) && changed.contains(x, y))
|
|
||||||
pix[cur] = watermarkUnpacked[y * rw + x];
|
|
||||||
|
|
||||||
if (cur || (y == rh - 1 && x == rw - 1))
|
|
||||||
*dst++ = pix[0] | (pix[1] << 4);
|
|
||||||
|
|
||||||
cur ^= 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
uLong destLen = MAXW * MAXH / 2;
|
|
||||||
if (compress2(watermarkData, &destLen, watermarkTmp, rw * rh / 2 + 1, 1) != Z_OK)
|
|
||||||
vlog.error("Zlib compression error");
|
|
||||||
|
|
||||||
watermarkDataLen = destLen;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Limit changes to once per second
|
// Limit changes to once per second
|
||||||
@ -412,5 +399,5 @@ bool watermarkTextNeedsUpdate(const bool early) {
|
|||||||
if (early)
|
if (early)
|
||||||
now = time(NULL);
|
now = time(NULL);
|
||||||
|
|
||||||
return now != lastUpdate;
|
return now != lastUpdate && strchr(Server::DLP_WatermarkText, '%');
|
||||||
}
|
}
|
||||||
|
@ -35,7 +35,6 @@ struct watermarkInfo_t {
|
|||||||
extern watermarkInfo_t watermarkInfo;
|
extern watermarkInfo_t watermarkInfo;
|
||||||
|
|
||||||
bool watermarkInit();
|
bool watermarkInit();
|
||||||
void packWatermark(const rfb::Region &changed); // filter and pack the watermark for sending
|
|
||||||
bool watermarkTextNeedsUpdate(const bool early);
|
bool watermarkTextNeedsUpdate(const bool early);
|
||||||
|
|
||||||
extern uint8_t *watermarkData;
|
extern uint8_t *watermarkData;
|
||||||
|
2
kasmweb
2
kasmweb
@ -1 +1 @@
|
|||||||
Subproject commit 246dbd49996db31be241db112c69d05d77523559
|
Subproject commit f6c1d8c668beeff3aeccad13933a5ef52f0d5c32
|
Loading…
x
Reference in New Issue
Block a user