return false;
}
- inline void VNCServerST::startDefer()
+ void VNCServerST::startFrameClock()
{
- if (deferUpdateTime == 0)
+ if (frameTimer.isStarted())
return;
-
- if (deferPending && !alwaysSetDeferUpdateTimer)
+ if (blockCounter > 0)
return;
- gettimeofday(&deferStart, NULL);
- deferTimer.start(deferUpdateTime);
-
- deferPending = true;
+ frameTimer.start(1000/rfb::Server::frameRate);
}
- inline bool VNCServerST::checkDefer()
+ void VNCServerST::stopFrameClock()
{
- if (!deferPending)
- return true;
-
- if (msSince(&deferStart) >= (unsigned)deferUpdateTime)
- return true;
-
- return false;
+ frameTimer.stop();
}
- void VNCServerST::tryUpdate()
- {
- std::list<VNCSConnectionST*>::iterator ci, ci_next;
-
- if (blockCounter > 0)
- return;
-
- if (!checkDefer())
- return;
-
- for (ci = clients.begin(); ci != clients.end(); ci = ci_next) {
- ci_next = ci; ci_next++;
- (*ci)->writeFramebufferUpdateOrClose();
- }
- }
+ // writeUpdate() is called on a regular interval in order to see what
+ // updates are pending and propagates them to the update tracker for
+ // each client. It uses the ComparingUpdateTracker's compare() method
+ // to filter out areas of the screen which haven't actually changed. It
+ // also checks the state of the (server-side) rendered cursor, if
+ // necessary rendering it again with the correct background.
- // checkUpdate() is called just before sending an update. It checks to see
- // what updates are pending and propagates them to the update tracker for each
- // client. It uses the ComparingUpdateTracker's compare() method to filter out
- // areas of the screen which haven't actually changed. It also checks the
- // state of the (server-side) rendered cursor, if necessary rendering it again
- // with the correct background.
-
- bool VNCServerST::checkUpdate()
+ void VNCServerST::writeUpdate()
{
UpdateInfo ui;
- comparer->getUpdateInfo(&ui, pb->getRect());
-
- bool renderCursor = needRenderedCursor();
+ Region toCheck;
- if (ui.is_empty() && !(renderCursor && renderedCursorInvalid))
- return true;
-
- // Block clients as the frame buffer cannot be safely accessed
- if (blockCounter > 0)
- return false;
-
- // Block client from updating if we are currently deferring updates
- if (!checkDefer())
- return false;
+ std::list<VNCSConnectionST*>::iterator ci, ci_next;
- deferPending = false;
+ assert(blockCounter == 0);
- Region toCheck = ui.changed.union_(ui.copied);
+ comparer->getUpdateInfo(&ui, pb->getRect());
+ toCheck = ui.changed.union_(ui.copied);
- if (renderCursor) {
+ if (needRenderedCursor()) {
- Rect clippedCursorRect
- = cursor.getRect(cursorPos.subtract(cursor.hotspot)).intersect(pb->getRect());
+ Rect clippedCursorRect = Rect(0, 0, cursor->width(), cursor->height())
+ .translate(cursorPos.subtract(cursor->hotspot()))
+ .intersect(pb->getRect());
- if (!renderedCursorInvalid && (toCheck.intersect(clippedCursorRect)
- .is_empty())) {
- renderCursor = false;
- } else {
- toCheck.assign_union(clippedCursorRect);
- }
+ if (!toCheck.intersect(clippedCursorRect).is_empty())
+ renderedCursorInvalid = true;
}
pb->grabRegion(toCheck);
return true;
}
- renderedCursor.update(pb, &cursor, cursorPos);
+ const RenderedCursor* VNCServerST::getRenderedCursor()
+ {
+ if (renderedCursorInvalid) {
++ renderedCursor.update(pb, cursor, cursorPos);
+ renderedCursorInvalid = false;
+ }
+
+ return &renderedCursor;
+ }
+
void VNCServerST::getConnInfo(ListConnInfo * listConn)
{
listConn->Clear();