Minimal server side implementation of the extended desktop size protocol.
git-svn-id: svn://svn.code.sf.net/p/tigervnc/code/trunk@3698 3789f03b-4d11-0410-bbf8-ca57d06f2519
diff --git a/common/rfb/SMsgWriterV3.cxx b/common/rfb/SMsgWriterV3.cxx
index 1271619..ca6f3f0 100644
--- a/common/rfb/SMsgWriterV3.cxx
+++ b/common/rfb/SMsgWriterV3.cxx
@@ -1,4 +1,5 @@
/* Copyright (C) 2002-2005 RealVNC Ltd. All Rights Reserved.
+ * 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
@@ -18,6 +19,7 @@
#include <rdr/OutStream.h>
#include <rdr/MemOutStream.h>
#include <rfb/msgTypes.h>
+#include <rfb/screenTypes.h>
#include <rfb/Exception.h>
#include <rfb/ConnParams.h>
#include <rfb/SMsgWriterV3.h>
@@ -64,6 +66,15 @@
return true;
}
+bool SMsgWriterV3::writeExtendedDesktopSize(rdr::U16 error) {
+ if (!cp->supportsExtendedDesktopSize) return false;
+ if (error == resultUnsolicited)
+ needExtendedDesktopSize = true;
+ else
+ edsErrors.push_back(error);
+ return true;
+}
+
bool SMsgWriterV3::writeSetDesktopName() {
if (!cp->supportsDesktopRename) return false;
needSetDesktopName = true;
@@ -124,6 +135,8 @@
os->pad(1);
if (wsccb) nRects++;
if (needSetDesktopSize) nRects++;
+ if (needExtendedDesktopSize) nRects++;
+ if (!edsErrors.empty()) nRects += edsErrors.size();
if (needSetDesktopName) nRects++;
os->writeU16(nRects);
nRectsInUpdate = 0;
@@ -144,6 +157,50 @@
void SMsgWriterV3::writeFramebufferUpdateEnd()
{
+ /* Start with responses to SetDesktopSize messages */
+ if (!edsErrors.empty()) {
+ std::list<rdr::U16>::const_iterator iter;
+
+ if (!cp->supportsExtendedDesktopSize)
+ throw Exception("Client does not support extended desktop resize");
+ if ((nRectsInUpdate += edsErrors.size()) > nRectsInHeader && nRectsInHeader)
+ throw Exception("SMsgWriterV3 setExtendedDesktopSize: nRects out of sync");
+
+ for (iter = edsErrors.begin();iter != edsErrors.end();iter++) {
+ os->writeU16(1);
+ os->writeU16(*iter);
+ os->writeU16(0);
+ os->writeU16(0);
+ os->writeU32(pseudoEncodingExtendedDesktopSize);
+ os->writeU8(0); // # screens
+ os->pad(3);
+ }
+
+ edsErrors.clear();
+ }
+
+ /* Send this before SetDesktopSize to make life easier on the clients */
+ if (needExtendedDesktopSize) {
+ if (!cp->supportsExtendedDesktopSize)
+ throw Exception("Client does not support extended desktop resize");
+ if (++nRectsInUpdate > nRectsInHeader && nRectsInHeader)
+ throw Exception("SMsgWriterV3 setExtendedDesktopSize: nRects out of sync");
+ os->writeU16(0);
+ os->writeU16(0);
+ os->writeU16(cp->width);
+ os->writeU16(cp->height);
+ os->writeU32(pseudoEncodingExtendedDesktopSize);
+ os->writeU8(1); // # 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
+ needExtendedDesktopSize = false;
+ }
+
if (needSetDesktopSize) {
if (!cp->supportsDesktopResize)
throw Exception("Client does not support desktop resize");