Basic infrastructure for continuous updates.
git-svn-id: svn://svn.code.sf.net/p/tigervnc/code/trunk@4801 3789f03b-4d11-0410-bbf8-ca57d06f2519
diff --git a/common/rfb/CMsgHandler.cxx b/common/rfb/CMsgHandler.cxx
index 53f496b..eff4776 100644
--- a/common/rfb/CMsgHandler.cxx
+++ b/common/rfb/CMsgHandler.cxx
@@ -69,3 +69,8 @@
{
cp.supportsFence = true;
}
+
+void CMsgHandler::endOfContinuousUpdates()
+{
+ cp.supportsContinuousUpdates = true;
+}
diff --git a/common/rfb/CMsgHandler.h b/common/rfb/CMsgHandler.h
index 1e30eeb..d69d4f2 100644
--- a/common/rfb/CMsgHandler.h
+++ b/common/rfb/CMsgHandler.h
@@ -54,6 +54,7 @@
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 endOfContinuousUpdates();
virtual void serverInit() = 0;
virtual void framebufferUpdateStart() = 0;
diff --git a/common/rfb/CMsgReaderV3.cxx b/common/rfb/CMsgReaderV3.cxx
index ebf08d3..085cc5a 100644
--- a/common/rfb/CMsgReaderV3.cxx
+++ b/common/rfb/CMsgReaderV3.cxx
@@ -61,6 +61,7 @@
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);
@@ -166,3 +167,8 @@
handler->fence(flags, len, data);
}
+
+void CMsgReaderV3::readEndOfContinuousUpdates()
+{
+ handler->endOfContinuousUpdates();
+}
diff --git a/common/rfb/CMsgReaderV3.h b/common/rfb/CMsgReaderV3.h
index 9f55c65..bff70ef 100644
--- a/common/rfb/CMsgReaderV3.h
+++ b/common/rfb/CMsgReaderV3.h
@@ -33,6 +33,7 @@
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;
};
}
diff --git a/common/rfb/CMsgWriter.cxx b/common/rfb/CMsgWriter.cxx
index f221f22..ddc25ff 100644
--- a/common/rfb/CMsgWriter.cxx
+++ b/common/rfb/CMsgWriter.cxx
@@ -71,6 +71,7 @@
encodings[nEncodings++] = pseudoEncodingDesktopName;
encodings[nEncodings++] = pseudoEncodingLastRect;
+ encodings[nEncodings++] = pseudoEncodingContinuousUpdates;
encodings[nEncodings++] = pseudoEncodingFence;
if (Decoder::supported(preferredEncoding)) {
diff --git a/common/rfb/CMsgWriter.h b/common/rfb/CMsgWriter.h
index e5cc590..6617459 100644
--- a/common/rfb/CMsgWriter.h
+++ b/common/rfb/CMsgWriter.h
@@ -46,6 +46,8 @@
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;
// CMsgWriter implemented methods
virtual void writeSetPixelFormat(const PixelFormat& pf);
diff --git a/common/rfb/CMsgWriterV3.cxx b/common/rfb/CMsgWriterV3.cxx
index ab3680a..b96e2b3 100644
--- a/common/rfb/CMsgWriterV3.cxx
+++ b/common/rfb/CMsgWriterV3.cxx
@@ -97,3 +97,21 @@
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
index a0b9cab..fb1c42c 100644
--- a/common/rfb/CMsgWriterV3.h
+++ b/common/rfb/CMsgWriterV3.h
@@ -34,6 +34,8 @@
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
diff --git a/common/rfb/ConnParams.cxx b/common/rfb/ConnParams.cxx
index 35b0054..2f0e275 100644
--- a/common/rfb/ConnParams.cxx
+++ b/common/rfb/ConnParams.cxx
@@ -34,6 +34,7 @@
supportsDesktopResize(false), supportsExtendedDesktopSize(false),
supportsDesktopRename(false), supportsLastRect(false),
supportsSetDesktopSize(false), supportsFence(false),
+ supportsContinuousUpdates(false),
customCompressLevel(false), compressLevel(6),
noJpeg(false), qualityLevel(-1), fineQualityLevel(-1),
subsampling(SUBSAMP_UNDEFINED),
@@ -127,6 +128,8 @@
supportsLastRect = true;
else if (encodings[i] == pseudoEncodingFence)
supportsFence = true;
+ else if (encodings[i] == pseudoEncodingContinuousUpdates)
+ supportsContinuousUpdates = true;
else if (encodings[i] >= pseudoEncodingCompressLevel0 &&
encodings[i] <= pseudoEncodingCompressLevel9) {
customCompressLevel = true;
diff --git a/common/rfb/ConnParams.h b/common/rfb/ConnParams.h
index 35e0605..fa0fe02 100644
--- a/common/rfb/ConnParams.h
+++ b/common/rfb/ConnParams.h
@@ -81,6 +81,7 @@
bool supportsSetDesktopSize;
bool supportsFence;
+ bool supportsContinuousUpdates;
bool customCompressLevel;
int compressLevel;
diff --git a/common/rfb/SConnection.cxx b/common/rfb/SConnection.cxx
index ea56543..941d30a 100644
--- a/common/rfb/SConnection.cxx
+++ b/common/rfb/SConnection.cxx
@@ -342,3 +342,8 @@
writer()->writeFence(flags, len, data);
}
+
+void SConnection::enableContinuousUpdates(bool enable,
+ int x, int y, int w, int h)
+{
+}
diff --git a/common/rfb/SConnection.h b/common/rfb/SConnection.h
index 51ceac0..a3a9fc8 100644
--- a/common/rfb/SConnection.h
+++ b/common/rfb/SConnection.h
@@ -113,6 +113,11 @@
// support.
virtual void fence(rdr::U32 flags, unsigned len, const char data[]);
+ // enableContinuousUpdates() is called when the client wants to enable
+ // or disable continuous updates, or change the active area.
+ virtual void enableContinuousUpdates(bool enable,
+ int x, int y, int w, int h);
+
// 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.
diff --git a/common/rfb/SMsgHandler.cxx b/common/rfb/SMsgHandler.cxx
index ff15e19..d4046b1 100644
--- a/common/rfb/SMsgHandler.cxx
+++ b/common/rfb/SMsgHandler.cxx
@@ -41,9 +41,10 @@
void SMsgHandler::setEncodings(int nEncodings, rdr::S32* encodings)
{
- bool firstFence;
+ bool firstFence, firstContinuousUpdates;
firstFence = !cp.supportsFence;
+ firstContinuousUpdates = !cp.supportsContinuousUpdates;
cp.setEncodings(nEncodings, encodings);
@@ -51,6 +52,8 @@
if (cp.supportsFence && firstFence)
supportsFence();
+ if (cp.supportsContinuousUpdates && firstContinuousUpdates)
+ supportsContinuousUpdates();
}
void SMsgHandler::supportsLocalCursor()
@@ -61,6 +64,10 @@
{
}
+void SMsgHandler::supportsContinuousUpdates()
+{
+}
+
void SMsgHandler::setDesktopSize(int fb_width, int fb_height,
const ScreenSet& layout)
{
diff --git a/common/rfb/SMsgHandler.h b/common/rfb/SMsgHandler.h
index 0b1fd7e..c21cf52 100644
--- a/common/rfb/SMsgHandler.h
+++ b/common/rfb/SMsgHandler.h
@@ -51,6 +51,8 @@
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;
+ virtual void enableContinuousUpdates(bool enable,
+ int x, int y, int w, int h) = 0;
// InputHandler interface
// The InputHandler methods will be called for the corresponding messages.
@@ -66,6 +68,12 @@
// the client of server support.
virtual void supportsFence();
+ // supportsContinuousUpdates() is called the first time we detect that
+ // the client wants the continuous updates extension. A
+ // EndOfContinuousUpdates message should be sent back to the client at
+ // this point if it is supported.
+ virtual void supportsContinuousUpdates();
+
ConnParams cp;
};
}
diff --git a/common/rfb/SMsgReaderV3.cxx b/common/rfb/SMsgReaderV3.cxx
index eddeccf..cd957b9 100644
--- a/common/rfb/SMsgReaderV3.cxx
+++ b/common/rfb/SMsgReaderV3.cxx
@@ -55,6 +55,7 @@
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);
@@ -113,3 +114,18 @@
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
index f4cc7d7..805fd87 100644
--- a/common/rfb/SMsgReaderV3.h
+++ b/common/rfb/SMsgReaderV3.h
@@ -31,6 +31,7 @@
protected:
virtual void readSetDesktopSize();
virtual void readFence();
+ virtual void readEnableContinuousUpdates();
};
}
#endif
diff --git a/common/rfb/SMsgWriter.h b/common/rfb/SMsgWriter.h
index aaa98e4..3933b38 100644
--- a/common/rfb/SMsgWriter.h
+++ b/common/rfb/SMsgWriter.h
@@ -69,6 +69,10 @@
// writeFence() sends a new fence request or response to the client.
virtual void writeFence(rdr::U32 flags, unsigned len, const char data[])=0;
+ // writeEndOfContinuousUpdates() indicates that we have left continuous
+ // updates mode.
+ virtual void writeEndOfContinuousUpdates()=0;
+
// setupCurrentEncoder() should be called before each framebuffer update,
// prior to calling getNumRects() or writeFramebufferUpdateStart().
void setupCurrentEncoder();
diff --git a/common/rfb/SMsgWriterV3.cxx b/common/rfb/SMsgWriterV3.cxx
index 0867b10..86f3507 100644
--- a/common/rfb/SMsgWriterV3.cxx
+++ b/common/rfb/SMsgWriterV3.cxx
@@ -82,6 +82,15 @@
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;
diff --git a/common/rfb/SMsgWriterV3.h b/common/rfb/SMsgWriterV3.h
index 35f1f94..6710fa6 100644
--- a/common/rfb/SMsgWriterV3.h
+++ b/common/rfb/SMsgWriterV3.h
@@ -36,6 +36,7 @@
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,
diff --git a/common/rfb/encodings.h b/common/rfb/encodings.h
index 84844c5..5c6c5ea 100644
--- a/common/rfb/encodings.h
+++ b/common/rfb/encodings.h
@@ -37,6 +37,7 @@
const int pseudoEncodingExtendedDesktopSize = -308;
const int pseudoEncodingDesktopName = -307;
const int pseudoEncodingFence = -312;
+ const int pseudoEncodingContinuousUpdates = -313;
// TightVNC-specific
const int pseudoEncodingLastRect = -224;
diff --git a/common/rfb/msgTypes.h b/common/rfb/msgTypes.h
index e42d95a..a55e1c5 100644
--- a/common/rfb/msgTypes.h
+++ b/common/rfb/msgTypes.h
@@ -26,6 +26,8 @@
const int msgTypeBell = 2;
const int msgTypeServerCutText = 3;
+ const int msgTypeEndOfContinuousUpdates = 150;
+
const int msgTypeServerFence = 248;
// client to server
@@ -38,6 +40,8 @@
const int msgTypePointerEvent = 5;
const int msgTypeClientCutText = 6;
+ const int msgTypeEnableContinuousUpdates = 150;
+
const int msgTypeClientFence = 248;
const int msgTypeSetDesktopSize = 251;