git-svn-id: svn://svn.code.sf.net/p/tigervnc/code/trunk@3698 3789f03b-4d11-0410-bbf8-ca57d06f2519tags/v0.0.90
@@ -29,8 +29,10 @@ using namespace rfb; | |||
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) | |||
@@ -92,6 +94,7 @@ void ConnParams::setEncodings(int nEncodings, const rdr::U32* encodings) | |||
useCopyRect = false; | |||
supportsLocalCursor = false; | |||
supportsDesktopResize = false; | |||
supportsExtendedDesktopSize = false; | |||
supportsLocalXCursor = false; | |||
supportsLastRect = false; | |||
customCompressLevel = false; | |||
@@ -111,6 +114,8 @@ void ConnParams::setEncodings(int nEncodings, const rdr::U32* encodings) | |||
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) |
@@ -73,6 +73,7 @@ namespace rfb { | |||
bool supportsLocalCursor; | |||
bool supportsLocalXCursor; | |||
bool supportsDesktopResize; | |||
bool supportsExtendedDesktopSize; | |||
bool supportsDesktopRename; | |||
bool supportsLastRect; | |||
@@ -43,11 +43,13 @@ void SMsgHandler::setEncodings(int nEncodings, rdr::U32* encodings) | |||
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; | |||
} | |||
@@ -38,14 +38,15 @@ namespace rfb { | |||
// 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. |
@@ -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 | |||
@@ -51,9 +52,30 @@ void SMsgReaderV3::readMsg() | |||
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); | |||
} | |||
@@ -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 | |||
@@ -27,6 +28,8 @@ namespace rfb { | |||
virtual ~SMsgReaderV3(); | |||
virtual void readClientInit(); | |||
virtual void readMsg(); | |||
protected: | |||
virtual void readSetDesktopSize(); | |||
}; | |||
} | |||
#endif |
@@ -24,6 +24,7 @@ | |||
#include <rdr/types.h> | |||
#include <rfb/encodings.h> | |||
#include <rfb/screenTypes.h> | |||
#include <rfb/Encoder.h> | |||
#include <rfb/PixelBuffer.h> | |||
@@ -74,6 +75,8 @@ namespace rfb { | |||
// 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; | |||
@@ -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 @@ bool SMsgWriterV3::writeSetDesktopSize() { | |||
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 @@ void SMsgWriterV3::writeFramebufferUpdateStart(int nRects) | |||
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::writeFramebufferUpdateStart() | |||
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"); |
@@ -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,8 @@ | |||
#ifndef __RFB_SMSGWRITERV3_H__ | |||
#define __RFB_SMSGWRITERV3_H__ | |||
#include <list> | |||
#include <rfb/SMsgWriter.h> | |||
namespace rdr { class MemOutStream; } | |||
@@ -32,6 +35,7 @@ namespace rfb { | |||
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, | |||
@@ -52,6 +56,8 @@ namespace rfb { | |||
int nRectsInHeader; | |||
WriteSetCursorCallback* wsccb; | |||
bool needSetDesktopSize; | |||
bool needExtendedDesktopSize; | |||
std::list<rdr::U16> edsErrors; | |||
bool needSetDesktopName; | |||
bool needLastRect; | |||
}; |
@@ -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 | |||
@@ -19,6 +20,7 @@ | |||
#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> | |||
@@ -168,7 +170,8 @@ void VNCSConnectionST::pixelBufferChange() | |||
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; | |||
} | |||
@@ -490,9 +493,18 @@ void VNCSConnectionST::framebufferUpdateRequest(const Rect& r,bool incremental) | |||
// 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); |
@@ -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 | |||
@@ -124,6 +125,7 @@ namespace rfb { | |||
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(); | |||
@@ -33,6 +33,7 @@ namespace rfb { | |||
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 |
@@ -39,5 +39,7 @@ namespace rfb { | |||
const int msgTypeClientCutText = 6; | |||
const int msgTypeEnableContinuousUpdates = 150; | |||
const int msgTypeSetDesktopSize = 251; // FIXME: Unofficial | |||
} | |||
#endif |
@@ -0,0 +1,37 @@ | |||
/* 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 |