Implement server side support for SetDesktopSize.
It has some warts, but should be feature complete. Most of the magic happens
in the desktop class though.
git-svn-id: svn://svn.code.sf.net/p/tigervnc/code/trunk@3713 3789f03b-4d11-0410-bbf8-ca57d06f2519
diff --git a/common/rfb/VNCSConnectionST.cxx b/common/rfb/VNCSConnectionST.cxx
index 29c6274..fdcea88 100644
--- a/common/rfb/VNCSConnectionST.cxx
+++ b/common/rfb/VNCSConnectionST.cxx
@@ -191,6 +191,25 @@
}
}
+void VNCSConnectionST::screenLayoutChange(rdr::U16 reason)
+{
+ try {
+ if (!authenticated())
+ return;
+
+ cp.screenLayout = server->screenLayout;
+ if (state() == RFBSTATE_NORMAL) {
+ writer()->writeExtendedDesktopSize(reason, 0, cp.width, cp.height,
+ cp.screenLayout);
+ }
+
+ if (writer()->needFakeUpdate())
+ writeFramebufferUpdate();
+ } catch(rdr::Exception &e) {
+ close(e.str());
+ }
+}
+
void VNCSConnectionST::setColourMapEntriesOrClose(int firstColour,int nColours)
{
try {
@@ -512,8 +531,34 @@
void VNCSConnectionST::setDesktopSize(int fb_width, int fb_height,
const ScreenSet& layout)
{
- vlog.info("Rejecting client request to change desktop size");
- writer()->writeExtendedDesktopSize(resultProhibited);
+ unsigned int result;
+
+ // Don't bother the desktop with an invalid configuration
+ if (!layout.validate(fb_width, fb_height)) {
+ writer()->writeExtendedDesktopSize(reasonClient, resultInvalid,
+ fb_width, fb_height, layout);
+ if (writer()->needFakeUpdate())
+ writeFramebufferUpdate();
+ return;
+ }
+
+ // FIXME: the desktop will call back to VNCServerST and an extra set
+ // of ExtendedDesktopSize messages will be sent. This is okay
+ // protocol-wise, but unnecessary.
+ result = server->desktop->setScreenLayout(fb_width, fb_height, layout);
+
+ // Always send back a reply to the requesting client
+ writer()->writeExtendedDesktopSize(reasonClient, result,
+ fb_width, fb_height, layout);
+ if (writer()->needFakeUpdate())
+ writeFramebufferUpdate();
+
+ // But only notify other clients on success
+ if (result == resultSuccess) {
+ if (server->screenLayout != layout)
+ throw Exception("Desktop configured a different screen layout than requested");
+ server->notifyScreenLayoutChange(this);
+ }
}
void VNCSConnectionST::setInitialColourMap()