* 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>
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)
#include <rfb/Pixel.h>
#include <rfb/ConnParams.h>
#include <rfb/Rect.h>
+#include <rfb/ScreenSet.h>
namespace rdr { class InStream; }
// 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);
#include <rfb/CMsgReaderV3.h>
#include <rfb/CMsgHandler.h>
#include <rfb/util.h>
+#include <rfb/ScreenSet.h>
#include <stdio.h>
using namespace rfb;
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);
}
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),
#include <rdr/types.h>
#include <rfb/PixelFormat.h>
+#include <rfb/ScreenSet.h>
namespace rdr { class InStream; }
int width;
int height;
+ ScreenSet screenLayout;
const PixelFormat& pf() { return pf_; }
void setPF(const PixelFormat& pf);
bool supportsDesktopRename;
bool supportsLastRect;
+ bool supportsSetDesktopSize;
+
bool customCompressLevel;
int compressLevel;
bool noJpeg;
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 \
--- /dev/null
+/* 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
+
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
}
// 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;
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();