]> source.dussan.org Git - tigervnc.git/commitdiff
Properly parse the ExtendedDesktopSize rects in the client.
authorPierre Ossman <ossman@cendio.se>
Fri, 20 Mar 2009 16:05:04 +0000 (16:05 +0000)
committerPierre Ossman <ossman@cendio.se>
Fri, 20 Mar 2009 16:05:04 +0000 (16:05 +0000)
git-svn-id: svn://svn.code.sf.net/p/tigervnc/code/trunk@3702 3789f03b-4d11-0410-bbf8-ca57d06f2519

common/rfb/CMsgHandler.cxx
common/rfb/CMsgHandler.h
common/rfb/CMsgReaderV3.cxx
common/rfb/ConnParams.cxx
common/rfb/ConnParams.h
common/rfb/Makefile.am
common/rfb/ScreenSet.h [new file with mode: 0644]
common/rfb/rfb.dsp
unix/vncviewer/CConn.cxx
unix/vncviewer/CConn.h

index fa675dcc7fc5eab0add63895584e76c7f6c858e5..f459d18fd0617b494d90591b98b9e62bc1929cd6 100644 (file)
@@ -16,6 +16,8 @@
  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,
  * USA.
  */
+#include <stdio.h>
+
 #include <rfb/Exception.h>
 #include <rfb/CMsgHandler.h>
 #include <rfb/screenTypes.h>
@@ -36,13 +38,21 @@ void CMsgHandler::setDesktopSize(int width, int height)
   cp.height = height;
 }
 
-void CMsgHandler::setExtendedDesktopSize(int reason, int result, int width, int height)
+void CMsgHandler::setExtendedDesktopSize(int reason, int result,
+                                         int width, int height,
+                                         const ScreenSet& layout)
 {
+  cp.supportsSetDesktopSize = true;
+
   if ((reason == reasonClient) && (result != resultSuccess))
     return;
 
+  if (!layout.validate(width, height))
+    fprintf(stderr, "Server sent us an invalid screen layout\n");
+
   cp.width = width;
   cp.height = height;
+  cp.screenLayout = layout;
 }
 
 void CMsgHandler::setCursor(int w, int h, const Point& hotspot, void* data, void* mask)
index 49d407ad14719b5277fa416b648afd34570de990..36fc48ef3905afe961f5092b88d14483299ab9a7 100644 (file)
@@ -27,6 +27,7 @@
 #include <rfb/Pixel.h>
 #include <rfb/ConnParams.h>
 #include <rfb/Rect.h>
+#include <rfb/ScreenSet.h>
 
 namespace rdr { class InStream; }
 
@@ -44,7 +45,9 @@ namespace rfb {
     // methods to set the members of cp appropriately.
 
     virtual void setDesktopSize(int w, int h);
-    virtual void setExtendedDesktopSize(int reason, int result, int w, int h);
+    virtual void setExtendedDesktopSize(int reason, int result,
+                                        int w, int h,
+                                        const ScreenSet& layout);
     virtual void setCursor(int width, int height, const Point& hotspot,
                            void* data, void* mask);
     virtual void setPixelFormat(const PixelFormat& pf);
index 05fd94887f01b39a57a708bc410af704193199c3..5471593c59b720e0d6ff9783b1ee0e9f0dad91d8 100644 (file)
@@ -23,6 +23,7 @@
 #include <rfb/CMsgReaderV3.h>
 #include <rfb/CMsgHandler.h>
 #include <rfb/util.h>
+#include <rfb/ScreenSet.h>
 #include <stdio.h>
 
 using namespace rfb;
@@ -121,14 +122,25 @@ void CMsgReaderV3::readSetDesktopName(int x, int y, int w, int h)
 
 void CMsgReaderV3::readExtendedDesktopSize(int x, int y, int w, int h)
 {
-  unsigned int screens;
+  unsigned int screens, i;
+  rdr::U32 id, flags;
+  int sx, sy, sw, sh;
+  ScreenSet layout;
 
   screens = is->readU8();
   is->skip(3);
 
-  // XXX: We just ignore screen info right now
-  is->skip(16 * screens);
+  for (i = 0;i < screens;i++) {
+    id = is->readU32();
+    sx = is->readU16();
+    sy = is->readU16();
+    sw = is->readU16();
+    sh = is->readU16();
+    flags = is->readU32();
 
-  handler->setExtendedDesktopSize(x, y, w, h);
+    layout.add_screen(Screen(id, sx, sy, sw, sh, flags));
+  }
+
+  handler->setExtendedDesktopSize(x, y, w, h, layout);
 }
 
index 10b60fbd7eddd068ad3b524ca70ab02b3a08a769..7b27a73462327b01332320fd0a8fe6167dccaa7b 100644 (file)
@@ -32,6 +32,7 @@ ConnParams::ConnParams()
     supportsLocalCursor(false), supportsLocalXCursor(false),
     supportsDesktopResize(false), supportsExtendedDesktopSize(false),
     supportsDesktopRename(false), supportsLastRect(false),
+    supportsSetDesktopSize(false),
     customCompressLevel(false), compressLevel(6),
     noJpeg(false), qualityLevel(-1), 
     name_(0), nEncodings_(0), encodings_(0),
index bdd9cf231bc6f658cc80a03922328f090c897c30..7779640a5c2ea0457abcd241d270730207356e43 100644 (file)
@@ -24,6 +24,7 @@
 
 #include <rdr/types.h>
 #include <rfb/PixelFormat.h>
+#include <rfb/ScreenSet.h>
 
 namespace rdr { class InStream; }
 
@@ -57,6 +58,7 @@ namespace rfb {
 
     int width;
     int height;
+    ScreenSet screenLayout;
 
     const PixelFormat& pf() { return pf_; }
     void setPF(const PixelFormat& pf);
@@ -77,6 +79,8 @@ namespace rfb {
     bool supportsDesktopRename;
     bool supportsLastRect;
 
+    bool supportsSetDesktopSize;
+
     bool customCompressLevel;
     int compressLevel;
     bool noJpeg;
index 61f37bd1acffbedc37636cdd6064b1018f0a309c..d3b7e7676dd5e055bf8e5c30642d1f8c8ec09e60 100644 (file)
@@ -12,8 +12,8 @@ HDRS = Blacklist.h CapsContainer.h CapsList.h CConnection.h \
        Logger_stdio.h LogWriter.h msgTypes.h Password.h PixelBuffer.h \
        PixelFormat.h PixelFormat.inl Pixel.h RawDecoder.h RawEncoder.h \
        Rect.h Region.h rreDecode.h RREDecoder.h rreEncode.h RREEncoder.h \
-       ScaledPixelBuffer.h ScaleFilters.h SConnection.h screenTypes.h \
-       SDesktop.h secTypes.h ServerCore.h SMsgHandler.h \
+       ScaledPixelBuffer.h ScaleFilters.h SConnection.h ScreenSet.h \
+       screenTypes.h SDesktop.h secTypes.h ServerCore.h SMsgHandler.h \
        SMsgReader.h SMsgReaderV3.h SMsgWriter.h SMsgWriterV3.h \
        SSecurityFactoryStandard.h SSecurity.h SSecurityNone.h \
        SSecurityVncAuth.h Threading.h tightDecode.h TightDecoder.h \
diff --git a/common/rfb/ScreenSet.h b/common/rfb/ScreenSet.h
new file mode 100644 (file)
index 0000000..0783871
--- /dev/null
@@ -0,0 +1,80 @@
+/* Copyright 2009 Pierre Ossman for Cendio AB
+ * 
+ * This is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ * 
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with this software; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,
+ * USA.
+ */
+
+// Management class for the RFB virtual screens
+
+#ifndef __RFB_SCREENSET_INCLUDED__
+#define __RFB_SCREENSET_INCLUDED__
+
+#include <rfb/Rect.h>
+#include <list>
+#include <set>
+
+namespace rfb {
+
+  // rfb::Screen
+  //
+  // Represents a single RFB virtual screen, which includes
+  // coordinates, an id and flags.
+
+  struct Screen {
+    Screen(void) : id(0), flags(0) {};
+    Screen(rdr::U32 id_, int x_, int y_, int w_, int h_, rdr::U32 flags_) :
+      id(id_), dimensions(x_, y_, x_+w_, y_+h_), flags(flags_) {};
+    rdr::U32 id;
+    Rect dimensions;
+    rdr::U32 flags;
+  };
+
+  // rfb::ScreenSet
+  //
+  // Represents a complete screen configuration, excluding framebuffer
+  // dimensions.
+
+  struct ScreenSet {
+    ScreenSet(void) {};
+    inline void add_screen(const Screen screen) { screens.push_back(screen); };
+    inline bool validate(int fb_width, int fb_height) const {
+      std::list<Screen>::const_iterator iter;
+      std::set<rdr::U32> seen_ids;
+      Rect fb_rect;
+
+      if (screens.empty())
+        return false;
+
+      fb_rect.setXYWH(0, 0, fb_width, fb_height);
+
+      for (iter = screens.begin();iter != screens.end();++iter) {
+        if (iter->dimensions.is_empty())
+          return false;
+        if (!iter->dimensions.enclosed_by(fb_rect))
+          return false;
+        if (seen_ids.find(iter->id) != seen_ids.end())
+          return false;
+        seen_ids.insert(iter->id);
+      }
+
+      return true;
+    };
+    std::list<Screen> screens;
+  };
+
+};
+
+#endif
+
index fc1742e4ae66896c9dddd78f4a42f9af9a218d89..321c4e611bb4241310e6ce3822c4944947a5735a 100644 (file)
@@ -576,6 +576,10 @@ SOURCE=.\SConnection.h
 SOURCE=.\screenTypes.h\r
 # End Source File\r
 # Begin Source File\r
+
+SOURCE=.\ScreenSet.h\r
+# End Source File\r
+# Begin Source File\r
 \r
 SOURCE=.\SDesktop.h\r
 # End Source File\r
index 79195a8b6eef4e0f7c5b7c0a31936cae4b83b8bd..47ccbb27afa991f72567dee9036543687eb70fd5 100644 (file)
@@ -273,8 +273,9 @@ void CConn::setDesktopSize(int w, int h) {
 }
 
 // setExtendedDesktopSize() is a more advanced version of setDesktopSize()
-void CConn::setExtendedDesktopSize(int reason, int result, int w, int h) {
-  CConnection::setExtendedDesktopSize(reason, result, w,h);
+void CConn::setExtendedDesktopSize(int reason, int result, int w, int h,
+                                   const rfb::ScreenSet& layout) {
+  CConnection::setExtendedDesktopSize(reason, result, w, h, layout);
 
   if ((reason == reasonClient) && (result != resultSuccess))
     return;
index 27ab8e31e21b5d33347c160eb60b45049a31310f..10a12e495ee45d434e711576c47e0e559e2dcb1c 100644 (file)
@@ -75,7 +75,8 @@ public:
   rfb::CSecurity* getCSecurity(int secType);
   void serverInit();
   void setDesktopSize(int w, int h);
-  void setExtendedDesktopSize(int reason, int result, int w, int h);
+  void setExtendedDesktopSize(int reason, int result, int w, int h,
+                              const rfb::ScreenSet& layout);
   void setName(const char* name);
   void setColourMapEntries(int firstColour, int nColours, rdr::U16* rgbs);
   void bell();