]> source.dussan.org Git - tigervnc.git/commitdiff
Basic book keeping of screen layout on server.
authorPierre Ossman <ossman@cendio.se>
Fri, 20 Mar 2009 21:46:12 +0000 (21:46 +0000)
committerPierre Ossman <ossman@cendio.se>
Fri, 20 Mar 2009 21:46:12 +0000 (21:46 +0000)
git-svn-id: svn://svn.code.sf.net/p/tigervnc/code/trunk@3706 3789f03b-4d11-0410-bbf8-ca57d06f2519

common/rfb/SMsgWriterV3.cxx
common/rfb/ScreenSet.h
common/rfb/VNCSConnectionST.cxx
common/rfb/VNCServerST.cxx
common/rfb/VNCServerST.h

index ca6f3f03aa8208fed68a06b36c60187c4f648ef0..de093964dd5daeab647ad3c1b9039f66f578acea 100644 (file)
@@ -190,14 +190,20 @@ void SMsgWriterV3::writeFramebufferUpdateEnd()
     os->writeU16(cp->width);
     os->writeU16(cp->height);
     os->writeU32(pseudoEncodingExtendedDesktopSize);
-    os->writeU8(1);             // # screens
+
+    os->writeU8(cp->screenLayout.num_screens());
     os->pad(3);
-    os->writeU32(1);            // id
-    os->writeU16(0);            // x-pos
-    os->writeU16(0);            // y-pos
-    os->writeU16(cp->width);    // width
-    os->writeU16(cp->height);   // height
-    os->writeU32(0);            // flags
+
+    ScreenSet::const_iterator iter;
+    for (iter = cp->screenLayout.begin();iter != cp->screenLayout.end();++iter) {
+      os->writeU32(iter->id);
+      os->writeU16(iter->dimensions.tl.x);
+      os->writeU16(iter->dimensions.tl.y);
+      os->writeU16(iter->dimensions.width());
+      os->writeU16(iter->dimensions.height());
+      os->writeU32(iter->flags);
+    }
+
     needExtendedDesktopSize = false;
   }
 
index 0783871014ef36eac68750cf7a8198d4de03f87c..55abb5098955376b46ee8bb03383ea8c17f9139e 100644 (file)
@@ -48,7 +48,26 @@ namespace rfb {
 
   struct ScreenSet {
     ScreenSet(void) {};
+
+    typedef std::list<Screen>::iterator iterator;
+    typedef std::list<Screen>::const_iterator const_iterator;
+
+    inline iterator begin(void) { return screens.begin(); };
+    inline const_iterator begin(void) const { return screens.begin(); };
+    inline iterator end(void) { return screens.end(); };
+    inline const_iterator end(void) const { return screens.end(); };
+
+    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) {
+      std::list<Screen>::iterator iter;
+      for (iter = screens.begin();iter != screens.end();++iter) {
+        if (iter->id == id)
+            screens.erase(iter);
+      }
+    }
+
     inline bool validate(int fb_width, int fb_height) const {
       std::list<Screen>::const_iterator iter;
       std::set<rdr::U32> seen_ids;
@@ -56,6 +75,8 @@ namespace rfb {
 
       if (screens.empty())
         return false;
+      if (num_screens() > 255)
+        return false;
 
       fb_rect.setXYWH(0, 0, fb_width, fb_height);
 
@@ -71,6 +92,7 @@ namespace rfb {
 
       return true;
     };
+
     std::list<Screen> screens;
   };
 
index 58ec8aa8f1536fe18b25072b7582d5d6c0dd1af7..10050e386059bfb4ab10c7a40306f6813dba3c85 100644 (file)
@@ -169,6 +169,7 @@ void VNCSConnectionST::pixelBufferChange()
 
       cp.width = server->pb->width();
       cp.height = server->pb->height();
+      cp.screenLayout = server->screenLayout;
       if (state() == RFBSTATE_NORMAL) {
         if (!writer()->writeSetDesktopSize() &&
             !writer()->writeExtendedDesktopSize()) {
@@ -329,6 +330,7 @@ void VNCSConnectionST::authSuccess()
   // - Set the connection parameters appropriately
   cp.width = server->pb->width();
   cp.height = server->pb->height();
+  cp.screenLayout = server->screenLayout;
   cp.setName(server->getName());
   
   // - Set the default pixel format
index 5da6e7131fe7afc864edb936a552b6e77e71fcd5..edd5fc3719a5c1c6b3fdfffbb01eb2999ac3ddf7 100644 (file)
@@ -263,6 +263,31 @@ void VNCServerST::setPixelBuffer(PixelBuffer* pb_)
     cursor.setPF(pb->getPF());
     renderedCursor.setPF(pb->getPF());
 
+    if (screenLayout.num_screens() == 0) {
+      // Boot strap the screen layout
+      screenLayout.add_screen(Screen(0, 0, 0, pb->width(), pb->height(), 0));
+    } else {
+      // Check that the screen layout is still valid
+      if (!screenLayout.validate(pb->width(), pb->height())) {
+        Rect fbRect;
+        ScreenSet::iterator iter, iter_next;
+
+        fbRect.setXYWH(0, 0, pb->width(), pb->height());
+
+        for (iter = screenLayout.begin();iter != screenLayout.end();iter = iter_next) {
+          iter_next = iter; ++iter_next;
+          if (iter->dimensions.enclosed_by(fbRect))
+              continue;
+          iter->dimensions = iter->dimensions.intersect(fbRect);
+          if (iter->dimensions.is_empty()) {
+            slog.info("Removing screen %d (%x) as it is completely outside the new framebuffer",
+                      (int)iter->id, (unsigned)iter->id);
+            screenLayout.remove_screen(iter->id);
+          }
+        }
+      }
+    }
+
     std::list<VNCSConnectionST*>::iterator ci, ci_next;
     for (ci=clients.begin();ci!=clients.end();ci=ci_next) {
       ci_next = ci; ci_next++;
index 4035f93d27bb58e26234782180d8f8e393127000..8e98ba33ac5225b8b8cfc25d45baeaedb21ecce5 100644 (file)
@@ -33,6 +33,7 @@
 #include <rfb/Cursor.h>
 #include <network/Socket.h>
 #include <rfb/ListConnInfo.h>
+#include <rfb/ScreenSet.h>
 
 namespace rfb {
 
@@ -201,6 +202,7 @@ namespace rfb {
     SDesktop* desktop;
     bool desktopStarted;
     PixelBuffer* pb;
+    ScreenSet screenLayout;
 
     CharArray name;