aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPierre Ossman <ossman@cendio.se>2009-03-20 16:05:04 +0000
committerPierre Ossman <ossman@cendio.se>2009-03-20 16:05:04 +0000
commitcbd1b2c85f0bb39aea4ea226cced78889efe8f22 (patch)
treeec27b965e1f628638b597726cea94bbdbfe47ae0
parentd9a59ba3060fc6f4f2b347bba41fa1881a111618 (diff)
downloadtigervnc-cbd1b2c85f0bb39aea4ea226cced78889efe8f22.tar.gz
tigervnc-cbd1b2c85f0bb39aea4ea226cced78889efe8f22.zip
Properly parse the ExtendedDesktopSize rects in the client.
git-svn-id: svn://svn.code.sf.net/p/tigervnc/code/trunk@3702 3789f03b-4d11-0410-bbf8-ca57d06f2519
-rw-r--r--common/rfb/CMsgHandler.cxx12
-rw-r--r--common/rfb/CMsgHandler.h5
-rw-r--r--common/rfb/CMsgReaderV3.cxx20
-rw-r--r--common/rfb/ConnParams.cxx1
-rw-r--r--common/rfb/ConnParams.h4
-rw-r--r--common/rfb/Makefile.am4
-rw-r--r--common/rfb/ScreenSet.h80
-rw-r--r--common/rfb/rfb.dsp4
-rw-r--r--unix/vncviewer/CConn.cxx5
-rw-r--r--unix/vncviewer/CConn.h3
10 files changed, 127 insertions, 11 deletions
diff --git a/common/rfb/CMsgHandler.cxx b/common/rfb/CMsgHandler.cxx
index fa675dcc..f459d18f 100644
--- a/common/rfb/CMsgHandler.cxx
+++ b/common/rfb/CMsgHandler.cxx
@@ -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)
diff --git a/common/rfb/CMsgHandler.h b/common/rfb/CMsgHandler.h
index 49d407ad..36fc48ef 100644
--- a/common/rfb/CMsgHandler.h
+++ b/common/rfb/CMsgHandler.h
@@ -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);
diff --git a/common/rfb/CMsgReaderV3.cxx b/common/rfb/CMsgReaderV3.cxx
index 05fd9488..5471593c 100644
--- a/common/rfb/CMsgReaderV3.cxx
+++ b/common/rfb/CMsgReaderV3.cxx
@@ -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);
}
diff --git a/common/rfb/ConnParams.cxx b/common/rfb/ConnParams.cxx
index 10b60fbd..7b27a734 100644
--- a/common/rfb/ConnParams.cxx
+++ b/common/rfb/ConnParams.cxx
@@ -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),
diff --git a/common/rfb/ConnParams.h b/common/rfb/ConnParams.h
index bdd9cf23..7779640a 100644
--- a/common/rfb/ConnParams.h
+++ b/common/rfb/ConnParams.h
@@ -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;
diff --git a/common/rfb/Makefile.am b/common/rfb/Makefile.am
index 61f37bd1..d3b7e767 100644
--- a/common/rfb/Makefile.am
+++ b/common/rfb/Makefile.am
@@ -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
index 00000000..07838710
--- /dev/null
+++ b/common/rfb/ScreenSet.h
@@ -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
+
diff --git a/common/rfb/rfb.dsp b/common/rfb/rfb.dsp
index fc1742e4..321c4e61 100644
--- a/common/rfb/rfb.dsp
+++ b/common/rfb/rfb.dsp
@@ -576,6 +576,10 @@ SOURCE=.\SConnection.h
SOURCE=.\screenTypes.h
# End Source File
# Begin Source File
+
+SOURCE=.\ScreenSet.h
+# End Source File
+# Begin Source File
SOURCE=.\SDesktop.h
# End Source File
diff --git a/unix/vncviewer/CConn.cxx b/unix/vncviewer/CConn.cxx
index 79195a8b..47ccbb27 100644
--- a/unix/vncviewer/CConn.cxx
+++ b/unix/vncviewer/CConn.cxx
@@ -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;
diff --git a/unix/vncviewer/CConn.h b/unix/vncviewer/CConn.h
index 27ab8e31..10a12e49 100644
--- a/unix/vncviewer/CConn.h
+++ b/unix/vncviewer/CConn.h
@@ -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();