ConnParams::ConnParams()
: majorVersion(0), minorVersion(0), tightExtensionsEnabled(false),
width(0), height(0), useCopyRect(false),
- supportsLocalCursor(false), supportsLocalXCursor(false), supportsDesktopResize(true), supportsDesktopRename(false),
- supportsLastRect(false), customCompressLevel(false), compressLevel(6),
+ supportsLocalCursor(false), supportsLocalXCursor(false),
+ supportsDesktopResize(false), supportsExtendedDesktopSize(false),
+ supportsDesktopRename(false), supportsLastRect(false),
+ customCompressLevel(false), compressLevel(6),
noJpeg(false), qualityLevel(-1),
name_(0), nEncodings_(0), encodings_(0),
currentEncoding_(encodingRaw), verStrPos(0)
useCopyRect = false;
supportsLocalCursor = false;
supportsDesktopResize = false;
+ supportsExtendedDesktopSize = false;
supportsLocalXCursor = false;
supportsLastRect = false;
customCompressLevel = false;
supportsLocalXCursor = true;
else if (encodings[i] == pseudoEncodingDesktopSize)
supportsDesktopResize = true;
+ else if (encodings[i] == pseudoEncodingExtendedDesktopSize)
+ supportsExtendedDesktopSize = true;
else if (encodings[i] == pseudoEncodingDesktopName)
supportsDesktopRename = true;
else if (encodings[i] == pseudoEncodingLastRect)
bool supportsLocalCursor;
bool supportsLocalXCursor;
bool supportsDesktopResize;
+ bool supportsExtendedDesktopSize;
bool supportsDesktopRename;
bool supportsLastRect;
supportsLocalCursor();
}
-void SMsgHandler::framebufferUpdateRequest(const Rect& r, bool incremental)
+void SMsgHandler::supportsLocalCursor()
{
}
-void SMsgHandler::supportsLocalCursor()
+void SMsgHandler::setDesktopSize(int fb_width, int fb_height)
{
+ cp.width = fb_width;
+ cp.height = fb_height;
}
// The following methods are called as corresponding messages are read. A
// derived class should override these methods as desired. Note that for
- // the setPixelFormat() and setEncodings() methods, a derived class must
- // call on to SMsgHandler's methods.
+ // the setPixelFormat(), setEncodings() and setDesktopSize() methods, a
+ // derived class must call on to SMsgHandler's methods.
virtual void clientInit(bool shared);
virtual void setPixelFormat(const PixelFormat& pf);
virtual void setEncodings(int nEncodings, rdr::U32* encodings);
- virtual void framebufferUpdateRequest(const Rect& r, bool incremental);
+ virtual void framebufferUpdateRequest(const Rect& r, bool incremental) = 0;
+ virtual void setDesktopSize(int fb_width, int fb_height) = 0;
// InputHandler interface
// The InputHandler methods will be called for the corresponding messages.
/* 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
case msgTypeKeyEvent: readKeyEvent(); break;
case msgTypePointerEvent: readPointerEvent(); break;
case msgTypeClientCutText: readClientCutText(); break;
+ case msgTypeSetDesktopSize: readSetDesktopSize(); break;
default:
fprintf(stderr, "unknown message type %d\n", msgType);
throw Exception("unknown message type");
}
}
+
+void SMsgReaderV3::readSetDesktopSize()
+{
+ int width, height;
+ int screens, i;
+
+ is->skip(1);
+
+ width = is->readU16();
+ height = is->readU16();
+
+ screens = is->readU8();
+ is->skip(1);
+
+ // XXX: We don't support this command properly yet
+ is->skip(screens * 16);
+
+ handler->setDesktopSize(width, height);
+}
+
/* 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
virtual ~SMsgReaderV3();
virtual void readClientInit();
virtual void readMsg();
+ protected:
+ virtual void readSetDesktopSize();
};
}
#endif
#include <rdr/types.h>
#include <rfb/encodings.h>
+#include <rfb/screenTypes.h>
#include <rfb/Encoder.h>
#include <rfb/PixelBuffer.h>
// writeSetDesktopSize() on a V3 writer won't actually write immediately,
// but will write the relevant pseudo-rectangle as part of the next update.
virtual bool writeSetDesktopSize()=0;
+ // Same thing for the extended version
+ virtual bool writeExtendedDesktopSize(rdr::U16 error = resultUnsolicited)=0;
virtual bool writeSetDesktopName()=0;
/* 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
#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>
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;
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;
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");
/* 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
#ifndef __RFB_SMSGWRITERV3_H__
#define __RFB_SMSGWRITERV3_H__
+#include <list>
+
#include <rfb/SMsgWriter.h>
namespace rdr { class MemOutStream; }
virtual void startMsg(int type);
virtual void endMsg();
virtual bool writeSetDesktopSize();
+ virtual bool writeExtendedDesktopSize(rdr::U16 error);
virtual bool writeSetDesktopName();
virtual void cursorChange(WriteSetCursorCallback* cb);
virtual void writeSetCursor(int width, int height, const Point& hotspot,
int nRectsInHeader;
WriteSetCursorCallback* wsccb;
bool needSetDesktopSize;
+ bool needExtendedDesktopSize;
+ std::list<rdr::U16> edsErrors;
bool needSetDesktopName;
bool needLastRect;
};
/* 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
#include <rfb/VNCSConnectionST.h>
#include <rfb/LogWriter.h>
#include <rfb/secTypes.h>
+#include <rfb/screenTypes.h>
#include <rfb/ServerCore.h>
#include <rfb/ComparingUpdateTracker.h>
#include <rfb/KeyRemapper.h>
cp.width = server->pb->width();
cp.height = server->pb->height();
if (state() == RFBSTATE_NORMAL) {
- if (!writer()->writeSetDesktopSize()) {
+ if (!writer()->writeSetDesktopSize() &&
+ !writer()->writeExtendedDesktopSize()) {
close("Client does not support desktop resize");
return;
}
// Non-incremental update - treat as if area requested has changed
updates.add_changed(reqRgn);
server->comparer->add_changed(reqRgn);
+ // And update the clients view of screen layout
+ writer()->writeSetDesktopSize();
+ writer()->writeExtendedDesktopSize();
}
}
+void VNCSConnectionST::setDesktopSize(int fb_width, int fb_height)
+{
+ vlog.info("Rejecting client request to change desktop size");
+ writer()->writeExtendedDesktopSize(resultProhibited);
+}
+
void VNCSConnectionST::setInitialColourMap()
{
setColourMapEntries(0, 0);
/* 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
virtual void keyEvent(rdr::U32 key, bool down);
virtual void clientCutText(const char* str, int len);
virtual void framebufferUpdateRequest(const Rect& r, bool incremental);
+ virtual void setDesktopSize(int fb_width, int fb_height);
virtual void setInitialColourMap();
virtual void supportsLocalCursor();
const unsigned int pseudoEncodingXCursor = 0xffffff10;
const unsigned int pseudoEncodingCursor = 0xffffff11;
const unsigned int pseudoEncodingDesktopSize = 0xffffff21;
+ const unsigned int pseudoEncodingExtendedDesktopSize = 0xfffffecb; // FIXME: Unofficial
const unsigned int pseudoEncodingDesktopName = 0xfffffecdl;
// TightVNC-specific
const int msgTypeClientCutText = 6;
const int msgTypeEnableContinuousUpdates = 150;
+
+ const int msgTypeSetDesktopSize = 251; // FIXME: Unofficial
}
#endif
--- /dev/null
+/* 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
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this software; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+ * USA.
+ */
+#ifndef __RFB_SCREENTYPES_H__
+#define __RFB_SCREENTYPES_H__
+
+namespace rfb {
+
+ // Reasons
+ const unsigned int reasonServer = 0;
+ const unsigned int reasonClient = 1;
+ const unsigned int reasonOtherClient = 2;
+
+ // Result codes
+ const unsigned int resultSuccess = 0;
+ const unsigned int resultProhibited = 1;
+ const unsigned int resultNoResources = 2;
+ const unsigned int resultInvalid = 3;
+
+ const int resultUnsolicited = 0xffff; // internal code used for server changes
+
+}
+#endif