Browse Source

Basic infrastructure to support fences.


git-svn-id: svn://svn.code.sf.net/p/tigervnc/code/trunk@4798 3789f03b-4d11-0410-bbf8-ca57d06f2519
tags/v1.1.90
Pierre Ossman 12 years ago
parent
commit
c754cceeca

+ 14
- 0
common/rfb/CConnection.cxx View File

@@ -18,6 +18,7 @@
#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>
@@ -269,3 +270,16 @@ void CConnection::serverInit()
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);
}

+ 7
- 0
common/rfb/CConnection.h View File

@@ -136,6 +136,13 @@ namespace rfb {
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();

+ 5
- 1
common/rfb/CMsgHandler.cxx View File

@@ -1,5 +1,5 @@
/* 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
@@ -65,3 +65,7 @@ void CMsgHandler::setName(const char* name)
cp.setName(name);
}

void CMsgHandler::fence(rdr::U32 flags, unsigned len, const char data[])
{
cp.supportsFence = true;
}

+ 2
- 1
common/rfb/CMsgHandler.h View File

@@ -1,5 +1,5 @@
/* 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
@@ -53,6 +53,7 @@ namespace rfb {
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;

+ 23
- 1
common/rfb/CMsgReaderV3.cxx View File

@@ -1,5 +1,5 @@
/* 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
@@ -60,6 +60,7 @@ void CMsgReaderV3::readMsg()
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);
@@ -144,3 +145,24 @@ void CMsgReaderV3::readExtendedDesktopSize(int x, int y, int w, int h)
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);
}

+ 2
- 1
common/rfb/CMsgReaderV3.h View File

@@ -1,5 +1,5 @@
/* 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
@@ -32,6 +32,7 @@ namespace rfb {
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;
};
}

+ 6
- 1
common/rfb/CMsgWriter.cxx View File

@@ -60,6 +60,7 @@ void CMsgWriter::writeSetEncodings(int preferredEncoding, bool useCopyRect)
{
int nEncodings = 0;
rdr::U32 encodings[encodingMax+3];

if (cp->supportsLocalCursor)
encodings[nEncodings++] = pseudoEncodingCursor;
if (cp->supportsDesktopResize)
@@ -68,9 +69,14 @@ void CMsgWriter::writeSetEncodings(int preferredEncoding, bool useCopyRect)
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;
}
@@ -106,7 +112,6 @@ void CMsgWriter::writeSetEncodings(int preferredEncoding, bool useCopyRect)
}
}

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)

+ 2
- 0
common/rfb/CMsgWriter.h View File

@@ -1,4 +1,5 @@
/* 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
@@ -44,6 +45,7 @@ namespace rfb {

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);

+ 22
- 0
common/rfb/CMsgWriterV3.cxx View File

@@ -1,4 +1,5 @@
/* 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
@@ -17,6 +18,7 @@
*/
#include <rdr/OutStream.h>
#include <rfb/msgTypes.h>
#include <rfb/fenceTypes.h>
#include <rfb/Exception.h>
#include <rfb/ConnParams.h>
#include <rfb/CMsgWriterV3.h>
@@ -75,3 +77,23 @@ void CMsgWriterV3::writeSetDesktopSize(int width, int height,

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();
}

+ 2
- 0
common/rfb/CMsgWriterV3.h View File

@@ -1,4 +1,5 @@
/* 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
@@ -32,6 +33,7 @@ namespace rfb {

virtual void writeSetDesktopSize(int width, int height,
const ScreenSet& layout);
virtual void writeFence(rdr::U32 flags, unsigned len, const char data[]);
};
}
#endif

+ 3
- 1
common/rfb/ConnParams.cxx View File

@@ -33,7 +33,7 @@ ConnParams::ConnParams()
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),
@@ -125,6 +125,8 @@ void ConnParams::setEncodings(int nEncodings, const rdr::S32* encodings)
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;

+ 1
- 0
common/rfb/ConnParams.h View File

@@ -80,6 +80,7 @@ namespace rfb {
bool supportsLastRect;

bool supportsSetDesktopSize;
bool supportsFence;

bool customCompressLevel;
int compressLevel;

+ 13
- 0
common/rfb/SConnection.cxx View File

@@ -1,4 +1,5 @@
/* 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
@@ -20,6 +21,7 @@
#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>
@@ -329,3 +331,14 @@ void SConnection::framebufferUpdateRequest(const Rect& r, bool incremental)
}
}
}

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);
}

+ 7
- 0
common/rfb/SConnection.h View File

@@ -1,4 +1,5 @@
/* 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
@@ -106,6 +107,12 @@ namespace rfb {
// 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.

+ 13
- 1
common/rfb/SMsgHandler.cxx View File

@@ -1,5 +1,5 @@
/* 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
@@ -41,14 +41,26 @@ void SMsgHandler::setPixelFormat(const PixelFormat& pf)

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)
{

+ 7
- 1
common/rfb/SMsgHandler.h View File

@@ -1,5 +1,5 @@
/* 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
@@ -50,6 +50,7 @@ namespace rfb {
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.
@@ -60,6 +61,11 @@ namespace rfb {
// 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;
};
}

+ 23
- 1
common/rfb/SMsgReaderV3.cxx View File

@@ -1,5 +1,5 @@
/* 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
@@ -54,6 +54,7 @@ void SMsgReaderV3::readMsg()
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);
@@ -91,3 +92,24 @@ void SMsgReaderV3::readSetDesktopSize()
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);
}

+ 2
- 1
common/rfb/SMsgReaderV3.h View File

@@ -1,5 +1,5 @@
/* 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
@@ -30,6 +30,7 @@ namespace rfb {
virtual void readMsg();
protected:
virtual void readSetDesktopSize();
virtual void readFence();
};
}
#endif

+ 4
- 0
common/rfb/SMsgWriter.h View File

@@ -1,4 +1,5 @@
/* 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
@@ -65,6 +66,9 @@ namespace rfb {
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();

+ 22
- 1
common/rfb/SMsgWriterV3.cxx View File

@@ -1,5 +1,5 @@
/* 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
@@ -21,6 +21,7 @@
#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>
@@ -61,6 +62,26 @@ 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();
}

bool SMsgWriterV3::writeSetDesktopSize() {
if (!cp->supportsDesktopResize) return false;
needSetDesktopSize = true;

+ 2
- 1
common/rfb/SMsgWriterV3.h View File

@@ -1,5 +1,5 @@
/* 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
@@ -35,6 +35,7 @@ namespace rfb {
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,

+ 1
- 0
common/rfb/encodings.h View File

@@ -36,6 +36,7 @@ namespace rfb {
const int pseudoEncodingDesktopSize = -223;
const int pseudoEncodingExtendedDesktopSize = -308;
const int pseudoEncodingDesktopName = -307;
const int pseudoEncodingFence = -312;

// TightVNC-specific
const int pseudoEncodingLastRect = -224;

+ 36
- 0
common/rfb/fenceTypes.h View File

@@ -0,0 +1,36 @@
/* 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

+ 4
- 0
common/rfb/msgTypes.h View File

@@ -26,6 +26,8 @@ namespace rfb {
const int msgTypeBell = 2;
const int msgTypeServerCutText = 3;

const int msgTypeServerFence = 248;

// client to server

const int msgTypeSetPixelFormat = 0;
@@ -36,6 +38,8 @@ namespace rfb {
const int msgTypePointerEvent = 5;
const int msgTypeClientCutText = 6;

const int msgTypeClientFence = 248;

const int msgTypeSetDesktopSize = 251;
}
#endif

Loading…
Cancel
Save