From 34e62f347fa5352d704f864baa0639f94e674516 Mon Sep 17 00:00:00 2001 From: Pierre Ossman Date: Fri, 20 Mar 2009 21:46:12 +0000 Subject: [PATCH] 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 --- common/rfb/SMsgWriterV3.cxx | 20 +++++++++++++------- common/rfb/ScreenSet.h | 22 ++++++++++++++++++++++ common/rfb/VNCSConnectionST.cxx | 2 ++ common/rfb/VNCServerST.cxx | 25 +++++++++++++++++++++++++ common/rfb/VNCServerST.h | 2 ++ 5 files changed, 64 insertions(+), 7 deletions(-) diff --git a/common/rfb/SMsgWriterV3.cxx b/common/rfb/SMsgWriterV3.cxx index ca6f3f03..de093964 100644 --- a/common/rfb/SMsgWriterV3.cxx +++ b/common/rfb/SMsgWriterV3.cxx @@ -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; } diff --git a/common/rfb/ScreenSet.h b/common/rfb/ScreenSet.h index 07838710..55abb509 100644 --- a/common/rfb/ScreenSet.h +++ b/common/rfb/ScreenSet.h @@ -48,7 +48,26 @@ namespace rfb { struct ScreenSet { ScreenSet(void) {}; + + typedef std::list::iterator iterator; + typedef std::list::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::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::const_iterator iter; std::set 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 screens; }; diff --git a/common/rfb/VNCSConnectionST.cxx b/common/rfb/VNCSConnectionST.cxx index 58ec8aa8..10050e38 100644 --- a/common/rfb/VNCSConnectionST.cxx +++ b/common/rfb/VNCSConnectionST.cxx @@ -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 diff --git a/common/rfb/VNCServerST.cxx b/common/rfb/VNCServerST.cxx index 5da6e713..edd5fc37 100644 --- a/common/rfb/VNCServerST.cxx +++ b/common/rfb/VNCServerST.cxx @@ -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::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 4035f93d..8e98ba33 100644 --- a/common/rfb/VNCServerST.h +++ b/common/rfb/VNCServerST.h @@ -33,6 +33,7 @@ #include #include #include +#include namespace rfb { @@ -201,6 +202,7 @@ namespace rfb { SDesktop* desktop; bool desktopStarted; PixelBuffer* pb; + ScreenSet screenLayout; CharArray name; -- 2.39.5