Basic book keeping of screen layout on server.
git-svn-id: svn://svn.code.sf.net/p/tigervnc/code/trunk@3706 3789f03b-4d11-0410-bbf8-ca57d06f2519
diff --git a/common/rfb/SMsgWriterV3.cxx b/common/rfb/SMsgWriterV3.cxx
index ca6f3f0..de09396 100644
--- a/common/rfb/SMsgWriterV3.cxx
+++ b/common/rfb/SMsgWriterV3.cxx
@@ -190,14 +190,20 @@
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;
}
diff --git a/common/rfb/ScreenSet.h b/common/rfb/ScreenSet.h
index 0783871..55abb50 100644
--- a/common/rfb/ScreenSet.h
+++ b/common/rfb/ScreenSet.h
@@ -48,7 +48,26 @@
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 @@
if (screens.empty())
return false;
+ if (num_screens() > 255)
+ return false;
fb_rect.setXYWH(0, 0, fb_width, fb_height);
@@ -71,6 +92,7 @@
return true;
};
+
std::list<Screen> screens;
};
diff --git a/common/rfb/VNCSConnectionST.cxx b/common/rfb/VNCSConnectionST.cxx
index 58ec8aa..10050e3 100644
--- a/common/rfb/VNCSConnectionST.cxx
+++ b/common/rfb/VNCSConnectionST.cxx
@@ -169,6 +169,7 @@
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 @@
// - 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
diff --git a/common/rfb/VNCServerST.cxx b/common/rfb/VNCServerST.cxx
index 5da6e71..edd5fc3 100644
--- a/common/rfb/VNCServerST.cxx
+++ b/common/rfb/VNCServerST.cxx
@@ -263,6 +263,31 @@
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++;
diff --git a/common/rfb/VNCServerST.h b/common/rfb/VNCServerST.h
index 4035f93..8e98ba3 100644
--- a/common/rfb/VNCServerST.h
+++ b/common/rfb/VNCServerST.h
@@ -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 @@
SDesktop* desktop;
bool desktopStarted;
PixelBuffer* pb;
+ ScreenSet screenLayout;
CharArray name;