git-svn-id: svn://svn.code.sf.net/p/tigervnc/code/trunk@3706 3789f03b-4d11-0410-bbf8-ca57d06f2519tags/v0.0.90
os->writeU16(cp->width); | os->writeU16(cp->width); | ||||
os->writeU16(cp->height); | os->writeU16(cp->height); | ||||
os->writeU32(pseudoEncodingExtendedDesktopSize); | os->writeU32(pseudoEncodingExtendedDesktopSize); | ||||
os->writeU8(1); // # screens | |||||
os->writeU8(cp->screenLayout.num_screens()); | |||||
os->pad(3); | 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; | needExtendedDesktopSize = false; | ||||
} | } | ||||
struct ScreenSet { | struct ScreenSet { | ||||
ScreenSet(void) {}; | 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 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 { | inline bool validate(int fb_width, int fb_height) const { | ||||
std::list<Screen>::const_iterator iter; | std::list<Screen>::const_iterator iter; | ||||
std::set<rdr::U32> seen_ids; | std::set<rdr::U32> seen_ids; | ||||
if (screens.empty()) | if (screens.empty()) | ||||
return false; | return false; | ||||
if (num_screens() > 255) | |||||
return false; | |||||
fb_rect.setXYWH(0, 0, fb_width, fb_height); | fb_rect.setXYWH(0, 0, fb_width, fb_height); | ||||
return true; | return true; | ||||
}; | }; | ||||
std::list<Screen> screens; | std::list<Screen> screens; | ||||
}; | }; | ||||
cp.width = server->pb->width(); | cp.width = server->pb->width(); | ||||
cp.height = server->pb->height(); | cp.height = server->pb->height(); | ||||
cp.screenLayout = server->screenLayout; | |||||
if (state() == RFBSTATE_NORMAL) { | if (state() == RFBSTATE_NORMAL) { | ||||
if (!writer()->writeSetDesktopSize() && | if (!writer()->writeSetDesktopSize() && | ||||
!writer()->writeExtendedDesktopSize()) { | !writer()->writeExtendedDesktopSize()) { | ||||
// - Set the connection parameters appropriately | // - Set the connection parameters appropriately | ||||
cp.width = server->pb->width(); | cp.width = server->pb->width(); | ||||
cp.height = server->pb->height(); | cp.height = server->pb->height(); | ||||
cp.screenLayout = server->screenLayout; | |||||
cp.setName(server->getName()); | cp.setName(server->getName()); | ||||
// - Set the default pixel format | // - Set the default pixel format |
cursor.setPF(pb->getPF()); | cursor.setPF(pb->getPF()); | ||||
renderedCursor.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; | std::list<VNCSConnectionST*>::iterator ci, ci_next; | ||||
for (ci=clients.begin();ci!=clients.end();ci=ci_next) { | for (ci=clients.begin();ci!=clients.end();ci=ci_next) { | ||||
ci_next = ci; ci_next++; | ci_next = ci; ci_next++; |
#include <rfb/Cursor.h> | #include <rfb/Cursor.h> | ||||
#include <network/Socket.h> | #include <network/Socket.h> | ||||
#include <rfb/ListConnInfo.h> | #include <rfb/ListConnInfo.h> | ||||
#include <rfb/ScreenSet.h> | |||||
namespace rfb { | namespace rfb { | ||||
SDesktop* desktop; | SDesktop* desktop; | ||||
bool desktopStarted; | bool desktopStarted; | ||||
PixelBuffer* pb; | PixelBuffer* pb; | ||||
ScreenSet screenLayout; | |||||
CharArray name; | CharArray name; | ||||