#include <stdio.h>
#include <string.h>
#include <rfb/Exception.h>
+#include <rfb/fenceTypes.h>
#include <rfb/CMsgReaderV3.h>
#include <rfb/CMsgWriterV3.h>
#include <rfb/CSecurity.h>
state_ = RFBSTATE_NORMAL;
vlog.debug("initialisation done");
}
+
+void CConnection::fence(rdr::U32 flags, unsigned len, const char data[])
+{
+ CMsgHandler::fence(flags, len, data);
+
+ if (!(flags & fenceFlagRequest))
+ return;
+
+ // We cannot guarantee any synchronisation at this level
+ flags = 0;
+
+ writer()->writeFence(flags, len, data);
+}
protected:
void setState(stateEnum s) { state_ = s; }
+ private:
+ // This is a default implementation of fences that automatically
+ // responds to requests, stating no support for synchronisation.
+ // When overriding, call CMsgHandler::fence() directly in order to
+ // state correct support for fence flags.
+ virtual void fence(rdr::U32 flags, unsigned len, const char data[]);
+
private:
void processVersionMsg();
void processSecurityTypesMsg();
/* Copyright (C) 2002-2005 RealVNC Ltd. All Rights Reserved.
- * Copyright 2009 Pierre Ossman for Cendio AB
+ * 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
cp.setName(name);
}
+void CMsgHandler::fence(rdr::U32 flags, unsigned len, const char data[])
+{
+ cp.supportsFence = true;
+}
/* Copyright (C) 2002-2005 RealVNC Ltd. All Rights Reserved.
- * Copyright 2009 Pierre Ossman for Cendio AB
+ * 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
void* data, void* mask) = 0;
virtual void setPixelFormat(const PixelFormat& pf);
virtual void setName(const char* name);
+ virtual void fence(rdr::U32 flags, unsigned len, const char data[]);
virtual void serverInit() = 0;
virtual void framebufferUpdateStart() = 0;
/* Copyright (C) 2002-2005 RealVNC Ltd. All Rights Reserved.
- * Copyright 2009 Pierre Ossman for Cendio AB
+ * 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
case msgTypeSetColourMapEntries: readSetColourMapEntries(); break;
case msgTypeBell: readBell(); break;
case msgTypeServerCutText: readServerCutText(); break;
+ case msgTypeServerFence: readFence(); break;
default:
fprintf(stderr, "unknown message type %d\n", type);
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);
+}
/* Copyright (C) 2002-2005 RealVNC Ltd. All Rights Reserved.
- * Copyright 2009 Pierre Ossman for Cendio AB
+ * 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
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();
int nUpdateRectsLeft;
};
}
{
int nEncodings = 0;
rdr::U32 encodings[encodingMax+3];
+
if (cp->supportsLocalCursor)
encodings[nEncodings++] = pseudoEncodingCursor;
if (cp->supportsDesktopResize)
encodings[nEncodings++] = pseudoEncodingExtendedDesktopSize;
if (cp->supportsDesktopRename)
encodings[nEncodings++] = pseudoEncodingDesktopName;
+
+ encodings[nEncodings++] = pseudoEncodingLastRect;
+ encodings[nEncodings++] = pseudoEncodingFence;
+
if (Decoder::supported(preferredEncoding)) {
encodings[nEncodings++] = preferredEncoding;
}
+
if (useCopyRect) {
encodings[nEncodings++] = encodingCopyRect;
}
}
}
- encodings[nEncodings++] = pseudoEncodingLastRect;
if (cp->customCompressLevel && cp->compressLevel >= 0 && cp->compressLevel <= 9)
encodings[nEncodings++] = pseudoEncodingCompressLevel0 + cp->compressLevel;
if (!cp->noJpeg && cp->qualityLevel >= 0 && cp->qualityLevel <= 9)
/* 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
virtual void writeSetDesktopSize(int width, int height,
const ScreenSet& layout)=0;
+ virtual void writeFence(rdr::U32 flags, unsigned len, const char data[])=0;
// CMsgWriter implemented methods
virtual void writeSetPixelFormat(const PixelFormat& pf);
/* 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
*/
#include <rdr/OutStream.h>
#include <rfb/msgTypes.h>
+#include <rfb/fenceTypes.h>
#include <rfb/Exception.h>
#include <rfb/ConnParams.h>
#include <rfb/CMsgWriterV3.h>
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();
+}
/* 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
virtual void writeSetDesktopSize(int width, int height,
const ScreenSet& layout);
+ virtual void writeFence(rdr::U32 flags, unsigned len, const char data[]);
};
}
#endif
supportsLocalCursor(false), supportsLocalXCursor(false),
supportsDesktopResize(false), supportsExtendedDesktopSize(false),
supportsDesktopRename(false), supportsLastRect(false),
- supportsSetDesktopSize(false),
+ supportsSetDesktopSize(false), supportsFence(false),
customCompressLevel(false), compressLevel(6),
noJpeg(false), qualityLevel(-1), fineQualityLevel(-1),
subsampling(SUBSAMP_UNDEFINED),
supportsDesktopRename = true;
else if (encodings[i] == pseudoEncodingLastRect)
supportsLastRect = true;
+ else if (encodings[i] == pseudoEncodingFence)
+ supportsFence = true;
else if (encodings[i] >= pseudoEncodingCompressLevel0 &&
encodings[i] <= pseudoEncodingCompressLevel9) {
customCompressLevel = true;
bool supportsLastRect;
bool supportsSetDesktopSize;
+ bool supportsFence;
bool customCompressLevel;
int compressLevel;
/* Copyright (C) 2002-2005 RealVNC Ltd. All Rights Reserved.
+ * Copyright 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
#include <rfb/Exception.h>
#include <rfb/Security.h>
#include <rfb/msgTypes.h>
+#include <rfb/fenceTypes.h>
#include <rfb/SMsgReaderV3.h>
#include <rfb/SMsgWriterV3.h>
#include <rfb/SConnection.h>
}
}
}
+
+void SConnection::fence(rdr::U32 flags, unsigned len, const char data[])
+{
+ if (!(flags & fenceFlagRequest))
+ return;
+
+ // We cannot guarantee any synchronisation at this level
+ flags = 0;
+
+ writer()->writeFence(flags, len, data);
+}
/* Copyright (C) 2002-2005 RealVNC Ltd. All Rights Reserved.
+ * Copyright 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
// accepts the server's default pixel format and it uses a colour map.
virtual void setInitialColourMap();
+ // fence() is called when we get a fence request or response. By default
+ // it responds directly to requests (stating it doesn't support any
+ // synchronisation) and drops responses. Override to implement more proper
+ // support.
+ virtual void fence(rdr::U32 flags, unsigned len, const char data[]);
+
// setAccessRights() allows a security package to limit the access rights
// of a VNCSConnectionST to the server. How the access rights are treated
// is up to the derived class.
/* Copyright (C) 2002-2005 RealVNC Ltd. All Rights Reserved.
- * Copyright 2009 Pierre Ossman for Cendio AB
+ * 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
void SMsgHandler::setEncodings(int nEncodings, rdr::S32* encodings)
{
+ bool firstFence;
+
+ firstFence = !cp.supportsFence;
+
cp.setEncodings(nEncodings, encodings);
+
supportsLocalCursor();
+
+ if (cp.supportsFence && firstFence)
+ supportsFence();
}
void SMsgHandler::supportsLocalCursor()
{
}
+void SMsgHandler::supportsFence()
+{
+}
+
void SMsgHandler::setDesktopSize(int fb_width, int fb_height,
const ScreenSet& layout)
{
/* Copyright (C) 2002-2005 RealVNC Ltd. All Rights Reserved.
- * Copyright 2009 Pierre Ossman for Cendio AB
+ * 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
virtual void framebufferUpdateRequest(const Rect& r, bool incremental) = 0;
virtual void setDesktopSize(int fb_width, int fb_height,
const ScreenSet& layout) = 0;
+ virtual void fence(rdr::U32 flags, unsigned len, const char data[]) = 0;
// InputHandler interface
// The InputHandler methods will be called for the corresponding messages.
// specially for this purpose.
virtual void supportsLocalCursor();
+ // supportsFence() is called the first time we detect support for fences
+ // in the client. A fence message should be sent at this point to notify
+ // the client of server support.
+ virtual void supportsFence();
+
ConnParams cp;
};
}
/* Copyright (C) 2002-2005 RealVNC Ltd. All Rights Reserved.
- * Copyright 2009 Pierre Ossman for Cendio AB
+ * 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
case msgTypePointerEvent: readPointerEvent(); break;
case msgTypeClientCutText: readClientCutText(); break;
case msgTypeSetDesktopSize: readSetDesktopSize(); break;
+ case msgTypeClientFence: readFence(); break;
default:
fprintf(stderr, "unknown message type %d\n", msgType);
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);
+}
/* Copyright (C) 2002-2005 RealVNC Ltd. All Rights Reserved.
- * Copyright 2009 Pierre Ossman for Cendio AB
+ * 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
virtual void readMsg();
protected:
virtual void readSetDesktopSize();
+ virtual void readFence();
};
}
#endif
/* 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
virtual void writeBell();
virtual 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;
+
// setupCurrentEncoder() should be called before each framebuffer update,
// prior to calling getNumRects() or writeFramebufferUpdateStart().
void setupCurrentEncoder();
/* Copyright (C) 2002-2005 RealVNC Ltd. All Rights Reserved.
- * Copyright 2009 Pierre Ossman for Cendio AB
+ * 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
#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>
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();
+}
+
bool SMsgWriterV3::writeSetDesktopSize() {
if (!cp->supportsDesktopResize) return false;
needSetDesktopSize = true;
/* Copyright (C) 2002-2005 RealVNC Ltd. All Rights Reserved.
- * Copyright 2009 Pierre Ossman for Cendio AB
+ * 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
virtual void writeServerInit();
virtual void startMsg(int type);
virtual void endMsg();
+ virtual void writeFence(rdr::U32 flags, unsigned len, const char data[]);
virtual bool writeSetDesktopSize();
virtual bool writeExtendedDesktopSize();
virtual bool writeExtendedDesktopSize(rdr::U16 reason, rdr::U16 result,
const int pseudoEncodingDesktopSize = -223;
const int pseudoEncodingExtendedDesktopSize = -308;
const int pseudoEncodingDesktopName = -307;
+ const int pseudoEncodingFence = -312;
// TightVNC-specific
const int pseudoEncodingLastRect = -224;
--- /dev/null
+/* Copyright 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_FENCETYPES_H__
+#define __RFB_FENCETYPES_H__
+
+#include <rdr/types.h>
+
+namespace rfb {
+ const rdr::U32 fenceFlagBlockBefore = 1<<0;
+ const rdr::U32 fenceFlagBlockAfter = 1<<1;
+ const rdr::U32 fenceFlagSyncNext = 1<<2;
+
+ const rdr::U32 fenceFlagRequest = 1<<31;
+
+ const rdr::U32 fenceFlagsSupported = (fenceFlagBlockBefore |
+ fenceFlagBlockAfter |
+ fenceFlagSyncNext |
+ fenceFlagRequest);
+}
+
+#endif
const int msgTypeBell = 2;
const int msgTypeServerCutText = 3;
+ const int msgTypeServerFence = 248;
+
// client to server
const int msgTypeSetPixelFormat = 0;
const int msgTypePointerEvent = 5;
const int msgTypeClientCutText = 6;
+ const int msgTypeClientFence = 248;
+
const int msgTypeSetDesktopSize = 251;
}
#endif