]> source.dussan.org Git - tigervnc.git/commitdiff
Merge the "V3" message classes into the normal ones
authorPierre Ossman <ossman@cendio.se>
Thu, 16 Jan 2014 12:12:40 +0000 (13:12 +0100)
committerPierre Ossman <ossman@cendio.se>
Mon, 7 Jul 2014 12:42:08 +0000 (14:42 +0200)
We have no need for this abstraction so let's keep things simple.

20 files changed:
common/rfb/CConnection.cxx
common/rfb/CMakeLists.txt
common/rfb/CMsgReader.cxx
common/rfb/CMsgReader.h
common/rfb/CMsgReaderV3.cxx [deleted file]
common/rfb/CMsgReaderV3.h [deleted file]
common/rfb/CMsgWriter.cxx
common/rfb/CMsgWriter.h
common/rfb/CMsgWriterV3.cxx [deleted file]
common/rfb/CMsgWriterV3.h [deleted file]
common/rfb/SConnection.cxx
common/rfb/SMsgReader.cxx
common/rfb/SMsgReader.h
common/rfb/SMsgReaderV3.cxx [deleted file]
common/rfb/SMsgReaderV3.h [deleted file]
common/rfb/SMsgWriter.cxx
common/rfb/SMsgWriter.h
common/rfb/SMsgWriterV3.cxx [deleted file]
common/rfb/SMsgWriterV3.h [deleted file]
common/rfb/TightEncoder.cxx

index e73b02e6a11d8b6e4c31786c32ff7f29961c0cd4..1695c3a60971ac5abe618a8fa71eec6675701d80 100644 (file)
@@ -19,8 +19,8 @@
 #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>
@@ -254,8 +254,8 @@ void CConnection::throwConnFailedException()
 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);
index 9f5b59ec2ca114b0f64eadbf14054199b0089bd8..da68a27805bb9328ea6545f248456cae43e87ced 100644 (file)
@@ -5,9 +5,7 @@ set(RFB_SOURCES
   CConnection.cxx
   CMsgHandler.cxx
   CMsgReader.cxx
-  CMsgReaderV3.cxx
   CMsgWriter.cxx
-  CMsgWriterV3.cxx
   CSecurityPlain.cxx
   CSecurityStack.cxx
   CSecurityVeNCrypt.cxx
@@ -41,9 +39,7 @@ set(RFB_SOURCES
   SConnection.cxx
   SMsgHandler.cxx
   SMsgReader.cxx
-  SMsgReaderV3.cxx
   SMsgWriter.cxx
-  SMsgWriterV3.cxx
   ServerCore.cxx
   Security.cxx
   SecurityServer.cxx
index 63d31d1a7d076d8551a8bbf0483ee18bd0799026..8466c68c1ece38b766aca26e6071b69511a2b660 100644 (file)
@@ -1,4 +1,5 @@
 /* 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;
@@ -41,6 +44,81 @@ CMsgReader::~CMsgReader()
   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);
@@ -72,14 +150,38 @@ void CMsgReader::readServerCutText()
   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)
@@ -138,6 +240,43 @@ void CMsgReader::readSetCursor(int width, int height, const Point& hotspot)
   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);
index 7b36160957d05589223c03dfd7524d8e0e4d18d5..650f1642319af9e1035bccc8e620f785a3c67f0f 100644 (file)
@@ -1,4 +1,5 @@
 /* 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);
@@ -49,25 +53,27 @@ namespace rfb {
     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
diff --git a/common/rfb/CMsgReaderV3.cxx b/common/rfb/CMsgReaderV3.cxx
deleted file mode 100644 (file)
index 085cc5a..0000000
+++ /dev/null
@@ -1,174 +0,0 @@
-/* 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();
-}
diff --git a/common/rfb/CMsgReaderV3.h b/common/rfb/CMsgReaderV3.h
deleted file mode 100644 (file)
index bff70ef..0000000
+++ /dev/null
@@ -1,40 +0,0 @@
-/* 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
index 9ee7a02f1dc3f47694422bc27e3f72da391da1fd..3d51060f73606d617063a867c0706abd2be9b0b6 100644 (file)
@@ -1,4 +1,5 @@
 /* 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
@@ -18,7 +19,9 @@
 #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>
@@ -36,6 +39,12 @@ CMsgWriter::~CMsgWriter()
 {
 }
 
+void CMsgWriter::writeClientInit(bool shared)
+{
+  os->writeU8(shared);
+  endMsg();
+}
+
 void CMsgWriter::writeSetPixelFormat(const PixelFormat& pf)
 {
   startMsg(msgTypeSetPixelFormat);                                 
@@ -121,7 +130,35 @@ void CMsgWriter::writeSetEncodings(int preferredEncoding, bool useCopyRect)
 
   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);
@@ -133,6 +170,43 @@ void CMsgWriter::writeFramebufferUpdateRequest(const Rect& r, bool incremental)
   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)
 {
@@ -168,3 +242,13 @@ void CMsgWriter::clientCutText(const char* str, rdr::U32 len)
   os->writeBytes(str, len);
   endMsg();
 }
+
+void CMsgWriter::startMsg(int type)
+{
+  os->writeU8(type);
+}
+
+void CMsgWriter::endMsg()
+{
+  os->flush();
+}
index 661745984bb0f1f975667767dee63575d85c6ec9..fb18cdf737786d9491d71674d1ac6136f1bdd211 100644 (file)
@@ -1,5 +1,5 @@
 /* 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
@@ -23,8 +23,9 @@
 #ifndef __RFB_CMSGWRITER_H__
 #define __RFB_CMSGWRITER_H__
 
+#include <rdr/types.h>
+
 #include <rfb/InputHandler.h>
-#include <rfb/ScreenSet.h>
 
 namespace rdr { class OutStream; }
 
@@ -32,39 +33,38 @@ namespace rfb {
 
   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;
diff --git a/common/rfb/CMsgWriterV3.cxx b/common/rfb/CMsgWriterV3.cxx
deleted file mode 100644 (file)
index b96e2b3..0000000
+++ /dev/null
@@ -1,117 +0,0 @@
-/* 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();
-}
diff --git a/common/rfb/CMsgWriterV3.h b/common/rfb/CMsgWriterV3.h
deleted file mode 100644 (file)
index fb1c42c..0000000
+++ /dev/null
@@ -1,41 +0,0 @@
-/* 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
index ee5733653342a21523a4c18353bcba9009c148f1..ed9f8459205253ebe20972ad7ff1600faf75c4a4 100644 (file)
@@ -22,8 +22,8 @@
 #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>
 
@@ -297,8 +297,8 @@ void SConnection::approveConnection(bool accept, const char* reason)
 
   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;
index 49d8dcf18ccfa8a4d7504ac5abe13994cc7dd4ca..89c9a8fdefcdf9c0216e2de24230ae6d54841733 100644 (file)
@@ -1,4 +1,5 @@
 /* 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
@@ -17,6 +18,7 @@
  */
 #include <stdio.h>
 #include <rdr/InStream.h>
+#include <rfb/msgTypes.h>
 #include <rfb/Exception.h>
 #include <rfb/util.h>
 #include <rfb/SMsgHandler.h>
@@ -39,6 +41,49 @@ SMsgReader::~SMsgReader()
 {
 }
 
+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);
@@ -57,6 +102,36 @@ void SMsgReader::readSetEncodings()
   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();
@@ -67,6 +142,43 @@ void SMsgReader::readFramebufferUpdateRequest()
   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();
index e6e40448c3f57d93242abdbb0346abd037f83706..00cb303177f44566651bff3df0eef4bfb83f45fa 100644 (file)
@@ -1,4 +1,5 @@
 /* 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
@@ -30,24 +31,29 @@ namespace rfb {
 
   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;
diff --git a/common/rfb/SMsgReaderV3.cxx b/common/rfb/SMsgReaderV3.cxx
deleted file mode 100644 (file)
index cd957b9..0000000
+++ /dev/null
@@ -1,131 +0,0 @@
-/* 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);
-}
diff --git a/common/rfb/SMsgReaderV3.h b/common/rfb/SMsgReaderV3.h
deleted file mode 100644 (file)
index 805fd87..0000000
+++ /dev/null
@@ -1,37 +0,0 @@
-/* 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
index 509ffbf526c76f0d593f098056a35b9c0aa90160..c21f8bc54b0f80ac8a48816d6589d0abd1b79966 100644 (file)
@@ -1,5 +1,6 @@
 /* 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>
 
@@ -31,8 +35,11 @@ using namespace rfb;
 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++) {
@@ -59,6 +66,15 @@ SMsgWriter::~SMsgWriter()
   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)
 {
@@ -91,6 +107,35 @@ void SMsgWriter::writeServerCutText(const char* str, int len)
   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();
@@ -117,20 +162,133 @@ int SMsgWriter::getNumRects(const Rect &r)
   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,
@@ -155,6 +313,48 @@ 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);
@@ -178,6 +378,31 @@ void SMsgWriter::writeCopyRect(const Rect& r, int srcX, int srcY)
   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);
@@ -202,3 +427,119 @@ int SMsgWriter::bpp()
 {
   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;
+  }
+}
index edf294475def6e1e4cb9f0f375ecc12c0846a98f..a39cc4f75a304c1f2ab87679b92aa0ed19b693ac 100644 (file)
@@ -1,5 +1,5 @@
 /* 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:
@@ -48,30 +46,31 @@ namespace rfb {
 
   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().
@@ -81,43 +80,43 @@ namespace rfb {
     // 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
@@ -125,29 +124,26 @@ namespace rfb {
     // 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; }
@@ -162,17 +158,29 @@ namespace rfb {
     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];
@@ -180,6 +188,14 @@ namespace rfb {
 
     rdr::U8* imageBuf;
     int imageBufSize;
+
+    typedef struct {
+      rdr::U16 reason, result;
+      int fb_width, fb_height;
+      ScreenSet layout;
+    } ExtendedDesktopSizeMsg;
+
+    std::list<ExtendedDesktopSizeMsg> extendedDesktopSizeMsgs;
   };
 }
 #endif
diff --git a/common/rfb/SMsgWriterV3.cxx b/common/rfb/SMsgWriterV3.cxx
deleted file mode 100644 (file)
index 86f3507..0000000
+++ /dev/null
@@ -1,399 +0,0 @@
-/* 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;
-  }
-}
-
diff --git a/common/rfb/SMsgWriterV3.h b/common/rfb/SMsgWriterV3.h
deleted file mode 100644 (file)
index 6710fa6..0000000
+++ /dev/null
@@ -1,84 +0,0 @@
-/* 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
index 733365e0fc3046aa2fa91534990cc7e543a55adc..1cff7a604b4b8f06d91136753221cb0e655b8d96 100644 (file)
@@ -18,6 +18,7 @@
  */
 #include <rdr/OutStream.h>
 #include <rfb/TransImageGetter.h>
+#include <rfb/PixelBuffer.h>
 #include <rfb/encodings.h>
 #include <rfb/ConnParams.h>
 #include <rfb/SMsgWriter.h>