diff options
author | Constantin Kaplinsky <const@tightvnc.com> | 2006-05-25 05:01:55 +0000 |
---|---|---|
committer | Constantin Kaplinsky <const@tightvnc.com> | 2006-05-25 05:01:55 +0000 |
commit | a2adc8d4cfdf7336ce9192414c5e775224742a97 (patch) | |
tree | 0fc9f229bd40a2de342d91338798033da8ebd7bc /common/rfb/SMsgWriter.cxx | |
parent | 4fc2026b9595e9425f50616d18781995aebe495b (diff) | |
download | tigervnc-a2adc8d4cfdf7336ce9192414c5e775224742a97.tar.gz tigervnc-a2adc8d4cfdf7336ce9192414c5e775224742a97.zip |
Migrating to new directory structure adopted from the RealVNC's source tree. More changes will follow.
git-svn-id: svn://svn.code.sf.net/p/tigervnc/code/trunk@589 3789f03b-4d11-0410-bbf8-ca57d06f2519
Diffstat (limited to 'common/rfb/SMsgWriter.cxx')
-rw-r--r-- | common/rfb/SMsgWriter.cxx | 202 |
1 files changed, 202 insertions, 0 deletions
diff --git a/common/rfb/SMsgWriter.cxx b/common/rfb/SMsgWriter.cxx new file mode 100644 index 00000000..085dfc16 --- /dev/null +++ b/common/rfb/SMsgWriter.cxx @@ -0,0 +1,202 @@ +/* Copyright (C) 2002-2005 RealVNC Ltd. 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 <stdio.h> +#include <assert.h> +#include <rdr/OutStream.h> +#include <rfb/msgTypes.h> +#include <rfb/ColourMap.h> +#include <rfb/ConnParams.h> +#include <rfb/UpdateTracker.h> +#include <rfb/SMsgWriter.h> +#include <rfb/LogWriter.h> + +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), + imageBuf(0), imageBufSize(0) +{ + for (unsigned int i = 0; i <= encodingMax; i++) { + encoders[i] = 0; + bytesSent[i] = 0; + rectsSent[i] = 0; + } +} + +SMsgWriter::~SMsgWriter() +{ + vlog.info("framebuffer updates %d",updatesSent); + int bytes = 0; + for (unsigned int i = 0; i <= encodingMax; i++) { + delete encoders[i]; + if (i != encodingCopyRect) + bytes += bytesSent[i]; + if (rectsSent[i]) + vlog.info(" %s rects %d, bytes %d", + encodingName(i), rectsSent[i], bytesSent[i]); + } + vlog.info(" raw bytes equivalent %d, compression ratio %f", + rawBytesEquivalent, (double)rawBytesEquivalent / bytes); + delete [] imageBuf; +} + +void SMsgWriter::writeSetColourMapEntries(int firstColour, int nColours, + ColourMap* cm) +{ + startMsg(msgTypeSetColourMapEntries); + os->pad(1); + os->writeU16(firstColour); + os->writeU16(nColours); + for (int i = firstColour; i < firstColour+nColours; i++) { + int r, g, b; + cm->lookup(i, &r, &g, &b); + os->writeU16(r); + os->writeU16(g); + os->writeU16(b); + } + endMsg(); +} + +void SMsgWriter::writeBell() +{ + startMsg(msgTypeBell); + endMsg(); +} + +void SMsgWriter::writeServerCutText(const char* str, int len) +{ + startMsg(msgTypeServerCutText); + os->pad(3); + os->writeU32(len); + os->writeBytes(str, len); + endMsg(); +} + +void SMsgWriter::setupCurrentEncoder() +{ + unsigned int encoding = cp->currentEncoding(); + + // FIXME: Code duplication, see writeRect(). + if (!encoders[encoding]) { + encoders[encoding] = Encoder::createEncoder(encoding, this); + assert(encoders[encoding]); + } + + encoders[encoding]->setCompressLevel(cp->compressLevel); + encoders[encoding]->setQualityLevel(cp->qualityLevel); +} + +int SMsgWriter::getNumRects(const Rect &r) +{ + unsigned int encoding = cp->currentEncoding(); + + if (!encoders[encoding]) + setupCurrentEncoder(); + + return encoders[encoding]->getNumRects(r); +} + +// FIXME: This functions does not compute the number of rectangles correctly +// if the Tight encoder is used (but currently that does not matter +// because this function is never used). +void SMsgWriter::writeFramebufferUpdate(const UpdateInfo& ui, ImageGetter* ig, + Region* updatedRegion) +{ + writeFramebufferUpdateStart(ui.numRects()); + writeRects(ui, ig, updatedRegion); + writeFramebufferUpdateEnd(); +} + +void SMsgWriter::writeRects(const UpdateInfo& ui, ImageGetter* ig, + Region* updatedRegion) +{ + std::vector<Rect> rects; + std::vector<Rect>::const_iterator i; + updatedRegion->copyFrom(ui.changed); + updatedRegion->assign_union(ui.copied); + + ui.copied.get_rects(&rects, ui.copy_delta.x <= 0, ui.copy_delta.y <= 0); + for (i = rects.begin(); i != rects.end(); i++) + writeCopyRect(*i, i->tl.x - ui.copy_delta.x, i->tl.y - ui.copy_delta.y); + + ui.changed.get_rects(&rects); + for (i = rects.begin(); i != rects.end(); i++) { + Rect actual; + if (!writeRect(*i, ig, &actual)) { + updatedRegion->assign_subtract(*i); + updatedRegion->assign_union(actual); + } + } +} + + +bool SMsgWriter::needFakeUpdate() +{ + return false; +} + +bool SMsgWriter::writeRect(const Rect& r, ImageGetter* ig, Rect* actual) +{ + return writeRect(r, cp->currentEncoding(), ig, actual); +} + +bool SMsgWriter::writeRect(const Rect& r, unsigned int encoding, + ImageGetter* ig, Rect* actual) +{ + if (!encoders[encoding]) { + encoders[encoding] = Encoder::createEncoder(encoding, this); + assert(encoders[encoding]); + } + return encoders[encoding]->writeRect(r, ig, actual); +} + +void SMsgWriter::writeCopyRect(const Rect& r, int srcX, int srcY) +{ + startRect(r,encodingCopyRect); + os->writeU16(srcX); + os->writeU16(srcY); + endRect(); +} + +rdr::U8* SMsgWriter::getImageBuf(int required, int requested, int* nPixels) +{ + int requiredBytes = required * (cp->pf().bpp / 8); + int requestedBytes = requested * (cp->pf().bpp / 8); + int size = requestedBytes; + if (size > imageBufIdealSize) size = imageBufIdealSize; + + if (size < requiredBytes) + size = requiredBytes; + + if (imageBufSize < size) { + imageBufSize = size; + delete [] imageBuf; + imageBuf = new rdr::U8[imageBufSize]; + } + if (nPixels) + *nPixels = imageBufSize / (cp->pf().bpp / 8); + return imageBuf; +} + +int SMsgWriter::bpp() +{ + return cp->pf().bpp; +} |