We have no need for this abstraction so let's keep things simple.
#include <string.h>
#include <rfb/Exception.h>
#include <rfb/fenceTypes.h>
-#include <rfb/CMsgReaderV3.h>
-#include <rfb/CMsgWriterV3.h>
+#include <rfb/CMsgReader.h>
+#include <rfb/CMsgWriter.h>
#include <rfb/CSecurity.h>
#include <rfb/Security.h>
#include <rfb/CConnection.h>
void CConnection::securityCompleted()
{
state_ = RFBSTATE_INITIALISATION;
- reader_ = new CMsgReaderV3(this, is);
- writer_ = new CMsgWriterV3(&cp, os);
+ reader_ = new CMsgReader(this, is);
+ writer_ = new CMsgWriter(&cp, os);
vlog.debug("Authentication success!");
authSuccess();
writer_->writeClientInit(shared);
CConnection.cxx
CMsgHandler.cxx
CMsgReader.cxx
- CMsgReaderV3.cxx
CMsgWriter.cxx
- CMsgWriterV3.cxx
CSecurityPlain.cxx
CSecurityStack.cxx
CSecurityVeNCrypt.cxx
SConnection.cxx
SMsgHandler.cxx
SMsgReader.cxx
- SMsgReaderV3.cxx
SMsgWriter.cxx
- SMsgWriterV3.cxx
ServerCore.cxx
Security.cxx
SecurityServer.cxx
/* Copyright (C) 2002-2005 RealVNC Ltd. All Rights Reserved.
+ * Copyright 2009-2014 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
* USA.
*/
#include <stdio.h>
+#include <rfb/msgTypes.h>
#include <rdr/InStream.h>
#include <rfb/Exception.h>
#include <rfb/util.h>
#include <rfb/CMsgHandler.h>
#include <rfb/CMsgReader.h>
+#include <rfb/Decoder.h>
using namespace rfb;
CMsgReader::CMsgReader(CMsgHandler* handler_, rdr::InStream* is_)
: imageBufIdealSize(0), handler(handler_), is(is_),
- imageBuf(0), imageBufSize(0)
+ imageBuf(0), imageBufSize(0), nUpdateRectsLeft(0)
{
for (int i = 0; i <= encodingMax; i++) {
decoders[i] = 0;
delete [] imageBuf;
}
+void CMsgReader::readServerInit()
+{
+ int width = is->readU16();
+ int height = is->readU16();
+ handler->setDesktopSize(width, height);
+ PixelFormat pf;
+ pf.read(is);
+ handler->setPixelFormat(pf);
+ CharArray name(is->readString());
+ handler->setName(name.buf);
+ handler->serverInit();
+}
+
+void CMsgReader::readMsg()
+{
+ if (nUpdateRectsLeft == 0) {
+ int type = is->readU8();
+
+ switch (type) {
+ case msgTypeSetColourMapEntries:
+ readSetColourMapEntries();
+ break;
+ case msgTypeBell:
+ readBell();
+ break;
+ case msgTypeServerCutText:
+ readServerCutText();
+ break;
+ case msgTypeFramebufferUpdate:
+ readFramebufferUpdate();
+ break;
+ case msgTypeServerFence:
+ readFence();
+ break;
+ case msgTypeEndOfContinuousUpdates:
+ readEndOfContinuousUpdates();
+ break;
+ default:
+ fprintf(stderr, "unknown message type %d\n", type);
+ throw Exception("unknown message type");
+ }
+ } else {
+ int x = is->readU16();
+ int y = is->readU16();
+ int w = is->readU16();
+ int h = is->readU16();
+ int encoding = is->readS32();
+
+ switch (encoding) {
+ case pseudoEncodingLastRect:
+ nUpdateRectsLeft = 1; // this rectangle is the last one
+ break;
+ case pseudoEncodingCursor:
+ readSetCursor(w, h, Point(x,y));
+ break;
+ case pseudoEncodingDesktopName:
+ readSetDesktopName(x, y, w, h);
+ break;
+ case pseudoEncodingDesktopSize:
+ handler->setDesktopSize(w, h);
+ break;
+ case pseudoEncodingExtendedDesktopSize:
+ readExtendedDesktopSize(x, y, w, h);
+ break;
+ default:
+ readRect(Rect(x, y, x+w, y+h), encoding);
+ break;
+ };
+
+ nUpdateRectsLeft--;
+ if (nUpdateRectsLeft == 0)
+ handler->framebufferUpdateEnd();
+ }
+}
+
void CMsgReader::readSetColourMapEntries()
{
is->skip(1);
handler->serverCutText(ca.buf, len);
}
-void CMsgReader::readFramebufferUpdateStart()
+void CMsgReader::readFence()
{
- handler->framebufferUpdateStart();
+ rdr::U32 flags;
+ rdr::U8 len;
+ char data[64];
+
+ is->skip(3);
+
+ flags = is->readU32();
+
+ len = is->readU8();
+ if (len > sizeof(data)) {
+ fprintf(stderr, "Ignoring fence with too large payload\n");
+ is->skip(len);
+ return;
+ }
+
+ is->readBytes(data, len);
+
+ handler->fence(flags, len, data);
}
-void CMsgReader::readFramebufferUpdateEnd()
+void CMsgReader::readEndOfContinuousUpdates()
{
- handler->framebufferUpdateEnd();
+ handler->endOfContinuousUpdates();
+}
+
+void CMsgReader::readFramebufferUpdate()
+{
+ is->skip(1);
+ nUpdateRectsLeft = is->readU16();
+ handler->framebufferUpdateStart();
}
void CMsgReader::readRect(const Rect& r, int encoding)
handler->setCursor(width, height, hotspot, data.buf, mask.buf);
}
+void CMsgReader::readSetDesktopName(int x, int y, int w, int h)
+{
+ char* name = is->readString();
+
+ if (x || y || w || h) {
+ fprintf(stderr, "Ignoring DesktopName rect with non-zero position/size\n");
+ } else {
+ handler->setName(name);
+ }
+
+ delete [] name;
+}
+
+void CMsgReader::readExtendedDesktopSize(int x, int y, int w, int h)
+{
+ unsigned int screens, i;
+ rdr::U32 id, flags;
+ int sx, sy, sw, sh;
+ ScreenSet layout;
+
+ screens = is->readU8();
+ is->skip(3);
+
+ for (i = 0;i < screens;i++) {
+ id = is->readU32();
+ sx = is->readU16();
+ sy = is->readU16();
+ sw = is->readU16();
+ sh = is->readU16();
+ flags = is->readU32();
+
+ layout.add_screen(Screen(id, sx, sy, sw, sh, flags));
+ }
+
+ handler->setExtendedDesktopSize(x, y, w, h, layout);
+}
+
rdr::U8* CMsgReader::getImageBuf(int required, int requested, int* nPixels)
{
int requiredBytes = required * (handler->cp.pf().bpp / 8);
/* Copyright (C) 2002-2005 RealVNC Ltd. All Rights Reserved.
+ * Copyright 2009-2014 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
#define __RFB_CMSGREADER_H__
#include <rdr/types.h>
+
+#include <rfb/Rect.h>
#include <rfb/encodings.h>
-#include <rfb/Decoder.h>
namespace rdr { class InStream; }
namespace rfb {
class CMsgHandler;
+ class Decoder;
struct Rect;
class CMsgReader {
public:
+ CMsgReader(CMsgHandler* handler, rdr::InStream* is);
virtual ~CMsgReader();
- virtual void readServerInit()=0;
+ void readServerInit();
// readMsg() reads a message, calling the handler as appropriate.
- virtual void readMsg()=0;
+ void readMsg();
rdr::InStream* getInStream() { return is; }
rdr::U8* getImageBuf(int required, int requested=0, int* nPixels=0);
int imageBufIdealSize;
protected:
- virtual void readSetColourMapEntries();
- virtual void readBell();
- virtual void readServerCutText();
+ void readSetColourMapEntries();
+ void readBell();
+ void readServerCutText();
+ void readFence();
+ void readEndOfContinuousUpdates();
- virtual void readFramebufferUpdateStart();
- virtual void readFramebufferUpdateEnd();
- virtual void readRect(const Rect& r, int encoding);
+ void readFramebufferUpdate();
- virtual void readCopyRect(const Rect& r);
+ void readRect(const Rect& r, int encoding);
+ void readCopyRect(const Rect& r);
- virtual void readSetCursor(int width, int height, const Point& hotspot);
-
- CMsgReader(CMsgHandler* handler, rdr::InStream* is);
+ void readSetCursor(int width, int height, const Point& hotspot);
+ void readSetDesktopName(int x, int y, int w, int h);
+ void readExtendedDesktopSize(int x, int y, int w, int h);
CMsgHandler* handler;
rdr::InStream* is;
Decoder* decoders[encodingMax+1];
rdr::U8* imageBuf;
int imageBufSize;
+ int nUpdateRectsLeft;
};
}
#endif
+++ /dev/null
-/* Copyright (C) 2002-2005 RealVNC Ltd. All Rights Reserved.
- * Copyright 2009-2011 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.
- */
-#include <rfb/PixelFormat.h>
-#include <rfb/msgTypes.h>
-#include <rfb/Exception.h>
-#include <rdr/InStream.h>
-#include <rfb/CMsgReaderV3.h>
-#include <rfb/CMsgHandler.h>
-#include <rfb/util.h>
-#include <rfb/ScreenSet.h>
-#include <stdio.h>
-
-using namespace rfb;
-
-CMsgReaderV3::CMsgReaderV3(CMsgHandler* handler, rdr::InStream* is)
- : CMsgReader(handler, is), nUpdateRectsLeft(0)
-{
-}
-
-CMsgReaderV3::~CMsgReaderV3()
-{
-}
-
-void CMsgReaderV3::readServerInit()
-{
- int width = is->readU16();
- int height = is->readU16();
- handler->setDesktopSize(width, height);
- PixelFormat pf;
- pf.read(is);
- handler->setPixelFormat(pf);
- CharArray name(is->readString());
- handler->setName(name.buf);
- handler->serverInit();
-}
-
-void CMsgReaderV3::readMsg()
-{
- if (nUpdateRectsLeft == 0) {
-
- int type = is->readU8();
- switch (type) {
- case msgTypeFramebufferUpdate: readFramebufferUpdate(); break;
- case msgTypeSetColourMapEntries: readSetColourMapEntries(); break;
- case msgTypeBell: readBell(); break;
- case msgTypeServerCutText: readServerCutText(); break;
- case msgTypeServerFence: readFence(); break;
- case msgTypeEndOfContinuousUpdates: readEndOfContinuousUpdates(); break;
-
- default:
- fprintf(stderr, "unknown message type %d\n", type);
- throw Exception("unknown message type");
- }
-
- } else {
-
- int x = is->readU16();
- int y = is->readU16();
- int w = is->readU16();
- int h = is->readU16();
- int encoding = is->readS32();
-
- switch (encoding) {
- case pseudoEncodingDesktopSize:
- handler->setDesktopSize(w, h);
- break;
- case pseudoEncodingExtendedDesktopSize:
- readExtendedDesktopSize(x, y, w, h);
- break;
- case pseudoEncodingDesktopName:
- readSetDesktopName(x, y, w, h);
- break;
- case pseudoEncodingCursor:
- readSetCursor(w, h, Point(x,y));
- break;
- case pseudoEncodingLastRect:
- nUpdateRectsLeft = 1; // this rectangle is the last one
- break;
- default:
- readRect(Rect(x, y, x+w, y+h), encoding);
- break;
- };
-
- nUpdateRectsLeft--;
- if (nUpdateRectsLeft == 0) handler->framebufferUpdateEnd();
- }
-}
-
-void CMsgReaderV3::readFramebufferUpdate()
-{
- is->skip(1);
- nUpdateRectsLeft = is->readU16();
- handler->framebufferUpdateStart();
-}
-
-void CMsgReaderV3::readSetDesktopName(int x, int y, int w, int h)
-{
- char* name = is->readString();
-
- if (x || y || w || h) {
- fprintf(stderr, "Ignoring DesktopName rect with non-zero position/size\n");
- } else {
- handler->setName(name);
- }
-
- delete [] name;
-}
-
-void CMsgReaderV3::readExtendedDesktopSize(int x, int y, int w, int h)
-{
- unsigned int screens, i;
- rdr::U32 id, flags;
- int sx, sy, sw, sh;
- ScreenSet layout;
-
- screens = is->readU8();
- is->skip(3);
-
- for (i = 0;i < screens;i++) {
- id = is->readU32();
- sx = is->readU16();
- sy = is->readU16();
- sw = is->readU16();
- sh = is->readU16();
- flags = is->readU32();
-
- layout.add_screen(Screen(id, sx, sy, sw, sh, flags));
- }
-
- handler->setExtendedDesktopSize(x, y, w, h, layout);
-}
-
-void CMsgReaderV3::readFence()
-{
- rdr::U32 flags;
- rdr::U8 len;
- char data[64];
-
- is->skip(3);
-
- flags = is->readU32();
-
- len = is->readU8();
- if (len > sizeof(data)) {
- fprintf(stderr, "Ignoring fence with too large payload\n");
- is->skip(len);
- return;
- }
-
- is->readBytes(data, len);
-
- handler->fence(flags, len, data);
-}
-
-void CMsgReaderV3::readEndOfContinuousUpdates()
-{
- handler->endOfContinuousUpdates();
-}
+++ /dev/null
-/* Copyright (C) 2002-2005 RealVNC Ltd. All Rights Reserved.
- * Copyright 2009-2011 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_CMSGREADERV3_H__
-#define __RFB_CMSGREADERV3_H__
-
-#include <rfb/CMsgReader.h>
-
-namespace rfb {
- class CMsgReaderV3 : public CMsgReader {
- public:
- CMsgReaderV3(CMsgHandler* handler, rdr::InStream* is);
- virtual ~CMsgReaderV3();
- virtual void readServerInit();
- virtual void readMsg();
- private:
- virtual void readFramebufferUpdate();
- virtual void readSetDesktopName(int x, int y, int w, int h);
- virtual void readExtendedDesktopSize(int x, int y, int w, int h);
- virtual void readFence();
- virtual void readEndOfContinuousUpdates();
- int nUpdateRectsLeft;
- };
-}
-#endif
/* Copyright (C) 2002-2005 RealVNC Ltd. All Rights Reserved.
+ * Copyright 2009-2014 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 <stdio.h>
#include <rdr/OutStream.h>
#include <rfb/msgTypes.h>
+#include <rfb/fenceTypes.h>
#include <rfb/encodings.h>
+#include <rfb/Exception.h>
#include <rfb/PixelFormat.h>
#include <rfb/Rect.h>
#include <rfb/ConnParams.h>
{
}
+void CMsgWriter::writeClientInit(bool shared)
+{
+ os->writeU8(shared);
+ endMsg();
+}
+
void CMsgWriter::writeSetPixelFormat(const PixelFormat& pf)
{
startMsg(msgTypeSetPixelFormat);
writeSetEncodings(nEncodings, encodings);
}
-
+
+void CMsgWriter::writeSetDesktopSize(int width, int height,
+ const ScreenSet& layout)
+{
+ if (!cp->supportsSetDesktopSize)
+ throw Exception("Server does not support SetDesktopSize");
+
+ startMsg(msgTypeSetDesktopSize);
+ os->pad(1);
+
+ os->writeU16(width);
+ os->writeU16(height);
+
+ os->writeU8(layout.num_screens());
+ os->pad(1);
+
+ ScreenSet::const_iterator iter;
+ for (iter = layout.begin();iter != layout.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);
+ }
+
+ endMsg();
+}
+
void CMsgWriter::writeFramebufferUpdateRequest(const Rect& r, bool incremental)
{
startMsg(msgTypeFramebufferUpdateRequest);
endMsg();
}
+void CMsgWriter::writeEnableContinuousUpdates(bool enable,
+ int x, int y, int w, int h)
+{
+ if (!cp->supportsContinuousUpdates)
+ throw Exception("Server does not support continuous updates");
+
+ startMsg(msgTypeEnableContinuousUpdates);
+
+ os->writeU8(!!enable);
+
+ os->writeU16(x);
+ os->writeU16(y);
+ os->writeU16(w);
+ os->writeU16(h);
+
+ endMsg();
+}
+
+void CMsgWriter::writeFence(rdr::U32 flags, unsigned len, const char data[])
+{
+ if (!cp->supportsFence)
+ throw Exception("Server does not support fences");
+ if (len > 64)
+ throw Exception("Too large fence payload");
+ if ((flags & ~fenceFlagsSupported) != 0)
+ throw Exception("Unknown fence flags");
+
+ startMsg(msgTypeClientFence);
+ os->pad(3);
+
+ os->writeU32(flags);
+
+ os->writeU8(len);
+ os->writeBytes(data, len);
+
+ endMsg();
+}
void CMsgWriter::keyEvent(rdr::U32 key, bool down)
{
os->writeBytes(str, len);
endMsg();
}
+
+void CMsgWriter::startMsg(int type)
+{
+ os->writeU8(type);
+}
+
+void CMsgWriter::endMsg()
+{
+ os->flush();
+}
/* Copyright (C) 2002-2005 RealVNC Ltd. All Rights Reserved.
- * Copyright 2009-2011 Pierre Ossman for Cendio AB
+ * Copyright 2009-2014 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_CMSGWRITER_H__
#define __RFB_CMSGWRITER_H__
+#include <rdr/types.h>
+
#include <rfb/InputHandler.h>
-#include <rfb/ScreenSet.h>
namespace rdr { class OutStream; }
class PixelFormat;
class ConnParams;
+ class ScreenSet;
struct Rect;
class CMsgWriter : public InputHandler {
public:
+ CMsgWriter(ConnParams* cp, rdr::OutStream* os);
virtual ~CMsgWriter();
- // CMsgWriter abstract interface methods
- virtual void writeClientInit(bool shared)=0;
- virtual void startMsg(int type)=0;
- virtual void endMsg()=0;
+ void writeClientInit(bool shared);
+
+ void writeSetPixelFormat(const PixelFormat& pf);
+ void writeSetEncodings(int nEncodings, rdr::U32* encodings);
+ void writeSetEncodings(int preferredEncoding, bool useCopyRect);
+ void writeSetDesktopSize(int width, int height, const ScreenSet& layout);
- virtual void writeSetDesktopSize(int width, int height,
- const ScreenSet& layout)=0;
- virtual void writeFence(rdr::U32 flags, unsigned len, const char data[])=0;
- virtual void writeEnableContinuousUpdates(bool enable,
- int x, int y, int w, int h)=0;
+ void writeFramebufferUpdateRequest(const Rect& r,bool incremental);
+ void writeEnableContinuousUpdates(bool enable, int x, int y, int w, int h);
- // CMsgWriter implemented methods
- virtual void writeSetPixelFormat(const PixelFormat& pf);
- virtual void writeSetEncodings(int nEncodings, rdr::U32* encodings);
- virtual void writeSetEncodings(int preferredEncoding, bool useCopyRect);
- virtual void writeFramebufferUpdateRequest(const Rect& r,bool incremental);
+ void writeFence(rdr::U32 flags, unsigned len, const char data[]);
+
+ ConnParams* getConnParams() { return cp; }
+ rdr::OutStream* getOutStream() { return os; }
// InputHandler implementation
+
virtual void keyEvent(rdr::U32 key, bool down);
virtual void pointerEvent(const Point& pos, int buttonMask);
virtual void clientCutText(const char* str, rdr::U32 len);
- ConnParams* getConnParams() { return cp; }
- rdr::OutStream* getOutStream() { return os; }
-
protected:
- CMsgWriter(ConnParams* cp, rdr::OutStream* os);
+ void startMsg(int type);
+ void endMsg();
ConnParams* cp;
rdr::OutStream* os;
+++ /dev/null
-/* Copyright (C) 2002-2005 RealVNC Ltd. All Rights Reserved.
- * Copyright 2009-2011 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.
- */
-#include <rdr/OutStream.h>
-#include <rfb/msgTypes.h>
-#include <rfb/fenceTypes.h>
-#include <rfb/Exception.h>
-#include <rfb/ConnParams.h>
-#include <rfb/CMsgWriterV3.h>
-
-using namespace rfb;
-
-CMsgWriterV3::CMsgWriterV3(ConnParams* cp, rdr::OutStream* os)
- : CMsgWriter(cp, os)
-{
-}
-
-CMsgWriterV3::~CMsgWriterV3()
-{
-}
-
-void CMsgWriterV3::writeClientInit(bool shared)
-{
- os->writeU8(shared);
- endMsg();
-}
-
-void CMsgWriterV3::startMsg(int type)
-{
- os->writeU8(type);
-}
-
-void CMsgWriterV3::endMsg()
-{
- os->flush();
-}
-
-void CMsgWriterV3::writeSetDesktopSize(int width, int height,
- const ScreenSet& layout)
-{
- if (!cp->supportsSetDesktopSize)
- throw Exception("Server does not support SetDesktopSize");
-
- startMsg(msgTypeSetDesktopSize);
- os->pad(1);
-
- os->writeU16(width);
- os->writeU16(height);
-
- os->writeU8(layout.num_screens());
- os->pad(1);
-
- ScreenSet::const_iterator iter;
- for (iter = layout.begin();iter != layout.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);
- }
-
- endMsg();
-}
-
-void CMsgWriterV3::writeFence(rdr::U32 flags, unsigned len, const char data[])
-{
- if (!cp->supportsFence)
- throw Exception("Server does not support fences");
- if (len > 64)
- throw Exception("Too large fence payload");
- if ((flags & ~fenceFlagsSupported) != 0)
- throw Exception("Unknown fence flags");
-
- startMsg(msgTypeClientFence);
- os->pad(3);
-
- os->writeU32(flags);
-
- os->writeU8(len);
- os->writeBytes(data, len);
-
- endMsg();
-}
-
-void CMsgWriterV3::writeEnableContinuousUpdates(bool enable,
- int x, int y, int w, int h)
-{
- if (!cp->supportsContinuousUpdates)
- throw Exception("Server does not support continuous updates");
-
- startMsg(msgTypeEnableContinuousUpdates);
-
- os->writeU8(!!enable);
-
- os->writeU16(x);
- os->writeU16(y);
- os->writeU16(w);
- os->writeU16(h);
-
- endMsg();
-}
+++ /dev/null
-/* Copyright (C) 2002-2005 RealVNC Ltd. All Rights Reserved.
- * Copyright 2009-2011 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_CMSGWRITERV3_H__
-#define __RFB_CMSGWRITERV3_H__
-
-#include <rfb/CMsgWriter.h>
-
-namespace rfb {
- class CMsgWriterV3 : public CMsgWriter {
- public:
- CMsgWriterV3(ConnParams* cp, rdr::OutStream* os);
- virtual ~CMsgWriterV3();
-
- virtual void writeClientInit(bool shared);
- virtual void startMsg(int type);
- virtual void endMsg();
-
- virtual void writeSetDesktopSize(int width, int height,
- const ScreenSet& layout);
- virtual void writeFence(rdr::U32 flags, unsigned len, const char data[]);
- virtual void writeEnableContinuousUpdates(bool enable,
- int x, int y, int w, int h);
- };
-}
-#endif
#include <rfb/Security.h>
#include <rfb/msgTypes.h>
#include <rfb/fenceTypes.h>
-#include <rfb/SMsgReaderV3.h>
-#include <rfb/SMsgWriterV3.h>
+#include <rfb/SMsgReader.h>
+#include <rfb/SMsgWriter.h>
#include <rfb/SConnection.h>
#include <rfb/ServerCore.h>
if (accept) {
state_ = RFBSTATE_INITIALISATION;
- reader_ = new SMsgReaderV3(this, is);
- writer_ = new SMsgWriterV3(&cp, os);
+ reader_ = new SMsgReader(this, is);
+ writer_ = new SMsgWriter(&cp, os);
authSuccess();
} else {
state_ = RFBSTATE_INVALID;
/* Copyright (C) 2002-2005 RealVNC Ltd. All Rights Reserved.
+ * Copyright 2009-2014 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 <stdio.h>
#include <rdr/InStream.h>
+#include <rfb/msgTypes.h>
#include <rfb/Exception.h>
#include <rfb/util.h>
#include <rfb/SMsgHandler.h>
{
}
+void SMsgReader::readClientInit()
+{
+ bool shared = is->readU8();
+ handler->clientInit(shared);
+}
+
+void SMsgReader::readMsg()
+{
+ int msgType = is->readU8();
+ switch (msgType) {
+ case msgTypeSetPixelFormat:
+ readSetPixelFormat();
+ break;
+ case msgTypeSetEncodings:
+ readSetEncodings();
+ break;
+ case msgTypeSetDesktopSize:
+ readSetDesktopSize();
+ break;
+ case msgTypeFramebufferUpdateRequest:
+ readFramebufferUpdateRequest();
+ break;
+ case msgTypeEnableContinuousUpdates:
+ readEnableContinuousUpdates();
+ break;
+ case msgTypeClientFence:
+ readFence();
+ break;
+ case msgTypeKeyEvent:
+ readKeyEvent();
+ break;
+ case msgTypePointerEvent:
+ readPointerEvent();
+ break;
+ case msgTypeClientCutText:
+ readClientCutText();
+ break;
+ default:
+ fprintf(stderr, "unknown message type %d\n", msgType);
+ throw Exception("unknown message type");
+ }
+}
+
void SMsgReader::readSetPixelFormat()
{
is->skip(3);
handler->setEncodings(nEncodings, encodings.buf);
}
+void SMsgReader::readSetDesktopSize()
+{
+ int width, height;
+ int screens, i;
+ rdr::U32 id, flags;
+ int sx, sy, sw, sh;
+ ScreenSet layout;
+
+ is->skip(1);
+
+ width = is->readU16();
+ height = is->readU16();
+
+ screens = is->readU8();
+ is->skip(1);
+
+ for (i = 0;i < screens;i++) {
+ id = is->readU32();
+ sx = is->readU16();
+ sy = is->readU16();
+ sw = is->readU16();
+ sh = is->readU16();
+ flags = is->readU32();
+
+ layout.add_screen(Screen(id, sx, sy, sw, sh, flags));
+ }
+
+ handler->setDesktopSize(width, height, layout);
+}
+
void SMsgReader::readFramebufferUpdateRequest()
{
bool inc = is->readU8();
handler->framebufferUpdateRequest(Rect(x, y, x+w, y+h), inc);
}
+void SMsgReader::readEnableContinuousUpdates()
+{
+ bool enable;
+ int x, y, w, h;
+
+ enable = is->readU8();
+
+ x = is->readU16();
+ y = is->readU16();
+ w = is->readU16();
+ h = is->readU16();
+
+ handler->enableContinuousUpdates(enable, x, y, w, h);
+}
+
+void SMsgReader::readFence()
+{
+ rdr::U32 flags;
+ rdr::U8 len;
+ char data[64];
+
+ is->skip(3);
+
+ flags = is->readU32();
+
+ len = is->readU8();
+ if (len > sizeof(data)) {
+ fprintf(stderr, "Ignoring fence with too large payload\n");
+ is->skip(len);
+ return;
+ }
+
+ is->readBytes(data, len);
+
+ handler->fence(flags, len, data);
+}
+
void SMsgReader::readKeyEvent()
{
bool down = is->readU8();
/* Copyright (C) 2002-2005 RealVNC Ltd. All Rights Reserved.
+ * Copyright 2009-2014 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
class SMsgReader {
public:
+ SMsgReader(SMsgHandler* handler, rdr::InStream* is);
virtual ~SMsgReader();
- virtual void readClientInit()=0;
+ void readClientInit();
// readMsg() reads a message, calling the handler as appropriate.
- virtual void readMsg()=0;
+ void readMsg();
rdr::InStream* getInStream() { return is; }
protected:
- virtual void readSetPixelFormat();
- virtual void readSetEncodings();
- virtual void readFramebufferUpdateRequest();
- virtual void readKeyEvent();
- virtual void readPointerEvent();
- virtual void readClientCutText();
+ void readSetPixelFormat();
+ void readSetEncodings();
+ void readSetDesktopSize();
- SMsgReader(SMsgHandler* handler, rdr::InStream* is);
+ void readFramebufferUpdateRequest();
+ void readEnableContinuousUpdates();
+
+ void readFence();
+
+ void readKeyEvent();
+ void readPointerEvent();
+ void readClientCutText();
SMsgHandler* handler;
rdr::InStream* is;
+++ /dev/null
-/* Copyright (C) 2002-2005 RealVNC Ltd. All Rights Reserved.
- * Copyright 2009-2011 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.
- */
-
-#include <stdio.h>
-#include <rfb/PixelFormat.h>
-#include <rfb/msgTypes.h>
-#include <rfb/Exception.h>
-#include <rdr/InStream.h>
-#include <rfb/SMsgReaderV3.h>
-#include <rfb/SMsgHandler.h>
-#include <rfb/ScreenSet.h>
-
-using namespace rfb;
-
-SMsgReaderV3::SMsgReaderV3(SMsgHandler* handler, rdr::InStream* is)
- : SMsgReader(handler, is)
-{
-}
-
-SMsgReaderV3::~SMsgReaderV3()
-{
-}
-
-void SMsgReaderV3::readClientInit()
-{
- bool shared = is->readU8();
- handler->clientInit(shared);
-}
-
-void SMsgReaderV3::readMsg()
-{
- int msgType = is->readU8();
- switch (msgType) {
- case msgTypeSetPixelFormat: readSetPixelFormat(); break;
- case msgTypeSetEncodings: readSetEncodings(); break;
- case msgTypeFramebufferUpdateRequest: readFramebufferUpdateRequest(); break;
- case msgTypeKeyEvent: readKeyEvent(); break;
- case msgTypePointerEvent: readPointerEvent(); break;
- case msgTypeClientCutText: readClientCutText(); break;
- case msgTypeSetDesktopSize: readSetDesktopSize(); break;
- case msgTypeClientFence: readFence(); break;
- case msgTypeEnableContinuousUpdates: readEnableContinuousUpdates(); break;
-
- default:
- fprintf(stderr, "unknown message type %d\n", msgType);
- throw Exception("unknown message type");
- }
-}
-
-void SMsgReaderV3::readSetDesktopSize()
-{
- int width, height;
- int screens, i;
- rdr::U32 id, flags;
- int sx, sy, sw, sh;
- ScreenSet layout;
-
- is->skip(1);
-
- width = is->readU16();
- height = is->readU16();
-
- screens = is->readU8();
- is->skip(1);
-
- for (i = 0;i < screens;i++) {
- id = is->readU32();
- sx = is->readU16();
- sy = is->readU16();
- sw = is->readU16();
- sh = is->readU16();
- flags = is->readU32();
-
- layout.add_screen(Screen(id, sx, sy, sw, sh, flags));
- }
-
- handler->setDesktopSize(width, height, layout);
-}
-
-void SMsgReaderV3::readFence()
-{
- rdr::U32 flags;
- rdr::U8 len;
- char data[64];
-
- is->skip(3);
-
- flags = is->readU32();
-
- len = is->readU8();
- if (len > sizeof(data)) {
- fprintf(stderr, "Ignoring fence with too large payload\n");
- is->skip(len);
- return;
- }
-
- is->readBytes(data, len);
-
- handler->fence(flags, len, data);
-}
-
-void SMsgReaderV3::readEnableContinuousUpdates()
-{
- bool enable;
- int x, y, w, h;
-
- enable = is->readU8();
-
- x = is->readU16();
- y = is->readU16();
- w = is->readU16();
- h = is->readU16();
-
- handler->enableContinuousUpdates(enable, x, y, w, h);
-}
+++ /dev/null
-/* Copyright (C) 2002-2005 RealVNC Ltd. All Rights Reserved.
- * Copyright 2009-2011 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_SMSGREADERV3_H__
-#define __RFB_SMSGREADERV3_H__
-
-#include <rfb/SMsgReader.h>
-
-namespace rfb {
- class SMsgReaderV3 : public SMsgReader {
- public:
- SMsgReaderV3(SMsgHandler* handler, rdr::InStream* is);
- virtual ~SMsgReaderV3();
- virtual void readClientInit();
- virtual void readMsg();
- protected:
- virtual void readSetDesktopSize();
- virtual void readFence();
- virtual void readEnableContinuousUpdates();
- };
-}
-#endif
/* Copyright (C) 2002-2005 RealVNC Ltd. All Rights Reserved.
* Copyright (C) 2011 D. R. Commander. All Rights Reserved.
+ * Copyright 2009-2014 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 <assert.h>
#include <rdr/OutStream.h>
#include <rfb/msgTypes.h>
+#include <rfb/fenceTypes.h>
+#include <rfb/Exception.h>
#include <rfb/ColourMap.h>
#include <rfb/ConnParams.h>
#include <rfb/UpdateTracker.h>
+#include <rfb/Encoder.h>
#include <rfb/SMsgWriter.h>
#include <rfb/LogWriter.h>
static LogWriter vlog("SMsgWriter");
SMsgWriter::SMsgWriter(ConnParams* cp_, rdr::OutStream* os_)
- : imageBufIdealSize(0), cp(cp_), os(os_), lenBeforeRect(0),
- currentEncoding(0), updatesSent(0), rawBytesEquivalent(0),
+ : imageBufIdealSize(0), cp(cp_), os(os_), currentEncoding(0),
+ nRectsInUpdate(0), nRectsInHeader(0),
+ wsccb(0), needSetDesktopSize(false),
+ needExtendedDesktopSize(false), needSetDesktopName(false),
+ lenBeforeRect(0), updatesSent(0), rawBytesEquivalent(0),
imageBuf(0), imageBufSize(0)
{
for (int i = 0; i <= encodingMax; i++) {
delete [] imageBuf;
}
+void SMsgWriter::writeServerInit()
+{
+ os->writeU16(cp->width);
+ os->writeU16(cp->height);
+ cp->pf().write(os);
+ os->writeString(cp->name());
+ endMsg();
+}
+
void SMsgWriter::writeSetColourMapEntries(int firstColour, int nColours,
ColourMap* cm)
{
endMsg();
}
+void SMsgWriter::writeFence(rdr::U32 flags, unsigned len, const char data[])
+{
+ if (!cp->supportsFence)
+ throw Exception("Client does not support fences");
+ if (len > 64)
+ throw Exception("Too large fence payload");
+ if ((flags & ~fenceFlagsSupported) != 0)
+ throw Exception("Unknown fence flags");
+
+ startMsg(msgTypeServerFence);
+ os->pad(3);
+
+ os->writeU32(flags);
+
+ os->writeU8(len);
+ os->writeBytes(data, len);
+
+ endMsg();
+}
+
+void SMsgWriter::writeEndOfContinuousUpdates()
+{
+ if (!cp->supportsContinuousUpdates)
+ throw Exception("Client does not support continuous updates");
+
+ startMsg(msgTypeEndOfContinuousUpdates);
+ endMsg();
+}
+
void SMsgWriter::setupCurrentEncoder()
{
int encoding = cp->currentEncoding();
return encoders[encoding]->getNumRects(r);
}
+bool SMsgWriter::writeSetDesktopSize() {
+ if (!cp->supportsDesktopResize)
+ return false;
+
+ needSetDesktopSize = true;
+
+ return true;
+}
+
+bool SMsgWriter::writeExtendedDesktopSize() {
+ if (!cp->supportsExtendedDesktopSize)
+ return false;
+
+ needExtendedDesktopSize = true;
+
+ return true;
+}
+
+bool SMsgWriter::writeExtendedDesktopSize(rdr::U16 reason, rdr::U16 result,
+ int fb_width, int fb_height,
+ const ScreenSet& layout) {
+ ExtendedDesktopSizeMsg msg;
+
+ if (!cp->supportsExtendedDesktopSize)
+ return false;
+
+ msg.reason = reason;
+ msg.result = result;
+ msg.fb_width = fb_width;
+ msg.fb_height = fb_height;
+ msg.layout = layout;
+
+ extendedDesktopSizeMsgs.push_back(msg);
+
+ return true;
+}
+
+bool SMsgWriter::writeSetDesktopName() {
+ if (!cp->supportsDesktopRename)
+ return false;
+
+ needSetDesktopName = true;
+
+ return true;
+}
+
+void SMsgWriter::cursorChange(WriteSetCursorCallback* cb)
+{
+ wsccb = cb;
+}
+
+void SMsgWriter::writeSetCursor(int width, int height, const Point& hotspot,
+ void* data, void* mask)
+{
+ if (!wsccb)
+ return;
+
+ if (++nRectsInUpdate > nRectsInHeader && nRectsInHeader)
+ throw Exception("SMsgWriter::writeSetCursor: nRects out of sync");
+
+ os->writeS16(hotspot.x);
+ os->writeS16(hotspot.y);
+ os->writeU16(width);
+ os->writeU16(height);
+ os->writeU32(pseudoEncodingCursor);
+ os->writeBytes(data, width * height * (cp->pf().bpp/8));
+ os->writeBytes(mask, (width+7)/8 * height);
+}
+
+void SMsgWriter::writeSetXCursor(int width, int height, int hotspotX,
+ int hotspotY, void* data, void* mask)
+{
+ if (!wsccb)
+ return;
+
+ if (++nRectsInUpdate > nRectsInHeader && nRectsInHeader)
+ throw Exception("SMsgWriter::writeSetXCursor: nRects out of sync");
+
+ os->writeS16(hotspotX);
+ os->writeS16(hotspotY);
+ os->writeU16(width);
+ os->writeU16(height);
+ os->writeU32(pseudoEncodingXCursor);
+ // FIXME: We only support black and white cursors, currently. We
+ // could pass the correct color by using the pix0/pix1 values
+ // returned from getBitmap, in writeSetCursorCallback. However, we
+ // would then need to undo the conversion from rgb to Pixel that is
+ // done by FakeAllocColor.
+ if (width * height) {
+ os->writeU8(0);
+ os->writeU8(0);
+ os->writeU8(0);
+ os->writeU8(255);
+ os->writeU8(255);
+ os->writeU8(255);
+ os->writeBytes(data, (width+7)/8 * height);
+ os->writeBytes(mask, (width+7)/8 * height);
+ }
+}
+
bool SMsgWriter::needFakeUpdate()
{
- return false;
+ return wsccb || needSetDesktopName || needNoDataUpdate();
}
bool SMsgWriter::needNoDataUpdate()
{
- return false;
+ return needSetDesktopSize || needExtendedDesktopSize ||
+ !extendedDesktopSizeMsgs.empty();
}
void SMsgWriter::writeNoDataUpdate()
{
- // This class has no pseudo-rectangles so there is nothing to do here
- vlog.error("writeNoDataUpdate() called");
+ int nRects;
+
+ nRects = 0;
+
+ if (needSetDesktopSize)
+ nRects++;
+ if (needExtendedDesktopSize)
+ nRects++;
+ if (!extendedDesktopSizeMsgs.empty())
+ nRects += extendedDesktopSizeMsgs.size();
+
+ writeFramebufferUpdateStart(nRects);
+ writeNoDataRects();
+ writeFramebufferUpdateEnd();
}
void SMsgWriter::writeRects(const UpdateInfo& ui, TransImageGetter* ig,
}
}
+void SMsgWriter::writeFramebufferUpdateStart(int nRects)
+{
+ startMsg(msgTypeFramebufferUpdate);
+ os->pad(1);
+
+ if (nRects != 0xFFFF) {
+ if (wsccb)
+ nRects++;
+ if (needSetDesktopName)
+ nRects++;
+ }
+
+ os->writeU16(nRects);
+
+ nRectsInUpdate = 0;
+ if (nRects == 0xFFFF)
+ nRectsInHeader = 0;
+ else
+ nRectsInHeader = nRects;
+
+ writePseudoRects();
+}
+
+void SMsgWriter::writeFramebufferUpdateEnd()
+{
+ if (nRectsInUpdate != nRectsInHeader && nRectsInHeader)
+ throw Exception("SMsgWriter::writeFramebufferUpdateEnd: "
+ "nRects out of sync");
+
+ if (nRectsInHeader == 0) {
+ // Send last rect. marker
+ os->writeS16(0);
+ os->writeS16(0);
+ os->writeU16(0);
+ os->writeU16(0);
+ os->writeU32(pseudoEncodingLastRect);
+ }
+
+ updatesSent++;
+ endMsg();
+}
+
bool SMsgWriter::writeRect(const Rect& r, TransImageGetter* ig, Rect* actual)
{
return writeRect(r, cp->currentEncoding(), ig, actual);
endRect();
}
+void SMsgWriter::startRect(const Rect& r, int encoding)
+{
+ if (++nRectsInUpdate > nRectsInHeader && nRectsInHeader)
+ throw Exception("SMsgWriter::startRect: nRects out of sync");
+
+ currentEncoding = encoding;
+ lenBeforeRect = os->length();
+ if (encoding != encodingCopyRect)
+ rawBytesEquivalent += 12 + r.width() * r.height() * (bpp()/8);
+
+ os->writeS16(r.tl.x);
+ os->writeS16(r.tl.y);
+ os->writeU16(r.width());
+ os->writeU16(r.height());
+ os->writeU32(encoding);
+}
+
+void SMsgWriter::endRect()
+{
+ if (currentEncoding <= encodingMax) {
+ bytesSent[currentEncoding] += os->length() - lenBeforeRect;
+ rectsSent[currentEncoding]++;
+ }
+}
+
rdr::U8* SMsgWriter::getImageBuf(int required, int requested, int* nPixels)
{
int requiredBytes = required * (cp->pf().bpp / 8);
{
return cp->pf().bpp;
}
+
+void SMsgWriter::startMsg(int type)
+{
+ os->writeU8(type);
+}
+
+void SMsgWriter::endMsg()
+{
+ os->flush();
+}
+
+void SMsgWriter::writePseudoRects()
+{
+ if (wsccb) {
+ wsccb->writeSetCursorCallback();
+ wsccb = 0;
+ }
+
+ if (needSetDesktopName) {
+ if (!cp->supportsDesktopRename)
+ throw Exception("Client does not support desktop rename");
+ if (++nRectsInUpdate > nRectsInHeader && nRectsInHeader)
+ throw Exception("SMsgWriter::setDesktopName: nRects out of sync");
+
+ os->writeS16(0);
+ os->writeS16(0);
+ os->writeU16(0);
+ os->writeU16(0);
+ os->writeU32(pseudoEncodingDesktopName);
+ os->writeString(cp->name());
+
+ needSetDesktopName = false;
+ }
+}
+
+void SMsgWriter::writeNoDataRects()
+{
+ // Start with specific ExtendedDesktopSize messages
+ if (!extendedDesktopSizeMsgs.empty()) {
+ std::list<ExtendedDesktopSizeMsg>::const_iterator ri;
+ ScreenSet::const_iterator si;
+
+ if (!cp->supportsExtendedDesktopSize)
+ throw Exception("Client does not support extended desktop resize");
+ if ((nRectsInUpdate += extendedDesktopSizeMsgs.size()) > nRectsInHeader && nRectsInHeader)
+ throw Exception("SMsgWriter::SetDesktopSize reply: nRects out of sync");
+
+ for (ri = extendedDesktopSizeMsgs.begin();ri != extendedDesktopSizeMsgs.end();++ri) {
+ os->writeU16(ri->reason);
+ os->writeU16(ri->result);
+ os->writeU16(ri->fb_width);
+ os->writeU16(ri->fb_height);
+ os->writeU32(pseudoEncodingExtendedDesktopSize);
+
+ os->writeU8(ri->layout.num_screens());
+ os->pad(3);
+
+ for (si = ri->layout.begin();si != ri->layout.end();++si) {
+ os->writeU32(si->id);
+ os->writeU16(si->dimensions.tl.x);
+ os->writeU16(si->dimensions.tl.y);
+ os->writeU16(si->dimensions.width());
+ os->writeU16(si->dimensions.height());
+ os->writeU32(si->flags);
+ }
+ }
+
+ extendedDesktopSizeMsgs.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("SMsgWriter::setExtendedDesktopSize: nRects out of sync");
+
+ os->writeU16(0);
+ os->writeU16(0);
+ os->writeU16(cp->width);
+ os->writeU16(cp->height);
+ os->writeU32(pseudoEncodingExtendedDesktopSize);
+
+ os->writeU8(cp->screenLayout.num_screens());
+ os->pad(3);
+
+ 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;
+ }
+
+ // Some clients assume this is the last rectangle so don't send anything
+ // more after this
+ if (needSetDesktopSize) {
+ if (!cp->supportsDesktopResize)
+ throw Exception("Client does not support desktop resize");
+ if (++nRectsInUpdate > nRectsInHeader && nRectsInHeader)
+ throw Exception("SMsgWriter::setDesktopSize: nRects out of sync");
+
+ os->writeS16(0);
+ os->writeS16(0);
+ os->writeU16(cp->width);
+ os->writeU16(cp->height);
+ os->writeU32(pseudoEncodingDesktopSize);
+
+ needSetDesktopSize = false;
+ }
+}
/* Copyright (C) 2002-2005 RealVNC Ltd. All Rights Reserved.
- * Copyright 2009-2011 Pierre Ossman for Cendio AB
+ * Copyright 2009-2014 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/types.h>
#include <rfb/encodings.h>
-#include <rfb/screenTypes.h>
-#include <rfb/Encoder.h>
-#include <rfb/PixelBuffer.h>
#include <rfb/ScreenSet.h>
namespace rdr { class OutStream; }
namespace rfb {
- class PixelFormat;
class ConnParams;
- class ImageGetter;
+ class TransImageGetter;
class ColourMap;
class Region;
class UpdateInfo;
+ class Encoder;
+ class ScreenSet;
class WriteSetCursorCallback {
public:
class SMsgWriter {
public:
+ SMsgWriter(ConnParams* cp, rdr::OutStream* os);
virtual ~SMsgWriter();
// writeServerInit() must only be called at the appropriate time in the
// protocol initialisation.
- virtual void writeServerInit()=0;
+ void writeServerInit();
// Methods to write normal protocol messages
// writeSetColourMapEntries() writes a setColourMapEntries message, using
// the given ColourMap object to lookup the RGB values of the given range
// of colours.
- virtual void writeSetColourMapEntries(int firstColour, int nColours,
- ColourMap* cm);
+ void writeSetColourMapEntries(int firstColour, int nColours,
+ ColourMap* cm);
// writeBell() and writeServerCutText() do the obvious thing.
- virtual void writeBell();
- virtual void writeServerCutText(const char* str, int len);
+ void writeBell();
+ void writeServerCutText(const char* str, int len);
// writeFence() sends a new fence request or response to the client.
- virtual void writeFence(rdr::U32 flags, unsigned len, const char data[])=0;
+ void writeFence(rdr::U32 flags, unsigned len, const char data[]);
// writeEndOfContinuousUpdates() indicates that we have left continuous
// updates mode.
- virtual void writeEndOfContinuousUpdates()=0;
+ void writeEndOfContinuousUpdates();
// setupCurrentEncoder() should be called before each framebuffer update,
// prior to calling getNumRects() or writeFramebufferUpdateStart().
// given rectangle, for current encoder.
int getNumRects(const Rect &r);
- // 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;
+ // writeSetDesktopSize() won't actually write immediately, but will
+ // write the relevant pseudo-rectangle as part of the next update.
+ bool writeSetDesktopSize();
// Same thing for the extended version. The first version queues up a
// generic update of the current server state, but the second queues a
// specific message.
- virtual bool writeExtendedDesktopSize()=0;
- virtual bool writeExtendedDesktopSize(rdr::U16 reason, rdr::U16 result,
- int fb_width, int fb_height,
- const ScreenSet& layout)=0;
+ bool writeExtendedDesktopSize();
+ bool writeExtendedDesktopSize(rdr::U16 reason, rdr::U16 result,
+ int fb_width, int fb_height,
+ const ScreenSet& layout);
- virtual bool writeSetDesktopName()=0;
+ bool writeSetDesktopName();
// Like setDesktopSize, we can't just write out a setCursor message
- // immediately on a V3 writer. Instead of calling writeSetCursor()
- // directly, you must call cursorChange(), and then invoke writeSetCursor()
- // in response to the writeSetCursorCallback() callback. For a V3 writer
- // this will happen when the next update is sent.
- virtual void cursorChange(WriteSetCursorCallback* cb)=0;
- virtual void writeSetCursor(int width, int height, const Point& hotspot,
- void* data, void* mask)=0;
- virtual void writeSetXCursor(int width, int height, int hotspotX,
- int hotspotY, void* data, void* mask)=0;
+ // immediately. Instead of calling writeSetCursor() directly,
+ // you must call cursorChange(), and then invoke writeSetCursor()
+ // in response to the writeSetCursorCallback() callback. This will
+ // happen when the next update is sent.
+ void cursorChange(WriteSetCursorCallback* cb);
+ void writeSetCursor(int width, int height, const Point& hotspot,
+ void* data, void* mask);
+ void writeSetXCursor(int width, int height, int hotspotX, int hotspotY,
+ void* data, void* mask);
// needFakeUpdate() returns true when an immediate update is needed in
// order to flush out pseudo-rectangles to the client.
- virtual bool needFakeUpdate();
+ bool needFakeUpdate();
// needNoDataUpdate() returns true when an update without any
// framebuffer changes need to be sent (using writeNoDataUpdate()).
// Commonly this is an update that modifies the size of the framebuffer
// or the screen layout.
- virtual bool needNoDataUpdate();
+ bool needNoDataUpdate();
// writeNoDataUpdate() write a framebuffer update containing only
// pseudo-rectangles.
- virtual void writeNoDataUpdate();
+ void writeNoDataUpdate();
// writeRects() accepts an UpdateInfo (changed & copied regions) and an
// ImageGetter to fetch pixels from. It then calls writeCopyRect() and
// before the first writeRects() call and writeFrameBufferUpdateEnd() after
// the last one. It returns the actual region sent to the client, which
// may be smaller than the update passed in.
- virtual void writeRects(const UpdateInfo& update, TransImageGetter* ig,
- Region* updatedRegion);
+ void writeRects(const UpdateInfo& update, TransImageGetter* ig,
+ Region* updatedRegion);
// To construct a framebuffer update you can call
// writeFramebufferUpdateStart(), followed by a number of writeCopyRect()s
- // and writeRect()s, finishing with writeFramebufferUpdateEnd(). If you
- // know the exact number of rectangles ahead of time you can specify it to
- // writeFramebufferUpdateStart() which can be more efficient.
- virtual void writeFramebufferUpdateStart(int nRects)=0;
- virtual void writeFramebufferUpdateStart()=0;
- virtual void writeFramebufferUpdateEnd()=0;
+ // and writeRect()s, finishing with writeFramebufferUpdateEnd().
+ void writeFramebufferUpdateStart(int nRects);
+ void writeFramebufferUpdateEnd();
// writeRect() tries to write the given rectangle. If it is unable to
// write the whole rectangle it returns false and sets actual to the actual
// rectangle which was updated.
- virtual bool writeRect(const Rect& r, TransImageGetter* ig, Rect* actual);
- virtual bool writeRect(const Rect& r, int encoding,
- TransImageGetter* ig, Rect* actual);
+ bool writeRect(const Rect& r, TransImageGetter* ig, Rect* actual);
+ bool writeRect(const Rect& r, int encoding,
+ TransImageGetter* ig, Rect* actual);
- virtual void writeCopyRect(const Rect& r, int srcX, int srcY);
+ void writeCopyRect(const Rect& r, int srcX, int srcY);
- virtual void startRect(const Rect& r, int enc)=0;
- virtual void endRect()=0;
+ void startRect(const Rect& r, int enc);
+ void endRect();
ConnParams* getConnParams() { return cp; }
rdr::OutStream* getOutStream() { return os; }
int imageBufIdealSize;
protected:
- SMsgWriter(ConnParams* cp, rdr::OutStream* os);
+ void startMsg(int type);
+ void endMsg();
- virtual void startMsg(int type)=0;
- virtual void endMsg()=0;
+ void writePseudoRects();
+ void writeNoDataRects();
ConnParams* cp;
rdr::OutStream* os;
Encoder* encoders[encodingMax+1];
- int lenBeforeRect;
int currentEncoding;
+
+ int nRectsInUpdate;
+ int nRectsInHeader;
+
+ WriteSetCursorCallback* wsccb;
+
+ bool needSetDesktopSize;
+ bool needExtendedDesktopSize;
+ bool needSetDesktopName;
+ bool needLastRect;
+
+ int lenBeforeRect;
int updatesSent;
int bytesSent[encodingMax+1];
int rectsSent[encodingMax+1];
rdr::U8* imageBuf;
int imageBufSize;
+
+ typedef struct {
+ rdr::U16 reason, result;
+ int fb_width, fb_height;
+ ScreenSet layout;
+ } ExtendedDesktopSizeMsg;
+
+ std::list<ExtendedDesktopSizeMsg> extendedDesktopSizeMsgs;
};
}
#endif
+++ /dev/null
-/* Copyright (C) 2002-2005 RealVNC Ltd. All Rights Reserved.
- * Copyright 2009-2011 Pierre Ossman for Cendio AB
- * Copyright (C) 2011 D. R. Commander. All Rights Reserved.
- *
- * 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.
- */
-#include <rdr/OutStream.h>
-#include <rdr/MemOutStream.h>
-#include <rfb/msgTypes.h>
-#include <rfb/screenTypes.h>
-#include <rfb/fenceTypes.h>
-#include <rfb/Exception.h>
-#include <rfb/ConnParams.h>
-#include <rfb/SMsgWriterV3.h>
-
-using namespace rfb;
-
-SMsgWriterV3::SMsgWriterV3(ConnParams* cp, rdr::OutStream* os)
- : SMsgWriter(cp, os), updateOS(0), realOS(os), nRectsInUpdate(0),
- nRectsInHeader(0), wsccb(0), needSetDesktopSize(false),
- needExtendedDesktopSize(false), needSetDesktopName(false)
-{
-}
-
-SMsgWriterV3::~SMsgWriterV3()
-{
- delete updateOS;
-}
-
-void SMsgWriterV3::writeServerInit()
-{
- os->writeU16(cp->width);
- os->writeU16(cp->height);
- cp->pf().write(os);
- os->writeString(cp->name());
- endMsg();
-}
-
-void SMsgWriterV3::startMsg(int type)
-{
- if (os != realOS)
- throw Exception("startMsg called while writing an update?");
-
- os->writeU8(type);
-}
-
-void SMsgWriterV3::endMsg()
-{
- os->flush();
-}
-
-void SMsgWriterV3::writeFence(rdr::U32 flags, unsigned len, const char data[])
-{
- if (!cp->supportsFence)
- throw Exception("Client does not support fences");
- if (len > 64)
- throw Exception("Too large fence payload");
- if ((flags & ~fenceFlagsSupported) != 0)
- throw Exception("Unknown fence flags");
-
- startMsg(msgTypeServerFence);
- os->pad(3);
-
- os->writeU32(flags);
-
- os->writeU8(len);
- os->writeBytes(data, len);
-
- endMsg();
-}
-
-void SMsgWriterV3::writeEndOfContinuousUpdates()
-{
- if (!cp->supportsContinuousUpdates)
- throw Exception("Client does not support continuous updates");
-
- startMsg(msgTypeEndOfContinuousUpdates);
- endMsg();
-}
-
-bool SMsgWriterV3::writeSetDesktopSize() {
- if (!cp->supportsDesktopResize) return false;
- needSetDesktopSize = true;
- return true;
-}
-
-bool SMsgWriterV3::writeExtendedDesktopSize() {
- if (!cp->supportsExtendedDesktopSize) return false;
- needExtendedDesktopSize = true;
- return true;
-}
-
-bool SMsgWriterV3::writeExtendedDesktopSize(rdr::U16 reason, rdr::U16 result,
- int fb_width, int fb_height,
- const ScreenSet& layout) {
- ExtendedDesktopSizeMsg msg;
-
- if (!cp->supportsExtendedDesktopSize) return false;
-
- msg.reason = reason;
- msg.result = result;
- msg.fb_width = fb_width;
- msg.fb_height = fb_height;
- msg.layout = layout;
-
- extendedDesktopSizeMsgs.push_back(msg);
-
- return true;
-}
-
-bool SMsgWriterV3::writeSetDesktopName() {
- if (!cp->supportsDesktopRename) return false;
- needSetDesktopName = true;
- return true;
-}
-
-void SMsgWriterV3::cursorChange(WriteSetCursorCallback* cb)
-{
- wsccb = cb;
-}
-
-void SMsgWriterV3::writeSetCursor(int width, int height, const Point& hotspot,
- void* data, void* mask)
-{
- if (!wsccb) return;
- if (++nRectsInUpdate > nRectsInHeader && nRectsInHeader)
- throw Exception("SMsgWriterV3::writeSetCursor: nRects out of sync");
- os->writeS16(hotspot.x);
- os->writeS16(hotspot.y);
- os->writeU16(width);
- os->writeU16(height);
- os->writeU32(pseudoEncodingCursor);
- os->writeBytes(data, width * height * (cp->pf().bpp/8));
- os->writeBytes(mask, (width+7)/8 * height);
-}
-
-void SMsgWriterV3::writeSetXCursor(int width, int height, int hotspotX,
- int hotspotY, void* data, void* mask)
-{
- if (!wsccb) return;
- if (++nRectsInUpdate > nRectsInHeader && nRectsInHeader)
- throw Exception("SMsgWriterV3::writeSetXCursor: nRects out of sync");
- os->writeS16(hotspotX);
- os->writeS16(hotspotY);
- os->writeU16(width);
- os->writeU16(height);
- os->writeU32(pseudoEncodingXCursor);
- // FIXME: We only support black and white cursors, currently. We
- // could pass the correct color by using the pix0/pix1 values
- // returned from getBitmap, in writeSetCursorCallback. However, we
- // would then need to undo the conversion from rgb to Pixel that is
- // done by FakeAllocColor.
- if (width * height) {
- os->writeU8(0);
- os->writeU8(0);
- os->writeU8(0);
- os->writeU8(255);
- os->writeU8(255);
- os->writeU8(255);
- os->writeBytes(data, (width+7)/8 * height);
- os->writeBytes(mask, (width+7)/8 * height);
- }
-}
-
-bool SMsgWriterV3::needFakeUpdate()
-{
- return wsccb || needSetDesktopName || needNoDataUpdate();
-}
-
-bool SMsgWriterV3::needNoDataUpdate()
-{
- return needSetDesktopSize || needExtendedDesktopSize ||
- !extendedDesktopSizeMsgs.empty();
-}
-
-void SMsgWriterV3::writeNoDataUpdate()
-{
- int nRects;
-
- nRects = 0;
-
- if (needSetDesktopSize)
- nRects++;
- if (needExtendedDesktopSize)
- nRects++;
- if (!extendedDesktopSizeMsgs.empty())
- nRects += extendedDesktopSizeMsgs.size();
-
- writeFramebufferUpdateStart(nRects);
- writeNoDataRects();
- writeFramebufferUpdateEnd();
-}
-
-void SMsgWriterV3::writeFramebufferUpdateStart(int nRects)
-{
- startMsg(msgTypeFramebufferUpdate);
- os->pad(1);
-
- if (nRects != 0xFFFF) {
- if (wsccb)
- nRects++;
- if (needSetDesktopName)
- nRects++;
- }
-
- os->writeU16(nRects);
-
- nRectsInUpdate = 0;
- if (nRects == 0xFFFF)
- nRectsInHeader = 0;
- else
- nRectsInHeader = nRects;
-
- writePseudoRects();
-}
-
-void SMsgWriterV3::writeFramebufferUpdateStart()
-{
- nRectsInUpdate = nRectsInHeader = 0;
-
- if (!updateOS)
- updateOS = new rdr::MemOutStream;
- os = updateOS;
-
- writePseudoRects();
-}
-
-void SMsgWriterV3::writeFramebufferUpdateEnd()
-{
- if (nRectsInUpdate != nRectsInHeader && nRectsInHeader)
- throw Exception("SMsgWriterV3::writeFramebufferUpdateEnd: "
- "nRects out of sync");
-
- if (nRectsInHeader == 0) {
- // Send last rect. marker
- os->writeS16(0);
- os->writeS16(0);
- os->writeU16(0);
- os->writeU16(0);
- os->writeU32(pseudoEncodingLastRect);
- }
-
- if (os == updateOS) {
- os = realOS;
- startMsg(msgTypeFramebufferUpdate);
- os->pad(1);
- os->writeU16(nRectsInUpdate);
- os->writeBytes(updateOS->data(), updateOS->length());
- updateOS->clear();
- }
-
- updatesSent++;
- endMsg();
-}
-
-void SMsgWriterV3::startRect(const Rect& r, int encoding)
-{
- if (++nRectsInUpdate > nRectsInHeader && nRectsInHeader)
- throw Exception("SMsgWriterV3::startRect: nRects out of sync");
-
- currentEncoding = encoding;
- lenBeforeRect = os->length();
- if (encoding != encodingCopyRect)
- rawBytesEquivalent += 12 + r.width() * r.height() * (bpp()/8);
-
- os->writeS16(r.tl.x);
- os->writeS16(r.tl.y);
- os->writeU16(r.width());
- os->writeU16(r.height());
- os->writeU32(encoding);
-}
-
-void SMsgWriterV3::endRect()
-{
- if (currentEncoding <= encodingMax) {
- bytesSent[currentEncoding] += os->length() - lenBeforeRect;
- rectsSent[currentEncoding]++;
- }
-}
-
-void SMsgWriterV3::writePseudoRects()
-{
- if (wsccb) {
- wsccb->writeSetCursorCallback();
- wsccb = 0;
- }
-
- if (needSetDesktopName) {
- if (!cp->supportsDesktopRename)
- throw Exception("Client does not support desktop rename");
- if (++nRectsInUpdate > nRectsInHeader && nRectsInHeader)
- throw Exception("SMsgWriterV3 setDesktopName: nRects out of sync");
-
- os->writeS16(0);
- os->writeS16(0);
- os->writeU16(0);
- os->writeU16(0);
- os->writeU32(pseudoEncodingDesktopName);
- os->writeString(cp->name());
-
- needSetDesktopName = false;
- }
-}
-
-void SMsgWriterV3::writeNoDataRects()
-{
- // Start with specific ExtendedDesktopSize messages
- if (!extendedDesktopSizeMsgs.empty()) {
- std::list<ExtendedDesktopSizeMsg>::const_iterator ri;
- ScreenSet::const_iterator si;
-
- if (!cp->supportsExtendedDesktopSize)
- throw Exception("Client does not support extended desktop resize");
- if ((nRectsInUpdate += extendedDesktopSizeMsgs.size()) > nRectsInHeader && nRectsInHeader)
- throw Exception("SMsgWriterV3 SetDesktopSize reply: nRects out of sync");
-
- for (ri = extendedDesktopSizeMsgs.begin();ri != extendedDesktopSizeMsgs.end();++ri) {
- os->writeU16(ri->reason);
- os->writeU16(ri->result);
- os->writeU16(ri->fb_width);
- os->writeU16(ri->fb_height);
- os->writeU32(pseudoEncodingExtendedDesktopSize);
-
- os->writeU8(ri->layout.num_screens());
- os->pad(3);
-
- for (si = ri->layout.begin();si != ri->layout.end();++si) {
- os->writeU32(si->id);
- os->writeU16(si->dimensions.tl.x);
- os->writeU16(si->dimensions.tl.y);
- os->writeU16(si->dimensions.width());
- os->writeU16(si->dimensions.height());
- os->writeU32(si->flags);
- }
- }
-
- extendedDesktopSizeMsgs.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(cp->screenLayout.num_screens());
- os->pad(3);
-
- 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;
- }
-
- // Some clients assume this is the last rectangle so don't send anything
- // more after this
- if (needSetDesktopSize) {
- if (!cp->supportsDesktopResize)
- throw Exception("Client does not support desktop resize");
- if (++nRectsInUpdate > nRectsInHeader && nRectsInHeader)
- throw Exception("SMsgWriterV3 setDesktopSize: nRects out of sync");
-
- os->writeS16(0);
- os->writeS16(0);
- os->writeU16(cp->width);
- os->writeU16(cp->height);
- os->writeU32(pseudoEncodingDesktopSize);
-
- needSetDesktopSize = false;
- }
-}
-
+++ /dev/null
-/* Copyright (C) 2002-2005 RealVNC Ltd. All Rights Reserved.
- * Copyright 2009-2011 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_SMSGWRITERV3_H__
-#define __RFB_SMSGWRITERV3_H__
-
-#include <list>
-#include <utility>
-
-#include <rfb/SMsgWriter.h>
-
-namespace rdr { class MemOutStream; }
-
-namespace rfb {
- class SMsgWriterV3 : public SMsgWriter {
- public:
- SMsgWriterV3(ConnParams* cp, rdr::OutStream* os);
- virtual ~SMsgWriterV3();
-
- virtual void writeServerInit();
- virtual void startMsg(int type);
- virtual void endMsg();
- virtual void writeFence(rdr::U32 flags, unsigned len, const char data[]);
- virtual void writeEndOfContinuousUpdates();
- virtual bool writeSetDesktopSize();
- virtual bool writeExtendedDesktopSize();
- virtual bool writeExtendedDesktopSize(rdr::U16 reason, rdr::U16 result,
- int fb_width, int fb_height,
- const ScreenSet& layout);
- virtual bool writeSetDesktopName();
- virtual void cursorChange(WriteSetCursorCallback* cb);
- virtual void writeSetCursor(int width, int height, const Point& hotspot,
- void* data, void* mask);
- virtual void writeSetXCursor(int width, int height, int hotspotX,
- int hotspotY, void* data, void* mask);
- virtual bool needFakeUpdate();
- virtual bool needNoDataUpdate();
- virtual void writeNoDataUpdate();
- virtual void writeFramebufferUpdateStart(int nRects);
- virtual void writeFramebufferUpdateStart();
- virtual void writeFramebufferUpdateEnd();
- virtual void startRect(const Rect& r, int encoding);
- virtual void endRect();
-
- protected:
- virtual void writePseudoRects();
- virtual void writeNoDataRects();
-
- private:
- rdr::MemOutStream* updateOS;
- rdr::OutStream* realOS;
- int nRectsInUpdate;
- int nRectsInHeader;
- WriteSetCursorCallback* wsccb;
- bool needSetDesktopSize;
- bool needExtendedDesktopSize;
- bool needSetDesktopName;
- bool needLastRect;
-
- typedef struct {
- rdr::U16 reason, result;
- int fb_width, fb_height;
- ScreenSet layout;
- } ExtendedDesktopSizeMsg;
- std::list<ExtendedDesktopSizeMsg> extendedDesktopSizeMsgs;
-
- };
-}
-#endif
*/
#include <rdr/OutStream.h>
#include <rfb/TransImageGetter.h>
+#include <rfb/PixelBuffer.h>
#include <rfb/encodings.h>
#include <rfb/ConnParams.h>
#include <rfb/SMsgWriter.h>