[Enhancements, refactoring] Rationalized functions to control video
rectangle selection and default video rectangle. Added more logging and
improved error checking in the related code.


git-svn-id: svn://svn.code.sf.net/p/tigervnc/code/trunk@2753 3789f03b-4d11-0410-bbf8-ca57d06f2519
diff --git a/common/rfb/SMsgHandler.cxx b/common/rfb/SMsgHandler.cxx
index 64f0534..a4ae46d 100644
--- a/common/rfb/SMsgHandler.cxx
+++ b/common/rfb/SMsgHandler.cxx
@@ -54,8 +54,3 @@
 void SMsgHandler::setVideoRectangle(const Rect& r)
 {
 }
-
-void SMsgHandler::unsetVideoRectangle()
-{
-}
-
diff --git a/common/rfb/SMsgHandler.h b/common/rfb/SMsgHandler.h
index f6d714c..16b3c90 100644
--- a/common/rfb/SMsgHandler.h
+++ b/common/rfb/SMsgHandler.h
@@ -48,7 +48,6 @@
     virtual void framebufferUpdateRequest(const Rect& r, bool incremental);
 
     virtual void setVideoRectangle(const Rect& r);
-    virtual void unsetVideoRectangle();
 
     // 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 c55e8f1..d227064 100644
--- a/common/rfb/SMsgReader.cxx
+++ b/common/rfb/SMsgReader.cxx
@@ -106,15 +106,18 @@
   int y = is->readU16();
   int w = is->readU16();
   int h = is->readU16();
-  bool enable = w > 0 && h > 0;
+  Rect rect(x, y, x+w, y+h);
 
-  if (enable) {
+  if (!rect.is_empty()) {
     vlog.debug("Video area selected by client: %dx%d at (%d,%d)",
                w, h, x, y);
-    handler->setVideoRectangle(Rect(x, y, x+w, y+h));
+  } else if (x != 0 || y != 0 || w != 0 || h != 0) {
+    vlog.debug("Empty video area selected by client: %dx%d at (%d,%d)",
+               w, h, x, y);
+    rect.clear();
   } else {
     vlog.debug("Video area discarded by client");
-    handler->unsetVideoRectangle();
   }
+  handler->setVideoRectangle(rect);
 }
 
diff --git a/common/rfb/VNCSConnectionST.cxx b/common/rfb/VNCSConnectionST.cxx
index 84da709..8c52bcb 100644
--- a/common/rfb/VNCSConnectionST.cxx
+++ b/common/rfb/VNCSConnectionST.cxx
@@ -497,11 +497,6 @@
   server->setVideoRectangle(r);
 }
 
-void VNCSConnectionST::unsetVideoRectangle()
-{
-  server->unsetVideoRectangle();
-}
-
 void VNCSConnectionST::setInitialColourMap()
 {
   setColourMapEntries(0, 0);
diff --git a/common/rfb/VNCSConnectionST.h b/common/rfb/VNCSConnectionST.h
index 1df718a..d48c8c7 100644
--- a/common/rfb/VNCSConnectionST.h
+++ b/common/rfb/VNCSConnectionST.h
@@ -131,7 +131,6 @@
     virtual void supportsLocalCursor();
 
     virtual void setVideoRectangle(const Rect& r);
-    virtual void unsetVideoRectangle();
 
     // setAccessRights() allows a security package to limit the access rights
     // of a VNCSConnectioST to the server.  These access rights are applied
diff --git a/common/rfb/VNCServerST.cxx b/common/rfb/VNCServerST.cxx
index 0577d05..838f06c 100644
--- a/common/rfb/VNCServerST.cxx
+++ b/common/rfb/VNCServerST.cxx
@@ -259,6 +259,7 @@
 
   if (pb) {
     comparer = new ComparingUpdateTracker(pb);
+    applyVideoRectangle();
     cursor.setPF(pb->getPF());
     renderedCursor.setPF(pb->getPF());
 
@@ -302,17 +303,23 @@
 
 void VNCServerST::add_changed(const Region& region)
 {
-  comparer->add_changed(region);
+  if (comparer != 0) {
+    comparer->add_changed(region);
+  }
 }
 
 void VNCServerST::add_copied(const Region& dest, const Point& delta)
 {
-  comparer->add_copied(dest, delta);
+  if (comparer != 0) {
+    comparer->add_copied(dest, delta);
+  }
 }
 
 void VNCServerST::set_video_area(const Rect &rect)
 {
-  comparer->set_video_area(rect);
+  if (comparer != 0) {
+    comparer->set_video_area(rect);
+  }
 }
 
 bool VNCServerST::clientsReadyForUpdate()
@@ -553,28 +560,43 @@
   }
 }
 
+void VNCServerST::enableVideoSelection(bool enable)
+{
+  slog.debug("Enabling video selection");
+  m_videoSelectionEnabled = enable;
+  applyVideoRectangle();
+}
+
+bool VNCServerST::isVideoSelectionEnabled() const
+{
+  return m_videoSelectionEnabled;
+}
+
 void VNCServerST::setVideoRectangle(const Rect& r)
 {
-  if (isVideoSelectionEnabled()) {
-    // FIXME: Duplication between m_videoRect and comparer->video_area.
-    m_videoRect = r;
-    set_video_area(m_videoRect);
-  }
+  m_videoRect = r;
+  applyVideoRectangle();
 }
 
-void VNCServerST::unsetVideoRectangle()
-{
-  if (isVideoSelectionEnabled()) {
-    // FIXME: Duplication between m_videoRect and comparer->video_area.
-    m_videoRect.clear();
-    set_video_area(m_defaultVideoRect);
-  }
-}
-
-void VNCServerST::setDefaultVideoRect(const Rect& r)
+void VNCServerST::setDefaultVideoRectangle(const Rect& r)
 {
   m_defaultVideoRect = r;
-  if (m_videoRect.is_empty()) {
-    set_video_area(m_defaultVideoRect);
+  applyVideoRectangle();
+}
+
+void VNCServerST::applyVideoRectangle()
+{
+  if (pb != 0) {
+    if (isVideoSelectionEnabled() && !m_videoRect.is_empty()) {
+      slog.debug("Applying video selection");
+      set_video_area(m_videoRect);
+    } else {
+      if (!m_defaultVideoRect.is_empty()) {
+        slog.debug("Applying default video area");
+      } else {
+        slog.debug("Applying empty video area");
+      }
+      set_video_area(m_defaultVideoRect);
+    }
   }
 }
diff --git a/common/rfb/VNCServerST.h b/common/rfb/VNCServerST.h
index 1dd7afd..90bbeb5 100644
--- a/common/rfb/VNCServerST.h
+++ b/common/rfb/VNCServerST.h
@@ -199,13 +199,11 @@
     // request, as we expect that video data is changing continuously. By
     // default, this option is disabled, as it's rather a specialized feature
     // and video selection GUI can confuse users of the TightVNC client.
-    void enableVideoSelection(bool enable) { m_videoSelectionEnabled = enable; }
-    bool isVideoSelectionEnabled() { return m_videoSelectionEnabled; }
+    void enableVideoSelection(bool enable);
+    bool isVideoSelectionEnabled() const;
 
     void setVideoRectangle(const Rect& r);
-    void unsetVideoRectangle();
-
-    void setDefaultVideoRect(const Rect& r);
+    void setDefaultVideoRectangle(const Rect& r);
 
   protected:
 
@@ -259,6 +257,8 @@
     bool m_videoSelectionEnabled;
     Rect m_videoRect;
     Rect m_defaultVideoRect;
+
+    void applyVideoRectangle();
   };
 
 };
diff --git a/unix/x0vncserver/x0vncserver.cxx b/unix/x0vncserver/x0vncserver.cxx
index d21e71b..9b589d9 100644
--- a/unix/x0vncserver/x0vncserver.cxx
+++ b/unix/x0vncserver/x0vncserver.cxx
@@ -188,7 +188,7 @@
 
     server = (VNCServerST *)vs;
     server->setPixelBuffer(pb);
-    server->setDefaultVideoRect(geometry->getVideoRect());
+    server->setDefaultVideoRectangle(geometry->getVideoRect());
 
     running = true;
   }