aboutsummaryrefslogtreecommitdiff
path: root/nxcomp/src/RenderExtension.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'nxcomp/src/RenderExtension.cpp')
-rw-r--r--nxcomp/src/RenderExtension.cpp427
1 files changed, 427 insertions, 0 deletions
diff --git a/nxcomp/src/RenderExtension.cpp b/nxcomp/src/RenderExtension.cpp
new file mode 100644
index 000000000..64761bc05
--- /dev/null
+++ b/nxcomp/src/RenderExtension.cpp
@@ -0,0 +1,427 @@
+/**************************************************************************/
+/* */
+/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */
+/* Copyright (c) 2008-2014 Oleksandr Shneyder <o.shneyder@phoca-gmbh.de> */
+/* Copyright (c) 2014-2016 Ulrich Sibiller <uli42@gmx.de> */
+/* Copyright (c) 2014-2016 Mihai Moldovan <ionic@ionic.de> */
+/* Copyright (c) 2011-2016 Mike Gabriel <mike.gabriel@das-netzwerkteam.de>*/
+/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */
+/* */
+/* NXCOMP, NX protocol compression and NX extensions to this software */
+/* are copyright of the aforementioned persons and companies. */
+/* */
+/* Redistribution and use of the present software is allowed according */
+/* to terms specified in the file LICENSE.nxcomp which comes in the */
+/* source distribution. */
+/* */
+/* All rights reserved. */
+/* */
+/* NOTE: This software has received contributions from various other */
+/* contributors, only the core maintainers and supporters are listed as */
+/* copyright holders. Please contact us, if you feel you should be listed */
+/* as copyright holder, as well. */
+/* */
+/**************************************************************************/
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "NXrender.h"
+
+#include "ClientCache.h"
+
+#include "EncodeBuffer.h"
+#include "DecodeBuffer.h"
+
+#include "WriteBuffer.h"
+
+#include "RenderExtension.h"
+
+#include "RenderGenericRequest.h"
+#include "RenderCreatePicture.h"
+#include "RenderChangePicture.h"
+#include "RenderFreePicture.h"
+#include "RenderPictureClip.h"
+#include "RenderPictureTransform.h"
+#include "RenderPictureFilter.h"
+#include "RenderCreateGlyphSet.h"
+#include "RenderFreeGlyphSet.h"
+#include "RenderAddGlyphs.h"
+#include "RenderComposite.h"
+#include "RenderCompositeGlyphs.h"
+#include "RenderFillRectangles.h"
+#include "RenderTrapezoids.h"
+#include "RenderTriangles.h"
+
+//
+// Set the verbosity level.
+//
+
+#define PANIC
+#define WARNING
+#undef TEST
+#undef DEBUG
+
+//
+// Constructor and destructor.
+//
+
+RenderExtensionStore::RenderExtensionStore(StaticCompressor *compressor)
+
+ : MessageStore(compressor)
+{
+ enableCache = RENDEREXTENSION_ENABLE_CACHE;
+ enableData = RENDEREXTENSION_ENABLE_DATA;
+ enableSplit = RENDEREXTENSION_ENABLE_SPLIT;
+ enableCompress = RENDEREXTENSION_ENABLE_COMPRESS;
+
+ generic_ = new RenderGenericRequestStore();
+
+ for (int i = 0; i < RENDEREXTENSION_MINOR_OPCODE_LIMIT; i++)
+ {
+ minors_[i] = generic_;
+ }
+
+ minors_[X_RenderChangePicture] = new RenderChangePictureStore();
+ minors_[X_RenderFillRectangles] = new RenderFillRectanglesStore();
+ minors_[X_RenderAddGlyphs] = new RenderAddGlyphsStore();
+
+ // Since ProtoStep7 (#issue 108)
+ minors_[X_RenderCreatePicture] = new RenderCreatePictureStore();
+ minors_[X_RenderFreePicture] = new RenderFreePictureStore();
+ minors_[X_RenderSetPictureClipRectangles] = new RenderPictureClipStore();
+ minors_[X_RenderCreateGlyphSet] = new RenderCreateGlyphSetStore();
+ minors_[X_RenderComposite] = new RenderCompositeStore();
+ minors_[X_RenderCompositeGlyphs8] = new RenderCompositeGlyphsStore();
+ minors_[X_RenderCompositeGlyphs16] = new RenderCompositeGlyphsStore();
+ minors_[X_RenderCompositeGlyphs32] = new RenderCompositeGlyphsStore();
+
+ minors_[X_RenderSetPictureTransform] = new RenderPictureTransformStore();
+ minors_[X_RenderSetPictureFilter] = new RenderPictureFilterStore();
+ minors_[X_RenderFreeGlyphSet] = new RenderFreeGlyphSetStore();
+ minors_[X_RenderTrapezoids] = new RenderTrapezoidsStore();
+ minors_[X_RenderTriangles] = new RenderTrianglesStore();
+
+ dataLimit = RENDEREXTENSION_DATA_LIMIT;
+ dataOffset = RENDEREXTENSION_DATA_OFFSET;
+
+ // Since ProtoStep7 (#issue 108)
+ cacheSlots = RENDEREXTENSION_CACHE_SLOTS_IF_PROTO_STEP_7;
+
+ cacheThreshold = RENDEREXTENSION_CACHE_THRESHOLD;
+ cacheLowerThreshold = RENDEREXTENSION_CACHE_LOWER_THRESHOLD;
+
+ opcode_ = X_NXInternalRenderExtension;
+
+ messages_ -> resize(cacheSlots);
+
+ for (T_messages::iterator i = messages_ -> begin();
+ i < messages_ -> end(); i++)
+ {
+ *i = NULL;
+ }
+
+ temporary_ = NULL;
+}
+
+RenderExtensionStore::~RenderExtensionStore()
+{
+ for (int i = 0; i < RENDEREXTENSION_MINOR_OPCODE_LIMIT; i++)
+ {
+ if (minors_[i] != generic_)
+ {
+ delete minors_[i];
+ }
+ }
+
+ delete generic_;
+
+ for (T_messages::iterator i = messages_ -> begin();
+ i < messages_ -> end(); i++)
+ {
+ destroy(*i);
+ }
+
+ destroy(temporary_);
+}
+
+int RenderExtensionStore::validateMessage(const unsigned char *buffer, int size)
+{
+ #ifdef TEST
+ *logofs << name() << ": Encoding message OPCODE#"
+ << (unsigned) *buffer << " MINOR#" << (unsigned)
+ *(buffer + 1) << " with size " << size
+ << ".\n" << logofs_flush;
+ #endif
+
+ return (size >= control -> MinimumMessageSize &&
+ size <= control -> MaximumMessageSize);
+}
+
+//
+// Here are the methods to handle the messages' content.
+//
+
+int RenderExtensionStore::identitySize(const unsigned char *buffer, unsigned int size)
+{
+ return minors_[*(buffer + 1)] -> identitySize(buffer, size);
+}
+
+int RenderExtensionStore::encodeIdentity(EncodeBuffer &encodeBuffer, const unsigned char *buffer,
+ const unsigned int size, int bigEndian,
+ ChannelCache *channelCache) const
+{
+ encodeBuffer.encodeOpcodeValue(*(buffer + 1),
+ ((ClientCache *) channelCache) -> renderOpcodeCache);
+
+ minors_[*(buffer + 1)] -> encodeMessage(encodeBuffer, buffer, size,
+ bigEndian, channelCache);
+
+ return 1;
+}
+
+int RenderExtensionStore::decodeIdentity(DecodeBuffer &decodeBuffer, unsigned char *&buffer,
+ unsigned int &size, int bigEndian, WriteBuffer *writeBuffer,
+ ChannelCache *channelCache) const
+{
+ unsigned char type;
+
+ decodeBuffer.decodeOpcodeValue(type,
+ ((ClientCache *) channelCache) -> renderOpcodeCache);
+
+ minors_[type] -> decodeMessage(decodeBuffer, buffer, size, type,
+ bigEndian, writeBuffer, channelCache);
+
+ return 1;
+}
+
+int RenderExtensionStore::parseIdentity(Message *message, const unsigned char *buffer,
+ unsigned int size, int bigEndian) const
+{
+ return minors_[*(buffer + 1)] -> parseIdentity(message, buffer, size, bigEndian);
+}
+
+int RenderExtensionStore::unparseIdentity(const Message *message, unsigned char *buffer,
+ unsigned int size, int bigEndian) const
+{
+ return minors_[((RenderExtensionMessage *) message) -> data.any.type] ->
+ unparseIdentity(message, buffer, size, bigEndian);
+}
+
+void RenderExtensionStore::identityChecksum(const Message *message, const unsigned char *buffer,
+ unsigned int size, int bigEndian) const
+{
+ minors_[*(buffer + 1)] -> identityChecksum(message, buffer, size, md5_state_, bigEndian);
+}
+
+void RenderExtensionStore::updateIdentity(EncodeBuffer &encodeBuffer, const Message *message,
+ const Message *cachedMessage,
+ ChannelCache *channelCache) const
+{
+ minors_[((RenderExtensionMessage *) message) -> data.any.type] ->
+ updateIdentity(encodeBuffer, message, cachedMessage, channelCache);
+}
+
+void RenderExtensionStore::updateIdentity(DecodeBuffer &decodeBuffer, const Message *message,
+ ChannelCache *channelCache) const
+{
+ minors_[((RenderExtensionMessage *) message) -> data.any.type] ->
+ updateIdentity(decodeBuffer, message, channelCache);
+}
+
+void RenderExtensionStore::dumpIdentity(const Message *message) const
+{
+ #ifdef DUMP
+
+ #ifdef WARNING
+ *logofs << name() << ": WARNING! Dump of identity not implemented.\n"
+ << logofs_flush;
+ #endif
+
+ #endif
+}
+
+//
+// TODO: The following encoding and decoding functions
+// could be generalized further, for example by passing
+// the pointer to the data cache, the number of caches
+// made available by the caller and the first cache to
+// iterate through.
+//
+
+void RenderMinorExtensionStore::encodeLongData(EncodeBuffer &encodeBuffer, const unsigned char *buffer,
+ unsigned int offset, unsigned int size, int bigEndian,
+ ChannelCache *channelCache) const
+{
+ // Since ProtoStep7 (#issue 108)
+ encodeBuffer.encodeLongData(buffer + offset, size - offset);
+
+ #ifdef TEST
+ *logofs << name() << ": Encoded " << size - offset
+ << " bytes of long data.\n" << logofs_flush;
+ #endif
+}
+
+void RenderMinorExtensionStore::encodeIntData(EncodeBuffer &encodeBuffer, const unsigned char *buffer,
+ unsigned int offset, unsigned int size, int bigEndian,
+ ChannelCache *channelCache) const
+{
+ // Since ProtoStep7 (#issue 108)
+ encodeBuffer.encodeIntData(buffer + offset, size - offset);
+
+ #ifdef TEST
+ *logofs << name() << ": Encoded " << size - offset
+ << " bytes of int data.\n" << logofs_flush;
+ #endif
+}
+
+void RenderMinorExtensionStore::encodeCharData(EncodeBuffer &encodeBuffer, const unsigned char *buffer,
+ unsigned int offset, unsigned int size, int bigEndian,
+ ChannelCache *channelCache) const
+{
+ // Since ProtoStep7 (#issue 108)
+ encodeBuffer.encodeTextData(buffer + offset, size - offset);
+
+ #ifdef TEST
+ *logofs << name() << ": Encoded " << size - offset
+ << " bytes of text data.\n" << logofs_flush;
+ #endif
+}
+
+void RenderMinorExtensionStore::decodeLongData(DecodeBuffer &decodeBuffer, unsigned char *buffer,
+ unsigned int offset, unsigned int size, int bigEndian,
+ ChannelCache *channelCache) const
+{
+ // Since ProtoStep7 (#issue 108)
+ decodeBuffer.decodeLongData(buffer + offset, size - offset);
+
+ #ifdef TEST
+ *logofs << name() << ": Decoded " << size - offset
+ << " bytes of long data.\n" << logofs_flush;
+ #endif
+}
+
+void RenderMinorExtensionStore::decodeIntData(DecodeBuffer &decodeBuffer, unsigned char *buffer,
+ unsigned int offset, unsigned int size, int bigEndian,
+ ChannelCache *channelCache) const
+{
+ // Since ProtoStep7 (#issue 108)
+ decodeBuffer.decodeIntData(buffer + offset, size - offset);
+
+ #ifdef TEST
+ *logofs << name() << ": Decoded " << size - offset
+ << " bytes of int data.\n" << logofs_flush;
+ #endif
+}
+
+void RenderMinorExtensionStore::decodeCharData(DecodeBuffer &decodeBuffer, unsigned char *buffer,
+ unsigned int offset, unsigned int size, int bigEndian,
+ ChannelCache *channelCache) const
+{
+ // Since ProtoStep7 (#issue 108)
+ decodeBuffer.decodeTextData(buffer + offset, size - offset);
+
+ #ifdef TEST
+ *logofs << name() << ": Decoded " << size - offset
+ << " bytes of text data.\n" << logofs_flush;
+ #endif
+}
+
+void RenderMinorExtensionStore::parseIntData(const Message *message, const unsigned char *buffer,
+ unsigned int offset, unsigned int size,
+ int bigEndian) const
+{
+ RenderExtensionMessage *renderExtension = (RenderExtensionMessage *) message;
+
+ unsigned int last = ((unsigned) message -> i_size_ > size ? size : message -> i_size_);
+
+ for (unsigned int i = offset, c = (offset - 4) % 16; i < last; i += 2)
+ {
+ #ifdef DEBUG
+ *logofs << name() << ": Parsing int with i = " << i << " c = "
+ << c << ".\n" << logofs_flush;
+ #endif
+
+ renderExtension -> data.any.short_data[c] = GetUINT(buffer + i, bigEndian);
+
+ if (++c == 16) c = 0;
+ }
+}
+
+void RenderMinorExtensionStore::unparseIntData(const Message *message, unsigned char *buffer,
+ unsigned int offset, unsigned int size,
+ int bigEndian) const
+{
+ RenderExtensionMessage *renderExtension = (RenderExtensionMessage *) message;
+
+ unsigned int last = ((unsigned) message -> i_size_ > size ? size : message -> i_size_);
+
+ for (unsigned int i = offset, c = (offset - 4) % 16; i < last; i += 2)
+ {
+ #ifdef DEBUG
+ *logofs << name() << ": Unparsing int with i = " << i << " c = "
+ << c << ".\n" << logofs_flush;
+ #endif
+
+ PutUINT(renderExtension -> data.any.short_data[c], buffer + i, bigEndian);
+
+ if (++c == 16) c = 0;
+ }
+}
+
+void RenderMinorExtensionStore::updateIntData(EncodeBuffer &encodeBuffer, const Message *message,
+ const Message *cachedMessage, unsigned int offset,
+ unsigned int size, ChannelCache *channelCache) const
+{
+ RenderExtensionMessage *renderExtension = (RenderExtensionMessage *) message;
+ RenderExtensionMessage *cachedRenderExtension = (RenderExtensionMessage *) cachedMessage;
+
+ ClientCache *clientCache = (ClientCache *) channelCache;
+
+ unsigned int last = ((unsigned) message -> i_size_ > size ? size : message -> i_size_);
+
+ for (unsigned int i = offset, c = (offset - 4) % 16; i < last; i += 2)
+ {
+ #ifdef DEBUG
+ *logofs << name() << ": Encoding int update with i = " << i
+ << " c = " << c << ".\n" << logofs_flush;
+ #endif
+
+ encodeBuffer.encodeCachedValue(renderExtension -> data.any.short_data[c], 16,
+ *clientCache -> renderDataCache[c]);
+
+ cachedRenderExtension -> data.any.short_data[c] =
+ renderExtension -> data.any.short_data[c];
+
+ if (++c == 16) c = 0;
+ }
+}
+
+void RenderMinorExtensionStore::updateIntData(DecodeBuffer &decodeBuffer, const Message *message,
+ unsigned int offset, unsigned int size,
+ ChannelCache *channelCache) const
+{
+ RenderExtensionMessage *renderExtension = (RenderExtensionMessage *) message;
+
+ ClientCache *clientCache = (ClientCache *) channelCache;
+
+ unsigned int last = ((unsigned) message -> i_size_ > size ? size : message -> i_size_);
+
+ unsigned int value;
+
+ for (unsigned int i = offset, c = (offset - 4) % 16; i < last; i += 2)
+ {
+ #ifdef DEBUG
+ *logofs << name() << ": Decoding int update with i = " << i
+ << " c = " << c << ".\n" << logofs_flush;
+ #endif
+
+ decodeBuffer.decodeCachedValue(value, 16,
+ *clientCache -> renderDataCache[c]);
+
+ renderExtension -> data.any.short_data[c] = value;
+
+ if (++c == 16) c = 0;
+ }
+}