diff options
author | Pierre Ossman <ossman@cendio.se> | 2014-01-16 13:12:40 +0100 |
---|---|---|
committer | Pierre Ossman <ossman@cendio.se> | 2014-07-07 14:42:08 +0200 |
commit | 7638e9c5b1c59abc98e27986b8178f19e5e6cf2a (patch) | |
tree | 3e87cbfbbdc731017a5b0bff751a8b9deaa83c66 /common/rfb/CMsgReader.cxx | |
parent | 95f1f294d0fd7b006f52d18d39ae0c3116258d91 (diff) | |
download | tigervnc-7638e9c5b1c59abc98e27986b8178f19e5e6cf2a.tar.gz tigervnc-7638e9c5b1c59abc98e27986b8178f19e5e6cf2a.zip |
Merge the "V3" message classes into the normal ones
We have no need for this abstraction so let's keep things simple.
Diffstat (limited to 'common/rfb/CMsgReader.cxx')
-rw-r--r-- | common/rfb/CMsgReader.cxx | 149 |
1 files changed, 144 insertions, 5 deletions
diff --git a/common/rfb/CMsgReader.cxx b/common/rfb/CMsgReader.cxx index 63d31d1a..8466c68c 100644 --- a/common/rfb/CMsgReader.cxx +++ b/common/rfb/CMsgReader.cxx @@ -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 @@ -16,17 +17,19 @@ * 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); |