aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--common/rfb/VNCSConnectionST.cxx31
-rw-r--r--common/rfb/VNCServerST.cxx14
-rw-r--r--common/rfb/VNCServerST.h2
3 files changed, 29 insertions, 18 deletions
diff --git a/common/rfb/VNCSConnectionST.cxx b/common/rfb/VNCSConnectionST.cxx
index 3f92a429..126fb4e8 100644
--- a/common/rfb/VNCSConnectionST.cxx
+++ b/common/rfb/VNCSConnectionST.cxx
@@ -965,18 +965,13 @@ void VNCSConnectionST::writeNoDataUpdate()
void VNCSConnectionST::writeDataUpdate()
{
- Region req;
+ Region req, pending;
UpdateInfo ui;
bool needNewUpdateInfo;
const RenderedCursor *cursor;
updates.enable_copyrect(cp.useCopyRect);
- // See if we are allowed to send anything right now (the framebuffer
- // might have changed in ways we haven't yet been informed of).
- if (!server->checkUpdate())
- return;
-
// See what the client has requested (if anything)
if (continuousUpdates)
req = cuRegion.union_(requested);
@@ -986,6 +981,9 @@ void VNCSConnectionST::writeDataUpdate()
if (req.is_empty())
return;
+ // Get any framebuffer changes we haven't yet been informed of
+ pending = server->getPendingRegion();
+
// Get the lists of updates. Prior to exporting the data to the `ui' object,
// getUpdateInfo() will normalize the `updates' object such way that its
// `changed' and `copied' regions would not intersect.
@@ -1027,17 +1025,24 @@ void VNCSConnectionST::writeDataUpdate()
updateRenderedCursor = false;
}
- // Return if there is nothing to send the client.
-
- if (updates.is_empty() && !writer()->needFakeUpdate() &&
- !encodeManager.needsLosslessRefresh(req))
- return;
-
// The `updates' object could change, make sure we have valid update info.
if (needNewUpdateInfo)
updates.getUpdateInfo(&ui, req);
+ // If there are queued updates then we cannot safely send an update
+ // without risking a partially updated screen
+
+ if (!pending.is_empty()) {
+ // However we might still be able to send a lossless refresh
+ req.assign_subtract(pending);
+ req.assign_subtract(ui.changed);
+ req.assign_subtract(ui.copied);
+
+ ui.changed.clear();
+ ui.copied.clear();
+ }
+
// Does the client need a server-side rendered cursor?
cursor = NULL;
@@ -1059,6 +1064,8 @@ void VNCSConnectionST::writeDataUpdate()
damagedCursorRegion.assign_union(ui.changed.intersect(renderedCursorRect));
}
+ // Return if there is nothing to send the client.
+
if (ui.is_empty() && !writer()->needFakeUpdate() &&
!encodeManager.needsLosslessRefresh(req))
return;
diff --git a/common/rfb/VNCServerST.cxx b/common/rfb/VNCServerST.cxx
index 15df71b9..95870c92 100644
--- a/common/rfb/VNCServerST.cxx
+++ b/common/rfb/VNCServerST.cxx
@@ -656,17 +656,21 @@ void VNCServerST::writeUpdate()
// checkUpdate() is called by clients to see if it is safe to read from
// the framebuffer at this time.
-bool VNCServerST::checkUpdate()
+Region VNCServerST::getPendingRegion()
{
+ UpdateInfo ui;
+
// Block clients as the frame buffer cannot be safely accessed
if (blockCounter > 0)
- return false;
+ return pb->getRect();
// Block client from updating if there are pending updates
- if (!comparer->is_empty())
- return false;
+ if (comparer->is_empty())
+ return Region();
+
+ comparer->getUpdateInfo(&ui, pb->getRect());
- return true;
+ return ui.changed.union_(ui.copied);
}
const RenderedCursor* VNCServerST::getRenderedCursor()
diff --git a/common/rfb/VNCServerST.h b/common/rfb/VNCServerST.h
index 9a1a44d1..b7845ddd 100644
--- a/common/rfb/VNCServerST.h
+++ b/common/rfb/VNCServerST.h
@@ -229,7 +229,7 @@ namespace rfb {
void stopFrameClock();
int msToNextUpdate();
void writeUpdate();
- bool checkUpdate();
+ Region getPendingRegion();
const RenderedCursor* getRenderedCursor();
void notifyScreenLayoutChange(VNCSConnectionST *requester);